diff options
Diffstat (limited to 'bgpd')
| -rw-r--r-- | bgpd/bgp_bmp.c | 2 | ||||
| -rw-r--r-- | bgpd/bgp_ecommunity.c | 22 | ||||
| -rw-r--r-- | bgpd/bgp_fsm.c | 4 | ||||
| -rw-r--r-- | bgpd/bgp_fsm.h | 1 | ||||
| -rw-r--r-- | bgpd/bgp_mplsvpn.c | 68 | ||||
| -rw-r--r-- | bgpd/bgp_mplsvpn_snmp.c | 2 | ||||
| -rw-r--r-- | bgpd/bgp_nb_config.c | 7 | ||||
| -rw-r--r-- | bgpd/bgp_network.c | 1 | ||||
| -rw-r--r-- | bgpd/bgp_nht.c | 37 | ||||
| -rw-r--r-- | bgpd/bgp_nht.h | 2 | ||||
| -rw-r--r-- | bgpd/bgp_route.c | 2 | ||||
| -rw-r--r-- | bgpd/bgp_rpki.c | 2 | ||||
| -rw-r--r-- | bgpd/bgp_snmp.c | 2 | ||||
| -rw-r--r-- | bgpd/bgp_zebra.c | 3 | ||||
| -rw-r--r-- | bgpd/bgpd.c | 2 | ||||
| -rw-r--r-- | bgpd/bgpd.h | 1 | ||||
| -rw-r--r-- | bgpd/rfp-example/rfptest/subdir.am | 5 | ||||
| -rw-r--r-- | bgpd/subdir.am | 7 |
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) |
