Update to draft-ietf-idr-bgp-prefix-sid-05

Signed-off-by: Daniel Walton <dwalton@cumulusnetworks.com>

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)
This commit is contained in:
Daniel Walton 2017-04-26 21:45:32 +00:00
parent a30c159769
commit c5a543b433
6 changed files with 160 additions and 85 deletions

View file

@ -79,7 +79,7 @@ static const struct message attr_str [] =
{ BGP_ATTR_VNC, "VNC" }, { BGP_ATTR_VNC, "VNC" },
#endif #endif
{ BGP_ATTR_LARGE_COMMUNITIES, "LARGE_COMMUNITY" }, { 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); static const int attr_str_max = array_size(attr_str);
@ -533,7 +533,10 @@ static struct hash *attrhash;
static struct attr_extra * static struct attr_extra *
bgp_attr_extra_new (void) 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 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_PATH] = BGP_ATTR_FLAG_OPTIONAL | BGP_ATTR_FLAG_TRANS,
[BGP_ATTR_AS4_AGGREGATOR] = 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_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; static const size_t attr_flags_values_max = array_size(attr_flags_values) - 1;
@ -2278,49 +2281,103 @@ bgp_attr_encap(
return 0; return 0;
} }
/* Label index attribute */ /* Prefix SID attribute
* draft-ietf-idr-bgp-prefix-sid-05
*/
static bgp_attr_parse_ret_t 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 peer *const peer = args->peer;
struct attr *const attr = args->attr; struct attr *const attr = args->attr;
const bgp_size_t length = args->length; int type;
int length;
u_int32_t label_index; 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. */ attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_PREFIX_SID);
if (length != 8)
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, /* Ignore flags and reserved */
BGP_NOTIFY_UPDATE_ATTR_LENG_ERR, stream_getc (peer->ibuf);
args->total); stream_getw (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);
/* 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;
} }
/* First u32 is currently unused - reserved and flags (undefined) */ /* Placeholder code for the IPv6 SID type */
stream_getl (peer->ibuf); else if (type == BGP_PREFIX_SID_IPV6)
/* 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;
attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_LABEL_INDEX);
/*
* 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)
{ {
attr->extra->label_index = BGP_INVALID_LABEL_INDEX; if (length != BGP_PREFIX_SID_IPV6_LENGTH)
attr->flag &= ~ATTR_FLAG_BIT(BGP_ATTR_LABEL_INDEX); {
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);
}
/* Ignore reserved */
stream_getc (peer->ibuf);
stream_getw (peer->ibuf);
stream_get (&ipv6_sid, peer->ibuf, 16);
} }
/* Placeholder code for the Originator SRGB type */
else if (type == BGP_PREFIX_SID_ORIGINATOR_SRGB)
{
/* 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; 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: case BGP_ATTR_ENCAP:
ret = bgp_attr_encap (type, peer, length, attr, flag, startp); ret = bgp_attr_encap (type, peer, length, attr, flag, startp);
break; break;
case BGP_ATTR_LABEL_INDEX: case BGP_ATTR_PREFIX_SID:
ret = bgp_attr_label_index (&attr_args, mp_update); ret = bgp_attr_prefix_sid (&attr_args, mp_update);
break; break;
default: default:
ret = bgp_attr_unknown (&attr_args); ret = bgp_attr_unknown (&attr_args);
@ -3412,17 +3469,24 @@ bgp_packet_attribute (struct bgp *bgp, struct peer *peer,
/* Label index attribute. */ /* Label index attribute. */
if (safi == SAFI_LABELED_UNICAST) 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; u_int32_t label_index;
assert (attr->extra); assert (attr->extra);
label_index = attr->extra->label_index; label_index = attr->extra->label_index;
stream_putc (s, BGP_ATTR_FLAG_OPTIONAL|BGP_ATTR_FLAG_TRANS);
stream_putc (s, BGP_ATTR_LABEL_INDEX); if (label_index != BGP_INVALID_LABEL_INDEX)
stream_putc (s, 8); {
stream_putl (s, 0); stream_putc (s, BGP_ATTR_FLAG_OPTIONAL|BGP_ATTR_FLAG_TRANS);
stream_putl (s, label_index); 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); stream_putc_at (s, sizep, (stream_get_endp (s) - sizep) - 1);
} }
/* Label index */ /* Prefix SID */
if (attr->flag & ATTR_FLAG_BIT (BGP_ATTR_LABEL_INDEX)) if (attr->flag & ATTR_FLAG_BIT (BGP_ATTR_PREFIX_SID))
{ {
assert (attr->extra); assert (attr->extra);
stream_putc (s, BGP_ATTR_FLAG_OPTIONAL|BGP_ATTR_FLAG_TRANS);
stream_putc (s, BGP_ATTR_LABEL_INDEX); if (attr->extra->label_index != BGP_INVALID_LABEL_INDEX)
stream_putc (s, 8); {
stream_putl (s, 0); stream_putc (s, BGP_ATTR_FLAG_OPTIONAL|BGP_ATTR_FLAG_TRANS);
stream_putl (s, attr->extra->label_index); 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. */ /* Return total size of attribute. */

View file

@ -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 8+IPV6_MAX_BYTELEN
#define BGP_ATTR_NHLEN_VPNV6_GLOBAL_AND_LL ((8+IPV6_MAX_BYTELEN) * 2) #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 {
struct bgp_attr_encap_subtlv *next; /* for chaining */ struct bgp_attr_encap_subtlv *next; /* for chaining */

View file

@ -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", snprintf (buf + strlen (buf), size - strlen (buf), ", path %s",
aspath_print (attr->aspath)); aspath_print (attr->aspath));
if (CHECK_FLAG (attr->flag, ATTR_FLAG_BIT (BGP_ATTR_LABEL_INDEX))) if (CHECK_FLAG (attr->flag, ATTR_FLAG_BIT (BGP_ATTR_PREFIX_SID)))
snprintf (buf + strlen (buf), size - strlen (buf), ", label-index %u", {
if (attr->extra->label_index != BGP_INVALID_LABEL_INDEX)
snprintf (buf + strlen (buf), size - strlen (buf), ", label-index %u",
attr->extra->label_index); attr->extra->label_index);
}
if (strlen (buf) > 1) if (strlen (buf) > 1)
return 1; return 1;

View file

@ -150,11 +150,15 @@ bgp_reg_dereg_for_label (struct bgp_node *rn, struct bgp_info *ri,
if (reg) if (reg)
{ {
assert (ri); 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); 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); SET_FLAG (rn->flags, BGP_NODE_REGISTERED_FOR_LABEL);
} }

