diff options
author | Daniel Walton <dwalton@cumulusnetworks.com> | 2017-06-16 21:12:57 +0200 |
---|---|---|
committer | Daniel Walton <dwalton@cumulusnetworks.com> | 2017-06-16 21:12:57 +0200 |
commit | 9bedbb1e52fbef082702723ee0a119d76a997ec8 (patch) | |
tree | 4732c6ea051da93c49e01910192226828e54781f | |
parent | Merge pull request #718 from qlyoung/fix-vtysh-shit (diff) | |
download | frr-9bedbb1e52fbef082702723ee0a119d76a997ec8.tar.xz frr-9bedbb1e52fbef082702723ee0a119d76a997ec8.zip |
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.
-rw-r--r-- | bgpd/bgp_attr.c | 30 | ||||
-rw-r--r-- | bgpd/bgp_attr.h | 10 | ||||
-rw-r--r-- | bgpd/bgp_evpn.c | 16 | ||||
-rw-r--r-- | bgpd/bgp_evpn.h | 2 | ||||
-rw-r--r-- | bgpd/bgp_label.c | 51 | ||||
-rw-r--r-- | bgpd/bgp_label.h | 32 | ||||
-rw-r--r-- | bgpd/bgp_mplsvpn.c | 26 | ||||
-rw-r--r-- | bgpd/bgp_mplsvpn.h | 4 | ||||
-rw-r--r-- | bgpd/bgp_packet.c | 1 | ||||
-rw-r--r-- | bgpd/bgp_route.c | 230 | ||||
-rw-r--r-- | bgpd/bgp_route.h | 8 | ||||
-rw-r--r-- | bgpd/bgp_table.h | 3 | ||||
-rw-r--r-- | bgpd/bgp_updgrp_adv.c | 3 | ||||
-rw-r--r-- | bgpd/bgp_updgrp_packet.c | 10 | ||||
-rw-r--r-- | bgpd/bgp_vty.c | 78 | ||||
-rw-r--r-- | bgpd/bgp_vty.h | 10 | ||||
-rw-r--r-- | bgpd/bgp_zebra.c | 62 | ||||
-rw-r--r-- | bgpd/bgpd.c | 11 | ||||
-rw-r--r-- | bgpd/bgpd.h | 1 | ||||
-rw-r--r-- | lib/mpls.h | 9 | ||||
-rw-r--r-- | lib/stream.c | 9 | ||||
-rw-r--r-- | lib/stream.h | 3 | ||||
-rw-r--r-- | zebra/zebra_mpls.c | 2 | ||||
-rw-r--r-- | zebra/zserv.c | 2 |
24 files changed, 355 insertions, 258 deletions
diff --git a/bgpd/bgp_attr.c b/bgpd/bgp_attr.c index cf2e48759..1d038ba45 100644 --- a/bgpd/bgp_attr.c +++ b/bgpd/bgp_attr.c @@ -39,6 +39,7 @@ #include "bgpd/bgp_aspath.h" #include "bgpd/bgp_community.h" #include "bgpd/bgp_debug.h" +#include "bgpd/bgp_label.h" #include "bgpd/bgp_packet.h" #include "bgpd/bgp_ecommunity.h" #include "bgpd/bgp_lcommunity.h" @@ -536,6 +537,7 @@ bgp_attr_extra_new (void) struct attr_extra *extra; extra = XCALLOC (MTYPE_ATTR_EXTRA, sizeof (struct attr_extra)); extra->label_index = BGP_INVALID_LABEL_INDEX; + extra->label = MPLS_INVALID_LABEL; return extra; } @@ -579,6 +581,9 @@ bgp_attr_dup (struct attr *new, struct attr *orig) { new->extra = extra; memset(new->extra, 0, sizeof(struct attr_extra)); + new->extra->label_index = BGP_INVALID_LABEL_INDEX; + new->extra->label = MPLS_INVALID_LABEL; + if (orig->extra) { *new->extra = *orig->extra; } @@ -962,6 +967,8 @@ bgp_attr_default_set (struct attr *attr, u_char origin) attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_AS_PATH); attr->extra->weight = BGP_ATTR_DEFAULT_WEIGHT; attr->extra->tag = 0; + attr->extra->label_index = BGP_INVALID_LABEL_INDEX; + attr->extra->label = MPLS_INVALID_LABEL; attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_NEXT_HOP); attr->extra->mp_nexthop_len = IPV6_MAX_BYTELEN; @@ -1003,6 +1010,8 @@ bgp_attr_aggregate_intern (struct bgp *bgp, u_char origin, attr.flag |= ATTR_FLAG_BIT (BGP_ATTR_COMMUNITIES); } + attre.label_index = BGP_INVALID_LABEL_INDEX; + attre.label = MPLS_INVALID_LABEL; attre.weight = BGP_ATTR_DEFAULT_WEIGHT; attre.mp_nexthop_len = IPV6_MAX_BYTELEN; if (! as_set || atomic_aggregate) @@ -2964,27 +2973,27 @@ bgp_packet_mpattr_start (struct stream *s, struct peer *peer, void bgp_packet_mpattr_prefix (struct stream *s, afi_t afi, safi_t safi, struct prefix *p, struct prefix_rd *prd, - u_char *tag, int addpath_encode, + mpls_label_t *label, int addpath_encode, u_int32_t addpath_tx_id, struct attr *attr) { if (safi == SAFI_MPLS_VPN) { if (addpath_encode) stream_putl(s, addpath_tx_id); - /* Tag, RD, Prefix write. */ + /* Label, RD, Prefix write. */ stream_putc (s, p->prefixlen + 88); - stream_put (s, tag, 3); + stream_put (s, label, BGP_LABEL_BYTES); stream_put (s, prd->val, 8); stream_put (s, &p->u.prefix, PSIZE (p->prefixlen)); } else if (safi == SAFI_EVPN) { - bgp_packet_mpattr_route_type_5(s, p, prd, tag, attr); + bgp_packet_mpattr_route_type_5(s, p, prd, label, attr); } else if (safi == SAFI_LABELED_UNICAST) { /* Prefix write with label. */ - stream_put_labeled_prefix(s, p, tag); + stream_put_labeled_prefix(s, p, label); } else stream_put_prefix_addpath (s, p, addpath_encode, addpath_tx_id); @@ -3115,7 +3124,7 @@ bgp_packet_attribute (struct bgp *bgp, struct peer *peer, struct stream *s, struct attr *attr, struct bpacket_attr_vec_arr *vecarr, struct prefix *p, afi_t afi, safi_t safi, - struct peer *from, struct prefix_rd *prd, u_char *tag, + struct peer *from, struct prefix_rd *prd, mpls_label_t *label, int addpath_encode, u_int32_t addpath_tx_id) { @@ -3138,7 +3147,7 @@ bgp_packet_attribute (struct bgp *bgp, struct peer *peer, size_t mpattrlen_pos = 0; mpattrlen_pos = bgp_packet_mpattr_start(s, peer, afi, safi, vecarr, attr); - bgp_packet_mpattr_prefix(s, afi, safi, p, prd, tag, + bgp_packet_mpattr_prefix(s, afi, safi, p, prd, label, addpath_encode, addpath_tx_id, attr); bgp_packet_mpattr_end(s, mpattrlen_pos); } @@ -3571,16 +3580,17 @@ bgp_packet_mpunreach_start (struct stream *s, afi_t afi, safi_t safi) void bgp_packet_mpunreach_prefix (struct stream *s, struct prefix *p, afi_t afi, safi_t safi, struct prefix_rd *prd, - u_char *tag, int addpath_encode, + mpls_label_t *label, int addpath_encode, u_int32_t addpath_tx_id, struct attr *attr) { u_char wlabel[3] = {0x80, 0x00, 0x00}; if (safi == SAFI_LABELED_UNICAST) - tag = wlabel; + label = (mpls_label_t *) wlabel; return bgp_packet_mpattr_prefix (s, afi, safi, p, prd, - tag, addpath_encode, addpath_tx_id, attr); + label, + addpath_encode, addpath_tx_id, attr); } void diff --git a/bgpd/bgp_attr.h b/bgpd/bgp_attr.h index f25df3a8b..f3c1b5e3c 100644 --- a/bgpd/bgp_attr.h +++ b/bgpd/bgp_attr.h @@ -21,6 +21,7 @@ #ifndef _QUAGGA_BGP_ATTR_H #define _QUAGGA_BGP_ATTR_H +#include "mpls.h" #include "bgp_attr_evpn.h" /* Simple bit mapping. */ @@ -145,6 +146,9 @@ struct attr_extra /* Label index */ u_int32_t label_index; + /* MPLS label */ + mpls_label_t label; + uint16_t encap_tunneltype; /* grr */ struct bgp_attr_encap_subtlv *encap_subtlvs; /* rfc5512 */ @@ -254,7 +258,7 @@ extern bgp_size_t bgp_packet_attribute (struct bgp *bgp, struct peer *, struct bpacket_attr_vec_arr *vecarr, struct prefix *, afi_t, safi_t, struct peer *, struct prefix_rd *, - u_char *, int, u_int32_t); + mpls_label_t *, int, u_int32_t); extern void bgp_dump_routes_attr (struct stream *, struct attr *, struct prefix *); extern int attrhash_cmp (const void *, const void *); @@ -303,7 +307,7 @@ extern size_t bgp_packet_mpattr_start(struct stream *s, struct peer *peer, struct attr *attr); extern void bgp_packet_mpattr_prefix(struct stream *s, afi_t afi, safi_t safi, struct prefix *p, struct prefix_rd *prd, - u_char *tag, int addpath_encode, + mpls_label_t *label, int addpath_encode, u_int32_t addpath_tx_id, struct attr *); extern size_t bgp_packet_mpattr_prefix_size(afi_t afi, safi_t safi, @@ -314,7 +318,7 @@ extern size_t bgp_packet_mpunreach_start (struct stream *s, afi_t afi, safi_t safi); extern void bgp_packet_mpunreach_prefix (struct stream *s, struct prefix *p, afi_t afi, safi_t safi, struct prefix_rd *prd, - u_char *tag, int, u_int32_t, struct attr *); + mpls_label_t *, int, u_int32_t, struct attr *); extern void bgp_packet_mpunreach_end (struct stream *s, size_t attrlen_pnt); static inline int diff --git a/bgpd/bgp_evpn.c b/bgpd/bgp_evpn.c index c5a0ef889..d516f1718 100644 --- a/bgpd/bgp_evpn.c +++ b/bgpd/bgp_evpn.c @@ -33,6 +33,7 @@ #include "bgpd/bgp_route.h" #include "bgpd/bgp_attr.h" #include "bgpd/bgp_mplsvpn.h" +#include "bgpd/bgp_label.h" #include "bgpd/bgp_evpn.h" int @@ -46,7 +47,7 @@ bgp_nlri_parse_evpn(struct peer *peer, struct attr *attr, struct evpn_addr *p_evpn_p; struct bgp_route_evpn evpn; uint8_t route_type, route_length; - u_char *pnt_label; + mpls_label_t label; u_int32_t addpath_id = 0; /* Check peer status. */ @@ -146,22 +147,23 @@ bgp_nlri_parse_evpn(struct peer *peer, struct attr *attr, } /* Fetch Label */ - if (pnt + 3 > lim) { + if (pnt + BGP_LABEL_BYTES > lim) { zlog_err("not enough bytes for Label left in NLRI?"); return -1; } - pnt_label = pnt; - pnt += 3; + memcpy(&label, pnt, BGP_LABEL_BYTES); + bgp_set_valid_label(&label); + pnt += BGP_LABEL_BYTES; if (!withdraw) { bgp_update(peer, &p, addpath_id, attr, AFI_L2VPN, SAFI_EVPN, ZEBRA_ROUTE_BGP, BGP_ROUTE_NORMAL, - &prd, pnt_label, 0, &evpn); + &prd, &label, 0, &evpn); } else { bgp_withdraw(peer, &p, addpath_id, attr, AFI_L2VPN, SAFI_EVPN, ZEBRA_ROUTE_BGP, - BGP_ROUTE_NORMAL, &prd, pnt_label, &evpn); + BGP_ROUTE_NORMAL, &prd, &label, &evpn); } } @@ -174,7 +176,7 @@ bgp_nlri_parse_evpn(struct peer *peer, struct attr *attr, void bgp_packet_mpattr_route_type_5(struct stream *s, struct prefix *p, struct prefix_rd *prd, - u_char * label, struct attr *attr) + mpls_label_t *label, struct attr *attr) { int len; char temp[16]; diff --git a/bgpd/bgp_evpn.h b/bgpd/bgp_evpn.h index 95d428015..feabc9cd2 100644 --- a/bgpd/bgp_evpn.h +++ b/bgpd/bgp_evpn.h @@ -27,7 +27,7 @@ extern int bgp_nlri_parse_evpn(struct peer *peer, struct attr *attr, extern void bgp_packet_mpattr_route_type_5(struct stream *s, struct prefix *p, struct prefix_rd *prd, - u_char * label, struct attr *attr); + mpls_label_t *label, struct attr *attr); /* EVPN route types as per RFC7432 and * as per draft-ietf-bess-evpn-prefix-advertisement-02 */ diff --git a/bgpd/bgp_label.c b/bgpd/bgp_label.c index 0798515eb..adeaa7f3b 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); } } diff --git a/bgpd/bgp_label.h b/bgpd/bgp_label.h index dbc675dd4..796df6652 100644 --- a/bgpd/bgp_label.h +++ b/bgpd/bgp_label.h @@ -32,8 +32,8 @@ struct peer; extern void bgp_reg_dereg_for_label (struct bgp_node *rn, struct bgp_info *ri, int reg); extern int bgp_parse_fec_update(void); -extern u_char * bgp_adv_label(struct bgp_node *rn, struct bgp_info *ri, - struct peer *to, afi_t afi, safi_t safi); +extern mpls_label_t bgp_adv_label(struct bgp_node *rn, struct bgp_info *ri, + struct peer *to, afi_t afi, safi_t safi); extern int bgp_nlri_parse_label (struct peer *peer, struct attr *attr, struct bgp_nlri *packet); @@ -48,38 +48,35 @@ bgp_labeled_safi (safi_t safi) } static inline int -bgp_is_withdraw_label (u_char *pkt) +bgp_is_withdraw_label (mpls_label_t *label) { + u_char *pkt = (u_char *) label; if ((pkt[0] == 0x80) && (pkt[1] == 0x00) && (pkt[2] == 0x00)) return 1; return 0; } -static inline u_char * -bgp_encode_withdraw_label (u_char *pkt) -{ - *pkt++ = 0x80; *pkt++ = 0x00; *pkt++ = 0x00; - return pkt; -} - static inline int -bgp_is_valid_label (u_char *t) +bgp_is_valid_label (mpls_label_t *label) { + u_char *t= (u_char *) label; if (!t) return 0; return (t[2] & 0x02); } static inline void -bgp_set_valid_label (u_char *t) +bgp_set_valid_label (mpls_label_t *label) { + u_char *t= (u_char *) label; if (t) t[2] |= 0x02; } static inline void -bgp_unset_valid_label (u_char *t) +bgp_unset_valid_label (mpls_label_t *label) { + u_char *t= (u_char *) label; if (t) t[2] &= ~0x02; } @@ -98,16 +95,18 @@ bgp_unregister_for_label (struct bgp_node *rn) /* Label stream to value */ static inline u_int32_t -label_pton (u_char t[]) +label_pton (mpls_label_t *label) { + u_char *t= (u_char *) label; return ((((unsigned int) t[0]) << 12) | (((unsigned int) t[1]) << 4) | ((unsigned int) ((t[2] & 0xF0) >> 4))); } /* Encode label values */ static inline void -label_ntop (u_int32_t l, int bos, u_char t[]) +label_ntop (u_int32_t l, int bos, mpls_label_t *label) { + u_char *t= (u_char *) label; t[0] = ((l & 0x000FF000) >> 12); t[1] = ((l & 0x00000FF0) >> 4); t[2] = ((l & 0x0000000F) << 4); @@ -117,8 +116,9 @@ label_ntop (u_int32_t l, int bos, u_char t[]) /* Return BOS value of label stream */ static inline u_char -label_bos (u_char t[]) +label_bos (mpls_label_t *label) { + u_char *t= (u_char *) label; return (t[2] & 0x01); }; diff --git a/bgpd/bgp_mplsvpn.c b/bgpd/bgp_mplsvpn.c index 73c0389b1..551614aef 100644 --- a/bgpd/bgp_mplsvpn.c +++ b/bgpd/bgp_mplsvpn.c @@ -27,12 +27,13 @@ #include "stream.h" #include "queue.h" #include "filter.h" - #include "lib/json.h" + #include "bgpd/bgpd.h" #include "bgpd/bgp_table.h" #include "bgpd/bgp_route.h" #include "bgpd/bgp_attr.h" +#include "bgpd/bgp_label.h" #include "bgpd/bgp_mplsvpn.h" #include "bgpd/bgp_packet.h" #include "bgpd/bgp_vty.h" @@ -87,9 +88,10 @@ encode_rd_type (u_int16_t v, u_char *pnt) } u_int32_t -decode_label (u_char *pnt) +decode_label (mpls_label_t *label_pnt) { u_int32_t l; + u_char *pnt = (u_char *) label_pnt; l = ((u_int32_t) *pnt++ << 12); l |= (u_int32_t) *pnt++ << 4; @@ -98,9 +100,10 @@ decode_label (u_char *pnt) } void -encode_label(u_int32_t label, - u_char *pnt) +encode_label(mpls_label_t label, + mpls_label_t *label_pnt) { + u_char *pnt = (u_char *) label_pnt; if (pnt == NULL) return; *pnt++ = (label>>12) & 0xff; @@ -169,7 +172,7 @@ bgp_nlri_parse_vpn (struct peer *peer, struct attr *attr, struct rd_as rd_as; struct rd_ip rd_ip; struct prefix_rd prd; - u_char *tagpnt; + mpls_label_t label; afi_t afi; safi_t safi; int addpath_encoded; @@ -249,14 +252,15 @@ bgp_nlri_parse_vpn (struct peer *peer, struct attr *attr, return -1; } - /* Copyr label to prefix. */ - tagpnt = pnt; + /* Copy label to prefix. */ + memcpy(&label, pnt, BGP_LABEL_BYTES); + bgp_set_valid_label(&label); /* Copy routing distinguisher to rd. */ - memcpy (&prd.val, pnt + 3, 8); + memcpy (&prd.val, pnt + BGP_LABEL_BYTES, 8); /* Decode RD type. */ - type = decode_rd_type (pnt + 3); + type = decode_rd_type (pnt + BGP_LABEL_BYTES); switch (type) { @@ -289,12 +293,12 @@ bgp_nlri_parse_vpn (struct peer *peer, struct attr *attr, if (attr) { bgp_update (peer, &p, addpath_id, attr, packet->afi, SAFI_MPLS_VPN, - ZEBRA_ROUTE_BGP, BGP_ROUTE_NORMAL, &prd, tagpnt, 0, NULL); + ZEBRA_ROUTE_BGP, BGP_ROUTE_NORMAL, &prd, &label, 0, NULL); } else { bgp_withdraw (peer, &p, addpath_id, attr, packet->afi, SAFI_MPLS_VPN, - ZEBRA_ROUTE_BGP, BGP_ROUTE_NORMAL, &prd, tagpnt, NULL); + ZEBRA_ROUTE_BGP, BGP_ROUTE_NORMAL, &prd, &label, NULL); } } /* Packet length consistency check. */ diff --git a/bgpd/bgp_mplsvpn.h b/bgpd/bgp_mplsvpn.h index faae041e0..fba68b368 100644 --- a/bgpd/bgp_mplsvpn.h +++ b/bgpd/bgp_mplsvpn.h @@ -94,8 +94,8 @@ extern u_int16_t decode_rd_type (u_char *); extern void encode_rd_type (u_int16_t, u_char *); extern void bgp_mplsvpn_init (void); extern int bgp_nlri_parse_vpn (struct peer *, struct attr *, struct bgp_nlri *); -extern u_int32_t decode_label (u_char *); -extern void encode_label(u_int32_t, u_char *); +extern u_int32_t decode_label (mpls_label_t *); +extern void encode_label(mpls_label_t, mpls_label_t *); extern void decode_rd_as (u_char *, struct rd_as *); extern void decode_rd_as4 (u_char *, struct rd_as *); extern void decode_rd_ip (u_char *, struct rd_ip *); diff --git a/bgpd/bgp_packet.c b/bgpd/bgp_packet.c index da6bf5c3c..d81f03c8b 100644 --- a/bgpd/bgp_packet.c +++ b/bgpd/bgp_packet.c @@ -1391,6 +1391,7 @@ bgp_update_receive (struct peer *peer, bgp_size_t size) memset (&attr, 0, sizeof (struct attr)); memset (&extra, 0, sizeof (struct attr_extra)); extra.label_index = BGP_INVALID_LABEL_INDEX; + extra.label = MPLS_INVALID_LABEL; memset (&nlris, 0, sizeof (nlris)); attr.extra = &extra; memset (peer->rcvd_attr_str, 0, BUFSIZ); diff --git a/bgpd/bgp_route.c b/bgpd/bgp_route.c index 31c1dd8c1..15367ec7c 100644 --- a/bgpd/bgp_route.c +++ b/bgpd/bgp_route.c @@ -35,7 +35,6 @@ #include "thread.h" #include "workqueue.h" #include "queue.h" -#include "mpls.h" #include "memory.h" #include "lib/json.h" @@ -117,6 +116,7 @@ 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; return new; } @@ -694,7 +694,17 @@ bgp_info_cmp (struct bgp *bgp, struct bgp_info *new, struct bgp_info *exist, /* 11. Maximum path check. */ if (newm == existm) { - if (bgp_flag_check(bgp, BGP_FLAG_ASPATH_MULTIPATH_RELAX)) + /* 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)) != + (exist->extra && bgp_is_valid_label(&exist->extra->label))) + { + if (debug) + zlog_debug("%s: %s and %s cannot be multipath, one has a label while the other does not", + pfx_buf, new_buf, exist_buf); + } + else if (bgp_flag_check(bgp, BGP_FLAG_ASPATH_MULTIPATH_RELAX)) { /* @@ -1271,14 +1281,14 @@ subgroup_announce_check (struct bgp_node *rn, struct bgp_info *ri, /* If it's labeled safi, make sure the route has a valid label. */ if (safi == SAFI_LABELED_UNICAST) { - u_char *tag = bgp_adv_label(rn, ri, peer, afi, safi); - if (!bgp_is_valid_label(tag)) + mpls_label_t label = bgp_adv_label(rn, ri, peer, afi, safi); + if (!bgp_is_valid_label(&label)) { if (bgp_debug_update(NULL, p, subgrp->update_group, 0)) zlog_debug ("u%" PRIu64 ":s%" PRIu64 " %s/%d is filtered - no label (%p)", subgrp->update_group->id, subgrp->id, inet_ntop(p->family, &p->u.prefix, buf, SU_ADDRSTRLEN), - p->prefixlen, tag); + p->prefixlen, &label); return 0; } } @@ -1940,7 +1950,7 @@ bgp_process_main (struct work_queue *wq, void *data) * Right now, since we only deal with per-prefix labels, it is not necessary * to do this upon changes to best path except of the label index changes. */ - if (safi == SAFI_LABELED_UNICAST) + if (safi == SAFI_UNICAST) { bgp_table_lock (bgp_node_table (rn)); if (new_select) @@ -1955,8 +1965,8 @@ bgp_process_main (struct work_queue *wq, void *data) { if (CHECK_FLAG (rn->flags, BGP_NODE_REGISTERED_FOR_LABEL)) bgp_unregister_for_label (rn); - label_ntop (MPLS_IMP_NULL_LABEL, 1, rn->local_label); - bgp_set_valid_label(rn->local_label); + label_ntop (MPLS_IMP_NULL_LABEL, 1, &rn->local_label); + bgp_set_valid_label(&rn->local_label); } else bgp_register_for_label (rn, new_select); @@ -1997,6 +2007,10 @@ bgp_process_main (struct work_queue *wq, void *data) { group_announce_route(bgp, afi, safi, rn, new_select); + /* unicast routes must also be annouced to labeled-unicast update-groups */ + if (safi == SAFI_UNICAST) + group_announce_route(bgp, afi, SAFI_LABELED_UNICAST, rn, new_select); + UNSET_FLAG (old_select->flags, BGP_INFO_ATTR_CHANGED); UNSET_FLAG (rn->flags, BGP_NODE_LABEL_CHANGED); } @@ -2049,6 +2063,10 @@ bgp_process_main (struct work_queue *wq, void *data) group_announce_route(bgp, afi, safi, rn, new_select); + /* unicast routes must also be annouced to labeled-unicast update-groups */ + if (safi == SAFI_UNICAST) + group_announce_route(bgp, afi, SAFI_LABELED_UNICAST, rn, new_select); + /* FIB update. */ if (bgp_fibupd_safi(safi) && (bgp->inst_type != BGP_INSTANCE_TYPE_VIEW) && @@ -2464,7 +2482,7 @@ bgp_update_martian_nexthop (struct bgp *bgp, afi_t afi, safi_t safi, struct attr 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, u_char *tag, + int sub_type, struct prefix_rd *prd, mpls_label_t *label, int soft_reconfig, struct bgp_route_evpn* evpn) { int ret; @@ -2481,18 +2499,24 @@ bgp_update (struct peer *peer, struct prefix *p, u_int32_t addpath_id, char label_buf[20]; int connected = 0; int do_loop_check = 1; + int has_valid_label = 0; #if ENABLE_BGP_VNC int vnc_implicit_withdraw = 0; #endif memset (&new_attr, 0, sizeof(struct attr)); memset (&new_extra, 0, sizeof(struct attr_extra)); + new_extra.label_index = BGP_INVALID_LABEL_INDEX; + new_extra.label = MPLS_INVALID_LABEL; bgp = peer->bgp; rn = bgp_afi_node_get (bgp->rib[afi][safi], afi, safi, p, prd); label_buf[0] = '\0'; - if (bgp_labeled_safi(safi)) - sprintf (label_buf, "label %u", label_pton(tag)); + + has_valid_label = bgp_is_valid_label(label); + + if (has_valid_label) + sprintf (label_buf, "label %u", label_pton(label)); /* When peer's soft reconfiguration enabled. Record input packet in Adj-RIBs-In. */ @@ -2592,8 +2616,8 @@ bgp_update (struct peer *peer, struct prefix *p, u_int32_t addpath_id, /* Same attribute comes in. */ if (!CHECK_FLAG (ri->flags, BGP_INFO_REMOVED) && attrhash_cmp (ri->attr, attr_new) - && (!bgp_labeled_safi(safi) || - memcmp ((bgp_info_extra_get (ri))->tag, tag, 3) == 0) + && (!has_valid_label || + memcmp (&(bgp_info_extra_get (ri))->label, label, BGP_LABEL_BYTES) == 0) && (overlay_index_equal(afi, ri, evpn==NULL?NULL:&evpn->eth_s_id, evpn==NULL?NULL:&evpn->gw_ip))) { @@ -2714,9 +2738,12 @@ bgp_update (struct peer *peer, struct prefix *p, u_int32_t addpath_id, bgp_attr_unintern (&ri->attr); ri->attr = attr_new; - /* Update MPLS tag. */ - if (bgp_labeled_safi(safi)) - memcpy ((bgp_info_extra_get (ri))->tag, tag, 3); + /* 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); + } #if ENABLE_BGP_VNC if ((afi == AFI_IP || afi == AFI_IP6) && (safi == SAFI_UNICAST)) @@ -2814,10 +2841,10 @@ bgp_update (struct peer *peer, struct prefix *p, u_int32_t addpath_id, #if ENABLE_BGP_VNC if (SAFI_MPLS_VPN == safi) { - uint32_t label = decode_label(tag); + mpls_label_t label_decoded = decode_label(label); rfapiProcessUpdate(peer, NULL, p, prd, attr, afi, safi, type, sub_type, - &label); + &label_decoded); } if (SAFI_ENCAP == safi) { @@ -2846,9 +2873,12 @@ bgp_update (struct peer *peer, struct prefix *p, u_int32_t addpath_id, /* Make new BGP info. */ new = info_make(type, sub_type, 0, peer, attr_new, rn); - /* Update MPLS tag. */ - if (bgp_labeled_safi(safi)) - memcpy ((bgp_info_extra_get (new))->tag, tag, 3); + /* 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); + } /* Update Overlay Index */ if(afi == AFI_L2VPN) @@ -2928,10 +2958,10 @@ bgp_update (struct peer *peer, struct prefix *p, u_int32_t addpath_id, #if ENABLE_BGP_VNC if (SAFI_MPLS_VPN == safi) { - uint32_t label = decode_label(tag); + mpls_label_t label_decoded = decode_label(label); rfapiProcessUpdate(peer, NULL, p, prd, attr, afi, safi, type, sub_type, - &label); + &label_decoded); } if (SAFI_ENCAP == safi) { @@ -2981,7 +3011,7 @@ bgp_update (struct peer *peer, struct prefix *p, u_int32_t addpath_id, 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, u_char *tag, struct bgp_route_evpn *evpn) + struct prefix_rd *prd, mpls_label_t *label, struct bgp_route_evpn *evpn) { struct bgp *bgp; char pfx_buf[BGP_PRD_PATH_STRLEN]; @@ -3169,11 +3199,11 @@ bgp_soft_reconfig_table (struct peer *peer, afi_t afi, safi_t safi, if (ain->peer == peer) { struct bgp_info *ri = rn->info; - u_char *tag = (ri && ri->extra) ? ri->extra->tag : NULL; + mpls_label_t label = (ri && ri->extra) ? ri->extra->label : MPLS_INVALID_LABEL; ret = bgp_update (peer, &rn->p, ain->addpath_rx_id, ain->attr, afi, safi, ZEBRA_ROUTE_BGP, BGP_ROUTE_NORMAL, - prd, tag, 1, NULL); + prd, &label, 1, NULL); if (ret < 0) { @@ -4021,7 +4051,7 @@ bgp_static_withdraw (struct bgp *bgp, struct prefix *p, afi_t afi, */ static void bgp_static_withdraw_safi (struct bgp *bgp, struct prefix *p, afi_t afi, - safi_t safi, struct prefix_rd *prd, u_char *tag) + safi_t safi, struct prefix_rd *prd) { struct bgp_node *rn; struct bgp_info *ri; @@ -4134,8 +4164,7 @@ bgp_static_update_safi (struct bgp *bgp, struct prefix *p, /* Unintern original. */ aspath_unintern (&attr.aspath); bgp_attr_extra_free (&attr); - bgp_static_withdraw_safi (bgp, p, afi, safi, &bgp_static->prd, - bgp_static->tag); + bgp_static_withdraw_safi (bgp, p, afi, safi, &bgp_static->prd); return; } @@ -4204,9 +4233,9 @@ bgp_static_update_safi (struct bgp *bgp, struct prefix *p, rn); SET_FLAG (new->flags, BGP_INFO_VALID); new->extra = bgp_info_extra_new(); - memcpy (new->extra->tag, bgp_static->tag, 3); + new->extra->label = bgp_static->label; #if ENABLE_BGP_VNC - label = decode_label (bgp_static->tag); + label = decode_label (bgp_static->label); #endif /* Aggregate address increment. */ @@ -4437,8 +4466,7 @@ bgp_static_delete (struct bgp *bgp) bgp_static = rm->info; bgp_static_withdraw_safi (bgp, &rm->p, AFI_IP, safi, - (struct prefix_rd *)&rn->p, - bgp_static->tag); + (struct prefix_rd *)&rn->p); bgp_static_free (bgp_static); rn->info = NULL; bgp_unlock_node (rn); @@ -4552,7 +4580,7 @@ bgp_static_set_safi (afi_t afi, safi_t safi, struct vty *vty, const char *ip_str struct bgp_node *rn; struct bgp_table *table; struct bgp_static *bgp_static; - u_char tag[3]; + mpls_label_t label = MPLS_INVALID_LABEL; struct prefix gw_ip; /* validate ip prefix */ @@ -4580,13 +4608,10 @@ bgp_static_set_safi (afi_t afi, safi_t safi, struct vty *vty, const char *ip_str if (label_str) { unsigned long label_val; - VTY_GET_INTEGER_RANGE("Label/tag", label_val, label_str, 0, 16777215); - encode_label (label_val, tag); - } - else - { - memset (tag, 0, sizeof(tag)); /* empty, not even BoS */ + VTY_GET_INTEGER_RANGE("Label", label_val, label_str, 0, 16777215); + encode_label (label_val, &label); } + if (safi == SAFI_EVPN) { if( esi && str2esi (esi, NULL) == 0) @@ -4639,7 +4664,7 @@ bgp_static_set_safi (afi_t afi, safi_t safi, struct vty *vty, const char *ip_str bgp_static->valid = 0; bgp_static->igpmetric = 0; bgp_static->igpnexthop.s_addr = 0; - memcpy(bgp_static->tag, tag, 3); + bgp_static->label = label; bgp_static->prd = prd; if (rmap_str) @@ -4688,7 +4713,7 @@ bgp_static_unset_safi(afi_t afi, safi_t safi, struct vty *vty, const char *ip_st struct bgp_node *rn; struct bgp_table *table; struct bgp_static *bgp_static; - u_char tag[3]; + mpls_label_t label = MPLS_INVALID_LABEL; /* Convert IP prefix string to struct prefix. */ ret = str2prefix (ip_str, &p); @@ -4714,12 +4739,8 @@ bgp_static_unset_safi(afi_t afi, safi_t safi, struct vty *vty, const char *ip_st if (label_str) { unsigned long label_val; - VTY_GET_INTEGER_RANGE("Label/tag", label_val, label_str, 0, MPLS_LABEL_MAX); - encode_label (label_val, tag); - } - else - { - memset (tag, 0, sizeof(tag)); /* empty, not even BoS */ + VTY_GET_INTEGER_RANGE("Label", label_val, label_str, 0, MPLS_LABEL_MAX); + encode_label (label_val, &label); } prn = bgp_node_get (bgp->route[afi][safi], @@ -4734,7 +4755,7 @@ bgp_static_unset_safi(afi_t afi, safi_t safi, struct vty *vty, const char *ip_st if (rn) { - bgp_static_withdraw_safi (bgp, &p, afi, safi, &prd, tag); + bgp_static_withdraw_safi (bgp, &p, afi, safi, &prd); bgp_static = rn->info; bgp_static_free (bgp_static); @@ -6658,7 +6679,7 @@ route_vty_out_tag (struct vty *vty, struct prefix *p, { json_object *json_out = NULL; struct attr *attr; - u_int32_t label = 0; + mpls_label_t label = MPLS_INVALID_LABEL; if (!binfo->extra) return; @@ -6741,19 +6762,20 @@ route_vty_out_tag (struct vty *vty, struct prefix *p, } } - label = decode_label (binfo->extra->tag); + label = decode_label (&binfo->extra->label); - if (json) + // dwalton why is this called 'notag'? + if (bgp_is_valid_label(&label)) { - if (label) - json_object_int_add(json_out, "notag", label); - json_object_array_add(json, json_out); - } - else - { - vty_out (vty, "notag/%d", label); - - vty_out (vty, "%s", VTY_NEWLINE); + if (json) + { + json_object_int_add(json_out, "notag", label); + json_object_array_add(json, json_out); + } + else + { + vty_out (vty, "notag/%d%s", label, VTY_NEWLINE); + } } } @@ -7642,10 +7664,10 @@ route_vty_out_detail (struct vty *vty, struct bgp *bgp, struct prefix *p, if (binfo->extra && binfo->extra->damp_info) bgp_damp_info_vty (vty, binfo, json_path); - /* Remove Label */ - if (bgp_labeled_safi(safi) && binfo->extra) + /* Remote Label */ + if (binfo->extra && bgp_is_valid_label(&binfo->extra->label)) { - uint32_t label = label_pton(binfo->extra->tag); + mpls_label_t label = label_pton(&binfo->extra->label); if (json_paths) json_object_int_add(json_path, "remoteLabel", label); else @@ -8124,12 +8146,21 @@ route_vty_out_detail_header (struct vty *vty, struct bgp *bgp, int no_advertise = 0; int local_as = 0; int first = 1; + int has_valid_label = 0; + uint32_t label = 0; json_object *json_adv_to = NULL; p = &rn->p; + has_valid_label = bgp_is_valid_label(&rn->local_label); + + if (has_valid_label) + label = label_pton(&rn->local_label); if (json) { + if (has_valid_label) + json_object_int_add(json, "localLabel", label); + json_object_string_add(json, "prefix", inet_ntop (p->family, &p->u.prefix, buf2, INET6_ADDRSTRLEN)); json_object_int_add(json, "prefixlen", p->prefixlen); } @@ -8146,17 +8177,10 @@ route_vty_out_detail_header (struct vty *vty, struct bgp *bgp, buf2, p->prefixlen, VTY_NEWLINE); - if (bgp_labeled_safi(safi)) - { - vty_out(vty, "Local label: "); - if (!bgp_is_valid_label(rn->local_label)) - vty_out(vty, "not allocated%s", VTY_NEWLINE); - else - { - uint32_t label = label_pton(rn->local_label); - vty_out(vty, "%d%s", label, VTY_NEWLINE); - } - } + if (has_valid_label) + vty_out(vty, "Local label: %d%s", label, VTY_NEWLINE); + else if (bgp_labeled_safi(safi)) + vty_out(vty, "Local label: not allocated%s", VTY_NEWLINE); } for (ri = rn->info; ri; ri = ri->next) @@ -8438,17 +8462,13 @@ bgp_show_lcommunity_list (struct vty *vty, struct bgp *bgp, const char *lcom, DEFUN (show_ip_bgp_large_community_list, show_ip_bgp_large_community_list_cmd, - "show [ip] bgp [<view|vrf> WORD] [<ipv4|ipv6> [<unicast|multicast|vpn|labeled-unicast>]] large-community-list <(1-500)|WORD> [json]", + "show [ip] bgp [<view|vrf> WORD] ["BGP_AFI_CMD_STR" ["BGP_SAFI_CMD_STR"]] large-community-list <(1-500)|WORD> [json]", SHOW_STR IP_STR BGP_STR BGP_INSTANCE_HELP_STR - "Address Family\n" - "Address Family\n" - "Address Family modifier\n" - "Address Family modifier\n" - "Address Family modifier\n" - "Address Family modifier\n" + BGP_AFI_HELP_STR + BGP_SAFI_HELP_STR "Display routes matching the large-community-list\n" "large-community-list number\n" "large-community-list name\n" @@ -8484,17 +8504,13 @@ DEFUN (show_ip_bgp_large_community_list, } DEFUN (show_ip_bgp_large_community, show_ip_bgp_large_community_cmd, - "show [ip] bgp [<view|vrf> WORD] [<ipv4|ipv6> [<unicast|multicast|vpn|labeled-unicast>]] large-community [AA:BB:CC] [json]", + "show [ip] bgp [<view|vrf> WORD] ["BGP_AFI_CMD_STR" ["BGP_SAFI_CMD_STR"]] large-community [AA:BB:CC] [json]", SHOW_STR IP_STR BGP_STR BGP_INSTANCE_HELP_STR - "Address Family\n" - "Address Family\n" - "Address Family modifier\n" - "Address Family modifier\n" - "Address Family modifier\n" - "Address Family modifier\n" + BGP_AFI_HELP_STR + BGP_SAFI_HELP_STR "Display routes matching the large-communities\n" "List of large-community numbers\n" JSON_STR) @@ -9437,18 +9453,14 @@ bgp_peer_counts (struct vty *vty, struct peer *peer, afi_t afi, safi_t safi, u_c DEFUN (show_ip_bgp_instance_neighbor_prefix_counts, show_ip_bgp_instance_neighbor_prefix_counts_cmd, - "show [ip] bgp [<view|vrf> WORD] [<ipv4|ipv6> [<unicast|multicast|vpn|labeled-unicast>]] " + "show [ip] bgp [<view|vrf> WORD] ["BGP_AFI_CMD_STR" ["BGP_SAFI_CMD_STR"]] " "neighbors <A.B.C.D|X:X::X:X|WORD> prefix-counts [json]", SHOW_STR IP_STR BGP_STR BGP_INSTANCE_HELP_STR - "Address Family\n" - "Address Family\n" - "Address Family modifier\n" - "Address Family modifier\n" - "Address Family modifier\n" - "Address Family modifier\n" + BGP_AFI_HELP_STR + BGP_SAFI_HELP_STR "Address Family modifier\n" "Detailed information on TCP and BGP neighbor connections\n" "Neighbor to display information about\n" @@ -10638,7 +10650,7 @@ bgp_config_write_network_vpn (struct vty *vty, struct bgp *bgp, struct prefix *p; struct prefix_rd *prd; struct bgp_static *bgp_static; - u_int32_t label; + mpls_label_t label; char buf[SU_ADDRSTRLEN]; char rdbuf[RD_ADDRSTRLEN]; @@ -10656,7 +10668,7 @@ bgp_config_write_network_vpn (struct vty *vty, struct bgp *bgp, /* "network" configuration display. */ prefix_rd2str (prd, rdbuf, RD_ADDRSTRLEN); - label = decode_label (bgp_static->tag); + label = decode_label (&bgp_static->label); vty_out (vty, " network %s/%d rd %s", inet_ntop (p->family, &p->u.prefix, buf, SU_ADDRSTRLEN), @@ -10717,7 +10729,7 @@ bgp_config_write_network_evpn (struct vty *vty, struct bgp *bgp, prefix2str (p, buf, sizeof (buf)), vty_out (vty, " network %s rd %s ethtag %u tag %u esi %s gwip %s routermac %s", buf, rdbuf, p->u.prefix_evpn.eth_tag, - decode_label (bgp_static->tag), esi, buf2 , macrouter); + decode_label (&bgp_static->label), esi, buf2 , macrouter); vty_out (vty, "%s", VTY_NEWLINE); if (macrouter) XFREE (MTYPE_TMP, macrouter); @@ -10911,8 +10923,10 @@ bgp_route_init (void) install_element (BGP_IPV4_NODE, &bgp_network_route_map_cmd); install_element (BGP_IPV4_NODE, &bgp_network_mask_route_map_cmd); install_element (BGP_IPV4_NODE, &bgp_network_mask_natural_route_map_cmd); - install_element (BGP_IPV4L_NODE, &no_bgp_network_label_index_cmd); - install_element (BGP_IPV4L_NODE, &no_bgp_network_label_index_route_map_cmd); + install_element (BGP_IPV4_NODE, &bgp_network_label_index_cmd); + install_element (BGP_IPV4_NODE, &bgp_network_label_index_route_map_cmd); + install_element (BGP_IPV4_NODE, &no_bgp_network_label_index_cmd); + install_element (BGP_IPV4_NODE, &no_bgp_network_label_index_route_map_cmd); install_element (BGP_IPV4_NODE, &no_bgp_table_map_cmd); install_element (BGP_IPV4_NODE, &no_bgp_network_cmd); install_element (BGP_IPV4_NODE, &no_bgp_network_mask_cmd); @@ -10941,20 +10955,6 @@ bgp_route_init (void) install_element (BGP_IPV4M_NODE, &no_aggregate_address_mask_cmd); /* IPv4 labeled-unicast configuration. */ - install_element (BGP_IPV4L_NODE, &bgp_table_map_cmd); - install_element (BGP_IPV4L_NODE, &bgp_network_cmd); - install_element (BGP_IPV4L_NODE, &bgp_network_mask_cmd); - install_element (BGP_IPV4L_NODE, &bgp_network_mask_natural_cmd); - install_element (BGP_IPV4L_NODE, &bgp_network_route_map_cmd); - install_element (BGP_IPV4L_NODE, &bgp_network_mask_route_map_cmd); - install_element (BGP_IPV4L_NODE, &bgp_network_mask_natural_route_map_cmd); - install_element (BGP_IPV4L_NODE, &bgp_network_label_index_cmd); - install_element (BGP_IPV4L_NODE, &bgp_network_label_index_route_map_cmd); - install_element (BGP_IPV4L_NODE, &no_bgp_table_map_cmd); - install_element (BGP_IPV4L_NODE, &no_bgp_network_cmd); - install_element (BGP_IPV4L_NODE, &no_bgp_network_mask_cmd); - install_element (BGP_IPV4L_NODE, &no_bgp_network_mask_natural_cmd); - install_element (VIEW_NODE, &show_ip_bgp_instance_all_cmd); install_element (VIEW_NODE, &show_ip_bgp_cmd); install_element (VIEW_NODE, &show_ip_bgp_route_cmd); diff --git a/bgpd/bgp_route.h b/bgpd/bgp_route.h index 3d179e07b..763553b55 100644 --- a/bgpd/bgp_route.h +++ b/bgpd/bgp_route.h @@ -74,7 +74,7 @@ struct bgp_info_extra u_int32_t igpmetric; /* MPLS label. */ - u_char tag[3]; + mpls_label_t label; #if ENABLE_BGP_VNC union { @@ -207,7 +207,7 @@ struct bgp_static struct prefix_rd prd; /* MPLS label. */ - u_char tag[3]; + mpls_label_t label; /* EVPN */ struct eth_segment_id *eth_s_id; @@ -344,9 +344,9 @@ extern int bgp_static_unset_safi (afi_t afi, safi_t safi, struct vty *, const ch /* this is primarily for MPLS-VPN */ extern int bgp_update (struct peer *, struct prefix *, u_int32_t, struct attr *, afi_t, safi_t, int, int, struct prefix_rd *, - u_char *, int, struct bgp_route_evpn *); + mpls_label_t *, int, struct bgp_route_evpn *); extern int bgp_withdraw (struct peer *, struct prefix *, u_int32_t, struct attr *, - afi_t, safi_t, int, int, struct prefix_rd *, u_char *, + afi_t, safi_t, int, int, struct prefix_rd *, mpls_label_t *, struct bgp_route_evpn *); /* for bgp_nexthop and bgp_damp */ diff --git a/bgpd/bgp_table.h b/bgpd/bgp_table.h index cff270ebb..3aa519d56 100644 --- a/bgpd/bgp_table.h +++ b/bgpd/bgp_table.h @@ -21,6 +21,7 @@ #ifndef _QUAGGA_BGP_TABLE_H #define _QUAGGA_BGP_TABLE_H +#include "mpls.h" #include "table.h" struct bgp_table @@ -56,7 +57,7 @@ struct bgp_node struct bgp_node *prn; - u_char local_label[3]; + mpls_label_t local_label; uint64_t version; u_char flags; diff --git a/bgpd/bgp_updgrp_adv.c b/bgpd/bgp_updgrp_adv.c index c6a160632..80620a908 100644 --- a/bgpd/bgp_updgrp_adv.c +++ b/bgpd/bgp_updgrp_adv.c @@ -599,6 +599,9 @@ subgroup_announce_table (struct update_subgroup *subgrp, safi = SUBGRP_SAFI (subgrp); addpath_capable = bgp_addpath_encode_tx (peer, afi, safi); + if (safi == SAFI_LABELED_UNICAST) + safi = SAFI_UNICAST; + if (!table) table = peer->bgp->rib[afi][safi]; diff --git a/bgpd/bgp_updgrp_packet.c b/bgpd/bgp_updgrp_packet.c index 51abc19be..1857d9683 100644 --- a/bgpd/bgp_updgrp_packet.c +++ b/bgpd/bgp_updgrp_packet.c @@ -785,26 +785,26 @@ subgroup_update_packet (struct update_subgroup *subgrp) else { /* Encode the prefix in MP_REACH_NLRI attribute */ - u_char *tag = NULL; + mpls_label_t label = MPLS_INVALID_LABEL; if (rn->prn) prd = (struct prefix_rd *) &rn->prn->p; if (safi == SAFI_LABELED_UNICAST) - tag = bgp_adv_label(rn, binfo, peer, afi, safi); + label = bgp_adv_label(rn, binfo, peer, afi, safi); else if (binfo && binfo->extra) - tag = binfo->extra->tag; + label = binfo->extra->label; if (bgp_labeled_safi(safi)) - sprintf (label_buf, "label %u", label_pton(tag)); + sprintf (label_buf, "label %u", label_pton(&label)); if (stream_empty (snlri)) mpattrlen_pos = bgp_packet_mpattr_start (snlri, peer, afi, safi, &vecarr, adv->baa->attr); bgp_packet_mpattr_prefix (snlri, afi, safi, &rn->p, prd, - tag, addpath_encode, addpath_tx_id, adv->baa->attr); + &label, addpath_encode, addpath_tx_id, adv->baa->attr); } num_pfx++; diff --git a/bgpd/bgp_vty.c b/bgpd/bgp_vty.c index f5f538de9..3c510f377 100644 --- a/bgpd/bgp_vty.c +++ b/bgpd/bgp_vty.c @@ -531,6 +531,9 @@ bgp_vty_return (struct vty *vty, int ret) case BGP_ERR_INVALID_FOR_DIRECT_PEER: str = "Operation not allowed on a directly connected neighbor"; break; + case BGP_ERR_PEER_SAFI_CONFLICT: + str = "Cannot activate peer for both 'ipv4 unicast' and 'ipv4 labeled-unicast'"; + break; } if (str) { @@ -3317,10 +3320,7 @@ DEFUN (neighbor_activate, return CMD_WARNING; ret = peer_activate (peer, bgp_node_afi (vty), bgp_node_safi (vty)); - - if (ret) - return CMD_WARNING; - return CMD_SUCCESS; + return bgp_vty_return (vty, ret); } ALIAS_HIDDEN (neighbor_activate, @@ -3348,10 +3348,7 @@ DEFUN (no_neighbor_activate, return CMD_WARNING; ret = peer_deactivate (peer, bgp_node_afi (vty), bgp_node_safi (vty)); - - if (ret) - return CMD_WARNING; - return CMD_SUCCESS; + return bgp_vty_return (vty, ret); } ALIAS_HIDDEN (no_neighbor_activate, @@ -6499,7 +6496,7 @@ bgp_clear_prefix (struct vty *vty, const char *view_name, const char *ip_str, /* one clear bgp command to rule them all */ DEFUN (clear_ip_bgp_all, clear_ip_bgp_all_cmd, - "clear [ip] bgp [<view|vrf> WORD] ["BGP_AFI_CMD_STR" ["BGP_SAFI_CMD_STR"]] <*|A.B.C.D|X:X::X:X|WORD|(1-4294967295)|external|peer-group WORD> [<soft [<in|out>]|in [prefix-filter]|out>]", + "clear [ip] bgp [<view|vrf> WORD] ["BGP_AFI_CMD_STR" ["BGP_SAFI_WITH_LABEL_CMD_STR"]] <*|A.B.C.D|X:X::X:X|WORD|(1-4294967295)|external|peer-group WORD> [<soft [<in|out>]|in [prefix-filter]|out>]", CLEAR_STR IP_STR BGP_STR @@ -6513,7 +6510,7 @@ DEFUN (clear_ip_bgp_all, "Clear all members of peer-group\n" "BGP peer-group name\n" BGP_AFI_HELP_STR - BGP_SAFI_HELP_STR + BGP_SAFI_WITH_LABEL_HELP_STR BGP_SOFT_STR BGP_SOFT_IN_STR BGP_SOFT_OUT_STR @@ -6534,12 +6531,18 @@ DEFUN (clear_ip_bgp_all, /* clear [ip] bgp */ if (argv_find (argv, argc, "ip", &idx)) afi = AFI_IP; + /* [<view|vrf> WORD] */ if (argv_find (argv, argc, "view", &idx) || argv_find (argv, argc, "vrf", &idx)) { vrf = argv[idx + 1]->arg; idx += 2; } + + /* ["BGP_AFI_CMD_STR" ["BGP_SAFI_CMD_STR"]] */ + if (argv_find_and_parse_afi (argv, argc, &idx, &afi)) + argv_find_and_parse_safi (argv, argc, &idx, &safi); + /* <*|A.B.C.D|X:X::X:X|WORD|(1-4294967295)|external|peer-group WORD> */ if (argv_find (argv, argc, "*", &idx)) { @@ -6575,11 +6578,7 @@ DEFUN (clear_ip_bgp_all, { clr_sort = clear_external; } - /* ["BGP_AFI_CMD_STR" ["BGP_SAFI_CMD_STR"]] */ - if (argv_find_and_parse_afi (argv, argc, &idx, &afi)) - { - argv_find_and_parse_safi (argv, argc, &idx, &safi); - } + /* [<soft [<in|out>]|in [prefix-filter]|out>] */ if (argv_find (argv, argc, "soft", &idx)) { @@ -6952,6 +6951,22 @@ DEFUN (show_bgp_memory, return CMD_SUCCESS; } +static int +bgp_show_summary_afi_safi_peer (struct peer *peer, int afi, int safi) +{ + if (peer->afc[afi][safi]) + return 1; + + /* The peer is doing 'ipv4 labeled-unicast' but we put those routes in + * the 'ipv4 unicast' table so return True for SAFI_UNICAST if they are + * doing SAFI_LABELED_UNICAST + */ + if (safi == SAFI_UNICAST && peer->afc[afi][SAFI_LABELED_UNICAST]) + return 1; + + return 0; +} + /* Show BGP peer's summary information. */ static int bgp_show_summary (struct vty *vty, struct bgp *bgp, int afi, int safi, @@ -6985,7 +7000,7 @@ bgp_show_summary (struct vty *vty, struct bgp *bgp, int afi, int safi, if (!CHECK_FLAG(peer->flags, PEER_FLAG_CONFIG_NODE)) continue; - if (peer->afc[afi][safi]) + if (bgp_show_summary_afi_safi_peer (peer, afi, safi)) { memset(dn_flag, '\0', sizeof(dn_flag)); if (peer_dynamic_neighbor(peer)) @@ -7015,7 +7030,7 @@ bgp_show_summary (struct vty *vty, struct bgp *bgp, int afi, int safi, if (!CHECK_FLAG(peer->flags, PEER_FLAG_CONFIG_NODE)) continue; - if (peer->afc[afi][safi]) + if (bgp_show_summary_afi_safi_peer (peer, afi, safi)) { if (!count) { @@ -7319,6 +7334,13 @@ bgp_show_summary_afi_safi_peer_exists (struct bgp *bgp, int afi, int safi) if (peer->afc[afi][safi]) return 1; + + /* The peer is doing 'ipv4 labeled-unicast' but we put those routes in + * the 'ipv4 unicast' table so return True for SAFI_UNICAST if they are + * doing SAFI_LABELED_UNICAST + */ + if (safi == SAFI_UNICAST && peer->afc[afi][SAFI_LABELED_UNICAST]) + return 1; } return 0; @@ -7344,6 +7366,16 @@ bgp_show_summary_afi_safi (struct vty *vty, struct bgp *bgp, int afi, int safi, safi = 1; /* SAFI_UNICAST */ while (safi < SAFI_MAX) { + + /* SAFI_LABELED_UNICAST routes are treated as SAFI_UNICAST + * so do not display a summary + */ + if (safi == SAFI_LABELED_UNICAST) + { + safi++; + continue; + } + if (bgp_show_summary_afi_safi_peer_exists (bgp, afi, safi)) { json_output = true; @@ -9610,13 +9642,13 @@ bgp_show_update_groups(struct vty *vty, const char *name, DEFUN (show_ip_bgp_updgrps, show_ip_bgp_updgrps_cmd, - "show [ip] bgp [<view|vrf> WORD] ["BGP_AFI_CMD_STR" ["BGP_SAFI_CMD_STR"]] update-groups [SUBGROUP-ID]", + "show [ip] bgp [<view|vrf> WORD] ["BGP_AFI_CMD_STR" ["BGP_SAFI_WITH_LABEL_CMD_STR"]] update-groups [SUBGROUP-ID]", SHOW_STR IP_STR BGP_STR BGP_INSTANCE_HELP_STR BGP_AFI_HELP_STR - BGP_SAFI_HELP_STR + BGP_SAFI_WITH_LABEL_HELP_STR "Detailed info about dynamic update groups\n" "Specific subgroup to display detailed info for\n") { @@ -11027,14 +11059,8 @@ bgp_vty_init (void) install_element (BGP_IPV6_NODE, &bgp_maxpaths_ibgp_cluster_cmd); install_element (BGP_IPV6_NODE, &no_bgp_maxpaths_ibgp_cmd); - install_element (BGP_IPV4L_NODE, &bgp_maxpaths_cmd); - install_element (BGP_IPV4L_NODE, &no_bgp_maxpaths_cmd); install_element (BGP_IPV6L_NODE, &bgp_maxpaths_cmd); install_element (BGP_IPV6L_NODE, &no_bgp_maxpaths_cmd); - - install_element (BGP_IPV4L_NODE, &bgp_maxpaths_ibgp_cmd); - install_element (BGP_IPV4L_NODE, &bgp_maxpaths_ibgp_cluster_cmd); - install_element (BGP_IPV4L_NODE, &no_bgp_maxpaths_ibgp_cmd); install_element (BGP_IPV6L_NODE, &bgp_maxpaths_ibgp_cmd); install_element (BGP_IPV6L_NODE, &bgp_maxpaths_ibgp_cluster_cmd); install_element (BGP_IPV6L_NODE, &no_bgp_maxpaths_ibgp_cmd); @@ -11191,7 +11217,6 @@ bgp_vty_init (void) install_element (BGP_NODE, &neighbor_set_peer_group_cmd); install_element (BGP_IPV4_NODE, &neighbor_set_peer_group_hidden_cmd); install_element (BGP_IPV4M_NODE, &neighbor_set_peer_group_hidden_cmd); - install_element (BGP_IPV4L_NODE, &neighbor_set_peer_group_hidden_cmd); install_element (BGP_IPV6_NODE, &neighbor_set_peer_group_hidden_cmd); install_element (BGP_IPV6M_NODE, &neighbor_set_peer_group_hidden_cmd); install_element (BGP_IPV6L_NODE, &neighbor_set_peer_group_hidden_cmd); @@ -11202,7 +11227,6 @@ bgp_vty_init (void) install_element (BGP_NODE, &no_neighbor_set_peer_group_cmd); install_element (BGP_IPV4_NODE, &no_neighbor_set_peer_group_hidden_cmd); install_element (BGP_IPV4M_NODE, &no_neighbor_set_peer_group_hidden_cmd); - install_element (BGP_IPV4L_NODE, &no_neighbor_set_peer_group_hidden_cmd); install_element (BGP_IPV6_NODE, &no_neighbor_set_peer_group_hidden_cmd); install_element (BGP_IPV6M_NODE, &no_neighbor_set_peer_group_hidden_cmd); install_element (BGP_IPV6L_NODE, &no_neighbor_set_peer_group_hidden_cmd); diff --git a/bgpd/bgp_vty.h b/bgpd/bgp_vty.h index 1bb9cfb71..b3e6f73a6 100644 --- a/bgpd/bgp_vty.h +++ b/bgpd/bgp_vty.h @@ -28,15 +28,21 @@ struct bgp; #define BGP_AFI_CMD_STR "<ipv4|ipv6>" #define BGP_AFI_HELP_STR "Address Family\nAddress Family\n" -#define BGP_SAFI_CMD_STR "<unicast|multicast|vpn|labeled-unicast>" +#define BGP_SAFI_CMD_STR "<unicast|multicast|vpn>" #define BGP_SAFI_HELP_STR \ "Address Family modifier\n" \ "Address Family modifier\n" \ - "Address Family modifier\n" \ "Address Family modifier\n" #define BGP_AFI_SAFI_CMD_STR BGP_AFI_CMD_STR" "BGP_SAFI_CMD_STR #define BGP_AFI_SAFI_HELP_STR BGP_AFI_HELP_STR BGP_SAFI_HELP_STR +#define BGP_SAFI_WITH_LABEL_CMD_STR "<unicast|multicast|vpn|labeled-unicast>" +#define BGP_SAFI_WITH_LABEL_HELP_STR \ + "Address Family modifier\n" \ + "Address Family modifier\n" \ + "Address Family modifier\n" \ + "Address Family modifier\n" + extern void bgp_vty_init (void); extern const char *afi_safi_print (afi_t, safi_t); extern const char *afi_safi_json (afi_t, safi_t); diff --git a/bgpd/bgp_zebra.c b/bgpd/bgp_zebra.c index 4fff339b8..970318327 100644 --- a/bgpd/bgp_zebra.c +++ b/bgpd/bgp_zebra.c @@ -1227,7 +1227,7 @@ bgp_zebra_announce (struct bgp_node *rn, struct prefix *p, struct bgp_info *info struct bgp_info local_info; struct bgp_info *info_cp = &local_info; route_tag_t tag; - u_int32_t label; + mpls_label_t label; /* Don't try to install if we're not connected to Zebra or Zebra doesn't * know of this instance. @@ -1278,6 +1278,7 @@ bgp_zebra_announce (struct bgp_node *rn, struct prefix *p, struct bgp_info *info struct in_addr *nexthop; char buf[2][INET_ADDRSTRLEN]; int valid_nh_count = 0; + int has_valid_label = 0; /* resize nexthop buffer size if necessary */ if ((oldsize = stream_get_size (bgp_nexthop_buf)) < @@ -1297,7 +1298,7 @@ bgp_zebra_announce (struct bgp_node *rn, struct prefix *p, struct bgp_info *info /* For labeled unicast, each nexthop has a label too. Resize label * buffer, if required. */ - if (safi == SAFI_LABELED_UNICAST) + if (safi == SAFI_UNICAST) { if ((oldsize = stream_get_size (bgp_label_buf)) < (sizeof (unsigned int) * nhcount)) @@ -1342,9 +1343,10 @@ bgp_zebra_announce (struct bgp_node *rn, struct prefix *p, struct bgp_info *info { stream_put (bgp_nexthop_buf, &nexthop, sizeof (struct in_addr *)); valid_nh_count++; - if (safi == SAFI_LABELED_UNICAST) + if (info->extra && bgp_is_valid_label(&info->extra->label)) { - label = label_pton(info->extra->tag); + has_valid_label = 1; + label = label_pton(&info->extra->label); stream_put (bgp_label_buf, &label, sizeof (u_int32_t)); } } @@ -1372,9 +1374,10 @@ bgp_zebra_announce (struct bgp_node *rn, struct prefix *p, struct bgp_info *info continue; stream_put (bgp_nexthop_buf, &nexthop, sizeof (struct in_addr *)); - if (safi == SAFI_LABELED_UNICAST) + if (mpinfo->extra && bgp_is_valid_label(&mpinfo->extra->label)) { - label = label_pton(mpinfo->extra->tag); + has_valid_label = 1; + label = label_pton(&mpinfo->extra->label); stream_put (bgp_label_buf, &label, sizeof (u_int32_t)); } valid_nh_count++; @@ -1385,9 +1388,11 @@ bgp_zebra_announce (struct bgp_node *rn, struct prefix *p, struct bgp_info *info api.type = ZEBRA_ROUTE_BGP; api.instance = 0; api.message = 0; - api.safi = (safi == SAFI_LABELED_UNICAST) ? SAFI_UNICAST : safi; + assert (safi != SAFI_LABELED_UNICAST); // remove this assert after testing + api.safi = safi; SET_FLAG (api.message, ZAPI_MESSAGE_NEXTHOP); - if (safi == SAFI_LABELED_UNICAST) + + if (has_valid_label) SET_FLAG (api.message, ZAPI_MESSAGE_LABEL); /* Note that this currently only applies to Null0 routes for aggregates. @@ -1401,7 +1406,7 @@ bgp_zebra_announce (struct bgp_node *rn, struct prefix *p, struct bgp_info *info api.nexthop_num = valid_nh_count; api.nexthop = (struct in_addr **)STREAM_DATA (bgp_nexthop_buf); - if (safi == SAFI_LABELED_UNICAST) + if (has_valid_label) { api.label_num = valid_nh_count; api.label = (unsigned int *)STREAM_DATA (bgp_label_buf); @@ -1441,7 +1446,7 @@ bgp_zebra_announce (struct bgp_node *rn, struct prefix *p, struct bgp_info *info for (i = 0; i < api.nexthop_num; i++) { label_buf[0] = '\0'; - if (safi == SAFI_LABELED_UNICAST) + if (has_valid_label) sprintf(label_buf, "label %u", api.label[i]); zlog_debug(" nhop [%d]: %s %s", i+1, @@ -1463,6 +1468,7 @@ bgp_zebra_announce (struct bgp_node *rn, struct prefix *p, struct bgp_info *info struct zapi_ipv6 api; int valid_nh_count = 0; char buf[2][INET6_ADDRSTRLEN]; + int has_valid_label = 0; /* resize nexthop buffer size if necessary */ if ((oldsize = stream_get_size (bgp_nexthop_buf)) < @@ -1495,7 +1501,7 @@ bgp_zebra_announce (struct bgp_node *rn, struct prefix *p, struct bgp_info *info /* For labeled unicast, each nexthop has a label too. Resize label * buffer, if required. */ - if (safi == SAFI_LABELED_UNICAST) + if (safi == SAFI_UNICAST) { if ((oldsize = stream_get_size (bgp_label_buf)) < (sizeof (unsigned int) * nhcount)) @@ -1556,9 +1562,11 @@ bgp_zebra_announce (struct bgp_node *rn, struct prefix *p, struct bgp_info *info } stream_put (bgp_nexthop_buf, &nexthop, sizeof (struct in6_addr *)); stream_put (bgp_ifindices_buf, &ifindex, sizeof (unsigned int)); - if (safi == SAFI_LABELED_UNICAST) + + if (info->extra && bgp_is_valid_label(&info->extra->label)) { - label = label_pton(info->extra->tag); + has_valid_label = 1; + label = label_pton(&info->extra->label); stream_put (bgp_label_buf, &label, sizeof (u_int32_t)); } valid_nh_count++; @@ -1603,9 +1611,11 @@ bgp_zebra_announce (struct bgp_node *rn, struct prefix *p, struct bgp_info *info stream_put (bgp_nexthop_buf, &nexthop, sizeof (struct in6_addr *)); stream_put (bgp_ifindices_buf, &ifindex, sizeof (unsigned int)); - if (safi == SAFI_LABELED_UNICAST) + + if (mpinfo->extra && bgp_is_valid_label(&mpinfo->extra->label)) { - label = label_pton(mpinfo->extra->tag); + has_valid_label = 1; + label = label_pton(&mpinfo->extra->label); stream_put (bgp_label_buf, &label, sizeof (u_int32_t)); } valid_nh_count++; @@ -1617,9 +1627,11 @@ bgp_zebra_announce (struct bgp_node *rn, struct prefix *p, struct bgp_info *info api.type = ZEBRA_ROUTE_BGP; api.instance = 0; api.message = 0; - api.safi = (safi == SAFI_LABELED_UNICAST) ? SAFI_UNICAST : safi; + assert (safi != SAFI_LABELED_UNICAST); // remove this assert after testing + api.safi = safi; SET_FLAG (api.message, ZAPI_MESSAGE_NEXTHOP); - if (safi == SAFI_LABELED_UNICAST) + + if (has_valid_label) SET_FLAG (api.message, ZAPI_MESSAGE_LABEL); /* Note that this currently only applies to Null0 routes for aggregates. @@ -1636,7 +1648,7 @@ bgp_zebra_announce (struct bgp_node *rn, struct prefix *p, struct bgp_info *info SET_FLAG (api.message, ZAPI_MESSAGE_IFINDEX); api.ifindex_num = valid_nh_count; api.ifindex = (ifindex_t *)STREAM_DATA (bgp_ifindices_buf); - if (safi == SAFI_LABELED_UNICAST) + if (has_valid_label) { api.label_num = valid_nh_count; api.label = (unsigned int *)STREAM_DATA (bgp_label_buf); @@ -1676,7 +1688,7 @@ bgp_zebra_announce (struct bgp_node *rn, struct prefix *p, struct bgp_info *info for (i = 0; i < api.nexthop_num; i++) { label_buf[0] = '\0'; - if (safi == SAFI_LABELED_UNICAST) + if (has_valid_label) sprintf(label_buf, "label %u", api.label[i]); zlog_debug(" nhop [%d]: %s if %s %s", i+1, @@ -1707,7 +1719,7 @@ bgp_zebra_announce (struct bgp_node *rn, struct prefix *p, struct bgp_info *info for (i = 0; i < api.nexthop_num; i++) { label_buf[0] = '\0'; - if (safi == SAFI_LABELED_UNICAST) + if (has_valid_label) sprintf(label_buf, "label %u", api.label[i]); zlog_debug(" nhop [%d]: %s if %s %s", i+1, @@ -1793,10 +1805,9 @@ bgp_zebra_withdraw (struct prefix *p, struct bgp_info *info, safi_t safi) api.type = ZEBRA_ROUTE_BGP; api.instance = 0; api.message = 0; - api.safi = (safi == SAFI_LABELED_UNICAST) ? SAFI_UNICAST : safi; + assert (safi != SAFI_LABELED_UNICAST); // remove this assert after testing + api.safi = safi; SET_FLAG (api.message, ZAPI_MESSAGE_NEXTHOP); - if (safi == SAFI_LABELED_UNICAST) - SET_FLAG (api.message, ZAPI_MESSAGE_LABEL); api.nexthop_num = 0; api.nexthop = NULL; api.label_num = 0; @@ -1836,10 +1847,9 @@ bgp_zebra_withdraw (struct prefix *p, struct bgp_info *info, safi_t safi) api.type = ZEBRA_ROUTE_BGP; api.instance = 0; api.message = 0; - api.safi = (safi == SAFI_LABELED_UNICAST) ? SAFI_UNICAST : safi; + assert (safi != SAFI_LABELED_UNICAST); // remove this assert after testing + api.safi = safi; SET_FLAG (api.message, ZAPI_MESSAGE_NEXTHOP); - if (safi == SAFI_LABELED_UNICAST) - SET_FLAG (api.message, ZAPI_MESSAGE_LABEL); api.nexthop_num = 0; api.nexthop = NULL; api.ifindex_num = 0; diff --git a/bgpd/bgpd.c b/bgpd/bgpd.c index cf6c00ae5..1160066e8 100644 --- a/bgpd/bgpd.c +++ b/bgpd/bgpd.c @@ -1756,6 +1756,11 @@ non_peergroup_activate_af (struct peer *peer, afi_t afi, safi_t safi) return 1; } + /* Do not activate a peer for both SAFI_UNICAST and SAFI_LABELED_UNICAST */ + if ((safi == SAFI_UNICAST && peer->afc[afi][SAFI_LABELED_UNICAST]) || + (safi == SAFI_LABELED_UNICAST && peer->afc[afi][SAFI_UNICAST])) + return BGP_ERR_PEER_SAFI_CONFLICT; + /* Nothing to do if we've already activated this peer */ if (peer->afc[afi][safi]) return 0; @@ -1815,6 +1820,12 @@ peer_activate (struct peer *peer, afi_t afi, safi_t safi) * peer-group as well */ if (CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP)) { + + /* Do not activate a peer for both SAFI_UNICAST and SAFI_LABELED_UNICAST */ + if ((safi == SAFI_UNICAST && peer->afc[afi][SAFI_LABELED_UNICAST]) || + (safi == SAFI_LABELED_UNICAST && peer->afc[afi][SAFI_UNICAST])) + return BGP_ERR_PEER_SAFI_CONFLICT; + peer->afc[afi][safi] = 1; group = peer->group; diff --git a/bgpd/bgpd.h b/bgpd/bgpd.h index 84dcb7e1d..2e96f6cb9 100644 --- a/bgpd/bgpd.h +++ b/bgpd/bgpd.h @@ -1157,6 +1157,7 @@ enum bgp_clear_type #define BGP_ERR_INVALID_FOR_DYNAMIC_PEER -32 #define BGP_ERR_MAX -33 #define BGP_ERR_INVALID_FOR_DIRECT_PEER -34 +#define BGP_ERR_PEER_SAFI_CONFLICT -35 /* * Enumeration of different policy kinds a peer can be configured with. diff --git a/lib/mpls.h b/lib/mpls.h index 6cf014275..d78fcb1f5 100644 --- a/lib/mpls.h +++ b/lib/mpls.h @@ -76,8 +76,13 @@ typedef unsigned int mpls_lse_t; /* MPLS label value as a 32-bit (mostly we only care about the label value). */ typedef unsigned int mpls_label_t; -#define MPLS_NO_LABEL 0xFFFFFFFF -#define MPLS_INVALID_LABEL 0xFFFFFFFF +/* The MPLS explicit-null label is 0 which means when you memset a mpls_label_t + * to zero you have set that variable to explicit-null which was probably not + * your intent. The work-around is to use one bit to indicate if the + * mpls_label_t has been set by the user. MPLS_INVALID_LABEL has this bit clear + * so that we can use MPLS_INVALID_LABEL to initialize mpls_label_t variables. + */ +#define MPLS_INVALID_LABEL 0xFFFDFFFF /* LSP types. */ enum lsp_types_t diff --git a/lib/stream.c b/lib/stream.c index e8320a8fa..6163a5b3e 100644 --- a/lib/stream.c +++ b/lib/stream.c @@ -920,9 +920,10 @@ stream_put_prefix (struct stream *s, struct prefix *p) /* Put NLRI with label */ int -stream_put_labeled_prefix (struct stream *s, struct prefix *p, u_char *label) +stream_put_labeled_prefix (struct stream *s, struct prefix *p, mpls_label_t *label) { size_t psize; + u_char *label_pnt = (u_char *) label; STREAM_VERIFY_SANE(s); @@ -935,9 +936,9 @@ stream_put_labeled_prefix (struct stream *s, struct prefix *p, u_char *label) } stream_putc (s, (p->prefixlen + 24)); - stream_putc(s, label[0]); - stream_putc(s, label[1]); - stream_putc(s, label[2]); + stream_putc(s, label_pnt[0]); + stream_putc(s, label_pnt[1]); + stream_putc(s, label_pnt[2]); memcpy (s->data + s->endp, &p->u.prefix, psize); s->endp += psize; diff --git a/lib/stream.h b/lib/stream.h index dd6aae677..c012cc459 100644 --- a/lib/stream.h +++ b/lib/stream.h @@ -22,6 +22,7 @@ #ifndef _ZEBRA_STREAM_H #define _ZEBRA_STREAM_H +#include "mpls.h" #include "prefix.h" /* @@ -181,7 +182,7 @@ extern int stream_put_prefix_addpath (struct stream *, struct prefix *, u_int32_t addpath_tx_id); extern int stream_put_prefix (struct stream *, struct prefix *); extern int stream_put_labeled_prefix (struct stream *, struct prefix *, - u_char *); + mpls_label_t *); extern void stream_get (void *, struct stream *, size_t); extern void stream_get_from (void *, struct stream *, size_t, size_t); extern u_char stream_getc (struct stream *); diff --git a/zebra/zebra_mpls.c b/zebra/zebra_mpls.c index fb46184b6..fcf1a02eb 100644 --- a/zebra/zebra_mpls.c +++ b/zebra/zebra_mpls.c @@ -1876,7 +1876,7 @@ zebra_mpls_lsp_uninstall (struct zebra_vrf *zvrf, struct route_node *rn, struct * Registration from a client for the label binding for a FEC. If a binding * already exists, it is informed to the client. * NOTE: If there is a manually configured label binding, that is used. - * Otherwise, if aa label index is specified, it means we have to allocate the + * Otherwise, if a label index is specified, it means we have to allocate the * label from a locally configured label block (SRGB), if one exists and index * is acceptable. */ diff --git a/zebra/zserv.c b/zebra/zserv.c index ba42c67be..07d0d2f2c 100644 --- a/zebra/zserv.c +++ b/zebra/zserv.c @@ -989,6 +989,8 @@ zserv_fec_register (struct zserv *client, int sock, u_short length) label_index = stream_getl(s); l += 4; } + else + label_index = MPLS_INVALID_LABEL_INDEX; zebra_mpls_fec_register (zvrf, &p, label_index, client); } |