]> git.proxmox.com Git - mirror_frr.git/commitdiff
Update to draft-ietf-idr-bgp-prefix-sid-05
authorDaniel Walton <dwalton@cumulusnetworks.com>
Wed, 26 Apr 2017 21:45:32 +0000 (21:45 +0000)
committerDaniel Walton <dwalton@cumulusnetworks.com>
Wed, 26 Apr 2017 21:45:32 +0000 (21:45 +0000)
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)

bgpd/bgp_attr.c
bgpd/bgp_attr.h
bgpd/bgp_debug.c
bgpd/bgp_label.c
bgpd/bgp_route.c
bgpd/bgpd.h

index a25ebf4772cd9a4e4635c436a0c24676329c6cdc..b2789cd47dcc4cfd542f8144994abc2fb9e4d3b3 100644 (file)
@@ -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. */
index d57e944aa09ab9c4e262402ec911e33a94170d6e..3351ad2239c681239d3d63c9c31b5435e084de4a 100644 (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_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 */
index 8e4d8bf4f292b9d3d6e5ac9d19384725e8207050..0bd74dbdc4ba6a9f9e8069e037e1a799dde175fd 100644 (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",
              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;
index 615eca58849b3dcae95d5b2bc198cb569eacc835..e4186a5732c90adfe0da3bb767e9ac1342eab6de 100644 (file)
@@ -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);
     }
index 88147e2b6843fb7fc28d41e1c9300bee353dfa24..2666644c7e9e852ce9a15fd4fb4ff740e0c15e71 100644 (file)
@@ -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 */
index 1b97a25039272bda2b6ad7d8e45ad678cd78163f..ac09b97580f0a6d4ac36883719f500a977c95bd8 100644 (file)
@@ -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