View file

@ -301,16 +301,7 @@ bgp_pcount_adjust (struct bgp_node *rn, struct bgp_info *ri)
static int static int
bgp_label_index_differs (struct bgp_info *ri1, struct bgp_info *ri2) bgp_label_index_differs (struct bgp_info *ri1, struct bgp_info *ri2)
{ {
u_int32_t ri1_label_index = BGP_INVALID_LABEL_INDEX; return (!(ri1->attr->extra->label_index == ri2->attr->extra->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));
} }
/* Set/unset bgp_info flags, adjusting any other state as needed. /* 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) new_select->sub_type != old_select->sub_type)
{ {
if (new_select->sub_type == BGP_ROUTE_STATIC && 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)) if (CHECK_FLAG (rn->flags, BGP_NODE_REGISTERED_FOR_LABEL))
bgp_unregister_for_label (rn); 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) if (bgp_static->label_index != BGP_INVALID_LABEL_INDEX)
{ {
(bgp_attr_extra_get (&attr))->label_index = bgp_static->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. */ /* 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) if (binfo->extra && binfo->extra->damp_info)
bgp_damp_info_vty (vty, binfo, json_path); bgp_damp_info_vty (vty, binfo, json_path);
/* Label information */ /* Remove Label */
if ((bgp_labeled_safi(safi) && binfo->extra) || if (bgp_labeled_safi(safi) && binfo->extra)
(CHECK_FLAG (attr->flag, ATTR_FLAG_BIT (BGP_ATTR_LABEL_INDEX))))
{ {
if (bgp_labeled_safi(safi) && binfo->extra) uint32_t label = label_pton(binfo->extra->tag);
{ if (json_paths)
uint32_t label = label_pton(binfo->extra->tag); json_object_int_add(json_path, "remoteLabel", label);
if (json_paths) else
json_object_int_add(json_path, "remoteLabel", label); vty_out(vty, " Remote label: %d%s", label, VTY_NEWLINE);
else }
vty_out(vty, " Remote label: %d%s", label, VTY_NEWLINE);
}
if (CHECK_FLAG (attr->flag, ATTR_FLAG_BIT (BGP_ATTR_LABEL_INDEX))) /* 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); if (json_paths)
else json_object_int_add(json_path, "labelIndex", attr->extra->label_index);
vty_out(vty, " Label Index: %d%s", attr->extra->label_index, VTY_NEWLINE); else
} vty_out(vty, " Label Index: %d%s", attr->extra->label_index, VTY_NEWLINE);
} }
/* Line 8 display Addpath IDs */ /* Line 8 display Addpath IDs */

View file

@ -973,7 +973,7 @@ struct bgp_nlri
#define BGP_ATTR_AS_PATHLIMIT 21 #define BGP_ATTR_AS_PATHLIMIT 21
#define BGP_ATTR_ENCAP 23 #define BGP_ATTR_ENCAP 23
#define BGP_ATTR_LARGE_COMMUNITIES 32 #define BGP_ATTR_LARGE_COMMUNITIES 32
#define BGP_ATTR_LABEL_INDEX 40 #define BGP_ATTR_PREFIX_SID 40
#if ENABLE_BGP_VNC #if ENABLE_BGP_VNC
#define BGP_ATTR_VNC 255 #define BGP_ATTR_VNC 255
#endif #endif