]> git.puffer.fish Git - matthieu/frr.git/commitdiff
MPLS: Configure static routes with labels in Quagga
authorvivek <vivek@cumulusnetworks.com>
Mon, 18 Apr 2016 22:54:11 +0000 (22:54 +0000)
committerDonald Sharp <sharpd@cumulusnetworks.com>
Fri, 23 Sep 2016 13:31:01 +0000 (09:31 -0400)
Introduce ability to configure static routes with labels. Only supported for
IPv4.

Signed-off-by: Vivek Venkatraman <vivek@cumulusnetworks.com>
Reviewed-by: Donald Sharp <sharpd@cumulusnetworks.com>
Ticket: CM-6040
Reviewed By: CCR-3090
Testing Done: Testing in SE-1

zebra/zebra_mpls.c
zebra/zebra_mpls.h
zebra/zebra_mpls_null.c
zebra/zebra_static.c
zebra/zebra_static.h
zebra/zebra_vty.c

index c337a8312a905b7ecbed7a29836ea0211e1838f3..3e841147721771f2a02b547b2e4c21ababb1554f 100644 (file)
@@ -1337,6 +1337,63 @@ mpls_processq_init (struct zebra_t *zebra)
 
 /* Public functions */
 
+/*
+ * String to label conversion, labels separated by '/'.
+ */
+int
+mpls_str2label (const char *label_str, u_int8_t *num_labels,
+                mpls_label_t *labels)
+{
+  char *endp;
+  int i;
+
+  *num_labels = 0;
+  for (i = 0; i < MPLS_MAX_LABELS; i++)
+    {
+      u_int32_t label;
+
+      label = strtoul(label_str, &endp, 0);
+
+      /* validity checks */
+      if (endp == label_str)
+        return -1;
+
+      if (!IS_MPLS_UNRESERVED_LABEL(label))
+        return -1;
+
+      labels[i] = label;
+      if (*endp == '\0')
+        {
+          *num_labels = i + 1;
+          return 0;
+        }
+
+      /* Check separator. */
+      if (*endp != '/')
+        return -1;
+
+      label_str = endp + 1;
+    }
+
+  /* Too many labels. */
+  return -1;
+}
+
+/*
+ * Label to string conversion, labels in string separated by '/'.
+ */
+char *
+mpls_label2str (u_int8_t num_labels, mpls_label_t *labels,
+                char *buf, int len)
+{
+  buf[0] = '\0';
+  if (num_labels == 1)
+    snprintf (buf, len, "%u", labels[0]);
+  else if (num_labels == 2)
+    snprintf (buf, len, "%u/%u", labels[0], labels[1]);
+  return buf;
+}
+
 /*
  * Check that the label values used in LSP creation are consistent. The
  * main criteria is that if there is ECMP, the label operation must still
index 27073791940d00ef3075819f970b6f951d6cdde9..11949c931361e49ff341e77c7a9e485c213cd6b5 100644 (file)
@@ -38,6 +38,8 @@
 
 /* Definitions and macros. */
 
+#define MPLS_MAX_LABELS 2  /* Maximum # labels that can be pushed. */
+
 #define NHLFE_FAMILY(nhlfe)                        \
   (((nhlfe)->nexthop->type == NEXTHOP_TYPE_IPV6 || \
     (nhlfe)->nexthop->type == NEXTHOP_TYPE_IPV6_IFINDEX) ? AF_INET6 : AF_INET)
@@ -155,6 +157,20 @@ struct zebra_lsp_t_
 
 /* Function declarations. */
 
+/*
+ * String to label conversion, labels separated by '/'.
+ */
+int
+mpls_str2label (const char *label_str, u_int8_t *num_labels,
+                mpls_label_t *labels);
+
+/*
+ * Label to string conversion, labels in string separated by '/'.
+ */
+char *
+mpls_label2str (u_int8_t num_labels, mpls_label_t *labels,
+                char *buf, int len);
+
 /*
  * Check that the label values used in LSP creation are consistent. The
  * main criteria is that if there is ECMP, the label operation must still
index dc9993e7e703df4074e78d275982561d2fee4fbb..2953138dbc3e82bda4a21a43693619280506a639 100644 (file)
@@ -4,6 +4,20 @@
 #include "zebra/zserv.h"
 #include "zebra/zebra_mpls.h"
 
+int
+mpls_str2label (const char *label_str, u_int8_t *num_labels,
+                mpls_label_t *labels)
+{
+  return 0;
+}
+
+char *
+mpls_label2str (u_int8_t num_labels, mpls_label_t *labels,
+                char *buf, int len)
+{
+  return NULL;
+}
+
 int
 zebra_mpls_lsp_label_consistent (struct zebra_vrf *zvrf, mpls_label_t in_label,
                      mpls_label_t out_label, enum nexthop_types_t gtype,
index 18efe26d9f93f508de99e2fcb92dfbe2d3e5d14a..4acb77497dc08c0b398af707cc3ccf64bb134182 100644 (file)
@@ -180,6 +180,7 @@ static_install_route (afi_t afi, safi_t safi, struct prefix *p, struct static_ro
         rib_addnode (rn, rib, 1);
     }
 }
+
 static int
 static_nexthop_same (struct nexthop *nexthop, struct static_route *si)
 {
@@ -314,7 +315,8 @@ int
 static_add_route (afi_t afi, safi_t safi, u_char type, struct prefix *p,
                  union g_addr *gate, ifindex_t ifindex,
                  const char *ifname, u_char flags, u_short tag,
-                 u_char distance, struct zebra_vrf *zvrf)
+                 u_char distance, struct zebra_vrf *zvrf,
+                 struct static_nh_label *snh_label)
 {
   struct route_node *rn;
   struct static_route *si;
@@ -349,7 +351,8 @@ static_add_route (afi_t afi, safi_t safi, u_char type, struct prefix *p,
               (afi == AFI_IP6 && IPV6_ADDR_SAME (gate, &si->addr.ipv6))))
          && (! ifindex || ifindex == si->ifindex))
        {
-         if ((distance == si->distance) && (tag == si->tag))
+         if ((distance == si->distance) && (tag == si->tag) &&
+             !memcmp (&si->snh_label, snh_label, sizeof (struct static_nh_label)))
            {
              route_unlock_node (rn);
              return 0;
@@ -359,10 +362,10 @@ static_add_route (afi_t afi, safi_t safi, u_char type, struct prefix *p,
        }
     }
 
-  /* Distance or tag changed. */
+  /* Distance or tag or label changed, delete existing first. */
   if (update)
-    static_delete_route (afi, safi, type, p, gate,
-                        ifindex, update->tag, update->distance, zvrf);
+    static_delete_route (afi, safi, type, p, gate, ifindex, update->tag,
+                        update->distance, zvrf, &update->snh_label);
 
   /* Make new static route structure. */
   si = XCALLOC (MTYPE_STATIC_ROUTE, sizeof (struct static_route));
@@ -391,6 +394,9 @@ static_add_route (afi_t afi, safi_t safi, u_char type, struct prefix *p,
       break;
     }
 
+  /* Save labels, if any. */
+  memcpy (&si->snh_label, snh_label, sizeof (struct static_nh_label));
+
   /* Add new static route information to the tree with sort by
      distance value and gateway address. */
   for (pp = NULL, cp = rn->info; cp; pp = cp, cp = cp->next)
@@ -427,7 +433,8 @@ static_add_route (afi_t afi, safi_t safi, u_char type, struct prefix *p,
 int
 static_delete_route (afi_t afi, safi_t safi, u_char type, struct prefix *p,
                     union g_addr *gate, ifindex_t ifindex,
-                    u_short tag, u_char distance, struct zebra_vrf *zvrf)
+                    u_short tag, u_char distance, struct zebra_vrf *zvrf,
+                    struct static_nh_label *snh_label)
 {
   struct route_node *rn;
   struct static_route *si;
@@ -450,7 +457,9 @@ static_delete_route (afi_t afi, safi_t safi, u_char type, struct prefix *p,
                       (afi == AFI_IP && IPV4_ADDR_SAME (gate, &si->addr.ipv4)) ||
                       (afi == AFI_IP6 && IPV6_ADDR_SAME (gate, &si->addr.ipv6))))
        && (! ifindex || ifindex == si->ifindex)
-       && (! tag || (tag == si->tag)))
+       && (! tag || (tag == si->tag))
+       && (! snh_label->num_labels ||
+           !memcmp (&si->snh_label, snh_label, sizeof (struct static_nh_label))))
       break;
 
   /* Can't find static route. */
index 0f00609b5586920f53cf4b935cb15bc15bbd246e..9178a6dd45e018470e526e8b351a6894889000f6 100644 (file)
 #ifndef __ZEBRA_STATIC_H__
 #define __ZEBRA_STATIC_H__
 
+/* Static route label information */
+struct static_nh_label
+{
+  u_int8_t num_labels;
+  u_int8_t reserved[3];
+  mpls_label_t label[2];
+};
+
 /* Static route information. */
 struct static_route
 {
@@ -66,6 +74,9 @@ struct static_route
  see ZEBRA_FLAG_REJECT
      ZEBRA_FLAG_BLACKHOLE
  */
+
+  /* Label information */
+  struct static_nh_label snh_label;
 };
 
 extern void
