summaryrefslogtreecommitdiffstats
path: root/bgpd
diff options
context:
space:
mode:
authorvivek <vivek@cumulusnetworks.com>2018-08-28 00:13:30 +0200
committervivek <vivek@cumulusnetworks.com>2018-08-28 00:13:30 +0200
commitf190902f523abaa1035cbbb385387bc6c72dd1dc (patch)
tree9472de5fb49314eba45868ed7b66376f7329b2fe /bgpd
parentbgpd, zebra: Fix warnings (diff)
parentMerge pull request #2898 from donaldsharp/vrf_bitmap_is_whack (diff)
downloadfrr-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.c17
-rw-r--r--bgpd/bgp_evpn_private.h1
-rw-r--r--bgpd/bgp_evpn_vty.c8
-rw-r--r--bgpd/bgp_flowspec.c2
-rw-r--r--bgpd/bgp_flowspec_vty.c10
-rw-r--r--bgpd/bgp_network.c3
-rw-r--r--bgpd/bgp_pbr.c13
-rw-r--r--bgpd/bgp_route.c130
-rw-r--r--bgpd/bgp_rpki.c129
-rw-r--r--bgpd/bgp_table.h4
-rw-r--r--bgpd/bgp_vty.c283
-rw-r--r--bgpd/bgp_zebra.c8
-rw-r--r--bgpd/bgp_zebra.h3
-rw-r--r--bgpd/bgpd.c22
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 */