diff --git a/bgpd/bgp_attr.c b/bgpd/bgp_attr.c index f3848db072df..55e03669d124 100644 --- a/bgpd/bgp_attr.c +++ b/bgpd/bgp_attr.c @@ -55,6 +55,8 @@ #include "bgp_evpn.h" #include "bgp_flowspec_private.h" #include "bgp_mac.h" +#include "bgpd/bgp_lsdb.h" +#include "bgpd/bgp_ls.h" /* Attribute strings for logging. */ static const struct message attr_str[] = { @@ -80,6 +82,7 @@ static const struct message attr_str[] = { #ifdef ENABLE_BGP_VNC_ATTR {BGP_ATTR_VNC, "VNC"}, #endif + {BGP_ATTR_LINK_STATE, "LINK_STATE"}, {BGP_ATTR_LARGE_COMMUNITIES, "LARGE_COMMUNITY"}, {BGP_ATTR_PREFIX_SID, "PREFIX_SID"}, {BGP_ATTR_IPV6_EXT_COMMUNITIES, "IPV6_EXT_COMMUNITIES"}, @@ -95,6 +98,8 @@ static const struct message attr_flag_str[] = { {BGP_ATTR_FLAG_EXTLEN, "Extended Length"}, {0}}; +// static const size_t attr_flag_str_max = array_size(attr_flag_str); + static struct hash *cluster_hash; static void *cluster_hash_alloc(void *p) @@ -1413,6 +1418,7 @@ bgp_attr_malformed(struct bgp_attr_parser_args *args, uint8_t subcode, return BGP_ATTR_PARSE_WITHDRAW; case BGP_ATTR_MP_REACH_NLRI: case BGP_ATTR_MP_UNREACH_NLRI: + case BGP_ATTR_LINK_STATE: bgp_notify_send_with_data(peer, BGP_NOTIFY_UPDATE_ERR, subcode, notify_datap, length); return BGP_ATTR_PARSE_ERROR; @@ -1496,6 +1502,7 @@ const uint8_t attr_flags_values[] = { [BGP_ATTR_IPV6_EXT_COMMUNITIES] = BGP_ATTR_FLAG_OPTIONAL | BGP_ATTR_FLAG_TRANS, [BGP_ATTR_AIGP] = BGP_ATTR_FLAG_OPTIONAL | BGP_ATTR_FLAG_TRANS, + [BGP_ATTR_LINK_STATE] = BGP_ATTR_FLAG_OPTIONAL, }; static const size_t attr_flags_values_max = array_size(attr_flags_values) - 1; @@ -2157,6 +2164,72 @@ bgp_attr_cluster_list(struct bgp_attr_parser_args *args) return BGP_ATTR_PARSE_PROCEED; } +/* Parsing of MP_[UN]REACH_NLRI Link-State Attribute */ +static int bgp_mp_reach_nlri_ls_parse(struct bgp_attr_parser_args *args, + struct stream *s, bgp_size_t nlri_len) +{ + struct peer *const peer = args->peer; + struct attr *const attr = args->attr; + const bgp_size_t length = nlri_len; + size_t endp; + size_t nlri_endp; + /* Link State type & length */ + uint16_t nlri_type; + uint16_t nlri_length; + + endp = stream_get_getp(s) + length; + + attr->mp_bgpls_nlri = XCALLOC(MTYPE_BGP_LSDB, sizeof(struct mp_bgpls_nlri)); + + /* Get link state attributes to the end of attribute length. */ + while (stream_get_getp(s) < endp) { + /* ----------------- Type of link-state------------- */ + nlri_type = stream_getw(s); + + /*---------Length of : Type of link-state---------- */ + nlri_length = stream_getw(s); + + /* size of whole attribute */ + nlri_endp = stream_get_getp(s) + nlri_length; + + while (stream_get_getp(s) < nlri_endp) { + /* Type of Attribute : Link, Node , IPv4 & IPv6 Prefix + */ + switch (nlri_type) { + case LINK_STATE_NODE_NLRI: + /* For mp_reach_nlri.c & bgp_ls_bpls_nlri.c */ + bgp_mp_node_decode(args, s); + break; + + case LINK_STATE_LINK_NLRI: + /* For mp_reach_nlri.c & bgp_ls_bpls_nlri.c */ + bgp_mp_link_decode(args, s); + break; + + case LINK_STATE_IPV4_TOPOLOGY_PREFIX_NLRI: + /* For mp_reach_nlri.c & bgp_ls_bpls_nlri.c */ + bgp_mp_prefix_decode(args, s); + break; + + case LINK_STATE_IPV6_TOPOLOGY_PREFIX_NLRI: + /* For mp_reach_nlri.c & bgp_ls_bpls_nlri.c */ + bgp_mp_prefix_decode(args, s); + break; + + default: + zlog_info( + "%s: (%s) Wrong MP_NREACH_NLRI type : %d", + __func__, peer->host, nlri_type); + return BGP_ATTR_PARSE_ERROR_NOTIFYPLS; + break; + } + } + return BGP_ATTR_PARSE_PROCEED; + } + return BGP_ATTR_PARSE_PROCEED; +} + + /* Multiprotocol reachability information parse. */ int bgp_mp_reach_parse(struct bgp_attr_parser_args *args, struct bgp_nlri *mp_update) @@ -2206,13 +2279,19 @@ int bgp_mp_reach_parse(struct bgp_attr_parser_args *args, /* Get nexthop length. */ attr->mp_nexthop_len = stream_getc(s); - if (LEN_LEFT < attr->mp_nexthop_len) { + nlri_len = LEN_LEFT; + if (nlri_len < attr->mp_nexthop_len) { zlog_info( "%s: %s sent next-hop length, %u, in MP_REACH_NLRI which goes past the end of attribute", __func__, peer->host, attr->mp_nexthop_len); return BGP_ATTR_PARSE_ERROR_NOTIFYPLS; } + if (afi == AFI_LINK_STATE && safi == SAFI_LINK_STATE) { + bgp_mp_reach_nlri_ls_parse(args, s, nlri_len); + goto skip_length_check; + } + /* Nexthop length check. */ switch (attr->mp_nexthop_len) { case 0: @@ -2300,6 +2379,7 @@ int bgp_mp_reach_parse(struct bgp_attr_parser_args *args, return BGP_ATTR_PARSE_ERROR_NOTIFYPLS; } +skip_length_check: if (!LEN_LEFT) { zlog_info("%s: %s sent SNPA which couldn't be read", __func__, peer->host); @@ -2354,6 +2434,7 @@ int bgp_mp_unreach_parse(struct bgp_attr_parser_args *args, afi_t afi; iana_safi_t pkt_safi; safi_t safi; + // size_t start; uint16_t withdraw_len; struct peer *const peer = args->peer; struct attr *const attr = args->attr; @@ -2361,7 +2442,10 @@ int bgp_mp_unreach_parse(struct bgp_attr_parser_args *args, s = peer->curr; + // start = stream_get_getp(s); + #define BGP_MP_UNREACH_MIN_SIZE 3 + // #define LEN_LEFT (length - (stream_get_getp(s) - start)) if ((length > STREAM_READABLE(s)) || (length < BGP_MP_UNREACH_MIN_SIZE)) return BGP_ATTR_PARSE_ERROR_NOTIFYPLS; @@ -2389,6 +2473,15 @@ int bgp_mp_unreach_parse(struct bgp_attr_parser_args *args, mp_withdraw->nlri = stream_pnt(s); mp_withdraw->length = withdraw_len; + /* must have nrli_len, what is left of the attribute */ + // nlri_len = LEN_LEFT; + /* For AFI SAFI link State: we use the fonction mp_reach_nlri_parse */ + // if ((afi ==AFI_LINK_STATE && safi==SAFI_LINK_STATE)||(afi + // ==AFI_LINK_STATE && safi==SAFI_LINK_STATE_VPN)) + // { + // mp_reach_nlri_parse(args,s,nlri_len); + // } + stream_forward_getp(s, withdraw_len); attr->flag |= ATTR_FLAG_BIT(BGP_ATTR_MP_UNREACH_NLRI); @@ -3243,6 +3336,65 @@ static enum bgp_attr_parse_ret bgp_attr_otc(struct bgp_attr_parser_args *args) return BGP_ATTR_PARSE_PROCEED; } +/*----BGP Link State 99 information----*/ +static enum bgp_attr_parse_ret +bgp_attr_link_state(struct bgp_attr_parser_args *args) +{ + + struct stream *s; + struct peer *const peer = args->peer; + struct attr *const attr = args->attr; + const bgp_size_t length = args->length; + struct bgp *bgp; + struct bgp_lsdb *bgp_lsdb; + struct bgp_ls *bgp_ls; + // bgp_size_t nlri_len; + // size_t endp; + // size_t start; + + /* Set end of packet. */ + s = BGP_INPUT(peer); + + // start = stream_get_getp(s); + + //#define LEN_LEFT (length - (stream_get_getp(s) - start)) + + if (length > STREAM_READABLE(s)) { + zlog_info("%s sent invalid length, %lu", peer->host, + (unsigned long)length); + return BGP_ATTR_PARSE_ERROR_NOTIFYPLS; + } + + if (length < BGP_ATTR_MIN_LEN) { + /* XXX warning: long int format, int arg (arg 5) */ + /*zlog (peer->log, LOG_WARNING, + "%s: error BGP attribute length %lu is smaller than min + len", peer->host, (unsigned long) ( BGP_INPUT_PNT (peer)));*/ /*modification*/ + + bgp_notify_send(peer, BGP_NOTIFY_UPDATE_ERR, + BGP_NOTIFY_UPDATE_ATTR_LENG_ERR); + return BGP_ATTR_PARSE_ERROR; + } + + /* must have nrli_len, what is left of the attribute */ + // nlri_len = LEN_LEFT; + // stream_forward_getp (s, nlri_len); + bgp_link_state_decode(args, s); + + /* BGP Link-State - save attributes in LSDB */ + bgp = bgp_get_default(); + bgp_lsdb = bgp->lsdb; + // if (bgp_lsdb) + // bgp_lsdb_free(bgp_lsdb); + bgp_lsdb = bgp_lsdb_new(); + + bgp_ls = ls_attr_set(attr); + if (bgp_ls) + bgp_lsdb_add(bgp_lsdb, bgp_ls); + + return BGP_ATTR_PARSE_PROCEED; +} + /* BGP unknown attribute treatment. */ static enum bgp_attr_parse_ret bgp_attr_unknown(struct bgp_attr_parser_args *args) @@ -3597,6 +3749,9 @@ enum bgp_attr_parse_ret bgp_attr_parse(struct peer *peer, struct attr *attr, case BGP_ATTR_AIGP: ret = bgp_attr_aigp(&attr_args); break; + case BGP_ATTR_LINK_STATE: + ret = bgp_attr_link_state(&attr_args); + break; default: ret = bgp_attr_unknown(&attr_args); break; @@ -3877,6 +4032,10 @@ size_t bgp_packet_mpattr_start(struct stream *s, struct peer *peer, afi_t afi, stream_put_ipv4(s, attr->nexthop.s_addr); } break; + case SAFI_LINK_STATE: + case SAFI_LINK_STATE_VPN: + /* TODO */ + break; case SAFI_UNSPEC: case SAFI_MAX: assert(!"SAFI's UNSPEC or MAX being specified are a DEV ESCAPE"); @@ -3931,6 +4090,10 @@ size_t bgp_packet_mpattr_start(struct stream *s, struct peer *peer, afi_t afi, case SAFI_FLOWSPEC: stream_putc(s, 0); /* no nexthop for flowspec */ break; + case SAFI_LINK_STATE: + case SAFI_LINK_STATE_VPN: + /* TODO */ + break; case SAFI_UNSPEC: case SAFI_MAX: assert(!"SAFI's UNSPEC or MAX being specified are a DEV ESCAPE"); @@ -3948,6 +4111,20 @@ size_t bgp_packet_mpattr_start(struct stream *s, struct peer *peer, afi_t afi, case AFI_MAX: assert(!"DEV ESCAPE: AFI_UNSPEC or AFI_MAX should not be used here"); break; + case AFI_LINK_STATE: + switch (safi) { + case SAFI_LINK_STATE: + // struct attr_extra *attre = attr->mp_nexthop_len; + // assert (attr->mp_nexthop_len); + // stream_putc(s, + // attr->mp_nexthop_len); if + // (attr->mp_nexthop_len == 4) stream_put_ipv4(s, + // attr->nexthop.s_addr); + break; + default: + break; + } + break; } /* SNPA */ @@ -3994,7 +4171,72 @@ void bgp_packet_mpattr_prefix(struct stream *s, afi_t afi, safi_t safi, stream_put(s, (const void *)p->u.prefix_flowspec.ptr, p->u.prefix_flowspec.prefixlen); break; - + case SAFI_LINK_STATE: + case SAFI_LINK_STATE_VPN: + stream_put(s, &attr->mp_bgpls_nlri->header.nlri_type, 2); + stream_put(s, &attr->mp_bgpls_nlri->header.nlri_length, 2); + if (SAFI_LINK_STATE_VPN) + stream_put(s, prd->val, 4); + stream_put(s, &attr->mp_bgpls_nlri->ext_hdr.proto_id, 1); + stream_put(s, &attr->mp_bgpls_nlri->ext_hdr.nlri_identifier, 8); + stream_put(s, &attr->mp_bgpls_nlri->tlvcp.header.nlri_type, 2); + stream_put(s, &attr->mp_bgpls_nlri->tlvcp.header.nlri_length, + 2); + switch (attr->mp_bgpls_nlri->tlvcp.header.nlri_type) { + case BGP_NLRI_TLV_LOCAL_NODE_DESCRIPTORS: + stream_put(s, &attr->mp_bgpls_nlri->local_node->value, + attr->mp_bgpls_nlri->local_node->header + .nlri_length); + break; + case BGP_NLRI_TLV_REMOTE_NODE_DESCRIPTORS: + stream_put(s, &attr->mp_bgpls_nlri->remote_node->value, + attr->mp_bgpls_nlri->local_node->header + .nlri_length); + break; + case BGP_NLRI_TLV_LINK_LOCAL_REMOTE_IDENTIFIERS: + stream_put(s, &attr->mp_bgpls_nlri->llri.local, 4); + stream_put(s, &attr->mp_bgpls_nlri->llri.remote, 4); + break; + case BGP_NLRI_TLV_IPV4_INTERFACE_ADDRESS: + stream_put(s, &attr->mp_bgpls_nlri->i4ia.value, + BGP_NLRI_TLV_LEN_IPV4_INTERFACE_ADDRESS); + break; + case BGP_NLRI_TLV_IPV4_NEIGHBOR_ADDRESS: + stream_put(s, &attr->mp_bgpls_nlri->i4na.value, + BGP_NLRI_TLV_LEN_IPV4_NEIGHBOR_ADDRESS); + break; + case BGP_NLRI_TLV_IPV6_INTERFACE_ADDRESS: +#ifdef HAVE_IPV6 + stream_put(s, &attr->mp_bgpls_nlri->i6ia.value, + BGP_NLRI_TLV_LEN_IPV6_INTERFACE_ADDRESS); +#endif /* HAVE_IPV6 */ + break; + case BGP_NLRI_TLV_IPV6_NEIGHBOR_ADDRESS: +#ifdef HAVE_IPV6 + stream_put(s, &attr->mp_bgpls_nlri->i6na.value, + BGP_NLRI_TLV_LEN_IPV6_NEIGHBOR_ADDRESS); +#endif /* HAVE_IPV6 */ + break; + case BGP_NLRI_TLV_MULTI_TOPOLOGY_ID: + stream_put( + s, &attr->mp_bgpls_nlri->mid->value, + attr->mp_bgpls_nlri->mid->header.nlri_length); + break; + case BGP_NLRI_TLV_OSPF_ROUTE_TYPE: + stream_put(s, &attr->mp_bgpls_nlri->ort.value, + BGP_NLRI_TLV_LEN_OSPF_TYPE_ROUTE); + break; + case BGP_NLRI_TLV_IP_REACHABILITY_INFORMATION: + stream_put(s, &attr->mp_bgpls_nlri->ipreach->prefix, 1); + stream_put(s, &attr->mp_bgpls_nlri->ipreach->value, + (attr->mp_bgpls_nlri->ipreach->header + .nlri_length - + 1)); + break; + default: + break; + } + break; case SAFI_UNICAST: case SAFI_MULTICAST: stream_put_prefix_addpath(s, p, addpath_capable, addpath_tx_id); @@ -4040,6 +4282,10 @@ size_t bgp_packet_mpattr_prefix_size(afi_t afi, safi_t safi, case SAFI_FLOWSPEC: size = ((struct prefix_fs *)p)->prefix.prefixlen; break; + case SAFI_LINK_STATE: + case SAFI_LINK_STATE_VPN: + /* TODO */ + break; } return size; @@ -4177,6 +4423,7 @@ bgp_size_t bgp_packet_attribute(struct bgp *bgp, struct peer *peer, { size_t cp; size_t aspath_sizep; + size_t linkstate_sizep; struct aspath *aspath; int send_as4_path = 0; int send_as4_aggregator = 0; @@ -4654,6 +4901,15 @@ bgp_size_t bgp_packet_attribute(struct bgp *bgp, struct peer *peer, /* Tunnel Encap attribute */ bgp_packet_mpattr_tea(bgp, peer, s, attr, BGP_ATTR_ENCAP); + if (attr && attr->link_state_attr) { + stream_putc(s, BGP_ATTR_FLAG_OPTIONAL | + BGP_ATTR_FLAG_TRANS); + stream_putc(s, BGP_ATTR_LINK_STATE); + linkstate_sizep = stream_get_endp(s); + stream_putc(s, linkstate_sizep); + bgp_put_link_state(s, attr); + } + #ifdef ENABLE_BGP_VNC_ATTR /* VNC attribute */ bgp_packet_mpattr_tea(bgp, peer, s, attr, BGP_ATTR_VNC); @@ -4752,6 +5008,133 @@ void bgp_packet_mpunreach_end(struct stream *s, size_t attrlen_pnt) bgp_packet_mpattr_end(s, attrlen_pnt); } +/*BGP link state information */ +/*Link state_nlri*/ +void bgp_put_link_state(struct stream *s, struct attr *attr) +{ + int i = 1; + int n; + // struct attr_extra *attre = attr->mp_nexthop_len; + + stream_put(s, &attr->link_state_attr->header.nlri_type, 2); + stream_put(s, &attr->link_state_attr->header.nlri_length, 2); + stream_put(s, &attr->link_state_attr->header.nlri_type, 2); + stream_put(s, &attr->link_state_attr->header.nlri_length, 2); + switch (attr->link_state_attr->header.nlri_type) { + /******************************************************/ + case BGP_NLRI_TLV_NODE_FLAG_BITS: + stream_put(s, &attr->link_state_attr->nfb.value, + BGP_NLRI_TLV_LEN_NODE_FLAG_BITS); + break; + case BGP_NLRI_TLV_OPAQUE_NODE_PROPERTIES: + stream_put(s, &attr->link_state_attr->onp->value, + attr->link_state_attr->onp->header.nlri_length); + break; + case BGP_NLRI_TLV_NODE_NAME: + stream_put(s, &attr->link_state_attr->nn->value, + attr->link_state_attr->nn->header.nlri_length); + break; + case BGP_NLRI_TLV_IS_IS_AREA_IDENTIFIER: + stream_put(s, &attr->link_state_attr->iiai->value, + attr->link_state_attr->iiai->header.nlri_length); + break; + case BGP_NLRI_TLV_IPV4_ROUTER_ID_OF_LOCAL_NODE: + stream_put(s, &attr->link_state_attr->i4ridofln.value, + BGP_NLRI_TLV_LEN_IPV4_ROUTER_ID_OF_LOCAL_NODE); + break; + case BGP_NLRI_TLV_IPV6_ROUTER_ID_OF_LOCAL_NODE: +#ifdef HAVE_IPV6 +// stream_put (s, +//&attr->link_state_attr->i6ridofln.value,BGP_NLRI_TLV_LEN_IPV6_ROUTER_ID_OF_LOCAL_NODE); +#endif /*HAVE_IPV6*/ + break; + case BGP_NLRI_TLV_IPV4_ROUTER_ID_OF_REMOTE_NODE: + // stream_put (s, + //&attr->link_state_attr->i4ridofrn.value,BGP_NLRI_TLV_LEN_IPV4_ROUTER_ID_OF_REMOTE_NODE); + break; + case BGP_NLRI_TLV_IPV6_ROUTER_ID_OF_REMOTE_NODE: +#ifdef HAVE_IPV6 + stream_put(s, &attr->link_state_attr->i6ridofrn.value, + BGP_NLRI_TLV_LEN_IPV6_ROUTER_ID_OF_REMOTE_NODE); +#endif /*HAVE_IPV6*/ + break; + case BGP_NLRI_TLV_ADMINISTRATIVE_GROUP_COLOR: + stream_put(s, &attr->link_state_attr->agc.value, + BGP_NLRI_TLV_LEN_ADMINISTRATIVE_GROUP_COLOR); + break; + case BGP_NLRI_TLV_MAX_LINK_BANDWIDTH: + stream_put(s, &attr->link_state_attr->mlb.value, + BGP_NLRI_TLV_LEN_MAX_LINK_BANDWIDTH); + break; + case BGP_NLRI_TLV_MAX_RESERVABLE_LINK_BANDWIDTH: + stream_put(s, &attr->link_state_attr->mrlb.value, + BGP_NLRI_TLV_LEN_MAX_RESERVABLE_LINK_BANDWIDTH); + break; + case BGP_NLRI_TLV_UNRESERVED_BANDWIDTH: + + n = (attr->link_state_attr->urb.header.nlri_length) / 8; + for (i = 1; i <= n; i++) { + stream_put(s, &attr->link_state_attr->urb.value[i], 1); + } + break; + case BGP_NLRI_TLV_TE_DEFAULT_METRIC: + stream_put(s, &attr->link_state_attr->tdm.value, + BGP_NLRI_TLV_LEN_TE_DEFAULT_METRIC); + break; + case BGP_NLRI_TLV_LINK_PROTECTION_TYPE: + stream_put(s, &attr->link_state_attr->lpt.value, + BGP_NLRI_TLV_LEN_LINK_PROTECTION_TYPE); + break; + case BGP_NLRI_TLV_MPLS_PROTOCOL_MASK: + stream_put(s, &attr->link_state_attr->mpm.value, + BGP_NLRI_TLV_LEN_MPLS_PROTOCOL_MASK); + break; + case BGP_NLRI_TLV_IGP_METRIC: + stream_put(s, &attr->link_state_attr->igpm->value, + BGP_NLRI_TLV_LEN_METRIC); + break; + case BGP_NLRI_TLV_SHARED_RISK_LINK_GROUP: + stream_put(s, &attr->link_state_attr->srlg->value, + attr->link_state_attr->srlg->header.nlri_length); + break; + case BGP_NLRI_TLV_OPAQUE_LINK_ATTRIBUTE: + stream_put(s, &attr->link_state_attr->ola->value, + attr->link_state_attr->ola->header.nlri_length); + break; + case BGP_NLRI_TLV_LINK_NAME_ATTRIBUTE: + stream_put(s, &attr->link_state_attr->lna->value, + attr->link_state_attr->lna->header.nlri_length); + break; + case BGP_NLRI_TLV_IGP_FLAGS: + stream_put(s, &attr->link_state_attr->ifl.value, + BGP_NLRI_TLV_LEN_IGP_FLAGS); + break; + case BGP_NLRI_TLV_ROUTE_TAG: + stream_put(s, &attr->link_state_attr->rt->value, + attr->link_state_attr->rt->header.nlri_length); + break; + case BGP_NLRI_TLV_EXTENDED_TAG: + stream_put(s, &attr->link_state_attr->et->value, + attr->link_state_attr->et->header.nlri_length); + break; + case BGP_NLRI_TLV_PREFIX_METRIC: + stream_put(s, &attr->link_state_attr->pm.value, + BGP_NLRI_TLV_LEN_PREFIX_METRIC); + break; + case BGP_NLRI_TLV_OSPF_FORWARDING_ADDRESS: + stream_put(s, &attr->link_state_attr->ofa.value, + attr->link_state_attr->ofa.header.nlri_length); + break; + case BGP_NLRI_TLV_OPAQUE_PREFIX_ATTRIBUTE: + stream_put(s, &attr->link_state_attr->opa->value, + attr->link_state_attr->opa->header.nlri_length); + break; + default: + break; + } +} + + /* Initialization of attribute. */ void bgp_attr_init(void) { diff --git a/bgpd/bgp_attr.h b/bgpd/bgp_attr.h index a34da1a6de72..c8fca5c2494b 100644 --- a/bgpd/bgp_attr.h +++ b/bgpd/bgp_attr.h @@ -151,6 +151,7 @@ struct bgp_attr_srv6_l3vpn { uint8_t transposition_offset; }; + /* BGP core attribute structure. */ struct attr { /* AS Path structure */ @@ -174,6 +175,10 @@ struct attr { /* Path origin attribute */ uint8_t origin; + /* BGP Link-State attributes*/ + struct mp_bgpls_nlri *mp_bgpls_nlri; /* BGP LS extension NLRI */ + struct ls_bgpls *link_state_attr; /* BGP Link State attribute */ + /* PMSI tunnel type (RFC 6514). */ enum pta_type pmsi_tnl_type; @@ -390,6 +395,7 @@ extern void bgp_attr_finish(void); extern enum bgp_attr_parse_ret bgp_attr_parse(struct peer *peer, struct attr *attr, bgp_size_t size, struct bgp_nlri *mp_update, struct bgp_nlri *mp_withdraw); +extern void bgp_attr_undup(struct attr *new, struct attr *old); extern struct attr *bgp_attr_intern(struct attr *attr); extern void bgp_attr_unintern_sub(struct attr *attr); extern void bgp_attr_unintern(struct attr **pattr); @@ -436,6 +442,11 @@ extern int bgp_mp_unreach_parse(struct bgp_attr_parser_args *args, extern enum bgp_attr_parse_ret bgp_attr_prefix_sid(struct bgp_attr_parser_args *args); +/* BGP-LS */ +extern void bgp_put_link_state(struct stream *s, struct attr *attr); +extern int link_state_value(struct stream *s, struct peer *peer, + uint16_t l_type, uint16_t l_length); + extern struct bgp_attr_encap_subtlv * encap_tlv_dup(struct bgp_attr_encap_subtlv *orig); diff --git a/bgpd/bgp_bgpls_nlri.c b/bgpd/bgp_bgpls_nlri.c new file mode 100644 index 000000000000..9f374b6b0495 --- /dev/null +++ b/bgpd/bgp_bgpls_nlri.c @@ -0,0 +1,1285 @@ +/* + * This is an implementation of BGP Link State as per RFC 7752 + * + * Copyright (C) 2020 Orange http://www.orange.com + * + * This program 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 of the License, or (at your option) + * any later version. + * + * This program 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 this program; see the file COPYING; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include + +#include "command.h" +#include "linklist.h" +#include "prefix.h" +#include "memory.h" +#include "vector.h" +#include "vty.h" +#include "stream.h" +#include "log.h" +#include "hash.h" +#include "jhash.h" +#include "sockunion.h" /* for inet_aton() */ +#include "table.h" +#include "if.h" +#include "thread.h" +#include "checksum.h" +#include "md5.h" +#include "network.h" + +#include "bgpd/bgp_attr.h" +#include "bgpd/bgp_ls.h" +#include "bgpd/bgpd.h" +#include "bgpd/bgp_route.h" +#include "bgpd/bgp_aspath.h" +#include "bgpd/bgp_community.h" +#include "bgpd/bgp_debug.h" +#include "bgpd/bgp_packet.h" +#include "bgpd/bgp_ecommunity.h" + +/***************************************************************************************** + +--------------------+-------------------+----------+ + | Sub-TLV Code Point | Description | Length | + +--------------------+-------------------+----------+ + | 512 | Autonomous System | 4 | + | 513 | BGP-LS Identifier | 4 | + | 514 | OSPF Area-ID | 4 | + | 515 | IGP Router-ID | Variable | + +--------------------+-------------------+----------+ +******************************************************************************************/ + + +int bgp_mp_node_decode(struct bgp_attr_parser_args *args, struct stream *s) +{ + struct peer *const peer = args->peer; + struct attr *const attr = args->attr; + uint16_t type, node_type; + uint16_t length, node_length; + size_t nlri_node_endp; + + attr->mp_bgpls_nlri->ext_hdr.proto_id = stream_getc(s); + attr->mp_bgpls_nlri->ext_hdr.nlri_identifier = stream_getq(s); + type = stream_getw(s); /* Type */ + length = stream_getw(s); /* Length */ + + if (type != BGP_NLRI_TLV_LOCAL_NODE_DESCRIPTORS) { + zlog_info("%s sent invalid Node Descriptor, %lu", peer->host, + (unsigned long)length); + } + + nlri_node_endp = stream_get_getp(s) + length; + // int n, i; /*new version*/ + while (stream_get_getp(s) < nlri_node_endp) { + node_type = stream_getw(s); + node_length = stream_getw(s); + + switch (node_type) { + + case BGP_NLRI_TLV_AUTONOMOUS_SYSTEM: + + stream_get(attr->mp_bgpls_nlri->local_node->value, s, + BGP_NLRI_TLV_LEN_AUTONOMOUS_SYSTEM); + + break; + + case BGP_NLRI_TLV_BGP_LS_IDENTIFIER: + + stream_get(attr->mp_bgpls_nlri->local_node->value, s, + BGP_NLRI_TLV_LEN_BGP_LS_IDENTIFIER); + + break; + + case BGP_NLRI_TLV_AREA_ID: + + stream_get(attr->mp_bgpls_nlri->local_node->value, s, + BGP_NLRI_TLV_LEN_AREA_ID); + + break; + + case BGP_NLRI_TLV_IGP_ROUTER_ID: + + switch (node_length) { + case BGP_NLRI_IS_IS_NON_PSEUDONODE: + stream_get( + &attr->mp_bgpls_nlri->local_node->value, + s, BGP_NLRI_IS_IS_NON_PSEUDONODE); + break; + + case BGP_NLRI_IS_IS_PSEUDONODE: + stream_get( + &attr->mp_bgpls_nlri->local_node->value, + s, BGP_NLRI_IS_IS_PSEUDONODE); + break; + + case BGP_NLRI_OSPF_NON_PSEUDONODE: + stream_get( + &attr->mp_bgpls_nlri->local_node->value, + s, BGP_NLRI_OSPF_NON_PSEUDONODE); + break; + + case BGP_NLRI_OSPF_PSEUDONODE: + stream_get( + &attr->mp_bgpls_nlri->local_node->value, + s, BGP_NLRI_OSPF_PSEUDONODE); + break; + + default: + zlog_info("%s sent invalid IGP Router-ID, %lu", + peer->host, (unsigned long)length); + break; + } + + break; + + default: + zlog_info("%s sent invalid Node Descriptor, %lu", + peer->host, (unsigned long)length); + break; + } + + break; + } + return BGP_ATTR_PARSE_PROCEED; +} + +/******************************************************************************** + + +-----------+---------------------+---------------+-----------------+ + | TLV Code | Description | IS-IS TLV | Value defined | + | Point | | /Sub-TLV | in: | + +-----------+---------------------+---------------+-----------------+ + | 258 | Link Local/Remote | 22/4 | [RFC5307]/1.1 | + | | Identifiers | | | + | 259 | IPv4 interface | 22/6 | [RFC5305]/3.2 | + | | address | | | + | 260 | IPv4 neighbor | 22/8 | [RFC5305]/3.3 | + | | address | | | + | 261 | IPv6 interface | 22/12 | [RFC6119]/4.2 | + | | address | | | + | 262 | IPv6 neighbor | 22/13 | [RFC6119]/4.3 | + | | address | | | + | 263 | Multi-Topology | --- | Section 3.2.1.5 | + | | Identifier | | | + +-----------+---------------------+---------------+-----------------+ +*********************************************************************************/ +int bgp_mp_link_decode(struct bgp_attr_parser_args *args, struct stream *s) +{ + struct peer *const peer = args->peer; + struct attr *const attr = args->attr; + uint16_t type, node_type; + uint16_t length, node_length; + size_t nlri_node_endp; + + attr->mp_bgpls_nlri->ext_hdr.proto_id = stream_getc(s); + attr->mp_bgpls_nlri->ext_hdr.nlri_identifier = stream_getq(s); + type = stream_getw(s); + length = stream_getw(s); + + nlri_node_endp = stream_get_getp(s) + length; + int n, i; + + switch (type) { + case BGP_NLRI_TLV_LOCAL_NODE_DESCRIPTORS: + + while (stream_get_getp(s) < nlri_node_endp) { + node_type = stream_getw(s); + node_length = stream_getw(s); + + switch (node_type) { + + case BGP_NLRI_TLV_AUTONOMOUS_SYSTEM: + + stream_get( + attr->mp_bgpls_nlri->local_node->value, + s, BGP_NLRI_TLV_LEN_AUTONOMOUS_SYSTEM); + + break; + + case BGP_NLRI_TLV_BGP_LS_IDENTIFIER: + + stream_get( + attr->mp_bgpls_nlri->local_node->value, + s, BGP_NLRI_TLV_LEN_BGP_LS_IDENTIFIER); + + break; + + case BGP_NLRI_TLV_AREA_ID: + + stream_get( + attr->mp_bgpls_nlri->local_node->value, + s, BGP_NLRI_TLV_LEN_AREA_ID); + + break; + + case BGP_NLRI_TLV_IGP_ROUTER_ID: + + switch (node_length) { + case BGP_NLRI_IS_IS_NON_PSEUDONODE: + + stream_get( + &attr->mp_bgpls_nlri->local_node + ->value, + s, + BGP_NLRI_IS_IS_NON_PSEUDONODE); + break; + + case BGP_NLRI_IS_IS_PSEUDONODE: + stream_get(&attr->mp_bgpls_nlri + ->local_node->value, + s, + BGP_NLRI_IS_IS_PSEUDONODE); + break; + + case BGP_NLRI_OSPF_NON_PSEUDONODE: + stream_get( + &attr->mp_bgpls_nlri->local_node + ->value, + s, + BGP_NLRI_OSPF_NON_PSEUDONODE); + break; + + case BGP_NLRI_OSPF_PSEUDONODE: + stream_get(&attr->mp_bgpls_nlri + ->local_node->value, + s, BGP_NLRI_OSPF_PSEUDONODE); + break; + + default: + zlog_info( + "%s sent invalid IGP Router-ID, %lu", + peer->host, + (unsigned long)length); + break; + } + + break; + + default: + zlog_info( + "%s sent invalid Node Descriptor, %lu", + peer->host, (unsigned long)length); + break; + } + } + break; + + case BGP_NLRI_TLV_REMOTE_NODE_DESCRIPTORS: + + while (stream_get_getp(s) < nlri_node_endp) { + node_type = stream_getw(s); + node_length = stream_getw(s); + + switch (node_type) { + + case BGP_NLRI_TLV_AUTONOMOUS_SYSTEM: + + stream_get( + attr->mp_bgpls_nlri->local_node->value, + s, BGP_NLRI_TLV_LEN_AUTONOMOUS_SYSTEM); + + break; + + case BGP_NLRI_TLV_BGP_LS_IDENTIFIER: + + stream_get( + attr->mp_bgpls_nlri->local_node->value, + s, BGP_NLRI_TLV_LEN_BGP_LS_IDENTIFIER); + + break; + + case BGP_NLRI_TLV_AREA_ID: + + stream_get( + attr->mp_bgpls_nlri->local_node->value, + s, BGP_NLRI_TLV_LEN_AREA_ID); + + break; + + case BGP_NLRI_TLV_IGP_ROUTER_ID: + + switch (node_length) { + case BGP_NLRI_IS_IS_NON_PSEUDONODE: + stream_get( + &attr->mp_bgpls_nlri + ->remote_node->value, + s, + BGP_NLRI_IS_IS_NON_PSEUDONODE); + break; + + case BGP_NLRI_IS_IS_PSEUDONODE: + stream_get( + &attr->mp_bgpls_nlri + ->remote_node->value, + s, BGP_NLRI_IS_IS_PSEUDONODE); + break; + + case BGP_NLRI_OSPF_NON_PSEUDONODE: + stream_get( + &attr->mp_bgpls_nlri + ->remote_node->value, + s, + BGP_NLRI_OSPF_NON_PSEUDONODE); + break; + + case BGP_NLRI_OSPF_PSEUDONODE: + stream_get( + &attr->mp_bgpls_nlri + ->remote_node->value, + s, BGP_NLRI_OSPF_PSEUDONODE); + break; + + default: + zlog_info( + "%s sent invalid IGP Router-ID, %lu", + peer->host, + (unsigned long)length); + break; + } + + break; + + default: + zlog_info( + "%s sent invalid Node Descriptor, %lu", + peer->host, (unsigned long)length); + break; + } + } + break; + + case BGP_NLRI_TLV_LINK_LOCAL_REMOTE_IDENTIFIERS: + + node_type = stream_getw(s); + node_length = stream_getw(s); + + attr->mp_bgpls_nlri->llri.local = stream_getw(s); + + attr->mp_bgpls_nlri->llri.remote = stream_getw(s); + + break; + + case BGP_NLRI_TLV_IPV4_INTERFACE_ADDRESS: + + node_type = stream_getw(s); + node_length = stream_getw(s); + + attr->mp_bgpls_nlri->i4ia.value.s_addr = stream_get_ipv4(s); + + break; + + case BGP_NLRI_TLV_IPV4_NEIGHBOR_ADDRESS: + + node_type = stream_getw(s); + node_length = stream_getw(s); + + attr->mp_bgpls_nlri->i4na.value.s_addr = stream_get_ipv4(s); + + break; + + case BGP_NLRI_TLV_IPV6_INTERFACE_ADDRESS: + + node_type = stream_getw(s); + node_length = stream_getw(s); + + stream_get(&attr->mp_bgpls_nlri->i6ia.value, s, + BGP_NLRI_TLV_LEN_IPV6_INTERFACE_ADDRESS); + + break; + + case BGP_NLRI_TLV_IPV6_NEIGHBOR_ADDRESS: + + node_type = stream_getw(s); + node_length = stream_getw(s); + + stream_get(&attr->mp_bgpls_nlri->i6ia.value, s, + BGP_NLRI_TLV_LEN_IPV6_NEIGHBOR_ADDRESS); + + break; + + case BGP_NLRI_TLV_MULTI_TOPOLOGY_ID: + + node_type = stream_getw(s); + node_length = stream_getw(s); + + + n = (node_length) / 2; + i = 0; + for (i = 0; i <= (n - 1); i++) { + attr->mp_bgpls_nlri->mid->value[i] = stream_getw(s); + } + + break; + + default: + break; + } + return BGP_ATTR_PARSE_PROCEED; +} + +/********************************************************************************* ++---------------+----------------------+----------+-----------------+ + | TLV Code | Description | Length | Reference | + | Point | | | | + +---------------+----------------------+----------+-----------------+ + | 1152 | IGP Flags | 1 | Section 3.3.3.1 | + | 1153 | Route Tag | 4*n | Section 3.3.3.2 | + | 1154 | Extended Tag | 8*n | Section 3.3.3.3 | + | 1155 | Prefix Metric | 4 | Section 3.3.3.4 | + | 1156 | OSPF Forwarding | 4 | Section 3.3.3.5 | + | | Address | | | + | 1157 | Opaque Prefix | variable | Section 3.3.3.6 | + | | Attribute | | | + +---------------+----------------------+----------+-----------------+ +**********************************************************************************/ + +int bgp_mp_prefix_decode(struct bgp_attr_parser_args *args, struct stream *s) +{ + struct peer *const peer = args->peer; + struct attr *const attr = args->attr; + uint16_t type, node_type; + uint16_t length, node_length; + size_t nlri_node_endp; + + attr->mp_bgpls_nlri->ext_hdr.proto_id = stream_getc(s); + attr->mp_bgpls_nlri->ext_hdr.nlri_identifier = stream_getq(s); + type = stream_getw(s); + length = stream_getw(s); + int n, i; + switch (type) { + + case BGP_NLRI_TLV_LOCAL_NODE_DESCRIPTORS: + + nlri_node_endp = stream_get_getp(s) + length; + + while (stream_get_getp(s) < nlri_node_endp) { + + node_type = stream_getw(s); + node_length = stream_getw(s); + + switch (node_type) { + + case BGP_NLRI_TLV_AUTONOMOUS_SYSTEM: + + stream_get( + attr->mp_bgpls_nlri->local_node->value, + s, BGP_NLRI_TLV_LEN_AUTONOMOUS_SYSTEM); + + break; + + case BGP_NLRI_TLV_BGP_LS_IDENTIFIER: + + stream_get( + attr->mp_bgpls_nlri->local_node->value, + s, BGP_NLRI_TLV_LEN_BGP_LS_IDENTIFIER); + + break; + + case BGP_NLRI_TLV_AREA_ID: + + stream_get( + attr->mp_bgpls_nlri->local_node->value, + s, BGP_NLRI_TLV_LEN_AREA_ID); + + break; + + case BGP_NLRI_TLV_IGP_ROUTER_ID: + + switch (node_length) { + case BGP_NLRI_IS_IS_NON_PSEUDONODE: + stream_get( + &attr->mp_bgpls_nlri->local_node + ->value, + s, + BGP_NLRI_IS_IS_NON_PSEUDONODE); + break; + + case BGP_NLRI_IS_IS_PSEUDONODE: + stream_get(&attr->mp_bgpls_nlri + ->local_node->value, + s, + BGP_NLRI_IS_IS_PSEUDONODE); + break; + + case BGP_NLRI_OSPF_NON_PSEUDONODE: + stream_get( + &attr->mp_bgpls_nlri->local_node + ->value, + s, + BGP_NLRI_OSPF_NON_PSEUDONODE); + break; + + case BGP_NLRI_OSPF_PSEUDONODE: + stream_get(&attr->mp_bgpls_nlri + ->local_node->value, + s, BGP_NLRI_OSPF_PSEUDONODE); + break; + + default: + zlog_info( + "%s sent invalid IGP Router-ID, %lu", + peer->host, + (unsigned long)length); + break; + } + + break; + + default: + zlog_info( + "%s sent invalid Node Descriptor, %lu", + peer->host, (unsigned long)length); + break; + } + } + break; + + case BGP_NLRI_TLV_MULTI_TOPOLOGY_ID: + + node_type = stream_getw(s); + node_length = stream_getw(s); + + n = (node_length) / 2; + i = 0; + for (i = 0; i <= (n - 1); i++) { + attr->mp_bgpls_nlri->mid->value[i] = stream_getw(s); + } + + break; + + case BGP_NLRI_TLV_OSPF_ROUTE_TYPE: + + node_type = stream_getw(s); + node_length = stream_getw(s); + + attr->mp_bgpls_nlri->ort.value = stream_getc(s); + + break; + + case BGP_NLRI_TLV_IP_REACHABILITY_INFORMATION: + + node_type = stream_getw(s); + node_length = stream_getw(s); + + attr->mp_bgpls_nlri->ipreach->prefix = stream_getc(s); + + stream_get(&attr->mp_bgpls_nlri->ipreach->value, s, + attr->mp_bgpls_nlri->ipreach->prefix); + break; + + default: + zlog_info("%s sent invalid Link State IS-IS TLV, %lu", + peer->host, (unsigned long)length); + return BGP_ATTR_PARSE_ERROR_NOTIFYPLS; + break; + } + return BGP_ATTR_PARSE_PROCEED; +} + +/*----------------------------------------------------------------------------------------------* + * Followings are vty session control + *functions. + ** + *----------------------------------------------------------------------------------------------*/ + +static uint16_t +show_vty_multi_topology_identifier(struct vty *vty, + struct te_tlv_nlri_header *tlvh) +{ + struct bgp_nlri_tlv_mt_id *top; + int i, n; + + top = (struct bgp_nlri_tlv_mt_id *)tlvh; + n = ntohs(top->header.nlri_length) / sizeof(top->value[0]); + if (vty != NULL) { + vty_out(vty, " Multi Topology ID number: %d\n", n); + } else { + zlog_debug(" Multi Topology ID number: %d", n); + } + for (i = 0; i < n; i++) { + if (vty != NULL) { + vty_out(vty, " ID #%d: %d\n", i, + ntohs(top->value[i])); + } else { + zlog_debug(" ID #%d: %d", i, ntohs(top->value[i])); + } + } + return BGP_TLV_SIZE(tlvh); +} + +static uint16_t show_vty_node_flag_bits(struct vty *vty, + struct te_tlv_nlri_header *tlvh) +{ + struct bgp_nlri_tlv_nfb *top = (struct bgp_nlri_tlv_nfb *)tlvh; + + if (vty != NULL) + vty_out(vty, " Node flag bits: %d\n", (uint8_t)(top->value)); + else + zlog_debug(" Node flag bits: %d", (uint8_t)(top->value)); + + return BGP_TLV_SIZE(tlvh); +} + +static uint16_t show_vty_opaque_node_properties(struct vty *vty, + struct te_tlv_nlri_header *tlvh) +{ + struct bgp_nlri_tlv_onp *top = (struct bgp_nlri_tlv_onp *)tlvh; + if (vty != NULL) + vty_out(vty, " Opaque Node Properties: %p\n", &top->value); + else + zlog_debug(" Opaque Node Properties: %p", &top->value); + return BGP_TLV_SIZE(tlvh); +} + +static uint16_t show_vty_node_name(struct vty *vty, + struct te_tlv_nlri_header *tlvh) +{ + struct bgp_nlri_tlv_nn *top = (struct bgp_nlri_tlv_nn *)tlvh; + if (vty != NULL) + vty_out(vty, " Node name: %p\n", &top->value); + else + zlog_debug(" Node name: %p", &top->value); + + return BGP_TLV_SIZE(tlvh); +} + +static uint16_t show_vty_is_is_area_identifier(struct vty *vty, + struct te_tlv_nlri_header *tlvh) +{ + struct bgp_nlri_tlv_iiai *top = (struct bgp_nlri_tlv_iiai *)tlvh; + if (vty != NULL) + vty_out(vty, " IS-IS Area Identifier: %p\n", &top->value); + else + zlog_debug(" IS-IS Area Identifier: %p", &top->value); + + return BGP_TLV_SIZE(tlvh); +} + +static uint16_t +show_vty_ipv4_router_id_of_local_node(struct vty *vty, + struct te_tlv_nlri_header *tlvh) +{ + struct bgp_nlri_tlv_i4_rid_lrn *top = + (struct bgp_nlri_tlv_i4_rid_lrn *)tlvh; + + if (vty != NULL) + vty_out(vty, " IPv4 Router ID of local node: %pI4\n", + &top->value); + else + zlog_debug(" IPv4 Router ID of local node: %pI4", + &top->value); + + return BGP_TLV_SIZE(tlvh); +} + +static uint16_t +show_vty_ipv6_router_id_of_local_node(struct vty *vty, + struct te_tlv_nlri_header *tlvh) +{ + struct bgp_nlri_tlv_i6_rid_lrn *top = + (struct bgp_nlri_tlv_i6_rid_lrn *)tlvh; + + if (vty != NULL) + + vty_out(vty, " IPv6 Router ID of local node: %pI6\n", + &top->value); + else + zlog_debug(" IPv6 Router ID of local node: %pI6", + &top->value); + return BGP_TLV_SIZE(tlvh); +} + +static uint16_t +show_vty_ipv4_router_id_of_remote_node(struct vty *vty, + struct te_tlv_nlri_header *tlvh) +{ + struct bgp_nlri_tlv_i4_rid_lrn *top = + (struct bgp_nlri_tlv_i4_rid_lrn *)tlvh; + + if (vty != NULL) + vty_out(vty, " IPv4 Router ID of remote node: %pI4\n", + &top->value); + else + zlog_debug(" IPv4 Router ID of remote node: %pI4", + &top->value); + + return BGP_TLV_SIZE(tlvh); +} + +static uint16_t +show_vty_ipv6_router_id_of_remote_node(struct vty *vty, + struct te_tlv_nlri_header *tlvh) +{ + struct bgp_nlri_tlv_i6_rid_lrn *top = + (struct bgp_nlri_tlv_i6_rid_lrn *)tlvh; + + if (vty != NULL) + vty_out(vty, " IPv6 Router ID of remote node: %pI6\n", + &top->value); + else + zlog_debug(" IPv6 Router ID of remote node: %pI6", + &top->value); + return BGP_TLV_SIZE(tlvh); +} + +static uint16_t show_vty_admin_grp_color(struct vty *vty, + struct te_tlv_nlri_header *tlvh) +{ + struct bgp_nlri_tlv_agc *top = (struct bgp_nlri_tlv_agc *)tlvh; + if (vty != NULL) + vty_out(vty, " Administrative Group: 0x%x\n", + (uint32_t)ntohl(top->value)); + else + zlog_debug(" Administrative Group: 0x%x", + (uint32_t)ntohl(top->value)); + + return (BGP_TLV_SIZE(tlvh)); +} + +static uint16_t show_vty_max_link_bw(struct vty *vty, + struct te_tlv_nlri_header *tlvh) +{ + struct bgp_nlri_tlv_max_link_bw *top = + (struct bgp_nlri_tlv_max_link_bw *)tlvh; + float fval; + + fval = ntohf(top->value); + + if (vty != NULL) + vty_out(vty, " Maximum Bandwidth: %g (Bytes/sec)\n", fval); + else + zlog_debug(" Maximum Bandwidth: %g (Bytes/sec)", fval); + + return BGP_TLV_SIZE(tlvh); +} + +static uint16_t show_vty_max_rsv_bw(struct vty *vty, + struct te_tlv_nlri_header *tlvh) +{ + struct bgp_nlri_tlv_max_rsv_link_bw *top = + (struct bgp_nlri_tlv_max_rsv_link_bw *)tlvh; + + float fval; + + fval = ntohf(top->value); + + if (vty != NULL) + vty_out(vty, + " Maximum Reservable Bandwidth: %g (Bytes/sec)\n", + fval); + else + zlog_debug(" Maximum Reservable Bandwidth: %g (Bytes/sec)", + fval); + + return BGP_TLV_SIZE(tlvh); +} + +static uint16_t show_vty_unrsv_bw(struct vty *vty, + struct te_tlv_nlri_header *tlvh) +{ + struct bgp_nlri_tlv_ursv_bw *top = (struct bgp_nlri_tlv_ursv_bw *)tlvh; + + float fval1, fval2; + int i; + + if (vty != NULL) + vty_out(vty, " Unreserved Bandwidth:\n"); + else + zlog_debug(" Unreserved Bandwidth:"); + + for (i = 0; i < 8; i += 2) //à revenir imperativement + { + fval1 = ntohf(top->value[i]); + fval2 = ntohf(top->value[i + 1]); + if (vty != NULL) + vty_out(vty, + " [%d]: %g (Bytes/sec),\t[%d]: %g (Bytes/sec)\n", + i, fval1, i + 1, fval2); + else + zlog_debug( + " [%d]: %g (Bytes/sec), [%d]: %g (Bytes/sec)", + i, fval1, i + 1, fval2); + } + + return BGP_TLV_SIZE(tlvh); +} + +static uint16_t show_vty_te_metric(struct vty *vty, + struct te_tlv_nlri_header *tlvh) +{ + struct bgp_nlri_tlv_tdm *top = (struct bgp_nlri_tlv_tdm *)tlvh; + // uint32_t te_metric; + + // te_metric = tlvh->value[2] | tlvh->value[1] << 8 | tlvh->value[0] << + // 16; + if (vty != NULL) + vty_out(vty, " Traffic Engineering Metric: %u\n", + (uint32_t)ntohl(top->value)); + else + zlog_debug(" Traffic Engineering Metric: %u", + (uint32_t)ntohl(top->value)); + + return BGP_TLV_SIZE(tlvh); +} + +static uint16_t show_vty_link_protection_type(struct vty *vty, + struct te_tlv_nlri_header *tlvh) +{ + struct bgp_nlri_tlv_link_pt *top = (struct bgp_nlri_tlv_link_pt *)tlvh; + + if (vty != NULL) + vty_out(vty, " Link Protection Type: %d\n", + (uint16_t)ntohs(top->value)); + else + zlog_debug(" Link Protection Type: %d", + (uint16_t)ntohs(top->value)); + + return BGP_TLV_SIZE(tlvh); +} + +static uint16_t show_vty_mpls_protocol_mask(struct vty *vty, + struct te_tlv_nlri_header *tlvh) +{ + struct bgp_nlri_tlv_mpls_pm *top = (struct bgp_nlri_tlv_mpls_pm *)tlvh; + + if (vty != NULL) + vty_out(vty, " MPLS Protocol Mask: %c\n", + (uint8_t)ntohs(top->value)); + else + zlog_debug(" MPLS Protocol Mask: %c", + (uint8_t)ntohs(top->value)); + + return BGP_TLV_SIZE(tlvh); +} + +static uint16_t show_vty_igp_metric(struct vty *vty, + struct te_tlv_nlri_header *tlvh) +{ + + struct bgp_nlri_tlv_metric *top = (struct bgp_nlri_tlv_metric *)tlvh; + + if (vty != NULL) + vty_out(vty, " IGP Metric: %u\n", + (uint32_t)ntohs(*top->value)); + else + zlog_debug(" IGP Metric: %u", (uint32_t)ntohs(*top->value)); + + return BGP_TLV_SIZE(tlvh); +} + +static uint16_t show_vty_shared_risk_link_group(struct vty *vty, + struct te_tlv_nlri_header *tlvh) +{ + struct bgp_nlri_tlv_srlg *top; + int i, n; + + top = (struct bgp_nlri_tlv_srlg *)tlvh; + n = ntohs(top->header.nlri_length) / sizeof(&top->value[0]); + // The size is 4 bytes + if (vty != NULL) + vty_out(vty, " Shared Risk Link Group Number: %d\n", n); + else + zlog_debug(" Shared Risk Link Group Number: %d", n); + + for (i = 0; i < n; i++) { + if (vty != NULL) + vty_out(vty, " Value n° #%d: %d\n", i, + ntohs(top->value[i])); + else + zlog_debug(" Value n° #%d: %d", i, + ntohs(top->value[i])); + } + + return BGP_TLV_SIZE(tlvh); +} +static uint16_t show_vty_opaque_link_attribute(struct vty *vty, + struct te_tlv_nlri_header *tlvh) +{ + struct bgp_nlri_tlv_ola *top = (struct bgp_nlri_tlv_ola *)tlvh; + + if (vty != NULL) { + vty_out(vty, " Opaque Link attributes: %p\n", top->value); + } else { + zlog_debug(" Opaque Link attributes: %p", top->value); + } + + return BGP_TLV_SIZE(tlvh); +} + +static uint16_t show_vty_link_name_attribute(struct vty *vty, + struct te_tlv_nlri_header *tlvh) +{ + struct bgp_nlri_tlv_lna *top = (struct bgp_nlri_tlv_lna *)tlvh; + + if (vty != NULL) { + vty_out(vty, " Link Name: %p\n", top->value); + } else + zlog_debug(" Link Name: %p", top->value); + + return BGP_TLV_SIZE(tlvh); +} + +static uint16_t show_vty_bgp_nlri_tlv_igp_flags(struct vty *vty, + struct te_tlv_nlri_header *tlvh) +{ + struct bgp_nlri_tlv_igp_flags *top = + (struct bgp_nlri_tlv_igp_flags *)tlvh; + + if (vty != NULL) + vty_out(vty, " IGP Flags: %u\n", (uint8_t)ntohs(top->value)); + else + zlog_debug(" IGP Flags: %u", (uint8_t)ntohs(top->value)); + + return BGP_TLV_SIZE(tlvh); +} + +static uint16_t show_vty_bgp_nlri_tlv_route_tag(struct vty *vty, + struct te_tlv_nlri_header *tlvh) +{ + struct bgp_nlri_tlv_route_tag *top; + int i, n; + top = (struct bgp_nlri_tlv_route_tag *)tlvh; + + n = ntohs(top->header.nlri_length) / sizeof(&top->value[0]); + // The size is 4 bytes + if (vty != NULL) + vty_out(vty, " Route Tag(s): %d\n", n); + else + zlog_debug(" Route Tag(s): %d", n); + + for (i = 0; i < n; i++) { + if (vty != NULL) + vty_out(vty, " Value n° #%d: %x\n", i, + ntohl(top->value[i])); + else + zlog_debug(" Value n° #%d: %x", i, + ntohl(top->value[i])); + } + + return BGP_TLV_SIZE(tlvh); +} + +static uint16_t +show_vty_bgp_nlri_tlv_extended_tag(struct vty *vty, + struct te_tlv_nlri_header *tlvh) +{ + struct bgp_nlri_tlv_extended_tag *top; + int i, n; + top = (struct bgp_nlri_tlv_extended_tag *)tlvh; + + n = ntohs(top->header.nlri_length) / sizeof(&top->value[0]); + // The size is 8 bytes + if (vty != NULL) + vty_out(vty, " Extended Route Tag(s): %d\n", n); + else + zlog_debug(" Extended Route Tag(s): %d", n); + + for (i = 0; i < n; i++) { + if (vty != NULL) { + vty_out(vty, " Value n° #%d: %llu\n", i, + (uint64_t)ntohl(top->value[i])); + } else + zlog_debug(" Value n° #%d: %llu", i, + (uint64_t)ntohl(top->value[i])); + } + + return BGP_TLV_SIZE(tlvh); +} + +static uint16_t +show_vty_bgp_nlri_tlv_prefix_metric(struct vty *vty, + struct te_tlv_nlri_header *tlvh) +{ + struct bgp_nlri_tlv_prefix_metric *top = + (struct bgp_nlri_tlv_prefix_metric *)tlvh; + + if (vty != NULL) + vty_out(vty, " Prefix Metric: %u\n", ntohl(top->value)); + else + zlog_debug(" Prefix Metric: %u", + (uint32_t)ntohl(top->value)); + + return BGP_TLV_SIZE(tlvh); +} + +static uint16_t +show_bgp_nlri_tlv_ospf_fowarding_adress(struct vty *vty, + struct te_tlv_nlri_header *tlvh) +{ + struct bgp_nlri_tlv_ospf_fowarding_adress *top = + (struct bgp_nlri_tlv_ospf_fowarding_adress *)tlvh; + if (vty != NULL) { + if (top->header.nlri_length == + BGP_NLRI_TLV_LEN_IPV4_FOWARDING_ADDRESS) { + vty_out(vty, " IPv4 OSPF Fowarding Address: %pI4\n", + &top->value.addr4); + } + if (top->header.nlri_length == + BGP_NLRI_TLV_LEN_IPV6_FOWARDING_ADDRESS) { + vty_out(vty, " IPv6 OSPF Fowarding Address: %pI6\n", + &top->value.addr6); + } + } else { + zlog_debug(" IPv4 OSPF Fowarding Address: %pI4", + &top->value.addr4); + zlog_debug(" IPv6 OSPF Fowarding Address: %pI6", + &top->value.addr6); + } + return BGP_TLV_SIZE(tlvh); +} + +static uint16_t +show_bgp_nlri_tlv_opaque_prefix_attribute(struct vty *vty, + struct te_tlv_nlri_header *tlvh) +{ + struct bgp_nlri_tlv_opa *top = (struct bgp_nlri_tlv_opa *)tlvh; + + if (vty != NULL) + + vty_out(vty, " Opaque prefix Attribute: %p\n", top->value); + else + zlog_debug(" Opaque prefix Attribute: %p", top->value); + + return BGP_TLV_SIZE(tlvh); +} + +static uint16_t show_vty_unknown_tlv(struct vty *vty, + struct te_tlv_nlri_header *tlvh) +{ + int i, rtn = 1; + uint8_t *v = (uint8_t *)tlvh; + + if (vty != NULL) { + if (tlvh->nlri_length != 0) { + vty_out(vty, + " Unknown TLV: [type(%#.2x), length(%#.2x)]\n", + tlvh->nlri_type, tlvh->nlri_length); + vty_out(vty, " Dump: [00]"); + rtn = 1; /* initialize end of line counter */ + for (i = 0; i < tlvh->nlri_length; i++) { + vty_out(vty, " %#.2x", v[i]); + if (rtn == 8) { + vty_out(vty, "\n [%.2x]", + i + 1); + rtn = 1; + } else + rtn++; + } + vty_out(vty, "\n"); + } else + vty_out(vty, + " Unknown TLV: [type(%#.2x), length(%#.2x)]\n", + tlvh->nlri_type, tlvh->nlri_length); + } else { + zlog_debug(" Unknown TLV: [type(%#.2x), length(%#.2x)]", + tlvh->nlri_type, tlvh->nlri_length); + } + + return BGP_TLV_HDR_SIZE; +} + +/*--------------- ---------Main Show function--------------------------------- + */ + +int show_bgp_linkstate_print_detail(struct vty *vty, struct ls_bgpls *te) +{ + struct te_tlv_nlri_header *tlvh, *next; + uint16_t sum = 0; + + zlog_debug("BGP-LS: Show database TE detail"); + + if (te->header.nlri_type == 0) /* En attendant */ + return CMD_WARNING; + + tlvh = &te->header; + + for (; sum < te->header.nlri_length; + tlvh = (next ? next : BGP_TLV_HDR_NEXT(tlvh))) { + next = NULL; + switch (ntohs(tlvh->nlri_type)) { + case BGP_NLRI_TLV_MULTI_TOPOLOGY_ID: + sum += show_vty_multi_topology_identifier(vty, tlvh); + break; + case BGP_NLRI_TLV_NODE_FLAG_BITS: + sum += show_vty_node_flag_bits(vty, tlvh); + break; + case BGP_NLRI_TLV_OPAQUE_NODE_PROPERTIES: + sum += show_vty_opaque_node_properties(vty, tlvh); + break; + case BGP_NLRI_TLV_NODE_NAME: + sum += show_vty_node_name(vty, tlvh); + break; + case BGP_NLRI_TLV_IS_IS_AREA_IDENTIFIER: + sum += show_vty_is_is_area_identifier(vty, tlvh); + break; + case BGP_NLRI_TLV_IPV4_ROUTER_ID_OF_LOCAL_NODE: + sum += show_vty_ipv4_router_id_of_local_node(vty, tlvh); + break; + case BGP_NLRI_TLV_IPV6_ROUTER_ID_OF_LOCAL_NODE: + sum += show_vty_ipv6_router_id_of_local_node(vty, tlvh); + break; + case BGP_NLRI_TLV_IPV4_ROUTER_ID_OF_REMOTE_NODE: + sum += show_vty_ipv4_router_id_of_remote_node(vty, + tlvh); + break; + case BGP_NLRI_TLV_IPV6_ROUTER_ID_OF_REMOTE_NODE: + sum += show_vty_ipv6_router_id_of_remote_node(vty, + tlvh); + break; + case BGP_NLRI_TLV_ADMINISTRATIVE_GROUP_COLOR: + sum += show_vty_admin_grp_color(vty, tlvh); + break; + case BGP_NLRI_TLV_MAX_LINK_BANDWIDTH: + sum += show_vty_max_link_bw(vty, tlvh); + break; + case BGP_NLRI_TLV_MAX_RESERVABLE_LINK_BANDWIDTH: + sum += show_vty_max_rsv_bw(vty, tlvh); + break; + case BGP_NLRI_TLV_UNRESERVED_BANDWIDTH: + sum += show_vty_unrsv_bw(vty, tlvh); + break; + case BGP_NLRI_TLV_TE_DEFAULT_METRIC: + sum += show_vty_te_metric(vty, tlvh); + break; + case BGP_NLRI_TLV_LINK_PROTECTION_TYPE: + sum += show_vty_link_protection_type(vty, tlvh); + break; + case BGP_NLRI_TLV_MPLS_PROTOCOL_MASK: + sum += show_vty_mpls_protocol_mask(vty, tlvh); + break; + case BGP_NLRI_TLV_IGP_METRIC: + sum += show_vty_igp_metric(vty, tlvh); + break; + case BGP_NLRI_TLV_SHARED_RISK_LINK_GROUP: + sum += show_vty_shared_risk_link_group(vty, tlvh); + break; + case BGP_NLRI_TLV_OPAQUE_LINK_ATTRIBUTE: + sum += show_vty_opaque_link_attribute(vty, tlvh); + break; + case BGP_NLRI_TLV_LINK_NAME_ATTRIBUTE: + sum += show_vty_link_name_attribute(vty, tlvh); + break; + case BGP_NLRI_TLV_IGP_FLAGS: + sum += show_vty_bgp_nlri_tlv_igp_flags(vty, tlvh); + break; + case BGP_NLRI_TLV_ROUTE_TAG: + sum += show_vty_bgp_nlri_tlv_route_tag(vty, tlvh); + break; + case BGP_NLRI_TLV_EXTENDED_TAG: + sum += show_vty_bgp_nlri_tlv_extended_tag(vty, tlvh); + break; + case BGP_NLRI_TLV_PREFIX_METRIC: + sum += show_vty_bgp_nlri_tlv_prefix_metric(vty, tlvh); + break; + case BGP_NLRI_TLV_OSPF_FORWARDING_ADDRESS: + sum += show_bgp_nlri_tlv_ospf_fowarding_adress(vty, + tlvh); + break; + case BGP_NLRI_TLV_OPAQUE_PREFIX_ATTRIBUTE: + sum += show_bgp_nlri_tlv_opaque_prefix_attribute(vty, + tlvh); + break; + default: + sum += show_vty_unknown_tlv(vty, tlvh); + break; + } + } + return sum; +} + +// static +int show_ls_route(struct vty *vty, struct peer *peer) +{ + struct bgp *bgp; + struct bgp_table *table; + struct bgp_node *rn; + struct bgp_node *rm; + struct attr *attr; + int rd_header; + int header = 1; + // char v4_header[] = " Network Next Hop Metric + // LocPrf Weight Path%s"; + + bgp = bgp_get_default(); + if (bgp == NULL) { + vty_out(vty, "No BGP process is configured\n"); + return CMD_WARNING; + } + + for (rn = bgp_table_top(bgp->rib[AFI_LINK_STATE][SAFI_LINK_STATE]); rn; + rn = bgp_route_next(rn)) { + + if ((table = rn->info) != NULL) { + rd_header = 1; + + for (rm = bgp_table_top(table); rm; + rm = bgp_route_next(rm)) + if ((attr = rm->info) != NULL) { + if (header) { + vty_out(vty, + "BGP table version is 0, local router ID is %s\n", + inet_ntoa( + bgp->router_id)); + vty_out(vty, + "Status codes: s suppressed, d damped, h history, * valid, > best, i - internal\n"); + vty_out(vty, + "Origin codes: i - IGP, e - EGP, ? - incomplete\n\n"); + header = 0; + } + + if (rd_header) { + show_bgp_linkstate_print_detail( + vty, + attr->link_state_attr); + } + } + } + } + + return CMD_SUCCESS; +} + +/*------------------------------------------------------------------------* + * Followings are vty command functions. + *------------------------------------------------------------------------*/ +DEFUN(show_ip_bgp_linkstate_database, show_ip_bgp_linkstate_database_cmd, + "show ip bgp ls database", + SHOW_STR IP_STR BGP_STR + "Link State Information: BGP-LS Attributes\n" + "Database of BGP-LS Attributes\n") +{ + return CMD_SUCCESS; +} + + +DEFUN(show_ip_bgp_linkstate_database_detail, + show_ip_bgp_linkstate_database_detail_cmd, + "show ip bgp ls database detail", + SHOW_STR IP_STR BGP_STR + "Link State Information: BGP-LS Attributes\n" + "Database of BGP-LS Attributes\n" + "Database detail of BGP-LS Attributes\n") +{ + struct bgp *bgp; + struct peer *peer; + bgp = bgp_get_default(); + peer = bgp->peer_self; + show_ls_route(vty, peer); + return CMD_SUCCESS; +} + +void bgp_link_state_init(void) +{ + install_element(VIEW_NODE, &show_ip_bgp_linkstate_database_cmd); + install_element(VIEW_NODE, &show_ip_bgp_linkstate_database_detail_cmd); +} diff --git a/bgpd/bgp_btoa.c b/bgpd/bgp_btoa.c index aa14d99f1856..f2bc27cd3e7a 100644 --- a/bgpd/bgp_btoa.c +++ b/bgpd/bgp_btoa.c @@ -190,6 +190,9 @@ int main(int argc, char **argv) case AFI_IP6: printf("/AFI_IP6\n"); break; + case AFI_LINK_STATE: + printf("/AFI_LINK_STATE\n"); + break; default: printf("/UNKNOWN %d", subtype); break; diff --git a/bgpd/bgp_ls.h b/bgpd/bgp_ls.h new file mode 100644 index 000000000000..991fd856edc1 --- /dev/null +++ b/bgpd/bgp_ls.h @@ -0,0 +1,699 @@ +/* + * This is an implementation of BGP Link State as per RFC 7752 + * + * Copyright (C) 2020 Orange http://www.orange.com + * + * This program 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 of the License, or (at your option) + * any later version. + * + * This program 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 this program; see the file COPYING; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef _ZEBRA_BGP_LS_TE_H +#define _ZEBRA_BGP_LS_TE_H + +#include "bgpd/bgp_attr.h" + +#define BGP_TLV_HDR_SIZE (sizeof(struct te_tlv_nlri_header)) + +#define BGP_TLV_BODY_SIZE(tlvh) \ + (ROUNDUP(ntohs((tlvh)->nlri_length), sizeof(uint32_t))) + +#define BGP_TLV_SIZE(tlvh) (BGP_TLV_HDR_SIZE + ntohs((tlvh)->nlri_length)) + +#define BGP_TLV_HDR_NEXT(tlvh) \ + (struct te_tlv_nlri_header *)((char *)(tlvh) + BGP_TLV_SIZE(tlvh)) + +#define BGP_TLV_TYPE(tlvh) tlvh.header.nlri_type +#define BGP_TLV_LEN(tlvh) tlvh.header.nlri_length +#define BGP_TLV_HDR(tlvh) tlvh.header +#define BGP_TLV_VAL(tlvh) tlvh.value +#define BGP_TLV_DATA(tlvh) tlvh + BGP_TLV_HDR_SIZE + +#ifdef roundup +#define ROUNDUP(val, gran) roundup(val, gran) +#else /* roundup */ +#define ROUNDUP(val, gran) (((val)-1 | (gran)-1) + 1) +#endif /* roundup */ + + +/* 0 1 2 3 + 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | NLRI Type | Total NLRI Length | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | | + // Link-State NLRI (variable) // + | | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +*/ + +struct te_tlv_nlri_header { + uint16_t nlri_type; /* TE_BGP_TLV_XXX (see below) */ + uint16_t nlri_length; /* Value portion only, in bytes */ +}; + +struct route_distinguisher { + struct te_tlv_nlri_header header; + uint32_t value; /*Value for Route distinguisher*/ +}; + +/* Link-State NLRI types + +--------+---------------------------+ + | Type | NLRI Type | + +--------+---------------------------+ + | 1 | Node NLRI | + | 2 | Link NLRI | + | 3 | IPv4 Topology Prefix NLRI | + | 4 | IPv6 Topology Prefix NLRI | + +------+-----------------------------+ + */ + +enum bgp_ls_nlri_type { + LINK_STATE_NODE_UNKNOWN = 1, + LINK_STATE_NODE_NLRI = 1, + LINK_STATE_LINK_NLRI = 2, + LINK_STATE_IPV4_TOPOLOGY_PREFIX_NLRI = 3, + LINK_STATE_IPV6_TOPOLOGY_PREFIX_NLRI = 4, +}; + +/* Link-State NLRI Protocol-ID values + +-------------+----------------------------------+ + | Protocol-ID | NLRI information source protocol | + +-------------+----------------------------------+ + | 1 | IS-IS Level 1 | + | 2 | IS-IS Level 2 | + | 3 | OSPFv2 | + | 4 | Direct | + | 5 | Static configuration | + | 6 | OSPFv3 | + +-------------+----------------------------------+ + */ + +enum bgp_ls_nlri_proto { + BGP_LS_NLRI_PROTO_ID_UNKNOWN = 0, + BGP_LS_NLRI_PROTO_ID_IS_IS_LEVEL_1 = 1, + BGP_LS_NLRI_PROTO_ID_IS_IS_LEVEL_2 = 2, + BGP_LS_NLRI_PROTO_ID_OSPF = 3, + BGP_LS_NLRI_PROTO_ID_DIRECT = 4, + BGP_LS_NLRI_PROTO_ID_STATIC = 5, + BGP_LS_NLRI_PROTO_ID_OSPFv3 = 6, +}; + +struct bgp_ls_nlri_extra_header { + enum bgp_ls_nlri_proto proto_id; + uint64_t nlri_identifier; +}; + +struct tlv_code_point { + struct te_tlv_nlri_header header; +}; + +/* Link-State routing universes + +------------+----------------------------------+ + | Identifier | Routing Universe | + +------------+----------------------------------+ + | 0 | Default Layer 3 Routing topology | + +------------+----------------------------------+ + */ +#define BGP_LS_NLRI_ROUTING_UNIVERSE_LEVEL_3 0 + +/* Link-State Node descriptors + * +3.2.1.2. Local Node Descriptors + The Local Node Descriptors TLV contains Node Descriptors for the node + anchoring the local end of the link. This is a mandatory TLV in all + three types of NLRIs (node, link, and prefix). The length of this + TLV is variable. The value contains one or more Node Descriptor + Sub-TLVs defined in Section 3.2.1.4. +3.2.1.3. Remote Node Descriptors + + The Remote Node Descriptors TLV contains Node Descriptors for the + node anchoring the remote end of the link. This is a mandatory TLV + for Link NLRIs. The length of this TLV is variable. The value + contains one or more Node Descriptor Sub-TLVs defined in + Section 3.2.1.4. + + +--------------------+-------------------+----------+ + | Sub-TLV Code Point | Description | Length | + +--------------------+-------------------+----------+ + | 512 | Autonomous System | 4 | + | 513 | BGP-LS Identifier | 4 | + | 514 | OSPF Area-ID | 4 | + | 515 | IGP Router-ID | Variable | + +--------------------+-------------------+----------+ + */ + +#define BGP_NLRI_TLV_LOCAL_NODE_DESCRIPTORS 256 +#define BGP_NLRI_TLV_REMOTE_NODE_DESCRIPTORS 257 +#define BGP_NLRI_TLV_AUTONOMOUS_SYSTEM 512 +#define BGP_NLRI_TLV_BGP_LS_IDENTIFIER 513 +#define BGP_NLRI_TLV_AREA_ID 514 +#define BGP_NLRI_TLV_IGP_ROUTER_ID 515 + +/* bgp_nlri_tlv_local_remote_node_descriptors */ +struct bgp_nlri_tlv_lrnd { + struct te_tlv_nlri_header header; + void *value; +}; + + +/* + * +-----------+---------------------+---------------+-----------------+ + | TLV Code | Description | IS-IS TLV | Value defined | + | Point | | /Sub-TLV | in: | + +-----------+---------------------+---------------+-----------------+ + | 258 | Link Local/Remote | 22/4 | [RFC5307]/1.1 | + | | Identifiers | | | + | 259 | IPv4 interface | 22/6 | [RFC5305]/3.2 | + | | address | | | + | 260 | IPv4 neighbor | 22/8 | [RFC5305]/3.3 | + | | address | | | + | 261 | IPv6 interface | 22/12 | [RFC6119]/4.2 | + | | address | | | + | 262 | IPv6 neighbor | 22/13 | [RFC6119]/4.3 | + | | address | | | + | 263 | Multi-Topology | --- | Section 3.2.1.5 | + | | Identifier | | | + +-----------+---------------------+---------------+-----------------+ + + */ +#define BGP_NLRI_TLV_LINK_LOCAL_REMOTE_IDENTIFIERS 258 +/* bgp_nlri_tlv_link_local_remote_identifiers */ +struct bgp_nlri_tlv_llri { + struct te_tlv_nlri_header header; /* Value length is 8 bytes. */ + uint32_t local; /* Link Local Identifier */ + uint32_t remote; /* Link Remote Identifier */ +}; + +#define BGP_NLRI_TLV_IPV4_INTERFACE_ADDRESS 259 +/* bgp_nlri_tlv_ipv4_interface_address */ +struct bgp_nlri_tlv_i4i_addr { + struct te_tlv_nlri_header header; /* Value length is 4 x N bytes. */ + struct in_addr value; /* Local IPv4 address(es). */ +}; + +#define BGP_NLRI_TLV_IPV4_NEIGHBOR_ADDRESS 260 +/* bgp_nlri_tlv_ipv4_neighbor_address */ +struct bgp_nlri_tlv_i4n_addr { + struct te_tlv_nlri_header header; /* Value length is 4 x N bytes. */ + struct in_addr value; /* Neighbor's IPv4 address(es). */ +}; + +#define BGP_NLRI_TLV_IPV6_INTERFACE_ADDRESS 261 +/* struct bgp_nlri_tlv_ipv6_interface_address */ +struct bgp_nlri_tlv_i6i_addr { + struct te_tlv_nlri_header header; /* Value length is 16 x N bytes. */ + struct in6_addr value; /* Local IPv6 address(es). */ +}; + +#define BGP_NLRI_TLV_IPV6_NEIGHBOR_ADDRESS 262 +/* bgp_nlri_tlv_ipv6_neighbor_address */ +struct bgp_nlri_tlv_i6n_addr { + struct te_tlv_nlri_header header; /* Value length is 16 x N bytes. */ + struct in6_addr value; /* Neighbor's IPv6 address(es). */ +}; + +/* + * +--------------+-----------------------+----------+-----------------+ + | TLV Code | Description | Length | Value defined | + | Point | | | in: | + +--------------+-----------------------+----------+-----------------+ + | 263 | Multi-Topology | variable | Section 3.2.1.5 | + | | Identifier | | | + | 264 | OSPF Route Type | 1 | Section 3.2.3.1 | + | 265 | IP Reachability | variable | Section 3.2.3.2 | + | | Information | | | + +--------------+-----------------------+----------+-----------------+ + */ + +#define BGP_NLRI_TLV_MULTI_TOPOLOGY_ID 263 +/* bgp_nlri_tlv_multi_topology_id */ +struct bgp_nlri_tlv_mt_id { + struct te_tlv_nlri_header header; /* Value length is 2*n bytes. */ + uint16_t *value; /* Multi Topology ID: only 12 bits => 0 ... 4096 */ +}; + +#define BGP_NLRI_TLV_OSPF_ROUTE_TYPE 264 +/* bgp_nlri_tlv_ospf_route_type */ +struct bgp_nlri_tlv_ort { + struct te_tlv_nlri_header header; + uint8_t value; /* Value length is 1 byte */ +} __attribute__((__packed__)); + +#define BGP_LS_PREFIX_OSPF_ROUTE_TYPE_UNKNOWN 0 +#define BGP_LS_PREFIX_OSPF_ROUTE_TYPE_INTRA_AREA 1 +#define BGP_LS_PREFIX_OSPF_ROUTE_TYPE_INTER_AREA 2 +#define BGP_LS_PREFIX_OSPF_ROUTE_TYPE_EXTERNAL_1 3 +#define BGP_LS_PREFIX_OSPF_ROUTE_TYPE_EXTERNAL_2 4 +#define BGP_LS_PREFIX_OSPF_ROUTE_TYPE_NSSA_1 5 +#define BGP_LS_PREFIX_OSPF_ROUTE_TYPE_NSSA_2 6 + +/* + * Intra-Area (0x1) + + * Inter-Area (0x2) + + * External 1 (0x3) + + * External 2 (0x4) + + * NSSA 1 (0x5) + + * NSSA 2 (0x6) + */ + +#define BGP_NLRI_TLV_IP_REACHABILITY_INFORMATION 265 +/* bgp_nlri_tlv_ip_reachability */ +struct bgp_nlri_tlv_ip_reach { + struct te_tlv_nlri_header header; + uint8_t prefix; /*lenght*/ + void *value; /* a revoir absolument */ +} __attribute__((__packed__)); + +/* + +--------------------+-------------------+----------+ + | Sub-TLV Code Point | Description | Length | + +--------------------+-------------------+----------+ + | 512 | Autonomous System | 4 | + | 513 | BGP-LS Identifier | 4 | + | 514 | OSPF Area-ID | 4 | + | 515 | IGP Router-ID | Variable | + | 516-1023 | Unassigned | | + +--------------------+-------------------+----------+ +*/ + + +/* + *********************************************************************************** + * LINK_STATE:99 + ** + *********************************************************************************** + */ + +/* + +--------------+-----------------------+----------+-----------------+ + | TLV Code | Description | Length | Value defined | + | Point | | | in: | + +--------------+-----------------------+----------+-----------------+ + | 263 | Multi-Topology | variable | Section 3.2.1.5 | + | | Identifier | | | + | 1024 | Node Flag Bits | 1 | Section 3.3.1.1 | + | 1025 | Opaque Node | variable | Section 3.3.1.5 | + | | Properties | | | + | 1026 | Node Name | variable | Section 3.3.1.3 | + | 1027 | IS-IS Area Identifier | variable | Section 3.3.1.2 | + | 1028 | IPv4 Router-ID of | 4 | [RFC5305]/4.3 | + | | Local Node | | | + | 1029 | IPv6 Router-ID of | 16 | [RFC6119]/4.1 | + | | Local Node | | | + +--------------+-----------------------+----------+-----------------+ + */ + + +#define BGP_NLRI_TLV_NODE_FLAG_BITS 1024 +/* struct bgp_nlri_tlv_node_flag_bits */ +struct bgp_nlri_tlv_nfb { + struct te_tlv_nlri_header header; /* Value length is 1 byte */ + uint8_t value; /* OTEB Reserve only 12 bits => 0 ...256*/ +} __attribute__((__packed__)); + +#define BGP_NLRI_TLV_OPAQUE_NODE_PROPERTIES 1025 +/* bgp_nlri_tlv_opaque_node_properties */ +struct bgp_nlri_tlv_onp { + struct te_tlv_nlri_header header; + void *value; +}; + +#define BGP_NLRI_TLV_NODE_NAME 1026 +/* bgp_nlri_tlv_node_name */ +struct bgp_nlri_tlv_nn { + struct te_tlv_nlri_header header; + void *value; +}; + +#define BGP_NLRI_TLV_IS_IS_AREA_IDENTIFIER 1027 +/* bgp_nlri_tlv_is_is_area_identifier */ +struct bgp_nlri_tlv_iiai { + struct te_tlv_nlri_header header; + void *value; +}; + +/* +--------------+-----------------------+----------+-----------------+ + | TLV Code | Description | Length | Value defined | + | Point | | | in: | + +--------------+-----------------------+----------+-----------------+ + | 263 | Multi-Topology | variable | Section 3.2.1.5 | + | | Identifier | | | + | 1024 | Node Flag Bits | 1 | Section 3.3.1.1 | + | 1025 | Opaque Node | variable | Section 3.3.1.5 | + | | Properties | | | + | 1026 | Node Name | variable | Section 3.3.1.3 | + | 1027 | IS-IS Area Identifier | variable | Section 3.3.1.2 | + | 1028 | IPv4 Router-ID of | 4 | [RFC5305]/4.3 | + | | Local Node | | | + | 1029 | IPv6 Router-ID of | 16 | [RFC6119]/4.1 | + | | Local Node | | | + +--------------+-----------------------+----------+-----------------+ + + */ + +#define BGP_NLRI_TLV_IPV4_ROUTER_ID_OF_LOCAL_NODE 1028 +/* bgp_nlri_tlv_ipv4_router_id_of_local_remote_node */ +struct bgp_nlri_tlv_i4_rid_lrn { + struct te_tlv_nlri_header header; /* Value length is 4 x N bytes. */ + struct in_addr value; /* Local IPv4 address(es). */ +}; + +#define BGP_NLRI_TLV_IPV6_ROUTER_ID_OF_LOCAL_NODE 1029 +/* bgp_nlri_tlv_ipv6_router_id_of_local_remote_node */ +struct bgp_nlri_tlv_i6_rid_lrn { + struct te_tlv_nlri_header header; /* Value length is 16 x N bytes. */ + struct in6_addr value; /* Local IPv6 address(es). */ +}; + +/* + +-----------+---------------------+--------------+------------------+ + | TLV Code | Description | IS-IS TLV | Defined in: | + | Point | | /Sub-TLV | | + +-----------+---------------------+--------------+------------------+ + | 1028 | IPv4 Router-ID of | 134/--- | [RFC5305]/4.3 | + | | Local Node | | | + | 1029 | IPv6 Router-ID of | 140/--- | [RFC6119]/4.1 | + | | Local Node | | | + | 1030 | IPv4 Router-ID of | 134/--- | [RFC5305]/4.3 | + | | Remote Node | | | + | 1031 | IPv6 Router-ID of | 140/--- | [RFC6119]/4.1 | + | | Remote Node | | | + | 1088 | Administrative | 22/3 | [RFC5305]/3.1 | + | | group (color) | | | + | 1089 | Maximum link | 22/9 | [RFC5305]/3.3 | + | | bandwidth | | | + | 1090 | Max. reservable | 22/10 | [RFC5305]/3.5 | + | | link bandwidth | | | + | 1091 | Unreserved | 22/11 | [RFC5305]/3.6 | + | | bandwidth | | | + | 1092 | TE Default Metric | 22/18 | Section 3.3.2.3/ | + | 1093 | Link Protection | 22/20 | [RFC5307]/1.2 | + | | Type | | | + | 1094 | MPLS Protocol Mask | --- | Section 3.3.2.2 | + | 1095 | IGP Metric | --- | Section 3.3.2.4 | + | 1096 | Shared Risk Link | --- | Section 3.3.2.5 | + | | Group | | | + | 1097 | Opaque link | --- | Section 3.3.2.6 | + | | attribute | | | + | 1098 | Link Name attribute | --- | Section 3.3.2.7 | + | 1099-1151 | Unassigned | --- | | + +-----------+---------------------+--------------+------------------+ +*/ + +#define BGP_NLRI_TLV_IPV4_ROUTER_ID_OF_REMOTE_NODE 1030 +/*Same structure than 1028*/ + +#define BGP_NLRI_TLV_IPV6_ROUTER_ID_OF_REMOTE_NODE 1031 +/*Same structure than 1029*/ + +#define BGP_NLRI_TLV_ADMINISTRATIVE_GROUP_COLOR 1088 +/* bgp_nlri_tlv_administrative_group_color */ +struct bgp_nlri_tlv_agc { + struct te_tlv_nlri_header header; /* Value length is 4 bytes. */ + uint32_t value; /* Admin. group membership. */ +}; + +#define BGP_NLRI_TLV_MAX_LINK_BANDWIDTH 1089 +/*bgp_nlri_tlv_max_link_bandwith */ +struct bgp_nlri_tlv_max_link_bw { + struct te_tlv_nlri_header header; /* Value length is 4 bytes. */ + float value; /* bytes/sec */ +}; + +#define BGP_NLRI_TLV_MAX_RESERVABLE_LINK_BANDWIDTH 1090 +/* bgp_nlri_tlv_max_reservable_link_bandwith */ +struct bgp_nlri_tlv_max_rsv_link_bw { + struct te_tlv_nlri_header header; /* Value length is 4 bytes. */ + float value; /* bytes/sec */ +}; + +#define BGP_NLRI_TLV_UNRESERVED_BANDWIDTH 1091 +/* bgp_nlri_tlv_unreserved_bandwith */ +struct bgp_nlri_tlv_ursv_bw { + struct te_tlv_nlri_header header; /* Value length is 32 bytes. */ + float value[8]; /* One for each priority level. */ +}; + +#define BGP_NLRI_TLV_TE_DEFAULT_METRIC 1092 +/* bgp_nlri_tlv_te_default_metric */ +struct bgp_nlri_tlv_tdm { + struct te_tlv_nlri_header header; /* Value length is 4 bytes. */ + uint32_t value; /* Link metric for TE purpose. */ +}; + +#define BGP_NLRI_TLV_LINK_PROTECTION_TYPE 1093 +/* bgp_nlri_tlv_link_protection_type */ +struct bgp_nlri_tlv_link_pt { + struct te_tlv_nlri_header header; /* Value length is xxxx bytes. */ + uint16_t value; /* Only 8 bits : 0.....256*/ +}; + +#define BGP_NLRI_TLV_MPLS_PROTOCOL_MASK 1094 +/* bgp_nlri_tlv_mpls_protocol_mask */ +struct bgp_nlri_tlv_mpls_pm { + struct te_tlv_nlri_header header; /* Value length is 2 bytes. */ + uint8_t value; /* Only 6 bits : 0.....64*/ +} __attribute__((__packed__)); + +#define BGP_NLRI_TLV_IGP_METRIC 1095 +/* bgp_nlri_tlv_metric */ +struct bgp_nlri_tlv_metric { + struct te_tlv_nlri_header header; /* Value length is 4 bytes. */ + uint8_t *value; /* max 24 bits : 0.....64*/ +} __attribute__((__packed__)); + +#define BGP_NLRI_TLV_SHARED_RISK_LINK_GROUP 1096 +/* bgp_nlri_tlv_shared_risk_link_group */ +struct bgp_nlri_tlv_srlg { + struct te_tlv_nlri_header header; /* Value length is 2*n bytes. */ + uint32_t *value; /* 4*n*/ +}; /* *Check * */ + +#define BGP_NLRI_TLV_OPAQUE_LINK_ATTRIBUTE 1097 +/* bgp_nlri_tlv_opaque_link_attribute */ +struct bgp_nlri_tlv_ola { + struct te_tlv_nlri_header header; /* Value length is variable bytes. */ + void *value; +}; /*Check */ + +#define BGP_NLRI_TLV_LINK_NAME_ATTRIBUTE 1098 +/* bgp_nlri_tlv_link_name_attribute */ +struct bgp_nlri_tlv_lna { + struct te_tlv_nlri_header header; /* Value length max is 255 bytes. */ + void *value; /* 2040 bits : 0.....64*/ +}; /*Check */ + +/* + +---------------+----------------------+----------+-----------------+ + | TLV Code | Description | Length | Reference | + | Point | | | | + +---------------+----------------------+----------+-----------------+ + | 1152 | IGP Flags | 1 | Section 3.3.3.1 | + | 1153 | Route Tag | 4*n | Section 3.3.3.2 | + | 1154 | Extended Tag | 8*n | Section 3.3.3.3 | + | 1155 | Prefix Metric | 4 | Section 3.3.3.4 | + | 1156 | OSPF Forwarding | 4 | Section 3.3.3.5 | + | | Address | | | + | 1157 | Opaque Prefix | variable | Section 3.3.3.6 | + | | Attribute | | | + | 1158-65535 | Unassigned | variable | | + +---------------+----------------------+----------+-----------------+ +*/ + +#define BGP_NLRI_TLV_IGP_FLAGS 1152 +/* bgp_nlri_tlv_igp_flags */ +struct bgp_nlri_tlv_igp_flags { + struct te_tlv_nlri_header header; /* Value length is 1 bytes. */ + uint8_t value; /* Only 4 bits is used */ +} __attribute__((__packed__)); + +#define BGP_NLRI_TLV_ROUTE_TAG 1153 +/* bgp_nlri_tlv_route_tag */ +struct bgp_nlri_tlv_route_tag { + struct te_tlv_nlri_header header; /* Value length is 4*n bytes. */ + uint32_t *value; /* */ +}; + +#define BGP_NLRI_TLV_EXTENDED_TAG 1154 +/* bgp_nlri_tlv_extended_tag */ +struct bgp_nlri_tlv_extended_tag { + struct te_tlv_nlri_header header; /* Value length is 8*n bytes. */ + uint64_t *value; /* */ +}; + +#define BGP_NLRI_TLV_PREFIX_METRIC 1155 +/* bgp_nlri_tlv_prefix_metric */ +struct bgp_nlri_tlv_prefix_metric { + struct te_tlv_nlri_header header; /* Value length is 4 bytes. */ + uint32_t value; +}; + +#define BGP_NLRI_TLV_OSPF_FORWARDING_ADDRESS 1156 +/* bgp_nlri_tlv_ospf_fowarding_adress */ +struct bgp_nlri_tlv_ospf_fowarding_adress { + struct te_tlv_nlri_header header; /* Value length is 4 or 16 bytes. */ + union { + struct in_addr addr4; + struct in6_addr addr6; + } value; /* IPV4 or IPV6 Prefix Metric*/ +}; + +#define BGP_NLRI_TLV_OPAQUE_PREFIX_ATTRIBUTE 1157 +/* bgp_nlri_tlv_opaque_prefix_attribute */ +struct bgp_nlri_tlv_opa { + struct te_tlv_nlri_header header; /* Value length is variable bytes. */ + void *value; /* */ + /** Check **/ +}; + + +/* Link-State NLRI TLV lengths */ + +#define BGP_NLRI_TLV_LEN_AUTONOMOUS_SYSTEM 4 +#define BGP_NLRI_TLV_LEN_BGP_LS_IDENTIFIER 4 +#define BGP_NLRI_TLV_LEN_AREA_ID 4 +#define BGP_NLRI_TLV_LEN_IPV4_ROUTER_ID 4 +#define BGP_NLRI_TLV_LEN_IPV6_ROUTER_ID 16 +#define BGP_NLRI_TLV_LEN_IPV4_ROUTER_ID_OF_LOCAL_NODE \ + BGP_NLRI_TLV_LEN_IPV4_ROUTER_ID +#define BGP_NLRI_TLV_LEN_IPV6_ROUTER_ID_OF_LOCAL_NODE \ + BGP_NLRI_TLV_LEN_IPV6_ROUTER_ID +#define BGP_NLRI_TLV_LEN_IPV4_ROUTER_ID_OF_REMOTE_NODE \ + BGP_NLRI_TLV_LEN_IPV4_ROUTER_ID +#define BGP_NLRI_TLV_LEN_IPV6_ROUTER_ID_OF_REMOTE_NODE \ + BGP_NLRI_TLV_LEN_IPV6_ROUTER_ID +#define BGP_NLRI_TLV_LEN_LINK_LOCAL_REMOTE_IDENTIFIERS 8 +#define BGP_NLRI_TLV_LEN_IPV4_INTERFACE_ADDRESS 4 +#define BGP_NLRI_TLV_LEN_IPV4_NEIGHBOR_ADDRESS 4 +#define BGP_NLRI_TLV_LEN_IPV6_INTERFACE_ADDRESS 16 +#define BGP_NLRI_TLV_LEN_IPV6_NEIGHBOR_ADDRESS 16 +#define BGP_NLRI_TLV_LEN_MULTI_TOPOLOGY_ID 2 +#define BGP_NLRI_TLV_LEN_OSPF_TYPE_ROUTE 1 +#define BGP_NLRI_TLV_LEN_ADMINISTRATIVE_GROUP_COLOR 4 +#define BGP_NLRI_TLV_LEN_MAX_LINK_BANDWIDTH 4 +#define BGP_NLRI_TLV_LEN_MAX_RESERVABLE_LINK_BANDWIDTH 4 +#define BGP_NLRI_TLV_LEN_UNRESERVED_BANDWIDTH 32 +#define BGP_NLRI_TLV_LEN_TE_DEFAULT_METRIC 4 /* not 3 */ +#define BGP_NLRI_TLV_LEN_LINK_PROTECTION_TYPE 2 /* 1 or 2 or 3 */ +#define BGP_NLRI_TLV_LEN_MPLS_PROTOCOL_MASK 1 +#define BGP_NLRI_TLV_LEN_METRIC 3 /* prefer to 3 */ +#define BGP_NLRI_TLV_LEN_IGP_FLAGS 1 +#define BGP_NLRI_TLV_LEN_PREFIX_METRIC 4 +#define BGP_NLRI_TLV_LEN_AREA_ID 4 +#define BGP_NLRI_TLV_LEN_NODE_FLAG_BITS 1 +#define BGP_NLRI_TLV_LEN_IPV4_FOWARDING_ADDRESS 4 +#define BGP_NLRI_TLV_LEN_IPV6_FOWARDING_ADDRESS 16 + +#define BGP_NLRI_IS_IS_NON_PSEUDONODE 6 +#define BGP_NLRI_IS_IS_PSEUDONODE 7 +#define BGP_NLRI_OSPF_NON_PSEUDONODE 4 +#define BGP_NLRI_OSPF_PSEUDONODE 8 + +/* Following declaration concerns the LS-TE and LINk-TE information */ + +/**Prototype Fonction de parsing des attributs */ + +/* BGP LS MP_[UN]REACH_NLRI prefix attributes */ +struct mp_bgpls_nlri { + + struct te_tlv_nlri_header header; + /**************************************************************/ + /*struct route_distinguisher rd;*/ /*Prefix RD*/ + struct prefix_rd prd; + /**************************************************************/ + /* + struct link_state_node_nlri node_nlri; + struct link_state_link_nlri link_nlri; + struct link_state_ipv4_nlri ipv4_nlri; + struct link_state_ipv6_nlri ipv6_nlri; + */ + /***********************************************************/ + struct bgp_ls_nlri_extra_header ext_hdr; + struct tlv_code_point tlvcp; + /*************************************************************/ + + struct bgp_nlri_tlv_lrnd *local_node; + struct bgp_nlri_tlv_lrnd *remote_node; + struct bgp_nlri_tlv_llri llri; + struct bgp_nlri_tlv_i4i_addr i4ia; + struct bgp_nlri_tlv_i4n_addr i4na; + struct bgp_nlri_tlv_i6i_addr i6ia; + struct bgp_nlri_tlv_i6n_addr i6na; + struct bgp_nlri_tlv_mt_id *mid; + struct bgp_nlri_tlv_ort ort; + struct bgp_nlri_tlv_ip_reach *ipreach; + /*************************************************************/ +}; + +/* BGP LS LINK_STATE prefix attributes */ +struct ls_bgpls { + struct te_tlv_nlri_header header; + + /*************************************************************/ + struct bgp_nlri_tlv_mt_id *mid; + struct bgp_nlri_tlv_nfb nfb; + struct bgp_nlri_tlv_onp *onp; + struct bgp_nlri_tlv_nn *nn; + struct bgp_nlri_tlv_iiai *iiai; + + /*************************************************************/ + struct bgp_nlri_tlv_i4_rid_lrn i4ridofln; + struct bgp_nlri_tlv_i6_rid_lrn i6ridofln; + struct bgp_nlri_tlv_i4_rid_lrn i4ridofrn; + struct bgp_nlri_tlv_i6_rid_lrn i6ridofrn; + struct bgp_nlri_tlv_agc agc; + struct bgp_nlri_tlv_max_link_bw mlb; + struct bgp_nlri_tlv_max_rsv_link_bw mrlb; + struct bgp_nlri_tlv_ursv_bw urb; + struct bgp_nlri_tlv_tdm tdm; + struct bgp_nlri_tlv_link_pt lpt; + struct bgp_nlri_tlv_mpls_pm mpm; + struct bgp_nlri_tlv_metric *igpm; + struct bgp_nlri_tlv_srlg *srlg; + struct bgp_nlri_tlv_ola *ola; + struct bgp_nlri_tlv_lna *lna; + /************************************************************/ + struct bgp_nlri_tlv_igp_flags ifl; + struct bgp_nlri_tlv_route_tag *rt; + struct bgp_nlri_tlv_extended_tag *et; + struct bgp_nlri_tlv_prefix_metric pm; + struct bgp_nlri_tlv_ospf_fowarding_adress ofa; + struct bgp_nlri_tlv_opa *opa; +}; + +extern void bgp_link_state_init(void); +extern void htonft(float *src, float *dst); +extern void ntohft(float *src, float *dst); + +/*For files bgp_bgpls_nlri.c & bgp_ls_bgpls.c*/ +extern int bgp_mp_node_decode(struct bgp_attr_parser_args *args, + struct stream *s); +extern int bgp_mp_link_decode(struct bgp_attr_parser_args *args, + struct stream *s); +extern int bgp_mp_prefix_decode(struct bgp_attr_parser_args *args, + struct stream *s); +extern int bgp_link_state_decode(struct bgp_attr_parser_args *args, + struct stream *s); +extern int show_bgp_linkstate_print_detail(struct vty *vty, + struct ls_bgpls *te); +extern int show_bgp_mpreach_print_detail(struct vty *vty, + struct mp_bgpls_nlri *te); +extern int show_ls_route(struct vty *vty, struct peer *peer); + +#endif /*_ZEBRA_BGP_LS_TE_H*/ diff --git a/bgpd/bgp_ls_bgpls.c b/bgpd/bgp_ls_bgpls.c new file mode 100644 index 000000000000..9357c8a14f5b --- /dev/null +++ b/bgpd/bgp_ls_bgpls.c @@ -0,0 +1,650 @@ +/* + * This is an implementation of BGP Link State as per RFC 7752 + * + * Copyright (C) 2020 Orange http://www.orange.com + * + * This program 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 of the License, or (at your option) + * any later version. + * + * This program 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 this program; see the file COPYING; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include + +#include "linklist.h" +#include "prefix.h" +#include "memory.h" +#include "vector.h" +#include "vty.h" +#include "stream.h" +#include "log.h" +#include "hash.h" +#include "jhash.h" +#include "command.h" +#include "sockunion.h" /* for inet_aton() */ +#include "table.h" +#include "if.h" +#include "thread.h" +#include "checksum.h" +#include "md5.h" +#include "bgpd/bgp_attr.h" +#include "bgpd/bgp_ls.h" +#include "bgpd/bgpd.h" +#include "bgpd/bgp_route.h" +#include "bgpd/bgp_aspath.h" +#include "bgpd/bgp_community.h" +#include "bgpd/bgp_debug.h" +#include "bgpd/bgp_packet.h" +#include "bgpd/bgp_ecommunity.h" +#include "bgpd/bgp_lsdb.h" + +/************************************************************************************** + + +--------------+-----------------------+----------+-----------------+ + | TLV Code | Description | Length | Value defined | + | Point | | | in: | + +--------------+-----------------------+----------+-----------------+ + | 263 | Multi-Topology | variable | Section 3.2.1.5 | + | | Identifier | | | + | 1024 | Node Flag Bits | 1 | Section 3.3.1.1 | + | 1025 | Opaque Node | variable | Section 3.3.1.5 | + | | Properties | | | + | 1026 | Node Name | variable | Section 3.3.1.3 | + | 1027 | IS-IS Area Identifier | variable | Section 3.3.1.2 | + | 1028 | IPv4 Router-ID of | 4 | [RFC5305]/4.3 | + | | Local Node | | | + | 1029 | IPv6 Router-ID of | 16 | [RFC6119]/4.1 | + | | Local Node | | | + +--------------+-----------------------+----------+-----------------+ + + +-----------+---------------------+--------------+------------------+ + | TLV Code | Description | IS-IS TLV | Defined in: | + | Point | | /Sub-TLV | | + +-----------+---------------------+--------------+------------------+ + | 1028 | IPv4 Router-ID of | 134/--- | [RFC5305]/4.3 | + | | Local Node | | | + | 1029 | IPv6 Router-ID of | 140/--- | [RFC6119]/4.1 | + | | Local Node | | | + | 1030 | IPv4 Router-ID of | 134/--- | [RFC5305]/4.3 | + | | Remote Node | | | + | 1031 | IPv6 Router-ID of | 140/--- | [RFC6119]/4.1 | + | | Remote Node | | | + | 1088 | Administrative | 22/3 | [RFC5305]/3.1 | + | | group (color) | | | + | 1089 | Maximum link | 22/9 | [RFC5305]/3.3 | + | | bandwidth | | | + | 1090 | Max. reservable | 22/10 | [RFC5305]/3.5 | + | | link bandwidth | | | + | 1091 | Unreserved | 22/11 | [RFC5305]/3.6 | + | | bandwidth | | | + | 1092 | TE Default Metric | 22/18 | Section 3.3.2.3/ | + | 1093 | Link Protection | 22/20 | [RFC5307]/1.2 | + | | Type | | | + | 1094 | MPLS Protocol Mask | --- | Section 3.3.2.2 | + | 1095 | IGP Metric | --- | Section 3.3.2.4 | + | 1096 | Shared Risk Link | --- | Section 3.3.2.5 | + | | Group | | | + | 1097 | Opaque link | --- | Section 3.3.2.6 | + | | attribute | | | + | 1098 | Link Name attribute | --- | Section 3.3.2.7 | + +-----------+---------------------+--------------+------------------+ +****************************************************************************************/ + +int bgp_link_state_decode(struct bgp_attr_parser_args *args, struct stream *s) +{ + size_t endp; + const bgp_size_t length = args->length; + struct attr *const attr = args->attr; + int i, n; + uint16_t ls_type; + uint16_t ls_length, mid_length; + + ls_length = 0; + + endp = stream_get_getp(s) + length; + + /* TODO: alloc / free */ + if (!attr->link_state_attr) + attr->link_state_attr = + XCALLOC(MTYPE_BGP_LSDB, sizeof(struct ls_bgpls)); + + /* Get link state attributes to the end of attribute length. */ + while (stream_get_getp(s) < endp) { + ls_type = stream_getw(s); + ls_length = stream_getw(s); + + if (ls_length > length) + break; + /* + if (length) + { + zlog_info ("%s: (%s) Failed to read Link + State Value %d : %d ,%d", + __func__, + peer->host,ls_type,ls_length,length); + } + */ + switch (ls_type) { + /******************************************************** + ---- Node Attribute ---- + ********************************************************/ + + case BGP_NLRI_TLV_MULTI_TOPOLOGY_ID: + mid_length = stream_getw(s); + n = (mid_length) / 2; + i = 0; + for (i = 0; i <= (n - 1); i++) { + attr->mp_bgpls_nlri->mid->value[i] = + stream_getw(s); + } + break; + + case BGP_NLRI_TLV_NODE_FLAG_BITS: + attr->link_state_attr->nfb.value = stream_getc(s); + break; + + case BGP_NLRI_TLV_OPAQUE_NODE_PROPERTIES: + attr->link_state_attr->onp = + XCALLOC(MTYPE_BGP_LSDB, ls_length); + stream_get(&attr->link_state_attr->onp, s, ls_length); + break; + + case BGP_NLRI_TLV_NODE_NAME: + attr->link_state_attr->nn = + XCALLOC(MTYPE_BGP_LSDB, ls_length); + stream_get(&attr->link_state_attr->nn, s, ls_length); + break; + + case BGP_NLRI_TLV_IS_IS_AREA_IDENTIFIER: + attr->link_state_attr->iiai = + XCALLOC(MTYPE_BGP_LSDB, ls_length); + stream_get(&attr->link_state_attr->iiai, s, ls_length); + break; + + case BGP_NLRI_TLV_IPV4_ROUTER_ID_OF_LOCAL_NODE: + attr->link_state_attr->i4ridofln.value.s_addr = + stream_get_ipv4(s); + break; + + case BGP_NLRI_TLV_IPV6_ROUTER_ID_OF_LOCAL_NODE: + stream_get( + &attr->link_state_attr->i6ridofln, s, + BGP_NLRI_TLV_LEN_IPV6_ROUTER_ID_OF_LOCAL_NODE); + break; + + /******************************************************** + ---- Link Attribute ---- + ********************************************************/ + + case BGP_NLRI_TLV_IPV4_ROUTER_ID_OF_REMOTE_NODE: + attr->link_state_attr->i4ridofrn.value.s_addr = + stream_get_ipv4(s); + break; + + case BGP_NLRI_TLV_IPV6_ROUTER_ID_OF_REMOTE_NODE: + stream_get( + &attr->link_state_attr->i6ridofrn, s, + BGP_NLRI_TLV_LEN_IPV6_ROUTER_ID_OF_LOCAL_NODE); + break; + + case BGP_NLRI_TLV_ADMINISTRATIVE_GROUP_COLOR: + attr->link_state_attr->agc.value = stream_getl(s); + break; + + case BGP_NLRI_TLV_MAX_LINK_BANDWIDTH: + attr->link_state_attr->mlb.value = stream_getl(s); + break; + + case BGP_NLRI_TLV_MAX_RESERVABLE_LINK_BANDWIDTH: + attr->link_state_attr->mrlb.value = stream_getl(s); + break; + + case BGP_NLRI_TLV_UNRESERVED_BANDWIDTH: + n = attr->link_state_attr->header.nlri_length; + for (i = 0; i <= (n - 1); i++) { + attr->link_state_attr->urb.value[i] = + stream_getl(s); + } + break; + + case BGP_NLRI_TLV_TE_DEFAULT_METRIC: + attr->link_state_attr->tdm.value = stream_getl(s); + break; + + case BGP_NLRI_TLV_LINK_PROTECTION_TYPE: + attr->link_state_attr->lpt.value = stream_getw(s); + break; + + case BGP_NLRI_TLV_MPLS_PROTOCOL_MASK: + attr->link_state_attr->mpm.value = stream_getc(s); + break; + + case BGP_NLRI_TLV_IGP_METRIC: + attr->link_state_attr->igpm = + XCALLOC(MTYPE_BGP_LSDB, ls_length); + stream_get(&attr->link_state_attr->igpm, s, ls_length); + break; + + case BGP_NLRI_TLV_SHARED_RISK_LINK_GROUP: + n = (ls_length) / 4; + + for (i = 0; i <= (n - 1); i++) { + attr->link_state_attr->srlg->value[i] = + stream_getl(s); + } + break; + + case BGP_NLRI_TLV_OPAQUE_LINK_ATTRIBUTE: + attr->link_state_attr->ola = + XCALLOC(MTYPE_BGP_LSDB, ls_length); + stream_get(&attr->link_state_attr->ola, s, ls_length); + break; + + case BGP_NLRI_TLV_LINK_NAME_ATTRIBUTE: + attr->link_state_attr->lna = + XCALLOC(MTYPE_BGP_LSDB, ls_length); + stream_get(&attr->link_state_attr->lna, s, ls_length); + break; + + /******************************************************** + ---- Prefix Attribute ---- + ********************************************************/ + case BGP_NLRI_TLV_IGP_FLAGS: + attr->link_state_attr->ifl.value = stream_getc(s); + break; + + case BGP_NLRI_TLV_ROUTE_TAG: + n = (ls_length) / 4; + i = 0; + for (i = 0; i <= (n - 1); i++) { + attr->link_state_attr->rt->value[i] = + stream_getl(s); + } + break; + + case BGP_NLRI_TLV_EXTENDED_TAG: + n = (ls_length) / 8; + i = 0; + for (i = 0; i <= (n - 1); i++) { + attr->link_state_attr->et->value[i] = + stream_getq(s); + } + break; + + case BGP_NLRI_TLV_PREFIX_METRIC: + attr->link_state_attr->pm.value = stream_getl(s); + break; + + case BGP_NLRI_TLV_OSPF_FORWARDING_ADDRESS: + switch (ls_length) { + case 4: + attr->link_state_attr->ofa.value.addr4.s_addr = + stream_get_ipv4(s); + break; + case 16: + stream_get( + &attr->link_state_attr->ofa, s, + BGP_NLRI_TLV_LEN_IPV6_FOWARDING_ADDRESS); + break; + default: + /* + zlog_info ("%s: %s, NLRI length, %s, goes past end + of attribute", + __func__, + peer->host, ls_length); + */ + // return BGP_ATTR_PARSE_ERROR_NOTIFYPLS; + break; + } + break; + + case BGP_NLRI_TLV_OPAQUE_PREFIX_ATTRIBUTE: + attr->link_state_attr->opa = + XCALLOC(MTYPE_BGP_LSDB, ls_length); + stream_get(&attr->link_state_attr->opa, s, ls_length); + break; + + default: + /* + zlog_info ("%s sent invalid Link State + TLV, %p", peer->host,value); + return BGP_ATTR_PARSE_ERROR_NOTIFYPLS; + */ + stream_forward_getp(s, ls_length); + break; + } + // pos+=stream_get_getp (s); + } + return BGP_ATTR_PARSE_PROCEED; +} + +/*----------------------------------------------------------------------------* + * Followings are vty session control functions. + ** + *----------------------------------------------------------------------------*/ +static uint16_t show_vty_local_node_descriptors(struct vty *vty, + struct te_tlv_nlri_header *tlvh) +{ + struct bgp_nlri_tlv_lrnd *top = (struct bgp_nlri_tlv_lrnd *)tlvh; + + if (vty != NULL) + vty_out(vty, " Local Node Descriptors: %p octets of data\n", + top->value); + else + zlog_debug(" Local Node Descriptors: %p octets of data", + top->value); + + return BGP_TLV_SIZE(tlvh); /* Here is special, not "TLV_SIZE". */ +} + +static uint16_t +show_vty_remote_node_descriptors(struct vty *vty, + struct te_tlv_nlri_header *tlvh) +{ + struct bgp_nlri_tlv_lrnd *top = (struct bgp_nlri_tlv_lrnd *)tlvh; + + if (vty != NULL) + vty_out(vty, " Remote Node Descriptors: %p octets of data\n", + top->value); + else + zlog_debug(" Remote Node Descriptors: %p octets of data", + top->value); + + return BGP_TLV_SIZE(tlvh); /* Here is special, not "TLV_SIZE". */ +} + +static uint16_t show_vty_subtlv_llri(struct vty *vty, + struct te_tlv_nlri_header *tlvh) +{ + struct bgp_nlri_tlv_llri *top = (struct bgp_nlri_tlv_llri *)tlvh; + + if (vty != NULL) { + vty_out(vty, " Link Local ID: %d\n", + (uint32_t)ntohl(top->local)); + vty_out(vty, " Link Remote ID: %d\n", + (uint32_t)ntohl(top->remote)); + } else { + zlog_debug(" Link Local ID: %d", + (uint32_t)ntohl(top->local)); + zlog_debug(" Link Remote ID: %d", + (uint32_t)ntohl(top->remote)); + } + + return BGP_TLV_SIZE(tlvh); +} + +static uint16_t show_vty_ipv4_interface_addr(struct vty *vty, + struct te_tlv_nlri_header *tlvh) +{ + struct bgp_nlri_tlv_i4i_addr *top = + (struct bgp_nlri_tlv_i4i_addr *)tlvh; + + if (vty != NULL) + vty_out(vty, " IPv4 interface Address: %pI4\n", &top->value); + else + zlog_debug(" IPv4 interface Address: %pI4", &top->value); + + return BGP_TLV_SIZE(tlvh); +} + +static uint16_t show_vty_ipv4_neighbor_addr(struct vty *vty, + struct te_tlv_nlri_header *tlvh) +{ + struct bgp_nlri_tlv_i4n_addr *top = + (struct bgp_nlri_tlv_i4n_addr *)tlvh; + + if (vty != NULL) + vty_out(vty, " IPv4 neighbor Address: %pI4\n", &top->value); + else + zlog_debug(" IPv4 neighbor Address: %pI4", &top->value); + + return BGP_TLV_SIZE(tlvh); +} + +static uint16_t show_vty_ipv6_interface_addr(struct vty *vty, + struct te_tlv_nlri_header *tlvh) +{ + struct bgp_nlri_tlv_i6i_addr *top = + (struct bgp_nlri_tlv_i6i_addr *)tlvh; + + if (vty != NULL) + vty_out(vty, " IPv6 interface Address: %pI6\n", &top->value); + else + zlog_debug(" IPv6 interface Address: %pI6", &top->value); + return BGP_TLV_SIZE(tlvh); +} + + +static uint16_t show_vty_ipv6_neighbor_addr(struct vty *vty, + struct te_tlv_nlri_header *tlvh) +{ + struct bgp_nlri_tlv_i6n_addr *top = + (struct bgp_nlri_tlv_i6n_addr *)tlvh; + + if (vty != NULL) + vty_out(vty, " IPv6 neighbor Address: %pI6\n", &top->value); + else + zlog_debug(" IPv6 neighbor Address: %pI6", &top->value); + return BGP_TLV_SIZE(tlvh); +} + +static uint16_t show_vty_multi_topology_id(struct vty *vty, + struct te_tlv_nlri_header *tlvh) +{ + struct bgp_nlri_tlv_mt_id *top; + int i, n; + + top = (struct bgp_nlri_tlv_mt_id *)tlvh; + n = ntohs(tlvh->nlri_length) / sizeof(&top->value[0]); + if (vty != NULL) + vty_out(vty, " Multi Topology ID number: %d\n", n); + else + zlog_debug(" Multi Topology ID number: %d", n); + + for (i = 0; i < n; i++) { + if (vty != NULL) { + vty_out(vty, " ID #%d: %x\n", i, + (uint16_t)ntohs(top->value[i])); + } else + zlog_debug(" ID #%d: %x", i, + (uint16_t)ntohs(top->value[i])); + } + return BGP_TLV_SIZE(tlvh); +} + +static uint16_t show_vty_ospf_type_route(struct vty *vty, + struct te_tlv_nlri_header *tlvh) +{ + struct bgp_nlri_tlv_ort *top = (struct bgp_nlri_tlv_ort *)tlvh; + + if (vty != NULL) + vty_out(vty, " OSPF Type Route: %c\n", + (uint8_t)ntohs(top->value)); + else + zlog_debug("OSPF Type Route: %c", (uint8_t)ntohs(top->value)); + + return BGP_TLV_SIZE(tlvh); +} + +static uint16_t show_vty_ip_reachability(struct vty *vty, + struct te_tlv_nlri_header *tlvh) +{ + struct bgp_nlri_tlv_ip_reach *top = + (struct bgp_nlri_tlv_ip_reach *)tlvh; + + if (vty != NULL) { + vty_out(vty, " IP Reachability: %c\n", + (uint8_t)ntohs(top->prefix)); + vty_out(vty, " IP Reachability: %p\n", &top->value); + + } else { + zlog_debug(" IP Reachability: %c", + (uint8_t)ntohs(top->prefix)); + zlog_debug(" IP Reachability: %p", &top->value); + } + return BGP_TLV_SIZE(tlvh); +} + +static uint16_t show_vty_unknown_tlv(struct vty *vty, + struct te_tlv_nlri_header *tlvh) +{ + int i, rtn = 1; + uint8_t *v = (uint8_t *)tlvh; + + if (vty != NULL) { + if (tlvh->nlri_length != 0) { + vty_out(vty, + " Unknown TLV: [type(%#.2x), length(%#.2x)]\n", + tlvh->nlri_type, tlvh->nlri_length); + vty_out(vty, " Dump: [00]"); + rtn = 1; /* initialize end of line counter */ + for (i = 0; i < tlvh->nlri_length; i++) { + vty_out(vty, " %#.2x", v[i]); + if (rtn == 8) { + vty_out(vty, "\n [%.2x]", + i + 1); + rtn = 1; + } else + rtn++; + } + vty_out(vty, "\n"); + } else + vty_out(vty, + " Unknown TLV: [type(%#.2x), length(%#.2x)]\n", + tlvh->nlri_type, tlvh->nlri_length); + } else { + zlog_debug(" Unknown TLV: [type(%#.2x), length(%#.2x)]", + tlvh->nlri_type, tlvh->nlri_length); + } + + return BGP_TLV_HDR_SIZE; +} +/*--------------- ---------Main Show function--------------------------------- + */ + +int show_bgp_mpreach_print_detail(struct vty *vty, struct mp_bgpls_nlri *te) +{ + struct te_tlv_nlri_header *tlvh, *next; + uint16_t sum = 0; + + zlog_debug("BGP-LS: Show database TE detail"); + + if (te->header.nlri_type == 0) + return CMD_WARNING; + // tlvh->nlri_type = te->header.nlri_type; + tlvh = &te->header; + + for (; sum < te->header.nlri_length; + tlvh = (next ? next : BGP_TLV_HDR_NEXT(tlvh))) { + next = NULL; + switch (tlvh->nlri_type) { + case BGP_NLRI_TLV_LOCAL_NODE_DESCRIPTORS: + sum += show_vty_local_node_descriptors(vty, tlvh); + break; + case BGP_NLRI_TLV_REMOTE_NODE_DESCRIPTORS: + sum += show_vty_remote_node_descriptors(vty, tlvh); + break; + case BGP_NLRI_TLV_LINK_LOCAL_REMOTE_IDENTIFIERS: + sum += show_vty_subtlv_llri(vty, tlvh); + break; + case BGP_NLRI_TLV_IPV4_INTERFACE_ADDRESS: + sum += show_vty_ipv4_interface_addr(vty, tlvh); + break; + case BGP_NLRI_TLV_IPV4_NEIGHBOR_ADDRESS: + sum += show_vty_ipv4_neighbor_addr(vty, tlvh); + break; + case BGP_NLRI_TLV_IPV6_INTERFACE_ADDRESS: + sum += show_vty_ipv6_interface_addr(vty, tlvh); + break; + case BGP_NLRI_TLV_IPV6_NEIGHBOR_ADDRESS: + sum += show_vty_ipv6_neighbor_addr(vty, tlvh); + break; + case BGP_NLRI_TLV_MULTI_TOPOLOGY_ID: + sum += show_vty_multi_topology_id(vty, tlvh); + break; + case BGP_NLRI_TLV_OSPF_ROUTE_TYPE: + sum += show_vty_ospf_type_route(vty, tlvh); + break; + case BGP_NLRI_TLV_IP_REACHABILITY_INFORMATION: + sum += show_vty_ip_reachability(vty, tlvh); + break; + default: + sum += show_vty_unknown_tlv(vty, tlvh); + break; + } + } + return CMD_SUCCESS; +} + +DEFUN(show_ip_bgp_mpreach_database, show_ip_bgp_mpreach_database_cmd, + "show ip bgp mp_reach database", + SHOW_STR IP_STR BGP_STR + "Link State Information: BGP-LS Attributes\n" + "Database of BGP-LS Attributes\n") +{ + return 0; +} + +DEFUN(show_ip_bgp_mpreach_database_detail, + show_ip_bgp_mpreach_database_detail_cmd, + "show ip bgp mp_reach database detail", + SHOW_STR IP_STR BGP_STR + "Link State Information: BGP-LS Attributes\n" + "Database of BGP-LS Attributes\n" + "Database detail of BGP-LS Attributes\n") +{ + struct bgp *bgp; + struct bgp_table *table; + struct bgp_node *rn; + struct bgp_node *rm; + struct attr *attr; + int rd_header; + int header = 1; + + bgp = bgp_get_default(); + if (bgp == NULL) { + vty_out(vty, "No BGP process is configured\n"); + return CMD_WARNING; + } + + for (rn = bgp_table_top(bgp->rib[AFI_LINK_STATE][SAFI_LINK_STATE]); rn; + rn = bgp_route_next(rn)) { + + if ((table = rn->info) != NULL) { + rd_header = 1; + + for (rm = bgp_table_top(table); rm; + rm = bgp_route_next(rm)) + if ((attr = rm->info) != NULL) { + if (header) { + vty_out(vty, + "BGP table version is 0, local router ID is %s\n", + inet_ntoa( + bgp->router_id)); + vty_out(vty, + "Status codes: s suppressed, d damped, h history, * valid, > best, i - internal\n"); + vty_out(vty, + "Origin codes: i - IGP, e - EGP, ? - incomplete\n\n"); + header = 0; + } + + if (rd_header) { + show_bgp_mpreach_print_detail( + vty, + attr->mp_bgpls_nlri); + } + } + } + } + + return CMD_SUCCESS; +} diff --git a/bgpd/bgp_lsdb.c b/bgpd/bgp_lsdb.c new file mode 100644 index 000000000000..404abc14de11 --- /dev/null +++ b/bgpd/bgp_lsdb.c @@ -0,0 +1,471 @@ +/* + * This is an implementation of BGP Link State as per RFC 7752 + * + * Copyright (C) 2020 Orange http://www.orange.com + * + * This program 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 of the License, or (at your option) + * any later version. + * + * This program 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 this program; see the file COPYING; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include + +#include "prefix.h" +#include "table.h" +#include "memory.h" +#include "log.h" +#include "vty.h" +#include "stream.h" +#include "jhash.h" + +#include "bgpd/bgp_attr.h" +#include "bgpd/bgpd.h" +#include "bgpd/bgp_lsdb.h" +#include "bgpd/bgp_ls.h" + +/* Lock LS. */ +struct bgp_ls *bgp_ls_lock(struct bgp_ls *ls) +{ + ls->lock++; + return ls; +} + +/* Unlock LS. */ +void bgp_ls_unlock(struct bgp_ls **ls) +{ + /* This is sanity check. */ + if (!ls || !*ls) + return; + + (*ls)->lock--; + + assert((*ls)->lock >= 0); + + if ((*ls)->lock == 0) { + // bgp_ls_free(*ls); + *ls = NULL; + } +} + +struct bgp_lsdb *bgp_lsdb_new() +{ + struct bgp_lsdb *new; + + new = XCALLOC(MTYPE_BGP_LSDB, sizeof(struct bgp_lsdb)); + bgp_lsdb_init(new); + + return new; +} + +void bgp_lsdb_init(struct bgp_lsdb *lsdb) +{ + int i; + + for (i = BGP_LS_MIN_NLRI_TYPE; i < BGP_LS_MIN_NLRI_TYPE; i++) + lsdb->type[i].db = route_table_init(); +} + +void bgp_lsdb_free(struct bgp_lsdb *lsdb) +{ + bgp_lsdb_cleanup(lsdb); + XFREE(MTYPE_BGP_LSDB, lsdb); +} + +void bgp_lsdb_cleanup(struct bgp_lsdb *lsdb) +{ + int i; + + assert(lsdb); + assert(lsdb->total == 0); + + bgp_lsdb_delete_all(lsdb); + + for (i = BGP_LS_MIN_NLRI_TYPE; i < BGP_LS_MIN_NLRI_TYPE; i++) + route_table_finish(lsdb->type[i].db); +} + +/*Add attribute into a buffer*/ +struct bgp_ls *ls_attr_node_set(struct attr *attr) +{ + struct bgp_ls *ls; + + if (!attr) + return NULL; + // if (!attr->mp_bgpls_nlri) + // return NULL; + if (!attr->link_state_attr) + return NULL; + + ls = XCALLOC(MTYPE_BGP_LSDB, sizeof(struct bgp_ls)); + + /* TODO: alloc / free */ + ls->node = XCALLOC(MTYPE_BGP_LSDB, sizeof(struct link_state_node_nlri)); + + /*--------mp_bgpls_nlri & mp_bgpls_nlri------------*/ + ls->header = &attr->mp_bgpls_nlri->header; + + ls->node->proto_id = attr->mp_bgpls_nlri->ext_hdr.proto_id; + ls->node->nlri_identifier = + attr->mp_bgpls_nlri->ext_hdr.nlri_identifier; + ls->node->local_node = attr->mp_bgpls_nlri->local_node; + /*---------------link_state-------------------*/ + ls->node->mid = attr->mp_bgpls_nlri->mid; + ls->node->nfb = &attr->link_state_attr->nfb; + ls->node->onp = attr->link_state_attr->onp; + ls->node->nn = attr->link_state_attr->nn; + ls->node->iiai = attr->link_state_attr->iiai; + ls->node->i4ridofln = &attr->link_state_attr->i4ridofln; + ls->node->i6ridofln = &attr->link_state_attr->i6ridofln; + ls->node->i4ridofrn = &attr->link_state_attr->i4ridofrn; + ls->node->i6ridofrn = &attr->link_state_attr->i6ridofrn; + + return ls; +} + +struct bgp_ls *ls_attr_link_set(struct attr *attr) +{ + struct bgp_ls *ls; + + if (!attr) + return NULL; + + ls = XCALLOC(MTYPE_BGP_LSDB, sizeof(struct bgp_ls)); + /*--------mp_bgpls_nlri & mp_bgpls_nlri------------*/ + ls->header = &attr->mp_bgpls_nlri->header; + ls->link->proto_id = attr->mp_bgpls_nlri->ext_hdr.proto_id; + ls->link->nlri_identifier = + attr->mp_bgpls_nlri->ext_hdr.nlri_identifier; + ls->link->local_node = attr->mp_bgpls_nlri->local_node; + ls->link->remote_node = attr->mp_bgpls_nlri->remote_node; + ls->link->llri = &attr->mp_bgpls_nlri->llri; + ls->link->i4ia = &attr->mp_bgpls_nlri->i4ia; + ls->link->i4na = &attr->mp_bgpls_nlri->i4na; + ls->link->i6ia = &attr->mp_bgpls_nlri->i6ia; + ls->link->i6na = &attr->mp_bgpls_nlri->i6na; + ls->link->mid = attr->mp_bgpls_nlri->mid; + /*---------------link_state-------------------*/ + ls->link->i4ridofln = &attr->link_state_attr->i4ridofln; + ls->link->i6ridofln = &attr->link_state_attr->i6ridofln; + ls->link->i4ridofrn = &attr->link_state_attr->i4ridofrn; + ls->link->i6ridofrn = &attr->link_state_attr->i6ridofrn; + ls->link->agc = &attr->link_state_attr->agc; + ls->link->mlb = &attr->link_state_attr->mlb; + ls->link->mrlb = &attr->link_state_attr->mrlb; + ls->link->urb = &attr->link_state_attr->urb; + ls->link->tdm = &attr->link_state_attr->tdm; + ls->link->lpt = &attr->link_state_attr->lpt; + ls->link->mpm = &attr->link_state_attr->mpm; + ls->link->igpm = attr->link_state_attr->igpm; + ls->link->srlg = attr->link_state_attr->srlg; + ls->link->ola = attr->link_state_attr->ola; + ls->link->lna = attr->link_state_attr->lna; + + return ls; +} + +struct bgp_ls *ls_attr_ipv4_prefix_set(struct attr *attr) +{ + struct bgp_ls *ls; + + if (!attr) + return NULL; + + ls = XCALLOC(MTYPE_BGP_LSDB, sizeof(struct bgp_ls)); + /*--------mp_bgpls_nlri & mp_bgpls_nlri------------*/ + ls->ipv4_prefix->header = &attr->mp_bgpls_nlri->header; + ls->ipv4_prefix->proto_id = attr->mp_bgpls_nlri->ext_hdr.proto_id; + ls->node->nlri_identifier = + attr->mp_bgpls_nlri->ext_hdr.nlri_identifier; + ls->ipv4_prefix->local_node = attr->mp_bgpls_nlri->local_node; + ls->ipv4_prefix->mid = attr->mp_bgpls_nlri->mid; + ls->ipv4_prefix->ort = &attr->mp_bgpls_nlri->ort; + ls->ipv4_prefix->ipreach = attr->mp_bgpls_nlri->ipreach; + /*---------------link_state-------------------*/ + ls->ipv4_prefix->ifl = &attr->link_state_attr->ifl; + ls->ipv4_prefix->rt = attr->link_state_attr->rt; + ls->ipv4_prefix->et = attr->link_state_attr->et; + ls->ipv4_prefix->pm = &attr->link_state_attr->pm; + ls->ipv4_prefix->ofa = &attr->link_state_attr->ofa; + ls->ipv4_prefix->opa = attr->link_state_attr->opa; + + return ls; +} + +struct bgp_ls *ls_attr_ipv6_prefix_set(struct attr *attr) +{ + struct bgp_ls *ls; + + if (!attr) + return NULL; + + ls = XCALLOC(MTYPE_BGP_LSDB, sizeof(struct bgp_ls)); + /*--------mp_bgpls_nlri & mp_bgpls_nlri------------*/ + ls->ipv6_prefix->header = &attr->mp_bgpls_nlri->header; + ls->ipv6_prefix->proto_id = attr->mp_bgpls_nlri->ext_hdr.proto_id; + ls->ipv6_prefix->nlri_identifier = + attr->mp_bgpls_nlri->ext_hdr.nlri_identifier; + ls->ipv6_prefix->local_node = attr->mp_bgpls_nlri->local_node; + ls->ipv6_prefix->mid = attr->mp_bgpls_nlri->mid; + ls->ipv6_prefix->ort = &attr->mp_bgpls_nlri->ort; + ls->ipv6_prefix->ipreach = attr->mp_bgpls_nlri->ipreach; + /*--------------------link_state--------------------*/ + ls->ipv6_prefix->ifl = &attr->link_state_attr->ifl; + ls->ipv6_prefix->rt = attr->link_state_attr->rt; + ls->ipv6_prefix->et = attr->link_state_attr->et; + ls->ipv6_prefix->pm = &attr->link_state_attr->pm; + ls->ipv6_prefix->ofa = &attr->link_state_attr->ofa; + ls->ipv6_prefix->opa = attr->link_state_attr->opa; + + return ls; +} + +struct bgp_ls *ls_attr_set(struct attr *attr) +{ + struct bgp_ls *bgp_ls; + + bgp_ls = ls_attr_node_set(attr); + // ls_attr_ipv6_prefix_set(attr); + + return bgp_ls; +} + +// static void bgp_lsdb_delete_entry(struct bgp_lsdb *lsdb, struct route_node +// *rn) +//{ +// struct bgp_ls *ls = rn->info; +// if (!ls) +// return; +// assert(rn->table == lsdb->type[ls->header->nlri_type].db); +// lsdb->type[ls->header->nlri_type].count--; +// lsdb->total--; +// rn->info = NULL; +// route_unlock_node(rn); +// bgp_ls_unlock(&ls); /* lsdb */ +// return; +//} + +/* Add new LS to lsdb. */ +void bgp_lsdb_add(struct bgp_lsdb *lsdb, struct bgp_ls *ls) +{ + struct route_table *table; + // struct attr attr; + struct route_node *rn; + int i; + + if (!ls) + return; + + for (i = BGP_LS_MIN_NLRI_TYPE; i <= BGP_LS_MAX_NLRI_TYPE; i++) { + // table = lsdb->type[ls->header->nlri_type].db; + table = lsdb->type[i].db; + + /* TODO should not happen */ + if (!table) + continue; + + rn = route_node_get(table, (struct prefix *)&ls); + + /* nothing to do? */ + if (rn->info && rn->info == ls) { + route_unlock_node(rn); + return; + } + + /* purge old entry? */ + if (rn->info) + bgp_lsdb_delete_entry(lsdb, rn); + + lsdb->type[ls->header->nlri_type].count++; + lsdb->total++; + rn->info = bgp_ls_lock(ls); /* lsdb */ + } +} + +void bgp_lsdb_delete(struct bgp_lsdb *lsdb, struct bgp_ls *ls) +{ + struct route_table *table; + struct route_node *rn; + + if (!lsdb) { + zlog_warn("%s: Called with NULL LSDB", __func__); + if (ls) + zlog_warn("LSA[Type%d:%d]: LS %d, lsa->lsdb %d", 0, 0, + 0, 0); + + return; + } + + if (!ls) { + zlog_warn("%s: Called with NULL LS", __func__); + return; + } + + assert(ls->header->nlri_type < BGP_LS_MAX_NLRI_TYPE); + table = lsdb->type[ls->header->nlri_type].db; + // ls_attr_set (&attr, ls); + if ((rn = route_node_lookup(table, (struct prefix *)&ls))) { + if (rn->info == ls) + bgp_lsdb_delete_entry(lsdb, rn); + route_unlock_node(rn); /* route_node_lookup */ + } +} + +void bgp_lsdb_delete_all(struct bgp_lsdb *lsdb) +{ + struct route_table *table; + struct route_node *rn; + int i; + + for (i = BGP_LS_MIN_NLRI_TYPE; i < BGP_LS_MAX_NLRI_TYPE; i++) { + table = lsdb->type[i].db; + for (rn = route_top(table); rn; rn = route_next(rn)) + if (rn->info != NULL) + bgp_lsdb_delete_entry(lsdb, rn); + } +} + +struct bgp_ls *bgp_lsdb_lookup(struct bgp_lsdb *lsdb, struct bgp_ls *ls) +{ + struct route_table *table; + struct attr attr; + struct route_node *rn; + struct bgp_ls *find; + + table = lsdb->type[ls->header->nlri_type].db; + ls_attr_set(&attr); + rn = route_node_lookup(table, (struct prefix *)&attr); + if (rn) { + find = rn->info; + route_unlock_node(rn); + return find; + } + return NULL; +} + +struct bgp_ls *bgp_lsdb_lookup_by_id(struct bgp_lsdb *lsdb, uint8_t type, + struct in_addr id, + struct in_addr adv_router) +{ + struct route_table *table; + struct attr attr; + struct route_node *rn; + struct bgp_ls *find; + + table = lsdb->type[type].db; + + memset(&attr, 0, sizeof(struct attr)); + // attr.family = 0; + // attr.prefixlen = 64; + // attr.id = id; + // attr.adv_router = adv_router; + + rn = route_node_lookup(table, (struct prefix *)&attr); + if (rn) { + find = rn->info; + route_unlock_node(rn); + return find; + } + + return NULL; +} + +struct bgp_ls *bgp_lsdb_lookup_by_id_next(struct bgp_lsdb *lsdb, uint8_t type, + struct in_addr id, + struct in_addr adv_router, int first) +{ + struct route_table *table; + struct bgp_ls ls; + struct route_node *rn; + struct bgp_ls *find; + + table = lsdb->type[type].db; + + memset(&ls, 0, sizeof(struct bgp_ls)); + /* + attr.family = 0; + attr.prefixlen = 64; + attr.id = id; + attr.adv_router = adv_router; + */ + + if (first) + rn = route_top(table); + else { + if ((rn = route_node_lookup(table, (struct prefix *)&ls)) == + NULL) + return NULL; + rn = route_next(rn); + } + + for (; rn; rn = route_next(rn)) + if (rn->info) + break; + + if (rn && rn->info) { + find = rn->info; + route_unlock_node(rn); + return find; + } + return NULL; +} + +unsigned long bgp_lsdb_count_all(struct bgp_lsdb *lsdb) +{ + return lsdb->total; +} + +unsigned long bgp_lsdb_count(struct bgp_lsdb *lsdb, int type) +{ + return lsdb->type[type].count; +} + +void bgp_lsdb_delete_entry(struct bgp_lsdb *lsdb, struct route_node *rn) +{ + struct bgp_ls *ls = rn->info; + + if (!ls) + return; + + lsdb->total--; + rn->info = NULL; + route_unlock_node(rn); + + return; +} + +// unsigned long bgp_lsdb_count_all(struct bgp_lsdb *lsdb) +//{ +// return lsdb->total; +//} +// unsigned long bgp_lsdb_count(struct bgp_lsdb *lsdb, int type) +//{ +// return lsdb->type[type].count; +//} + +/* +unsigned long +bgp_lsdb_count_self (struct bgp_lsdb *lsdb, int type) +{ + return lsdb->type[type].count_self; +} +*/ + +unsigned int bgp_lsdb_checksum(struct bgp_lsdb *lsdb, int type) +{ + return lsdb->type[type].checksum; +} + +unsigned long bgp_lsdb_isempty(struct bgp_lsdb *lsdb) +{ + return (lsdb->total == 0); +} diff --git a/bgpd/bgp_lsdb.h b/bgpd/bgp_lsdb.h new file mode 100644 index 000000000000..e0d43ede1c7f --- /dev/null +++ b/bgpd/bgp_lsdb.h @@ -0,0 +1,185 @@ +/* + * This is an implementation of BGP Link State as per RFC 7752 + * + * Copyright (C) 2020 Orange http://www.orange.com + * + * This program 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 of the License, or (at your option) + * any later version. + * + * This program 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 this program; see the file COPYING; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef _BGP_LS_LSDB_H +#define _BGP_LS_LSDB_H + +#define BGP_LS_MIN_NLRI_TYPE 1 +#define BGP_LS_MAX_NLRI_TYPE 4 + +/* BGP LSDB structure. */ +struct bgp_lsdb { + struct { + unsigned long count; + unsigned long count_self; + unsigned int checksum; + struct route_table *db; + } type[BGP_LS_MAX_NLRI_TYPE]; + unsigned long total; +}; + +/* Macros. */ +#define LSDB_LOOP(T, N, L) \ + if ((T) != NULL) \ + for ((N) = route_top((T)); ((N)); ((N)) = route_next((N))) \ + if (((L) = (N)->info)) + +#define NODE_LSDB(A) ((A)->lsdb->type[LINK_STATE_NODE_NLRI].db) +#define LINK_LSDB(A) ((A)->lsdb->type[LINK_STATE_LINK_NLRI].db) +#define IPV4_TOPOLOGY_PREFIX_LSDB(A) \ + ((A)->lsdb->type[LINK_STATE_IPV4_TOPOLOGY_PREFIX_NLRI].db) +#define IPV6_TOPOLOGY_PREFIX_LSDB(A) \ + ((A)->lsdb->type[LINK_STATE_IPV6_TOPOLOGY_PREFIX_NLRI].db) + +struct link_state_node_nlri { + /****MP_REACH_NLRI****/ + struct te_tlv_nlri_header *header; + uint8_t proto_id; + uint64_t nlri_identifier; + struct bgp_nlri_tlv_lrnd *local_node; + /****LINK_STATE****/ + struct bgp_nlri_tlv_mt_id *mid; + struct bgp_nlri_tlv_nfb *nfb; + struct bgp_nlri_tlv_onp *onp; + struct bgp_nlri_tlv_nn *nn; + struct bgp_nlri_tlv_iiai *iiai; + struct bgp_nlri_tlv_i4_rid_lrn *i4ridofln; + struct bgp_nlri_tlv_i6_rid_lrn *i6ridofln; + struct bgp_nlri_tlv_i4_rid_lrn *i4ridofrn; + struct bgp_nlri_tlv_i6_rid_lrn *i6ridofrn; +}; + +struct link_state_link_nlri { + /****MP_REACH_NLRI****/ + struct te_tlv_nlri_header *header; + uint8_t proto_id; + uint64_t nlri_identifier; + struct bgp_nlri_tlv_lrnd *local_node; + struct bgp_nlri_tlv_lrnd *remote_node; + struct bgp_nlri_tlv_llri *llri; + struct bgp_nlri_tlv_i4i_addr *i4ia; + struct bgp_nlri_tlv_i4n_addr *i4na; + struct bgp_nlri_tlv_i6i_addr *i6ia; + struct bgp_nlri_tlv_i6n_addr *i6na; + struct bgp_nlri_tlv_mt_id *mid; + /****LINK_STATE****/ + struct bgp_nlri_tlv_i4_rid_lrn *i4ridofln; + struct bgp_nlri_tlv_i6_rid_lrn *i6ridofln; + struct bgp_nlri_tlv_i4_rid_lrn *i4ridofrn; + struct bgp_nlri_tlv_i6_rid_lrn *i6ridofrn; + struct bgp_nlri_tlv_agc *agc; + struct bgp_nlri_tlv_max_link_bw *mlb; + struct bgp_nlri_tlv_max_rsv_link_bw *mrlb; + struct bgp_nlri_tlv_ursv_bw *urb; + struct bgp_nlri_tlv_tdm *tdm; + struct bgp_nlri_tlv_link_pt *lpt; + struct bgp_nlri_tlv_mpls_pm *mpm; + struct bgp_nlri_tlv_metric *igpm; + struct bgp_nlri_tlv_srlg *srlg; + struct bgp_nlri_tlv_ola *ola; + struct bgp_nlri_tlv_lna *lna; +}; + +struct link_state_ipv4_nlri { + /****MP_REACH_NLRI****/ + struct te_tlv_nlri_header *header; + uint8_t proto_id; + uint64_t nlri_identifier; + struct bgp_nlri_tlv_lrnd *local_node; // + struct bgp_nlri_tlv_mt_id *mid; + struct bgp_nlri_tlv_ort *ort; + struct bgp_nlri_tlv_ip_reach *ipreach; + /****LINK_STATE****/ + struct bgp_nlri_tlv_igp_flags *ifl; + struct bgp_nlri_tlv_route_tag *rt; + struct bgp_nlri_tlv_extended_tag *et; + struct bgp_nlri_tlv_prefix_metric *pm; + struct bgp_nlri_tlv_ospf_fowarding_adress *ofa; + struct bgp_nlri_tlv_opa *opa; +}; + +struct link_state_ipv6_nlri { + /****MP_REACH_NLRI****/ + struct te_tlv_nlri_header *header; + uint8_t proto_id; + uint64_t nlri_identifier; + struct bgp_nlri_tlv_lrnd *local_node; + struct bgp_nlri_tlv_mt_id *mid; + struct bgp_nlri_tlv_ort *ort; + struct bgp_nlri_tlv_ip_reach *ipreach; + /****LINK_STATE****/ + struct bgp_nlri_tlv_igp_flags *ifl; + struct bgp_nlri_tlv_route_tag *rt; + struct bgp_nlri_tlv_extended_tag *et; + struct bgp_nlri_tlv_prefix_metric *pm; + struct bgp_nlri_tlv_ospf_fowarding_adress *ofa; + struct bgp_nlri_tlv_opa *opa; +}; + +struct bgp_ls { + struct te_tlv_nlri_header *header; + struct link_state_node_nlri *node; + struct link_state_link_nlri *link; + struct link_state_ipv4_nlri *ipv4_prefix; + struct link_state_ipv6_nlri *ipv6_prefix; + + /* All of reference count, also lock to remove. */ + int lock; + + /* References to this LSA in neighbor retransmission lists*/ + int retransmit_counter; + + /* Refreshement List or Queue */ + int refresh_list; +}; + +/* BGP LSDB related functions. */ +extern void bgp_ls_unlock(struct bgp_ls **ls); +extern struct bgp_ls *bgp_ls_lock(struct bgp_ls *ls); +extern struct bgp_lsdb *bgp_lsdb_new(void); +extern void bgp_lsdb_init(struct bgp_lsdb *); +extern void bgp_lsdb_free(struct bgp_lsdb *); +extern void bgp_lsdb_cleanup(struct bgp_lsdb *); +extern void bgp_ls_prefix_set(struct attr *lp, struct bgp_ls *ls); +extern void bgp_lsdb_add(struct bgp_lsdb *, struct bgp_ls *); +extern void bgp_lsdb_delete(struct bgp_lsdb *, struct bgp_ls *); +extern void bgp_lsdb_delete_all(struct bgp_lsdb *); +extern void bgp_lsdb_delete_entry(struct bgp_lsdb *lsdb, struct route_node *rn); + +extern struct bgp_ls *ls_attr_node_set(struct attr *attr); +extern struct bgp_ls *ls_attr_link_set(struct attr *attr); +extern struct bgp_ls *ls_attr_ipv4_prefix_set(struct attr *attr); +extern struct bgp_ls *ls_attr_ipv6_prefix_set(struct attr *attr); +extern struct bgp_ls *ls_attr_set(struct attr *attr); + +extern void bgp_lsdb_clean_stat(struct bgp_lsdb *lsdb); +extern struct bgp_ls *bgp_lsdb_lookup(struct bgp_lsdb *, struct bgp_ls *); +extern struct bgp_ls *bgp_lsdb_lookup_by_id(struct bgp_lsdb *, uint8_t, + struct in_addr, struct in_addr); +extern struct bgp_ls *bgp_lsdb_lookup_by_id_next(struct bgp_lsdb *, uint8_t, + struct in_addr, struct in_addr, + int); +extern unsigned long bgp_lsdb_count_all(struct bgp_lsdb *); +extern unsigned long bgp_lsdb_count(struct bgp_lsdb *, int); +extern unsigned long bgp_lsdb_count_self(struct bgp_lsdb *, int); +extern unsigned int bgp_lsdb_checksum(struct bgp_lsdb *, int); +extern unsigned long bgp_lsdb_isempty(struct bgp_lsdb *); + +#endif /* _BGP_LS_LSDB_H */ diff --git a/bgpd/bgp_memory.c b/bgpd/bgp_memory.c index ced3e1890e0d..239a7057cf10 100644 --- a/bgpd/bgp_memory.c +++ b/bgpd/bgp_memory.c @@ -143,3 +143,5 @@ DEFINE_MTYPE(BGPD, BGP_NOTIFICATION, "BGP Notification Message"); DEFINE_MTYPE(BGPD, BGP_ORR_GROUP, "BGP Optimal Route Reflection Group"); DEFINE_MTYPE(BGPD, BGP_ORR_GROUP_NAME, "BGP Optimal Route Reflection Group Name"); + +DEFINE_MTYPE(BGPD, BGP_LSDB, "BGP Link State Data Base"); diff --git a/bgpd/bgp_memory.h b/bgpd/bgp_memory.h index 990c6e1faaec..2250f795c1fd 100644 --- a/bgpd/bgp_memory.h +++ b/bgpd/bgp_memory.h @@ -140,4 +140,7 @@ DECLARE_MTYPE(BGP_NOTIFICATION); DECLARE_MTYPE(BGP_ORR_GROUP); DECLARE_MTYPE(BGP_ORR_GROUP_NAME); +/* BGP-LS */ +DECLARE_MTYPE(BGP_LSDB); + #endif /* _QUAGGA_BGP_MEMORY_H */ diff --git a/bgpd/bgp_open.c b/bgpd/bgp_open.c index 79c54dd32d63..fca436d3bd7a 100644 --- a/bgpd/bgp_open.c +++ b/bgpd/bgp_open.c @@ -167,6 +167,12 @@ void bgp_capability_vty_out(struct vty *vty, struct peer *peer, bool use_json, "capabilityErrorMultiProtocolAfi", "L2VPN"); break; + case AFI_LINK_STATE: + json_object_string_add( + json_cap, + "capabilityErrorMultiProtocolAfi", + "Link State"); + break; default: json_object_int_add( json_cap, @@ -217,6 +223,18 @@ void bgp_capability_vty_out(struct vty *vty, struct peer *peer, bool use_json, "capabilityErrorMultiProtocolSafi", "flowspec"); break; + case SAFI_LINK_STATE: + json_object_string_add( + json_cap, + "capabilityErrorMultiProtocolSafi", + "Link State"); + break; + case SAFI_LINK_STATE_VPN: + json_object_string_add( + json_cap, + "capabilityErrorMultiProtocolSafi", + "Link State VPN"); + break; default: json_object_int_add( json_cap, @@ -237,6 +255,9 @@ void bgp_capability_vty_out(struct vty *vty, struct peer *peer, bool use_json, case AFI_L2VPN: vty_out(vty, "AFI L2VPN, "); break; + case AFI_LINK_STATE: + vty_out(vty, "AFI Link State, "); + break; default: vty_out(vty, "AFI Unknown %d, ", ntohs(mpc.afi)); @@ -264,6 +285,12 @@ void bgp_capability_vty_out(struct vty *vty, struct peer *peer, bool use_json, case SAFI_EVPN: vty_out(vty, "SAFI EVPN"); break; + case SAFI_LINK_STATE: + vty_out(vty, "SAFI LINK STATE"); + break; + case SAFI_LINK_STATE_VPN: + vty_out(vty, "SAFI LINK STATE VPN"); + break; default: vty_out(vty, "SAFI Unknown %d ", mpc.safi); @@ -1405,19 +1432,21 @@ int bgp_open_option_parse(struct peer *peer, uint16_t length, error. */ if (*mp_capability && !CHECK_FLAG(peer->flags, PEER_FLAG_OVERRIDE_CAPABILITY)) { - if (!peer->afc_nego[AFI_IP][SAFI_UNICAST] - && !peer->afc_nego[AFI_IP][SAFI_MULTICAST] - && !peer->afc_nego[AFI_IP][SAFI_LABELED_UNICAST] - && !peer->afc_nego[AFI_IP][SAFI_MPLS_VPN] - && !peer->afc_nego[AFI_IP][SAFI_ENCAP] - && !peer->afc_nego[AFI_IP][SAFI_FLOWSPEC] - && !peer->afc_nego[AFI_IP6][SAFI_UNICAST] - && !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_FLOWSPEC] - && !peer->afc_nego[AFI_L2VPN][SAFI_EVPN]) { + if (!peer->afc_nego[AFI_IP][SAFI_UNICAST] && + !peer->afc_nego[AFI_IP][SAFI_MULTICAST] && + !peer->afc_nego[AFI_IP][SAFI_LABELED_UNICAST] && + !peer->afc_nego[AFI_IP][SAFI_MPLS_VPN] && + !peer->afc_nego[AFI_IP][SAFI_ENCAP] && + !peer->afc_nego[AFI_IP][SAFI_FLOWSPEC] && + !peer->afc_nego[AFI_IP6][SAFI_UNICAST] && + !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_FLOWSPEC] && + !peer->afc_nego[AFI_L2VPN][SAFI_EVPN] && + !peer->afc_nego[AFI_LINK_STATE][SAFI_LINK_STATE] && + !peer->afc_nego[AFI_LINK_STATE][SAFI_LINK_STATE_VPN]) { flog_err(EC_BGP_PKT_OPEN, "%s [Error] Configured AFI/SAFIs do not overlap with received MP capabilities", peer->host); diff --git a/bgpd/bgp_packet.c b/bgpd/bgp_packet.c index 5d4cf2a6aaad..697d4d986796 100644 --- a/bgpd/bgp_packet.c +++ b/bgpd/bgp_packet.c @@ -37,6 +37,7 @@ #include "queue.h" #include "filter.h" #include "lib_errors.h" +#include "config.h" #include "bgpd/bgpd.h" #include "bgpd/bgp_table.h" @@ -1709,6 +1710,10 @@ static int bgp_open_receive(struct peer *peer, bgp_size_t size) peer->afc[AFI_L2VPN][SAFI_EVPN]; peer->afc_nego[AFI_IP6][SAFI_FLOWSPEC] = peer->afc[AFI_IP6][SAFI_FLOWSPEC]; + peer->afc_nego[AFI_LINK_STATE][SAFI_LINK_STATE] = + peer->afc[AFI_LINK_STATE][SAFI_LINK_STATE]; + peer->afc_nego[AFI_LINK_STATE][SAFI_LINK_STATE_VPN] = + peer->afc[AFI_LINK_STATE][SAFI_LINK_STATE_VPN]; } /* Verify valid local address present based on negotiated diff --git a/bgpd/bgp_route.c b/bgpd/bgp_route.c index 95493c11f850..26d58023142b 100644 --- a/bgpd/bgp_route.c +++ b/bgpd/bgp_route.c @@ -4598,10 +4598,11 @@ int bgp_update(struct peer *peer, const struct prefix *p, uint32_t addpath_id, /* Nexthop reachability check - for unicast and * labeled-unicast.. */ - if (((afi == AFI_IP || afi == AFI_IP6) - && (safi == SAFI_UNICAST || safi == SAFI_LABELED_UNICAST)) - || (safi == SAFI_EVPN && - bgp_evpn_is_prefix_nht_supported(p))) { + if (((afi == AFI_IP || afi == AFI_IP6 || + afi == AFI_LINK_STATE) && + (safi == SAFI_UNICAST || safi == SAFI_LABELED_UNICAST)) || + (safi == SAFI_EVPN && + bgp_evpn_is_prefix_nht_supported(p))) { if (safi != SAFI_EVPN && peer->sort == BGP_PEER_EBGP && peer->ttl == BGP_DEFAULT_TTL && !CHECK_FLAG(peer->flags, diff --git a/bgpd/bgp_updgrp_adv.c b/bgpd/bgp_updgrp_adv.c index cbd5d05922f9..cf6bd9246e98 100644 --- a/bgpd/bgp_updgrp_adv.c +++ b/bgpd/bgp_updgrp_adv.c @@ -814,7 +814,7 @@ void subgroup_default_originate(struct update_subgroup *subgrp, int withdraw) afi = SUBGRP_AFI(subgrp); safi = SUBGRP_SAFI(subgrp); - if (!(afi == AFI_IP || afi == AFI_IP6)) + if (!(afi == AFI_IP || afi == AFI_IP6 || afi == AFI_LINK_STATE)) return; if (safi == SAFI_LABELED_UNICAST) diff --git a/bgpd/bgp_vty.c b/bgpd/bgp_vty.c index 8ea9c1996bc6..33b5efc39e32 100644 --- a/bgpd/bgp_vty.c +++ b/bgpd/bgp_vty.c @@ -202,6 +202,16 @@ static enum node_type bgp_node_type(afi_t afi, safi_t safi) } case AFI_L2VPN: return BGP_EVPN_NODE; + case AFI_LINK_STATE: + switch (safi) { + case SAFI_LINK_STATE: + return BGP_LS_NODE; + case SAFI_LINK_STATE_VPN: + return BGP_LS_NODE; + default: + return BGP_IPV4_NODE; + } + break; case AFI_UNSPEC: case AFI_MAX: // We should never be here but to clarify the switch statement.. @@ -243,6 +253,11 @@ static const char *get_afi_safi_vty_str(afi_t afi, safi_t safi) } else if (afi == AFI_L2VPN) { if (safi == SAFI_EVPN) return "L2VPN EVPN"; + } else if (afi == AFI_LINK_STATE) { + if (safi == SAFI_LINK_STATE) + return "Link State"; + if (safi == SAFI_LINK_STATE_VPN) + return "Link State VPN"; } return "Unknown"; @@ -285,6 +300,11 @@ static const char *get_afi_safi_json_str(afi_t afi, safi_t safi) } else if (afi == AFI_L2VPN) { if (safi == SAFI_EVPN) return "l2VpnEvpn"; + } else if (afi == AFI_LINK_STATE) { + if (safi == SAFI_LINK_STATE) + return "linkState"; + if (safi == SAFI_LINK_STATE_VPN) + return "linkStateVPN"; } return "Unknown"; @@ -375,6 +395,9 @@ afi_t bgp_node_afi(struct vty *vty) case BGP_EVPN_NODE: afi = AFI_L2VPN; break; + case BGP_LS_NODE: + afi = AFI_LINK_STATE; + break; default: afi = AFI_IP; break; @@ -407,6 +430,9 @@ safi_t bgp_node_safi(struct vty *vty) case BGP_FLOWSPECV6_NODE: safi = SAFI_FLOWSPEC; break; + case BGP_LS_NODE: + safi = SAFI_LINK_STATE; + break; default: safi = SAFI_UNICAST; break; @@ -471,6 +497,10 @@ safi_t bgp_vty_safi_from_str(const char *safi_str) safi = SAFI_LABELED_UNICAST; else if (strmatch(safi_str, "flowspec")) safi = SAFI_FLOWSPEC; + else if (strmatch(safi_str, "link-state")) + safi = SAFI_LINK_STATE; + else if (strmatch(safi_str, "link-state-vpn")) + safi = SAFI_LINK_STATE_VPN; return safi; } @@ -566,6 +596,17 @@ static const char *get_bgp_default_af_flag(afi_t afi, safi_t safi) default: return "unknown-afi/safi"; } + break; + case AFI_LINK_STATE: + switch (safi) { + case SAFI_LINK_STATE: + return "link-state"; + case SAFI_LINK_STATE_VPN: + return "link-state-vpn"; + default: + return "unknown-afi/safi"; + } + break; case AFI_UNSPEC: case AFI_MAX: return "unknown-afi/safi"; @@ -9817,6 +9858,17 @@ DEFUN_NOSH (address_family_evpn, return CMD_SUCCESS; } +DEFUN_NOSH(address_family_linkstate, address_family_linkstate_cmd, + "address-family link-state link-state", + "Enter Address Family command mode\n" + BGP_AF_STR + BGP_AF_MODIFIER_STR) +{ + VTY_DECLVAR_CONTEXT(bgp, bgp); + vty->node = BGP_LS_NODE; + return CMD_SUCCESS; +} + DEFUN_NOSH (bgp_segment_routing_srv6, bgp_segment_routing_srv6_cmd, "segment-routing srv6", @@ -9957,7 +10009,8 @@ DEFUN_NOSH (exit_address_family, || vty->node == BGP_IPV6L_NODE || vty->node == BGP_VPNV6_NODE || vty->node == BGP_EVPN_NODE || vty->node == BGP_FLOWSPECV4_NODE - || vty->node == BGP_FLOWSPECV6_NODE) + || vty->node == BGP_FLOWSPECV6_NODE || + vty->node == BGP_LS_NODE) vty->node = BGP_NODE; return CMD_SUCCESS; } @@ -17714,6 +17767,11 @@ static void bgp_config_write_family(struct vty *vty, struct bgp *bgp, afi_t afi, } else if (afi == AFI_L2VPN) { if (safi == SAFI_EVPN) vty_frame(vty, "l2vpn evpn"); + } else if (afi == AFI_LINK_STATE) { + if (safi == SAFI_LINK_STATE) + vty_frame(vty, "link-state link-state"); + else if (safi == SAFI_LINK_STATE_VPN) + vty_frame(vty, "link-state link-state-vpn"); } vty_frame(vty, "\n"); @@ -18225,6 +18283,11 @@ int bgp_config_write(struct vty *vty) /* EVPN configuration. */ bgp_config_write_family(vty, bgp, AFI_L2VPN, SAFI_EVPN); + bgp_config_write_family(vty, bgp, AFI_LINK_STATE, + SAFI_LINK_STATE); + bgp_config_write_family(vty, bgp, AFI_LINK_STATE, + SAFI_LINK_STATE_VPN); + hook_call(bgp_inst_config_write, bgp, vty); #ifdef ENABLE_BGP_VNC @@ -18349,6 +18412,13 @@ static struct cmd_node bgp_srv6_node = { .prompt = "%s(config-router-srv6)# ", }; +static struct cmd_node bgp_ls_node = { + .name = "bgp link-state", + .node = BGP_LS_NODE, + .parent_node = BGP_NODE, + .prompt = "%s(config-router-af-ls)# ", +}; + static void community_list_vty(void); static void bgp_ac_peergroup(vector comps, struct cmd_token *token) @@ -18591,6 +18661,7 @@ void bgp_vty_init(void) install_node(&bgp_flowspecv4_node); install_node(&bgp_flowspecv6_node); install_node(&bgp_srv6_node); + install_node(&bgp_ls_node); /* Install default VTY commands to new nodes. */ install_default(BGP_NODE); @@ -18607,6 +18678,7 @@ void bgp_vty_init(void) install_default(BGP_EVPN_NODE); install_default(BGP_EVPN_VNI_NODE); install_default(BGP_SRV6_NODE); + install_default(BGP_LS_NODE); /* "global bgp inq-limit command */ install_element(CONFIG_NODE, &bgp_inq_limit_cmd); @@ -18736,6 +18808,12 @@ void bgp_vty_init(void) install_element(BGP_IPV6L_NODE, &bgp_maxpaths_ibgp_cluster_cmd); install_element(BGP_IPV6L_NODE, &no_bgp_maxpaths_ibgp_cmd); + + install_element(BGP_LS_NODE, &bgp_maxpaths_ibgp_cmd); + install_element(BGP_LS_NODE, &no_bgp_maxpaths_ibgp_cmd); + install_element(BGP_LS_NODE, &bgp_maxpaths_ibgp_cluster_cmd); + + /* "timers bgp" commands. */ install_element(BGP_NODE, &bgp_timers_cmd); install_element(BGP_NODE, &no_bgp_timers_cmd); @@ -18956,6 +19034,7 @@ void bgp_vty_init(void) install_element(BGP_FLOWSPECV4_NODE, &neighbor_activate_cmd); install_element(BGP_FLOWSPECV6_NODE, &neighbor_activate_cmd); install_element(BGP_EVPN_NODE, &neighbor_activate_cmd); + install_element(BGP_LS_NODE, &neighbor_activate_cmd); /* "no neighbor activate" commands. */ install_element(BGP_NODE, &no_neighbor_activate_hidden_cmd); @@ -18970,6 +19049,7 @@ void bgp_vty_init(void) install_element(BGP_FLOWSPECV4_NODE, &no_neighbor_activate_cmd); install_element(BGP_FLOWSPECV6_NODE, &no_neighbor_activate_cmd); install_element(BGP_EVPN_NODE, &no_neighbor_activate_cmd); + install_element(BGP_LS_NODE, &no_neighbor_activate_cmd); /* "neighbor peer-group" set commands. */ install_element(BGP_NODE, &neighbor_set_peer_group_cmd); @@ -18984,6 +19064,8 @@ void bgp_vty_init(void) &neighbor_set_peer_group_hidden_cmd); install_element(BGP_FLOWSPECV6_NODE, &neighbor_set_peer_group_hidden_cmd); + install_element(BGP_LS_NODE, &neighbor_set_peer_group_hidden_cmd); + /* "no neighbor peer-group unset" commands. */ install_element(BGP_NODE, &no_neighbor_set_peer_group_cmd); @@ -18998,6 +19080,7 @@ void bgp_vty_init(void) &no_neighbor_set_peer_group_hidden_cmd); install_element(BGP_FLOWSPECV6_NODE, &no_neighbor_set_peer_group_hidden_cmd); + install_element(BGP_LS_NODE, &no_neighbor_set_peer_group_hidden_cmd); /* "neighbor softreconfiguration inbound" commands.*/ install_element(BGP_NODE, &neighbor_soft_reconfiguration_hidden_cmd); @@ -19028,6 +19111,8 @@ void bgp_vty_init(void) &no_neighbor_soft_reconfiguration_cmd); install_element(BGP_EVPN_NODE, &neighbor_soft_reconfiguration_cmd); install_element(BGP_EVPN_NODE, &no_neighbor_soft_reconfiguration_cmd); + install_element(BGP_LS_NODE, &neighbor_soft_reconfiguration_cmd); + install_element(BGP_LS_NODE, &no_neighbor_soft_reconfiguration_cmd); /* "neighbor attribute-unchanged" commands. */ install_element(BGP_NODE, &neighbor_attr_unchanged_hidden_cmd); @@ -19048,10 +19133,12 @@ void bgp_vty_init(void) install_element(BGP_VPNV4_NODE, &no_neighbor_attr_unchanged_cmd); install_element(BGP_VPNV6_NODE, &neighbor_attr_unchanged_cmd); install_element(BGP_VPNV6_NODE, &no_neighbor_attr_unchanged_cmd); - install_element(BGP_EVPN_NODE, &neighbor_attr_unchanged_cmd); install_element(BGP_EVPN_NODE, &no_neighbor_attr_unchanged_cmd); + install_element(BGP_LS_NODE, &neighbor_attr_unchanged_cmd); + install_element(BGP_LS_NODE, &no_neighbor_attr_unchanged_cmd); + install_element(BGP_FLOWSPECV4_NODE, &neighbor_attr_unchanged_cmd); install_element(BGP_FLOWSPECV4_NODE, &no_neighbor_attr_unchanged_cmd); install_element(BGP_FLOWSPECV6_NODE, &neighbor_attr_unchanged_cmd); @@ -19084,6 +19171,9 @@ void bgp_vty_init(void) install_element(BGP_EVPN_NODE, &neighbor_nexthop_self_cmd); install_element(BGP_EVPN_NODE, &no_neighbor_nexthop_self_cmd); + install_element(BGP_LS_NODE, &neighbor_nexthop_self_cmd); + install_element(BGP_LS_NODE, &no_neighbor_nexthop_self_cmd); + /* "neighbor next-hop-self force" commands. */ install_element(BGP_NODE, &neighbor_nexthop_self_force_hidden_cmd); install_element(BGP_NODE, &no_neighbor_nexthop_self_force_hidden_cmd); @@ -19131,6 +19221,8 @@ void bgp_vty_init(void) &no_neighbor_nexthop_self_all_hidden_cmd); install_element(BGP_EVPN_NODE, &neighbor_nexthop_self_force_cmd); install_element(BGP_EVPN_NODE, &no_neighbor_nexthop_self_force_cmd); + install_element(BGP_LS_NODE, &neighbor_nexthop_self_force_cmd); + install_element(BGP_LS_NODE, &no_neighbor_nexthop_self_force_cmd); /* "neighbor as-override" commands. */ install_element(BGP_NODE, &neighbor_as_override_hidden_cmd); @@ -19264,6 +19356,19 @@ void bgp_vty_init(void) install_element(BGP_VPNV6_NODE, &no_neighbor_remove_private_as_all_replace_as_cmd); + install_element(BGP_LS_NODE, &neighbor_remove_private_as_cmd); + install_element(BGP_LS_NODE, &no_neighbor_remove_private_as_cmd); + install_element(BGP_LS_NODE, &neighbor_remove_private_as_all_cmd); + install_element(BGP_LS_NODE, &no_neighbor_remove_private_as_all_cmd); + install_element(BGP_LS_NODE, + &neighbor_remove_private_as_replace_as_cmd); + install_element(BGP_LS_NODE, + &no_neighbor_remove_private_as_replace_as_cmd); + install_element(BGP_LS_NODE, + &neighbor_remove_private_as_all_replace_as_cmd); + install_element(BGP_LS_NODE, + &no_neighbor_remove_private_as_all_replace_as_cmd); + /* "neighbor send-community" commands.*/ install_element(BGP_NODE, &neighbor_send_community_hidden_cmd); install_element(BGP_NODE, &neighbor_send_community_type_hidden_cmd); @@ -19302,6 +19407,11 @@ void bgp_vty_init(void) install_element(BGP_VPNV6_NODE, &no_neighbor_send_community_cmd); install_element(BGP_VPNV6_NODE, &no_neighbor_send_community_type_cmd); + install_element(BGP_LS_NODE, &neighbor_send_community_cmd); + install_element(BGP_LS_NODE, &neighbor_send_community_type_cmd); + install_element(BGP_LS_NODE, &no_neighbor_send_community_cmd); + install_element(BGP_LS_NODE, &no_neighbor_send_community_type_cmd); + /* "neighbor route-reflector" commands.*/ install_element(BGP_NODE, &neighbor_route_reflector_client_hidden_cmd); install_element(BGP_NODE, @@ -19339,6 +19449,9 @@ void bgp_vty_init(void) install_element(BGP_EVPN_NODE, &neighbor_route_reflector_client_cmd); install_element(BGP_EVPN_NODE, &no_neighbor_route_reflector_client_cmd); + install_element(BGP_LS_NODE, &neighbor_route_reflector_client_cmd); + install_element(BGP_LS_NODE, &no_neighbor_route_reflector_client_cmd); + /* "optimal-route-reflection" commands */ install_element(BGP_IPV4_NODE, &optimal_route_reflection_cmd); install_element(BGP_IPV4M_NODE, &optimal_route_reflection_cmd); @@ -19394,6 +19507,8 @@ void bgp_vty_init(void) install_element(BGP_FLOWSPECV6_NODE, &neighbor_route_server_client_cmd); install_element(BGP_FLOWSPECV6_NODE, &no_neighbor_route_server_client_cmd); + install_element(BGP_LS_NODE, &neighbor_route_server_client_cmd); + install_element(BGP_LS_NODE, &no_neighbor_route_server_client_cmd); /* "neighbor disable-addpath-rx" commands. */ install_element(BGP_IPV4_NODE, &neighbor_disable_addpath_rx_cmd); @@ -19508,6 +19623,8 @@ void bgp_vty_init(void) install_element(BGP_IPV6M_NODE, &no_neighbor_capability_orf_prefix_cmd); install_element(BGP_IPV6L_NODE, &neighbor_capability_orf_prefix_cmd); install_element(BGP_IPV6L_NODE, &no_neighbor_capability_orf_prefix_cmd); + install_element(BGP_LS_NODE, &neighbor_capability_orf_prefix_cmd); + install_element(BGP_LS_NODE, &no_neighbor_capability_orf_prefix_cmd); /* "neighbor capability dynamic" commands.*/ install_element(BGP_NODE, &neighbor_capability_dynamic_cmd); @@ -19572,6 +19689,10 @@ void bgp_vty_init(void) install_element(BGP_IPV6L_NODE, &neighbor_default_originate_rmap_cmd); install_element(BGP_IPV6L_NODE, &no_neighbor_default_originate_cmd); + install_element(BGP_LS_NODE, &neighbor_default_originate_cmd); + install_element(BGP_LS_NODE, &neighbor_default_originate_rmap_cmd); + install_element(BGP_LS_NODE, &no_neighbor_default_originate_cmd); + /* "neighbor port" commands. */ install_element(BGP_NODE, &neighbor_port_cmd); install_element(BGP_NODE, &no_neighbor_port_cmd); @@ -19644,6 +19765,8 @@ void bgp_vty_init(void) install_element(BGP_VPNV4_NODE, &no_neighbor_distribute_list_cmd); install_element(BGP_VPNV6_NODE, &neighbor_distribute_list_cmd); install_element(BGP_VPNV6_NODE, &no_neighbor_distribute_list_cmd); + install_element(BGP_LS_NODE, &neighbor_distribute_list_cmd); + install_element(BGP_LS_NODE, &no_neighbor_distribute_list_cmd); /* "neighbor prefix-list" commands. */ install_element(BGP_NODE, &neighbor_prefix_list_hidden_cmd); @@ -19668,6 +19791,7 @@ void bgp_vty_init(void) install_element(BGP_FLOWSPECV4_NODE, &no_neighbor_prefix_list_cmd); install_element(BGP_FLOWSPECV6_NODE, &neighbor_prefix_list_cmd); install_element(BGP_FLOWSPECV6_NODE, &no_neighbor_prefix_list_cmd); + install_element(BGP_LS_NODE, &neighbor_prefix_list_cmd); /* "neighbor filter-list" commands. */ install_element(BGP_NODE, &neighbor_filter_list_hidden_cmd); @@ -19692,6 +19816,8 @@ void bgp_vty_init(void) install_element(BGP_FLOWSPECV4_NODE, &no_neighbor_filter_list_cmd); install_element(BGP_FLOWSPECV6_NODE, &neighbor_filter_list_cmd); install_element(BGP_FLOWSPECV6_NODE, &no_neighbor_filter_list_cmd); + install_element(BGP_LS_NODE, &neighbor_filter_list_cmd); + install_element(BGP_LS_NODE, &no_neighbor_filter_list_cmd); /* "neighbor route-map" commands. */ install_element(BGP_NODE, &neighbor_route_map_hidden_cmd); @@ -19718,6 +19844,7 @@ void bgp_vty_init(void) install_element(BGP_FLOWSPECV6_NODE, &no_neighbor_route_map_cmd); install_element(BGP_EVPN_NODE, &neighbor_route_map_cmd); install_element(BGP_EVPN_NODE, &no_neighbor_route_map_cmd); + install_element(BGP_LS_NODE, &neighbor_route_map_cmd); /* "neighbor unsuppress-map" commands. */ install_element(BGP_NODE, &neighbor_unsuppress_map_hidden_cmd); @@ -19738,6 +19865,8 @@ void bgp_vty_init(void) install_element(BGP_VPNV4_NODE, &no_neighbor_unsuppress_map_cmd); install_element(BGP_VPNV6_NODE, &neighbor_unsuppress_map_cmd); install_element(BGP_VPNV6_NODE, &no_neighbor_unsuppress_map_cmd); + install_element(BGP_LS_NODE, &neighbor_unsuppress_map_cmd); + install_element(BGP_LS_NODE, &no_neighbor_unsuppress_map_cmd); /* "neighbor advertise-map" commands. */ install_element(BGP_NODE, &bgp_condadv_period_cmd); @@ -19855,6 +19984,16 @@ void bgp_vty_init(void) &neighbor_maximum_prefix_threshold_restart_cmd); install_element(BGP_VPNV6_NODE, &no_neighbor_maximum_prefix_cmd); + install_element(BGP_LS_NODE, &neighbor_maximum_prefix_cmd); + install_element(BGP_LS_NODE, &neighbor_maximum_prefix_threshold_cmd); + install_element(BGP_LS_NODE, &neighbor_maximum_prefix_warning_cmd); + install_element(BGP_LS_NODE, + &neighbor_maximum_prefix_threshold_warning_cmd); + install_element(BGP_LS_NODE, &neighbor_maximum_prefix_restart_cmd); + install_element(BGP_LS_NODE, + &neighbor_maximum_prefix_threshold_restart_cmd); + install_element(BGP_LS_NODE, &no_neighbor_maximum_prefix_cmd); + /* "neighbor allowas-in" */ install_element(BGP_NODE, &neighbor_allowas_in_hidden_cmd); install_element(BGP_NODE, &no_neighbor_allowas_in_hidden_cmd); @@ -19877,6 +20016,9 @@ void bgp_vty_init(void) install_element(BGP_EVPN_NODE, &neighbor_allowas_in_cmd); install_element(BGP_EVPN_NODE, &no_neighbor_allowas_in_cmd); + install_element(BGP_LS_NODE, &neighbor_allowas_in_cmd); + install_element(BGP_LS_NODE, &no_neighbor_allowas_in_cmd); + /* neighbor accept-own */ install_element(BGP_VPNV4_NODE, &neighbor_accept_own_cmd); install_element(BGP_VPNV6_NODE, &neighbor_accept_own_cmd); @@ -19911,6 +20053,8 @@ void bgp_vty_init(void) install_element(BGP_NODE, &address_family_evpn_cmd); + install_element(BGP_NODE, &address_family_linkstate_cmd); + /* "exit-address-family" command. */ install_element(BGP_IPV4_NODE, &exit_address_family_cmd); install_element(BGP_IPV4M_NODE, &exit_address_family_cmd); @@ -19923,6 +20067,7 @@ void bgp_vty_init(void) install_element(BGP_FLOWSPECV4_NODE, &exit_address_family_cmd); install_element(BGP_FLOWSPECV6_NODE, &exit_address_family_cmd); install_element(BGP_EVPN_NODE, &exit_address_family_cmd); + install_element(BGP_LS_NODE, &exit_address_family_cmd); /* BGP retain all route-target */ install_element(BGP_VPNV4_NODE, &bgp_retain_route_target_cmd); diff --git a/bgpd/bgpd.c b/bgpd/bgpd.c index 734e44f2525d..7d44eda723e4 100644 --- a/bgpd/bgpd.c +++ b/bgpd/bgpd.c @@ -93,6 +93,7 @@ #include "bgpd/bgp_evpn_mh.h" #include "bgpd/bgp_mac.h" #include "bgpd/bgp_orr.h" +#include "bgpd/bgp_ls.h" DEFINE_MTYPE_STATIC(BGPD, PEER_TX_SHUTDOWN_MSG, "Peer shutdown message (TX)"); DEFINE_MTYPE_STATIC(BGPD, BGP_EVPN_INFO, "BGP EVPN instance information"); @@ -1964,6 +1965,10 @@ void peer_as_change(struct peer *peer, as_t as, int as_specified) PEER_FLAG_REFLECTOR_CLIENT); UNSET_FLAG(peer->af_flags[AFI_L2VPN][SAFI_EVPN], PEER_FLAG_REFLECTOR_CLIENT); + UNSET_FLAG(peer->af_flags[AFI_LINK_STATE][SAFI_LINK_STATE], + PEER_FLAG_REFLECTOR_CLIENT); + UNSET_FLAG(peer->af_flags[AFI_LINK_STATE][SAFI_LINK_STATE_VPN], + PEER_FLAG_REFLECTOR_CLIENT); } } @@ -4215,7 +4220,9 @@ bool peer_active(struct peer *peer) || peer->afc[AFI_IP6][SAFI_MPLS_VPN] || peer->afc[AFI_IP6][SAFI_ENCAP] || peer->afc[AFI_IP6][SAFI_FLOWSPEC] - || peer->afc[AFI_L2VPN][SAFI_EVPN]) + || peer->afc[AFI_L2VPN][SAFI_EVPN] + || peer->afc[AFI_LINK_STATE][SAFI_LINK_STATE] + || peer->afc[AFI_LINK_STATE][SAFI_LINK_STATE_VPN]) return true; return false; } @@ -4235,7 +4242,9 @@ bool peer_active_nego(struct peer *peer) || peer->afc_nego[AFI_IP6][SAFI_MPLS_VPN] || peer->afc_nego[AFI_IP6][SAFI_ENCAP] || peer->afc_nego[AFI_IP6][SAFI_FLOWSPEC] - || peer->afc_nego[AFI_L2VPN][SAFI_EVPN]) + || peer->afc_nego[AFI_L2VPN][SAFI_EVPN] + || peer->afc_nego[AFI_LINK_STATE][SAFI_LINK_STATE] + || peer->afc_nego[AFI_LINK_STATE][SAFI_LINK_STATE_VPN]) return true; return false; } @@ -8138,6 +8147,9 @@ void bgp_init(unsigned short instance) /* BFD init */ bgp_bfd_init(bm->master); + /* BGP-LS init */ + bgp_link_state_init(); + bgp_lp_vty_init(); cmd_variable_handler_register(bgp_viewvrf_var_handlers); diff --git a/bgpd/bgpd.h b/bgpd/bgpd.h index a75bfdf7465d..5b48acc3cd46 100644 --- a/bgpd/bgpd.h +++ b/bgpd/bgpd.h @@ -97,6 +97,8 @@ enum bgp_af_index { BGP_AF_IPV6_LBL_UNICAST, BGP_AF_IPV4_FLOWSPEC, BGP_AF_IPV6_FLOWSPEC, + BGP_AF_LINK_STATE, + BGP_AF_LINK_STATE_VPN, BGP_AF_MAX }; @@ -428,6 +430,8 @@ struct bgp { struct bgp_snmp_stats *snmp_stats; + struct bgp_lsdb *lsdb; /* BGP-LS database */ + /* BGP configuration. */ uint16_t config; #define BGP_CONFIG_CLUSTER_ID (1 << 0) @@ -1911,6 +1915,7 @@ struct bgp_nlri { #define BGP_ATTR_ENCAP 23 #define BGP_ATTR_IPV6_EXT_COMMUNITIES 25 #define BGP_ATTR_AIGP 26 +#define BGP_ATTR_LINK_STATE 29 #define BGP_ATTR_LARGE_COMMUNITIES 32 #define BGP_ATTR_OTC 35 #define BGP_ATTR_PREFIX_SID 40 @@ -2502,6 +2507,15 @@ static inline int afindex(afi_t afi, safi_t safi) default: return BGP_AF_MAX; } + case AFI_LINK_STATE: + switch (safi) { + case SAFI_LINK_STATE: + return BGP_AF_LINK_STATE; + case SAFI_LINK_STATE_VPN: + return BGP_AF_LINK_STATE_VPN; + default: + return BGP_AF_MAX; + } default: return BGP_AF_MAX; } @@ -2524,7 +2538,9 @@ static inline int peer_afi_active_nego(const struct peer *peer, afi_t afi) || peer->afc_nego[afi][SAFI_MPLS_VPN] || peer->afc_nego[afi][SAFI_ENCAP] || peer->afc_nego[afi][SAFI_FLOWSPEC] - || peer->afc_nego[afi][SAFI_EVPN]) + || peer->afc_nego[afi][SAFI_EVPN] + || peer->afc_nego[afi][SAFI_LINK_STATE] + || peer->afc_nego[afi][SAFI_LINK_STATE_VPN]) return 1; return 0; } @@ -2544,7 +2560,9 @@ static inline int peer_group_af_configured(struct peer_group *group) || peer->afc[AFI_IP6][SAFI_MPLS_VPN] || peer->afc[AFI_IP6][SAFI_ENCAP] || peer->afc[AFI_IP6][SAFI_FLOWSPEC] - || peer->afc[AFI_L2VPN][SAFI_EVPN]) + || peer->afc[AFI_L2VPN][SAFI_EVPN] + || peer->afc[AFI_LINK_STATE][SAFI_LINK_STATE] + || peer->afc[AFI_LINK_STATE][SAFI_LINK_STATE_VPN]) return 1; return 0; } diff --git a/bgpd/subdir.am b/bgpd/subdir.am index 88f53da35efe..20b4e50f2d53 100644 --- a/bgpd/subdir.am +++ b/bgpd/subdir.am @@ -75,6 +75,9 @@ bgpd_libbgp_a_SOURCES = \ bgpd/bgp_vpn.c \ bgpd/bgp_vty.c \ bgpd/bgp_zebra.c \ + bgpd/bgp_ls_bgpls.c \ + bgpd/bgp_bgpls_nlri.c \ + bgpd/bgp_lsdb.c \ bgpd/bgpd.c \ bgpd/bgp_orr.c \ bgpd/bgp_trace.c \ @@ -159,6 +162,8 @@ noinst_HEADERS += \ bgpd/bgp_vpn.h \ bgpd/bgp_vty.h \ bgpd/bgp_zebra.h \ + bgpd/bgp_ls.h \ + bgpd/bgp_lsdb.h \ bgpd/bgpd.h \ bgpd/bgp_orr.h \ bgpd/bgp_trace.h \ diff --git a/lib/command.h b/lib/command.h index 0f9715e81c1c..f10cc71d8f96 100644 --- a/lib/command.h +++ b/lib/command.h @@ -184,6 +184,7 @@ enum node_type { OPENFABRIC_NODE, /* OpenFabric router configuration node */ VRRP_NODE, /* VRRP node */ BMP_NODE, /* BMP config under router bgp */ + BGP_LS_NODE, /* BGP-LS configuration node */ NODE_TYPE_MAX, /* maximum */ }; diff --git a/lib/iana_afi.h b/lib/iana_afi.h index 56e8a24b86f1..88beca78c05a 100644 --- a/lib/iana_afi.h +++ b/lib/iana_afi.h @@ -39,6 +39,7 @@ typedef enum { IANA_AFI_IPV4 = 1, IANA_AFI_IPV6 = 2, IANA_AFI_L2VPN = 25, + IANA_AFI_LINK_STATE = 16388, /* BGP-LS RFC 7752 */ } iana_afi_t; typedef enum { @@ -48,6 +49,8 @@ typedef enum { IANA_SAFI_LABELED_UNICAST = 4, IANA_SAFI_ENCAP = 7, IANA_SAFI_EVPN = 70, + IANA_SAFI_LINK_STATE = 71, /* BGP-LS RFC 7752 */ + IANA_SAFI_LINK_STATE_VPN = 72, /* BGP-LS RFC 7752 */ IANA_SAFI_MPLS_VPN = 128, IANA_SAFI_FLOWSPEC = 133 } iana_safi_t; @@ -61,6 +64,8 @@ static inline afi_t afi_iana2int(iana_afi_t afi) return AFI_IP6; case IANA_AFI_L2VPN: return AFI_L2VPN; + case IANA_AFI_LINK_STATE: + return AFI_LINK_STATE; default: return AFI_MAX; } @@ -75,6 +80,8 @@ static inline iana_afi_t afi_int2iana(afi_t afi) return IANA_AFI_IPV6; case AFI_L2VPN: return IANA_AFI_L2VPN; + case AFI_LINK_STATE: + return IANA_AFI_LINK_STATE; default: return IANA_AFI_RESERVED; } @@ -102,6 +109,10 @@ static inline safi_t safi_iana2int(iana_safi_t safi) return SAFI_LABELED_UNICAST; case IANA_SAFI_FLOWSPEC: return SAFI_FLOWSPEC; + case IANA_SAFI_LINK_STATE: + return SAFI_LINK_STATE; + case IANA_SAFI_LINK_STATE_VPN: + return SAFI_LINK_STATE_VPN; default: return SAFI_MAX; } @@ -124,6 +135,10 @@ static inline iana_safi_t safi_int2iana(safi_t safi) return IANA_SAFI_LABELED_UNICAST; case SAFI_FLOWSPEC: return IANA_SAFI_FLOWSPEC; + case SAFI_LINK_STATE: + return IANA_SAFI_LINK_STATE; + case SAFI_LINK_STATE_VPN: + return IANA_SAFI_LINK_STATE_VPN; default: return IANA_SAFI_RESERVED; } diff --git a/lib/prefix.c b/lib/prefix.c index 4642f14d35ad..0208fd18b9f5 100644 --- a/lib/prefix.c +++ b/lib/prefix.c @@ -147,6 +147,8 @@ const char *afi2str(afi_t afi) return "IPv6"; case AFI_L2VPN: return "l2vpn"; + case AFI_LINK_STATE: + return "link-state"; case AFI_MAX: return "bad-value"; default: @@ -172,6 +174,10 @@ const char *safi2str(safi_t safi) return "labeled-unicast"; case SAFI_FLOWSPEC: return "flowspec"; + case SAFI_LINK_STATE: + return "link-state"; + case SAFI_LINK_STATE_VPN: + return "link-state-vpn"; default: return "unknown"; } diff --git a/lib/prefix.h b/lib/prefix.h index 7de8d7903ea6..361c641b0135 100644 --- a/lib/prefix.h +++ b/lib/prefix.h @@ -179,6 +179,12 @@ struct flowspec_prefix { uintptr_t ptr; }; +struct linkstate_prefix { + uint8_t nrli_type ; + uint16_t prefixlen; /* length in bytes */ + uintptr_t ptr; +}; + /* FRR generic prefix structure. */ struct prefix { uint8_t family; @@ -197,6 +203,7 @@ struct prefix { uintptr_t ptr; struct evpn_addr prefix_evpn; /* AF_EVPN */ struct flowspec_prefix prefix_flowspec; /* AF_FLOWSPEC */ + struct linkstate_prefix prefix_linkstate; /* AF_LINKSTATE */ } u __attribute__((aligned(8))); }; @@ -294,6 +301,14 @@ struct prefix_fs { struct flowspec_prefix prefix __attribute__((aligned(8))); }; + +/* Prefix for a BGP-LS entry */ +struct prefix_bgpls { + uint8_t family; + uint16_t prefixlen; /* unused */ + struct linkstate_prefix prefix __attribute__((aligned(8))); +}; + struct prefix_sg { uint8_t family; uint16_t prefixlen; diff --git a/lib/zebra.h b/lib/zebra.h index b2f5e5a848cc..f37edea78c6d 100644 --- a/lib/zebra.h +++ b/lib/zebra.h @@ -342,13 +342,14 @@ struct in_pktinfo { #define INADDR_LOOPBACK 0x7f000001 /* Internet address 127.0.0.1. */ #endif -/* Address family numbers from RFC1700. */ +/* Address family numbers. */ typedef enum { AFI_UNSPEC = 0, AFI_IP = 1, AFI_IP6 = 2, AFI_L2VPN = 3, - AFI_MAX = 4 + AFI_LINK_STATE = 4, /* BGP-LS RFC 7752 */ + AFI_MAX = 5, } afi_t; #define IS_VALID_AFI(a) ((a) > AFI_UNSPEC && (a) < AFI_MAX) @@ -363,7 +364,9 @@ typedef enum { SAFI_EVPN = 5, SAFI_LABELED_UNICAST = 6, SAFI_FLOWSPEC = 7, - SAFI_MAX = 8 + SAFI_LINK_STATE = 8, /* BGP-LS RFC 7752 */ + SAFI_LINK_STATE_VPN = 9, /* BGP-LS RFC 7752 */ + SAFI_MAX = 10, } safi_t; #define FOREACH_AFI_SAFI(afi, safi) \ diff --git a/vtysh/vtysh.c b/vtysh/vtysh.c index dea09fa151a8..8416a1e3860c 100644 --- a/vtysh/vtysh.c +++ b/vtysh/vtysh.c @@ -1442,6 +1442,13 @@ static struct cmd_node bgp_ipv6l_node = { .no_xpath = true, }; +static struct cmd_node bgp_ls_node = { + .name = "bgp link-state", + .node = BGP_LS_NODE, + .parent_node = BGP_NODE, + .prompt = "%s(config-router-af-ls)# ", +}; + #ifdef ENABLE_BGP_VNC static struct cmd_node bgp_vnc_defaults_node = { .name = "bgp vnc defaults", @@ -1749,6 +1756,16 @@ DEFUNSH(VTYSH_BGPD, address_family_flowspecv6, address_family_flowspecv6_cmd, return CMD_SUCCESS; } +DEFUNSH(VTYSH_BGPD, address_family_linkstate, address_family_linkstate_cmd, + "address-family link-state link-state", + "Enter Address Family command mode\n" + BGP_AF_STR + BGP_AF_MODIFIER_STR) +{ + vty->node = BGP_LS_NODE; + return CMD_SUCCESS; +} + DEFUNSH(VTYSH_BGPD, address_family_ipv4_multicast, address_family_ipv4_multicast_cmd, "address-family ipv4 multicast", "Enter Address Family command mode\n" @@ -2356,7 +2373,8 @@ DEFUNSH(VTYSH_BGPD, exit_address_family, exit_address_family_cmd, || vty->node == BGP_IPV6L_NODE || vty->node == BGP_IPV6M_NODE || vty->node == BGP_EVPN_NODE || vty->node == BGP_FLOWSPECV4_NODE - || vty->node == BGP_FLOWSPECV6_NODE) + || vty->node == BGP_FLOWSPECV6_NODE + || vty->node == BGP_LS_NODE) vty->node = BGP_NODE; return CMD_SUCCESS; } @@ -4554,6 +4572,13 @@ void vtysh_init_vty(void) install_element(BGP_EVPN_VNI_NODE, &vtysh_end_all_cmd); install_element(BGP_EVPN_VNI_NODE, &exit_vni_cmd); + install_node(&bgp_ls_node); + install_element(BGP_NODE, &address_family_linkstate_cmd); + install_element(BGP_LS_NODE, &vtysh_exit_bgpd_cmd); + install_element(BGP_LS_NODE, &vtysh_quit_bgpd_cmd); + install_element(BGP_LS_NODE, &vtysh_end_all_cmd); + install_element(BGP_LS_NODE, &exit_address_family_cmd); + install_node(&rpki_node); install_element(CONFIG_NODE, &rpki_cmd); install_element(RPKI_NODE, &rpki_exit_cmd); diff --git a/yang/frr-bgp-common-multiprotocol.yang b/yang/frr-bgp-common-multiprotocol.yang index 4b080613d637..33419a7f9bd3 100644 --- a/yang/frr-bgp-common-multiprotocol.yang +++ b/yang/frr-bgp-common-multiprotocol.yang @@ -203,5 +203,25 @@ submodule frr-bgp-common-multiprotocol { description "IPv6 flowspec configuration options."; } + + container linkstate-linkstate { + when "derived-from-or-self(../afi-safi-name, 'frr-rt:linkstate-linkstate')" { + description + "Include this container for Link-State specific + configuration."; + } + description + "Link-State configuration options."; + } + + container linkstate-linkstate-vpn { + when "derived-from-or-self(../afi-safi-name, 'frr-rt:linkstate-linkstate-vpn')" { + description + "Include this container for Link-State VPN specific + configuration."; + } + description + "Link-State VPN configuration options."; + } } } diff --git a/yang/frr-bgp.yang b/yang/frr-bgp.yang index 0e15195dd5ad..6eb448601e0e 100644 --- a/yang/frr-bgp.yang +++ b/yang/frr-bgp.yang @@ -818,6 +818,23 @@ module frr-bgp { uses structure-neighbor-group-filter-config; } + + augment "/frr-rt:routing/frr-rt:control-plane-protocols/frr-rt:control-plane-protocol/bgp/neighbors/neighbor/afi-safis/afi-safi/linkstate-linkstate" { + uses structure-neighbor-route-reflector; + + uses structure-neighbor-route-server; + + uses structure-neighbor-group-soft-reconfiguration; + } + + augment "/frr-rt:routing/frr-rt:control-plane-protocols/frr-rt:control-plane-protocol/bgp/neighbors/neighbor/afi-safis/afi-safi/linkstate-linkstate-vpn" { + uses structure-neighbor-route-reflector; + + uses structure-neighbor-route-server; + + uses structure-neighbor-group-soft-reconfiguration; + } + augment "/frr-rt:routing/frr-rt:control-plane-protocols/frr-rt:control-plane-protocol/bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-unicast" { uses structure-neighbor-group-add-paths; @@ -1089,6 +1106,22 @@ module frr-bgp { uses structure-neighbor-group-filter-config; } + augment "/frr-rt:routing/frr-rt:control-plane-protocols/frr-rt:control-plane-protocol/bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/linkstate-linkstate" { + uses structure-neighbor-route-reflector; + + uses structure-neighbor-route-server; + + uses structure-neighbor-group-soft-reconfiguration; + } + + augment "/frr-rt:routing/frr-rt:control-plane-protocols/frr-rt:control-plane-protocol/bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/linkstate-linkstate" { + uses structure-neighbor-route-reflector; + + uses structure-neighbor-route-server; + + uses structure-neighbor-group-soft-reconfiguration; + } + augment "/frr-rt:routing/frr-rt:control-plane-protocols/frr-rt:control-plane-protocol/bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-unicast" { uses structure-neighbor-group-add-paths; @@ -1365,4 +1398,20 @@ module frr-bgp { uses structure-neighbor-group-filter-config; } + + augment "/frr-rt:routing/frr-rt:control-plane-protocols/frr-rt:control-plane-protocol/bgp/peer-groups/peer-group/afi-safis/afi-safi/linkstate-linkstate" { + uses structure-neighbor-route-reflector; + + uses structure-neighbor-route-server; + + uses structure-neighbor-group-soft-reconfiguration; + } + + augment "/frr-rt:routing/frr-rt:control-plane-protocols/frr-rt:control-plane-protocol/bgp/peer-groups/peer-group/afi-safis/afi-safi/linkstate-linkstate-vpn" { + uses structure-neighbor-route-reflector; + + uses structure-neighbor-route-server; + + uses structure-neighbor-group-soft-reconfiguration; + } } diff --git a/yang/frr-routing.yang b/yang/frr-routing.yang index 6a721b29244d..7502960240b7 100644 --- a/yang/frr-routing.yang +++ b/yang/frr-routing.yang @@ -171,6 +171,20 @@ module frr-routing { } + identity linkstate-linkstate { + base afi-safi-type; + description + "This identity represents the link-state address family."; + } + + + identity linkstate-linkstate-vpn { + base afi-safi-type; + description + "This identity represents the link-state VPN address family."; + } + + identity control-plane-protocol { description "Base identity from which control-plane protocol identities are