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.
This commit is contained in:
Daniel Walton 2017-06-16 19:12:57 +00:00
parent 62e4232010
commit 9bedbb1e52
24 changed files with 355 additions and 258 deletions

View File

@ -39,6 +39,7 @@
#include "bgpd/bgp_aspath.h" #include "bgpd/bgp_aspath.h"
#include "bgpd/bgp_community.h" #include "bgpd/bgp_community.h"
#include "bgpd/bgp_debug.h" #include "bgpd/bgp_debug.h"
#include "bgpd/bgp_label.h"
#include "bgpd/bgp_packet.h" #include "bgpd/bgp_packet.h"
#include "bgpd/bgp_ecommunity.h" #include "bgpd/bgp_ecommunity.h"
#include "bgpd/bgp_lcommunity.h" #include "bgpd/bgp_lcommunity.h"
@ -536,6 +537,7 @@ bgp_attr_extra_new (void)
struct attr_extra *extra; struct attr_extra *extra;
extra = XCALLOC (MTYPE_ATTR_EXTRA, sizeof (struct attr_extra)); extra = XCALLOC (MTYPE_ATTR_EXTRA, sizeof (struct attr_extra));
extra->label_index = BGP_INVALID_LABEL_INDEX; extra->label_index = BGP_INVALID_LABEL_INDEX;
extra->label = MPLS_INVALID_LABEL;
return extra; return extra;
} }
@ -579,6 +581,9 @@ bgp_attr_dup (struct attr *new, struct attr *orig)
{ {
new->extra = extra; new->extra = extra;
memset(new->extra, 0, sizeof(struct attr_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) { if (orig->extra) {
*new->extra = *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->flag |= ATTR_FLAG_BIT (BGP_ATTR_AS_PATH);
attr->extra->weight = BGP_ATTR_DEFAULT_WEIGHT; attr->extra->weight = BGP_ATTR_DEFAULT_WEIGHT;
attr->extra->tag = 0; 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->flag |= ATTR_FLAG_BIT (BGP_ATTR_NEXT_HOP);
attr->extra->mp_nexthop_len = IPV6_MAX_BYTELEN; 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); 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.weight = BGP_ATTR_DEFAULT_WEIGHT;
attre.mp_nexthop_len = IPV6_MAX_BYTELEN; attre.mp_nexthop_len = IPV6_MAX_BYTELEN;
if (! as_set || atomic_aggregate) if (! as_set || atomic_aggregate)
@ -2964,27 +2973,27 @@ bgp_packet_mpattr_start (struct stream *s, struct peer *peer,
void void
bgp_packet_mpattr_prefix (struct stream *s, afi_t afi, safi_t safi, bgp_packet_mpattr_prefix (struct stream *s, afi_t afi, safi_t safi,
struct prefix *p, struct prefix_rd *prd, 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) u_int32_t addpath_tx_id, struct attr *attr)
{ {
if (safi == SAFI_MPLS_VPN) if (safi == SAFI_MPLS_VPN)
{ {
if (addpath_encode) if (addpath_encode)
stream_putl(s, addpath_tx_id); stream_putl(s, addpath_tx_id);
/* Tag, RD, Prefix write. */ /* Label, RD, Prefix write. */
stream_putc (s, p->prefixlen + 88); 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, prd->val, 8);
stream_put (s, &p->u.prefix, PSIZE (p->prefixlen)); stream_put (s, &p->u.prefix, PSIZE (p->prefixlen));
} }
else if (safi == SAFI_EVPN) 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) else if (safi == SAFI_LABELED_UNICAST)
{ {
/* Prefix write with label. */ /* Prefix write with label. */
stream_put_labeled_prefix(s, p, tag); stream_put_labeled_prefix(s, p, label);
} }
else else
stream_put_prefix_addpath (s, p, addpath_encode, addpath_tx_id); 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 stream *s, struct attr *attr,
struct bpacket_attr_vec_arr *vecarr, struct bpacket_attr_vec_arr *vecarr,
struct prefix *p, afi_t afi, safi_t safi, 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, int addpath_encode,
u_int32_t addpath_tx_id) u_int32_t addpath_tx_id)
{ {
@ -3138,7 +3147,7 @@ bgp_packet_attribute (struct bgp *bgp, struct peer *peer,
size_t mpattrlen_pos = 0; size_t mpattrlen_pos = 0;
mpattrlen_pos = bgp_packet_mpattr_start(s, peer, afi, safi, vecarr, attr); 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); addpath_encode, addpath_tx_id, attr);
bgp_packet_mpattr_end(s, mpattrlen_pos); 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 void
bgp_packet_mpunreach_prefix (struct stream *s, struct prefix *p, bgp_packet_mpunreach_prefix (struct stream *s, struct prefix *p,
afi_t afi, safi_t safi, struct prefix_rd *prd, 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_int32_t addpath_tx_id, struct attr *attr)
{ {
u_char wlabel[3] = {0x80, 0x00, 0x00}; u_char wlabel[3] = {0x80, 0x00, 0x00};
if (safi == SAFI_LABELED_UNICAST) if (safi == SAFI_LABELED_UNICAST)
tag = wlabel; label = (mpls_label_t *) wlabel;
return bgp_packet_mpattr_prefix (s, afi, safi, p, prd, 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 void

View File

@ -21,6 +21,7 @@
#ifndef _QUAGGA_BGP_ATTR_H #ifndef _QUAGGA_BGP_ATTR_H
#define _QUAGGA_BGP_ATTR_H #define _QUAGGA_BGP_ATTR_H
#include "mpls.h"
#include "bgp_attr_evpn.h" #include "bgp_attr_evpn.h"
/* Simple bit mapping. */ /* Simple bit mapping. */
@ -145,6 +146,9 @@ struct attr_extra
/* Label index */ /* Label index */
u_int32_t label_index; u_int32_t label_index;
/* MPLS label */
mpls_label_t label;
uint16_t encap_tunneltype; /* grr */ uint16_t encap_tunneltype; /* grr */
struct bgp_attr_encap_subtlv *encap_subtlvs; /* rfc5512 */ 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 bpacket_attr_vec_arr *vecarr,
struct prefix *, afi_t, safi_t, struct prefix *, afi_t, safi_t,
struct peer *, struct prefix_rd *, 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 *, extern void bgp_dump_routes_attr (struct stream *, struct attr *,
struct prefix *); struct prefix *);
extern int attrhash_cmp (const void *, const void *); 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); struct attr *attr);
extern void bgp_packet_mpattr_prefix(struct stream *s, afi_t afi, safi_t safi, extern void bgp_packet_mpattr_prefix(struct stream *s, afi_t afi, safi_t safi,
struct prefix *p, struct prefix_rd *prd, 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, u_int32_t addpath_tx_id,
struct attr *); struct attr *);
extern size_t bgp_packet_mpattr_prefix_size(afi_t afi, safi_t safi, 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); safi_t safi);
extern void bgp_packet_mpunreach_prefix (struct stream *s, struct prefix *p, extern void bgp_packet_mpunreach_prefix (struct stream *s, struct prefix *p,
afi_t afi, safi_t safi, struct prefix_rd *prd, 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); extern void bgp_packet_mpunreach_end (struct stream *s, size_t attrlen_pnt);
static inline int static inline int

View File

@ -33,6 +33,7 @@
#include "bgpd/bgp_route.h" #include "bgpd/bgp_route.h"
#include "bgpd/bgp_attr.h" #include "bgpd/bgp_attr.h"
#include "bgpd/bgp_mplsvpn.h" #include "bgpd/bgp_mplsvpn.h"
#include "bgpd/bgp_label.h"
#include "bgpd/bgp_evpn.h" #include "bgpd/bgp_evpn.h"
int int
@ -46,7 +47,7 @@ bgp_nlri_parse_evpn(struct peer *peer, struct attr *attr,
struct evpn_addr *p_evpn_p; struct evpn_addr *p_evpn_p;
struct bgp_route_evpn evpn; struct bgp_route_evpn evpn;
uint8_t route_type, route_length; uint8_t route_type, route_length;
u_char *pnt_label; mpls_label_t label;
u_int32_t addpath_id = 0; u_int32_t addpath_id = 0;
/* Check peer status. */ /* Check peer status. */
@ -146,22 +147,23 @@ bgp_nlri_parse_evpn(struct peer *peer, struct attr *attr,
} }
/* Fetch Label */ /* Fetch Label */
if (pnt + 3 > lim) { if (pnt + BGP_LABEL_BYTES > lim) {
zlog_err("not enough bytes for Label left in NLRI?"); zlog_err("not enough bytes for Label left in NLRI?");
return -1; return -1;
} }
pnt_label = pnt;
pnt += 3; memcpy(&label, pnt, BGP_LABEL_BYTES);
bgp_set_valid_label(&label);
pnt += BGP_LABEL_BYTES;
if (!withdraw) { if (!withdraw) {
bgp_update(peer, &p, addpath_id, attr, AFI_L2VPN, bgp_update(peer, &p, addpath_id, attr, AFI_L2VPN,
SAFI_EVPN, ZEBRA_ROUTE_BGP, BGP_ROUTE_NORMAL, SAFI_EVPN, ZEBRA_ROUTE_BGP, BGP_ROUTE_NORMAL,
&prd, pnt_label, 0, &evpn); &prd, &label, 0, &evpn);
} else { } else {
bgp_withdraw(peer, &p, addpath_id, attr, AFI_L2VPN, bgp_withdraw(peer, &p, addpath_id, attr, AFI_L2VPN,
SAFI_EVPN, ZEBRA_ROUTE_BGP, 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 void
bgp_packet_mpattr_route_type_5(struct stream *s, bgp_packet_mpattr_route_type_5(struct stream *s,
struct prefix *p, struct prefix_rd *prd, struct prefix *p, struct prefix_rd *prd,
u_char * label, struct attr *attr) mpls_label_t *label, struct attr *attr)
{ {
int len; int len;
char temp[16]; char temp[16];

View File

@ -27,7 +27,7 @@ extern int bgp_nlri_parse_evpn(struct peer *peer, struct attr *attr,
extern void extern void
bgp_packet_mpattr_route_type_5(struct stream *s, bgp_packet_mpattr_route_type_5(struct stream *s,
struct prefix *p, struct prefix_rd *prd, 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 /* EVPN route types as per RFC7432 and
* as per draft-ietf-bess-evpn-prefix-advertisement-02 * as per draft-ietf-bess-evpn-prefix-advertisement-02
*/ */

View File

@ -63,7 +63,7 @@ bgp_parse_fec_update (void)
/* hack for the bgp instance & SAFI = have to send/receive it */ /* hack for the bgp instance & SAFI = have to send/receive it */
afi = family2afi(p.family); afi = family2afi(p.family);
safi = SAFI_LABELED_UNICAST; safi = SAFI_UNICAST;
bgp = bgp_get_default(); bgp = bgp_get_default();
if (!bgp) if (!bgp)
{ {
@ -74,7 +74,7 @@ bgp_parse_fec_update (void)
table = bgp->rib[afi][safi]; table = bgp->rib[afi][safi];
if (!table) if (!table)
{ {
zlog_debug("no %u labeled-unicast table", p.family); zlog_debug("no %u unicast table", p.family);
return -1; return -1;
} }
rn = bgp_node_lookup(table, &p); rn = bgp_node_lookup(table, &p);
@ -86,11 +86,11 @@ bgp_parse_fec_update (void)
/* treat it as implicit withdraw - the label is invalid */ /* treat it as implicit withdraw - the label is invalid */
if (label == MPLS_INVALID_LABEL) if (label == MPLS_INVALID_LABEL)
bgp_unset_valid_label(rn->local_label); bgp_unset_valid_label(&rn->local_label);
else else
{ {
label_ntop(label, 1, rn->local_label); label_ntop(label, 1, &rn->local_label);
bgp_set_valid_label(rn->local_label); bgp_set_valid_label(&rn->local_label);
} }
SET_FLAG(rn->flags, BGP_NODE_LABEL_CHANGED); SET_FLAG(rn->flags, BGP_NODE_LABEL_CHANGED);
bgp_unlock_node (rn); bgp_unlock_node (rn);
@ -98,18 +98,18 @@ bgp_parse_fec_update (void)
return 1; return 1;
} }
u_char * mpls_label_t
bgp_adv_label (struct bgp_node *rn, struct bgp_info *ri, struct peer *to, bgp_adv_label (struct bgp_node *rn, struct bgp_info *ri, struct peer *to,
afi_t afi, safi_t safi) afi_t afi, safi_t safi)
{ {
struct peer *from; struct peer *from;
u_char *remote_label; mpls_label_t remote_label;
int reflect; int reflect;
if (!rn || !ri || !to) 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; from = ri->peer;
reflect = ((from->sort == BGP_PEER_IBGP) && (to->sort == BGP_PEER_IBGP)); 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 static int
bgp_nlri_get_labels (struct peer *peer, u_char *pnt, u_char plen, bgp_nlri_get_labels (struct peer *peer, u_char *pnt, u_char plen, mpls_label_t *label)
u_char label[])
{ {
u_char *data = pnt; u_char *data = pnt;
u_char *lim = pnt + plen; u_char *lim = pnt + plen;
u_char llen = 0; u_char llen = 0;
u_char label_index = 0;
for (; data < lim; data += BGP_LABEL_BYTES) for (; data < lim; data += BGP_LABEL_BYTES)
{ {
memcpy(label, 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)) if (bgp_is_withdraw_label(label) || label_bos(label))
break; 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))) 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); peer->host);
return llen; return llen;
@ -206,7 +218,7 @@ bgp_nlri_parse_label (struct peer *peer, struct attr *attr,
safi_t safi; safi_t safi;
int addpath_encoded; int addpath_encoded;
u_int32_t addpath_id; u_int32_t addpath_id;
u_char label[3]; mpls_label_t label = MPLS_INVALID_LABEL;
u_char llen; u_char llen;
/* Check peer status. */ /* Check peer status. */
@ -254,8 +266,7 @@ bgp_nlri_parse_label (struct peer *peer, struct attr *attr,
} }
/* Fill in the labels */ /* Fill in the labels */
llen = bgp_nlri_get_labels(peer, pnt, psize, label); 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);
p.prefixlen = prefixlen - BSIZE(llen); p.prefixlen = prefixlen - BSIZE(llen);
/* There needs to be at least one label */ /* There needs to be at least one label */
@ -319,13 +330,13 @@ bgp_nlri_parse_label (struct peer *peer, struct attr *attr,
if (attr) if (attr)
{ {
bgp_update (peer, &p, addpath_id, attr, packet->afi, SAFI_LABELED_UNICAST, bgp_update (peer, &p, addpath_id, attr, packet->afi, SAFI_UNICAST,
ZEBRA_ROUTE_BGP, BGP_ROUTE_NORMAL, NULL, label, 0, NULL); ZEBRA_ROUTE_BGP, BGP_ROUTE_NORMAL, NULL, &label, 0, NULL);
} }
else else
{ {
bgp_withdraw (peer, &p, addpath_id, attr, packet->afi, SAFI_LABELED_UNICAST, bgp_withdraw (peer, &p, addpath_id, attr, packet->afi, SAFI_UNICAST,
ZEBRA_ROUTE_BGP, BGP_ROUTE_NORMAL, NULL, label, NULL); ZEBRA_ROUTE_BGP, BGP_ROUTE_NORMAL, NULL, &label, NULL);
} }
} }

View File

@ -32,8 +32,8 @@ struct peer;
extern void bgp_reg_dereg_for_label (struct bgp_node *rn, struct bgp_info *ri, extern void bgp_reg_dereg_for_label (struct bgp_node *rn, struct bgp_info *ri,
int reg); int reg);
extern int bgp_parse_fec_update(void); extern int bgp_parse_fec_update(void);
extern u_char * bgp_adv_label(struct bgp_node *rn, struct bgp_info *ri, extern 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 *to, afi_t afi, safi_t safi);
extern int bgp_nlri_parse_label (struct peer *peer, struct attr *attr, extern int bgp_nlri_parse_label (struct peer *peer, struct attr *attr,
struct bgp_nlri *packet); struct bgp_nlri *packet);
@ -48,38 +48,35 @@ bgp_labeled_safi (safi_t safi)
} }
static inline int 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)) if ((pkt[0] == 0x80) && (pkt[1] == 0x00) && (pkt[2] == 0x00))
return 1; return 1;
return 0; return 0;
} }
static inline u_char *
bgp_encode_withdraw_label (u_char *pkt)
{
*pkt++ = 0x80; *pkt++ = 0x00; *pkt++ = 0x00;
return pkt;
}
static inline int 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) if (!t)
return 0; return 0;
return (t[2] & 0x02); return (t[2] & 0x02);
} }
static inline void 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) if (t)
t[2] |= 0x02; t[2] |= 0x02;
} }
static inline void 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) if (t)
t[2] &= ~0x02; t[2] &= ~0x02;
} }
@ -98,16 +95,18 @@ bgp_unregister_for_label (struct bgp_node *rn)
/* Label stream to value */ /* Label stream to value */
static inline u_int32_t 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) | return ((((unsigned int) t[0]) << 12) | (((unsigned int) t[1]) << 4) |
((unsigned int) ((t[2] & 0xF0) >> 4))); ((unsigned int) ((t[2] & 0xF0) >> 4)));
} }
/* Encode label values */ /* Encode label values */
static inline void 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[0] = ((l & 0x000FF000) >> 12);
t[1] = ((l & 0x00000FF0) >> 4); t[1] = ((l & 0x00000FF0) >> 4);
t[2] = ((l & 0x0000000F) << 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 */ /* Return BOS value of label stream */
static inline u_char 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); return (t[2] & 0x01);
}; };

