vlib: autogenerate <node> before <last-in-arc> constraints

If an arc declaration includes '.last_in_arc = "some-node"', assume
that folks mean it and add explicit ordering constraints.

Fix the "arp" arc declaration which claimed that the arc ends at
arp-disabled, but the arc really ends at error-drop.

Type: fix

Signed-off-by: Dave Barach <dave@barachs.net>
Change-Id: Ie2de1fb30091671cbc7c62770903a2e05987f141
diff --git a/src/vnet/ethernet/arp.c b/src/vnet/ethernet/arp.c
index a42cfda..ca9a21c 100644
--- a/src/vnet/ethernet/arp.c
+++ b/src/vnet/ethernet/arp.c
@@ -1711,7 +1711,7 @@
 {
   .arc_name = "arp",
   .start_nodes = VNET_FEATURES ("arp-input"),
-  .last_in_arc = "arp-disabled",
+  .last_in_arc = "error-drop",
   .arc_index_ptr = &ethernet_arp_main.feature_arc_index,
 };
 
diff --git a/src/vnet/feature/feature.c b/src/vnet/feature/feature.c
index 47c8c62..6bef262 100644
--- a/src/vnet/feature/feature.c
+++ b/src/vnet/feature/feature.c
@@ -122,6 +122,7 @@
       vcm = &cm->config_main;
       if ((error = vnet_feature_arc_init
 	   (vm, vcm, areg->start_nodes, areg->n_start_nodes,
+	    areg->last_in_arc,
 	    fm->next_feature_by_arc[arc_index],
 	    fm->next_constraint_by_arc[arc_index],
 	    &fm->feature_nodes[arc_index])))
diff --git a/src/vnet/feature/feature.h b/src/vnet/feature/feature.h
index 6e34018..ef5f4c6 100644
--- a/src/vnet/feature/feature.h
+++ b/src/vnet/feature/feature.h
@@ -446,6 +446,7 @@
    vnet_config_main_t * vcm,
    char **feature_start_nodes,
    int num_feature_start_nodes,
+   char *last_in_arc,
    vnet_feature_registration_t * first_reg,
    vnet_feature_constraint_registration_t * first_const_set,
    char ***in_feature_nodes);
diff --git a/src/vnet/feature/registration.c b/src/vnet/feature/registration.c
index fb10fbb..030486a 100644
--- a/src/vnet/feature/registration.c
+++ b/src/vnet/feature/registration.c
@@ -122,6 +122,7 @@
 		       vnet_config_main_t * vcm,
 		       char **feature_start_nodes,
 		       int num_feature_start_nodes,
+		       char *last_in_arc,
 		       vnet_feature_registration_t * first_reg,
 		       vnet_feature_constraint_registration_t *
 		       first_const_set, char ***in_feature_nodes)
@@ -154,6 +155,27 @@
 
   this_reg = first_reg;
 
+  /* Autogenerate <node> before <last-in-arc> constraints */
+  if (last_in_arc)
+    {
+      while (this_reg)
+	{
+	  /* If this isn't the last node in the arc... */
+	  if (clib_strcmp (this_reg->node_name, last_in_arc))
+	    {
+	      /*
+	       * Add an explicit constraint so this feature will run
+	       * before the last node in the arc
+	       */
+	      constraint_tuple = format (0, "%s,%s%c", this_reg->node_name,
+					 last_in_arc, 0);
+	      vec_add1 (constraints, constraint_tuple);
+	    }
+	  this_reg = this_reg->next_in_arc;
+	}
+      this_reg = first_reg;
+    }
+
   /* pass 1, collect feature node names, construct a before b pairs */
   while (this_reg)
     {