]> git.puffer.fish Git - mirror/frr.git/commitdiff
zebra: more informative error messages for mpls labels
authorQuentin Young <qlyoung@cumulusnetworks.com>
Wed, 31 May 2017 21:27:08 +0000 (21:27 +0000)
committerQuentin Young <qlyoung@cumulusnetworks.com>
Wed, 31 May 2017 21:31:55 +0000 (21:31 +0000)
Signed-off-by: Quentin Young <qlyoung@cumulusnetworks.com>
zebra/zebra_mpls.c
zebra/zebra_vty.c

index b547c62566dc25fc04debb8a27854e355413fcd9..9cfa607c3e4baaacf841b6c44d80eb9dd6109a8a 100644 (file)
@@ -1734,44 +1734,59 @@ mpls_processq_init (struct zebra_t *zebra)
 
 /*
  * String to label conversion, labels separated by '/'.
+ *
+ * @param label_str labels separated by /
+ * @param num_labels number of labels; zero if conversion was unsuccessful
+ * @param labels preallocated mpls_label_t array of size MPLS_MAX_LABELS; only
+ *               modified if the conversion succeeded
+ * @return  0 on success
+ *         -1 if the string could not be parsed as integers
+ *         -2 if a label was inside the reserved range (0-15)
+ *         -3 if the number of labels given exceeds MPLS_MAX_LABELS
  */
 int
 mpls_str2label (const char *label_str, u_int8_t *num_labels,
                 mpls_label_t *labels)
 {
-  char *endp;
-  int i;
+  char *ostr;                           // copy of label string (start)
+  char *lstr;                           // copy of label string
+  char *nump;                           // pointer to next segment
+  char *endp;                           // end pointer
+  int i;                                // for iterating label_str
+  int rc;                               // return code
+  mpls_label_t pl[MPLS_MAX_LABELS];     // parsed labels
 
+  /* labels to zero until we have a successful parse */
+  ostr = lstr = XSTRDUP (MTYPE_TMP, label_str);
   *num_labels = 0;
-  for (i = 0; i < MPLS_MAX_LABELS; i++)
-    {
-      mpls_label_t label;
+  rc = 0;
 
-      label = strtoul(label_str, &endp, 0);
-
-      /* validity checks */
-      if (endp == label_str)
-        return -1;
-
-      if (!IS_MPLS_UNRESERVED_LABEL(label))
-        return -1;
+  for (i = 0; i < MPLS_MAX_LABELS && lstr && !rc; i++)
+    {
+      nump = strsep (&lstr, "/");
+      pl[i] = strtoul(nump, &endp, 10);
 
-      labels[i] = label;
-      if (*endp == '\0')
-        {
-          *num_labels = i + 1;
-          return 0;
-        }
+      /* format check */
+      if (*endp != '\0')
+        rc = -1;
+      /* validity check */
+      else if (!IS_MPLS_UNRESERVED_LABEL(pl[i]))
+        rc = -2;
+    }
 
-      /* Check separator. */
-      if (*endp != '/')
-        return -1;
+  /* excess labels */
+  if (!rc && i == MPLS_MAX_LABELS && lstr)
+    rc = -3;
 
-      label_str = endp + 1;
+  if (!rc)
+    {
+      *num_labels = i + 1;
+      memcpy (labels, pl, *num_labels * sizeof (mpls_label_t));
     }
 
-  /* Too many labels. */
-  return -1;
+  XFREE (MTYPE_TMP, ostr);
+
+  return rc;
 }
 
 /*
index d0d761af95c31958282b1586df56354eb66783fb..89707663892121e3d3de1762650fa96be0ba3353 100644 (file)
@@ -126,10 +126,24 @@ zebra_static_ipv4 (struct vty *vty, safi_t safi, int add_cmd,
                   VTY_NEWLINE);
          return CMD_WARNING;
        }
-      if (mpls_str2label (label_str, &snh_label.num_labels,
-                          snh_label.label))
+      int rc = mpls_str2label (label_str, &snh_label.num_labels,
+                               snh_label.label);
+      if (rc < 0)
         {
-          vty_out (vty, "%% Malformed label(s)%s", VTY_NEWLINE);
+          switch (rc) {
+          case -1:
+            vty_out (vty, "%% Malformed label(s)%s", VTY_NEWLINE);
+            break;
+          case -2:
+            vty_out (vty, "%% Cannot use reserved label(s) (%d-%d)%s",
+                     MPLS_MIN_RESERVED_LABEL, MPLS_MAX_RESERVED_LABEL,
+                     VTY_NEWLINE);
+            break;
+          case -3:
+            vty_out (vty, "%% Too many labels. Enter %d or fewer%s",
+                     MPLS_MAX_LABELS, VTY_NEWLINE);
+            break;
+          }
           return CMD_WARNING;
         }
     }
@@ -2047,10 +2061,24 @@ static_ipv6_func (struct vty *vty, int add_cmd, const char *dest_str,
                    VTY_NEWLINE);
           return CMD_WARNING;
         }
-      if (mpls_str2label (label_str, &snh_label.num_labels,
-                          snh_label.label))
+      int rc = mpls_str2label (label_str, &snh_label.num_labels,
+                               snh_label.label);
+      if (rc < 0)
         {
-          vty_out (vty, "%% Malformed label(s)%s", VTY_NEWLINE);
+          switch (rc) {
+          case -1:
+            vty_out (vty, "%% Malformed label(s)%s", VTY_NEWLINE);
+            break;
+          case -2:
+            vty_out (vty, "%% Cannot use reserved label(s) (%d-%d)%s",
+                     MPLS_MIN_RESERVED_LABEL, MPLS_MAX_RESERVED_LABEL,
+                     VTY_NEWLINE);
+            break;
+          case -3:
+            vty_out (vty, "%% Too many labels. Enter %d or fewer%s",
+                     MPLS_MAX_LABELS, VTY_NEWLINE);
+            break;
+          }
           return CMD_WARNING;
         }
     }