diff options
60 files changed, 850 insertions, 721 deletions
diff --git a/babeld/babeld.c b/babeld/babeld.c index b44b25ab4e..e17e00ca56 100644 --- a/babeld/babeld.c +++ b/babeld/babeld.c @@ -617,8 +617,7 @@ DEFUN (no_router_babel, "no router babel", NO_STR "Disable a routing process\n" - "Remove Babel instance command\n" - "No attributes\n") + "Remove Babel instance command\n") { if(babel_routing_process) babel_clean_routing_process(); diff --git a/bgpd/bgp_attr.c b/bgpd/bgp_attr.c index d343ce236b..439469d61e 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" @@ -537,6 +538,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; } @@ -580,6 +582,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; } @@ -681,6 +686,7 @@ attrhash_key_make (void *p) MIX(extra->mp_nexthop_global_in.s_addr); MIX(extra->originator_id.s_addr); MIX(extra->tag); + MIX(extra->label); MIX(extra->label_index); } @@ -963,6 +969,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; @@ -1004,6 +1012,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) @@ -2965,27 +2975,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); @@ -3116,7 +3126,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) { @@ -3139,7 +3149,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); } @@ -3572,16 +3582,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 f25df3a8b9..f3c1b5e3c2 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_attr_evpn.c b/bgpd/bgp_attr_evpn.c index e565d0801b..6970d5a679 100644 --- a/bgpd/bgp_attr_evpn.c +++ b/bgpd/bgp_attr_evpn.c @@ -125,13 +125,13 @@ bgp_build_evpn_prefix(int evpn_type, uint32_t eth_tag, struct prefix *dst) p_evpn_p->eth_tag = eth_tag; p_evpn_p->ip_prefix_length = p2.prefixlen; if (src->family == AF_INET) { - p_evpn_p->flags = IP_PREFIX_V4; - memcpy(&p_evpn_p->ip.v4_addr, &src->u.prefix4, + SET_IPADDR_V4 (&p_evpn_p->ip); + memcpy(&p_evpn_p->ip.ipaddr_v4, &src->u.prefix4, sizeof(struct in_addr)); dst->prefixlen = (u_char) PREFIX_LEN_ROUTE_TYPE_5_IPV4; } else { - p_evpn_p->flags = IP_PREFIX_V6; - memcpy(&p_evpn_p->ip.v6_addr, &src->u.prefix6, + SET_IPADDR_V6 (&p_evpn_p->ip); + memcpy(&p_evpn_p->ip.ipaddr_v6, &src->u.prefix6, sizeof(struct in6_addr)); dst->prefixlen = (u_char) PREFIX_LEN_ROUTE_TYPE_5_IPV6; } diff --git a/bgpd/bgp_evpn.c b/bgpd/bgp_evpn.c index c5a0ef8893..34a3315c0c 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. */ @@ -124,20 +125,20 @@ bgp_nlri_parse_evpn(struct peer *peer, struct attr *attr, /* determine IPv4 or IPv6 prefix */ if (route_length - 4 - 10 - 8 - 3 /* label to be read */ >= 32) { - p_evpn_p->flags = IP_PREFIX_V6; - memcpy(&(p_evpn_p->ip.v6_addr), pnt, 16); + SET_IPADDR_V6 (&p_evpn_p->ip); + memcpy(&(p_evpn_p->ip.ipaddr_v6), pnt, 16); pnt += 16; memcpy(&evpn.gw_ip.ipv6, pnt, 16); pnt += 16; } else { - p_evpn_p->flags = IP_PREFIX_V4; - memcpy(&(p_evpn_p->ip.v4_addr), pnt, 4); + SET_IPADDR_V4 (&p_evpn_p->ip); + memcpy(&(p_evpn_p->ip.ipaddr_v4), pnt, 4); pnt += 4; memcpy(&evpn.gw_ip.ipv4, pnt, 4); pnt += 4; } p.family = AFI_L2VPN; - if (p_evpn_p->flags == IP_PREFIX_V4) + if (IS_IPADDR_V4(&p_evpn_p->ip)) p.prefixlen = (u_char) PREFIX_LEN_ROUTE_TYPE_5_IPV4; else @@ -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]; @@ -184,7 +186,7 @@ bgp_packet_mpattr_route_type_5(struct stream *s, if (p->family != AF_ETHERNET) return; p_evpn_p = &(p->u.prefix_evpn); - if (p_evpn_p->flags & IP_PREFIX_V4) + if (IS_IPADDR_V4(&p_evpn_p->ip)) len = 8; /* ipv4 */ else len = 32; /* ipv6 */ @@ -199,12 +201,12 @@ bgp_packet_mpattr_route_type_5(struct stream *s, stream_put(s, &temp, 10); stream_putl(s, p_evpn_p->eth_tag); stream_putc(s, p_evpn_p->ip_prefix_length); - if (p_evpn_p->flags & IP_PREFIX_V4) - stream_put_ipv4(s, p_evpn_p->ip.v4_addr.s_addr); + if (IS_IPADDR_V4(&p_evpn_p->ip)) + stream_put_ipv4(s, p_evpn_p->ip.ipaddr_v4.s_addr); else - stream_put(s, &p_evpn_p->ip.v6_addr, 16); + stream_put(s, &p_evpn_p->ip.ipaddr_v6, 16); if (attr && attr->extra) { - if (p_evpn_p->flags & IP_PREFIX_V4) + if (IS_IPADDR_V4(&p_evpn_p->ip)) stream_put_ipv4(s, attr->extra->evpn_overlay.gw_ip.ipv4. s_addr); @@ -212,7 +214,7 @@ bgp_packet_mpattr_route_type_5(struct stream *s, stream_put(s, &(attr->extra->evpn_overlay.gw_ip.ipv6), 16); } else { - if (p_evpn_p->flags & IP_PREFIX_V4) + if (IS_IPADDR_V4(&p_evpn_p->ip)) stream_put_ipv4(s, 0); else stream_put(s, &temp, 16); diff --git a/bgpd/bgp_evpn.h b/bgpd/bgp_evpn.h index 95d4280150..feabc9cd27 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 0798515ebb..fc0654f186 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,33 @@ 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_depth = 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); + label_depth += 1; + if (bgp_is_withdraw_label(label) || label_bos(label)) break; } + + /* 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_depth > 1) + zlog_warn("%s rcvd UPDATE with label stack %d deep", + peer->host, label_depth); + 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 +217,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 +265,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 +329,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 dbc675dd43..c98f4531f6 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,38 @@ bgp_labeled_safi (safi_t safi) } static inline int -bgp_is_withdraw_label (u_char *pkt) +bgp_is_withdraw_label (mpls_label_t *label) { - if ((pkt[0] == 0x80) && (pkt[1] == 0x00) && (pkt[2] == 0x00)) + u_char *pkt = (u_char *) label; + + /* The check on pkt[2] for 0x00 or 0x02 is in case bgp_set_valid_label() + * was called on the withdraw label */ + if ((pkt[0] == 0x80) && (pkt[1] == 0x00) && ((pkt[2] == 0x00) || (pkt[2] == 0x02))) 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 +98,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 +119,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_main.c b/bgpd/bgp_main.c index 9fcbff0f53..b4d71f78d2 100644 --- a/bgpd/bgp_main.c +++ b/bgpd/bgp_main.c @@ -232,12 +232,6 @@ bgp_exit (int status) vnc_zebra_destroy(); #endif bgp_zebra_destroy(); - if (bgp_nexthop_buf) - stream_free (bgp_nexthop_buf); - if (bgp_ifindices_buf) - stream_free (bgp_ifindices_buf); - if (bgp_label_buf) - stream_free (bgp_label_buf); /* reverse bgp_master_init */ if (bm->master) diff --git a/bgpd/bgp_mplsvpn.c b/bgpd/bgp_mplsvpn.c index dcbfdebe49..b5fbfd8bb6 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 f82a27b151..4ba4597d06 100644 --- a/bgpd/bgp_mplsvpn.h +++ b/bgpd/bgp_mplsvpn.h @@ -101,8 +101,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 90aa68cfc4..0c31d6e9f3 100644 --- a/bgpd/bgp_packet.c +++ b/bgpd/bgp_packet.c @@ -247,8 +247,7 @@ bgp_write_packet (struct peer *peer) if (!(PAF_SUBGRP(paf))->t_coalesce && peer->afc_nego[afi][safi] && peer->synctime && ! CHECK_FLAG (peer->af_sflags[afi][safi], - PEER_STATUS_EOR_SEND) - && safi != SAFI_EVPN) + PEER_STATUS_EOR_SEND)) { SET_FLAG (peer->af_sflags[afi][safi], PEER_STATUS_EOR_SEND); @@ -1159,6 +1158,7 @@ bgp_open_receive (struct peer *peer, bgp_size_t size) peer->afc_nego[AFI_IP6][SAFI_UNICAST] = peer->afc[AFI_IP6][SAFI_UNICAST]; peer->afc_nego[AFI_IP6][SAFI_MULTICAST] = peer->afc[AFI_IP6][SAFI_MULTICAST]; peer->afc_nego[AFI_IP6][SAFI_LABELED_UNICAST] = peer->afc[AFI_IP6][SAFI_LABELED_UNICAST]; + peer->afc_nego[AFI_L2VPN][SAFI_EVPN] = peer->afc[AFI_L2VPN][SAFI_EVPN]; } /* When collision is detected and this peer is closed. Retrun @@ -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 404360a3af..12ad65883e 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,9 +1950,8 @@ 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) { if (!old_select || @@ -1955,8 +1964,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 +2006,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 +2062,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 +2481,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 +2498,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 +2615,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 +2737,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 +2840,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 +2872,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 +2957,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 +3010,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 +3198,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) { @@ -4017,7 +4046,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; @@ -4065,7 +4094,7 @@ bgp_static_update_safi (struct bgp *bgp, struct prefix *p, struct attr attr = { 0 }; struct bgp_info *ri; #if ENABLE_BGP_VNC - u_int32_t label = 0; + mpls_label_t label = 0; #endif union gw_addr add; @@ -4130,8 +4159,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; } @@ -4176,7 +4204,7 @@ bgp_static_update_safi (struct bgp *bgp, struct prefix *p, ri->uptime = bgp_clock (); #if ENABLE_BGP_VNC if (ri->extra) - label = decode_label (ri->extra->tag); + label = decode_label (&ri->extra->label); #endif /* Process change. */ @@ -4200,9 +4228,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. */ @@ -4430,8 +4458,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); @@ -4545,7 +4572,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 */ @@ -4574,12 +4601,9 @@ bgp_static_set_safi (afi_t afi, safi_t safi, struct vty *vty, const char *ip_str { unsigned long label_val; label_val = strtoul(label_str, NULL, 10); - encode_label (label_val, tag); - } - else - { - memset (tag, 0, sizeof(tag)); /* empty, not even BoS */ + encode_label (label_val, &label); } + if (safi == SAFI_EVPN) { if( esi && str2esi (esi, NULL) == 0) @@ -4601,8 +4625,10 @@ bgp_static_set_safi (afi_t afi, safi_t safi, struct vty *vty, const char *ip_str vty_outln (vty, "%% Malformed GatewayIp"); return CMD_WARNING; } - if((gw_ip.family == AF_INET && (p.u.prefix_evpn.flags & IP_PREFIX_V6)) - || (gw_ip.family == AF_INET6 && (p.u.prefix_evpn.flags & IP_PREFIX_V4))) + if((gw_ip.family == AF_INET && + IS_EVPN_PREFIX_IPADDR_V6((struct prefix_evpn *)&p)) || + (gw_ip.family == AF_INET6 && + IS_EVPN_PREFIX_IPADDR_V4((struct prefix_evpn *)&p))) { vty_outln (vty, "%% GatewayIp family differs with IP prefix"); return CMD_WARNING; @@ -4632,7 +4658,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) @@ -4681,7 +4707,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); @@ -4708,11 +4734,7 @@ bgp_static_unset_safi(afi_t afi, safi_t safi, struct vty *vty, const char *ip_st { unsigned long label_val; label_val = strtoul(label_str, NULL, 10); - encode_label (label_val, tag); - } - else - { - memset (tag, 0, sizeof(tag)); /* empty, not even BoS */ + encode_label (label_val, &label); } prn = bgp_node_get (bgp->route[afi][safi], @@ -4727,7 +4749,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); @@ -6650,7 +6672,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; @@ -6733,19 +6755,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) - { - if (label) - json_object_int_add(json_out, "notag", label); - json_object_array_add(json, json_out); - } - else + if (bgp_is_valid_label(&label)) { - vty_out (vty, "notag/%d", label); - - vty_out (vty, VTYNL); + if (json) + { + 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, VTYNL); + } } } @@ -6807,11 +6830,11 @@ route_vty_out_overlay (struct vty *vty, struct prefix *p, char *str = esi2str(id); vty_out (vty, "%s", str); XFREE (MTYPE_TMP, str); - if (p->u.prefix_evpn.flags & IP_PREFIX_V4) + if (IS_EVPN_PREFIX_IPADDR_V4((struct prefix_evpn *)p)) { vty_out (vty, "/%s", inet_ntoa (attr->extra->evpn_overlay.gw_ip.ipv4)); } - else if (p->u.prefix_evpn.flags & IP_PREFIX_V6) + else if (IS_EVPN_PREFIX_IPADDR_V6((struct prefix_evpn *)p)) { vty_out (vty, "/%s", inet_ntop (AF_INET6, &(attr->extra->evpn_overlay.gw_ip.ipv6), @@ -7174,7 +7197,8 @@ route_vty_out_detail (struct vty *vty, struct bgp *bgp, struct prefix *p, /* Line2 display Next-hop, Neighbor, Router-id */ /* Display the nexthop */ - if (p->family == AF_INET && + if ((p->family == AF_INET || + p->family == AF_ETHERNET) && (safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP || safi == SAFI_EVPN || @@ -7631,10 +7655,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 @@ -8113,12 +8137,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; + mpls_label_t label; 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); } @@ -8135,17 +8168,10 @@ route_vty_out_detail_header (struct vty *vty, struct bgp *bgp, buf2, p->prefixlen); - if (bgp_labeled_safi(safi)) - { - vty_out(vty, "Local label: "); - if (!bgp_is_valid_label(rn->local_label)) - vty_outln (vty, "not allocated"); - else - { - uint32_t label = label_pton(rn->local_label); - vty_outln (vty, "%d", label); - } - } + if (has_valid_label) + vty_outln (vty, "Local label: %d", label); + else if (bgp_labeled_safi(safi)) + vty_outln (vty, "Local label: not allocated"); } for (ri = rn->info; ri; ri = ri->next) @@ -8427,17 +8453,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> VIEWVRFNAME] [<ipv4|ipv6> [<unicast|multicast|vpn|labeled-unicast>]] large-community-list <(1-500)|WORD> [json]", + "show [ip] bgp [<view|vrf> VIEWVRFNAME] ["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" @@ -8473,17 +8495,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> VIEWVRFNAME] [<ipv4|ipv6> [<unicast|multicast|vpn|labeled-unicast>]] large-community [AA:BB:CC] [json]", + "show [ip] bgp [<view|vrf> VIEWVRFNAME] ["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) @@ -9424,19 +9442,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> VIEWVRFNAME] [<ipv4|ipv6> [<unicast|multicast|vpn|labeled-unicast>]] " + "show [ip] bgp [<view|vrf> VIEWVRFNAME] ["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" - "Address Family modifier\n" + BGP_AFI_HELP_STR + BGP_SAFI_HELP_STR "Detailed information on TCP and BGP neighbor connections\n" "Neighbor to display information about\n" "Neighbor to display information about\n" @@ -10626,7 +10639,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]; @@ -10644,7 +10657,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), @@ -10705,7 +10718,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, VTYNL); if (macrouter) XFREE (MTYPE_TMP, macrouter); @@ -10898,8 +10911,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); @@ -10928,20 +10943,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); @@ -10975,10 +10976,10 @@ bgp_route_init (void) install_element (BGP_IPV6_NODE, &ipv6_bgp_network_route_map_cmd); install_element (BGP_IPV6_NODE, &no_bgp_table_map_cmd); install_element (BGP_IPV6_NODE, &no_ipv6_bgp_network_cmd); - install_element (BGP_IPV6L_NODE, &ipv6_bgp_network_label_index_cmd); - install_element (BGP_IPV6L_NODE, &no_ipv6_bgp_network_label_index_cmd); - install_element (BGP_IPV6L_NODE, &ipv6_bgp_network_label_index_route_map_cmd); - install_element (BGP_IPV6L_NODE, &no_ipv6_bgp_network_label_index_route_map_cmd); + install_element (BGP_IPV6_NODE, &ipv6_bgp_network_label_index_cmd); + install_element (BGP_IPV6_NODE, &no_ipv6_bgp_network_label_index_cmd); + install_element (BGP_IPV6_NODE, &ipv6_bgp_network_label_index_route_map_cmd); + install_element (BGP_IPV6_NODE, &no_ipv6_bgp_network_label_index_route_map_cmd); install_element (BGP_IPV6_NODE, &ipv6_aggregate_address_cmd); install_element (BGP_IPV6_NODE, &no_ipv6_aggregate_address_cmd); diff --git a/bgpd/bgp_route.h b/bgpd/bgp_route.h index 532bd8ac02..0c77cc1ee0 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 7b22872628..d11b70842b 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 @@ -53,7 +54,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 d12d282a93..c4cb8ae1b3 100644 --- a/bgpd/bgp_updgrp_adv.c +++ b/bgpd/bgp_updgrp_adv.c @@ -598,6 +598,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 1a72301a1f..dff46a9466 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 6e998085c1..710aa926ad 100644 --- a/bgpd/bgp_vty.c +++ b/bgpd/bgp_vty.c @@ -517,6 +517,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) { @@ -1376,7 +1379,6 @@ DEFUN (bgp_update_delay_establish_wait, "update-delay (0-3600) (1-3600)", "Force initial delay for best-path and updates\n" "Seconds\n" - "Wait for peers to be established\n" "Seconds\n") { int idx_number = 1; @@ -1391,7 +1393,7 @@ DEFUN (no_bgp_update_delay, NO_STR "Force initial delay for best-path and updates\n" "Seconds\n" - "Wait for peers to be established\n") + "Seconds\n") { return bgp_update_delay_deconfig_vty(vty); } @@ -3259,10 +3261,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, @@ -3290,10 +3289,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, @@ -6182,7 +6178,7 @@ DEFUN_NOSH (address_family_ipv4_safi, "address-family ipv4 [<unicast|multicast|vpn|labeled-unicast>]", "Enter Address Family command mode\n" "Address Family\n" - BGP_SAFI_HELP_STR) + BGP_SAFI_WITH_LABEL_HELP_STR) { if (argc == 3) @@ -6201,7 +6197,7 @@ DEFUN_NOSH (address_family_ipv6_safi, "address-family ipv6 [<unicast|multicast|vpn|labeled-unicast>]", "Enter Address Family command mode\n" "Address Family\n" - BGP_SAFI_HELP_STR) + BGP_SAFI_WITH_LABEL_HELP_STR) { if (argc == 3) { @@ -6240,11 +6236,10 @@ DEFUN_NOSH (address_family_vpnv6, DEFUN_NOSH (address_family_evpn, address_family_evpn_cmd, - "address-family <l2vpn evpn>", + "address-family l2vpn evpn", "Enter Address Family command mode\n" - "EVPN Address family\n" - "Layer2 VPN Address family\n" - "Ethernet Virtual Private Network Subsequent Address Family\n") + "Address Family\n" + "Address Family modifier\n") { vty->node = BGP_EVPN_NODE; return CMD_SUCCESS; @@ -6352,7 +6347,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> VIEWVRFNAME] ["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> VIEWVRFNAME] ["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 @@ -6366,7 +6361,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 @@ -6387,12 +6382,18 @@ DEFUN (clear_ip_bgp_all, /* clear [ip] bgp */ if (argv_find (argv, argc, "ip", &idx)) afi = AFI_IP; + /* [<view|vrf> VIEWVRFNAME] */ 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)) { @@ -6428,11 +6429,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)) { @@ -7327,13 +7324,13 @@ bgp_show_summary_vty (struct vty *vty, const char *name, /* `show [ip] bgp summary' commands. */ DEFUN (show_ip_bgp_summary, show_ip_bgp_summary_cmd, - "show [ip] bgp [<view|vrf> VIEWVRFNAME] ["BGP_AFI_CMD_STR" ["BGP_SAFI_CMD_STR"]] summary [json]", + "show [ip] bgp [<view|vrf> VIEWVRFNAME] ["BGP_AFI_CMD_STR" ["BGP_SAFI_WITH_LABEL_CMD_STR"]] summary [json]", SHOW_STR IP_STR BGP_STR BGP_INSTANCE_HELP_STR BGP_AFI_HELP_STR - BGP_SAFI_HELP_STR + BGP_SAFI_WITH_LABEL_HELP_STR "Summary of BGP neighbor status\n" JSON_STR) { @@ -9463,13 +9460,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> VIEWVRFNAME] ["BGP_AFI_CMD_STR" ["BGP_SAFI_CMD_STR"]] update-groups [SUBGROUP-ID]", + "show [ip] bgp [<view|vrf> VIEWVRFNAME] ["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") { @@ -9620,8 +9617,7 @@ DEFUN (show_bgp_updgrps_afi_adj, "Detailed info about dynamic update groups\n" "Advertisement queue\n" "Announced routes\n" - "Packet queue\n" - "Specific subgroup info wanted for\n") + "Packet queue\n") { int idx_afi = 2; int idx_safi = 3; @@ -9726,8 +9722,7 @@ DEFUN (show_bgp_updgrps_afi_adj_s, "Specific subgroup to display info for\n" "Advertisement queue\n" "Announced routes\n" - "Packet queue\n" - "Specific subgroup info wanted for\n") + "Packet queue\n") { int idx_afi = 2; int idx_safi = 3; @@ -10879,14 +10874,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); @@ -11043,7 +11032,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); @@ -11054,7 +11042,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); @@ -12180,8 +12167,7 @@ DEFUN (ip_lcommunity_list_standard, LCOMMUNITY_LIST_STR "Large Community list number (standard)\n" "Specify large community to reject\n" - "Specify large community to accept\n" - LCOMMUNITY_VAL_STR) + "Specify large community to accept\n") { return lcommunity_list_set_vty (vty, argc, argv, LARGE_COMMUNITY_LIST_STANDARD, 0); } diff --git a/bgpd/bgp_vty.h b/bgpd/bgp_vty.h index fcef4ccc01..edc994a57c 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 66c18c8e57..71a4d4317a 100644 --- a/bgpd/bgp_zebra.c +++ b/bgpd/bgp_zebra.c @@ -1222,12 +1222,11 @@ bgp_zebra_announce (struct bgp_node *rn, struct prefix *p, struct bgp_info *info u_char distance; struct peer *peer; struct bgp_info *mpinfo; - size_t oldsize, newsize; - u_int32_t nhcount, metric; + u_int32_t metric; 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. @@ -1270,87 +1269,26 @@ bgp_zebra_announce (struct bgp_node *rn, struct prefix *p, struct bgp_info *info SET_FLAG (flags, ZEBRA_FLAG_INTERNAL); - nhcount = 1 + bgp_info_mpath_count (info); - if (p->family == AF_INET && !BGP_ATTR_NEXTHOP_AFI_IP6(info->attr)) { struct zapi_ipv4 api; 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)) < - (sizeof (struct in_addr *) * nhcount)) - { - newsize = sizeof (struct in_addr *) * nhcount; - newsize = stream_resize (bgp_nexthop_buf, newsize); - if (newsize == oldsize) - { - zlog_err ("can't resize nexthop buffer"); - return; - } - } stream_reset (bgp_nexthop_buf); nexthop = NULL; - /* For labeled unicast, each nexthop has a label too. Resize label - * buffer, if required. - */ - if (safi == SAFI_LABELED_UNICAST) - { - if ((oldsize = stream_get_size (bgp_label_buf)) < - (sizeof (unsigned int) * nhcount)) - { - newsize = (sizeof (unsigned int) * nhcount); - newsize = stream_resize (bgp_label_buf, newsize); - if (newsize == oldsize) - { - zlog_err ("can't resize label buffer"); - return; - } - } - stream_reset (bgp_label_buf); - } - - /* Metric is currently based on the best-path only. */ - metric = info->attr->med; + stream_reset (bgp_label_buf); if (bgp->table_map[afi][safi].name) - { - BGP_INFO_ATTR_BUF_INIT(); - - /* Copy info and attributes, so the route-map apply doesn't modify the - BGP route info. */ - BGP_INFO_ATTR_BUF_COPY(info, info_cp); - if (bgp_table_map_apply(bgp->table_map[afi][safi].map, p, info_cp)) - { - metric = info_cp->attr->med; - nexthop = &info_cp->attr->nexthop; - - if (info_cp->attr->extra) - tag = info_cp->attr->extra->tag; - } - BGP_INFO_ATTR_BUF_FREE(info_cp); - } - else - { - nexthop = &info->attr->nexthop; - } + BGP_INFO_ATTR_BUF_INIT(); - if (nexthop) - { - stream_put (bgp_nexthop_buf, &nexthop, sizeof (struct in_addr *)); - valid_nh_count++; - if (safi == SAFI_LABELED_UNICAST) - { - label = label_pton(info->extra->tag); - stream_put (bgp_label_buf, &label, sizeof (u_int32_t)); - } - } - - for (mpinfo = bgp_info_mpath_first (info); mpinfo; - mpinfo = bgp_info_mpath_next (mpinfo)) + /* Metric is currently based on the best-path only */ + metric = info->attr->med; + for (mpinfo = info ; mpinfo; mpinfo = bgp_info_mpath_next (mpinfo)) { nexthop = NULL; @@ -1360,22 +1298,29 @@ bgp_zebra_announce (struct bgp_node *rn, struct prefix *p, struct bgp_info *info BGP route info. */ BGP_INFO_ATTR_BUF_COPY(mpinfo, info_cp); if (bgp_table_map_apply(bgp->table_map[afi][safi].map, p, info_cp)) - nexthop = &info_cp->attr->nexthop; + { + if (mpinfo == info) + { + /* Metric is currently based on the best-path only */ + metric = info_cp->attr->med; + tag = info_cp->attr->extra->tag; + } + nexthop = &info_cp->attr->nexthop; + } BGP_INFO_ATTR_BUF_FREE(info_cp); } else - { - nexthop = &mpinfo->attr->nexthop; - } + nexthop = &mpinfo->attr->nexthop; if (nexthop == NULL) 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); - stream_put (bgp_label_buf, &label, sizeof (u_int32_t)); + has_valid_label = 1; + label = label_pton(&mpinfo->extra->label); + stream_put (bgp_label_buf, &label, sizeof (mpls_label_t)); } valid_nh_count++; } @@ -1385,9 +1330,10 @@ 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; + 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 +1347,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 +1387,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,109 +1409,22 @@ 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)) < - (sizeof (struct in6_addr *) * nhcount)) - { - newsize = (sizeof (struct in6_addr *) * nhcount); - newsize = stream_resize (bgp_nexthop_buf, newsize); - if (newsize == oldsize) - { - zlog_err ("can't resize nexthop buffer"); - return; - } - } stream_reset (bgp_nexthop_buf); - - /* resize ifindices buffer size if necessary */ - if ((oldsize = stream_get_size (bgp_ifindices_buf)) < - (sizeof (unsigned int) * nhcount)) - { - newsize = (sizeof (unsigned int) * nhcount); - newsize = stream_resize (bgp_ifindices_buf, newsize); - if (newsize == oldsize) - { - zlog_err ("can't resize nexthop buffer"); - return; - } - } stream_reset (bgp_ifindices_buf); - - /* For labeled unicast, each nexthop has a label too. Resize label - * buffer, if required. - */ - if (safi == SAFI_LABELED_UNICAST) - { - if ((oldsize = stream_get_size (bgp_label_buf)) < - (sizeof (unsigned int) * nhcount)) - { - newsize = (sizeof (unsigned int) * nhcount); - newsize = stream_resize (bgp_label_buf, newsize); - if (newsize == oldsize) - { - zlog_err ("can't resize label buffer"); - return; - } - } - stream_reset (bgp_label_buf); - } + stream_reset (bgp_label_buf); ifindex = 0; nexthop = NULL; assert (info->attr->extra); - /* Metric is currently based on the best-path only. */ - metric = info->attr->med; - if (bgp->table_map[afi][safi].name) - { - BGP_INFO_ATTR_BUF_INIT(); - - /* Copy info and attributes, so the route-map apply doesn't modify the - BGP route info. */ - BGP_INFO_ATTR_BUF_COPY(info, info_cp); - if (bgp_table_map_apply(bgp->table_map[afi][safi].map, p, info_cp)) - { - metric = info_cp->attr->med; - nexthop = bgp_info_to_ipv6_nexthop(info_cp); - - if (info_cp->attr->extra) - tag = info_cp->attr->extra->tag; - } - BGP_INFO_ATTR_BUF_FREE(info_cp); - } - else - { - nexthop = bgp_info_to_ipv6_nexthop(info); - } - - if (nexthop) - { - if (info->attr->extra->mp_nexthop_len == BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL) - if (info->peer->nexthop.ifp) - ifindex = info->peer->nexthop.ifp->ifindex; - - if (!ifindex) - { - if (info->peer->conf_if || info->peer->ifname) - ifindex = if_nametoindex (info->peer->conf_if ? info->peer->conf_if : info->peer->ifname); - else if (info->peer->nexthop.ifp) - ifindex = info->peer->nexthop.ifp->ifindex; - } - stream_put (bgp_nexthop_buf, &nexthop, sizeof (struct in6_addr *)); - stream_put (bgp_ifindices_buf, &ifindex, sizeof (unsigned int)); - if (safi == SAFI_LABELED_UNICAST) - { - label = label_pton(info->extra->tag); - stream_put (bgp_label_buf, &label, sizeof (u_int32_t)); - } - valid_nh_count++; - } + BGP_INFO_ATTR_BUF_INIT(); - for (mpinfo = bgp_info_mpath_first (info); mpinfo; - mpinfo = bgp_info_mpath_next (mpinfo)) + metric = info->attr->med; + for (mpinfo = info ; mpinfo; mpinfo = bgp_info_mpath_next (mpinfo)) { ifindex = 0; nexthop = NULL; @@ -1576,18 +1435,24 @@ bgp_zebra_announce (struct bgp_node *rn, struct prefix *p, struct bgp_info *info BGP route info. */ BGP_INFO_ATTR_BUF_COPY(mpinfo, info_cp); if (bgp_table_map_apply(bgp->table_map[afi][safi].map, p, info_cp)) - nexthop = bgp_info_to_ipv6_nexthop(info_cp); + { + if (mpinfo == info) + { + metric = info_cp->attr->med; + tag = info_cp->attr->extra->tag; + } + nexthop = bgp_info_to_ipv6_nexthop(info_cp); + } BGP_INFO_ATTR_BUF_FREE(info_cp); } else - { - nexthop = bgp_info_to_ipv6_nexthop(mpinfo); - } + nexthop = bgp_info_to_ipv6_nexthop(mpinfo); if (nexthop == NULL) continue; - if (mpinfo->attr->extra->mp_nexthop_len == BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL) + if ((mpinfo == info) && + mpinfo->attr->extra->mp_nexthop_len == BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL) if (mpinfo->peer->nexthop.ifp) ifindex = mpinfo->peer->nexthop.ifp->ifindex; @@ -1603,10 +1468,12 @@ 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); - stream_put (bgp_label_buf, &label, sizeof (u_int32_t)); + has_valid_label = 1; + label = label_pton(&mpinfo->extra->label); + stream_put (bgp_label_buf, &label, sizeof (mpls_label_t)); } valid_nh_count++; } @@ -1617,9 +1484,10 @@ 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; + 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 +1504,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 +1544,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 +1575,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 +1661,8 @@ 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; + 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 +1702,8 @@ 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; + 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; @@ -2270,14 +2134,22 @@ bgp_zebra_init (struct thread_master *master) zclient->import_check_update = bgp_read_import_check_update; zclient->fec_update = bgp_read_fec_update; - bgp_nexthop_buf = stream_new(BGP_NEXTHOP_BUF_SIZE); - bgp_ifindices_buf = stream_new(BGP_IFINDICES_BUF_SIZE); - bgp_label_buf = stream_new(BGP_LABEL_BUF_SIZE); + bgp_nexthop_buf = stream_new(multipath_num * sizeof (struct in6_addr)); + bgp_ifindices_buf = stream_new(multipath_num * sizeof (unsigned int)); + bgp_label_buf = stream_new(multipath_num * sizeof (unsigned int)); } void bgp_zebra_destroy(void) { + + if (bgp_nexthop_buf) + stream_free (bgp_nexthop_buf); + if (bgp_ifindices_buf) + stream_free (bgp_ifindices_buf); + if (bgp_label_buf) + stream_free (bgp_label_buf); + if (zclient == NULL) return; zclient_stop(zclient); diff --git a/bgpd/bgp_zebra.h b/bgpd/bgp_zebra.h index 6a36fb84f7..3d634ed695 100644 --- a/bgpd/bgp_zebra.h +++ b/bgpd/bgp_zebra.h @@ -21,14 +21,6 @@ #ifndef _QUAGGA_BGP_ZEBRA_H #define _QUAGGA_BGP_ZEBRA_H -#define BGP_NEXTHOP_BUF_SIZE (8 * sizeof (struct in_addr *)) -#define BGP_IFINDICES_BUF_SIZE (8 * sizeof (unsigned int)) -#define BGP_LABEL_BUF_SIZE (8 * sizeof (unsigned int)) - -extern struct stream *bgp_nexthop_buf; -extern struct stream *bgp_ifindices_buf; -extern struct stream *bgp_label_buf; - extern void bgp_zebra_init (struct thread_master *master); extern void bgp_zebra_destroy (void); extern int bgp_if_update_all (void); diff --git a/bgpd/bgpd.c b/bgpd/bgpd.c index 9dd0374c9d..d7ddd5db8a 100644 --- a/bgpd/bgpd.c +++ b/bgpd/bgpd.c @@ -1477,17 +1477,28 @@ bgp_recalculate_all_bestpaths (struct bgp *bgp) { afi_t afi; safi_t safi; - struct bgp_node *rn; + struct bgp_node *rn, *nrn; for (afi = AFI_IP; afi < AFI_MAX; afi++) { for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++) { - for (rn = bgp_table_top (bgp->rib[afi][safi]); rn; rn = bgp_route_next (rn)) + for (rn = bgp_table_top (bgp->rib[afi][safi]); rn; + rn = bgp_route_next (rn)) { if (rn->info != NULL) { - bgp_process (bgp, rn, afi, safi); + /* Special handling for 2-level routing tables. */ + if (safi == SAFI_MPLS_VPN || + safi == SAFI_ENCAP || + safi == SAFI_EVPN) + { + for (nrn = bgp_table_top((struct bgp_table *)(rn->info)); + nrn; nrn = bgp_route_next (nrn)) + bgp_process (bgp, nrn, afi, safi); + } + else + bgp_process (bgp, rn, afi, safi); } } } @@ -1756,6 +1767,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 +1831,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; @@ -2714,6 +2736,8 @@ peer_group_bind (struct bgp *bgp, union sockunion *su, struct peer *peer, peer_group2peer_config_copy_af (group, peer, afi, safi); } } + else if (peer->afc[afi][safi]) + peer_deactivate (peer, afi, safi); } if (peer->group) @@ -2794,6 +2818,8 @@ peer_group_bind (struct bgp *bgp, union sockunion *su, struct peer *peer, peer_af_create(peer, afi, safi); peer_group2peer_config_copy_af (group, peer, afi, safi); } + else if (peer->afc[afi][safi]) + peer_deactivate (peer, afi, safi); SET_FLAG(peer->flags, PEER_FLAG_CONFIG_NODE); @@ -3289,6 +3315,8 @@ bgp_free (struct bgp *bgp) { afi_t afi; safi_t safi; + struct bgp_table *table; + struct bgp_node *rn; QOBJ_UNREG (bgp); @@ -3304,6 +3332,18 @@ bgp_free (struct bgp *bgp) for (afi = AFI_IP; afi < AFI_MAX; afi++) for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++) { + /* Special handling for 2-level routing tables. */ + if (safi == SAFI_MPLS_VPN || + safi == SAFI_ENCAP || + safi == SAFI_EVPN) + { + for (rn = bgp_table_top(bgp->rib[afi][safi]); rn; + rn = bgp_route_next (rn)) + { + table = (struct bgp_table *) rn->info; + bgp_table_finish(&table); + } + } if (bgp->route[afi][safi]) bgp_table_finish (&bgp->route[afi][safi]); if (bgp->aggregate[afi][safi]) @@ -3617,7 +3657,8 @@ peer_active (struct peer *peer) || peer->afc[AFI_IP6][SAFI_MULTICAST] || peer->afc[AFI_IP6][SAFI_LABELED_UNICAST] || peer->afc[AFI_IP6][SAFI_MPLS_VPN] - || peer->afc[AFI_IP6][SAFI_ENCAP]) + || peer->afc[AFI_IP6][SAFI_ENCAP] + || peer->afc[AFI_L2VPN][SAFI_EVPN]) return 1; return 0; } @@ -3635,7 +3676,8 @@ peer_active_nego (struct peer *peer) || peer->afc_nego[AFI_IP6][SAFI_MULTICAST] || peer->afc_nego[AFI_IP6][SAFI_LABELED_UNICAST] || peer->afc_nego[AFI_IP6][SAFI_MPLS_VPN] - || peer->afc_nego[AFI_IP6][SAFI_ENCAP]) + || peer->afc_nego[AFI_IP6][SAFI_ENCAP] + || peer->afc_nego[AFI_L2VPN][SAFI_EVPN]) return 1; return 0; } diff --git a/bgpd/bgpd.h b/bgpd/bgpd.h index 78f04728d9..5dc25d00a9 100644 --- a/bgpd/bgpd.h +++ b/bgpd/bgpd.h @@ -1151,6 +1151,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. @@ -1461,7 +1462,8 @@ peer_afi_active_nego (const struct peer *peer, afi_t afi) || peer->afc_nego[afi][SAFI_MULTICAST] || peer->afc_nego[afi][SAFI_LABELED_UNICAST] || peer->afc_nego[afi][SAFI_MPLS_VPN] - || peer->afc_nego[afi][SAFI_ENCAP]) + || peer->afc_nego[afi][SAFI_ENCAP] + || peer->afc_nego[afi][SAFI_EVPN]) return 1; return 0; } @@ -1481,7 +1483,8 @@ peer_group_af_configured (struct peer_group *group) || peer->afc[AFI_IP6][SAFI_MULTICAST] || peer->afc[AFI_IP6][SAFI_LABELED_UNICAST] || peer->afc[AFI_IP6][SAFI_MPLS_VPN] - || peer->afc[AFI_IP6][SAFI_ENCAP]) + || peer->afc[AFI_IP6][SAFI_ENCAP] + || peer->afc[AFI_IP6][SAFI_EVPN]) return 1; return 0; } diff --git a/bgpd/rfapi/bgp_rfapi_cfg.c b/bgpd/rfapi/bgp_rfapi_cfg.c index 5cd8528ea9..14cce2d606 100644 --- a/bgpd/rfapi/bgp_rfapi_cfg.c +++ b/bgpd/rfapi/bgp_rfapi_cfg.c @@ -1313,9 +1313,9 @@ DEFUN (vnc_nve_group_redist_bgpdirect_no_prefixlist, NO_STR "Redistribute from other protocol\n" "Redistribute from BGP directly\n" - "Disable redistribute filter\n" "IPv4 routes\n" - "IPv6 routes\n" "Prefix-list for filtering redistributed routes\n") + "IPv6 routes\n" + "Prefix-list for filtering redistributed routes\n") { VTY_DECLVAR_CONTEXT(bgp, bgp); VTY_DECLVAR_CONTEXT_SUB(rfapi_nve_group_cfg, rfg) @@ -1412,7 +1412,6 @@ DEFUN (vnc_nve_group_redist_bgpdirect_no_routemap, NO_STR "Redistribute from other protocols\n" "Redistribute from BGP directly\n" - "Disable redistribute filter\n" "Route-map for filtering redistributed routes\n") { VTY_DECLVAR_CONTEXT(bgp, bgp); @@ -2076,7 +2075,6 @@ DEFUN (vnc_nve_export_prefixlist, "Export to other protocols\n" "Export to BGP\n" "Export to Zebra (experimental)\n" - "Filters, used in 'registering-nve' export mode\n" "IPv4 prefixes\n" "IPv6 prefixes\n" "Prefix-list for filtering exported routes\n" "Prefix list name\n") @@ -2178,7 +2176,6 @@ DEFUN (vnc_nve_export_routemap, "Export to other protocols\n" "Export to BGP\n" "Export to Zebra (experimental)\n" - "Filters, used in 'registering-nve' export mode\n" "Route-map for filtering exported routes\n" "Route map name\n") { VTY_DECLVAR_CONTEXT(bgp, bgp); @@ -3918,7 +3915,6 @@ DEFUN (vnc_l2_group_no_labels, vnc_l2_group_no_labels_cmd, "no labels LABELLIST...", NO_STR - "Remove label values associated with L2 group\n" "Specify label values associated with L2 group\n" "Space separated list of label values <0-1048575>\n") { diff --git a/bgpd/rfapi/rfapi.c b/bgpd/rfapi/rfapi.c index 510fbc27a4..ffd4e3e323 100644 --- a/bgpd/rfapi/rfapi.c +++ b/bgpd/rfapi/rfapi.c @@ -1170,7 +1170,7 @@ add_vnc_route ( /* save backref to rfapi handle */ assert (bgp_info_extra_get (new)); new->extra->vnc.export.rfapi_handle = (void *) rfd; - encode_label (label_val, new->extra->tag); + encode_label (label_val, &new->extra->label); /* debug */ @@ -1197,7 +1197,7 @@ add_vnc_route ( bgp, prd, table, p, new); } bgp_unlock_node (prn); - encode_label (label_val, bn->local_label); + encode_label (label_val, &bn->local_label); } bgp_unlock_node (bn); diff --git a/bgpd/rfapi/rfapi_import.c b/bgpd/rfapi/rfapi_import.c index 27f42cf02e..b0c6db2a1e 100644 --- a/bgpd/rfapi/rfapi_import.c +++ b/bgpd/rfapi/rfapi_import.c @@ -543,7 +543,7 @@ rfapiBgpInfoCreate ( rfapi_time (&new->extra->vnc.import.create_time); } if (label) - encode_label (*label, new->extra->tag); + encode_label (*label, &new->extra->label); new->type = type; new->sub_type = sub_type; new->peer = peer; @@ -1431,7 +1431,7 @@ rfapiRouteInfo2NextHopEntry ( vo->v.l2addr.local_nve_id = bi->extra->vnc.import.rd.val[1]; /* label comes from MP_REACH_NLRI label */ - vo->v.l2addr.label = decode_label (bi->extra->tag); + vo->v.l2addr.label = decode_label (&bi->extra->label); new->vn_options = vo; @@ -4542,7 +4542,7 @@ rfapiBgpTableFilteredImport ( continue; if (bi->extra) - label = decode_label (bi->extra->tag); + label = decode_label (&bi->extra->label); (*rfapiBgpInfoFilteredImportFunction (safi)) ( it, /* which import table */ FIF_ACTION_UPDATE, diff --git a/bgpd/rfapi/rfapi_rib.c b/bgpd/rfapi/rfapi_rib.c index b2e6503ab4..5c3976a0c1 100644 --- a/bgpd/rfapi/rfapi_rib.c +++ b/bgpd/rfapi/rfapi_rib.c @@ -735,7 +735,7 @@ rfapiRibBi2Ri( vo->v.l2addr.local_nve_id = bi->extra->vnc.import.rd.val[1]; /* label comes from MP_REACH_NLRI label */ - vo->v.l2addr.label = decode_label (bi->extra->tag); + vo->v.l2addr.label = decode_label (&bi->extra->label); rfapi_vn_options_free (ri->vn_options); /* maybe free old version */ ri->vn_options = vo; diff --git a/bgpd/rfapi/rfapi_vty.c b/bgpd/rfapi/rfapi_vty.c index 2062164890..d12958a600 100644 --- a/bgpd/rfapi/rfapi_vty.c +++ b/bgpd/rfapi/rfapi_vty.c @@ -478,7 +478,7 @@ rfapi_vty_out_vncinfo ( } if (bi->extra != NULL) - vty_out (vty, " label=%u", decode_label (bi->extra->tag)); + vty_out (vty, " label=%u", decode_label (&bi->extra->label)); if (!rfapiGetVncLifetime (bi->attr, &lifetime)) { @@ -1178,7 +1178,7 @@ rfapiPrintRemoteRegBi ( inet_ntop (pfx_vn.family, &pfx_vn.u.prefix, buf_ntop, BUFSIZ)); if (bi->extra) { - u_int32_t l = decode_label (bi->extra->tag); + u_int32_t l = decode_label (&bi->extra->label); snprintf (buf_vn, BUFSIZ, "Label: %d", l); } else /* should never happen */ @@ -1305,7 +1305,7 @@ rfapiPrintRemoteRegBi ( } if (tun_type != BGP_ENCAP_TYPE_MPLS && bi->extra) { - u_int32_t l = decode_label (bi->extra->tag); + u_int32_t l = decode_label (&bi->extra->label); if (!MPLS_LABEL_IS_NULL (l)) { fp (out, " Label: %d", l); @@ -2672,8 +2672,7 @@ DEFUN (add_vnc_prefix_cost_life, "Administrative cost [default: 255]\n" "Administrative cost\n" "Registration lifetime [default: infinite]\n" - "Lifetime value in seconds\n" - "[local-next-hop (A.B.C.D|X:X::X:X)] [local-cost <0-255>]\n") + "Lifetime value in seconds\n") { /* pfx vn un cost life */ return register_add (vty, argv[3], argv[5], argv[7], argv[9], argv[11], @@ -2698,8 +2697,7 @@ DEFUN (add_vnc_prefix_life_cost, "Registration lifetime [default: infinite]\n" "Lifetime value in seconds\n" "Administrative cost [default: 255]\n" - "Administrative cost\n" - "[local-next-hop (A.B.C.D|X:X::X:X)] [local-cost <0-255>]\n") + "Administrative cost\n") { /* pfx vn un cost life */ return register_add (vty, argv[3], argv[5], argv[7], argv[11], argv[9], @@ -2722,8 +2720,7 @@ DEFUN (add_vnc_prefix_cost, "UN IPv4 interface address\n" "UN IPv6 interface address\n" "Administrative cost [default: 255]\n" - "Administrative cost\n" - "[local-next-hop (A.B.C.D|X:X::X:X)] [local-cost <0-255>]\n") + "Administrative cost\n") { /* pfx vn un cost life */ return register_add (vty, argv[3], argv[5], argv[7], argv[9], NULL, @@ -2746,8 +2743,7 @@ DEFUN (add_vnc_prefix_life, "UN IPv4 interface address\n" "UN IPv6 interface address\n" "Registration lifetime [default: infinite]\n" - "Lifetime value in seconds\n" - "[local-next-hop (A.B.C.D|X:X::X:X)] [local-cost <0-255>]\n") + "Lifetime value in seconds\n") { /* pfx vn un cost life */ return register_add (vty, argv[3], argv[5], argv[7], NULL, argv[9], @@ -2768,8 +2764,7 @@ DEFUN (add_vnc_prefix, "VN IPv6 interface address\n" "UN address of NVE\n" "UN IPv4 interface address\n" - "UN IPv6 interface address\n" - "[local-next-hop (A.B.C.D|X:X::X:X)] [local-cost <0-255>]\n") + "UN IPv6 interface address\n") { /* pfx vn un cost life */ return register_add (vty, argv[3], argv[5], argv[7], NULL, NULL, @@ -4064,7 +4059,6 @@ DEFUN (clear_vnc_mac_vn_un, "VNI keyword\n" "Any virtual network identifier\n" "Virtual network identifier\n" - "Virtual network identifier\n" "VN address of NVE\n" "All VN addresses\n" "VN IPv4 interface address\n" diff --git a/bgpd/rfapi/vnc_import_bgp.c b/bgpd/rfapi/vnc_import_bgp.c index cb9c474d92..47203cd238 100644 --- a/bgpd/rfapi/vnc_import_bgp.c +++ b/bgpd/rfapi/vnc_import_bgp.c @@ -536,7 +536,7 @@ vnc_import_bgp_add_route_mode_resolve_nve_one_bi ( ecommunity_merge (new_ecom, bi->attr->extra->ecommunity); if (bi->extra) - label = decode_label (bi->extra->tag); + label = decode_label (&bi->extra->label); add_vnc_route ( &vncHDResolveNve, @@ -1919,7 +1919,7 @@ vnc_import_bgp_exterior_add_route_it ( if (bi_interior->extra) { prd = &bi_interior->extra->vnc.import.rd; - label = decode_label (bi_interior->extra->tag); + label = decode_label (&bi_interior->extra->label); } else prd = NULL; @@ -2101,7 +2101,7 @@ vnc_import_bgp_exterior_del_route ( if (bi_interior->extra) { prd = &bi_interior->extra->vnc.import.rd; - label = decode_label (bi_interior->extra->tag); + label = decode_label (&bi_interior->extra->label); } else prd = NULL; @@ -2249,7 +2249,7 @@ vnc_import_bgp_exterior_add_route_interior ( if (bi_interior->extra) { prd = &bi_interior->extra->vnc.import.rd; - label = decode_label (bi_interior->extra->tag); + label = decode_label (&bi_interior->extra->label); } else prd = NULL; @@ -2364,7 +2364,7 @@ vnc_import_bgp_exterior_add_route_interior ( if (bi->extra) { prd = &bi->extra->vnc.import.rd; - label = decode_label (bi->extra->tag); + label = decode_label (&bi->extra->label); } else prd = NULL; @@ -2388,7 +2388,7 @@ vnc_import_bgp_exterior_add_route_interior ( if (bi_interior->extra) { prd = &bi_interior->extra->vnc.import.rd; - label = decode_label (bi_interior->extra->tag); + label = decode_label (&bi_interior->extra->label); } else prd = NULL; @@ -2512,7 +2512,7 @@ vnc_import_bgp_exterior_add_route_interior ( if (bi_interior->extra) { prd = &bi_interior->extra->vnc.import.rd; - label = decode_label (bi_interior->extra->tag); + label = decode_label (&bi_interior->extra->label); } else prd = NULL; @@ -2633,7 +2633,7 @@ vnc_import_bgp_exterior_del_route_interior ( if (bi_interior->extra) { prd = &bi_interior->extra->vnc.import.rd; - label = decode_label (bi_interior->extra->tag); + label = decode_label (&bi_interior->extra->label); } else prd = NULL; @@ -2716,7 +2716,7 @@ vnc_import_bgp_exterior_del_route_interior ( if (bi->extra) { prd = &bi->extra->vnc.import.rd; - label = decode_label (bi->extra->tag); + label = decode_label (&bi->extra->label); } else prd = NULL; diff --git a/isisd/isis_vty.c b/isisd/isis_vty.c index b603ab5dc9..f0e2831bff 100644 --- a/isisd/isis_vty.c +++ b/isisd/isis_vty.c @@ -673,7 +673,6 @@ DEFUN (isis_hello_interval, "isis hello-interval (1-600)", "IS-IS commands\n" "Set Hello interval\n" - "Hello interval value\n" "Holdtime 1 seconds, interval depends on multiplier\n") { int idx_number = 2; @@ -721,7 +720,6 @@ DEFUN (isis_hello_interval_l1, "isis hello-interval (1-600) level-1", "IS-IS commands\n" "Set Hello interval\n" - "Hello interval value\n" "Holdtime 1 second, interval depends on multiplier\n" "Specify hello-interval for level-1 IIHs\n") { @@ -769,7 +767,6 @@ DEFUN (isis_hello_interval_l2, "isis hello-interval (1-600) level-2", "IS-IS commands\n" "Set Hello interval\n" - "Hello interval value\n" "Holdtime 1 second, interval depends on multiplier\n" "Specify hello-interval for level-2 IIHs\n") { @@ -958,8 +955,7 @@ DEFUN (isis_hello_padding, "isis hello padding", "IS-IS commands\n" "Add padding to IS-IS hello packets\n" - "Pad hello packets\n" - "<cr>\n") + "Pad hello packets\n") { struct isis_circuit *circuit = isis_circuit_lookup (vty); if (!circuit) @@ -976,8 +972,7 @@ DEFUN (no_isis_hello_padding, NO_STR "IS-IS commands\n" "Add padding to IS-IS hello packets\n" - "Pad hello packets\n" - "<cr>\n") + "Pad hello packets\n") { struct isis_circuit *circuit = isis_circuit_lookup (vty); if (!circuit) @@ -1431,8 +1426,7 @@ DEFUN (no_metric_style, DEFUN (set_overload_bit, set_overload_bit_cmd, "set-overload-bit", - "Set overload bit to avoid any transit traffic\n" - "Set overload bit\n") + "Set overload bit to avoid any transit traffic\n") { VTY_DECLVAR_CONTEXT (isis_area, area); @@ -1455,8 +1449,7 @@ DEFUN (no_set_overload_bit, DEFUN (set_attached_bit, set_attached_bit_cmd, "set-attached-bit", - "Set attached bit to identify as L1/L2 router for inter-area traffic\n" - "Set attached bit\n") + "Set attached bit to identify as L1/L2 router for inter-area traffic\n") { VTY_DECLVAR_CONTEXT (isis_area, area); diff --git a/lib/Makefile.am b/lib/Makefile.am index e1b84587da..5847ad4939 100644 --- a/lib/Makefile.am +++ b/lib/Makefile.am @@ -86,6 +86,9 @@ pkginclude_HEADERS = \ frr_pthread.h \ vrf_int.h \ termtable.h \ + vlan.h \ + vxlan.h \ + ipaddr.h \ # end noinst_HEADERS = \ diff --git a/lib/agentx.c b/lib/agentx.c index 08cd650153..d058779aff 100644 --- a/lib/agentx.c +++ b/lib/agentx.c @@ -175,8 +175,7 @@ config_write_agentx (struct vty *vty) DEFUN (agentx_enable, agentx_enable_cmd, "agentx", - "SNMP AgentX protocol settings\n" - "SNMP AgentX settings\n") + "SNMP AgentX protocol settings\n") { if (!agentx_enabled) { @@ -194,8 +193,7 @@ DEFUN (no_agentx, no_agentx_cmd, "no agentx", NO_STR - "SNMP AgentX protocol settings\n" - "SNMP AgentX settings\n") + "SNMP AgentX protocol settings\n") { if (!agentx_enabled) return CMD_SUCCESS; vty_outln (vty, "SNMP AgentX support cannot be disabled once enabled"); diff --git a/lib/bitfield.h b/lib/bitfield.h index 4ff9c7fb2e..1e0b54731a 100644 --- a/lib/bitfield.h +++ b/lib/bitfield.h @@ -78,12 +78,27 @@ typedef unsigned int word_t; bf_set_bit(v, id); \ } while (0) -/** +/* + * allocate and assign 0th bit in the bitfiled. + */ +#define bf_assign_zero_index(v) \ + do { \ + int id = 0; \ + bf_assign_index(v, id); \ + } while (0) + +/* * return an id to bitfield v */ #define bf_release_index(v, id) \ (v).data[bf_index(id)] &= ~(1 << (bf_offset(id))) +/* + * return 0th index back to bitfield + */ +#define bf_release_zero_index(v) \ + bf_release_index(v, 0) + #define bf_index(b) ((b) / WORD_SIZE) #define bf_offset(b) ((b) % WORD_SIZE) @@ -118,4 +133,15 @@ typedef unsigned int word_t; (b) += (w * WORD_SIZE); \ } while (0) +/* + * Free the allocated memory for data + * @v: an instance of bitfield_t struct. + */ +#define bf_free(v) \ + do { \ + if ((v).data) { \ + free((v).data); \ + } \ + } while (0) + #endif diff --git a/lib/command.c b/lib/command.c index de8899687c..5ca4a0fda9 100644 --- a/lib/command.c +++ b/lib/command.c @@ -2200,7 +2200,6 @@ DEFUN (no_config_log_file, "Logging control\n" "Cancel logging to file\n" "Logging file name\n" - "Logging file name\n" "Logging level\n") { zlog_reset_file (); diff --git a/lib/command_parse.y b/lib/command_parse.y index 3337481094..ba042c33be 100644 --- a/lib/command_parse.y +++ b/lib/command_parse.y @@ -443,6 +443,14 @@ terminate_graph (CMD_YYLTYPE *locp, struct parser_ctx *ctx, struct graph_node *end_element_node = graph_new_node (ctx->graph, element, NULL); + if (ctx->docstr && strlen (ctx->docstr) > 1) { + zlog_debug ("Excessive docstring while parsing '%s'", ctx->el->string); + zlog_debug ("----------"); + while (ctx->docstr && ctx->docstr[1] != '\0') + zlog_debug ("%s", strsep(&ctx->docstr, "\n")); + zlog_debug ("----------\n"); + } + graph_add_edge (finalnode, end_token_node); graph_add_edge (end_token_node, end_element_node); } diff --git a/lib/hash.h b/lib/hash.h index 9395440acb..01d2b1ddc8 100644 --- a/lib/hash.h +++ b/lib/hash.h @@ -84,6 +84,8 @@ struct hash char *name; }; +#define hashcount(X) ((X)->count) + extern struct hash *hash_create (unsigned int (*) (void *), int (*) (const void *, const void *), const char *); diff --git a/lib/ipaddr.h b/lib/ipaddr.h new file mode 100644 index 0000000000..ea98a1b746 --- /dev/null +++ b/lib/ipaddr.h @@ -0,0 +1,94 @@ +/* + * IP address structure (for generic IPv4 or IPv6 address) + * Copyright (C) 2016, 2017 Cumulus Networks, Inc. + * + * This file is part of FRR. + * + * FRR is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2, or (at your option) any + * later version. + * + * FRR is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with FRR; see the file COPYING. If not, write to the Free + * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + * 02111-1307, USA. + */ + +#ifndef __IPADDR_H__ +#define __IPADDR_H__ + +#include <zebra.h> + +/* + * Generic IP address - union of IPv4 and IPv6 address. + */ +enum ipaddr_type_t +{ + IPADDR_NONE = 0, + IPADDR_V4 = 1, /* IPv4 */ + IPADDR_V6 = 2, /* IPv6 */ +}; + +struct ipaddr +{ + enum ipaddr_type_t ipa_type; + union + { + u_char addr; + struct in_addr _v4_addr; + struct in6_addr _v6_addr; + } ip; +#define ipaddr_v4 ip._v4_addr +#define ipaddr_v6 ip._v6_addr +}; + +#define IS_IPADDR_NONE(p) ((p)->ipa_type == IPADDR_NONE) +#define IS_IPADDR_V4(p) ((p)->ipa_type == IPADDR_V4) +#define IS_IPADDR_V6(p) ((p)->ipa_type == IPADDR_V6) + +#define SET_IPADDR_V4(p) (p)->ipa_type = IPADDR_V4 +#define SET_IPADDR_V6(p) (p)->ipa_type = IPADDR_V6 + +static inline int +str2ipaddr (const char *str, struct ipaddr *ip) +{ + int ret; + + memset (ip, 0, sizeof (struct ipaddr)); + + ret = inet_pton (AF_INET, str, &ip->ipaddr_v4); + if (ret > 0) /* Valid IPv4 address. */ + { + ip->ipa_type = IPADDR_V4; + return 0; + } + ret = inet_pton (AF_INET6, str, &ip->ipaddr_v6); + if (ret > 0) /* Valid IPv6 address. */ + { + ip->ipa_type = IPADDR_V6; + return 0; + } + + return -1; +} + +static inline char * +ipaddr2str (struct ipaddr *ip, char *buf, int size) +{ + buf[0] = '\0'; + if (ip) + { + if (IS_IPADDR_V4(ip)) + inet_ntop (AF_INET, &ip->ip.addr, buf, size); + else if (IS_IPADDR_V6(ip)) + inet_ntop (AF_INET6, &ip->ip.addr, buf, size); + } + return buf; +} +#endif /* __IPADDR_H__ */ diff --git a/lib/mpls.h b/lib/mpls.h index c963e55087..20315df7d6 100644 --- a/lib/mpls.h +++ b/lib/mpls.h @@ -80,8 +80,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/plist.c b/lib/plist.c index 172f2b39db..339540a2b5 100644 --- a/lib/plist.c +++ b/lib/plist.c @@ -1736,9 +1736,7 @@ DEFPY (show_ipv6_prefix_list, PREFIX_LIST_STR "Name of a prefix list\n" "sequence number of an entry\n" - "Sequence number\n" - "Lookup longer prefix\n" - "First matched prefix\n") + "Sequence number\n") { enum display_type dtype = normal_display; if (dseq) diff --git a/lib/prefix.c b/lib/prefix.c index 4131f37fbd..f89b5a5ee6 100644 --- a/lib/prefix.c +++ b/lib/prefix.c @@ -877,6 +877,66 @@ str2prefix (const char *str, struct prefix *p) return 0; } +static const char * +prefixeth2str (const struct prefix *p, char *str, int size) +{ + u_char family; + char buf[PREFIX2STR_BUFFER]; + char buf2[ETHER_ADDR_STRLEN]; + + if (p->u.prefix_evpn.route_type == 2) + { + if (IS_EVPN_PREFIX_IPADDR_NONE((struct prefix_evpn *)p)) + snprintf (str, size, "[%d]:[%s]/%d", + p->u.prefix_evpn.route_type, + prefix_mac2str (&p->u.prefix_evpn.mac, buf2, sizeof (buf2)), + p->prefixlen); + else + { + family = IS_EVPN_PREFIX_IPADDR_V4((struct prefix_evpn *)p) ? \ + AF_INET : AF_INET6; + snprintf (str, size, "[%d]:[%s]:[%s]/%d", + p->u.prefix_evpn.route_type, + prefix_mac2str (&p->u.prefix_evpn.mac, buf2, sizeof (buf2)), + inet_ntop (family, &p->u.prefix_evpn.ip.ip.addr, + buf, PREFIX2STR_BUFFER), + p->prefixlen); + } + } + else if (p->u.prefix_evpn.route_type == 3) + { + family = IS_EVPN_PREFIX_IPADDR_V4((struct prefix_evpn *)p) ? \ + AF_INET : AF_INET6; + snprintf (str, size, "[%d]:[%s]/%d", + p->u.prefix_evpn.route_type, + inet_ntop (family, &p->u.prefix_evpn.ip.ip.addr, + buf, PREFIX2STR_BUFFER), + p->prefixlen); + } + else if (p->u.prefix_evpn.route_type == 5) + { + family = IS_EVPN_PREFIX_IPADDR_V4((struct prefix_evpn *)p) ? \ + AF_INET : AF_INET6; + snprintf (str, size, "[%d]:[%u][%s]/%d", + p->u.prefix_evpn.route_type, + p->u.prefix_evpn.eth_tag, + inet_ntop (family, &p->u.prefix_evpn.ip.ip.addr, + buf, PREFIX2STR_BUFFER), + p->prefixlen); + } + else + { + sprintf (str, "UNK AF_ETHER prefix"); + snprintf(str, size, "%02x:%02x:%02x:%02x:%02x:%02x/%d", + p->u.prefix_eth.octet[0], p->u.prefix_eth.octet[1], + p->u.prefix_eth.octet[2], p->u.prefix_eth.octet[3], + p->u.prefix_eth.octet[4], p->u.prefix_eth.octet[5], + p->prefixlen); + } + + return str; +} + const char * prefix2str (union prefixconstptr pu, char *str, int size) { @@ -893,28 +953,9 @@ prefix2str (union prefixconstptr pu, char *str, int size) break; case AF_ETHERNET: - if (p->u.prefix_evpn.route_type == 5) - { - u_char family; - family = (p->u.prefix_evpn.flags & (IP_ADDR_V4 | IP_PREFIX_V4)) ? - AF_INET : AF_INET6; - snprintf (str, size, "[%d]:[%u][%s]/%d", - p->u.prefix_evpn.route_type, - p->u.prefix_evpn.eth_tag, - inet_ntop (family, &p->u.prefix_evpn.ip.addr, - buf, PREFIX2STR_BUFFER), - p->prefixlen); - } - else - { - sprintf (str, "UNK AF_ETHER prefix"); - snprintf(str, size, "%02x:%02x:%02x:%02x:%02x:%02x/%d", - p->u.prefix_eth.octet[0], p->u.prefix_eth.octet[1], - p->u.prefix_eth.octet[2], p->u.prefix_eth.octet[3], - p->u.prefix_eth.octet[4], p->u.prefix_eth.octet[5], - p->prefixlen); - } + prefixeth2str (p, str, size); break; + default: sprintf (str, "UNK prefix"); break; diff --git a/lib/prefix.h b/lib/prefix.h index 24144e80a3..549798e92e 100644 --- a/lib/prefix.h +++ b/lib/prefix.h @@ -32,6 +32,7 @@ # endif #endif #include "sockunion.h" +#include "ipaddr.h" #ifndef ETHER_ADDR_LEN #ifdef ETHERADDRL @@ -62,30 +63,23 @@ struct ethaddr { struct evpn_addr { u_char route_type; - u_char flags; -#define IP_ADDR_NONE 0x0 -#define IP_ADDR_V4 0x1 -#define IP_ADDR_V6 0x2 -#define IP_PREFIX_V4 0x4 -#define IP_PREFIX_V6 0x8 + u_char ip_prefix_length; struct ethaddr mac; uint32_t eth_tag; - u_char ip_prefix_length; + struct ipaddr ip; +#if 0 union { u_char addr; struct in_addr v4_addr; struct in6_addr v6_addr; } ip; +#endif }; -/* EVPN prefix structure. */ -struct prefix_evpn -{ - u_char family; - u_char prefixlen; - struct evpn_addr prefix __attribute__ ((aligned (8))); -}; +#define IS_EVPN_PREFIX_IPADDR_NONE(evp) IS_IPADDR_NONE(&(evp)->prefix.ip) +#define IS_EVPN_PREFIX_IPADDR_V4(evp) IS_IPADDR_V4(&(evp)->prefix.ip) +#define IS_EVPN_PREFIX_IPADDR_V6(evp) IS_IPADDR_V6(&(evp)->prefix.ip) /* * A struct prefix contains an address family, a prefix length, and an @@ -167,6 +161,14 @@ struct prefix_eth struct ethaddr eth_addr __attribute__ ((aligned (8))); /* AF_ETHERNET */ }; +/* EVPN prefix structure. */ +struct prefix_evpn +{ + u_char family; + u_char prefixlen; + struct evpn_addr prefix __attribute__ ((aligned (8))); +}; + /* Prefix for a generic pointer */ struct prefix_ptr { diff --git a/lib/stream.c b/lib/stream.c index e8320a8fa1..6163a5b3ec 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 dd6aae677d..c012cc4593 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/lib/vlan.h b/lib/vlan.h new file mode 100644 index 0000000000..5e735aac1f --- /dev/null +++ b/lib/vlan.h @@ -0,0 +1,29 @@ +/* VLAN (802.1q) common header. + * Copyright (C) 2016, 2017 Cumulus Networks, Inc. + * + * This file is part of FRR. + * + * FRR is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2, or (at your option) any + * later version. + * + * FRR is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with FRR; see the file COPYING. If not, write to the Free + * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + * 02111-1307, USA. + */ + +#ifndef __VLAN_H__ +#define __VLAN_H__ + +/* VLAN Identifier */ +typedef u_int16_t vlanid_t; +#define VLANID_MAX 4095 + +#endif /* __VLAN_H__ */ diff --git a/lib/vxlan.h b/lib/vxlan.h new file mode 100644 index 0000000000..75c7b97347 --- /dev/null +++ b/lib/vxlan.h @@ -0,0 +1,29 @@ +/* VxLAN common header. + * Copyright (C) 2016, 2017 Cumulus Networks, Inc. + * + * This file is part of FRR. + * + * FRR is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2, or (at your option) any + * later version. + * + * FRR is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with FRR; see the file COPYING. If not, write to the Free + * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + * 02111-1307, USA. + */ + +#ifndef __VXLAN_H__ +#define __VXLAN_H__ + +/* VxLAN Network Identifier - 24-bit (RFC 7348) */ +typedef u_int32_t vni_t; +#define VNI_MAX 16777215 /* (2^24 - 1) */ + +#endif /* __VXLAN_H__ */ diff --git a/lib/zebra.h b/lib/zebra.h index 901a49073d..7f2609c125 100644 --- a/lib/zebra.h +++ b/lib/zebra.h @@ -126,7 +126,7 @@ typedef unsigned char u_int8_t; #define __APPLE_USE_RFC_3542 #endif -#include "lib/openbsd-tree.h" +#include "openbsd-tree.h" #include <netinet/in.h> #include <netinet/in_systm.h> diff --git a/ospf6d/ospf6_interface.c b/ospf6d/ospf6_interface.c index e50de6fab2..e91c249845 100644 --- a/ospf6d/ospf6_interface.c +++ b/ospf6d/ospf6_interface.c @@ -1729,9 +1729,7 @@ DEFUN (no_ipv6_ospf6_network, NO_STR IP6_STR OSPF6_STR - "Network type\n" - "Default to whatever interface type system specifies" - ) + "Set default network type\n") { VTY_DECLVAR_CONTEXT(interface, ifp); struct ospf6_interface *oi; diff --git a/ospf6d/ospf6_top.c b/ospf6d/ospf6_top.c index 2f157d98a0..268b7a60a2 100644 --- a/ospf6d/ospf6_top.c +++ b/ospf6d/ospf6_top.c @@ -697,7 +697,6 @@ DEFUN (ospf6_stub_router_admin, ospf6_stub_router_admin_cmd, "stub-router administrative", "Make router a stub router\n" - "Advertise inability to be a transit router\n" "Administratively applied, for an indefinite period\n") { struct listnode *node; @@ -722,7 +721,6 @@ DEFUN (no_ospf6_stub_router_admin, "no stub-router administrative", NO_STR "Make router a stub router\n" - "Advertise ability to be a transit router\n" "Administratively applied, for an indefinite period\n") { struct listnode *node; diff --git a/ospfd/ospf_vty.c b/ospfd/ospf_vty.c index 799214c9c5..bc98da45ee 100644 --- a/ospfd/ospf_vty.c +++ b/ospfd/ospf_vty.c @@ -7095,8 +7095,7 @@ DEFUN (ospf_redistribute_source, "Metric for redistributed routes\n" "OSPF default metric\n" "OSPF exterior metric type for redistributed routes\n" - "Set OSPF External Type 1 metrics\n" - "Set OSPF External Type 2 metrics\n" + "Set OSPF External Type 1/2 metrics\n" "Route map reference\n" "Pointer to route-map entries\n") { @@ -7147,8 +7146,7 @@ DEFUN (no_ospf_redistribute_source, "Metric for redistributed routes\n" "OSPF default metric\n" "OSPF exterior metric type for redistributed routes\n" - "Set OSPF External Type 1 metrics\n" - "Set OSPF External Type 2 metrics\n" + "Set OSPF External Type 1/2 metrics\n" "Route map reference\n" "Pointer to route-map entries\n") { @@ -7179,8 +7177,7 @@ DEFUN (ospf_redistribute_instance_source, "Metric for redistributed routes\n" "OSPF default metric\n" "OSPF exterior metric type for redistributed routes\n" - "Set OSPF External Type 1 metrics\n" - "Set OSPF External Type 2 metrics\n" + "Set OSPF External Type 1/2 metrics\n" "Route map reference\n" "Pointer to route-map entries\n") { @@ -7251,8 +7248,7 @@ DEFUN (no_ospf_redistribute_instance_source, "Metric for redistributed routes\n" "OSPF default metric\n" "OSPF exterior metric type for redistributed routes\n" - "Set OSPF External Type 1 metrics\n" - "Set OSPF External Type 2 metrics\n" + "Set OSPF External Type 1/2 metrics\n" "Route map reference\n" "Pointer to route-map entries\n") { @@ -7345,8 +7341,7 @@ DEFUN (ospf_default_information_originate, "OSPF default metric\n" "OSPF metric\n" "OSPF metric type for default routes\n" - "Set OSPF External Type 1 metrics\n" - "Set OSPF External Type 2 metrics\n" + "Set OSPF External Type 1/2 metrics\n" "Route map reference\n" "Pointer to route-map entries\n") { @@ -7392,8 +7387,7 @@ DEFUN (no_ospf_default_information_originate, "OSPF default metric\n" "OSPF metric\n" "OSPF metric type for default routes\n" - "Set OSPF External Type 1 metrics\n" - "Set OSPF External Type 2 metrics\n" + "Set OSPF External Type 1/2 metrics\n" "Route map reference\n" "Pointer to route-map entries\n") { diff --git a/pimd/pim_cmd.c b/pimd/pim_cmd.c index 0051298e4a..b0afc7828a 100644 --- a/pimd/pim_cmd.c +++ b/pimd/pim_cmd.c @@ -4256,7 +4256,6 @@ DEFUN_HIDDEN (no_ip_multicast_routing, "no ip multicast-routing", NO_STR IP_STR - "Global IP configuration subcommands\n" "Enable IP multicast forwarding\n") { vty_outln (vty, @@ -5732,7 +5731,6 @@ DEFUN (debug_ssmpingd, debug_ssmpingd_cmd, "debug ssmpingd", DEBUG_STR - DEBUG_PIM_STR DEBUG_SSMPINGD_STR) { PIM_DO_DEBUG_SSMPINGD; @@ -5744,7 +5742,6 @@ DEFUN (no_debug_ssmpingd, "no debug ssmpingd", NO_STR DEBUG_STR - DEBUG_PIM_STR DEBUG_SSMPINGD_STR) { PIM_DONT_DEBUG_SSMPINGD; diff --git a/ripd/rip_interface.c b/ripd/rip_interface.c index 425b01c247..4ce1b9b655 100644 --- a/ripd/rip_interface.c +++ b/ripd/rip_interface.c @@ -1327,8 +1327,7 @@ DEFUN (ip_rip_receive_version, "Routing Information Protocol\n" "Advertisement reception\n" "Version control\n" - "RIP version 1\n" - "RIP version 2\n" + "RIP version\n" "None\n") { VTY_DECLVAR_CONTEXT(interface, ifp); @@ -1357,31 +1356,13 @@ DEFUN (ip_rip_receive_version, DEFUN (ip_rip_receive_version_1, ip_rip_receive_version_1_cmd, - "ip rip receive version (1-1) (2-2)", + "ip rip receive version <1 2|2 1>", IP_STR "Routing Information Protocol\n" "Advertisement reception\n" "Version control\n" "RIP version 1\n" - "RIP version 2\n") -{ - VTY_DECLVAR_CONTEXT(interface, ifp); - struct rip_interface *ri; - - ri = ifp->info; - - /* Version 1 and 2. */ - ri->ri_receive = RI_RIP_VERSION_1_AND_2; - return CMD_SUCCESS; -} - -DEFUN (ip_rip_receive_version_2, - ip_rip_receive_version_2_cmd, - "ip rip receive version (2-2) (1-1)", - IP_STR - "Routing Information Protocol\n" - "Advertisement reception\n" - "Version control\n" + "RIP version 2\n" "RIP version 2\n" "RIP version 1\n") { @@ -1403,8 +1384,7 @@ DEFUN (no_ip_rip_receive_version, "Routing Information Protocol\n" "Advertisement reception\n" "Version control\n" - "Version 1\n" - "Version 2\n") + "RIP version\n") { VTY_DECLVAR_CONTEXT(interface, ifp); struct rip_interface *ri; @@ -1423,8 +1403,7 @@ DEFUN (ip_rip_send_version, "Routing Information Protocol\n" "Advertisement transmission\n" "Version control\n" - "RIP version 1\n" - "RIP version 2\n") + "RIP version\n") { VTY_DECLVAR_CONTEXT(interface, ifp); int idx_type = 4; @@ -1448,31 +1427,13 @@ DEFUN (ip_rip_send_version, DEFUN (ip_rip_send_version_1, ip_rip_send_version_1_cmd, - "ip rip send version (1-1) (2-2)", + "ip rip send version <1 2|2 1>", IP_STR "Routing Information Protocol\n" "Advertisement transmission\n" "Version control\n" "RIP version 1\n" - "RIP version 2\n") -{ - VTY_DECLVAR_CONTEXT(interface, ifp); - struct rip_interface *ri; - - ri = ifp->info; - - /* Version 1 and 2. */ - ri->ri_send = RI_RIP_VERSION_1_AND_2; - return CMD_SUCCESS; -} - -DEFUN (ip_rip_send_version_2, - ip_rip_send_version_2_cmd, - "ip rip send version (2-2) (1-1)", - IP_STR - "Routing Information Protocol\n" - "Advertisement transmission\n" - "Version control\n" + "RIP version 2\n" "RIP version 2\n" "RIP version 1\n") { @@ -1494,8 +1455,7 @@ DEFUN (no_ip_rip_send_version, "Routing Information Protocol\n" "Advertisement transmission\n" "Version control\n" - "Version 1\n" - "Version 2\n") + "RIP version\n") { VTY_DECLVAR_CONTEXT(interface, ifp); struct rip_interface *ri; @@ -2034,12 +1994,10 @@ rip_if_init (void) install_element (INTERFACE_NODE, &ip_rip_send_version_cmd); install_element (INTERFACE_NODE, &ip_rip_send_version_1_cmd); - install_element (INTERFACE_NODE, &ip_rip_send_version_2_cmd); install_element (INTERFACE_NODE, &no_ip_rip_send_version_cmd); install_element (INTERFACE_NODE, &ip_rip_receive_version_cmd); install_element (INTERFACE_NODE, &ip_rip_receive_version_1_cmd); - install_element (INTERFACE_NODE, &ip_rip_receive_version_2_cmd); install_element (INTERFACE_NODE, &no_ip_rip_receive_version_cmd); install_element (INTERFACE_NODE, &ip_rip_v2_broadcast_cmd); diff --git a/tests/Makefile.am b/tests/Makefile.am index 559d769702..8f612c45a5 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -148,7 +148,9 @@ EXTRA_DIST = \ lib/test_stream.refout \ lib/test_table.py \ lib/test_timer_correctness.py \ - lib/test_ttable.py + lib/test_ttable.py \ + lib/test_ttable.refout \ + # end .PHONY: tests.xml tests.xml: $(check_PROGRAMS) diff --git a/vtysh/vtysh.c b/vtysh/vtysh.c index 0e04f4bf8e..f02bd0c888 100644 --- a/vtysh/vtysh.c +++ b/vtysh/vtysh.c @@ -564,9 +564,10 @@ vtysh_mark_file (const char *filename) * to move into node in the vtysh where it succeeded. */ if (ret == CMD_SUCCESS || ret == CMD_SUCCESS_DAEMON || ret == CMD_WARNING) { - if ((prev_node == BGP_VPNV4_NODE || prev_node == BGP_IPV4_NODE - || prev_node == BGP_IPV6_NODE || prev_node == BGP_IPV4M_NODE - || prev_node == BGP_IPV6M_NODE || prev_node == BGP_VPNV6_NODE + if ((prev_node == BGP_VPNV4_NODE || prev_node == BGP_VPNV6_NODE + || prev_node == BGP_IPV4_NODE || prev_node == BGP_IPV6_NODE + || prev_node == BGP_IPV4L_NODE || prev_node == BGP_IPV6L_NODE + || prev_node == BGP_IPV4M_NODE || prev_node == BGP_IPV6M_NODE || prev_node == BGP_EVPN_NODE) && (tried == 1)) { @@ -1271,9 +1272,8 @@ DEFUNSH (VTYSH_BGPD, address_family_evpn_cmd, "address-family <l2vpn evpn>", "Enter Address Family command mode\n" - "EVPN Address family\n" - "Layer2 VPN Address family\n" - "Ethernet Virtual Private Network Subsequent Address Family\n") + "Address Family\n" + "Address Family modifier\n") { vty->node = BGP_EVPN_NODE; return CMD_SUCCESS; @@ -2445,10 +2445,9 @@ DEFUNSH (VTYSH_ALL, DEFUNSH (VTYSH_ALL, vtysh_config_password, vtysh_password_cmd, - "password (8-8) WORD", + "password [(8-8)] WORD", "Assign the terminal connection password\n" "Specifies a HIDDEN password will follow\n" - "dummy string \n" "The HIDDEN line password string\n") { return CMD_SUCCESS; diff --git a/zebra/if_netlink.c b/zebra/if_netlink.c index 8c50a95065..5af6c3a08f 100644 --- a/zebra/if_netlink.c +++ b/zebra/if_netlink.c @@ -437,6 +437,32 @@ netlink_interface (struct sockaddr_nl *snl, struct nlmsghdr *h, return 0; } +/* Request for specific interface or address information from the kernel */ +static int +netlink_request_intf_addr (struct zebra_ns *zns, + int family, int type, + u_int32_t filter_mask) +{ + struct + { + struct nlmsghdr n; + struct ifinfomsg ifm; + char buf[256]; + } req; + + /* Form the request, specifying filter (rtattr) if needed. */ + memset (&req, 0, sizeof (req)); + req.n.nlmsg_type = type; + req.n.nlmsg_len = NLMSG_LENGTH(sizeof(struct ifinfomsg)); + req.ifm.ifi_family = family; + + /* Include filter, if specified. */ + if (filter_mask) + addattr32 (&req.n, sizeof(req), IFLA_EXT_MASK, filter_mask); + + return netlink_request (&zns->netlink_cmd, &req.n); +} + /* Interface lookup by netlink socket. */ int interface_lookup_netlink (struct zebra_ns *zns) @@ -444,7 +470,7 @@ interface_lookup_netlink (struct zebra_ns *zns) int ret; /* Get interface information. */ - ret = netlink_request (AF_PACKET, RTM_GETLINK, &zns->netlink_cmd); + ret = netlink_request_intf_addr (zns, AF_PACKET, RTM_GETLINK, 0); if (ret < 0) return ret; ret = netlink_parse_info (netlink_interface, &zns->netlink_cmd, zns, 0, 1); @@ -452,7 +478,7 @@ interface_lookup_netlink (struct zebra_ns *zns) return ret; /* Get IPv4 address of the interfaces. */ - ret = netlink_request (AF_INET, RTM_GETADDR, &zns->netlink_cmd); + ret = netlink_request_intf_addr (zns, AF_INET, RTM_GETADDR, 0); if (ret < 0) return ret; ret = netlink_parse_info (netlink_interface_addr, &zns->netlink_cmd, zns, 0, 1); @@ -460,7 +486,7 @@ interface_lookup_netlink (struct zebra_ns *zns) return ret; /* Get IPv6 address of the interfaces. */ - ret = netlink_request (AF_INET6, RTM_GETADDR, &zns->netlink_cmd); + ret = netlink_request_intf_addr (zns, AF_INET6, RTM_GETADDR, 0); if (ret < 0) return ret; ret = netlink_parse_info (netlink_interface_addr, &zns->netlink_cmd, zns, 0, 1); diff --git a/zebra/kernel_netlink.c b/zebra/kernel_netlink.c index be9376b07f..3570676a4a 100644 --- a/zebra/kernel_netlink.c +++ b/zebra/kernel_netlink.c @@ -385,6 +385,12 @@ rta_addattr_l (struct rtattr *rta, unsigned int maxlen, int type, } int +addattr16 (struct nlmsghdr *n, unsigned int maxlen, int type, u_int16_t data) +{ + return addattr_l(n, maxlen, type, &data, sizeof(u_int16_t)); +} + +int addattr32 (struct nlmsghdr *n, unsigned int maxlen, int type, int data) { return addattr_l(n, maxlen, type, &data, sizeof(u_int32_t)); @@ -683,6 +689,7 @@ netlink_talk (int (*filter) (struct sockaddr_nl *, struct nlmsghdr *, snl.nl_family = AF_NETLINK; n->nlmsg_seq = ++nl->seq; + n->nlmsg_pid = nl->snl.nl_pid; /* Request an acknowledgement by setting NLM_F_ACK */ n->nlmsg_flags |= NLM_F_ACK; @@ -721,20 +728,16 @@ netlink_talk (int (*filter) (struct sockaddr_nl *, struct nlmsghdr *, return netlink_parse_info (filter, nl, zns, 0, startup); } -/* Get type specified information from netlink. */ +/* Issue request message to kernel via netlink socket. GET messages + * are issued through this interface. + */ int -netlink_request (int family, int type, struct nlsock *nl) +netlink_request (struct nlsock *nl, struct nlmsghdr *n) { int ret; struct sockaddr_nl snl; int save_errno; - struct - { - struct nlmsghdr nlh; - struct rtgenmsg g; - } req; - /* Check netlink socket. */ if (nl->sock < 0) { @@ -742,27 +745,22 @@ netlink_request (int family, int type, struct nlsock *nl) return -1; } + /* Fill common fields for all requests. */ + n->nlmsg_flags = NLM_F_ROOT | NLM_F_MATCH | NLM_F_REQUEST; + n->nlmsg_pid = nl->snl.nl_pid; + n->nlmsg_seq = ++nl->seq; + memset (&snl, 0, sizeof snl); snl.nl_family = AF_NETLINK; - memset (&req, 0, sizeof req); - req.nlh.nlmsg_len = sizeof req; - req.nlh.nlmsg_type = type; - req.nlh.nlmsg_flags = NLM_F_ROOT | NLM_F_MATCH | NLM_F_REQUEST; - req.nlh.nlmsg_pid = nl->snl.nl_pid; - req.nlh.nlmsg_seq = ++nl->seq; - req.g.rtgen_family = family; - - /* linux appears to check capabilities on every message - * have to raise caps for every message sent - */ + /* Raise capabilities and send message, then lower capabilities. */ if (zserv_privs.change (ZPRIVS_RAISE)) { zlog_err("Can't raise privileges"); return -1; } - ret = sendto (nl->sock, (void *) &req, sizeof req, 0, + ret = sendto (nl->sock, (void *)n, n->nlmsg_len, 0, (struct sockaddr *) &snl, sizeof snl); save_errno = errno; diff --git a/zebra/kernel_netlink.h b/zebra/kernel_netlink.h index 36ab5c3254..d642423232 100644 --- a/zebra/kernel_netlink.h +++ b/zebra/kernel_netlink.h @@ -31,6 +31,8 @@ extern int addattr_l (struct nlmsghdr *n, unsigned int maxlen, int type, void *data, unsigned int alen); extern int rta_addattr_l (struct rtattr *rta, unsigned int maxlen, int type, void *data, unsigned int alen); +extern int addattr16 (struct nlmsghdr *n, unsigned int maxlen, + int type, u_int16_t data); extern int addattr32 (struct nlmsghdr *n, unsigned int maxlen, int type, int data); extern struct rtattr *addattr_nest(struct nlmsghdr *n, int maxlen, int type); @@ -52,7 +54,7 @@ extern int netlink_talk (int (*filter) (struct sockaddr_nl *, struct nlmsghdr *, ns_id_t, int startup), struct nlmsghdr *n, struct nlsock *nl, struct zebra_ns *zns, int startup); -extern int netlink_request (int family, int type, struct nlsock *nl); +extern int netlink_request (struct nlsock *nl, struct nlmsghdr *n); #endif /* HAVE_NETLINK */ diff --git a/zebra/rt_netlink.c b/zebra/rt_netlink.c index 0adbe2c27f..471f650588 100644 --- a/zebra/rt_netlink.c +++ b/zebra/rt_netlink.c @@ -600,6 +600,25 @@ netlink_route_change (struct sockaddr_nl *snl, struct nlmsghdr *h, return 0; } +/* Request for specific route information from the kernel */ +static int +netlink_request_route (struct zebra_ns *zns, int family, int type) +{ + struct + { + struct nlmsghdr n; + struct rtmsg rtm; + } req; + + /* Form the request, specifying filter (rtattr) if needed. */ + memset (&req, 0, sizeof (req)); + req.n.nlmsg_type = type; + req.n.nlmsg_len = NLMSG_LENGTH(sizeof(struct rtmsg)); + req.rtm.rtm_family = family; + + return netlink_request (&zns->netlink_cmd, &req.n); +} + /* Routing table read function using netlink interface. Only called bootstrap time. */ int @@ -608,7 +627,7 @@ netlink_route_read (struct zebra_ns *zns) int ret; /* Get IPv4 routing table. */ - ret = netlink_request (AF_INET, RTM_GETROUTE, &zns->netlink_cmd); + ret = netlink_request_route (zns, AF_INET, RTM_GETROUTE); if (ret < 0) return ret; ret = netlink_parse_info (netlink_route_change_read_unicast, &zns->netlink_cmd, zns, 0, 1); @@ -616,7 +635,7 @@ netlink_route_read (struct zebra_ns *zns) return ret; /* Get IPv6 routing table. */ - ret = netlink_request (AF_INET6, RTM_GETROUTE, &zns->netlink_cmd); + ret = netlink_request_route (zns, AF_INET6, RTM_GETROUTE); if (ret < 0) return ret; ret = netlink_parse_info (netlink_route_change_read_unicast, &zns->netlink_cmd, zns, 0, 1); diff --git a/zebra/zebra_mpls.c b/zebra/zebra_mpls.c index 93844ee2a6..510d796937 100644 --- a/zebra/zebra_mpls.c +++ b/zebra/zebra_mpls.c @@ -1870,7 +1870,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/zebra_vty.c b/zebra/zebra_vty.c index c861efbddf..6ba4c1b9d5 100644 --- a/zebra/zebra_vty.c +++ b/zebra/zebra_vty.c @@ -433,8 +433,7 @@ DEFUN (ip_route_flags, "Set tag for this route\n" "Tag value\n" "Distance value for this route\n" - VRF_CMD_HELP_STR - MPLS_LABEL_HELPSTR) + VRF_CMD_HELP_STR) { int idx_ipv4_prefixlen = 2; int idx_reject_blackhole = 3; @@ -466,8 +465,7 @@ DEFUN (ip_route_mask, "Set tag for this route\n" "Tag value\n" "Distance value for this route\n" - VRF_CMD_HELP_STR - MPLS_LABEL_HELPSTR) + VRF_CMD_HELP_STR) { int idx_ipv4 = 2; int idx_ipv4_2 = 3; @@ -497,8 +495,7 @@ DEFUN (ip_route_mask_flags, "Set tag for this route\n" "Tag value\n" "Distance value for this route\n" - VRF_CMD_HELP_STR - MPLS_LABEL_HELPSTR) + VRF_CMD_HELP_STR) { int idx_ipv4 = 2; int idx_ipv4_2 = 3; @@ -530,8 +527,7 @@ DEFUN (no_ip_route, "Tag of this route\n" "Tag value\n" "Distance value for this route\n" - VRF_CMD_HELP_STR - MPLS_LABEL_HELPSTR) + VRF_CMD_HELP_STR) { int idx_ipv4_prefixlen = 3; int idx_ipv4_ifname_null = 4; @@ -561,8 +557,7 @@ DEFUN (no_ip_route_flags, "Tag of this route\n" "Tag value\n" "Distance value for this route\n" - VRF_CMD_HELP_STR - MPLS_LABEL_HELPSTR) + VRF_CMD_HELP_STR) { int idx_ipv4_prefixlen = 3; int idx_curr = 5; @@ -591,8 +586,7 @@ DEFUN (no_ip_route_mask, "Tag of this route\n" "Tag value\n" "Distance value for this route\n" - VRF_CMD_HELP_STR - MPLS_LABEL_HELPSTR) + VRF_CMD_HELP_STR) { int idx_ipv4 = 3; int idx_ipv4_2 = 4; @@ -624,8 +618,7 @@ DEFUN (no_ip_route_mask_flags, "Tag of this route\n" "Tag value\n" "Distance value for this route\n" - VRF_CMD_HELP_STR - MPLS_LABEL_HELPSTR) + VRF_CMD_HELP_STR) { int idx_ipv4 = 3; int idx_ipv4_2 = 4; @@ -1360,7 +1353,6 @@ DEFUN (no_ipv6_nht_default_route, return CMD_SUCCESS; } -// dwalton one "show ip route" to rule them all DEFUN (show_ip_route, show_ip_route_cmd, "show ip <fib|route> [vrf NAME] [tag (1-4294967295)|A.B.C.D/M longer-prefixes|supernets-only|" FRR_IP_REDIST_STR_ZEBRA "|ospf (1-65535)] [json]", @@ -2171,8 +2163,7 @@ DEFUN (ipv6_route, "Set tag for this route\n" "Tag value\n" "Distance value for this prefix\n" - VRF_CMD_HELP_STR - MPLS_LABEL_HELPSTR) + VRF_CMD_HELP_STR) { int idx_ipv6_prefixlen = 2; int idx_ipv6_ifname; @@ -2218,8 +2209,7 @@ DEFUN (ipv6_route_flags, "Set tag for this route\n" "Tag value\n" "Distance value for this prefix\n" - VRF_CMD_HELP_STR - MPLS_LABEL_HELPSTR) + VRF_CMD_HELP_STR) { int idx_ipv6_prefixlen = 2; int idx_ipv6_ifname; @@ -2267,8 +2257,7 @@ DEFUN (ipv6_route_ifname, "Set tag for this route\n" "Tag value\n" "Distance value for this prefix\n" - VRF_CMD_HELP_STR - MPLS_LABEL_HELPSTR) + VRF_CMD_HELP_STR) { int idx_ipv6_prefixlen = 2; int idx_ipv6 = 3; @@ -2318,8 +2307,7 @@ DEFUN (ipv6_route_ifname_flags, "Set tag for this route\n" "Tag value\n" "Distance value for this prefix\n" - VRF_CMD_HELP_STR - MPLS_LABEL_HELPSTR) + VRF_CMD_HELP_STR) { int idx_ipv6_prefixlen = 2; int idx_ipv6; @@ -2372,8 +2360,7 @@ DEFUN (no_ipv6_route, "Set tag for this route\n" "Tag value\n" "Distance value for this prefix\n" - VRF_CMD_HELP_STR - MPLS_LABEL_HELPSTR) + VRF_CMD_HELP_STR) { int idx_ipv6_prefixlen = 3; int idx_ipv6_ifname; @@ -2420,8 +2407,7 @@ DEFUN (no_ipv6_route_flags, "Set tag for this route\n" "Tag value\n" "Distance value for this prefix\n" - VRF_CMD_HELP_STR - MPLS_LABEL_HELPSTR) + VRF_CMD_HELP_STR) { int idx_ipv6_prefixlen = 3; int idx_ipv6_ifname; @@ -2470,8 +2456,7 @@ DEFUN (no_ipv6_route_ifname, "Set tag for this route\n" "Tag value\n" "Distance value for this prefix\n" - VRF_CMD_HELP_STR - MPLS_LABEL_HELPSTR) + VRF_CMD_HELP_STR) { int idx_ipv6_prefixlen = 3; int idx_ipv6; @@ -2522,8 +2507,7 @@ DEFUN (no_ipv6_route_ifname_flags, "Set tag for this route\n" "Tag value\n" "Distance value for this prefix\n" - VRF_CMD_HELP_STR - MPLS_LABEL_HELPSTR) + VRF_CMD_HELP_STR) { int idx_ipv6_prefixlen = 3; int idx_ipv6; @@ -2561,7 +2545,6 @@ DEFUN (no_ipv6_route_ifname_flags, tag, distance, vrf, NULL); } -// dwalton duplicate to here DEFUN (show_ipv6_route, show_ipv6_route_cmd, "show ipv6 <fib|route> [vrf NAME] [tag (1-4294967295)|X:X::X:X/M longer-prefixes|" FRR_IP6_REDIST_STR_ZEBRA "] [json]", diff --git a/zebra/zserv.c b/zebra/zserv.c index 72f7382882..3da94459f7 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); } |