@@ -77,13 +88,14 @@ extern int
 static_add_route (afi_t, safi_t safi, u_char type, struct prefix *p,
                  union g_addr *gate, ifindex_t ifindex,
                  const char *ifname, u_char flags, u_short tag,
-                 u_char distance, struct zebra_vrf *zvrf);
+                 u_char distance, struct zebra_vrf *zvrf,
+                 struct static_nh_label *snh_label);
 
 extern int
 static_delete_route (afi_t, safi_t safi, u_char type, struct prefix *p,
-                    union g_addr *gate, ifindex_t ifindex,
-                    u_short tag, u_char distance,
-                    struct zebra_vrf *zvrf);
+                    union g_addr *gate, ifindex_t ifindex, u_short tag,
+                    u_char distance, struct zebra_vrf *zvrf,
+                    struct static_nh_label *snh_label);
 
 
 #endif
index 95fbfeffce2a28221ac04b862da48097e1cbe272..fa2a2708894d870206eb84a353a44b55641da934 100644 (file)
@@ -58,7 +58,7 @@ zebra_static_ipv4 (struct vty *vty, safi_t safi, int add_cmd,
                   const char *dest_str, const char *mask_str,
                   const char *gate_str, const char *flag_str,
                   const char *tag_str, const char *distance_str,
-                  const char *vrf_id_str)
+                  const char *vrf_id_str, const char *label_str)
 {
   int ret;
   u_char distance;
@@ -71,7 +71,9 @@ zebra_static_ipv4 (struct vty *vty, safi_t safi, int add_cmd,
   unsigned int ifindex = 0;
   const char *ifname = NULL;
   u_char type = STATIC_IPV4_BLACKHOLE;
+  struct static_nh_label snh_label;
 
+  memset (&snh_label, 0, sizeof (struct static_nh_label));
   ret = str2prefix (dest_str, &p);
   if (ret <= 0)
     {
@@ -113,6 +115,17 @@ zebra_static_ipv4 (struct vty *vty, safi_t safi, int add_cmd,
       return CMD_WARNING;
     }
 
+  /* Labels */
+  if (label_str)
+    {
+      if (mpls_str2label (label_str, &snh_label.num_labels,
+                          snh_label.label))
+        {
+          vty_out (vty, "%% Malformed label(s)%s", VTY_NEWLINE);
+          return CMD_WARNING;
+        }
+    }
+
   /* Null0 static route.  */
   if ((gate_str != NULL) && (strncasecmp (gate_str, "Null0", strlen (gate_str)) == 0))
     {
@@ -122,9 +135,11 @@ zebra_static_ipv4 (struct vty *vty, safi_t safi, int add_cmd,
           return CMD_WARNING;
         }
       if (add_cmd)
-        static_add_route (AFI_IP, safi, type, &p, NULL, ifindex, ifname, ZEBRA_FLAG_BLACKHOLE, tag, distance, zvrf);
+        static_add_route (AFI_IP, safi, type, &p, NULL, ifindex, ifname,
+                         ZEBRA_FLAG_BLACKHOLE, tag, distance, zvrf, &snh_label);
       else
-        static_delete_route (AFI_IP, safi, type, &p, NULL, ifindex, tag, distance, zvrf);
+        static_delete_route (AFI_IP, safi, type, &p, NULL, ifindex, tag,
+                            distance, zvrf, &snh_label);
       return CMD_SUCCESS;
     }
 
@@ -148,9 +163,11 @@ zebra_static_ipv4 (struct vty *vty, safi_t safi, int add_cmd,
   if (gate_str == NULL)
   {
     if (add_cmd)
-      static_add_route (AFI_IP, safi, type, &p, NULL, ifindex, ifname, flag, tag, distance, zvrf);
+      static_add_route (AFI_IP, safi, type, &p, NULL, ifindex, ifname, flag,
+                       tag, distance, zvrf, &snh_label);
     else
-      static_delete_route (AFI_IP, safi, type, &p, NULL, ifindex, tag, distance, zvrf);
+      static_delete_route (AFI_IP, safi, type, &p, NULL, ifindex, tag, distance,
+                          zvrf, &snh_label);
 
     return CMD_SUCCESS;
   }
@@ -175,9 +192,13 @@ zebra_static_ipv4 (struct vty *vty, safi_t safi, int add_cmd,
     type = STATIC_IPV4_GATEWAY;
 
   if (add_cmd)
-    static_add_route (AFI_IP, safi, type, &p, ifindex ? NULL : (union g_addr *)&gate, ifindex, ifname, flag, tag, distance, zvrf);
+    static_add_route (AFI_IP, safi, type, &p,
+                     ifindex ? NULL : (union g_addr *)&gate, ifindex, ifname,
+                     flag, tag, distance, zvrf, &snh_label);
   else
-    static_delete_route (AFI_IP, safi, type, &p, ifindex ? NULL : (union g_addr *)&gate, ifindex, tag, distance, zvrf);
+    static_delete_route (AFI_IP, safi, type, &p,
+                        ifindex ? NULL : (union g_addr *)&gate, ifindex, tag,
+                        distance, zvrf, &snh_label);
 
   return CMD_SUCCESS;
 }
@@ -193,7 +214,8 @@ DEFUN (ip_mroute_dist,
        "Nexthop interface name\n"
        "Distance\n")
 {
-  return zebra_static_ipv4 (vty, SAFI_MULTICAST, 1, argv[0], NULL, argv[1], NULL, NULL, argc > 2 ? argv[2] : NULL, NULL);
+  return zebra_static_ipv4 (vty, SAFI_MULTICAST, 1, argv[0], NULL, argv[1],
+                           NULL, NULL, argc > 2 ? argv[2] : NULL, NULL, NULL);
 }
 
 ALIAS (ip_mroute_dist,
@@ -215,7 +237,8 @@ DEFUN (no_ip_mroute_dist,
        "Nexthop interface name\n"
        "Distance\n")
 {
-  return zebra_static_ipv4 (vty, SAFI_MULTICAST, 0, argv[0], NULL, argv[1], NULL, NULL, argc > 2 ? argv[2] : NULL, NULL);
+  return zebra_static_ipv4 (vty, SAFI_MULTICAST, 0, argv[0], NULL, argv[1],
+                           NULL, NULL, argc > 2 ? argv[2] : NULL, NULL, NULL);
 }
 
 ALIAS (no_ip_mroute_dist,
@@ -328,21 +351,23 @@ DEFUN (show_ip_rpf_addr,
 /* Static route configuration.  */
 DEFUN (ip_route, 
        ip_route_cmd,
-       "ip route A.B.C.D/M (A.B.C.D|INTERFACE|null0)",
+       "ip route A.B.C.D/M (A.B.C.D|INTERFACE|null0) {label WORD}",
        IP_STR
        "Establish static routes\n"
        "IP destination prefix (e.g. 10.0.0.0/8)\n"
        "IP gateway address\n"
        "IP gateway interface name\n"
-       "Null interface\n")
+       "Null interface\n"
+       "Specify label(s) for this route\n"
+       "One or more labels separated by '/'\n")
 {
   return zebra_static_ipv4 (vty, SAFI_UNICAST, 1, argv[0], NULL, argv[1], NULL, NULL,
-                            NULL, NULL);
+                            NULL, NULL, argv[2]);
 }
 
 DEFUN (ip_route_tag,
        ip_route_tag_cmd,
-       "ip route A.B.C.D/M (A.B.C.D|INTERFACE|null0) tag <1-65535>",
+       "ip route A.B.C.D/M (A.B.C.D|INTERFACE|null0) tag <1-65535> {label WORD}",
        IP_STR
        "Establish static routes\n"
        "IP destination prefix (e.g. 10.0.0.0/8)\n"
@@ -350,30 +375,34 @@ DEFUN (ip_route_tag,
        "IP gateway interface name\n"
        "Null interface\n"
        "Set tag for this route\n"
-       "Tag value\n")
+       "Tag value\n"
+       "Specify label(s) for this route\n"
+       "One or more labels separated by '/'\n")
 {
   return zebra_static_ipv4 (vty, SAFI_UNICAST, 1, argv[0], NULL, argv[1], NULL, argv[2],
-                            NULL, NULL);
+                            NULL, NULL, argv[3]);
 }
 
 DEFUN (ip_route_flags,
        ip_route_flags_cmd,
-       "ip route A.B.C.D/M (A.B.C.D|INTERFACE) (reject|blackhole)",
+       "ip route A.B.C.D/M (A.B.C.D|INTERFACE) (reject|blackhole) {label WORD}",
        IP_STR
        "Establish static routes\n"
        "IP destination prefix (e.g. 10.0.0.0/8)\n"
        "IP gateway address\n"
        "IP gateway interface name\n"
        "Emit an ICMP unreachable when matched\n"
-       "Silently discard pkts when matched\n")
+       "Silently discard pkts when matched\n"
+       "Specify label(s) for this route\n"
+       "One or more labels separated by '/'\n")
 {
   return zebra_static_ipv4 (vty, SAFI_UNICAST, 1, argv[0], NULL, argv[1], argv[2], NULL,
-                            NULL, NULL);
+                            NULL, NULL, argv[3]);
 }
 
 DEFUN (ip_route_flags_tag,
        ip_route_flags_tag_cmd,
-       "ip route A.B.C.D/M (A.B.C.D|INTERFACE) (reject|blackhole) tag <1-65535>",
+       "ip route A.B.C.D/M (A.B.C.D|INTERFACE) (reject|blackhole) tag <1-65535> {label WORD}",
        IP_STR
        "Establish static routes\n"
        "IP destination prefix (e.g. 10.0.0.0/8)\n"
@@ -382,11 +411,13 @@ DEFUN (ip_route_flags_tag,
        "Emit an ICMP unreachable when matched\n"
        "Silently discard pkts when matched\n"
        "Set tag for this route\n"
-       "Tag value\n")
+       "Tag value\n"
+       "Specify label(s) for this route\n"
+       "One or more labels separated by '/'\n")
 
 {
   return zebra_static_ipv4 (vty, SAFI_UNICAST, 1, argv[0], NULL, argv[1], argv[2], argv[3],
-                            NULL, NULL);
+                            NULL, NULL, argv[4]);
 }
 
 DEFUN (ip_route_flags2,
@@ -399,7 +430,7 @@ DEFUN (ip_route_flags2,
        "Silently discard pkts when matched\n")
 {
   return zebra_static_ipv4 (vty, SAFI_UNICAST, 1, argv[0], NULL, NULL, argv[1], NULL,
-                            NULL, NULL);
+                            NULL, NULL, NULL);
 }
 
 DEFUN (ip_route_flags2_tag,
@@ -415,28 +446,30 @@ DEFUN (ip_route_flags2_tag,
 
 {
   return zebra_static_ipv4 (vty, SAFI_UNICAST, 1, argv[0], NULL, NULL, argv[1], argv[2],
-                            NULL, NULL);
+                            NULL, NULL, NULL);
 }
 
 /* Mask as A.B.C.D format.  */
 DEFUN (ip_route_mask,
        ip_route_mask_cmd,
-       "ip route A.B.C.D A.B.C.D (A.B.C.D|INTERFACE|null0)",
+       "ip route A.B.C.D A.B.C.D (A.B.C.D|INTERFACE|null0) {label WORD}",
        IP_STR
        "Establish static routes\n"
        "IP destination prefix\n"
        "IP destination prefix mask\n"
        "IP gateway address\n"
        "IP gateway interface name\n"
-       "Null interface\n")
+       "Null interface\n"
+       "Specify label(s) for this route\n"
+       "One or more labels separated by '/'\n")
 {
   return zebra_static_ipv4 (vty, SAFI_UNICAST, 1, argv[0], argv[1], argv[2], NULL, NULL,
-                            NULL, NULL);
+                            NULL, NULL, argv[3]);
 }
 
 DEFUN (ip_route_mask_tag,
        ip_route_mask_tag_cmd,
-       "ip route A.B.C.D A.B.C.D (A.B.C.D|INTERFACE|null0) tag <1-65535>",
+       "ip route A.B.C.D A.B.C.D (A.B.C.D|INTERFACE|null0) tag <1-65535> {label WORD}",
        IP_STR
        "Establish static routes\n"
        "IP destination prefix\n"
@@ -445,11 +478,13 @@ DEFUN (ip_route_mask_tag,
        "IP gateway interface name\n"
        "Null interface\n"
        "Set tag for this route\n"
-       "Tag value\n")
+       "Tag value\n"
+       "Specify label(s) for this route\n"
+       "One or more labels separated by '/'\n")
 
 {
   return zebra_static_ipv4 (vty, SAFI_UNICAST, 1, argv[0], argv[1], argv[2], NULL, argv[3],
-                            NULL, NULL);
+                            NULL, NULL, argv[4]);
 }
 
 DEFUN (ip_route_mask_flags,
@@ -465,7 +500,7 @@ DEFUN (ip_route_mask_flags,
        "Silently discard pkts when matched\n")
 {
   return zebra_static_ipv4 (vty, SAFI_UNICAST, 1, argv[0], argv[1], argv[2], argv[3], NULL,
-                            NULL, NULL);
+                            NULL, NULL, NULL);
 }
 
 DEFUN (ip_route_mask_flags_tag,
@@ -484,7 +519,7 @@ DEFUN (ip_route_mask_flags_tag,
 
 {
   return zebra_static_ipv4 (vty, SAFI_UNICAST, 1, argv[0], argv[1], argv[2], argv[3], argv[4],
-                            NULL, NULL);
+                            NULL, NULL, NULL);
 }
 
 DEFUN (ip_route_mask_flags2,
@@ -498,7 +533,7 @@ DEFUN (ip_route_mask_flags2,
        "Silently discard pkts when matched\n")
 {
   return zebra_static_ipv4 (vty, SAFI_UNICAST, 1, argv[0], argv[1], NULL, argv[2], NULL,
-                            NULL, NULL);
+                            NULL, NULL, NULL);
 }
 
 DEFUN (ip_route_mask_flags2_tag,
@@ -514,28 +549,30 @@ DEFUN (ip_route_mask_flags2_tag,
        "Tag value\n")
 {
   return zebra_static_ipv4 (vty, SAFI_UNICAST, 1, argv[0], argv[1], NULL, argv[2], argv[3],
-                            NULL, NULL);
+                            NULL, NULL, NULL);
 }
 
 /* Distance option value.  */
 DEFUN (ip_route_distance,
        ip_route_distance_cmd,
-       "ip route A.B.C.D/M (A.B.C.D|INTERFACE|null0) <1-255>",
+       "ip route A.B.C.D/M (A.B.C.D|INTERFACE|null0) <1-255> {label WORD}",
        IP_STR
        "Establish static routes\n"
        "IP destination prefix (e.g. 10.0.0.0/8)\n"
        "IP gateway address\n"
        "IP gateway interface name\n"
        "Null interface\n"
-       "Distance value for this route\n")
+       "Distance value for this route\n"
+       "Specify label(s) for this route\n"
+       "One or more labels separated by '/'\n")
 {
   return zebra_static_ipv4 (vty, SAFI_UNICAST, 1, argv[0], NULL, argv[1], NULL, NULL,
-                            argv[2], NULL);
+                            argv[2], NULL, argv[3]);
 }
 
 DEFUN (ip_route_tag_distance,
        ip_route_tag_distance_cmd,
-       "ip route A.B.C.D/M (A.B.C.D|INTERFACE|null0) tag <1-65535> <1-255>",
+       "ip route A.B.C.D/M (A.B.C.D|INTERFACE|null0) tag <1-65535> <1-255> {label WORD}",
        IP_STR
        "Establish static routes\n"
        "IP destination prefix (e.g. 10.0.0.0/8)\n"
@@ -544,11 +581,13 @@ DEFUN (ip_route_tag_distance,
        "Null interface\n"
        "Set tag for this route\n"
        "Tag value\n"
-       "Distance value for this route\n")
+       "Distance value for this route\n"
+       "Specify label(s) for this route\n"
+       "One or more labels separated by '/'\n")
 
 {
   return zebra_static_ipv4 (vty, SAFI_UNICAST, 1, argv[0], NULL, argv[1], NULL, argv[2],
-                            argv[3], NULL);
+                            argv[3], NULL, argv[4]);
 }
 
 DEFUN (ip_route_flags_distance,
@@ -564,7 +603,7 @@ DEFUN (ip_route_flags_distance,
        "Distance value for this route\n")
 {
   return zebra_static_ipv4 (vty, SAFI_UNICAST, 1, argv[0], NULL, argv[1], argv[2], NULL,
-                            argv[3], NULL);
+                            argv[3], NULL, NULL);
 }
 
 DEFUN (ip_route_flags_tag_distance,
@@ -582,7 +621,7 @@ DEFUN (ip_route_flags_tag_distance,
        "Distance value for this route\n")
 {
   return zebra_static_ipv4 (vty, SAFI_UNICAST, 1, argv[0], NULL, argv[1], argv[2], argv[3],
-                            argv[4], NULL);
+                            argv[4], NULL, NULL);
 }
 
 DEFUN (ip_route_flags_distance2,
@@ -596,7 +635,7 @@ DEFUN (ip_route_flags_distance2,
        "Distance value for this route\n")
 {
   return zebra_static_ipv4 (vty, SAFI_UNICAST, 1, argv[0], NULL, NULL, argv[1], NULL,
-                            argv[2], NULL);
+                            argv[2], NULL, NULL);
 }
 
 DEFUN (ip_route_flags_tag_distance2,
@@ -612,12 +651,12 @@ DEFUN (ip_route_flags_tag_distance2,
        "Distance value for this route\n")
 {
   return zebra_static_ipv4 (vty, SAFI_UNICAST, 1, argv[0], NULL, NULL, argv[1], argv[2],
-                            argv[3], NULL);
+                            argv[3], NULL, NULL);
 }
 
 DEFUN (ip_route_mask_distance,
        ip_route_mask_distance_cmd,
-       "ip route A.B.C.D A.B.C.D (A.B.C.D|INTERFACE|null0) <1-255>",
+       "ip route A.B.C.D A.B.C.D (A.B.C.D|INTERFACE|null0) <1-255> {label WORD}",
        IP_STR
        "Establish static routes\n"
        "IP destination prefix\n"
@@ -625,15 +664,17 @@ DEFUN (ip_route_mask_distance,
        "IP gateway address\n"
        "IP gateway interface name\n"
        "Null interface\n"
-       "Distance value for this route\n")
+       "Distance value for this route\n"
+       "Specify label(s) for this route\n"
+       "One or more labels separated by '/'\n")
 {
   return zebra_static_ipv4 (vty, SAFI_UNICAST, 1, argv[0], argv[1], argv[2], NULL, NULL,
-                            argv[3], NULL);
+                            argv[3], NULL, argv[4]);
 }
 
 DEFUN (ip_route_mask_tag_distance,
        ip_route_mask_tag_distance_cmd,
-       "ip route A.B.C.D A.B.C.D (A.B.C.D|INTERFACE|null0) tag <1-65535> <1-255>",
+       "ip route A.B.C.D A.B.C.D (A.B.C.D|INTERFACE|null0) tag <1-65535> <1-255> {label WORD}",
        IP_STR
        "Establish static routes\n"
        "IP destination prefix\n"
@@ -643,10 +684,12 @@ DEFUN (ip_route_mask_tag_distance,
        "Null interface\n"
        "Set tag for this route\n"
        "Tag value\n"
-       "Distance value for this route\n")
+       "Distance value for this route\n"
+       "Specify label(s) for this route\n"
+       "One or more labels separated by '/'\n")
 {
   return zebra_static_ipv4 (vty, SAFI_UNICAST, 1, argv[0], argv[1], argv[2], NULL, argv[3],
-                            argv[4], NULL);
+                            argv[4], NULL, argv[5]);
 }
 
 DEFUN (ip_route_mask_flags_tag_distance,
@@ -665,7 +708,7 @@ DEFUN (ip_route_mask_flags_tag_distance,
        "Silently discard pkts when matched\n")
 {
   return zebra_static_ipv4 (vty, SAFI_UNICAST, 1, argv[0], argv[1], argv[2], argv[3], argv[4],
-                            argv[5], NULL);
+                            argv[5], NULL, NULL);
 }
 
 
