{ 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);
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
[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;
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;
}
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);
/* 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);
+ }
}
}
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. */
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.
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);
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. */
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 */