diff options
| author | Daniel Walton <dwalton@cumulusnetworks.com> | 2017-06-16 19:12:57 +0000 |
|---|---|---|
| committer | Daniel Walton <dwalton@cumulusnetworks.com> | 2017-06-16 19:12:57 +0000 |
| commit | 9bedbb1e52fbef082702723ee0a119d76a997ec8 (patch) | |
| tree | 4732c6ea051da93c49e01910192226828e54781f /bgpd/bgp_label.c | |
| parent | 62e4232010330e515630399838288f6281d04de6 (diff) | |
bgpd: Install SAFI_LABELED_UNICAST routes in SAFI_UNICAST table
Signed-off-by: Daniel Walton <dwalton@cumulusnetworks.com>
- All ipv4 labeled-unicast routes are now installed in the ipv4 unicast
table. This allows us to do things like take routes from an ipv4
unicast peer, allocate a label for them and TX them to a ipv4
labeled-unicast peer. We can do the opposite where we take routes from
a labeled-unicast peer, remove the label and advertise them to an ipv4
unicast peer.
- Multipath over a labeled route and non-labeled route is not allowed.
- You cannot activate a peer for both 'ipv4 unicast' and 'ipv4
labeled-unicast'
- The 'tag' variable was overloaded for zebra's route tag feature as
well as the mpls label. I added a 'mpls_label_t mpls' variable to
avoid this. This is much cleaner but resulted in touching a lot of
code.
Diffstat (limited to 'bgpd/bgp_label.c')
| -rw-r--r-- | bgpd/bgp_label.c | 51 |
1 files changed, 31 insertions, 20 deletions
diff --git a/bgpd/bgp_label.c b/bgpd/bgp_label.c index 0798515ebb..adeaa7f3bd 100644 --- a/bgpd/bgp_label.c +++ b/bgpd/bgp_label.c @@ -63,7 +63,7 @@ bgp_parse_fec_update (void) /* hack for the bgp instance & SAFI = have to send/receive it */ afi = family2afi(p.family); - safi = SAFI_LABELED_UNICAST; + safi = SAFI_UNICAST; bgp = bgp_get_default(); if (!bgp) { @@ -74,7 +74,7 @@ bgp_parse_fec_update (void) table = bgp->rib[afi][safi]; if (!table) { - zlog_debug("no %u labeled-unicast table", p.family); + zlog_debug("no %u unicast table", p.family); return -1; } rn = bgp_node_lookup(table, &p); @@ -86,11 +86,11 @@ bgp_parse_fec_update (void) /* treat it as implicit withdraw - the label is invalid */ if (label == MPLS_INVALID_LABEL) - bgp_unset_valid_label(rn->local_label); + bgp_unset_valid_label(&rn->local_label); else { - label_ntop(label, 1, rn->local_label); - bgp_set_valid_label(rn->local_label); + label_ntop(label, 1, &rn->local_label); + bgp_set_valid_label(&rn->local_label); } SET_FLAG(rn->flags, BGP_NODE_LABEL_CHANGED); bgp_unlock_node (rn); @@ -98,18 +98,18 @@ bgp_parse_fec_update (void) return 1; } -u_char * +mpls_label_t bgp_adv_label (struct bgp_node *rn, struct bgp_info *ri, struct peer *to, afi_t afi, safi_t safi) { struct peer *from; - u_char *remote_label; + mpls_label_t remote_label; int reflect; if (!rn || !ri || !to) - return NULL; + return MPLS_INVALID_LABEL; - remote_label = ri->extra ? ri->extra->tag : NULL; + remote_label = ri->extra ? ri->extra->label : MPLS_INVALID_LABEL; from = ri->peer; reflect = ((from->sort == BGP_PEER_IBGP) && (to->sort == BGP_PEER_IBGP)); @@ -172,22 +172,34 @@ bgp_reg_dereg_for_label (struct bgp_node *rn, struct bgp_info *ri, } static int -bgp_nlri_get_labels (struct peer *peer, u_char *pnt, u_char plen, - u_char label[]) +bgp_nlri_get_labels (struct peer *peer, u_char *pnt, u_char plen, mpls_label_t *label) { u_char *data = pnt; u_char *lim = pnt + plen; u_char llen = 0; + u_char label_index = 0; for (; data < lim; data += BGP_LABEL_BYTES) { memcpy(label, data, BGP_LABEL_BYTES); - llen += 3; + llen += BGP_LABEL_BYTES; + + bgp_set_valid_label(label); + if (bgp_is_withdraw_label(label) || label_bos(label)) break; + + label_index += 1; } + + /* If we RX multiple labels we will end up keeping only the last + * one. We do not yet support a label stack greater than 1. */ + if (label_index > 1) + zlog_warn("%s rcvd UPDATE with label stack %d deep", + peer->host, label_index); + if (!(bgp_is_withdraw_label(label) || label_bos(label))) - zlog_warn("%s: [Update:RCVD] invalid label - no bottom of stack", + zlog_warn("%s rcvd UPDATE with invalid label stack - no bottom of stack", peer->host); return llen; @@ -206,7 +218,7 @@ bgp_nlri_parse_label (struct peer *peer, struct attr *attr, safi_t safi; int addpath_encoded; u_int32_t addpath_id; - u_char label[3]; + mpls_label_t label = MPLS_INVALID_LABEL; u_char llen; /* Check peer status. */ @@ -254,8 +266,7 @@ bgp_nlri_parse_label (struct peer *peer, struct attr *attr, } /* Fill in the labels */ - llen = bgp_nlri_get_labels(peer, pnt, psize, label); - // zlog_debug("rcvd label [%x/%x/%x], llen=%d\n", label[0], label[1], label[2], llen); + llen = bgp_nlri_get_labels(peer, pnt, psize, &label); p.prefixlen = prefixlen - BSIZE(llen); /* There needs to be at least one label */ @@ -319,13 +330,13 @@ bgp_nlri_parse_label (struct peer *peer, struct attr *attr, if (attr) { - bgp_update (peer, &p, addpath_id, attr, packet->afi, SAFI_LABELED_UNICAST, - ZEBRA_ROUTE_BGP, BGP_ROUTE_NORMAL, NULL, label, 0, NULL); + bgp_update (peer, &p, addpath_id, attr, packet->afi, SAFI_UNICAST, + ZEBRA_ROUTE_BGP, BGP_ROUTE_NORMAL, NULL, &label, 0, NULL); } else { - bgp_withdraw (peer, &p, addpath_id, attr, packet->afi, SAFI_LABELED_UNICAST, - ZEBRA_ROUTE_BGP, BGP_ROUTE_NORMAL, NULL, label, NULL); + bgp_withdraw (peer, &p, addpath_id, attr, packet->afi, SAFI_UNICAST, + ZEBRA_ROUTE_BGP, BGP_ROUTE_NORMAL, NULL, &label, NULL); } } |