@@ -683,7 +726,7 @@ DEFUN (ip_route_mask_flags_distance,
        "Distance value for this route\n")
 {
   return zebra_static_ipv4 (vty, SAFI_UNICAST, 1, argv[0], argv[1], argv[2], argv[3], NULL,
-                            argv[4], NULL);
+                            argv[4], NULL, NULL);
 }
 
 DEFUN (ip_route_mask_flags_distance2,
@@ -698,7 +741,7 @@ DEFUN (ip_route_mask_flags_distance2,
        "Distance value for this route\n")
 {
   return zebra_static_ipv4 (vty, SAFI_UNICAST, 1, argv[0], argv[1], NULL, argv[2], NULL,
-                            argv[3], NULL);
+                            argv[3], NULL, NULL);
 }
 
 DEFUN (ip_route_mask_flags_tag_distance2,
@@ -715,27 +758,29 @@ DEFUN (ip_route_mask_flags_tag_distance2,
        "Silently discard pkts when matched\n")
 {
   return zebra_static_ipv4 (vty, SAFI_UNICAST, 1, argv[0], argv[1], NULL, argv[2], argv[3],
-                            argv[4], NULL);
+                            argv[4], NULL, NULL);
 }
 
 DEFUN (no_ip_route, 
        no_ip_route_cmd,
-       "no ip route A.B.C.D/M (A.B.C.D|INTERFACE|null0)",
+       "no ip route A.B.C.D/M (A.B.C.D|INTERFACE|null0) {label WORD}",
        NO_STR
        IP_STR
        "Establish static routes\n"
        "IP destination prefix (e.g. 10.0.0.0/8)\n"
        "IP gateway address\n"
        "IP gateway interface name\n"
-       "Null interface\n")
+       "Null interface\n"
+       "Specify label(s) for this route\n"
+       "One or more labels separated by '/'\n")
 {
   return zebra_static_ipv4 (vty, SAFI_UNICAST, 0, argv[0], NULL, argv[1], NULL, NULL,
-                            NULL, NULL);
+                            NULL, NULL, argv[2]);
 }
 
 DEFUN (no_ip_route_tag,
        no_ip_route_tag_cmd,
-       "no ip route A.B.C.D/M (A.B.C.D|INTERFACE|null0) tag <1-65535>",
+       "no ip route A.B.C.D/M (A.B.C.D|INTERFACE|null0) tag <1-65535> {label WORD}",
        NO_STR
        IP_STR
        "Establish static routes\n"
@@ -744,10 +789,12 @@ DEFUN (no_ip_route_tag,
        "IP gateway interface name\n"
        "Null interface\n"
        "Tag of this route\n"
-       "Tag value\n")
+       "Tag value\n"
+       "Specify label(s) for this route\n"
+       "One or more labels separated by '/'\n")
 {
   return zebra_static_ipv4 (vty, SAFI_UNICAST, 0, argv[0], NULL, argv[1], NULL, argv[2],
-                            NULL, NULL);
+                            NULL, NULL, argv[3]);
 }
 
 ALIAS (no_ip_route,
@@ -787,7 +834,7 @@ DEFUN (no_ip_route_flags2,
        "Silently discard pkts when matched\n")
 {
   return zebra_static_ipv4 (vty, SAFI_UNICAST, 0, argv[0], NULL, NULL, NULL, NULL,
-                            NULL, NULL);
+                            NULL, NULL, NULL);
 }
 
 DEFUN (no_ip_route_flags2_tag,
@@ -803,12 +850,12 @@ DEFUN (no_ip_route_flags2_tag,
        "Tag value\n")
 {
   return zebra_static_ipv4 (vty, SAFI_UNICAST, 0, argv[0], NULL, NULL, NULL, argv[1],
-                            NULL, NULL);
+                            NULL, NULL, NULL);
 }
 
 DEFUN (no_ip_route_mask,
        no_ip_route_mask_cmd,
-       "no ip route A.B.C.D A.B.C.D (A.B.C.D|INTERFACE|null0)",
+       "no ip route A.B.C.D A.B.C.D (A.B.C.D|INTERFACE|null0) {label WORD}",
        NO_STR
        IP_STR
        "Establish static routes\n"
@@ -816,15 +863,17 @@ DEFUN (no_ip_route_mask,
        "IP destination prefix mask\n"
        "IP gateway address\n"
        "IP gateway interface name\n"
-       "Null interface\n")
+       "Null interface\n"
+       "Specify label(s) for this route\n"
+       "One or more labels separated by '/'\n")
 {
   return zebra_static_ipv4 (vty, SAFI_UNICAST, 0, argv[0], argv[1], argv[2], NULL, NULL,
-                            NULL, NULL);
+                            NULL, NULL, argv[3]);
 }
 
 DEFUN (no_ip_route_mask_tag,
        no_ip_route_mask_tag_cmd,
-       "no ip route A.B.C.D A.B.C.D (A.B.C.D|INTERFACE|null0) tag <1-65535>",
+       "no ip route A.B.C.D A.B.C.D (A.B.C.D|INTERFACE|null0) tag <1-65535> {label WORD}",
        NO_STR
        IP_STR
        "Establish static routes\n"
@@ -834,10 +883,12 @@ DEFUN (no_ip_route_mask_tag,
        "IP gateway interface name\n"
        "Null interface\n"
        "Tag of this route\n"
-       "Tag value\n")
+       "Tag value\n"
+       "Specify label(s) for this route\n"
+       "One or more labels separated by '/'\n")
 {
   return zebra_static_ipv4 (vty, SAFI_UNICAST, 0, argv[0], argv[1], argv[2], NULL, argv[3],
-                            NULL, NULL);
+                            NULL, NULL, argv[4]);
 }
 
 ALIAS (no_ip_route_mask,
@@ -880,7 +931,7 @@ DEFUN (no_ip_route_mask_flags2,
        "Silently discard pkts when matched\n")
 {
   return zebra_static_ipv4 (vty, SAFI_UNICAST, 0, argv[0], argv[1], NULL, NULL, NULL,
-                            NULL, NULL);
+                            NULL, NULL, NULL);
 }
 
 DEFUN (no_ip_route_mask_flags2_tag,
@@ -897,12 +948,12 @@ DEFUN (no_ip_route_mask_flags2_tag,
        "Tag value\n")
 {
   return zebra_static_ipv4 (vty, SAFI_UNICAST, 0, argv[0], argv[1], NULL, NULL, argv[2],
-                            NULL, NULL);
+                            NULL, NULL, NULL);
 }
 
 DEFUN (no_ip_route_distance,
        no_ip_route_distance_cmd,
-       "no ip route A.B.C.D/M (A.B.C.D|INTERFACE|null0) <1-255>",
+       "no ip route A.B.C.D/M (A.B.C.D|INTERFACE|null0) <1-255> {label WORD}",
        NO_STR
        IP_STR
        "Establish static routes\n"
@@ -910,15 +961,17 @@ DEFUN (no_ip_route_distance,
        "IP gateway address\n"
        "IP gateway interface name\n"
        "Null interface\n"
-       "Distance value for this route\n")
+       "Distance value for this route\n"
+       "Specify label(s) for this route\n"
+       "One or more labels separated by '/'\n")
 {
   return zebra_static_ipv4 (vty, SAFI_UNICAST, 0, argv[0], NULL, argv[1], NULL, NULL,
-                            argv[2], NULL);
+                            argv[2], NULL, argv[3]);
 }
 
 DEFUN (no_ip_route_tag_distance,
        no_ip_route_tag_distance_cmd,
-       "no ip route A.B.C.D/M (A.B.C.D|INTERFACE|null0) tag <1-65535> <1-255>",
+       "no ip route A.B.C.D/M (A.B.C.D|INTERFACE|null0) tag <1-65535> <1-255> {label WORD}",
        NO_STR
        IP_STR
        "Establish static routes\n"
@@ -928,10 +981,12 @@ DEFUN (no_ip_route_tag_distance,
        "Null interface\n"
        "Tag of this route\n"
        "Tag value\n"
-       "Distance value for this route\n")
+       "Distance value for this route\n"
+       "Specify label(s) for this route\n"
+       "One or more labels separated by '/'\n")
 {
   return zebra_static_ipv4 (vty, SAFI_UNICAST, 0, argv[0], NULL, argv[1], NULL, argv[2],
-                            argv[3], NULL);
+                            argv[3], NULL, argv[4]);
 }
 
 DEFUN (no_ip_route_flags_distance,
@@ -948,7 +1003,7 @@ DEFUN (no_ip_route_flags_distance,
        "Distance value for this route\n")
 {
   return zebra_static_ipv4 (vty, SAFI_UNICAST, 0, argv[0], NULL, argv[1], argv[2], NULL,
-                            argv[3], NULL);
+                            argv[3], NULL, NULL);
 }
 
 DEFUN (no_ip_route_flags_tag_distance,
@@ -967,7 +1022,7 @@ DEFUN (no_ip_route_flags_tag_distance,
        "Distance value for this route\n")
 {
   return zebra_static_ipv4 (vty, SAFI_UNICAST, 0, argv[0], NULL, argv[1], argv[2], argv[3],
-                            argv[4], NULL);
+                            argv[4], NULL, NULL);
 }
 
 DEFUN (no_ip_route_flags_distance2,
@@ -982,12 +1037,12 @@ DEFUN (no_ip_route_flags_distance2,
        "Distance value for this route\n")
 {
   return zebra_static_ipv4 (vty, SAFI_UNICAST, 0, argv[0], NULL, NULL, argv[1], NULL,
-                            argv[2], NULL);
+                            argv[2], NULL, NULL);
 }
 
 DEFUN (no_ip_route_flags_tag_distance2,
        no_ip_route_flags_tag_distance2_cmd,
-       "no ip route A.B.C.D/M (reject|blackhole) tag <1-65535> <1-255>",
+       "no ip route A.B.C.D A.B.C.D (A.B.C.D|INTERFACE|null0) <1-255> {label WORD}",
        NO_STR
        IP_STR
        "Establish static routes\n"
@@ -996,15 +1051,17 @@ DEFUN (no_ip_route_flags_tag_distance2,
        "Silently discard pkts when matched\n"
        "Tag of this route\n"
        "Tag value\n"
-       "Distance value for this route\n")
+       "Distance value for this route\n"
+       "Specify label(s) for this route\n"
+       "One or more labels separated by '/'\n")
 {
   return zebra_static_ipv4 (vty, SAFI_UNICAST, 0, argv[0], NULL, NULL, argv[1], argv[2],
-                            argv[3], NULL);
+                            argv[3], NULL, argv[4]);
 }
 
 DEFUN (no_ip_route_mask_distance,
        no_ip_route_mask_distance_cmd,
-       "no ip route A.B.C.D A.B.C.D (A.B.C.D|INTERFACE|null0) <1-255>",
+       "no ip route A.B.C.D A.B.C.D (A.B.C.D|INTERFACE|null0) tag <1-65535> <1-255> {label WORD}",
        NO_STR
        IP_STR
        "Establish static routes\n"
@@ -1013,15 +1070,17 @@ DEFUN (no_ip_route_mask_distance,
        "IP gateway address\n"
        "IP gateway interface name\n"
        "Null interface\n"
-       "Distance value for this route\n")
+       "Distance value for this route\n"
+       "Specify label(s) for this route\n"
+       "One or more labels separated by '/'\n")
 {
-  return zebra_static_ipv4 (vty, SAFI_UNICAST, 0, argv[0], argv[1], argv[2], NULL, NULL,
-                            argv[3], NULL);
+  return zebra_static_ipv4 (vty, SAFI_UNICAST, 0, argv[0], argv[1], argv[2], NULL, argv[3],
+                            argv[4], NULL, argv[5]);
 }
 
 DEFUN (no_ip_route_mask_tag_distance,
        no_ip_route_mask_tag_distance_cmd,
-       "no ip route A.B.C.D A.B.C.D (A.B.C.D|INTERFACE|null0) tag <1-65535> <1-255>",
+       "no ip route A.B.C.D A.B.C.D (A.B.C.D|INTERFACE|null0) tag <1-65535> <1-255> {label WORD}",
        NO_STR
        IP_STR
        "Establish static routes\n"
@@ -1032,10 +1091,12 @@ DEFUN (no_ip_route_mask_tag_distance,
        "Null interface\n"
        "Tag of this route\n"
        "Tag value\n"
-       "Distance value for this route\n")
+       "Distance value for this route\n"
+       "Specify label(s) for this route\n"
+       "One or more labels separated by '/'\n")
 {
   return zebra_static_ipv4 (vty, SAFI_UNICAST, 0, argv[0], argv[1], argv[2], NULL, argv[3],
-                            argv[4], NULL);
+                            argv[4], NULL, argv[5]);
 }
 
 DEFUN (no_ip_route_mask_flags_distance,
@@ -1053,7 +1114,7 @@ DEFUN (no_ip_route_mask_flags_distance,
        "Distance value for this route\n")
 {
   return zebra_static_ipv4 (vty, SAFI_UNICAST, 0, argv[0], argv[1], argv[2], argv[3], NULL,
-                            argv[4], NULL);
+                            argv[4], NULL, NULL);
 }
 
 DEFUN (no_ip_route_mask_flags_tag_distance,
@@ -1073,7 +1134,7 @@ DEFUN (no_ip_route_mask_flags_tag_distance,
        "Distance value for this route\n")
 {
   return zebra_static_ipv4 (vty, SAFI_UNICAST, 0, argv[0], argv[1], argv[2], argv[3], argv[4],
-                            argv[5], NULL);
+                            argv[5], NULL, NULL);
 }
 
 DEFUN (no_ip_route_mask_flags_distance2,
@@ -1089,7 +1150,7 @@ DEFUN (no_ip_route_mask_flags_distance2,
        "Distance value for this route\n")
 {
   return zebra_static_ipv4 (vty, SAFI_UNICAST, 0, argv[0], argv[1], NULL, argv[2], NULL,
-                            argv[3], NULL);
+                            argv[3], NULL, NULL);
 }
 
 DEFUN (no_ip_route_mask_flags_tag_distance2,
@@ -1107,7 +1168,7 @@ DEFUN (no_ip_route_mask_flags_tag_distance2,
        "Distance value for this route\n")
 {
   return zebra_static_ipv4 (vty, SAFI_UNICAST, 0, argv[0], argv[1], NULL, argv[2], argv[3],
-                            argv[4], NULL);
+                            argv[4], NULL, NULL);
 }
 
 /* Static route configuration.  */
