From: Daniel Walton Date: Wed, 26 Apr 2017 21:45:32 +0000 (+0000) Subject: Update to draft-ietf-idr-bgp-prefix-sid-05 X-Git-Tag: reindent-master-before~205^2 X-Git-Url: https://git.puffer.fish/?a=commitdiff_plain;h=refs%2Fpull%2F412%2Fhead;p=mirror%2Ffrr.git Update to draft-ietf-idr-bgp-prefix-sid-05 Signed-off-by: Daniel Walton The initial implementation was against draft-keyupate-idr-bgp-prefix-sid-02 This updates our label-index implementation up to draft-ietf-idr-bgp-prefix-sid-05 - changed BGP_ATTR_LABEL_INDEX to BGP_ATTR_PREFIX_SID - since there are multiple TLVs in BGP_ATTR_PREFIX_SID you can no longer rely on that flag to know if there is a label-index for the path. I changed bgp_attr_extra_new() to init the label_index to BGP_INVALID_LABEL_INDEX - put some placeholder code in for the other two TLVs (IPv6 and Originator SRGB) --- diff --git a/bgpd/bgp_attr.c b/bgpd/bgp_attr.c index a25ebf4772..b2789cd47d 100644 --- a/bgpd/bgp_attr.c +++ b/bgpd/bgp_attr.c @@ -79,7 +79,7 @@ static const struct message attr_str [] = { BGP_ATTR_VNC, "VNC" }, #endif { BGP_ATTR_LARGE_COMMUNITIES, "LARGE_COMMUNITY" }, - { BGP_ATTR_LABEL_INDEX, "LABEL_INDEX" } + { BGP_ATTR_PREFIX_SID, "PREFIX_SID" } }; static const int attr_str_max = array_size(attr_str); @@ -533,7 +533,10 @@ static struct hash *attrhash; static struct attr_extra * bgp_attr_extra_new (void) { - return XCALLOC (MTYPE_ATTR_EXTRA, sizeof (struct attr_extra)); + struct attr_extra *extra; + extra = XCALLOC (MTYPE_ATTR_EXTRA, sizeof (struct attr_extra)); + extra->label_index = BGP_INVALID_LABEL_INDEX; + return extra; } void @@ -1290,7 +1293,7 @@ const u_int8_t attr_flags_values [] = { [BGP_ATTR_AS4_PATH] = BGP_ATTR_FLAG_OPTIONAL | BGP_ATTR_FLAG_TRANS, [BGP_ATTR_AS4_AGGREGATOR] = BGP_ATTR_FLAG_OPTIONAL | BGP_ATTR_FLAG_TRANS, [BGP_ATTR_LARGE_COMMUNITIES]= BGP_ATTR_FLAG_OPTIONAL | BGP_ATTR_FLAG_TRANS, - [BGP_ATTR_LABEL_INDEX] = BGP_ATTR_FLAG_OPTIONAL | BGP_ATTR_FLAG_TRANS, + [BGP_ATTR_PREFIX_SID] = BGP_ATTR_FLAG_OPTIONAL | BGP_ATTR_FLAG_TRANS, }; static const size_t attr_flags_values_max = array_size(attr_flags_values) - 1; @@ -2278,49 +2281,103 @@ bgp_attr_encap( return 0; } -/* Label index attribute */ +/* Prefix SID attribute + * draft-ietf-idr-bgp-prefix-sid-05 + */ static bgp_attr_parse_ret_t -bgp_attr_label_index (struct bgp_attr_parser_args *args, struct bgp_nlri *mp_update) +bgp_attr_prefix_sid (struct bgp_attr_parser_args *args, struct bgp_nlri *mp_update) { struct peer *const peer = args->peer; struct attr *const attr = args->attr; - const bgp_size_t length = args->length; + int type; + int length; u_int32_t label_index; + struct in6_addr ipv6_sid; + u_int32_t srgb_base; + u_int32_t srgb_range; + int srgb_count; - /* Length check. */ - if (length != 8) + attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_PREFIX_SID); + + type = stream_getc (peer->ibuf); + length = stream_getw (peer->ibuf); + + if (type == BGP_PREFIX_SID_LABEL_INDEX) { - zlog_err ("Bad label index length %d", length); + if (length != BGP_PREFIX_SID_LABEL_INDEX_LENGTH) + { + zlog_err ("Prefix SID label index length is %d instead of %d", length, BGP_PREFIX_SID_LABEL_INDEX_LENGTH); + return bgp_attr_malformed (args, + BGP_NOTIFY_UPDATE_ATTR_LENG_ERR, + args->total); + } - return bgp_attr_malformed (args, - BGP_NOTIFY_UPDATE_ATTR_LENG_ERR, - args->total); - } + /* Ignore flags and reserved */ + stream_getc (peer->ibuf); + stream_getw (peer->ibuf); - /* First u32 is currently unused - reserved and flags (undefined) */ - stream_getl (peer->ibuf); + /* Fetch the label index and see if it is valid. */ + label_index = stream_getl (peer->ibuf); + if (label_index == BGP_INVALID_LABEL_INDEX) + return bgp_attr_malformed (args, + BGP_NOTIFY_UPDATE_OPT_ATTR_ERR, + args->total); - /* Fetch the label index and see if it is valid. */ - label_index = stream_getl (peer->ibuf); - if (label_index == BGP_INVALID_LABEL_INDEX) - return bgp_attr_malformed (args, - BGP_NOTIFY_UPDATE_OPT_ATTR_ERR, - args->total); + /* Store label index; subsequently, we'll check on address-family */ + (bgp_attr_extra_get (attr))->label_index = label_index; + + /* + * Ignore the Label index attribute unless received for labeled-unicast + * SAFI. + */ + if (!mp_update->length || mp_update->safi != SAFI_LABELED_UNICAST) + attr->extra->label_index = BGP_INVALID_LABEL_INDEX; + } - /* Store label index; subsequently, we'll check on address-family */ - (bgp_attr_extra_get (attr))->label_index = label_index; + /* Placeholder code for the IPv6 SID type */ + else if (type == BGP_PREFIX_SID_IPV6) + { + if (length != BGP_PREFIX_SID_IPV6_LENGTH) + { + zlog_err ("Prefix SID IPv6 length is %d instead of %d", length, BGP_PREFIX_SID_IPV6_LENGTH); + return bgp_attr_malformed (args, + BGP_NOTIFY_UPDATE_ATTR_LENG_ERR, + args->total); + } - attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_LABEL_INDEX); + /* Ignore reserved */ + stream_getc (peer->ibuf); + stream_getw (peer->ibuf); - /* - * Ignore the Label index attribute unless received for labeled-unicast - * SAFI. We reset the flag, though it is probably unnecesary. - */ - if (!mp_update->length || mp_update->safi != SAFI_LABELED_UNICAST) + stream_get (&ipv6_sid, peer->ibuf, 16); + } + + /* Placeholder code for the Originator SRGB type */ + else if (type == BGP_PREFIX_SID_ORIGINATOR_SRGB) { - attr->extra->label_index = BGP_INVALID_LABEL_INDEX; - attr->flag &= ~ATTR_FLAG_BIT(BGP_ATTR_LABEL_INDEX); + /* Ignore flags */ + stream_getw (peer->ibuf); + + length -= 2; + + if (length % BGP_PREFIX_SID_ORIGINATOR_SRGB_LENGTH) + { + zlog_err ("Prefix SID Originator SRGB length is %d, it must be a multiple of %d ", + length, BGP_PREFIX_SID_ORIGINATOR_SRGB_LENGTH); + return bgp_attr_malformed (args, + BGP_NOTIFY_UPDATE_ATTR_LENG_ERR, + args->total); + } + + srgb_count = length / BGP_PREFIX_SID_ORIGINATOR_SRGB_LENGTH; + + for (int i = 0; i < srgb_count; i++) + { + stream_get (&srgb_base, peer->ibuf, 3); + stream_get (&srgb_range, peer->ibuf, 3); + } } + return BGP_ATTR_PARSE_PROCEED; } @@ -2622,8 +2679,8 @@ bgp_attr_parse (struct peer *peer, struct attr *attr, bgp_size_t size, case BGP_ATTR_ENCAP: ret = bgp_attr_encap (type, peer, length, attr, flag, startp); break; - case BGP_ATTR_LABEL_INDEX: - ret = bgp_attr_label_index (&attr_args, mp_update); + case BGP_ATTR_PREFIX_SID: + ret = bgp_attr_prefix_sid (&attr_args, mp_update); break; default: ret = bgp_attr_unknown (&attr_args); @@ -3412,17 +3469,24 @@ bgp_packet_attribute (struct bgp *bgp, struct peer *peer, /* Label index attribute. */ if (safi == SAFI_LABELED_UNICAST) { - if (attr->flag & ATTR_FLAG_BIT (BGP_ATTR_LABEL_INDEX)) + if (attr->flag & ATTR_FLAG_BIT (BGP_ATTR_PREFIX_SID)) { u_int32_t label_index; assert (attr->extra); label_index = attr->extra->label_index; - stream_putc (s, BGP_ATTR_FLAG_OPTIONAL|BGP_ATTR_FLAG_TRANS); - stream_putc (s, BGP_ATTR_LABEL_INDEX); - stream_putc (s, 8); - stream_putl (s, 0); - stream_putl (s, label_index); + + if (label_index != BGP_INVALID_LABEL_INDEX) + { + stream_putc (s, BGP_ATTR_FLAG_OPTIONAL|BGP_ATTR_FLAG_TRANS); + stream_putc (s, BGP_ATTR_PREFIX_SID); + stream_putc (s, 10); + stream_putc (s, BGP_PREFIX_SID_LABEL_INDEX); + stream_putw (s, BGP_PREFIX_SID_LABEL_INDEX_LENGTH); + stream_putc (s, 0); // reserved + stream_putw (s, 0); // flags + stream_putl (s, label_index); + } } } @@ -3709,15 +3773,22 @@ bgp_dump_routes_attr (struct stream *s, struct attr *attr, stream_putc_at (s, sizep, (stream_get_endp (s) - sizep) - 1); } - /* Label index */ - if (attr->flag & ATTR_FLAG_BIT (BGP_ATTR_LABEL_INDEX)) + /* Prefix SID */ + if (attr->flag & ATTR_FLAG_BIT (BGP_ATTR_PREFIX_SID)) { assert (attr->extra); - stream_putc (s, BGP_ATTR_FLAG_OPTIONAL|BGP_ATTR_FLAG_TRANS); - stream_putc (s, BGP_ATTR_LABEL_INDEX); - stream_putc (s, 8); - stream_putl (s, 0); - stream_putl (s, attr->extra->label_index); + + if (attr->extra->label_index != BGP_INVALID_LABEL_INDEX) + { + stream_putc (s, BGP_ATTR_FLAG_OPTIONAL|BGP_ATTR_FLAG_TRANS); + stream_putc (s, BGP_ATTR_PREFIX_SID); + stream_putc (s, 10); + stream_putc (s, BGP_PREFIX_SID_LABEL_INDEX); + stream_putc (s, BGP_PREFIX_SID_LABEL_INDEX_LENGTH); + stream_putc (s, 0); // reserved + stream_putw (s, 0); // flags + stream_putl (s, attr->extra->label_index); + } } /* Return total size of attribute. */ diff --git a/bgpd/bgp_attr.h b/bgpd/bgp_attr.h index d57e944aa0..3351ad2239 100644 --- a/bgpd/bgp_attr.h +++ b/bgpd/bgp_attr.h @@ -57,6 +57,14 @@ Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA #define BGP_ATTR_NHLEN_VPNV6_GLOBAL 8+IPV6_MAX_BYTELEN #define BGP_ATTR_NHLEN_VPNV6_GLOBAL_AND_LL ((8+IPV6_MAX_BYTELEN) * 2) +/* Prefix SID types */ +#define BGP_PREFIX_SID_LABEL_INDEX 1 +#define BGP_PREFIX_SID_IPV6 2 +#define BGP_PREFIX_SID_ORIGINATOR_SRGB 3 + +#define BGP_PREFIX_SID_LABEL_INDEX_LENGTH 7 +#define BGP_PREFIX_SID_IPV6_LENGTH 19 +#define BGP_PREFIX_SID_ORIGINATOR_SRGB_LENGTH 6 struct bgp_attr_encap_subtlv { struct bgp_attr_encap_subtlv *next; /* for chaining */ diff --git a/bgpd/bgp_debug.c b/bgpd/bgp_debug.c index 8e4d8bf4f2..0bd74dbdc4 100644 --- a/bgpd/bgp_debug.c +++ b/bgpd/bgp_debug.c @@ -450,9 +450,12 @@ bgp_dump_attr (struct peer *peer, struct attr *attr, char *buf, size_t size) snprintf (buf + strlen (buf), size - strlen (buf), ", path %s", aspath_print (attr->aspath)); - if (CHECK_FLAG (attr->flag, ATTR_FLAG_BIT (BGP_ATTR_LABEL_INDEX))) - snprintf (buf + strlen (buf), size - strlen (buf), ", label-index %u", + if (CHECK_FLAG (attr->flag, ATTR_FLAG_BIT (BGP_ATTR_PREFIX_SID))) + { + if (attr->extra->label_index != BGP_INVALID_LABEL_INDEX) + snprintf (buf + strlen (buf), size - strlen (buf), ", label-index %u", attr->extra->label_index); + } if (strlen (buf) > 1) return 1; diff --git a/bgpd/bgp_label.c b/bgpd/bgp_label.c index 615eca5884..e4186a5732 100644 --- a/bgpd/bgp_label.c +++ b/bgpd/bgp_label.c @@ -150,11 +150,15 @@ bgp_reg_dereg_for_label (struct bgp_node *rn, struct bgp_info *ri, if (reg) { assert (ri); - if (ri->attr->flag & ATTR_FLAG_BIT (BGP_ATTR_LABEL_INDEX)) + if (ri->attr->flag & ATTR_FLAG_BIT (BGP_ATTR_PREFIX_SID)) { assert (ri->attr->extra); - flags |= ZEBRA_FEC_REGISTER_LABEL_INDEX; - stream_putl (s, ri->attr->extra->label_index); + + if (ri->attr->extra->label_index != BGP_INVALID_LABEL_INDEX) + { + flags |= ZEBRA_FEC_REGISTER_LABEL_INDEX; + stream_putl (s, ri->attr->extra->label_index); + } } SET_FLAG (rn->flags, BGP_NODE_REGISTERED_FOR_LABEL); } diff --git a/bgpd/bgp_route.c b/bgpd/bgp_route.c index 88147e2b68..2666644c7e 100644 --- a/bgpd/bgp_route.c +++ b/bgpd/bgp_route.c @@ -301,16 +301,7 @@ bgp_pcount_adjust (struct bgp_node *rn, struct bgp_info *ri) static int bgp_label_index_differs (struct bgp_info *ri1, struct bgp_info *ri2) { - u_int32_t ri1_label_index = BGP_INVALID_LABEL_INDEX; - u_int32_t ri2_label_index = BGP_INVALID_LABEL_INDEX; - - if (ri1->attr->flag & ATTR_FLAG_BIT (BGP_ATTR_LABEL_INDEX)) - ri1_label_index = ri1->attr->extra->label_index; - - if (ri2->attr->flag & ATTR_FLAG_BIT (BGP_ATTR_LABEL_INDEX)) - ri2_label_index = ri2->attr->extra->label_index; - - return (!(ri1_label_index == ri2_label_index)); + return (!(ri1->attr->extra->label_index == ri2->attr->extra->label_index)); } /* Set/unset bgp_info flags, adjusting any other state as needed. @@ -1960,7 +1951,8 @@ bgp_process_main (struct work_queue *wq, void *data) new_select->sub_type != old_select->sub_type) { if (new_select->sub_type == BGP_ROUTE_STATIC && - new_select->attr->flag & ATTR_FLAG_BIT (BGP_ATTR_LABEL_INDEX)) + new_select->attr->flag & ATTR_FLAG_BIT (BGP_ATTR_PREFIX_SID) && + new_select->attr->extra->label_index != BGP_INVALID_LABEL_INDEX) { if (CHECK_FLAG (rn->flags, BGP_NODE_REGISTERED_FOR_LABEL)) bgp_unregister_for_label (rn); @@ -3824,7 +3816,7 @@ bgp_static_update (struct bgp *bgp, struct prefix *p, if (bgp_static->label_index != BGP_INVALID_LABEL_INDEX) { (bgp_attr_extra_get (&attr))->label_index = bgp_static->label_index; - attr.flag |= ATTR_FLAG_BIT (BGP_ATTR_LABEL_INDEX); + attr.flag |= ATTR_FLAG_BIT (BGP_ATTR_PREFIX_SID); } /* Apply route-map. */ @@ -7653,26 +7645,23 @@ route_vty_out_detail (struct vty *vty, struct bgp *bgp, struct prefix *p, if (binfo->extra && binfo->extra->damp_info) bgp_damp_info_vty (vty, binfo, json_path); - /* Label information */ - if ((bgp_labeled_safi(safi) && binfo->extra) || - (CHECK_FLAG (attr->flag, ATTR_FLAG_BIT (BGP_ATTR_LABEL_INDEX)))) + /* Remove Label */ + if (bgp_labeled_safi(safi) && binfo->extra) { - if (bgp_labeled_safi(safi) && binfo->extra) - { - uint32_t label = label_pton(binfo->extra->tag); - if (json_paths) - json_object_int_add(json_path, "remoteLabel", label); - else - vty_out(vty, " Remote label: %d%s", label, VTY_NEWLINE); - } + uint32_t label = label_pton(binfo->extra->tag); + if (json_paths) + json_object_int_add(json_path, "remoteLabel", label); + else + vty_out(vty, " Remote label: %d%s", label, VTY_NEWLINE); + } - if (CHECK_FLAG (attr->flag, ATTR_FLAG_BIT (BGP_ATTR_LABEL_INDEX))) - { - if (json_paths) - json_object_int_add(json_path, "labelIndex", attr->extra->label_index); - else - vty_out(vty, " Label Index: %d%s", attr->extra->label_index, VTY_NEWLINE); - } + /* Label Index */ + if (attr->extra->label_index != BGP_INVALID_LABEL_INDEX) + { + if (json_paths) + json_object_int_add(json_path, "labelIndex", attr->extra->label_index); + else + vty_out(vty, " Label Index: %d%s", attr->extra->label_index, VTY_NEWLINE); } /* Line 8 display Addpath IDs */ diff --git a/bgpd/bgpd.h b/bgpd/bgpd.h index 1b97a25039..ac09b97580 100644 --- a/bgpd/bgpd.h +++ b/bgpd/bgpd.h @@ -973,7 +973,7 @@ struct bgp_nlri #define BGP_ATTR_AS_PATHLIMIT 21 #define BGP_ATTR_ENCAP 23 #define BGP_ATTR_LARGE_COMMUNITIES 32 -#define BGP_ATTR_LABEL_INDEX 40 +#define BGP_ATTR_PREFIX_SID 40 #if ENABLE_BGP_VNC #define BGP_ATTR_VNC 255 #endif