diff options
Diffstat (limited to 'bgpd/bgp_route.c')
| -rw-r--r-- | bgpd/bgp_route.c | 124 |
1 files changed, 79 insertions, 45 deletions
diff --git a/bgpd/bgp_route.c b/bgpd/bgp_route.c index fdc7f22ae8..36e0c92482 100644 --- a/bgpd/bgp_route.c +++ b/bgpd/bgp_route.c @@ -147,7 +147,8 @@ static struct bgp_info_extra *bgp_info_extra_new(void) { struct bgp_info_extra *new; new = XCALLOC(MTYPE_BGP_ROUTE_EXTRA, sizeof(struct bgp_info_extra)); - new->label = MPLS_INVALID_LABEL; + new->label[0] = MPLS_INVALID_LABEL; + new->num_labels = 0; return new; } @@ -770,9 +771,9 @@ static int bgp_info_cmp(struct bgp *bgp, struct bgp_info *new, /* If one path has a label but the other does not, do not treat * them as equals for multipath */ - if ((new->extra &&bgp_is_valid_label(&new->extra->label)) + if ((new->extra && bgp_is_valid_label(&new->extra->label[0])) != (exist->extra - && bgp_is_valid_label(&exist->extra->label))) { + && bgp_is_valid_label(&exist->extra->label[0]))) { if (debug) zlog_debug( "%s: %s and %s cannot be multipath, one has a label while the other does not", @@ -2225,9 +2226,11 @@ static void bgp_process_main_one(struct bgp *bgp, struct bgp_node *rn, /* advertise/withdraw type-5 routes */ if ((afi == AFI_IP || afi == AFI_IP6) && (safi == SAFI_UNICAST)) { if (new_select) - bgp_evpn_advertise_type5_route(bgp, rn, afi, safi); + bgp_evpn_advertise_type5_route(bgp, &rn->p, + new_select->attr, + afi, safi); else if (old_select) - bgp_evpn_withdraw_type5_route(bgp, rn, afi, safi); + bgp_evpn_withdraw_type5_route(bgp, &rn->p, afi, safi); } /* Clear any route change flags. */ @@ -2670,7 +2673,8 @@ static int bgp_update_martian_nexthop(struct bgp *bgp, afi_t afi, safi_t safi, int bgp_update(struct peer *peer, struct prefix *p, u_int32_t addpath_id, struct attr *attr, afi_t afi, safi_t safi, int type, - int sub_type, struct prefix_rd *prd, mpls_label_t *label, + int sub_type, struct prefix_rd *prd, + mpls_label_t *label, u_int32_t num_labels, int soft_reconfig, struct bgp_route_evpn *evpn) { int ret; @@ -2681,9 +2685,9 @@ int bgp_update(struct peer *peer, struct prefix *p, u_int32_t addpath_id, struct attr *attr_new; struct bgp_info *ri; struct bgp_info *new; + struct bgp_info_extra *extra; const char *reason; char pfx_buf[BGP_PRD_PATH_STRLEN]; - char label_buf[20]; int connected = 0; int do_loop_check = 1; int has_valid_label = 0; @@ -2698,10 +2702,11 @@ int bgp_update(struct peer *peer, struct prefix *p, u_int32_t addpath_id, bgp = peer->bgp; rn = bgp_afi_node_get(bgp->rib[afi][safi], afi, safi, p, prd); - has_valid_label = bgp_is_valid_label(label); - - if (has_valid_label) - sprintf(label_buf, "label %u", label_pton(label)); + /* TODO: Check to see if we can get rid of "is_valid_label" */ + if (afi == AFI_L2VPN && safi == SAFI_EVPN) + has_valid_label = (num_labels > 0) ? 1 : 0; + else + has_valid_label = bgp_is_valid_label(label); /* When peer's soft reconfiguration enabled. Record input packet in Adj-RIBs-In. */ @@ -2821,7 +2826,7 @@ int bgp_update(struct peer *peer, struct prefix *p, u_int32_t addpath_id, && attrhash_cmp(ri->attr, attr_new) && (!has_valid_label || memcmp(&(bgp_info_extra_get(ri))->label, label, - BGP_LABEL_BYTES) + num_labels * sizeof(mpls_label_t)) == 0) && (overlay_index_equal( afi, ri, evpn == NULL ? NULL : &evpn->eth_s_id, @@ -2832,7 +2837,8 @@ int bgp_update(struct peer *peer, struct prefix *p, u_int32_t addpath_id, && CHECK_FLAG(ri->flags, BGP_INFO_HISTORY)) { if (bgp_debug_update(peer, p, NULL, 1)) { bgp_debug_rdpfxpath2str( - afi, safi, prd, p, label, + afi, safi, prd, p, + label, num_labels, addpath_id ? 1 : 0, addpath_id, pfx_buf, sizeof(pfx_buf)); zlog_debug("%s rcvd %s", peer->host, @@ -2857,7 +2863,8 @@ int bgp_update(struct peer *peer, struct prefix *p, u_int32_t addpath_id, } bgp_debug_rdpfxpath2str( - afi, safi, prd, p, label, + afi, safi, prd, p, + label, num_labels, addpath_id ? 1 : 0, addpath_id, pfx_buf, sizeof(pfx_buf)); zlog_debug( @@ -2883,7 +2890,8 @@ int bgp_update(struct peer *peer, struct prefix *p, u_int32_t addpath_id, if (CHECK_FLAG(ri->flags, BGP_INFO_REMOVED)) { if (bgp_debug_update(peer, p, NULL, 1)) { bgp_debug_rdpfxpath2str( - afi, safi, prd, p, label, + afi, safi, prd, p, + label, num_labels, addpath_id ? 1 : 0, addpath_id, pfx_buf, sizeof(pfx_buf)); zlog_debug( @@ -2896,7 +2904,8 @@ int bgp_update(struct peer *peer, struct prefix *p, u_int32_t addpath_id, /* Received Logging. */ if (bgp_debug_update(peer, p, NULL, 1)) { - bgp_debug_rdpfxpath2str(afi, safi, prd, p, label, + bgp_debug_rdpfxpath2str(afi, safi, prd, p, + label, num_labels, addpath_id ? 1 : 0, addpath_id, pfx_buf, sizeof(pfx_buf)); zlog_debug("%s rcvd %s", peer->host, pfx_buf); @@ -2987,9 +2996,12 @@ int bgp_update(struct peer *peer, struct prefix *p, u_int32_t addpath_id, /* Update MPLS label */ if (has_valid_label) { - memcpy(&(bgp_info_extra_get(ri))->label, label, - BGP_LABEL_BYTES); - bgp_set_valid_label(&(bgp_info_extra_get(ri))->label); + extra = bgp_info_extra_get(ri); + memcpy(&extra->label, label, + num_labels * sizeof(mpls_label_t)); + extra->num_labels = num_labels; + if (!(afi == AFI_L2VPN && safi == SAFI_EVPN)) + bgp_set_valid_label(&extra->label[0]); } #if ENABLE_BGP_VNC @@ -3126,7 +3138,8 @@ int bgp_update(struct peer *peer, struct prefix *p, u_int32_t addpath_id, peer->rcvd_attr_printed = 1; } - bgp_debug_rdpfxpath2str(afi, safi, prd, p, label, + bgp_debug_rdpfxpath2str(afi, safi, prd, p, + label, num_labels, addpath_id ? 1 : 0, addpath_id, pfx_buf, sizeof(pfx_buf)); zlog_debug("%s rcvd %s", peer->host, pfx_buf); @@ -3137,9 +3150,12 @@ int bgp_update(struct peer *peer, struct prefix *p, u_int32_t addpath_id, /* Update MPLS label */ if (has_valid_label) { - memcpy(&(bgp_info_extra_get(new))->label, label, - BGP_LABEL_BYTES); - bgp_set_valid_label(&(bgp_info_extra_get(new))->label); + extra = bgp_info_extra_get(new); + memcpy(&extra->label, label, + num_labels * sizeof(mpls_label_t)); + extra->num_labels = num_labels; + if (!(afi == AFI_L2VPN && safi == SAFI_EVPN)) + bgp_set_valid_label(&extra->label[0]); } /* Update Overlay Index */ @@ -3241,7 +3257,8 @@ filtered: peer->rcvd_attr_printed = 1; } - bgp_debug_rdpfxpath2str(afi, safi, prd, p, label, + bgp_debug_rdpfxpath2str(afi, safi, prd, p, + label, num_labels, addpath_id ? 1 : 0, addpath_id, pfx_buf, sizeof(pfx_buf)); zlog_debug("%s rcvd UPDATE about %s -- DENIED due to: %s", @@ -3276,7 +3293,8 @@ filtered: int bgp_withdraw(struct peer *peer, struct prefix *p, u_int32_t addpath_id, struct attr *attr, afi_t afi, safi_t safi, int type, - int sub_type, struct prefix_rd *prd, mpls_label_t *label, + int sub_type, struct prefix_rd *prd, + mpls_label_t *label, u_int32_t num_labels, struct bgp_route_evpn *evpn) { struct bgp *bgp; @@ -3312,7 +3330,8 @@ int bgp_withdraw(struct peer *peer, struct prefix *p, u_int32_t addpath_id, if (!bgp_adj_in_unset(rn, peer, addpath_id)) { if (bgp_debug_update(peer, p, NULL, 1)) { bgp_debug_rdpfxpath2str( - afi, safi, prd, p, label, + afi, safi, prd, p, + label, num_labels, addpath_id ? 1 : 0, addpath_id, pfx_buf, sizeof(pfx_buf)); zlog_debug( @@ -3332,7 +3351,8 @@ int bgp_withdraw(struct peer *peer, struct prefix *p, u_int32_t addpath_id, /* Logging. */ if (bgp_debug_update(peer, p, NULL, 1)) { - bgp_debug_rdpfxpath2str(afi, safi, prd, p, label, + bgp_debug_rdpfxpath2str(afi, safi, prd, p, + label, num_labels, addpath_id ? 1 : 0, addpath_id, pfx_buf, sizeof(pfx_buf)); zlog_debug("%s rcvd UPDATE about %s -- withdrawn", peer->host, @@ -3343,7 +3363,8 @@ int bgp_withdraw(struct peer *peer, struct prefix *p, u_int32_t addpath_id, if (ri && !CHECK_FLAG(ri->flags, BGP_INFO_HISTORY)) bgp_rib_withdraw(rn, ri, peer, afi, safi, prd); else if (bgp_debug_update(peer, p, NULL, 1)) { - bgp_debug_rdpfxpath2str(afi, safi, prd, p, label, + bgp_debug_rdpfxpath2str(afi, safi, prd, p, + label, num_labels, addpath_id ? 1 : 0, addpath_id, pfx_buf, sizeof(pfx_buf)); zlog_debug("%s Can't find the route %s", peer->host, pfx_buf); @@ -3469,14 +3490,18 @@ static void bgp_soft_reconfig_table(struct peer *peer, afi_t afi, safi_t safi, continue; struct bgp_info *ri = rn->info; - mpls_label_t label = (ri && ri->extra) - ? ri->extra->label - : MPLS_INVALID_LABEL; + u_int32_t num_labels = 0; + mpls_label_t *label_pnt = NULL; + + if (ri && ri->extra) + num_labels = ri->extra->num_labels; + if (num_labels) + label_pnt = &ri->extra->label[0]; ret = bgp_update(peer, &rn->p, ain->addpath_rx_id, ain->attr, afi, safi, ZEBRA_ROUTE_BGP, - BGP_ROUTE_NORMAL, prd, &label, 1, - NULL); + BGP_ROUTE_NORMAL, prd, + label_pnt, num_labels, 1, NULL); if (ret < 0) { bgp_unlock_node(rn); @@ -4029,11 +4054,12 @@ int bgp_nlri_parse_ip(struct peer *peer, struct attr *attr, if (attr) ret = bgp_update(peer, &p, addpath_id, attr, afi, safi, ZEBRA_ROUTE_BGP, BGP_ROUTE_NORMAL, - NULL, NULL, 0, NULL); + NULL, NULL, 0, 0, NULL); else ret = bgp_withdraw(peer, &p, addpath_id, attr, afi, safi, ZEBRA_ROUTE_BGP, - BGP_ROUTE_NORMAL, NULL, NULL, NULL); + BGP_ROUTE_NORMAL, NULL, + NULL, 0, NULL); /* Address family configuration mismatch or maximum-prefix count overflow. */ @@ -4345,10 +4371,13 @@ static void bgp_static_update_safi(struct bgp *bgp, struct prefix *p, #if ENABLE_BGP_VNC mpls_label_t label = 0; #endif + u_int32_t num_labels = 0; union gw_addr add; assert(bgp_static); + if (bgp_static->label != MPLS_INVALID_LABEL) + num_labels = 1; rn = bgp_afi_node_get(bgp->rib[afi][safi], afi, safi, p, &bgp_static->prd); @@ -4443,7 +4472,7 @@ static void bgp_static_update_safi(struct bgp *bgp, struct prefix *p, ri->uptime = bgp_clock(); #if ENABLE_BGP_VNC if (ri->extra) - label = decode_label(&ri->extra->label); + label = decode_label(&ri->extra->label[0]); #endif /* Process change. */ @@ -4466,7 +4495,10 @@ static void bgp_static_update_safi(struct bgp *bgp, struct prefix *p, attr_new, rn); SET_FLAG(new->flags, BGP_INFO_VALID); new->extra = bgp_info_extra_new(); - new->extra->label = bgp_static->label; + if (num_labels) { + new->extra->label[0] = bgp_static->label; + new->extra->num_labels = num_labels; + } #if ENABLE_BGP_VNC label = decode_label(&bgp_static->label); #endif @@ -6713,7 +6745,7 @@ void route_vty_out_tag(struct vty *vty, struct prefix *p, } } - label = decode_label(&binfo->extra->label); + label = decode_label(&binfo->extra->label[0]); if (bgp_is_valid_label(&label)) { if (json) { @@ -7051,14 +7083,15 @@ void route_vty_out_detail(struct vty *vty, struct bgp *bgp, struct prefix *p, #if defined(HAVE_CUMULUS) if (!json_paths && safi == SAFI_EVPN) { - char tag_buf[20]; + char tag_buf[30]; bgp_evpn_route2str((struct prefix_evpn *)p, buf2, sizeof(buf2)); vty_out(vty, " Route %s", buf2); tag_buf[0] = '\0'; - if (binfo->extra) { - bgp_evpn_label2str(&binfo->extra->label, tag_buf, - sizeof(tag_buf)); + if (binfo->extra && binfo->extra->num_labels) { + bgp_evpn_label2str(binfo->extra->label, + binfo->extra->num_labels, + tag_buf, sizeof(tag_buf)); vty_out(vty, " VNI %s", tag_buf); } vty_out(vty, "\n"); @@ -7692,13 +7725,14 @@ void route_vty_out_detail(struct vty *vty, struct bgp *bgp, struct prefix *p, /* Remote Label */ #if defined(HAVE_CUMULUS) - if (binfo->extra && bgp_is_valid_label(&binfo->extra->label) + if (binfo->extra && bgp_is_valid_label(&binfo->extra->label[0]) && safi != SAFI_EVPN) #else - if (binfo->extra && bgp_is_valid_label(&binfo->extra->label)) + if (binfo->extra && bgp_is_valid_label(&binfo->extra->label[0])) #endif { - mpls_label_t label = label_pton(&binfo->extra->label); + mpls_label_t label = label_pton( + &binfo->extra->label[0]); if (json_paths) json_object_int_add(json_path, "remoteLabel", label); |
