summaryrefslogtreecommitdiff
path: root/bgpd
diff options
context:
space:
mode:
Diffstat (limited to 'bgpd')
-rw-r--r--bgpd/bgp_bmp.c2
-rw-r--r--bgpd/bgp_ecommunity.c22
-rw-r--r--bgpd/bgp_fsm.c4
-rw-r--r--bgpd/bgp_fsm.h1
-rw-r--r--bgpd/bgp_mplsvpn.c68
-rw-r--r--bgpd/bgp_mplsvpn_snmp.c2
-rw-r--r--bgpd/bgp_nb_config.c7
-rw-r--r--bgpd/bgp_network.c1
-rw-r--r--bgpd/bgp_nht.c37
-rw-r--r--bgpd/bgp_nht.h2
-rw-r--r--bgpd/bgp_route.c2
-rw-r--r--bgpd/bgp_rpki.c2
-rw-r--r--bgpd/bgp_snmp.c2
-rw-r--r--bgpd/bgp_zebra.c3
-rw-r--r--bgpd/bgpd.c2
-rw-r--r--bgpd/bgpd.h1
-rw-r--r--bgpd/rfp-example/rfptest/subdir.am5
-rw-r--r--bgpd/subdir.am7
18 files changed, 117 insertions, 53 deletions
diff --git a/bgpd/bgp_bmp.c b/bgpd/bgp_bmp.c
index 0e5f506b3a..abe97571c5 100644
--- a/bgpd/bgp_bmp.c
+++ b/bgpd/bgp_bmp.c
@@ -34,7 +34,7 @@
#include "lib_errors.h"
#include "stream.h"
#include "libfrr.h"
-#include "version.h"
+#include "lib/version.h"
#include "jhash.h"
#include "termtable.h"
diff --git a/bgpd/bgp_ecommunity.c b/bgpd/bgp_ecommunity.c
index 7f6f61e141..923c9b0d7e 100644
--- a/bgpd/bgp_ecommunity.c
+++ b/bgpd/bgp_ecommunity.c
@@ -1294,15 +1294,19 @@ bool ecommunity_del_val(struct ecommunity *ecom, struct ecommunity_val *eval)
/* Delete the selected value */
ecom->size--;
- p = XMALLOC(MTYPE_ECOMMUNITY_VAL, ecom->size * ecom->unit_size);
- if (c != 0)
- memcpy(p, ecom->val, c * ecom->unit_size);
- if ((ecom->size - c) != 0)
- memcpy(p + (c)*ecom->unit_size,
- ecom->val + (c + 1) * ecom->unit_size,
- (ecom->size - c) * ecom->unit_size);
- XFREE(MTYPE_ECOMMUNITY_VAL, ecom->val);
- ecom->val = p;
+ if (ecom->size) {
+ p = XMALLOC(MTYPE_ECOMMUNITY_VAL, ecom->size * ecom->unit_size);
+ if (c != 0)
+ memcpy(p, ecom->val, c * ecom->unit_size);
+ if ((ecom->size - c) != 0)
+ memcpy(p + (c)*ecom->unit_size,
+ ecom->val + (c + 1) * ecom->unit_size,
+ (ecom->size - c) * ecom->unit_size);
+ XFREE(MTYPE_ECOMMUNITY_VAL, ecom->val);
+ ecom->val = p;
+ } else
+ ecom->val = NULL;
+
return true;
}
diff --git a/bgpd/bgp_fsm.c b/bgpd/bgp_fsm.c
index 45a856a459..88c44fc984 100644
--- a/bgpd/bgp_fsm.c
+++ b/bgpd/bgp_fsm.c
@@ -101,7 +101,7 @@ static int bgp_delayopen_timer(struct thread *);
static int bgp_start(struct peer *);
/* Register peer with NHT */
-static int bgp_peer_reg_with_nht(struct peer *peer)
+int bgp_peer_reg_with_nht(struct peer *peer)
{
int connected = 0;
@@ -340,6 +340,8 @@ static struct peer *peer_xfer_conn(struct peer *from_peer)
* needed, even on a passive connection.
*/
bgp_peer_reg_with_nht(peer);
+ if (from_peer)
+ bgp_replace_nexthop_by_peer(from_peer, peer);
bgp_reads_on(peer);
bgp_writes_on(peer);
diff --git a/bgpd/bgp_fsm.h b/bgpd/bgp_fsm.h
index bcf697e153..12cbad3eb8 100644
--- a/bgpd/bgp_fsm.h
+++ b/bgpd/bgp_fsm.h
@@ -179,4 +179,5 @@ const char *print_peer_gr_mode(enum peer_mode pr_mode);
const char *print_peer_gr_cmd(enum peer_gr_command pr_gr_cmd);
const char *print_global_gr_mode(enum global_mode gl_mode);
const char *print_global_gr_cmd(enum global_gr_command gl_gr_cmd);
+int bgp_peer_reg_with_nht(struct peer *peer);
#endif /* _QUAGGA_BGP_FSM_H */
diff --git a/bgpd/bgp_mplsvpn.c b/bgpd/bgp_mplsvpn.c
index 62fed931f9..eb68d84c06 100644
--- a/bgpd/bgp_mplsvpn.c
+++ b/bgpd/bgp_mplsvpn.c
@@ -540,6 +540,17 @@ leak_update(struct bgp *bgp, /* destination bgp instance */
if (bpi) {
bool labelssame = labels_same(bpi, label, num_labels);
+ if (CHECK_FLAG(source_bpi->flags, BGP_PATH_REMOVED)
+ && CHECK_FLAG(bpi->flags, BGP_PATH_REMOVED)) {
+ if (debug) {
+ zlog_debug(
+ "%s: ->%s(s_flags: 0x%x b_flags: 0x%x): %pFX: Found route, being removed, not leaking",
+ __func__, bgp->name_pretty,
+ source_bpi->flags, bpi->flags, p);
+ }
+ return NULL;
+ }
+
if (attrhash_cmp(bpi->attr, new_attr) && labelssame
&& !CHECK_FLAG(bpi->flags, BGP_PATH_REMOVED)) {
@@ -613,6 +624,16 @@ leak_update(struct bgp *bgp, /* destination bgp instance */
return bpi;
}
+ if (CHECK_FLAG(source_bpi->flags, BGP_PATH_REMOVED)) {
+ if (debug) {
+ zlog_debug(
+ "%s: ->%s(s_flags: 0x%x): %pFX: New route, being removed, not leaking",
+ __func__, bgp->name_pretty,
+ source_bpi->flags, p);
+ }
+ return NULL;
+ }
+
new = info_make(ZEBRA_ROUTE_BGP, BGP_ROUTE_IMPORTED, 0,
bgp->peer_self, new_attr, bn);
@@ -1027,6 +1048,8 @@ void vpn_leak_from_vrf_withdraw_all(struct bgp *bgp_vpn, /* to */
if (debug)
zlog_debug("%s: deleting it",
__func__);
+ /* withdraw from leak-to vrfs as well */
+ vpn_leak_to_vrf_withdraw(bgp_vpn, bpi);
bgp_aggregate_decrement(
bgp_vpn,
bgp_dest_get_prefix(bn), bpi,
@@ -1101,7 +1124,10 @@ vpn_leak_to_vrf_update_onevrf(struct bgp *bgp_vrf, /* to */
if (!ecom_intersect(
bgp_vrf->vpn_policy[afi].rtlist[BGP_VPN_POLICY_DIR_FROMVPN],
path_vpn->attr->ecommunity)) {
-
+ if (debug)
+ zlog_debug(
+ "from vpn to vrf %s, skipping after no intersection of route targets",
+ bgp_vrf->name_pretty);
return;
}
@@ -1532,7 +1558,8 @@ void vpn_handle_router_id_update(struct bgp *bgp, bool withdraw,
bool is_config)
{
afi_t afi;
- int debug;
+ int debug = (BGP_DEBUG(vpn, VPN_LEAK_TO_VRF)
+ | BGP_DEBUG(vpn, VPN_LEAK_FROM_VRF));
char *vname;
const char *export_name;
char buf[RD_ADDRSTRLEN];
@@ -1541,14 +1568,23 @@ void vpn_handle_router_id_update(struct bgp *bgp, bool withdraw,
struct ecommunity *ecom;
vpn_policy_direction_t idir, edir;
+ /*
+ * Router-id change that is not explicitly configured
+ * (a change from zebra, frr restart for example)
+ * should not replace a configured vpn RD/RT.
+ */
+ if (!is_config) {
+ if (debug)
+ zlog_debug("%s: skipping non explicit router-id change",
+ __func__);
+ return;
+ }
+
if (bgp->inst_type != BGP_INSTANCE_TYPE_DEFAULT
&& bgp->inst_type != BGP_INSTANCE_TYPE_VRF)
return;
export_name = bgp->name ? bgp->name : VRF_DEFAULT_NAME;
- debug = (BGP_DEBUG(vpn, VPN_LEAK_TO_VRF) |
- BGP_DEBUG(vpn, VPN_LEAK_FROM_VRF));
-
idir = BGP_VPN_POLICY_DIR_FROMVPN;
edir = BGP_VPN_POLICY_DIR_TOVPN;
@@ -1574,26 +1610,12 @@ void vpn_handle_router_id_update(struct bgp *bgp, bool withdraw,
if (!bgp_import)
continue;
- ecommunity_del_val(bgp_import->vpn_policy[afi].
- rtlist[idir],
+ ecommunity_del_val(
+ bgp_import->vpn_policy[afi]
+ .rtlist[idir],
(struct ecommunity_val *)ecom->val);
-
}
} else {
- /*
- * Router-id changes that are not explicit config
- * changes should not replace configured RD/RT.
- */
- if (!is_config) {
- if (CHECK_FLAG(bgp->vpn_policy[afi].flags,
- BGP_VPN_POLICY_TOVPN_RD_SET)) {
- if (debug)
- zlog_debug("%s: auto router-id change skipped",
- __func__);
- goto postchange;
- }
- }
-
/* New router-id derive auto RD and RT and export
* to VPN
*/
@@ -1624,10 +1646,8 @@ void vpn_handle_router_id_update(struct bgp *bgp, bool withdraw,
else
bgp_import->vpn_policy[afi].rtlist[idir]
= ecommunity_dup(ecom);
-
}
-postchange:
/* Update routes to VPN */
vpn_leak_postchange(BGP_VPN_POLICY_DIR_TOVPN,
afi, bgp_get_default(),
diff --git a/bgpd/bgp_mplsvpn_snmp.c b/bgpd/bgp_mplsvpn_snmp.c
index 6f75856d54..7a2f618ce6 100644
--- a/bgpd/bgp_mplsvpn_snmp.c
+++ b/bgpd/bgp_mplsvpn_snmp.c
@@ -32,7 +32,7 @@
#include "filter.h"
#include "hook.h"
#include "libfrr.h"
-#include "version.h"
+#include "lib/version.h"
#include "bgpd/bgpd.h"
#include "bgpd/bgp_route.h"
diff --git a/bgpd/bgp_nb_config.c b/bgpd/bgp_nb_config.c
index 5a88bd08d9..94ff362d1a 100644
--- a/bgpd/bgp_nb_config.c
+++ b/bgpd/bgp_nb_config.c
@@ -123,7 +123,12 @@ int bgp_router_create(struct nb_cb_create_args *args)
if (is_new_bgp && inst_type == BGP_INSTANCE_TYPE_DEFAULT)
vpn_leak_postchange_all();
- if (inst_type == BGP_INSTANCE_TYPE_VRF)
+ /*
+ * Check if we need to export to other VRF(s).
+ * Leak the routes to importing bgp vrf instances,
+ * only when new bgp vrf instance is configured.
+ */
+ if (ret != BGP_INSTANCE_EXISTS)
bgp_vpn_leak_export(bgp);
UNSET_FLAG(bgp->vrf_flags, BGP_VRF_AUTO);
diff --git a/bgpd/bgp_network.c b/bgpd/bgp_network.c
index 4821ce8ddb..8d9024e07c 100644
--- a/bgpd/bgp_network.c
+++ b/bgpd/bgp_network.c
@@ -569,6 +569,7 @@ static int bgp_accept(struct thread *thread)
peer1->doppelganger = peer;
peer->fd = bgp_sock;
vrf_bind(peer->bgp->vrf_id, bgp_sock, bgp_get_bound_name(peer));
+ bgp_peer_reg_with_nht(peer);
bgp_fsm_change_status(peer, Active);
BGP_TIMER_OFF(peer->t_start); /* created in peer_create() */
diff --git a/bgpd/bgp_nht.c b/bgpd/bgp_nht.c
index 9c8d7878c5..7ccfae4ba4 100644
--- a/bgpd/bgp_nht.c
+++ b/bgpd/bgp_nht.c
@@ -98,6 +98,31 @@ void bgp_unlink_nexthop(struct bgp_path_info *path)
bgp_unlink_nexthop_check(bnc);
}
+void bgp_replace_nexthop_by_peer(struct peer *from, struct peer *to)
+{
+ struct prefix pp;
+ struct prefix pt;
+ struct bgp_nexthop_cache *bncp, *bnct;
+ afi_t afi;
+
+ if (!sockunion2hostprefix(&from->su, &pp))
+ return;
+
+ afi = family2afi(pp.family);
+ bncp = bnc_find(&from->bgp->nexthop_cache_table[afi], &pp, 0);
+
+ if (!sockunion2hostprefix(&to->su, &pt))
+ return;
+
+ bnct = bnc_find(&to->bgp->nexthop_cache_table[afi], &pt, 0);
+
+ if (bnct != bncp)
+ return;
+
+ if (bnct)
+ bnct->nht_info = to;
+}
+
void bgp_unlink_nexthop_by_peer(struct peer *peer)
{
struct prefix p;
@@ -273,8 +298,16 @@ int bgp_find_or_add_nexthop(struct bgp *bgp_route, struct bgp *bgp_nexthop,
(bgp_path_info_extra_get(pi))->igpmetric = bnc->metric;
else if (pi->extra)
pi->extra->igpmetric = 0;
- } else if (peer)
- bnc->nht_info = (void *)peer; /* NHT peer reference */
+ } else if (peer) {
+ /*
+ * Let's not accidently save the peer data for a peer
+ * we are going to throw away in a second or so.
+ * When we come back around we'll fix up this
+ * data properly in replace_nexthop_by_peer
+ */
+ if (CHECK_FLAG(peer->flags, PEER_FLAG_CONFIG_NODE))
+ bnc->nht_info = (void *)peer; /* NHT peer reference */
+ }
/*
* We are cheating here. Views have no associated underlying
diff --git a/bgpd/bgp_nht.h b/bgpd/bgp_nht.h
index a1683e1511..9268b225ca 100644
--- a/bgpd/bgp_nht.h
+++ b/bgpd/bgp_nht.h
@@ -51,7 +51,7 @@ extern int bgp_find_or_add_nexthop(struct bgp *bgp_route,
*/
extern void bgp_unlink_nexthop(struct bgp_path_info *p);
void bgp_unlink_nexthop_by_peer(struct peer *peer);
-
+void bgp_replace_nexthop_by_peer(struct peer *from, struct peer *to);
/**
* bgp_delete_connected_nexthop() - Reset the 'peer' pointer for a connected
* nexthop entry. If no paths reference the nexthop, it will be unregistered
diff --git a/bgpd/bgp_route.c b/bgpd/bgp_route.c
index 321397c3af..49b94e6d7c 100644
--- a/bgpd/bgp_route.c
+++ b/bgpd/bgp_route.c
@@ -10260,7 +10260,7 @@ void route_vty_out_detail(struct vty *vty, struct bgp *bgp, struct bgp_dest *bn,
vty_out(vty, "\n");
/* Line 4 display Community */
- if (attr->community) {
+ if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_COMMUNITIES)) {
if (json_paths) {
if (!attr->community->json)
community_str(attr->community, true);
diff --git a/bgpd/bgp_rpki.c b/bgpd/bgp_rpki.c
index bb85ad393d..816ed88eec 100644
--- a/bgpd/bgp_rpki.c
+++ b/bgpd/bgp_rpki.c
@@ -57,7 +57,7 @@
#endif
#include "hook.h"
#include "libfrr.h"
-#include "version.h"
+#include "lib/version.h"
#ifndef VTYSH_EXTRACT_PL
#include "bgpd/bgp_rpki_clippy.c"
diff --git a/bgpd/bgp_snmp.c b/bgpd/bgp_snmp.c
index 3afdbea908..61a6467ab6 100644
--- a/bgpd/bgp_snmp.c
+++ b/bgpd/bgp_snmp.c
@@ -32,7 +32,7 @@
#include "filter.h"
#include "hook.h"
#include "libfrr.h"
-#include "version.h"
+#include "lib/version.h"
#include "bgpd/bgpd.h"
#include "bgpd/bgp_table.h"
diff --git a/bgpd/bgp_zebra.c b/bgpd/bgp_zebra.c
index d1912db01f..ae0bf7fe92 100644
--- a/bgpd/bgp_zebra.c
+++ b/bgpd/bgp_zebra.c
@@ -1700,9 +1700,6 @@ int bgp_redistribute_set(struct bgp *bgp, afi_t afi, int type,
redist_add_instance(&zclient->mi_redist[afi][type], instance);
} else {
- if (vrf_bitmap_check(zclient->redist[afi][type], bgp->vrf_id))
- return CMD_WARNING;
-
#ifdef ENABLE_BGP_VNC
if (EVPN_ENABLED(bgp) && type == ZEBRA_ROUTE_VNC_DIRECT) {
vnc_export_bgp_enable(
diff --git a/bgpd/bgpd.c b/bgpd/bgpd.c
index d37b9fa48c..bad62f9946 100644
--- a/bgpd/bgpd.c
+++ b/bgpd/bgpd.c
@@ -3402,7 +3402,7 @@ int bgp_get(struct bgp **bgp_val, as_t *as, const char *name,
return ret;
case BGP_SUCCESS:
if (*bgp_val)
- return ret;
+ return BGP_INSTANCE_EXISTS;
}
bgp = bgp_create(as, name, inst_type);
diff --git a/bgpd/bgpd.h b/bgpd/bgpd.h
index 51134dc8c5..f9aa62c682 100644
--- a/bgpd/bgpd.h
+++ b/bgpd/bgpd.h
@@ -1844,6 +1844,7 @@ enum bgp_clear_type {
/* BGP error codes. */
#define BGP_SUCCESS 0
#define BGP_CREATED 1
+#define BGP_INSTANCE_EXISTS 2
#define BGP_ERR_INVALID_VALUE -1
#define BGP_ERR_INVALID_FLAG -2
#define BGP_ERR_INVALID_AS -3
diff --git a/bgpd/rfp-example/rfptest/subdir.am b/bgpd/rfp-example/rfptest/subdir.am
index 9f6d33a855..1b5024a30b 100644
--- a/bgpd/rfp-example/rfptest/subdir.am
+++ b/bgpd/rfp-example/rfptest/subdir.am
@@ -6,7 +6,10 @@ if ENABLE_BGP_VNC
noinst_PROGRAMS += bgpd/rfp-example/rfptest/rfptest
endif
-bgpd_rfp_example_rfptest_rfptest_CFLAGS = -I$(top_srcdir)/bgpd/rfapi
+bgpd_rfp_example_rfptest_rfptest_CFLAGS = \
+ $(AM_CFLAGS) \
+ -I$(top_srcdir)/bgpd/rfapi \
+ # end
bgpd_rfp_example_rfptest_rfptest_SOURCES = \
bgpd/rfp-example/rfptest/rfptest.c \
# end
diff --git a/bgpd/subdir.am b/bgpd/subdir.am
index 07e71ba601..2c73f14594 100644
--- a/bgpd/subdir.am
+++ b/bgpd/subdir.am
@@ -211,20 +211,17 @@ noinst_HEADERS += \
bgpd_bgpd_SOURCES = bgpd/bgp_main.c
bgpd_bgp_btoa_SOURCES = bgpd/bgp_btoa.c
-bgpd_bgpd_CFLAGS = $(AM_CFLAGS)
-bgpd_bgp_btoa_CFLAGS = $(AM_CFLAGS)
-
# RFPLDADD is set in bgpd/rfp-example/librfp/subdir.am
bgpd_bgpd_LDADD = bgpd/libbgp.a $(RFPLDADD) lib/libfrr.la $(LIBCAP) $(LIBM) $(UST_LIBS)
bgpd_bgp_btoa_LDADD = bgpd/libbgp.a $(RFPLDADD) lib/libfrr.la $(LIBCAP) $(LIBM) $(UST_LIBS)
bgpd_bgpd_snmp_la_SOURCES = bgpd/bgp_snmp.c bgpd/bgp_mplsvpn_snmp.c
-bgpd_bgpd_snmp_la_CFLAGS = $(WERROR) $(SNMP_CFLAGS) -std=gnu11
+bgpd_bgpd_snmp_la_CFLAGS = $(AM_CFLAGS) $(SNMP_CFLAGS) -std=gnu11
bgpd_bgpd_snmp_la_LDFLAGS = -avoid-version -module -shared -export-dynamic
bgpd_bgpd_snmp_la_LIBADD = lib/libfrrsnmp.la
bgpd_bgpd_rpki_la_SOURCES = bgpd/bgp_rpki.c
-bgpd_bgpd_rpki_la_CFLAGS = $(WERROR) $(RTRLIB_CFLAGS)
+bgpd_bgpd_rpki_la_CFLAGS = $(AM_CFLAGS) $(RTRLIB_CFLAGS)
bgpd_bgpd_rpki_la_LDFLAGS = -avoid-version -module -shared -export-dynamic
bgpd_bgpd_rpki_la_LIBADD = $(RTRLIB_LIBS)