View File

@ -27,12 +27,13 @@
#include "stream.h" #include "stream.h"
#include "queue.h" #include "queue.h"
#include "filter.h" #include "filter.h"
#include "lib/json.h" #include "lib/json.h"
#include "bgpd/bgpd.h" #include "bgpd/bgpd.h"
#include "bgpd/bgp_table.h" #include "bgpd/bgp_table.h"
#include "bgpd/bgp_route.h" #include "bgpd/bgp_route.h"
#include "bgpd/bgp_attr.h" #include "bgpd/bgp_attr.h"
#include "bgpd/bgp_label.h"
#include "bgpd/bgp_mplsvpn.h" #include "bgpd/bgp_mplsvpn.h"
#include "bgpd/bgp_packet.h" #include "bgpd/bgp_packet.h"
#include "bgpd/bgp_vty.h" #include "bgpd/bgp_vty.h"
@ -87,9 +88,10 @@ encode_rd_type (u_int16_t v, u_char *pnt)
} }
u_int32_t u_int32_t
decode_label (u_char *pnt) decode_label (mpls_label_t *label_pnt)
{ {
u_int32_t l; u_int32_t l;
u_char *pnt = (u_char *) label_pnt;
l = ((u_int32_t) *pnt++ << 12); l = ((u_int32_t) *pnt++ << 12);
l |= (u_int32_t) *pnt++ << 4; l |= (u_int32_t) *pnt++ << 4;
@ -98,9 +100,10 @@ decode_label (u_char *pnt)
} }
void void
encode_label(u_int32_t label, encode_label(mpls_label_t label,
u_char *pnt) mpls_label_t *label_pnt)
{ {
u_char *pnt = (u_char *) label_pnt;
if (pnt == NULL) if (pnt == NULL)
return; return;
*pnt++ = (label>>12) & 0xff; *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_as rd_as;
struct rd_ip rd_ip; struct rd_ip rd_ip;
struct prefix_rd prd; struct prefix_rd prd;
u_char *tagpnt; mpls_label_t label;
afi_t afi; afi_t afi;
safi_t safi; safi_t safi;
int addpath_encoded; int addpath_encoded;
@ -249,14 +252,15 @@ bgp_nlri_parse_vpn (struct peer *peer, struct attr *attr,
return -1; return -1;
} }
/* Copyr label to prefix. */ /* Copy label to prefix. */
tagpnt = pnt; memcpy(&label, pnt, BGP_LABEL_BYTES);
bgp_set_valid_label(&label);
/* Copy routing distinguisher to rd. */ /* Copy routing distinguisher to rd. */
memcpy (&prd.val, pnt + 3, 8); memcpy (&prd.val, pnt + BGP_LABEL_BYTES, 8);
/* Decode RD type. */ /* Decode RD type. */
type = decode_rd_type (pnt + 3); type = decode_rd_type (pnt + BGP_LABEL_BYTES);
switch (type) switch (type)
{ {
@ -289,12 +293,12 @@ bgp_nlri_parse_vpn (struct peer *peer, struct attr *attr,
if (attr) if (attr)
{ {
bgp_update (peer, &p, addpath_id, attr, packet->afi, SAFI_MPLS_VPN, 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 else
{ {
bgp_withdraw (peer, &p, addpath_id, attr, packet->afi, SAFI_MPLS_VPN, 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. */ /* Packet length consistency check. */

View File

@ -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 encode_rd_type (u_int16_t, u_char *);
extern void bgp_mplsvpn_init (void); extern void bgp_mplsvpn_init (void);
extern int bgp_nlri_parse_vpn (struct peer *, struct attr *, struct bgp_nlri *); extern int bgp_nlri_parse_vpn (struct peer *, struct attr *, struct bgp_nlri *);
extern u_int32_t decode_label (u_char *); extern u_int32_t decode_label (mpls_label_t *);
extern void encode_label(u_int32_t, u_char *); extern void encode_label(mpls_label_t, mpls_label_t *);
extern void decode_rd_as (u_char *, struct rd_as *); extern void decode_rd_as (u_char *, struct rd_as *);
extern void decode_rd_as4 (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 *); extern void decode_rd_ip (u_char *, struct rd_ip *);

View File

@ -1391,6 +1391,7 @@ bgp_update_receive (struct peer *peer, bgp_size_t size)
memset (&attr, 0, sizeof (struct attr)); memset (&attr, 0, sizeof (struct attr));
memset (&extra, 0, sizeof (struct attr_extra)); memset (&extra, 0, sizeof (struct attr_extra));
extra.label_index = BGP_INVALID_LABEL_INDEX; extra.label_index = BGP_INVALID_LABEL_INDEX;
extra.label = MPLS_INVALID_LABEL;
memset (&nlris, 0, sizeof (nlris)); memset (&nlris, 0, sizeof (nlris));
attr.extra = &extra; attr.extra = &extra;
memset (peer->rcvd_attr_str, 0, BUFSIZ); memset (peer->rcvd_attr_str, 0, BUFSIZ);

View File

@ -35,7 +35,6 @@
#include "thread.h" #include "thread.h"
#include "workqueue.h" #include "workqueue.h"
#include "queue.h" #include "queue.h"
#include "mpls.h"
#include "memory.h" #include "memory.h"
#include "lib/json.h" #include "lib/json.h"
@ -117,6 +116,7 @@ bgp_info_extra_new (void)
{ {
struct bgp_info_extra *new; struct bgp_info_extra *new;
new = XCALLOC (MTYPE_BGP_ROUTE_EXTRA, sizeof (struct bgp_info_extra)); new = XCALLOC (MTYPE_BGP_ROUTE_EXTRA, sizeof (struct bgp_info_extra));
new->label = MPLS_INVALID_LABEL;
return new; return new;
} }
@ -694,7 +694,17 @@ bgp_info_cmp (struct bgp *bgp, struct bgp_info *new, struct bgp_info *exist,
/* 11. Maximum path check. */ /* 11. Maximum path check. */
if (newm == existm) 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 it's labeled safi, make sure the route has a valid label. */
if (safi == SAFI_LABELED_UNICAST) if (safi == SAFI_LABELED_UNICAST)
{ {
u_char *tag = bgp_adv_label(rn, ri, peer, afi, safi); mpls_label_t label = bgp_adv_label(rn, ri, peer, afi, safi);
if (!bgp_is_valid_label(tag)) if (!bgp_is_valid_label(&label))
{ {
if (bgp_debug_update(NULL, p, subgrp->update_group, 0)) if (bgp_debug_update(NULL, p, subgrp->update_group, 0))
zlog_debug ("u%" PRIu64 ":s%" PRIu64 " %s/%d is filtered - no label (%p)", zlog_debug ("u%" PRIu64 ":s%" PRIu64 " %s/%d is filtered - no label (%p)",
subgrp->update_group->id, subgrp->id, subgrp->update_group->id, subgrp->id,
inet_ntop(p->family, &p->u.prefix, buf, SU_ADDRSTRLEN), inet_ntop(p->family, &p->u.prefix, buf, SU_ADDRSTRLEN),
p->prefixlen, tag); p->prefixlen, &label);
return 0; 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 * 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. * 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)); bgp_table_lock (bgp_node_table (rn));
if (new_select) 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)) if (CHECK_FLAG (rn->flags, BGP_NODE_REGISTERED_FOR_LABEL))
bgp_unregister_for_label (rn); bgp_unregister_for_label (rn);
label_ntop (MPLS_IMP_NULL_LABEL, 1, rn->local_label); label_ntop (MPLS_IMP_NULL_LABEL, 1, &rn->local_label);
bgp_set_valid_label(rn->local_label); bgp_set_valid_label(&rn->local_label);
} }
else else
bgp_register_for_label (rn, new_select); 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); 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 (old_select->flags, BGP_INFO_ATTR_CHANGED);
UNSET_FLAG (rn->flags, BGP_NODE_LABEL_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); 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. */ /* FIB update. */
if (bgp_fibupd_safi(safi) && if (bgp_fibupd_safi(safi) &&
(bgp->inst_type != BGP_INSTANCE_TYPE_VIEW) && (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 int
bgp_update (struct peer *peer, struct prefix *p, u_int32_t addpath_id, bgp_update (struct peer *peer, struct prefix *p, u_int32_t addpath_id,
struct attr *attr, afi_t afi, safi_t safi, int type, 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 soft_reconfig, struct bgp_route_evpn* evpn)
{ {
int ret; int ret;
@ -2481,18 +2499,24 @@ bgp_update (struct peer *peer, struct prefix *p, u_int32_t addpath_id,
char label_buf[20]; char label_buf[20];
int connected = 0; int connected = 0;
int do_loop_check = 1; int do_loop_check = 1;
int has_valid_label = 0;
#if ENABLE_BGP_VNC #if ENABLE_BGP_VNC
int vnc_implicit_withdraw = 0; int vnc_implicit_withdraw = 0;
#endif #endif
memset (&new_attr, 0, sizeof(struct attr)); memset (&new_attr, 0, sizeof(struct attr));
memset (&new_extra, 0, sizeof(struct attr_extra)); 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; bgp = peer->bgp;
rn = bgp_afi_node_get (bgp->rib[afi][safi], afi, safi, p, prd); rn = bgp_afi_node_get (bgp->rib[afi][safi], afi, safi, p, prd);
label_buf[0] = '\0'; 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 /* When peer's soft reconfiguration enabled. Record input packet in
Adj-RIBs-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. */ /* Same attribute comes in. */
if (!CHECK_FLAG (ri->flags, BGP_INFO_REMOVED) if (!CHECK_FLAG (ri->flags, BGP_INFO_REMOVED)
&& attrhash_cmp (ri->attr, attr_new) && attrhash_cmp (ri->attr, attr_new)
&& (!bgp_labeled_safi(safi) || && (!has_valid_label ||
memcmp ((bgp_info_extra_get (ri))->tag, tag, 3) == 0) memcmp (&(bgp_info_extra_get (ri))->label, label, BGP_LABEL_BYTES) == 0)
&& (overlay_index_equal(afi, ri, evpn==NULL?NULL:&evpn->eth_s_id, && (overlay_index_equal(afi, ri, evpn==NULL?NULL:&evpn->eth_s_id,
evpn==NULL?NULL:&evpn->gw_ip))) 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); bgp_attr_unintern (&ri->attr);
ri->attr = attr_new; ri->attr = attr_new;
/* Update MPLS tag. */ /* Update MPLS label */
if (bgp_labeled_safi(safi)) if (has_valid_label)
memcpy ((bgp_info_extra_get (ri))->tag, tag, 3); {
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 ENABLE_BGP_VNC
if ((afi == AFI_IP || afi == AFI_IP6) && (safi == SAFI_UNICAST)) 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 ENABLE_BGP_VNC
if (SAFI_MPLS_VPN == safi) 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, rfapiProcessUpdate(peer, NULL, p, prd, attr, afi, safi, type, sub_type,
&label); &label_decoded);
} }
if (SAFI_ENCAP == safi) 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. */ /* Make new BGP info. */
new = info_make(type, sub_type, 0, peer, attr_new, rn); new = info_make(type, sub_type, 0, peer, attr_new, rn);
/* Update MPLS tag. */ /* Update MPLS label */
if (bgp_labeled_safi(safi)) if (has_valid_label)
memcpy ((bgp_info_extra_get (new))->tag, tag, 3); {
memcpy (&(bgp_info_extra_get (new))->label, label, BGP_LABEL_BYTES);
bgp_set_valid_label(&(bgp_info_extra_get (new))->label);
}
/* Update Overlay Index */ /* Update Overlay Index */
if(afi == AFI_L2VPN) 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 ENABLE_BGP_VNC
if (SAFI_MPLS_VPN == safi) 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, rfapiProcessUpdate(peer, NULL, p, prd, attr, afi, safi, type, sub_type,
&label); &label_decoded);
} }
if (SAFI_ENCAP == safi) if (SAFI_ENCAP == safi)
{ {
@ -2981,7 +3011,7 @@ bgp_update (struct peer *peer, struct prefix *p, u_int32_t addpath_id,
int int
bgp_withdraw (struct peer *peer, struct prefix *p, u_int32_t addpath_id, 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 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; struct bgp *bgp;
char pfx_buf[BGP_PRD_PATH_STRLEN]; 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) if (ain->peer == peer)
{ {
struct bgp_info *ri = rn->info; 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, ret = bgp_update (peer, &rn->p, ain->addpath_rx_id, ain->attr,
afi, safi, ZEBRA_ROUTE_BGP, BGP_ROUTE_NORMAL, afi, safi, ZEBRA_ROUTE_BGP, BGP_ROUTE_NORMAL,
prd, tag, 1, NULL); prd, &label, 1, NULL);
if (ret < 0) if (ret < 0)
{ {
@ -4021,7 +4051,7 @@ bgp_static_withdraw (struct bgp *bgp, struct prefix *p, afi_t afi,
*/ */
static void static void
bgp_static_withdraw_safi (struct bgp *bgp, struct prefix *p, afi_t afi, 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_node *rn;
struct bgp_info *ri; struct bgp_info *ri;
@ -4134,8 +4164,7 @@ bgp_static_update_safi (struct bgp *bgp, struct prefix *p,
/* Unintern original. */ /* Unintern original. */
aspath_unintern (&attr.aspath); aspath_unintern (&attr.aspath);
bgp_attr_extra_free (&attr); bgp_attr_extra_free (&attr);
bgp_static_withdraw_safi (bgp, p, afi, safi, &bgp_static->prd, bgp_static_withdraw_safi (bgp, p, afi, safi, &bgp_static->prd);
bgp_static->tag);
return; return;
} }
@ -4204,9 +4233,9 @@ bgp_static_update_safi (struct bgp *bgp, struct prefix *p,
rn); rn);
SET_FLAG (new->flags, BGP_INFO_VALID); SET_FLAG (new->flags, BGP_INFO_VALID);
new->extra = bgp_info_extra_new(); new->extra = bgp_info_extra_new();
memcpy (new->extra->tag, bgp_static->tag, 3); new->extra->label = bgp_static->label;
#if ENABLE_BGP_VNC #if ENABLE_BGP_VNC
label = decode_label (bgp_static->tag); label = decode_label (bgp_static->label);
#endif #endif
/* Aggregate address increment. */ /* Aggregate address increment. */
@ -4437,8 +4466,7 @@ bgp_static_delete (struct bgp *bgp)
bgp_static = rm->info; bgp_static = rm->info;
bgp_static_withdraw_safi (bgp, &rm->p, bgp_static_withdraw_safi (bgp, &rm->p,
AFI_IP, safi, AFI_IP, safi,
(struct prefix_rd *)&rn->p, (struct prefix_rd *)&rn->p);
bgp_static->tag);
bgp_static_free (bgp_static); bgp_static_free (bgp_static);
rn->info = NULL; rn->info = NULL;
bgp_unlock_node (rn); 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_node *rn;
struct bgp_table *table; struct bgp_table *table;
struct bgp_static *bgp_static; struct bgp_static *bgp_static;
u_char tag[3]; mpls_label_t label = MPLS_INVALID_LABEL;
struct prefix gw_ip; struct prefix gw_ip;
/* validate ip prefix */ /* 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) if (label_str)
{ {
unsigned long label_val; unsigned long label_val;
VTY_GET_INTEGER_RANGE("Label/tag", label_val, label_str, 0, 16777215); VTY_GET_INTEGER_RANGE("Label", label_val, label_str, 0, 16777215);
encode_label (label_val, tag); encode_label (label_val, &label);
}
else
{
memset (tag, 0, sizeof(tag)); /* empty, not even BoS */
} }
if (safi == SAFI_EVPN) if (safi == SAFI_EVPN)
{ {
if( esi && str2esi (esi, NULL) == 0) 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->valid = 0;
bgp_static->igpmetric = 0; bgp_static->igpmetric = 0;
bgp_static->igpnexthop.s_addr = 0; bgp_static->igpnexthop.s_addr = 0;
memcpy(bgp_static->tag, tag, 3); bgp_static->label = label;
bgp_static->prd = prd; bgp_static->prd = prd;
if (rmap_str) 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_node *rn;
struct bgp_table *table; struct bgp_table *table;
struct bgp_static *bgp_static; struct bgp_static *bgp_static;
u_char tag[3]; mpls_label_t label = MPLS_INVALID_LABEL;
/* Convert IP prefix string to struct prefix. */ /* Convert IP prefix string to struct prefix. */
ret = str2prefix (ip_str, &p); 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) if (label_str)
{ {
unsigned long label_val; unsigned long label_val;
VTY_GET_INTEGER_RANGE("Label/tag", label_val, label_str, 0, MPLS_LABEL_MAX); VTY_GET_INTEGER_RANGE("Label", label_val, label_str, 0, MPLS_LABEL_MAX);
encode_label (label_val, tag); encode_label (label_val, &label);
}
else
{
memset (tag, 0, sizeof(tag)); /* empty, not even BoS */
} }
prn = bgp_node_get (bgp->route[afi][safi], 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) 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 = rn->info;
bgp_static_free (bgp_static); bgp_static_free (bgp_static);
@ -6658,7 +6679,7 @@ route_vty_out_tag (struct vty *vty, struct prefix *p,
{ {
json_object *json_out = NULL; json_object *json_out = NULL;
struct attr *attr; struct attr *attr;
u_int32_t label = 0; mpls_label_t label = MPLS_INVALID_LABEL;
if (!binfo->extra) if (!binfo->extra)
return; 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) if (json)
json_object_int_add(json_out, "notag", label); {
json_object_array_add(json, json_out); json_object_int_add(json_out, "notag", label);
} json_object_array_add(json, json_out);
else }
{ else
vty_out (vty, "notag/%d", label); {
vty_out (vty, "notag/%d%s", label, VTY_NEWLINE);
vty_out (vty, "%s", 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) if (binfo->extra && binfo->extra->damp_info)
bgp_damp_info_vty (vty, binfo, json_path); bgp_damp_info_vty (vty, binfo, json_path);
/* Remove Label */ /* Remote Label */
if (bgp_labeled_safi(safi) && binfo->extra) 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) if (json_paths)
json_object_int_add(json_path, "remoteLabel", label); json_object_int_add(json_path, "remoteLabel", label);
else else
@ -8124,12 +8146,21 @@ route_vty_out_detail_header (struct vty *vty, struct bgp *bgp,
int no_advertise = 0; int no_advertise = 0;
int local_as = 0; int local_as = 0;
int first = 1; int first = 1;
int has_valid_label = 0;
uint32_t label = 0;
json_object *json_adv_to = NULL; json_object *json_adv_to = NULL;
p = &rn->p; 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 (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_string_add(json, "prefix", inet_ntop (p->family, &p->u.prefix, buf2, INET6_ADDRSTRLEN));
json_object_int_add(json, "prefixlen", p->prefixlen); json_object_int_add(json, "prefixlen", p->prefixlen);
} }
@ -8146,17 +8177,10 @@ route_vty_out_detail_header (struct vty *vty, struct bgp *bgp,
buf2, buf2,
p->prefixlen, VTY_NEWLINE); p->prefixlen, VTY_NEWLINE);
if (bgp_labeled_safi(safi)) if (has_valid_label)
{ vty_out(vty, "Local label: %d%s", label, VTY_NEWLINE);
vty_out(vty, "Local label: "); else if (bgp_labeled_safi(safi))
if (!bgp_is_valid_label(rn->local_label)) vty_out(vty, "Local label: not allocated%s", VTY_NEWLINE);
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);
}
}
} }
for (ri = rn->info; ri; ri = ri->next) 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, DEFUN (show_ip_bgp_large_community_list,
show_ip_bgp_large_community_list_cmd, 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 SHOW_STR
IP_STR IP_STR
BGP_STR BGP_STR
BGP_INSTANCE_HELP_STR BGP_INSTANCE_HELP_STR
"Address Family\n" BGP_AFI_HELP_STR
"Address Family\n" BGP_SAFI_HELP_STR
"Address Family modifier\n"
"Address Family modifier\n"
"Address Family modifier\n"
"Address Family modifier\n"
"Display routes matching the large-community-list\n" "Display routes matching the large-community-list\n"
"large-community-list number\n" "large-community-list number\n"
"large-community-list name\n" "large-community-list name\n"
@ -8484,17 +8504,13 @@ DEFUN (show_ip_bgp_large_community_list,
} }
DEFUN (show_ip_bgp_large_community, DEFUN (show_ip_bgp_large_community,
show_ip_bgp_large_community_cmd, 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 SHOW_STR
IP_STR IP_STR
BGP_STR BGP_STR
BGP_INSTANCE_HELP_STR BGP_INSTANCE_HELP_STR
"Address Family\n" BGP_AFI_HELP_STR
"Address Family\n" BGP_SAFI_HELP_STR
"Address Family modifier\n"
"Address Family modifier\n"
"Address Family modifier\n"
"Address Family modifier\n"
"Display routes matching the large-communities\n" "Display routes matching the large-communities\n"
"List of large-community numbers\n" "List of large-community numbers\n"
JSON_STR) 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, DEFUN (show_ip_bgp_instance_neighbor_prefix_counts,
show_ip_bgp_instance_neighbor_prefix_counts_cmd, 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]", "neighbors <A.B.C.D|X:X::X:X|WORD> prefix-counts [json]",
SHOW_STR SHOW_STR
IP_STR IP_STR
BGP_STR BGP_STR
BGP_INSTANCE_HELP_STR BGP_INSTANCE_HELP_STR
"Address Family\n" BGP_AFI_HELP_STR
"Address Family\n" BGP_SAFI_HELP_STR
"Address Family modifier\n"
"Address Family modifier\n"
"Address Family modifier\n"
"Address Family modifier\n"
"Address Family modifier\n" "Address Family modifier\n"
"Detailed information on TCP and BGP neighbor connections\n" "Detailed information on TCP and BGP neighbor connections\n"
"Neighbor to display information about\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 *p;
struct prefix_rd *prd; struct prefix_rd *prd;
struct bgp_static *bgp_static; struct bgp_static *bgp_static;
u_int32_t label; mpls_label_t label;
char buf[SU_ADDRSTRLEN]; char buf[SU_ADDRSTRLEN];
char rdbuf[RD_ADDRSTRLEN]; char rdbuf[RD_ADDRSTRLEN];
@ -10656,7 +10668,7 @@ bgp_config_write_network_vpn (struct vty *vty, struct bgp *bgp,
/* "network" configuration display. */ /* "network" configuration display. */
prefix_rd2str (prd, rdbuf, RD_ADDRSTRLEN); 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", vty_out (vty, " network %s/%d rd %s",
inet_ntop (p->family, &p->u.prefix, buf, SU_ADDRSTRLEN), 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)), prefix2str (p, buf, sizeof (buf)),
vty_out (vty, " network %s rd %s ethtag %u tag %u esi %s gwip %s routermac %s", 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, 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); vty_out (vty, "%s", VTY_NEWLINE);
if (macrouter) if (macrouter)
XFREE (MTYPE_TMP, 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_route_map_cmd);
install_element (BGP_IPV4_NODE, &bgp_network_mask_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_IPV4_NODE, &bgp_network_mask_natural_route_map_cmd);
install_element (BGP_IPV4L_NODE, &no_bgp_network_label_index_cmd); install_element (BGP_IPV4_NODE, &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_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_table_map_cmd);
install_element (BGP_IPV4_NODE, &no_bgp_network_cmd); install_element (BGP_IPV4_NODE, &no_bgp_network_cmd);
install_element (BGP_IPV4_NODE, &no_bgp_network_mask_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); install_element (BGP_IPV4M_NODE, &no_aggregate_address_mask_cmd);
/* IPv4 labeled-unicast configuration. */ /* 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_instance_all_cmd);
install_element (VIEW_NODE, &show_ip_bgp_cmd); install_element (VIEW_NODE, &show_ip_bgp_cmd);
install_element (VIEW_NODE, &show_ip_bgp_route_cmd); install_element (VIEW_NODE, &show_ip_bgp_route_cmd);

View File

@ -74,7 +74,7 @@ struct bgp_info_extra
u_int32_t igpmetric; u_int32_t igpmetric;
/* MPLS label. */ /* MPLS label. */
u_char tag[3]; mpls_label_t label;
#if ENABLE_BGP_VNC #if ENABLE_BGP_VNC
union { union {
@ -207,7 +207,7 @@ struct bgp_static
struct prefix_rd prd; struct prefix_rd prd;
/* MPLS label. */ /* MPLS label. */
u_char tag[3]; mpls_label_t label;
/* EVPN */ /* EVPN */
struct eth_segment_id *eth_s_id; 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 */ /* this is primarily for MPLS-VPN */
extern int bgp_update (struct peer *, struct prefix *, u_int32_t, struct attr *, extern int bgp_update (struct peer *, struct prefix *, u_int32_t, struct attr *,
afi_t, safi_t, int, int, struct prefix_rd *, 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 *, 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 *); struct bgp_route_evpn *);
/* for bgp_nexthop and bgp_damp */ /* for bgp_nexthop and bgp_damp */

View File

@ -21,6 +21,7 @@
#ifndef _QUAGGA_BGP_TABLE_H #ifndef _QUAGGA_BGP_TABLE_H
#define _QUAGGA_BGP_TABLE_H #define _QUAGGA_BGP_TABLE_H
#include "mpls.h"
#include "table.h" #include "table.h"
struct bgp_table struct bgp_table
@ -56,7 +57,7 @@ struct bgp_node
struct bgp_node *prn; struct bgp_node *prn;
u_char local_label[3]; mpls_label_t local_label;
uint64_t version; uint64_t version;
u_char flags; u_char flags;

View File

@ -599,6 +599,9 @@ subgroup_announce_table (struct update_subgroup *subgrp,
safi = SUBGRP_SAFI (subgrp); safi = SUBGRP_SAFI (subgrp);
addpath_capable = bgp_addpath_encode_tx (peer, afi, safi); addpath_capable = bgp_addpath_encode_tx (peer, afi, safi);
if (safi == SAFI_LABELED_UNICAST)
safi = SAFI_UNICAST;
if (!table) if (!table)
table = peer->bgp->rib[afi][safi]; table = peer->bgp->rib[afi][safi];

View File

@ -785,26 +785,26 @@ subgroup_update_packet (struct update_subgroup *subgrp)
else else
{ {
/* Encode the prefix in MP_REACH_NLRI attribute */ /* Encode the prefix in MP_REACH_NLRI attribute */
u_char *tag = NULL; mpls_label_t label = MPLS_INVALID_LABEL;
if (rn->prn) if (rn->prn)
prd = (struct prefix_rd *) &rn->prn->p; prd = (struct prefix_rd *) &rn->prn->p;
if (safi == SAFI_LABELED_UNICAST) if (safi == SAFI_LABELED_UNICAST)
tag = bgp_adv_label(rn, binfo, peer, afi, safi); label = bgp_adv_label(rn, binfo, peer, afi, safi);
else else
if (binfo && binfo->extra) if (binfo && binfo->extra)
tag = binfo->extra->tag; label = binfo->extra->label;
if (bgp_labeled_safi(safi)) 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)) if (stream_empty (snlri))
mpattrlen_pos = bgp_packet_mpattr_start (snlri, peer, afi, safi, mpattrlen_pos = bgp_packet_mpattr_start (snlri, peer, afi, safi,
&vecarr, adv->baa->attr); &vecarr, adv->baa->attr);
bgp_packet_mpattr_prefix (snlri, afi, safi, &rn->p, prd, 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++; num_pfx++;

View File

@ -531,6 +531,9 @@ bgp_vty_return (struct vty *vty, int ret)
case BGP_ERR_INVALID_FOR_DIRECT_PEER: case BGP_ERR_INVALID_FOR_DIRECT_PEER:
str = "Operation not allowed on a directly connected neighbor"; str = "Operation not allowed on a directly connected neighbor";
break; break;
case BGP_ERR_PEER_SAFI_CONFLICT:
str = "Cannot activate peer for both 'ipv4 unicast' and 'ipv4 labeled-unicast'";
break;
} }
if (str) if (str)
{ {
@ -3317,10 +3320,7 @@ DEFUN (neighbor_activate,
return CMD_WARNING; return CMD_WARNING;
ret = peer_activate (peer, bgp_node_afi (vty), bgp_node_safi (vty)); ret = peer_activate (peer, bgp_node_afi (vty), bgp_node_safi (vty));
return bgp_vty_return (vty, ret);
if (ret)
return CMD_WARNING;
return CMD_SUCCESS;
} }
ALIAS_HIDDEN (neighbor_activate, ALIAS_HIDDEN (neighbor_activate,
@ -3348,10 +3348,7 @@ DEFUN (no_neighbor_activate,
return CMD_WARNING; return CMD_WARNING;
ret = peer_deactivate (peer, bgp_node_afi (vty), bgp_node_safi (vty)); ret = peer_deactivate (peer, bgp_node_afi (vty), bgp_node_safi (vty));
return bgp_vty_return (vty, ret);
if (ret)
return CMD_WARNING;
return CMD_SUCCESS;
} }
ALIAS_HIDDEN (no_neighbor_activate, 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 */ /* one clear bgp command to rule them all */
DEFUN (clear_ip_bgp_all, DEFUN (clear_ip_bgp_all,
clear_ip_bgp_all_cmd, 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 CLEAR_STR
IP_STR IP_STR
BGP_STR BGP_STR
@ -6513,7 +6510,7 @@ DEFUN (clear_ip_bgp_all,
"Clear all members of peer-group\n" "Clear all members of peer-group\n"
"BGP peer-group name\n" "BGP peer-group name\n"
BGP_AFI_HELP_STR BGP_AFI_HELP_STR
BGP_SAFI_HELP_STR BGP_SAFI_WITH_LABEL_HELP_STR
BGP_SOFT_STR BGP_SOFT_STR
BGP_SOFT_IN_STR BGP_SOFT_IN_STR
BGP_SOFT_OUT_STR BGP_SOFT_OUT_STR
@ -6534,12 +6531,18 @@ DEFUN (clear_ip_bgp_all,
/* clear [ip] bgp */ /* clear [ip] bgp */
if (argv_find (argv, argc, "ip", &idx)) if (argv_find (argv, argc, "ip", &idx))
afi = AFI_IP; afi = AFI_IP;
/* [<view|vrf> WORD] */ /* [<view|vrf> WORD] */
if (argv_find (argv, argc, "view", &idx) || argv_find (argv, argc, "vrf", &idx)) if (argv_find (argv, argc, "view", &idx) || argv_find (argv, argc, "vrf", &idx))
{ {
vrf = argv[idx + 1]->arg; vrf = argv[idx + 1]->arg;
idx += 2; 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> */ /* <*|A.B.C.D|X:X::X:X|WORD|(1-4294967295)|external|peer-group WORD> */
if (argv_find (argv, argc, "*", &idx)) if (argv_find (argv, argc, "*", &idx))
{ {
@ -6575,11 +6578,7 @@ DEFUN (clear_ip_bgp_all,
{ {
clr_sort = clear_external; 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>] */ /* [<soft [<in|out>]|in [prefix-filter]|out>] */
if (argv_find (argv, argc, "soft", &idx)) if (argv_find (argv, argc, "soft", &idx))
{ {
@ -6952,6 +6951,22 @@ DEFUN (show_bgp_memory,
return CMD_SUCCESS; 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. */ /* Show BGP peer's summary information. */
static int static int
bgp_show_summary (struct vty *vty, struct bgp *bgp, int afi, int safi, 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)) if (!CHECK_FLAG(peer->flags, PEER_FLAG_CONFIG_NODE))
continue; continue;
if (peer->afc[afi][safi]) if (bgp_show_summary_afi_safi_peer (peer, afi, safi))
{ {
memset(dn_flag, '\0', sizeof(dn_flag)); memset(dn_flag, '\0', sizeof(dn_flag));
if (peer_dynamic_neighbor(peer)) 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)) if (!CHECK_FLAG(peer->flags, PEER_FLAG_CONFIG_NODE))
continue; continue;
if (peer->afc[afi][safi]) if (bgp_show_summary_afi_safi_peer (peer, afi, safi))
{ {
if (!count) 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]) if (peer->afc[afi][safi])
return 1; 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; 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 */ safi = 1; /* SAFI_UNICAST */
while (safi < SAFI_MAX) 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)) if (bgp_show_summary_afi_safi_peer_exists (bgp, afi, safi))
{ {
json_output = true; json_output = true;
@ -9610,13 +9642,13 @@ bgp_show_update_groups(struct vty *vty, const char *name,
DEFUN (show_ip_bgp_updgrps, DEFUN (show_ip_bgp_updgrps,
show_ip_bgp_updgrps_cmd, 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 SHOW_STR
IP_STR IP_STR
BGP_STR BGP_STR
BGP_INSTANCE_HELP_STR BGP_INSTANCE_HELP_STR
BGP_AFI_HELP_STR BGP_AFI_HELP_STR
BGP_SAFI_HELP_STR BGP_SAFI_WITH_LABEL_HELP_STR
"Detailed info about dynamic update groups\n" "Detailed info about dynamic update groups\n"
"Specific subgroup to display detailed info for\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, &bgp_maxpaths_ibgp_cluster_cmd);
install_element (BGP_IPV6_NODE, &no_bgp_maxpaths_ibgp_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, &bgp_maxpaths_cmd);
install_element (BGP_IPV6L_NODE, &no_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_cmd);
install_element (BGP_IPV6L_NODE, &bgp_maxpaths_ibgp_cluster_cmd); install_element (BGP_IPV6L_NODE, &bgp_maxpaths_ibgp_cluster_cmd);
install_element (BGP_IPV6L_NODE, &no_bgp_maxpaths_ibgp_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_NODE, &neighbor_set_peer_group_cmd);
install_element (BGP_IPV4_NODE, &neighbor_set_peer_group_hidden_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_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_IPV6_NODE, &neighbor_set_peer_group_hidden_cmd);
install_element (BGP_IPV6M_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); 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_NODE, &no_neighbor_set_peer_group_cmd);
install_element (BGP_IPV4_NODE, &no_neighbor_set_peer_group_hidden_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_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_IPV6_NODE, &no_neighbor_set_peer_group_hidden_cmd);
install_element (BGP_IPV6M_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); install_element (BGP_IPV6L_NODE, &no_neighbor_set_peer_group_hidden_cmd);

View File

@ -28,15 +28,21 @@ struct bgp;
#define BGP_AFI_CMD_STR "<ipv4|ipv6>" #define BGP_AFI_CMD_STR "<ipv4|ipv6>"
#define BGP_AFI_HELP_STR "Address Family\nAddress Family\n" #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 \ #define BGP_SAFI_HELP_STR \
"Address Family modifier\n" \
"Address Family modifier\n" \ "Address Family modifier\n" \
"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_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_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 void bgp_vty_init (void);
extern const char *afi_safi_print (afi_t, safi_t); extern const char *afi_safi_print (afi_t, safi_t);
extern const char *afi_safi_json (afi_t, safi_t); extern const char *afi_safi_json (afi_t, safi_t);

View File

@ -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 local_info;
struct bgp_info *info_cp = &local_info; struct bgp_info *info_cp = &local_info;
route_tag_t tag; 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 /* Don't try to install if we're not connected to Zebra or Zebra doesn't
* know of this instance. * 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; struct in_addr *nexthop;
char buf[2][INET_ADDRSTRLEN]; char buf[2][INET_ADDRSTRLEN];
int valid_nh_count = 0; int valid_nh_count = 0;
int has_valid_label = 0;
/* resize nexthop buffer size if necessary */ /* resize nexthop buffer size if necessary */
if ((oldsize = stream_get_size (bgp_nexthop_buf)) < 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 /* For labeled unicast, each nexthop has a label too. Resize label
* buffer, if required. * buffer, if required.
*/ */
if (safi == SAFI_LABELED_UNICAST) if (safi == SAFI_UNICAST)
{ {
if ((oldsize = stream_get_size (bgp_label_buf)) < if ((oldsize = stream_get_size (bgp_label_buf)) <
(sizeof (unsigned int) * nhcount)) (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 *)); stream_put (bgp_nexthop_buf, &nexthop, sizeof (struct in_addr *));
valid_nh_count++; 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)); 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; continue;
stream_put (bgp_nexthop_buf, &nexthop, sizeof (struct in_addr *)); 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)); stream_put (bgp_label_buf, &label, sizeof (u_int32_t));
} }
valid_nh_count++; 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.type = ZEBRA_ROUTE_BGP;
api.instance = 0; api.instance = 0;
api.message = 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); SET_FLAG (api.message, ZAPI_MESSAGE_NEXTHOP);
if (safi == SAFI_LABELED_UNICAST)
if (has_valid_label)
SET_FLAG (api.message, ZAPI_MESSAGE_LABEL); SET_FLAG (api.message, ZAPI_MESSAGE_LABEL);
/* Note that this currently only applies to Null0 routes for aggregates. /* 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_num = valid_nh_count;
api.nexthop = (struct in_addr **)STREAM_DATA (bgp_nexthop_buf); 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_num = valid_nh_count;
api.label = (unsigned int *)STREAM_DATA (bgp_label_buf); 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++) for (i = 0; i < api.nexthop_num; i++)
{ {
label_buf[0] = '\0'; label_buf[0] = '\0';
if (safi == SAFI_LABELED_UNICAST) if (has_valid_label)
sprintf(label_buf, "label %u", api.label[i]); sprintf(label_buf, "label %u", api.label[i]);
zlog_debug(" nhop [%d]: %s %s", zlog_debug(" nhop [%d]: %s %s",
i+1, i+1,
@ -1463,6 +1468,7 @@ bgp_zebra_announce (struct bgp_node *rn, struct prefix *p, struct bgp_info *info
struct zapi_ipv6 api; struct zapi_ipv6 api;
int valid_nh_count = 0; int valid_nh_count = 0;
char buf[2][INET6_ADDRSTRLEN]; char buf[2][INET6_ADDRSTRLEN];
int has_valid_label = 0;
/* resize nexthop buffer size if necessary */ /* resize nexthop buffer size if necessary */
if ((oldsize = stream_get_size (bgp_nexthop_buf)) < 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 /* For labeled unicast, each nexthop has a label too. Resize label
* buffer, if required. * buffer, if required.
*/ */
if (safi == SAFI_LABELED_UNICAST) if (safi == SAFI_UNICAST)
{ {
if ((oldsize = stream_get_size (bgp_label_buf)) < if ((oldsize = stream_get_size (bgp_label_buf)) <
(sizeof (unsigned int) * nhcount)) (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_nexthop_buf, &nexthop, sizeof (struct in6_addr *));
stream_put (bgp_ifindices_buf, &ifindex, sizeof (unsigned int)); 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)); stream_put (bgp_label_buf, &label, sizeof (u_int32_t));
} }
valid_nh_count++; 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_nexthop_buf, &nexthop, sizeof (struct in6_addr *));
stream_put (bgp_ifindices_buf, &ifindex, sizeof (unsigned int)); 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)); stream_put (bgp_label_buf, &label, sizeof (u_int32_t));
} }
valid_nh_count++; 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.type = ZEBRA_ROUTE_BGP;
api.instance = 0; api.instance = 0;
api.message = 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); SET_FLAG (api.message, ZAPI_MESSAGE_NEXTHOP);
if (safi == SAFI_LABELED_UNICAST)
if (has_valid_label)
SET_FLAG (api.message, ZAPI_MESSAGE_LABEL); SET_FLAG (api.message, ZAPI_MESSAGE_LABEL);
/* Note that this currently only applies to Null0 routes for aggregates. /* 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); SET_FLAG (api.message, ZAPI_MESSAGE_IFINDEX);
api.ifindex_num = valid_nh_count; api.ifindex_num = valid_nh_count;
api.ifindex = (ifindex_t *)STREAM_DATA (bgp_ifindices_buf); 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_num = valid_nh_count;
api.label = (unsigned int *)STREAM_DATA (bgp_label_buf); 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++) for (i = 0; i < api.nexthop_num; i++)
{ {
label_buf[0] = '\0'; label_buf[0] = '\0';
if (safi == SAFI_LABELED_UNICAST) if (has_valid_label)
sprintf(label_buf, "label %u", api.label[i]); sprintf(label_buf, "label %u", api.label[i]);
zlog_debug(" nhop [%d]: %s if %s %s", zlog_debug(" nhop [%d]: %s if %s %s",
i+1, 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++) for (i = 0; i < api.nexthop_num; i++)
{ {
label_buf[0] = '\0'; label_buf[0] = '\0';
if (safi == SAFI_LABELED_UNICAST) if (has_valid_label)
sprintf(label_buf, "label %u", api.label[i]); sprintf(label_buf, "label %u", api.label[i]);
zlog_debug(" nhop [%d]: %s if %s %s", zlog_debug(" nhop [%d]: %s if %s %s",
i+1, 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.type = ZEBRA_ROUTE_BGP;
api.instance = 0; api.instance = 0;
api.message = 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); 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_num = 0;
api.nexthop = NULL; api.nexthop = NULL;
api.label_num = 0; 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.type = ZEBRA_ROUTE_BGP;
api.instance = 0; api.instance = 0;
api.message = 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); 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_num = 0;
api.nexthop = NULL; api.nexthop = NULL;
api.ifindex_num = 0; api.ifindex_num = 0;

View File

@ -1756,6 +1756,11 @@ non_peergroup_activate_af (struct peer *peer, afi_t afi, safi_t safi)
return 1; 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 */ /* Nothing to do if we've already activated this peer */
if (peer->afc[afi][safi]) if (peer->afc[afi][safi])
return 0; return 0;
@ -1815,6 +1820,12 @@ peer_activate (struct peer *peer, afi_t afi, safi_t safi)
* peer-group as well */ * peer-group as well */
if (CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP)) 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; peer->afc[afi][safi] = 1;
group = peer->group; group = peer->group;

View File

@ -1157,6 +1157,7 @@ enum bgp_clear_type
#define BGP_ERR_INVALID_FOR_DYNAMIC_PEER -32 #define BGP_ERR_INVALID_FOR_DYNAMIC_PEER -32
#define BGP_ERR_MAX -33 #define BGP_ERR_MAX -33
#define BGP_ERR_INVALID_FOR_DIRECT_PEER -34 #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. * Enumeration of different policy kinds a peer can be configured with.

View File

@ -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). */ /* MPLS label value as a 32-bit (mostly we only care about the label value). */
typedef unsigned int mpls_label_t; typedef unsigned int mpls_label_t;
#define MPLS_NO_LABEL 0xFFFFFFFF /* The MPLS explicit-null label is 0 which means when you memset a mpls_label_t
#define MPLS_INVALID_LABEL 0xFFFFFFFF * 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. */ /* LSP types. */
enum lsp_types_t enum lsp_types_t

View File

@ -920,9 +920,10 @@ stream_put_prefix (struct stream *s, struct prefix *p)
/* Put NLRI with label */ /* Put NLRI with label */
int 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; size_t psize;
u_char *label_pnt = (u_char *) label;
STREAM_VERIFY_SANE(s); 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, (p->prefixlen + 24));
stream_putc(s, label[0]); stream_putc(s, label_pnt[0]);
stream_putc(s, label[1]); stream_putc(s, label_pnt[1]);
stream_putc(s, label[2]); stream_putc(s, label_pnt[2]);
memcpy (s->data + s->endp, &p->u.prefix, psize); memcpy (s->data + s->endp, &p->u.prefix, psize);
s->endp += psize; s->endp += psize;

View File

@ -22,6 +22,7 @@
#ifndef _ZEBRA_STREAM_H #ifndef _ZEBRA_STREAM_H
#define _ZEBRA_STREAM_H #define _ZEBRA_STREAM_H
#include "mpls.h"
#include "prefix.h" #include "prefix.h"
/* /*
@ -181,7 +182,7 @@ extern int stream_put_prefix_addpath (struct stream *, struct prefix *,
u_int32_t addpath_tx_id); u_int32_t addpath_tx_id);
extern int stream_put_prefix (struct stream *, struct prefix *); extern int stream_put_prefix (struct stream *, struct prefix *);
extern int stream_put_labeled_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 (void *, struct stream *, size_t);
extern void stream_get_from (void *, struct stream *, size_t, size_t); extern void stream_get_from (void *, struct stream *, size_t, size_t);
extern u_char stream_getc (struct stream *); extern u_char stream_getc (struct stream *);

View File

@ -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 * Registration from a client for the label binding for a FEC. If a binding
* already exists, it is informed to the client. * already exists, it is informed to the client.
* NOTE: If there is a manually configured label binding, that is used. * 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 * label from a locally configured label block (SRGB), if one exists and index
* is acceptable. * is acceptable.
*/ */

View File

@ -989,6 +989,8 @@ zserv_fec_register (struct zserv *client, int sock, u_short length)
label_index = stream_getl(s); label_index = stream_getl(s);
l += 4; l += 4;
} }
else
label_index = MPLS_INVALID_LABEL_INDEX;
zebra_mpls_fec_register (zvrf, &p, label_index, client); zebra_mpls_fec_register (zvrf, &p, label_index, client);
} }