@@ -1122,7 +1183,8 @@ DEFUN (ip_route_vrf,
        "Null interface\n"
        VRF_CMD_HELP_STR)
 {
-  return zebra_static_ipv4 (vty, SAFI_UNICAST, 1, argv[0], NULL, argv[1], NULL, NULL, NULL, argv[2]);
+  return zebra_static_ipv4 (vty, SAFI_UNICAST, 1, argv[0], NULL, argv[1], NULL,
+                           NULL, NULL, argv[2], NULL);
 }
 
 DEFUN (ip_route_tag_vrf,
@@ -1138,7 +1200,8 @@ DEFUN (ip_route_tag_vrf,
        "Tag value\n"
        VRF_CMD_HELP_STR)
 {
-  return zebra_static_ipv4 (vty, SAFI_UNICAST, 1, argv[0], NULL, argv[1], NULL, argv[2], NULL, argv[3]);
+  return zebra_static_ipv4 (vty, SAFI_UNICAST, 1, argv[0], NULL, argv[1], NULL,
+                           argv[2], NULL, argv[3], NULL);
 }
 
 DEFUN (ip_route_flags_vrf,
@@ -1153,7 +1216,8 @@ DEFUN (ip_route_flags_vrf,
        "Silently discard pkts when matched\n"
        VRF_CMD_HELP_STR)
 {
-  return zebra_static_ipv4 (vty, SAFI_UNICAST, 1, argv[0], NULL, argv[1], argv[2], NULL, NULL, argv[3]);
+  return zebra_static_ipv4 (vty, SAFI_UNICAST, 1, argv[0], NULL, argv[1],
+                           argv[2], NULL, NULL, argv[3], NULL);
 }
 
 DEFUN (ip_route_flags_tag_vrf,
@@ -1171,7 +1235,8 @@ DEFUN (ip_route_flags_tag_vrf,
        VRF_CMD_HELP_STR)
 
 {
-  return zebra_static_ipv4 (vty, SAFI_UNICAST, 1, argv[0], NULL, argv[1], argv[2], argv[3], NULL, argv[4]);
+  return zebra_static_ipv4 (vty, SAFI_UNICAST, 1, argv[0], NULL, argv[1],
+                           argv[2], argv[3], NULL, argv[4], NULL);
 }
 
 DEFUN (ip_route_flags2_vrf,
@@ -1184,7 +1249,8 @@ DEFUN (ip_route_flags2_vrf,
        "Silently discard pkts when matched\n"
        VRF_CMD_HELP_STR)
 {
-  return zebra_static_ipv4 (vty, SAFI_UNICAST, 1, argv[0], NULL, NULL, argv[1], NULL, NULL, argv[2]);
+  return zebra_static_ipv4 (vty, SAFI_UNICAST, 1, argv[0], NULL, NULL, argv[1],
+                           NULL, NULL, argv[2], NULL);
 }
 
 DEFUN (ip_route_flags2_tag_vrf,
@@ -1200,7 +1266,8 @@ DEFUN (ip_route_flags2_tag_vrf,
        VRF_CMD_HELP_STR)
 
 {
-  return zebra_static_ipv4 (vty, SAFI_UNICAST, 1, argv[0], NULL, NULL, argv[1], argv[2], NULL, argv[3]);
+  return zebra_static_ipv4 (vty, SAFI_UNICAST, 1, argv[0], NULL, NULL, argv[1],
+                           argv[2], NULL, argv[3], NULL);
 }
 
 /* Mask as A.B.C.D format.  */
@@ -1216,7 +1283,8 @@ DEFUN (ip_route_mask_vrf,
        "Null interface\n"
        VRF_CMD_HELP_STR)
 {
-  return zebra_static_ipv4 (vty, SAFI_UNICAST, 1, argv[0], argv[1], argv[2], NULL, NULL, NULL, argv[3]);
+  return zebra_static_ipv4 (vty, SAFI_UNICAST, 1, argv[0], argv[1], argv[2],
+                           NULL, NULL, NULL, argv[3], NULL);
 }
 
 DEFUN (ip_route_mask_tag_vrf,
@@ -1234,7 +1302,8 @@ DEFUN (ip_route_mask_tag_vrf,
        VRF_CMD_HELP_STR)
 
 {
-  return zebra_static_ipv4 (vty, SAFI_UNICAST, 1, argv[0], argv[1], argv[2], NULL, argv[3], NULL, argv[4]);
+  return zebra_static_ipv4 (vty, SAFI_UNICAST, 1, argv[0], argv[1], argv[2],
+                           NULL, argv[3], NULL, argv[4], NULL);
 }
 
 DEFUN (ip_route_mask_flags_vrf,
@@ -1250,7 +1319,8 @@ DEFUN (ip_route_mask_flags_vrf,
        "Silently discard pkts when matched\n"
        VRF_CMD_HELP_STR)
 {
-  return zebra_static_ipv4 (vty, SAFI_UNICAST, 1, argv[0], argv[1], argv[2], argv[3], NULL, NULL, argv[4]);
+  return zebra_static_ipv4 (vty, SAFI_UNICAST, 1, argv[0], argv[1], argv[2],
+                           argv[3], NULL, NULL, argv[4], NULL);
 }
 
 DEFUN (ip_route_mask_flags_tag_vrf,
@@ -1269,7 +1339,8 @@ DEFUN (ip_route_mask_flags_tag_vrf,
        VRF_CMD_HELP_STR)
 
 {
-  return zebra_static_ipv4 (vty, SAFI_UNICAST, 1, argv[0], argv[1], argv[2], argv[3], argv[4], NULL, argv[5]);
+  return zebra_static_ipv4 (vty, SAFI_UNICAST, 1, argv[0], argv[1], argv[2],
+                           argv[3], argv[4], NULL, argv[5], NULL);
 }
 
 DEFUN (ip_route_mask_flags2_vrf,
@@ -1283,7 +1354,8 @@ DEFUN (ip_route_mask_flags2_vrf,
        "Silently discard pkts when matched\n"
        VRF_CMD_HELP_STR)
 {
-  return zebra_static_ipv4 (vty, SAFI_UNICAST, 1, argv[0], argv[1], NULL, argv[2], NULL, NULL, argv[3]);
+  return zebra_static_ipv4 (vty, SAFI_UNICAST, 1, argv[0], argv[1], NULL,
+                           argv[2], NULL, NULL, argv[3], NULL);
 }
 
 DEFUN (ip_route_mask_flags2_tag_vrf,
@@ -1299,7 +1371,8 @@ DEFUN (ip_route_mask_flags2_tag_vrf,
        "Tag value\n"
        VRF_CMD_HELP_STR)
 {
-  return zebra_static_ipv4 (vty, SAFI_UNICAST, 1, argv[0], argv[1], NULL, argv[2], argv[3], NULL, argv[4]);
+  return zebra_static_ipv4 (vty, SAFI_UNICAST, 1, argv[0], argv[1], NULL,
+                           argv[2], argv[3], NULL, argv[4], NULL);
 }
 
 /* Distance option value.  */
@@ -1315,7 +1388,8 @@ DEFUN (ip_route_distance_vrf,
        "Distance value for this route\n"
        VRF_CMD_HELP_STR)
 {
-  return zebra_static_ipv4 (vty, SAFI_UNICAST, 1, argv[0], NULL, argv[1], NULL, NULL, argv[2], argv[3]);
+  return zebra_static_ipv4 (vty, SAFI_UNICAST, 1, argv[0], NULL, argv[1], NULL,
+                           NULL, argv[2], argv[3], NULL);
 }
 
 DEFUN (ip_route_tag_distance_vrf,
@@ -1333,7 +1407,8 @@ DEFUN (ip_route_tag_distance_vrf,
        VRF_CMD_HELP_STR)
 
 {
-  return zebra_static_ipv4 (vty, SAFI_UNICAST, 1, argv[0], NULL, argv[1], NULL, argv[2], argv[3], argv[4]);
+  return zebra_static_ipv4 (vty, SAFI_UNICAST, 1, argv[0], NULL, argv[1], NULL,
+                           argv[2], argv[3], argv[4], NULL);
 }
 
 DEFUN (ip_route_flags_distance_vrf,
@@ -1349,7 +1424,8 @@ DEFUN (ip_route_flags_distance_vrf,
        "Distance value for this route\n"
        VRF_CMD_HELP_STR)
 {
-  return zebra_static_ipv4 (vty, SAFI_UNICAST, 1, argv[0], NULL, argv[1], argv[2], NULL, argv[3], argv[4]);
+  return zebra_static_ipv4 (vty, SAFI_UNICAST, 1, argv[0], NULL, argv[1],
+                           argv[2], NULL, argv[3], argv[4], NULL);
 }
 
 DEFUN (ip_route_flags_tag_distance_vrf,
@@ -1367,7 +1443,8 @@ DEFUN (ip_route_flags_tag_distance_vrf,
        "Distance value for this route\n"
        VRF_CMD_HELP_STR)
 {
-  return zebra_static_ipv4 (vty, SAFI_UNICAST, 1, argv[0], NULL, argv[1], argv[2], argv[3], argv[4],argv[5]);
+  return zebra_static_ipv4 (vty, SAFI_UNICAST, 1, argv[0], NULL, argv[1],
+                           argv[2], argv[3], argv[4],argv[5], NULL);
 }
 
 DEFUN (ip_route_flags_distance2_vrf,
@@ -1381,7 +1458,8 @@ DEFUN (ip_route_flags_distance2_vrf,
        "Distance value for this route\n"
        VRF_CMD_HELP_STR)
 {
-  return zebra_static_ipv4 (vty, SAFI_UNICAST, 1, argv[0], NULL, NULL, argv[1], NULL, argv[2], argv[3]);
+  return zebra_static_ipv4 (vty, SAFI_UNICAST, 1, argv[0], NULL, NULL, argv[1],
+                           NULL, argv[2], argv[3], NULL);
 }
 
 DEFUN (ip_route_flags_tag_distance2_vrf,
@@ -1397,7 +1475,8 @@ DEFUN (ip_route_flags_tag_distance2_vrf,
        "Distance value for this route\n"
        VRF_CMD_HELP_STR)
 {
-  return zebra_static_ipv4 (vty, SAFI_UNICAST, 1, argv[0], NULL, NULL, argv[1], argv[2], argv[3], argv[4]);
+  return zebra_static_ipv4 (vty, SAFI_UNICAST, 1, argv[0], NULL, NULL, argv[1],
+                           argv[2], argv[3], argv[4], NULL);
 }
 
 DEFUN (ip_route_mask_distance_vrf,
@@ -1413,7 +1492,8 @@ DEFUN (ip_route_mask_distance_vrf,
        "Distance value for this route\n"
        VRF_CMD_HELP_STR)
 {
-  return zebra_static_ipv4 (vty, SAFI_UNICAST, 1, argv[0], argv[1], argv[2], NULL, NULL, argv[3], argv[4]);
+  return zebra_static_ipv4 (vty, SAFI_UNICAST, 1, argv[0], argv[1], argv[2],
+                           NULL, NULL, argv[3], argv[4], NULL);
 }
 
 DEFUN (ip_route_mask_tag_distance_vrf,
@@ -1431,7 +1511,8 @@ DEFUN (ip_route_mask_tag_distance_vrf,
        "Distance value for this route\n"
        VRF_CMD_HELP_STR)
 {
-  return zebra_static_ipv4 (vty, SAFI_UNICAST, 1, argv[0], argv[1], argv[2], NULL, argv[3], argv[4], argv[5]);
+  return zebra_static_ipv4 (vty, SAFI_UNICAST, 1, argv[0], argv[1], argv[2],
+                           NULL, argv[3], argv[4], argv[5], NULL);
 }
 
 DEFUN (ip_route_mask_flags_tag_distance_vrf,
@@ -1450,7 +1531,8 @@ DEFUN (ip_route_mask_flags_tag_distance_vrf,
        "Silently discard pkts when matched\n"
        VRF_CMD_HELP_STR)
 {
-  return zebra_static_ipv4 (vty, SAFI_UNICAST, 1, argv[0], argv[1], argv[2], argv[3], argv[4], argv[5], argv[6]);
+  return zebra_static_ipv4 (vty, SAFI_UNICAST, 1, argv[0], argv[1], argv[2],
+                           argv[3], argv[4], argv[5], argv[6], NULL);
 }
 
 
@@ -1468,7 +1550,8 @@ DEFUN (ip_route_mask_flags_distance_vrf,
        "Distance value for this route\n"
        VRF_CMD_HELP_STR)
 {
-  return zebra_static_ipv4 (vty, SAFI_UNICAST, 1, argv[0], argv[1], argv[2], argv[3], NULL, argv[4], argv[5]);
+  return zebra_static_ipv4 (vty, SAFI_UNICAST, 1, argv[0], argv[1], argv[2],
+                           argv[3], NULL, argv[4], argv[5], NULL);
 }
 
 DEFUN (ip_route_mask_flags_distance2_vrf,
@@ -1483,7 +1566,8 @@ DEFUN (ip_route_mask_flags_distance2_vrf,
        "Distance value for this route\n"
        VRF_CMD_HELP_STR)
 {
-  return zebra_static_ipv4 (vty, SAFI_UNICAST, 1, argv[0], argv[1], NULL, argv[2], NULL, argv[3], argv[4]);
+  return zebra_static_ipv4 (vty, SAFI_UNICAST, 1, argv[0], argv[1], NULL,
+                           argv[2], NULL, argv[3], argv[4], NULL);
 }
 
 DEFUN (ip_route_mask_flags_tag_distance2_vrf,
@@ -1500,7 +1584,8 @@ DEFUN (ip_route_mask_flags_tag_distance2_vrf,
        "Silently discard pkts when matched\n"
        VRF_CMD_HELP_STR)
 {
-  return zebra_static_ipv4 (vty, SAFI_UNICAST, 1, argv[0], argv[1], NULL, argv[2], argv[3], argv[4], argv[5]);
+  return zebra_static_ipv4 (vty, SAFI_UNICAST, 1, argv[0], argv[1], NULL,
+                           argv[2], argv[3], argv[4], argv[5], NULL);
 }
 
 DEFUN (no_ip_route_vrf, 
@@ -1515,7 +1600,8 @@ DEFUN (no_ip_route_vrf,
        "Null interface\n"
        VRF_CMD_HELP_STR)
 {
-  return zebra_static_ipv4 (vty, SAFI_UNICAST, 0, argv[0], NULL, argv[1], NULL, NULL, NULL, argv[2]);
+  return zebra_static_ipv4 (vty, SAFI_UNICAST, 0, argv[0], NULL, argv[1], NULL,
+                           NULL, NULL, argv[2], NULL);
 }
 
 DEFUN (no_ip_route_flags_vrf,
@@ -1531,7 +1617,8 @@ DEFUN (no_ip_route_flags_vrf,
        "Silently discard pkts when matched\n"
        VRF_CMD_HELP_STR)
 {
-  return zebra_static_ipv4 (vty, SAFI_UNICAST, 0, argv[0], NULL, argv[1], argv[2], NULL, NULL, argv[3]);
+  return zebra_static_ipv4 (vty, SAFI_UNICAST, 0, argv[0], NULL, argv[1],
+                           argv[2], NULL, NULL, argv[3], NULL);
 }
 
 DEFUN (no_ip_route_tag_vrf,
@@ -1548,7 +1635,8 @@ DEFUN (no_ip_route_tag_vrf,
        "Tag value\n"
        VRF_CMD_HELP_STR)
 {
-  return zebra_static_ipv4 (vty, SAFI_UNICAST, 0, argv[0], NULL, argv[1], NULL, argv[2], NULL, argv[3]);
+  return zebra_static_ipv4 (vty, SAFI_UNICAST, 0, argv[0], NULL, argv[1], NULL,
+                           argv[2], NULL, argv[3], NULL);
 }
 
 DEFUN (no_ip_route_flags_tag_vrf,
@@ -1566,7 +1654,8 @@ DEFUN (no_ip_route_flags_tag_vrf,
        "Tag value\n"
        VRF_CMD_HELP_STR)
 {
-  return zebra_static_ipv4 (vty, SAFI_UNICAST, 0, argv[0], NULL, argv[1], argv[2], argv[3], NULL, argv[4]);
+  return zebra_static_ipv4 (vty, SAFI_UNICAST, 0, argv[0], NULL, argv[1],
+                           argv[2], argv[3], NULL, argv[4], NULL);
 }
 
 DEFUN (no_ip_route_flags2_vrf,
@@ -1580,7 +1669,8 @@ DEFUN (no_ip_route_flags2_vrf,
        "Silently discard pkts when matched\n"
        VRF_CMD_HELP_STR)
 {
-  return zebra_static_ipv4 (vty, SAFI_UNICAST, 0, argv[0], NULL, NULL, argv[1], NULL, NULL, argv[2]);
+  return zebra_static_ipv4 (vty, SAFI_UNICAST, 0, argv[0], NULL, NULL, argv[1],
+                           NULL, NULL, argv[2], NULL);
 }
 
 DEFUN (no_ip_route_flags2_tag_vrf,
@@ -1596,7 +1686,8 @@ DEFUN (no_ip_route_flags2_tag_vrf,
        "Tag value\n"
        VRF_CMD_HELP_STR)
 {
-  return zebra_static_ipv4 (vty, SAFI_UNICAST, 0, argv[0], NULL, NULL, argv[1], argv[2], NULL, argv[3]);
+  return zebra_static_ipv4 (vty, SAFI_UNICAST, 0, argv[0], NULL, NULL, argv[1],
+                           argv[2], NULL, argv[3], NULL);
 }
 
 DEFUN (no_ip_route_mask_vrf,
@@ -1612,7 +1703,8 @@ DEFUN (no_ip_route_mask_vrf,
        "Null interface\n"
        VRF_CMD_HELP_STR)
 {
-  return zebra_static_ipv4 (vty, SAFI_UNICAST, 0, argv[0], argv[1], argv[2], NULL, NULL, NULL, argv[3]);
+  return zebra_static_ipv4 (vty, SAFI_UNICAST, 0, argv[0], argv[1], argv[2],
+                           NULL, NULL, NULL, argv[3], NULL);
 }
 
 DEFUN (no_ip_route_mask_flags_vrf,
@@ -1629,7 +1721,8 @@ DEFUN (no_ip_route_mask_flags_vrf,
        "Silently discard pkts when matched\n"
        VRF_CMD_HELP_STR)
 {
-  return zebra_static_ipv4 (vty, SAFI_UNICAST, 0, argv[0], argv[1], argv[2], argv[3], NULL, NULL, argv[4]);
+  return zebra_static_ipv4 (vty, SAFI_UNICAST, 0, argv[0], argv[1], argv[2],
+                           argv[3], NULL, NULL, argv[4], NULL);
 }
 
 DEFUN (no_ip_route_mask_tag_vrf,
@@ -1647,7 +1740,8 @@ DEFUN (no_ip_route_mask_tag_vrf,
        "Tag value\n"
        VRF_CMD_HELP_STR)
 {
-  return zebra_static_ipv4 (vty, SAFI_UNICAST, 0, argv[0], argv[1], argv[2], NULL, argv[3], NULL, argv[4]);
+  return zebra_static_ipv4 (vty, SAFI_UNICAST, 0, argv[0], argv[1], argv[2],
+                           NULL, argv[3], NULL, argv[4], NULL);
 }
 
 DEFUN (no_ip_route_mask_flags_tag_vrf,
@@ -1666,7 +1760,8 @@ DEFUN (no_ip_route_mask_flags_tag_vrf,
        "Tag value\n"
        VRF_CMD_HELP_STR)
 {
-  return zebra_static_ipv4 (vty, SAFI_UNICAST, 0, argv[0], argv[1], argv[2], argv[3], argv[4], NULL, argv[5]);
+  return zebra_static_ipv4 (vty, SAFI_UNICAST, 0, argv[0], argv[1], argv[2],
+                           argv[3], argv[4], NULL, argv[5], NULL);
 }
 
 DEFUN (no_ip_route_mask_flags2_vrf,
@@ -1681,7 +1776,8 @@ DEFUN (no_ip_route_mask_flags2_vrf,
        "Silently discard pkts when matched\n"
        VRF_CMD_HELP_STR)
 {
-  return zebra_static_ipv4 (vty, SAFI_UNICAST, 0, argv[0], argv[1], NULL, argv[2], NULL, NULL, argv[3]);
+  return zebra_static_ipv4 (vty, SAFI_UNICAST, 0, argv[0], argv[1], NULL,
+                           argv[2], NULL, NULL, argv[3], NULL);
 }
 
 DEFUN (no_ip_route_mask_flags2_tag_vrf,
@@ -1698,7 +1794,8 @@ DEFUN (no_ip_route_mask_flags2_tag_vrf,
        "Tag value\n"
        VRF_CMD_HELP_STR)
 {
-  return zebra_static_ipv4 (vty, SAFI_UNICAST, 0, argv[0], argv[1], NULL, argv[2], argv[3], NULL, argv[4]);
+  return zebra_static_ipv4 (vty, SAFI_UNICAST, 0, argv[0], argv[1], NULL,
+                           argv[2], argv[3], NULL, argv[4], NULL);
 }
 
 
@@ -1715,7 +1812,8 @@ DEFUN (no_ip_route_distance_vrf,
        "Distance value for this route\n"
        VRF_CMD_HELP_STR)
 {
-  return zebra_static_ipv4 (vty, SAFI_UNICAST, 0, argv[0], NULL, argv[1], NULL, NULL, argv[2], argv[3]);
+  return zebra_static_ipv4 (vty, SAFI_UNICAST, 0, argv[0], NULL, argv[1], NULL,
+                           NULL, argv[2], argv[3], NULL);
 }
 
 DEFUN (no_ip_route_tag_distance_vrf,
@@ -1733,7 +1831,8 @@ DEFUN (no_ip_route_tag_distance_vrf,
        "Distance value for this route\n"
        VRF_CMD_HELP_STR)
 {
-  return zebra_static_ipv4 (vty, SAFI_UNICAST, 0, argv[0], NULL, argv[1], NULL, argv[2], argv[3], argv[4]);
+  return zebra_static_ipv4 (vty, SAFI_UNICAST, 0, argv[0], NULL, argv[1], NULL,
+                           argv[2], argv[3], argv[4], NULL);
 }
 
 DEFUN (no_ip_route_flags_distance_vrf,
@@ -1750,7 +1849,8 @@ DEFUN (no_ip_route_flags_distance_vrf,
        "Distance value for this route\n"
        VRF_CMD_HELP_STR)
 {
-  return zebra_static_ipv4 (vty, SAFI_UNICAST, 0, argv[0], NULL, argv[1], argv[2], NULL, argv[3], argv[4]);
+  return zebra_static_ipv4 (vty, SAFI_UNICAST, 0, argv[0], NULL, argv[1],
+                           argv[2], NULL, argv[3], argv[4], NULL);
 }
 
 DEFUN (no_ip_route_flags_tag_distance_vrf,
@@ -1769,7 +1869,8 @@ DEFUN (no_ip_route_flags_tag_distance_vrf,
        "Distance value for this route\n"
        VRF_CMD_HELP_STR)
 {
-  return zebra_static_ipv4 (vty, SAFI_UNICAST, 0, argv[0], NULL, argv[1], argv[2], argv[3], argv[4],argv[5]);
+  return zebra_static_ipv4 (vty, SAFI_UNICAST, 0, argv[0], NULL, argv[1],
+                           argv[2], argv[3], argv[4],argv[5], NULL);
 }
 
 DEFUN (no_ip_route_flags_distance2_vrf,
@@ -1784,7 +1885,8 @@ DEFUN (no_ip_route_flags_distance2_vrf,
        "Distance value for this route\n"
        VRF_CMD_HELP_STR)
 {
-  return zebra_static_ipv4 (vty, SAFI_UNICAST, 0, argv[0], NULL, NULL, argv[1], NULL, argv[2], argv[3]);
+  return zebra_static_ipv4 (vty, SAFI_UNICAST, 0, argv[0], NULL, NULL, argv[1],
+                           NULL, argv[2], argv[3], NULL);
 }
 
 DEFUN (no_ip_route_flags_tag_distance2_vrf,
@@ -1801,7 +1903,8 @@ DEFUN (no_ip_route_flags_tag_distance2_vrf,
        "Distance value for this route\n"
        VRF_CMD_HELP_STR)
 {
-  return zebra_static_ipv4 (vty, SAFI_UNICAST, 0, argv[0], NULL, NULL, argv[1], argv[2] , argv[3], argv[4]);
+  return zebra_static_ipv4 (vty, SAFI_UNICAST, 0, argv[0], NULL, NULL, argv[1],
+                           argv[2] , argv[3], argv[4], NULL);
 }
 
 DEFUN (no_ip_route_mask_distance_vrf,
@@ -1818,7 +1921,8 @@ DEFUN (no_ip_route_mask_distance_vrf,
        "Distance value for this route\n"
        VRF_CMD_HELP_STR)
 {
-  return zebra_static_ipv4 (vty, SAFI_UNICAST, 0, argv[0], argv[1], argv[2], NULL, NULL, argv[3], argv[4]);
+  return zebra_static_ipv4 (vty, SAFI_UNICAST, 0, argv[0], argv[1], argv[2],
+                           NULL, NULL, argv[3], argv[4], NULL);
 }
 
 DEFUN (no_ip_route_mask_tag_distance_vrf,
@@ -1837,7 +1941,8 @@ DEFUN (no_ip_route_mask_tag_distance_vrf,
        "Distance value for this route\n"
        VRF_CMD_HELP_STR)
 {
-  return zebra_static_ipv4 (vty, SAFI_UNICAST, 0, argv[0], argv[1], argv[2], NULL, argv[3], argv[4], argv[5]);
+  return zebra_static_ipv4 (vty, SAFI_UNICAST, 0, argv[0], argv[1], argv[2],
+                           NULL, argv[3], argv[4], argv[5], NULL);
 }
 
 DEFUN (no_ip_route_mask_flags_distance_vrf,
@@ -1855,7 +1960,8 @@ DEFUN (no_ip_route_mask_flags_distance_vrf,
        "Distance value for this route\n"
        VRF_CMD_HELP_STR)
 {
-  return zebra_static_ipv4 (vty, SAFI_UNICAST, 0, argv[0], argv[1], argv[2], argv[3], NULL, argv[4], argv[5]);
+  return zebra_static_ipv4 (vty, SAFI_UNICAST, 0, argv[0], argv[1], argv[2],
+                           argv[3], NULL, argv[4], argv[5], NULL);
 }
 
 DEFUN (no_ip_route_mask_flags_tag_distance_vrf,
@@ -1875,7 +1981,8 @@ DEFUN (no_ip_route_mask_flags_tag_distance_vrf,
        "Distance value for this route\n"
        VRF_CMD_HELP_STR)
 {
-  return zebra_static_ipv4 (vty, SAFI_UNICAST, 0, argv[0], argv[1], argv[2], argv[3], argv[4], argv[5], argv[6]);
+  return zebra_static_ipv4 (vty, SAFI_UNICAST, 0, argv[0], argv[1], argv[2],
+                           argv[3], argv[4], argv[5], argv[6], NULL);
 }
 
 DEFUN (no_ip_route_mask_flags_distance2_vrf,
@@ -1891,7 +1998,8 @@ DEFUN (no_ip_route_mask_flags_distance2_vrf,
        "Distance value for this route\n"
        VRF_CMD_HELP_STR)
 {
-  return zebra_static_ipv4 (vty, SAFI_UNICAST, 0, argv[0], argv[1], NULL, argv[2], NULL, argv[3], argv[4]);
+  return zebra_static_ipv4 (vty, SAFI_UNICAST, 0, argv[0], argv[1], NULL,
+                           argv[2], NULL, argv[3], argv[4], NULL);
 }
 
 DEFUN (no_ip_route_mask_flags_tag_distance2_vrf,
@@ -1909,7 +2017,8 @@ DEFUN (no_ip_route_mask_flags_tag_distance2_vrf,
        "Distance value for this route\n"
        VRF_CMD_HELP_STR)
 {
-  return zebra_static_ipv4 (vty, SAFI_UNICAST, 0, argv[0], argv[1], NULL, argv[2], argv[3], argv[4], argv[5]);
+  return zebra_static_ipv4 (vty, SAFI_UNICAST, 0, argv[0], argv[1], NULL,
+                           argv[2], argv[3], argv[4], argv[5], NULL);
 }
 
 static int
@@ -3729,7 +3838,7 @@ static_config_ipv4 (struct vty *vty, safi_t safi, const char *cmd)
   struct static_route *si;
   struct route_table *stable;
   struct zebra_vrf *zvrf;
-  char buf[PREFIX_STRLEN];
+  char buf[BUFSIZ];
   int write =0;
   struct listnode *node;
 
@@ -3775,6 +3884,12 @@ static_config_ipv4 (struct vty *vty, safi_t safi, const char *cmd)
             if (si->vrf_id != VRF_DEFAULT)
                 vty_out (vty, " vrf %s", zvrf ? zvrf->name : "");
 
+            /* Label information */
+            if (si->snh_label.num_labels)
+              vty_out (vty, " label %s",
+                       mpls_label2str (si->snh_label.num_labels,
+                                       si->snh_label.label, buf, sizeof buf));
+
             vty_out (vty, "%s", VTY_NEWLINE);
 
             write = 1;
@@ -3802,6 +3917,7 @@ static_ipv6_func (struct vty *vty, int add_cmd, const char *dest_str,
   unsigned int ifindex = 0;
   struct interface *ifp = NULL;
   struct zebra_vrf *zvrf;
+  struct static_nh_label snh_label;
   
   ret = str2prefix (dest_str, &p);
   if (ret <= 0)
@@ -3840,6 +3956,9 @@ static_ipv6_func (struct vty *vty, int add_cmd, const char *dest_str,
   if (tag_str)
     tag = atoi(tag_str);
 
+  /* Labels -- not supported for IPv6 for now. */
+  memset (&snh_label, 0, sizeof (struct static_nh_label));
+
   /* When gateway is valid IPv6 addrees, then gate is treated as
      nexthop address other case gate is treated as interface name. */
   ret = inet_pton (AF_INET6, gate_str, &gate_addr);
@@ -3895,9 +4014,11 @@ static_ipv6_func (struct vty *vty, int add_cmd, const char *dest_str,
     }
 
   if (add_cmd)
-    static_add_route (AFI_IP6, SAFI_UNICAST, type, &p, (union g_addr *)gate, ifindex, ifname, flag, tag, distance, zvrf);
+    static_add_route (AFI_IP6, SAFI_UNICAST, type, &p, (union g_addr *)gate,
+                     ifindex, ifname, flag, tag, distance, zvrf, &snh_label);
   else
-    static_delete_route (AFI_IP6, SAFI_UNICAST, type, &p, (union g_addr *)gate, ifindex, tag, distance, zvrf);
+    static_delete_route (AFI_IP6, SAFI_UNICAST, type, &p, (union g_addr *)gate,
+                        ifindex, tag, distance, zvrf, &snh_label);
 
   return CMD_SUCCESS;
 }