diff options
author | vivek <vivek@cumulusnetworks.com> | 2018-08-28 00:13:30 +0200 |
---|---|---|
committer | vivek <vivek@cumulusnetworks.com> | 2018-08-28 00:13:30 +0200 |
commit | f190902f523abaa1035cbbb385387bc6c72dd1dc (patch) | |
tree | 9472de5fb49314eba45868ed7b66376f7329b2fe /bgpd | |
parent | bgpd, zebra: Fix warnings (diff) | |
parent | Merge pull request #2898 from donaldsharp/vrf_bitmap_is_whack (diff) | |
download | frr-f190902f523abaa1035cbbb385387bc6c72dd1dc.tar.xz frr-f190902f523abaa1035cbbb385387bc6c72dd1dc.zip |
Merge remote-tracking branch 'upstream/master' into evpn-extended-mobility
Conflicts:
zebra/zebra_vxlan.c
Diffstat (limited to 'bgpd')
-rw-r--r-- | bgpd/bgp_evpn.c | 17 | ||||
-rw-r--r-- | bgpd/bgp_evpn_private.h | 1 | ||||
-rw-r--r-- | bgpd/bgp_evpn_vty.c | 8 | ||||
-rw-r--r-- | bgpd/bgp_flowspec.c | 2 | ||||
-rw-r--r-- | bgpd/bgp_flowspec_vty.c | 10 | ||||
-rw-r--r-- | bgpd/bgp_network.c | 3 | ||||
-rw-r--r-- | bgpd/bgp_pbr.c | 13 | ||||
-rw-r--r-- | bgpd/bgp_route.c | 130 | ||||
-rw-r--r-- | bgpd/bgp_rpki.c | 129 | ||||
-rw-r--r-- | bgpd/bgp_table.h | 4 | ||||
-rw-r--r-- | bgpd/bgp_vty.c | 283 | ||||
-rw-r--r-- | bgpd/bgp_zebra.c | 8 | ||||
-rw-r--r-- | bgpd/bgp_zebra.h | 3 | ||||
-rw-r--r-- | bgpd/bgpd.c | 22 |
14 files changed, 432 insertions, 201 deletions
diff --git a/bgpd/bgp_evpn.c b/bgpd/bgp_evpn.c index fee2e89f8..a104a2e16 100644 --- a/bgpd/bgp_evpn.c +++ b/bgpd/bgp_evpn.c @@ -4897,6 +4897,23 @@ void bgp_evpn_derive_auto_rd(struct bgp *bgp, struct bgpevpn *vpn) } /* + * Lookup L3-VNI + */ +bool bgp_evpn_lookup_l3vni_l2vni_table(vni_t vni) +{ + struct list *inst = bm->bgp; + struct listnode *node; + struct bgp *bgp_vrf; + + for (ALL_LIST_ELEMENTS_RO(inst, node, bgp_vrf)) { + if (bgp_vrf->l3vni == vni) + return true; + } + + return false; +} + +/* * Lookup VNI. */ struct bgpevpn *bgp_evpn_lookup_vni(struct bgp *bgp, vni_t vni) diff --git a/bgpd/bgp_evpn_private.h b/bgpd/bgp_evpn_private.h index 8d71c3123..f0017f353 100644 --- a/bgpd/bgp_evpn_private.h +++ b/bgpd/bgp_evpn_private.h @@ -503,4 +503,5 @@ extern struct evpnes *bgp_evpn_lookup_es(struct bgp *bgp, esi_t *esi); extern struct evpnes *bgp_evpn_es_new(struct bgp *bgp, esi_t *esi, struct ipaddr *originator_ip); extern void bgp_evpn_es_free(struct bgp *bgp, struct evpnes *es); +extern bool bgp_evpn_lookup_l3vni_l2vni_table(vni_t vni); #endif /* _BGP_EVPN_PRIVATE_H */ diff --git a/bgpd/bgp_evpn_vty.c b/bgpd/bgp_evpn_vty.c index 3828ce216..b553cb42a 100644 --- a/bgpd/bgp_evpn_vty.c +++ b/bgpd/bgp_evpn_vty.c @@ -1888,6 +1888,14 @@ static struct bgpevpn *evpn_create_update_vni(struct bgp *bgp, vni_t vni) vpn = bgp_evpn_lookup_vni(bgp, vni); if (!vpn) { + /* Check if this L2VNI is already configured as L3VNI */ + if (bgp_evpn_lookup_l3vni_l2vni_table(vni)) { + flog_err(BGP_ERR_VNI, + "%u: Failed to create L2VNI %u, it is configured as L3VNI", + bgp->vrf_id, vni); + return NULL; + } + /* tenant vrf will be updated when we get local_vni_add from * zebra */ diff --git a/bgpd/bgp_flowspec.c b/bgpd/bgp_flowspec.c index 6695596c6..e29508bf3 100644 --- a/bgpd/bgp_flowspec.c +++ b/bgpd/bgp_flowspec.c @@ -148,7 +148,7 @@ int bgp_nlri_parse_flowspec(struct peer *peer, struct attr *attr, if (BGP_DEBUG(flowspec, FLOWSPEC)) { char return_string[BGP_FLOWSPEC_NLRI_STRING_MAX]; - char local_string[BGP_FLOWSPEC_NLRI_STRING_MAX * 2]; + char local_string[BGP_FLOWSPEC_NLRI_STRING_MAX*2+16]; char ec_string[BGP_FLOWSPEC_NLRI_STRING_MAX]; char *s = NULL; diff --git a/bgpd/bgp_flowspec_vty.c b/bgpd/bgp_flowspec_vty.c index f8c061320..31d2c540f 100644 --- a/bgpd/bgp_flowspec_vty.c +++ b/bgpd/bgp_flowspec_vty.c @@ -335,7 +335,7 @@ void route_vty_out_flowspec(struct vty *vty, struct prefix *p, struct listnode *node; struct bgp_pbr_match_entry *bpme; struct bgp_pbr_match *bpm; - int unit = 0; + bool list_began = false; struct list *list_bpm; list_bpm = list_new(); @@ -347,14 +347,14 @@ void route_vty_out_flowspec(struct vty *vty, struct prefix *p, if (listnode_lookup(list_bpm, bpm)) continue; listnode_add(list_bpm, bpm); - if (unit == 0) + if (!list_began) { vty_out(vty, " ("); - else + list_began = true; + } else vty_out(vty, ", "); vty_out(vty, "%s", bpm->ipset_name); - unit++; } - if (unit) + if (list_began) vty_out(vty, ")"); vty_out(vty, "\n"); list_delete_and_null(&list_bpm); diff --git a/bgpd/bgp_network.c b/bgpd/bgp_network.c index 0664fdfd1..22d5d35c8 100644 --- a/bgpd/bgp_network.c +++ b/bgpd/bgp_network.c @@ -672,7 +672,8 @@ static int bgp_listener(int sock, struct sockaddr *sa, socklen_t salen, listener->fd = sock; /* this socket needs a change of ns. record bgp back pointer */ - if (bgp->vrf_id != VRF_DEFAULT && vrf_is_mapped_on_netns(bgp->vrf_id)) + if (bgp->vrf_id != VRF_DEFAULT && vrf_is_mapped_on_netns( + vrf_lookup_by_id(bgp->vrf_id))) listener->bgp = bgp; memcpy(&listener->su, sa, salen); diff --git a/bgpd/bgp_pbr.c b/bgpd/bgp_pbr.c index 129c143a6..b182fde1e 100644 --- a/bgpd/bgp_pbr.c +++ b/bgpd/bgp_pbr.c @@ -1680,7 +1680,7 @@ static void bgp_pbr_dump_entry(struct bgp_pbr_filter *bpf, bool add) ? "!" : "", bpf->dscp->val); } - zlog_info("BGP: %s FS PBR from %s to %s, %s %s", + zlog_debug("BGP: %s FS PBR from %s to %s, %s %s", add ? "adding" : "removing", bpf->src == NULL ? "<all>" : prefix2str(bpf->src, bufsrc, sizeof(bufsrc)), @@ -1807,7 +1807,7 @@ static void bgp_pbr_policyroute_add_to_zebra_unit(struct bgp *bgp, bgp_pbr_match_alloc_intern); /* new, then self allocate ipset_name and unique */ - if (bpm && bpm->unique == 0) { + if (bpm->unique == 0) { bpm->unique = ++bgp_pbr_match_counter_unique; /* 0 value is forbidden */ sprintf(bpm->ipset_name, "match%p", bpm); @@ -1838,10 +1838,9 @@ static void bgp_pbr_policyroute_add_to_zebra_unit(struct bgp *bgp, temp2.src_port_max = src_port ? src_port->max_port : 0; temp2.dst_port_max = dst_port ? dst_port->max_port : 0; temp2.proto = bpf->protocol; - if (bpm) - bpme = hash_get(bpm->entry_hash, &temp2, - bgp_pbr_match_entry_alloc_intern); - if (bpme && bpme->unique == 0) { + bpme = hash_get(bpm->entry_hash, &temp2, + bgp_pbr_match_entry_alloc_intern); + if (bpme->unique == 0) { bpme->unique = ++bgp_pbr_match_entry_counter_unique; /* 0 value is forbidden */ bpme->backpointer = bpm; @@ -1853,7 +1852,7 @@ static void bgp_pbr_policyroute_add_to_zebra_unit(struct bgp *bgp, bpme_found = true; /* already installed */ - if (bpme_found && bpme) { + if (bpme_found) { struct bgp_info_extra *extra = bgp_info_extra_get(binfo); if (extra && extra->bgp_fs_pbr && diff --git a/bgpd/bgp_route.c b/bgpd/bgp_route.c index 041049d05..50c484d7d 100644 --- a/bgpd/bgp_route.c +++ b/bgpd/bgp_route.c @@ -38,6 +38,7 @@ #include "queue.h" #include "memory.h" #include "lib/json.h" +#include "lib_errors.h" #include "bgpd/bgpd.h" #include "bgpd/bgp_table.h" @@ -188,8 +189,24 @@ static void bgp_info_extra_free(struct bgp_info_extra **extra) if (e->parent) { struct bgp_info *bi = (struct bgp_info *)e->parent; - if (bi->net) - bi->net = bgp_unlock_node((struct bgp_node *)bi->net); + if (bi->net) { + /* FIXME: since multiple e may have the same e->parent + * and e->parent->net is holding a refcount for each + * of them, we need to do some fudging here. + * + * WARNING: if bi->net->lock drops to 0, bi may be + * freed as well (because bi->net was holding the + * last reference to bi) => write after free! + */ + unsigned refcount; + + bi = bgp_info_lock(bi); + refcount = bi->net->lock - 1; + bgp_unlock_node((struct bgp_node *)bi->net); + if (!refcount) + bi->net = NULL; + bgp_info_unlock(bi); + } bgp_info_unlock(e->parent); e->parent = NULL; } @@ -198,8 +215,7 @@ static void bgp_info_extra_free(struct bgp_info_extra **extra) bgp_unlock(e->bgp_orig); if ((*extra)->bgp_fs_pbr) - list_delete_all_node((*extra)->bgp_fs_pbr); - (*extra)->bgp_fs_pbr = NULL; + list_delete_and_null(&((*extra)->bgp_fs_pbr)); XFREE(MTYPE_BGP_ROUTE_EXTRA, *extra); *extra = NULL; @@ -338,14 +354,9 @@ static void bgp_pcount_adjust(struct bgp_node *rn, struct bgp_info *ri) /* slight hack, but more robust against errors. */ if (ri->peer->pcount[table->afi][table->safi]) ri->peer->pcount[table->afi][table->safi]--; - else { - zlog_warn( - "%s: Asked to decrement 0 prefix count for peer %s", - __func__, ri->peer->host); - zlog_backtrace(LOG_WARNING); - zlog_warn("%s: Please report to Quagga bugzilla", - __func__); - } + else + flog_err(LIB_ERR_DEVELOPMENT, + "Asked to decrement 0 prefix count for peer"); } else if (BGP_INFO_COUNTABLE(ri) && !CHECK_FLAG(ri->flags, BGP_INFO_COUNTED)) { SET_FLAG(ri->flags, BGP_INFO_COUNTED); @@ -1039,8 +1050,8 @@ static enum filter_type bgp_input_filter(struct peer *peer, struct prefix *p, #define FILTER_EXIST_WARN(F, f, filter) \ if (BGP_DEBUG(update, UPDATE_IN) && !(F##_IN(filter))) \ - zlog_warn("%s: Could not find configured input %s-list %s!", \ - peer->host, #f, F##_IN_NAME(filter)); + zlog_debug("%s: Could not find configured input %s-list %s!", \ + peer->host, #f, F##_IN_NAME(filter)); if (DISTRIBUTE_IN_NAME(filter)) { FILTER_EXIST_WARN(DISTRIBUTE, distribute, filter); @@ -1078,8 +1089,8 @@ static enum filter_type bgp_output_filter(struct peer *peer, struct prefix *p, #define FILTER_EXIST_WARN(F, f, filter) \ if (BGP_DEBUG(update, UPDATE_OUT) && !(F##_OUT(filter))) \ - zlog_warn("%s: Could not find configured output %s-list %s!", \ - peer->host, #f, F##_OUT_NAME(filter)); + zlog_debug("%s: Could not find configured output %s-list %s!", \ + peer->host, #f, F##_OUT_NAME(filter)); if (DISTRIBUTE_OUT_NAME(filter)) { FILTER_EXIST_WARN(DISTRIBUTE, distribute, filter); @@ -8187,7 +8198,6 @@ static int bgp_show_table(struct vty *vty, struct bgp *bgp, safi_t safi, vty_out(vty, " \"routeDistinguishers\" : {"); ++*json_header_depth; } - json_paths = json_object_new_object(); } if (use_json && rd) { @@ -8414,8 +8424,6 @@ static int bgp_show_table(struct vty *vty, struct bgp *bgp, safi_t safi, *total_cum = total_count; } if (use_json) { - if (json_paths) - json_object_free(json_paths); if (rd) { vty_out(vty, " }%s ", (is_last ? "" : ",")); } @@ -8573,9 +8581,19 @@ void route_vty_out_detail_header(struct vty *vty, struct bgp *bgp, int count = 0; int best = 0; int suppress = 0; + int accept_own = 0; + int route_filter_translated_v4 = 0; + int route_filter_v4 = 0; + int route_filter_translated_v6 = 0; + int route_filter_v6 = 0; + int llgr_stale = 0; + int no_llgr = 0; + int accept_own_nexthop = 0; + int blackhole = 0; int no_export = 0; int no_advertise = 0; int local_as = 0; + int no_peer = 0; int first = 1; int has_valid_label = 0; mpls_label_t label = 0; @@ -8652,12 +8670,41 @@ void route_vty_out_detail_header(struct vty *vty, struct bgp *bgp, } else vty_out(vty, ", no best path"); - if (no_advertise) - vty_out(vty, ", not advertised to any peer"); + if (accept_own) + vty_out(vty, + ", accept own local route exported and imported in different VRF"); + else if (route_filter_translated_v4) + vty_out(vty, + ", mark translated RTs for VPNv4 route filtering"); + else if (route_filter_v4) + vty_out(vty, + ", attach RT as-is for VPNv4 route filtering"); + else if (route_filter_translated_v6) + vty_out(vty, + ", mark translated RTs for VPNv6 route filtering"); + else if (route_filter_v6) + vty_out(vty, + ", attach RT as-is for VPNv6 route filtering"); + else if (llgr_stale) + vty_out(vty, + ", mark routes to be retained for a longer time. Requeres support for Long-lived BGP Graceful Restart"); + else if (no_llgr) + vty_out(vty, + ", mark routes to not be treated according to Long-lived BGP Graceful Restart operations"); + else if (accept_own_nexthop) + vty_out(vty, + ", accept local nexthop"); + else if (blackhole) + vty_out(vty, ", inform peer to blackhole prefix"); else if (no_export) vty_out(vty, ", not advertised to EBGP peer"); + else if (no_advertise) + vty_out(vty, ", not advertised to any peer"); else if (local_as) vty_out(vty, ", not advertised outside local AS"); + else if (no_peer) + vty_out(vty, + ", inform EBGP peer not to advertise to their EBGP peers"); if (suppress) vty_out(vty, @@ -9018,6 +9065,10 @@ DEFUN (show_ip_bgp, |prefix-list WORD\ |filter-list WORD\ |statistics\ + |community <AA:NN|local-AS|no-advertise|no-export|graceful-shutdown\ + no-peer|blackhole|llgr-stale|no-llgr|accept-own|accept-own-nexthop\ + route-filter-v6|route-filter-v4|route-filter-translated-v6|\ + route-filter-translated-v4> [exact-match]\ |community-list <(1-500)|WORD> [exact-match]\ |A.B.C.D/M longer-prefixes\ |X:X::X:X/M longer-prefixes\ @@ -9037,6 +9088,23 @@ DEFUN (show_ip_bgp, "Display routes conforming to the filter-list\n" "Regular expression access list name\n" "BGP RIB advertisement statistics\n" + "Display routes matching the communities\n" + COMMUNITY_AANN_STR + "Do not send outside local AS (well-known community)\n" + "Do not advertise to any peer (well-known community)\n" + "Do not export to next AS (well-known community)\n" + "Graceful shutdown (well-known community)\n" + "Do not export to any peer (well-known community)\n" + "Inform EBGP peers to blackhole traffic to prefix (well-known community)\n" + "Staled Long-lived Graceful Restart VPN route (well-known community)\n" + "Removed because Long-lived Graceful Restart was not enabled for VPN route (well-known community)\n" + "Should accept local VPN route if exported and imported into different VRF (well-known community)\n" + "Should accept VPN route with local nexthop (well-known community)\n" + "RT VPNv6 route filtering (well-known community)\n" + "RT VPNv4 route filtering (well-known community)\n" + "RT translated VPNv6 route filtering (well-known community)\n" + "RT translated VPNv4 route filtering (well-known community)\n" + "Exact match of the communities\n" "Display routes matching the community-list\n" "community-list number\n" "community-list name\n" @@ -9797,8 +9865,6 @@ static int bgp_peer_count_walker(struct thread *t) pc->count[PCOUNT_ADJ_IN]++; for (ri = rn->info; ri; ri = ri->next) { - char buf[SU_ADDRSTRLEN]; - if (ri->peer != peer) continue; @@ -9820,22 +9886,12 @@ static int bgp_peer_count_walker(struct thread *t) if (CHECK_FLAG(ri->flags, BGP_INFO_COUNTED)) { pc->count[PCOUNT_COUNTED]++; if (CHECK_FLAG(ri->flags, BGP_INFO_UNUSEABLE)) - zlog_warn( - "%s [pcount] %s/%d is counted but flags 0x%x", - peer->host, - inet_ntop(rn->p.family, - &rn->p.u.prefix, buf, - SU_ADDRSTRLEN), - rn->p.prefixlen, ri->flags); + flog_err(LIB_ERR_DEVELOPMENT, + "Attempting to count but flags say it is unusable"); } else { if (!CHECK_FLAG(ri->flags, BGP_INFO_UNUSEABLE)) - zlog_warn( - "%s [pcount] %s/%d not counted but flags 0x%x", - peer->host, - inet_ntop(rn->p.family, - &rn->p.u.prefix, buf, - SU_ADDRSTRLEN), - rn->p.prefixlen, ri->flags); + flog_err(LIB_ERR_DEVELOPMENT, + "Not counted but flags say we should"); } } } diff --git a/bgpd/bgp_rpki.c b/bgpd/bgp_rpki.c index 52c5dc5e9..82b268c31 100644 --- a/bgpd/bgp_rpki.c +++ b/bgpd/bgp_rpki.c @@ -47,6 +47,7 @@ #include "bgpd/bgp_attr.h" #include "bgpd/bgp_aspath.h" #include "bgpd/bgp_route.h" +#include "lib/network.h" #include "lib/thread.h" #include "rtrlib/rtrlib.h" #include "rtrlib/rtr_mgr.h" @@ -131,12 +132,14 @@ static route_map_result_t route_match(void *rule, const struct prefix *prefix, static void *route_match_compile(const char *arg); static void revalidate_bgp_node(struct bgp_node *bgp_node, afi_t afi, safi_t safi); +static void revalidate_all_routes(void); static struct rtr_mgr_config *rtr_config; static struct list *cache_list; static int rtr_is_running; static int rtr_is_stopping; static int rtr_is_starting; +static _Atomic int rtr_update_overflow; static int rpki_debug; static unsigned int polling_period; static unsigned int expire_interval; @@ -229,7 +232,7 @@ static void *route_match_compile(const char *arg) { int *rpki_status; - rpki_status = XMALLOC(MTYPE_ROUTE_MAP_COMPILED, sizeof(uint8_t)); + rpki_status = XMALLOC(MTYPE_ROUTE_MAP_COMPILED, sizeof(int)); if (strcmp(arg, "valid") == 0) *rpki_status = RPKI_VALID; @@ -345,6 +348,19 @@ static int bgpd_sync_callback(struct thread *thread) thread_add_read(bm->master, bgpd_sync_callback, NULL, rpki_sync_socket_bgpd, NULL); + + if (atomic_load_explicit(&rtr_update_overflow, memory_order_seq_cst)) { + while (read(rpki_sync_socket_bgpd, &rec, + sizeof(struct pfx_record)) + != -1) + ; + + atomic_store_explicit(&rtr_update_overflow, 0, + memory_order_seq_cst); + revalidate_all_routes(); + return 0; + } + int retval = read(rpki_sync_socket_bgpd, &rec, sizeof(struct pfx_record)); if (retval != sizeof(struct pfx_record)) { @@ -356,26 +372,36 @@ static int bgpd_sync_callback(struct thread *thread) afi_t afi = (rec.prefix.ver == LRTR_IPV4) ? AFI_IP : AFI_IP6; for (ALL_LIST_ELEMENTS_RO(bm->bgp, node, bgp)) { - safi_t safi; + struct peer *peer; + struct listnode *peer_listnode; + + for (ALL_LIST_ELEMENTS_RO(bgp->peer, peer_listnode, peer)) { + safi_t safi; - for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++) { - if (!bgp->rib[afi][safi]) - continue; + for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++) { + if (!peer->bgp->rib[afi][safi]) + continue; - struct list *matches = list_new(); + struct list *matches = list_new(); - matches->del = (void (*)(void *))bgp_unlock_node; + matches->del = + (void (*)(void *))bgp_unlock_node; - bgp_table_range_lookup(bgp->rib[afi][safi], prefix, - rec.max_len, matches); + bgp_table_range_lookup( + peer->bgp->rib[afi][safi], prefix, + rec.max_len, matches); - struct bgp_node *bgp_node; + struct bgp_node *bgp_node; + struct listnode *bgp_listnode; - for (ALL_LIST_ELEMENTS_RO(matches, node, bgp_node)) - revalidate_bgp_node(bgp_node, afi, safi); + for (ALL_LIST_ELEMENTS_RO(matches, bgp_listnode, + bgp_node)) + revalidate_bgp_node(bgp_node, afi, + safi); - list_delete_and_null(&matches); + list_delete_and_null(&matches); + } } } @@ -398,14 +424,13 @@ static void revalidate_bgp_node(struct bgp_node *bgp_node, afi_t afi, label = bgp_info->extra->label; num_labels = bgp_info->extra->num_labels; } - ret = bgp_update(ain->peer, &bgp_node->p, 0, ain->attr, afi, - safi, ZEBRA_ROUTE_BGP, BGP_ROUTE_NORMAL, NULL, - label, num_labels, 1, NULL); + ret = bgp_update(ain->peer, &bgp_node->p, ain->addpath_rx_id, + ain->attr, afi, safi, ZEBRA_ROUTE_BGP, + BGP_ROUTE_NORMAL, NULL, label, num_labels, 1, + NULL); - if (ret < 0) { - bgp_unlock_node(bgp_node); + if (ret < 0) return; - } } } @@ -413,25 +438,23 @@ static void revalidate_all_routes(void) { struct bgp *bgp; struct listnode *node; - struct bgp_node *bgp_node; for (ALL_LIST_ELEMENTS_RO(bm->bgp, node, bgp)) { - for (size_t i = 0; i < 2; i++) { - safi_t safi; - afi_t afi = (i == 0) ? AFI_IP : AFI_IP6; + struct peer *peer; + struct listnode *peer_listnode; - for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++) { - if (!bgp->rib[afi][safi]) - continue; + for (ALL_LIST_ELEMENTS_RO(bgp->peer, peer_listnode, peer)) { + + for (size_t i = 0; i < 2; i++) { + safi_t safi; + afi_t afi = (i == 0) ? AFI_IP : AFI_IP6; - for (bgp_node = - bgp_table_top(bgp->rib[afi][safi]); - bgp_node; - bgp_node = bgp_route_next(bgp_node)) { - if (bgp_node->info != NULL) { - revalidate_bgp_node(bgp_node, - afi, safi); - } + for (safi = SAFI_UNICAST; safi < SAFI_MAX; + safi++) { + if (!peer->bgp->rib[afi][safi]) + continue; + + bgp_soft_reconfig_in(peer, afi, safi); } } } @@ -442,28 +465,53 @@ static void rpki_update_cb_sync_rtr(struct pfx_table *p __attribute__((unused)), const struct pfx_record rec, const bool added __attribute__((unused))) { - if (rtr_is_stopping || rtr_is_starting) + if (rtr_is_stopping || rtr_is_starting + || atomic_load_explicit(&rtr_update_overflow, memory_order_seq_cst)) return; int retval = write(rpki_sync_socket_rtr, &rec, sizeof(struct pfx_record)); - if (retval != sizeof(struct pfx_record)) + if (retval == -1 && (errno == EAGAIN || errno == EWOULDBLOCK)) + atomic_store_explicit(&rtr_update_overflow, 1, + memory_order_seq_cst); + + else if (retval != sizeof(struct pfx_record)) RPKI_DEBUG("Could not write to rpki_sync_socket_rtr"); } static void rpki_init_sync_socket(void) { int fds[2]; + const char *msg; RPKI_DEBUG("initializing sync socket"); if (socketpair(PF_LOCAL, SOCK_DGRAM, 0, fds) != 0) { - RPKI_DEBUG("Could not open rpki sync socket"); - return; + msg = "could not open rpki sync socketpair"; + goto err; } rpki_sync_socket_rtr = fds[0]; rpki_sync_socket_bgpd = fds[1]; + + if (set_nonblocking(rpki_sync_socket_rtr) != 0) { + msg = "could not set rpki_sync_socket_rtr to non blocking"; + goto err; + } + + if (set_nonblocking(rpki_sync_socket_bgpd) != 0) { + msg = "could not set rpki_sync_socket_bgpd to non blocking"; + goto err; + } + + thread_add_read(bm->master, bgpd_sync_callback, NULL, rpki_sync_socket_bgpd, NULL); + + return; + +err: + zlog_err("RPKI: %s", msg); + abort(); + } static int bgp_rpki_init(struct thread_master *master) @@ -514,6 +562,7 @@ static int start(void) rtr_is_stopping = 0; rtr_is_starting = 1; + rtr_update_overflow = 0; if (list_isempty(cache_list)) { RPKI_DEBUG( @@ -1210,10 +1259,10 @@ DEFUN_NOSH (rpki_exit, "exit", "Exit rpki configuration and restart rpki session\n") { - int ret = reset(false); + reset(false); vty->node = CONFIG_NODE; - return ret == SUCCESS ? CMD_SUCCESS : CMD_WARNING; + return CMD_SUCCESS; } DEFUN_NOSH (rpki_quit, diff --git a/bgpd/bgp_table.h b/bgpd/bgp_table.h index f7eac0954..60c2cbd4a 100644 --- a/bgpd/bgp_table.h +++ b/bgpd/bgp_table.h @@ -128,9 +128,9 @@ static inline struct bgp_node *bgp_node_parent_nolock(struct bgp_node *node) /* * bgp_unlock_node */ -static inline struct bgp_node *bgp_unlock_node(struct bgp_node *node) +static inline void bgp_unlock_node(struct bgp_node *node) { - return (struct bgp_node *)route_unlock_node(bgp_node_to_rnode(node)); + route_unlock_node(bgp_node_to_rnode(node)); } /* diff --git a/bgpd/bgp_vty.c b/bgpd/bgp_vty.c index fda458cb8..1460a2621 100644 --- a/bgpd/bgp_vty.c +++ b/bgpd/bgp_vty.c @@ -2019,7 +2019,7 @@ DEFUN (no_bgp_fast_external_failover, } /* "bgp enforce-first-as" configuration. */ -#if CONFDATE > 20180517 +#if CONFDATE > 20190517 CPP_NOTICE("bgpd: remove deprecated '[no] bgp enforce-first-as' commands") #endif @@ -10995,7 +10995,7 @@ DEFUN (show_ip_bgp_attr_info, } static int bgp_show_route_leak_vty(struct vty *vty, const char *name, - afi_t afi, safi_t safi) + afi_t afi, safi_t safi, uint8_t use_json) { struct bgp *bgp; struct listnode *node; @@ -11004,64 +11004,148 @@ static int bgp_show_route_leak_vty(struct vty *vty, const char *name, char *ecom_str; vpn_policy_direction_t dir; - if (name) { - bgp = bgp_lookup_by_name(name); + if (use_json) { + json_object *json = NULL; + json_object *json_import_vrfs = NULL; + json_object *json_export_vrfs = NULL; + + json = json_object_new_object(); + + /* Provide context for the block */ + json_object_string_add(json, "vrf", name ? name : "default"); + json_object_string_add(json, "afiSafi", + afi_safi_print(afi, safi)); + + bgp = name ? bgp_lookup_by_name(name) : bgp_get_default(); + if (!bgp) { - vty_out(vty, "%% No such BGP instance exist\n"); + json_object_boolean_true_add(json, + "bgpNoSuchInstance"); + vty_out(vty, "%s\n", + json_object_to_json_string_ext( + json, + JSON_C_TO_STRING_PRETTY)); + json_object_free(json); + return CMD_WARNING; } + + if (!CHECK_FLAG(bgp->af_flags[afi][safi], + BGP_CONFIG_VRF_TO_VRF_IMPORT)) { + json_object_string_add(json, "importFromVrfs", "none"); + json_object_string_add(json, "importRts", "none"); + } else { + json_import_vrfs = json_object_new_array(); + + for (ALL_LIST_ELEMENTS_RO( + bgp->vpn_policy[afi].import_vrf, + node, vname)) + json_object_array_add(json_import_vrfs, + json_object_new_string(vname)); + + dir = BGP_VPN_POLICY_DIR_FROMVPN; + ecom_str = ecommunity_ecom2str( + bgp->vpn_policy[afi].rtlist[dir], + ECOMMUNITY_FORMAT_ROUTE_MAP, 0); + json_object_object_add(json, "importFromVrfs", + json_import_vrfs); + json_object_string_add(json, "importRts", ecom_str); + + XFREE(MTYPE_ECOMMUNITY_STR, ecom_str); + } + + if (!CHECK_FLAG(bgp->af_flags[afi][safi], + BGP_CONFIG_VRF_TO_VRF_EXPORT)) { + json_object_string_add(json, "exportToVrfs", "none"); + json_object_string_add(json, "routeDistinguisher", + "none"); + json_object_string_add(json, "exportRts", "none"); + } else { + json_export_vrfs = json_object_new_array(); + + for (ALL_LIST_ELEMENTS_RO( + bgp->vpn_policy[afi].export_vrf, + node, vname)) + json_object_array_add(json_export_vrfs, + json_object_new_string(vname)); + json_object_object_add(json, "exportToVrfs", + json_export_vrfs); + json_object_string_add(json, "routeDistinguisher", + prefix_rd2str(&bgp->vpn_policy[afi].tovpn_rd, + buf1, RD_ADDRSTRLEN)); + + dir = BGP_VPN_POLICY_DIR_TOVPN; + ecom_str = ecommunity_ecom2str( + bgp->vpn_policy[afi].rtlist[dir], + ECOMMUNITY_FORMAT_ROUTE_MAP, 0); + json_object_string_add(json, "exportRts", ecom_str); + + XFREE(MTYPE_ECOMMUNITY_STR, ecom_str); + } + + vty_out(vty, "%s\n", + json_object_to_json_string_ext(json, + JSON_C_TO_STRING_PRETTY)); + json_object_free(json); + } else { - bgp = bgp_get_default(); + bgp = name ? bgp_lookup_by_name(name) : bgp_get_default(); + if (!bgp) { - vty_out(vty, - "%% Default BGP instance does not exist\n"); + vty_out(vty, "%% No such BGP instance exist\n"); return CMD_WARNING; } - } - if (!CHECK_FLAG(bgp->af_flags[afi][safi], - BGP_CONFIG_VRF_TO_VRF_IMPORT)) { - vty_out(vty, - "This VRF is not importing %s routes from any other VRF\n", - afi_safi_print(afi, safi)); - } else { - vty_out(vty, - "This VRF is importing %s routes from the following VRFs:\n", - afi_safi_print(afi, safi)); - for (ALL_LIST_ELEMENTS_RO(bgp->vpn_policy[afi].import_vrf, node, - vname)) { - vty_out(vty, " %s\n", vname); + if (!CHECK_FLAG(bgp->af_flags[afi][safi], + BGP_CONFIG_VRF_TO_VRF_IMPORT)) + vty_out(vty, + "This VRF is not importing %s routes from any other VRF\n", + afi_safi_print(afi, safi)); + else { + vty_out(vty, + "This VRF is importing %s routes from the following VRFs:\n", + afi_safi_print(afi, safi)); + + for (ALL_LIST_ELEMENTS_RO( + bgp->vpn_policy[afi].import_vrf, + node, vname)) + vty_out(vty, " %s\n", vname); + + dir = BGP_VPN_POLICY_DIR_FROMVPN; + ecom_str = ecommunity_ecom2str( + bgp->vpn_policy[afi].rtlist[dir], + ECOMMUNITY_FORMAT_ROUTE_MAP, 0); + vty_out(vty, "Import RT(s): %s\n", ecom_str); + + XFREE(MTYPE_ECOMMUNITY_STR, ecom_str); } - dir = BGP_VPN_POLICY_DIR_FROMVPN; - ecom_str = ecommunity_ecom2str( - bgp->vpn_policy[afi].rtlist[dir], - ECOMMUNITY_FORMAT_ROUTE_MAP, 0); - vty_out(vty, "Import RT(s): %s\n", ecom_str); - XFREE(MTYPE_ECOMMUNITY_STR, ecom_str); - } - if (!CHECK_FLAG(bgp->af_flags[afi][safi], - BGP_CONFIG_VRF_TO_VRF_EXPORT)) { - vty_out(vty, - "This VRF is not exporting %s routes to any other VRF\n", + if (!CHECK_FLAG(bgp->af_flags[afi][safi], + BGP_CONFIG_VRF_TO_VRF_EXPORT)) + vty_out(vty, + "This VRF is not exporting %s routes to any other VRF\n", afi_safi_print(afi, safi)); - } else { - vty_out(vty, - "This VRF is exporting %s routes to the following VRFs:\n", + else { + vty_out(vty, + "This VRF is exporting %s routes to the following VRFs:\n", afi_safi_print(afi, safi)); - for (ALL_LIST_ELEMENTS_RO(bgp->vpn_policy[afi].export_vrf, node, - vname)) { - vty_out(vty, " %s\n", vname); + + for (ALL_LIST_ELEMENTS_RO( + bgp->vpn_policy[afi].export_vrf, + node, vname)) + vty_out(vty, " %s\n", vname); + + vty_out(vty, "RD: %s\n", + prefix_rd2str(&bgp->vpn_policy[afi].tovpn_rd, + buf1, RD_ADDRSTRLEN)); + + dir = BGP_VPN_POLICY_DIR_TOVPN; + ecom_str = ecommunity_ecom2str( + bgp->vpn_policy[afi].rtlist[dir], + ECOMMUNITY_FORMAT_ROUTE_MAP, 0); + vty_out(vty, "Export RT: %s\n", ecom_str); + XFREE(MTYPE_ECOMMUNITY_STR, ecom_str); } - vty_out(vty, "RD: %s\n", - prefix_rd2str(&bgp->vpn_policy[afi].tovpn_rd, - buf1, RD_ADDRSTRLEN)); - dir = BGP_VPN_POLICY_DIR_TOVPN; - ecom_str = ecommunity_ecom2str( - bgp->vpn_policy[afi].rtlist[dir], - ECOMMUNITY_FORMAT_ROUTE_MAP, 0); - vty_out(vty, "Emport RT: %s\n", ecom_str); - XFREE(MTYPE_ECOMMUNITY_STR, ecom_str); } return CMD_SUCCESS; @@ -11069,20 +11153,22 @@ static int bgp_show_route_leak_vty(struct vty *vty, const char *name, /* "show [ip] bgp route-leak" command. */ DEFUN (show_ip_bgp_route_leak, - show_ip_bgp_route_leak_cmd, - "show [ip] bgp [<view|vrf> VIEWVRFNAME] ["BGP_AFI_CMD_STR" ["BGP_SAFI_CMD_STR"]] route-leak", - SHOW_STR - IP_STR - BGP_STR - BGP_INSTANCE_HELP_STR - BGP_AFI_HELP_STR - BGP_SAFI_HELP_STR - "Route leaking information\n") + show_ip_bgp_route_leak_cmd, + "show [ip] bgp [<view|vrf> VIEWVRFNAME] ["BGP_AFI_CMD_STR" ["BGP_SAFI_CMD_STR"]] route-leak [json]", + SHOW_STR + IP_STR + BGP_STR + BGP_INSTANCE_HELP_STR + BGP_AFI_HELP_STR + BGP_SAFI_HELP_STR + "Route leaking information\n" + JSON_STR) { char *vrf = NULL; afi_t afi = AFI_MAX; safi_t safi = SAFI_MAX; + uint8_t uj = use_json(argc, argv); int idx = 0; /* show [ip] bgp */ @@ -11110,7 +11196,7 @@ DEFUN (show_ip_bgp_route_leak, return CMD_WARNING; } - return bgp_show_route_leak_vty(vty, vrf, afi, safi); + return bgp_show_route_leak_vty(vty, vrf, afi, safi, uj); } static void bgp_show_all_instances_updgrps_vty(struct vty *vty, afi_t afi, @@ -11462,7 +11548,7 @@ DEFUN (bgp_redistribute_ipv4, } bgp_redist_add(bgp, AFI_IP, type, 0); - return bgp_redistribute_set(bgp, AFI_IP, type, 0); + return bgp_redistribute_set(bgp, AFI_IP, type, 0, false); } ALIAS_HIDDEN( @@ -11483,6 +11569,7 @@ DEFUN (bgp_redistribute_ipv4_rmap, int idx_word = 3; int type; struct bgp_redist *red; + bool changed; type = proto_redistnum(AFI_IP, argv[idx_protocol]->text); if (type < 0) { @@ -11491,8 +11578,8 @@ DEFUN (bgp_redistribute_ipv4_rmap, } red = bgp_redist_add(bgp, AFI_IP, type, 0); - bgp_redistribute_rmap_set(red, argv[idx_word]->arg); - return bgp_redistribute_set(bgp, AFI_IP, type, 0); + changed = bgp_redistribute_rmap_set(red, argv[idx_word]->arg); + return bgp_redistribute_set(bgp, AFI_IP, type, 0, changed); } ALIAS_HIDDEN( @@ -11516,6 +11603,7 @@ DEFUN (bgp_redistribute_ipv4_metric, int type; uint32_t metric; struct bgp_redist *red; + bool changed; type = proto_redistnum(AFI_IP, argv[idx_protocol]->text); if (type < 0) { @@ -11525,8 +11613,8 @@ DEFUN (bgp_redistribute_ipv4_metric, metric = strtoul(argv[idx_number]->arg, NULL, 10); red = bgp_redist_add(bgp, AFI_IP, type, 0); - bgp_redistribute_metric_set(bgp, red, AFI_IP, type, metric); - return bgp_redistribute_set(bgp, AFI_IP, type, 0); + changed = bgp_redistribute_metric_set(bgp, red, AFI_IP, type, metric); + return bgp_redistribute_set(bgp, AFI_IP, type, 0, changed); } ALIAS_HIDDEN( @@ -11553,6 +11641,7 @@ DEFUN (bgp_redistribute_ipv4_rmap_metric, int type; uint32_t metric; struct bgp_redist *red; + bool changed; type = proto_redistnum(AFI_IP, argv[idx_protocol]->text); if (type < 0) { @@ -11562,9 +11651,9 @@ DEFUN (bgp_redistribute_ipv4_rmap_metric, metric = strtoul(argv[idx_number]->arg, NULL, 10); red = bgp_redist_add(bgp, AFI_IP, type, 0); - bgp_redistribute_rmap_set(red, argv[idx_word]->arg); - bgp_redistribute_metric_set(bgp, red, AFI_IP, type, metric); - return bgp_redistribute_set(bgp, AFI_IP, type, 0); + changed = bgp_redistribute_rmap_set(red, argv[idx_word]->arg); + changed |= bgp_redistribute_metric_set(bgp, red, AFI_IP, type, metric); + return bgp_redistribute_set(bgp, AFI_IP, type, 0, changed); } ALIAS_HIDDEN( @@ -11595,6 +11684,7 @@ DEFUN (bgp_redistribute_ipv4_metric_rmap, int type; uint32_t metric; struct bgp_redist *red; + bool changed; type = proto_redistnum(AFI_IP, argv[idx_protocol]->text); if (type < 0) { @@ -11604,9 +11694,9 @@ DEFUN (bgp_redistribute_ipv4_metric_rmap, metric = strtoul(argv[idx_number]->arg, NULL, 10); red = bgp_redist_add(bgp, AFI_IP, type, 0); - bgp_redistribute_metric_set(bgp, red, AFI_IP, type, metric); - bgp_redistribute_rmap_set(red, argv[idx_word]->arg); - return bgp_redistribute_set(bgp, AFI_IP, type, 0); + changed = bgp_redistribute_metric_set(bgp, red, AFI_IP, type, metric); + changed |= bgp_redistribute_rmap_set(red, argv[idx_word]->arg); + return bgp_redistribute_set(bgp, AFI_IP, type, 0, changed); } ALIAS_HIDDEN( @@ -11642,7 +11732,7 @@ DEFUN (bgp_redistribute_ipv4_ospf, protocol = ZEBRA_ROUTE_TABLE; bgp_redist_add(bgp, AFI_IP, protocol, instance); - return bgp_redistribute_set(bgp, AFI_IP, protocol, instance); + return bgp_redistribute_set(bgp, AFI_IP, protocol, instance, false); } ALIAS_HIDDEN(bgp_redistribute_ipv4_ospf, bgp_redistribute_ipv4_ospf_hidden_cmd, @@ -11669,6 +11759,7 @@ DEFUN (bgp_redistribute_ipv4_ospf_rmap, struct bgp_redist *red; unsigned short instance; int protocol; + bool changed; if (strncmp(argv[idx_ospf_table]->arg, "o", 1) == 0) protocol = ZEBRA_ROUTE_OSPF; @@ -11677,8 +11768,8 @@ DEFUN (bgp_redistribute_ipv4_ospf_rmap, instance = strtoul(argv[idx_number]->arg, NULL, 10); red = bgp_redist_add(bgp, AFI_IP, protocol, instance); - bgp_redistribute_rmap_set(red, argv[idx_word]->arg); - return bgp_redistribute_set(bgp, AFI_IP, protocol, instance); + changed = bgp_redistribute_rmap_set(red, argv[idx_word]->arg); + return bgp_redistribute_set(bgp, AFI_IP, protocol, instance, changed); } ALIAS_HIDDEN(bgp_redistribute_ipv4_ospf_rmap, @@ -11709,6 +11800,7 @@ DEFUN (bgp_redistribute_ipv4_ospf_metric, struct bgp_redist *red; unsigned short instance; int protocol; + bool changed; if (strncmp(argv[idx_ospf_table]->arg, "o", 1) == 0) protocol = ZEBRA_ROUTE_OSPF; @@ -11719,8 +11811,9 @@ DEFUN (bgp_redistribute_ipv4_ospf_metric, metric = strtoul(argv[idx_number_2]->arg, NULL, 10); red = bgp_redist_add(bgp, AFI_IP, protocol, instance); - bgp_redistribute_metric_set(bgp, red, AFI_IP, protocol, metric); - return bgp_redistribute_set(bgp, AFI_IP, protocol, instance); + changed = bgp_redistribute_metric_set(bgp, red, AFI_IP, protocol, + metric); + return bgp_redistribute_set(bgp, AFI_IP, protocol, instance, changed); } ALIAS_HIDDEN(bgp_redistribute_ipv4_ospf_metric, @@ -11754,6 +11847,7 @@ DEFUN (bgp_redistribute_ipv4_ospf_rmap_metric, struct bgp_redist *red; unsigned short instance; int protocol; + bool changed; if (strncmp(argv[idx_ospf_table]->arg, "o", 1) == 0) protocol = ZEBRA_ROUTE_OSPF; @@ -11764,9 +11858,10 @@ DEFUN (bgp_redistribute_ipv4_ospf_rmap_metric, metric = strtoul(argv[idx_number_2]->arg, NULL, 10); red = bgp_redist_add(bgp, AFI_IP, protocol, instance); - bgp_redistribute_rmap_set(red, argv[idx_word]->arg); - bgp_redistribute_metric_set(bgp, red, AFI_IP, protocol, metric); - return bgp_redistribute_set(bgp, AFI_IP, protocol, instance); + changed = bgp_redistribute_rmap_set(red, argv[idx_word]->arg); + changed |= bgp_redistribute_metric_set(bgp, red, AFI_IP, protocol, + metric); + return bgp_redistribute_set(bgp, AFI_IP, protocol, instance, changed); } ALIAS_HIDDEN( @@ -11803,6 +11898,7 @@ DEFUN (bgp_redistribute_ipv4_ospf_metric_rmap, struct bgp_redist *red; unsigned short instance; int protocol; + bool changed; if (strncmp(argv[idx_ospf_table]->arg, "o", 1) == 0) protocol = ZEBRA_ROUTE_OSPF; @@ -11813,9 +11909,10 @@ DEFUN (bgp_redistribute_ipv4_ospf_metric_rmap, metric = strtoul(argv[idx_number_2]->arg, NULL, 10); red = bgp_redist_add(bgp, AFI_IP, protocol, instance); - bgp_redistribute_metric_set(bgp, red, AFI_IP, protocol, metric); - bgp_redistribute_rmap_set(red, argv[idx_word]->arg); - return bgp_redistribute_set(bgp, AFI_IP, protocol, instance); + changed = bgp_redistribute_metric_set(bgp, red, AFI_IP, protocol, + metric); + changed |= bgp_redistribute_rmap_set(red, argv[idx_word]->arg); + return bgp_redistribute_set(bgp, AFI_IP, protocol, instance, changed); } ALIAS_HIDDEN( @@ -11923,7 +12020,7 @@ DEFUN (bgp_redistribute_ipv6, } bgp_redist_add(bgp, AFI_IP6, type, 0); - return bgp_redistribute_set(bgp, AFI_IP6, type, 0); + return bgp_redistribute_set(bgp, AFI_IP6, type, 0, false); } DEFUN (bgp_redistribute_ipv6_rmap, @@ -11939,6 +12036,7 @@ DEFUN (bgp_redistribute_ipv6_rmap, int idx_word = 3; int type; struct bgp_redist *red; + bool changed; type = proto_redistnum(AFI_IP6, argv[idx_protocol]->text); if (type < 0) { @@ -11947,8 +12045,8 @@ DEFUN (bgp_redistribute_ipv6_rmap, } red = bgp_redist_add(bgp, AFI_IP6, type, 0); - bgp_redistribute_rmap_set(red, argv[idx_word]->arg); - return bgp_redistribute_set(bgp, AFI_IP6, type, 0); + changed = bgp_redistribute_rmap_set(red, argv[idx_word]->arg); + return bgp_redistribute_set(bgp, AFI_IP6, type, 0, changed); } DEFUN (bgp_redistribute_ipv6_metric, @@ -11965,6 +12063,7 @@ DEFUN (bgp_redistribute_ipv6_metric, int type; uint32_t metric; struct bgp_redist *red; + bool changed; type = proto_redistnum(AFI_IP6, argv[idx_protocol]->text); if (type < 0) { @@ -11974,8 +12073,8 @@ DEFUN (bgp_redistribute_ipv6_metric, metric = strtoul(argv[idx_number]->arg, NULL, 10); red = bgp_redist_add(bgp, AFI_IP6, type, 0); - bgp_redistribute_metric_set(bgp, red, AFI_IP6, type, metric); - return bgp_redistribute_set(bgp, AFI_IP6, type, 0); + changed = bgp_redistribute_metric_set(bgp, red, AFI_IP6, type, metric); + return bgp_redistribute_set(bgp, AFI_IP6, type, 0, changed); } DEFUN (bgp_redistribute_ipv6_rmap_metric, @@ -11995,6 +12094,7 @@ DEFUN (bgp_redistribute_ipv6_rmap_metric, int type; uint32_t metric; struct bgp_redist *red; + bool changed; type = proto_redistnum(AFI_IP6, argv[idx_protocol]->text); if (type < 0) { @@ -12004,9 +12104,10 @@ DEFUN (bgp_redistribute_ipv6_rmap_metric, metric = strtoul(argv[idx_number]->arg, NULL, 10); red = bgp_redist_add(bgp, AFI_IP6, type, 0); - bgp_redistribute_rmap_set(red, argv[idx_word]->arg); - bgp_redistribute_metric_set(bgp, red, AFI_IP6, type, metric); - return bgp_redistribute_set(bgp, AFI_IP6, type, 0); + changed = bgp_redistribute_rmap_set(red, argv[idx_word]->arg); + changed |= bgp_redistribute_metric_set(bgp, red, AFI_IP6, type, + metric); + return bgp_redistribute_set(bgp, AFI_IP6, type, 0, changed); } DEFUN (bgp_redistribute_ipv6_metric_rmap, @@ -12026,6 +12127,7 @@ DEFUN (bgp_redistribute_ipv6_metric_rmap, int type; uint32_t metric; struct bgp_redist *red; + bool changed; type = proto_redistnum(AFI_IP6, argv[idx_protocol]->text); if (type < 0) { @@ -12035,9 +12137,10 @@ DEFUN (bgp_redistribute_ipv6_metric_rmap, metric = strtoul(argv[idx_number]->arg, NULL, 10); red = bgp_redist_add(bgp, AFI_IP6, type, 0); - bgp_redistribute_metric_set(bgp, red, AFI_IP6, SAFI_UNICAST, metric); - bgp_redistribute_rmap_set(red, argv[idx_word]->arg); - return bgp_redistribute_set(bgp, AFI_IP6, type, 0); + changed = bgp_redistribute_metric_set(bgp, red, AFI_IP6, SAFI_UNICAST, + metric); + changed |= bgp_redistribute_rmap_set(red, argv[idx_word]->arg); + return bgp_redistribute_set(bgp, AFI_IP6, type, 0, changed); } DEFUN (no_bgp_redistribute_ipv6, diff --git a/bgpd/bgp_zebra.c b/bgpd/bgp_zebra.c index c7049ef21..43afc317e 100644 --- a/bgpd/bgp_zebra.c +++ b/bgpd/bgp_zebra.c @@ -1576,8 +1576,14 @@ static void bgp_redist_del(struct bgp *bgp, afi_t afi, uint8_t type, /* Other routes redistribution into BGP. */ int bgp_redistribute_set(struct bgp *bgp, afi_t afi, int type, - unsigned short instance) + unsigned short instance, bool changed) { + /* If redistribute options are changed call + * bgp_redistribute_unreg() to reset the option and withdraw + * the routes + */ + if (changed) + bgp_redistribute_unreg(bgp, afi, type, instance); /* Return if already redistribute flag is set. */ if (instance) { diff --git a/bgpd/bgp_zebra.h b/bgpd/bgp_zebra.h index e3c88b9db..546d72402 100644 --- a/bgpd/bgp_zebra.h +++ b/bgpd/bgp_zebra.h @@ -51,7 +51,8 @@ extern struct bgp_redist *bgp_redist_lookup(struct bgp *, afi_t, uint8_t, unsigned short); extern struct bgp_redist *bgp_redist_add(struct bgp *, afi_t, uint8_t, unsigned short); -extern int bgp_redistribute_set(struct bgp *, afi_t, int, unsigned short); +extern int bgp_redistribute_set(struct bgp *, afi_t, int, unsigned short, + bool changed); extern int bgp_redistribute_resend(struct bgp *, afi_t, int, unsigned short); extern int bgp_redistribute_rmap_set(struct bgp_redist *, const char *); extern int bgp_redistribute_metric_set(struct bgp *, struct bgp_redist *, afi_t, diff --git a/bgpd/bgpd.c b/bgpd/bgpd.c index c8b4e3acf..7ff5053ce 100644 --- a/bgpd/bgpd.c +++ b/bgpd/bgpd.c @@ -3187,15 +3187,16 @@ int bgp_delete(struct bgp *bgp) .import_redirect_rtlist); bgp->vpn_policy[afi].import_redirect_rtlist = NULL; } - /* Remove visibility via the master list - there may however still be - * routes to be processed still referencing the struct bgp. - */ - listnode_delete(bm->bgp, bgp); /* Deregister from Zebra, if needed */ if (IS_BGP_INST_KNOWN_TO_ZEBRA(bgp)) bgp_zebra_instance_deregister(bgp); + /* Remove visibility via the master list - there may however still be + * routes to be processed still referencing the struct bgp. + */ + listnode_delete(bm->bgp, bgp); + /* Free interfaces in this instance. */ bgp_if_finish(bgp); @@ -6631,17 +6632,6 @@ char *peer_uptime(time_t uptime2, char *buf, size_t len, uint8_t use_json, time_t uptime1, epoch_tbuf; struct tm *tm; - /* Check buffer length. */ - if (len < BGP_UPTIME_LEN) { - if (!use_json) { - zlog_warn("peer_uptime (): buffer shortage %lu", - (unsigned long)len); - /* XXX: should return status instead of buf... */ - snprintf(buf, len, "<error> "); - } - return buf; - } - /* If there is no connection has been done before print `never'. */ if (uptime2 == 0) { if (use_json) { @@ -7356,7 +7346,7 @@ static void bgp_config_write_family(struct vty *vty, struct bgp *bgp, afi_t afi, } /* clang-format off */ -#if CONFDATE > 20180517 +#if CONFDATE > 20190517 CPP_NOTICE("bgpd: remove 'bgp enforce-first-as' config migration from bgp_config_write") #endif /* clang-format on */ |