interface: fix interface-output and interface-tx multiarch selection

Type: fix
Change-Id: I77723dcbf753c2a7f1ec00f034d8ab604f12214b
Signed-off-by: Damjan Marion <damarion@cisco.com>
diff --git a/src/vnet/interface.c b/src/vnet/interface.c
index 862f574..638dc49 100644
--- a/src/vnet/interface.c
+++ b/src/vnet/interface.c
@@ -810,7 +810,8 @@
   vnet_config_main_t *cm;
   u32 hw_index, i;
   char *tx_node_name = NULL, *output_node_name = NULL;
-  vlib_node_function_t *output_node = vnet_interface_output_node_get ();
+  vlib_node_t *if_out_node =
+    vlib_get_node (vm, vnet_interface_output_node.index);
 
   pool_get (im->hw_interfaces, hw);
   clib_memset (hw, 0, sizeof (*hw));
@@ -896,8 +897,10 @@
       /* The new class may differ from the old one.
        * Functions have to be updated. */
       node = vlib_get_node (vm, hw->output_node_index);
-      node->function = output_node;
       node->format_trace = format_vnet_interface_output_trace;
+      node->node_fn_registrations = if_out_node->node_fn_registrations;
+      node->function = if_out_node->function;
+
       /* *INDENT-OFF* */
       foreach_vlib_main ({
         nrt = vlib_node_get_runtime (this_vlib_main, hw->output_node_index);
@@ -940,7 +943,13 @@
 
       r.flags = VLIB_NODE_FLAG_IS_OUTPUT;
       r.name = tx_node_name;
-      r.function = dev_class->tx_function;
+      if (dev_class->tx_fn_registrations)
+	{
+	  r.function = 0;
+	  r.node_fn_registrations = dev_class->tx_fn_registrations;
+	}
+      else
+	r.function = dev_class->tx_function;
 
       hw->tx_node_index = vlib_register_node (vm, &r);
 
@@ -950,8 +959,14 @@
 
       r.flags = 0;
       r.name = output_node_name;
-      r.function = output_node;
       r.format_trace = format_vnet_interface_output_trace;
+      if (if_out_node->node_fn_registrations)
+	{
+	  r.function = 0;
+	  r.node_fn_registrations = if_out_node->node_fn_registrations;
+	}
+      else
+	r.function = if_out_node->function;
 
       {
 	static char *e[] = {
diff --git a/src/vnet/interface.h b/src/vnet/interface.h
index 6b22bc3..83abea4 100644
--- a/src/vnet/interface.h
+++ b/src/vnet/interface.h
@@ -313,23 +313,25 @@
 static __clib_unused vnet_device_class_t __clib_unused_##x
 #endif
 
-#define VNET_DEVICE_CLASS_TX_FN(devclass)				\
-uword CLIB_MARCH_SFX (devclass##_tx_fn)();				\
-static vlib_node_fn_registration_t					\
-  CLIB_MARCH_SFX(devclass##_tx_fn_registration) =			\
-  { .function = &CLIB_MARCH_SFX (devclass##_tx_fn), };			\
-									\
-static void __clib_constructor						\
-CLIB_MARCH_SFX (devclass##_tx_fn_multiarch_register) (void)		\
-{									\
-  extern vnet_device_class_t devclass;					\
-  vlib_node_fn_registration_t *r;					\
-  r = &CLIB_MARCH_SFX (devclass##_tx_fn_registration);			\
-  r->priority = CLIB_MARCH_FN_PRIORITY();				\
-  r->next_registration = devclass.tx_fn_registrations;			\
-  devclass.tx_fn_registrations = r;					\
-}									\
-uword CLIB_CPU_OPTIMIZED CLIB_MARCH_SFX (devclass##_tx_fn)
+#define VNET_DEVICE_CLASS_TX_FN(devclass)                                     \
+  uword CLIB_MARCH_SFX (devclass##_tx_fn) ();                                 \
+  static vlib_node_fn_registration_t CLIB_MARCH_SFX (                         \
+    devclass##_tx_fn_registration) = {                                        \
+    .function = &CLIB_MARCH_SFX (devclass##_tx_fn),                           \
+  };                                                                          \
+                                                                              \
+  static void __clib_constructor CLIB_MARCH_SFX (                             \
+    devclass##_tx_fn_multiarch_register) (void)                               \
+  {                                                                           \
+    extern vnet_device_class_t devclass;                                      \
+    vlib_node_fn_registration_t *r;                                           \
+    r = &CLIB_MARCH_SFX (devclass##_tx_fn_registration);                      \
+    r->priority = CLIB_MARCH_FN_PRIORITY ();                                  \
+    r->name = CLIB_MARCH_VARIANT_STR;                                         \
+    r->next_registration = devclass.tx_fn_registrations;                      \
+    devclass.tx_fn_registrations = r;                                         \
+  }                                                                           \
+  uword CLIB_CPU_OPTIMIZED CLIB_MARCH_SFX (devclass##_tx_fn)
 
 /**
  * Link Type: A description of the protocol of packets on the link.
@@ -961,8 +963,6 @@
 
 int vnet_interface_name_renumber (u32 sw_if_index, u32 new_show_dev_instance);
 
-vlib_node_function_t *vnet_interface_output_node_get (void);
-
 void vnet_register_format_buffer_opaque_helper
   (vnet_buffer_opquae_formatter_t fn);
 
@@ -987,6 +987,8 @@
 
 int vnet_pcap_dispatch_trace_configure (vnet_pcap_dispatch_trace_args_t *);
 
+extern vlib_node_registration_t vnet_interface_output_node;
+
 #endif /* included_vnet_interface_h */
 
 /*
diff --git a/src/vnet/interface_output.c b/src/vnet/interface_output.c
index 641bd92..d244765 100644
--- a/src/vnet/interface_output.c
+++ b/src/vnet/interface_output.c
@@ -480,12 +480,8 @@
     }
 }
 
-static vlib_node_function_t CLIB_MULTIARCH_FN (vnet_interface_output_node);
-
-static uword
-CLIB_MULTIARCH_FN (vnet_interface_output_node) (vlib_main_t * vm,
-						vlib_node_runtime_t * node,
-						vlib_frame_t * frame)
+VLIB_NODE_FN (vnet_interface_output_node)
+(vlib_main_t *vm, vlib_node_runtime_t *node, vlib_frame_t *frame)
 {
   vnet_main_t *vnm = vnet_get_main ();
   vnet_hw_interface_t *hi;
@@ -503,15 +499,10 @@
 					      /* do_tx_offloads */ 1);
 }
 
-CLIB_MARCH_FN_REGISTRATION (vnet_interface_output_node);
-
-#ifndef CLIB_MARCH_VARIANT
-vlib_node_function_t *
-vnet_interface_output_node_get (void)
-{
-  return CLIB_MARCH_FN_POINTER (vnet_interface_output_node);
-}
-#endif /* CLIB_MARCH_VARIANT */
+VLIB_REGISTER_NODE (vnet_interface_output_node) = {
+  .name = "interface-output-template",
+  .vector_size = sizeof (u32),
+};
 
 /* Use buffer's sw_if_index[VNET_TX] to choose output interface. */
 VLIB_NODE_FN (vnet_per_buffer_interface_output_node) (vlib_main_t * vm,