forked from Mirror/frr
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:
parent
a30c159769
commit
c5a543b433
169
bgpd/bgp_attr.c
169
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);
|
||||
|
||||
/* 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) */
|
||||
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);
|
||||
|
||||
/* 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)
|
||||
/* Placeholder code for the IPv6 SID type */
|
||||
else if (type == BGP_PREFIX_SID_IPV6)
|
||||
{
|
||||
attr->extra->label_index = BGP_INVALID_LABEL_INDEX;
|
||||
attr->flag &= ~ATTR_FLAG_BIT(BGP_ATTR_LABEL_INDEX);
|
||||
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);
|
||||
}
|
||||
|
||||
/* 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;
|
||||
}
|
||||
|
||||
|
@ -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. */
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in a new issue