VPP-488: Fix build errors, which uncovered IPv6 load balance lookup bug.

Change-Id: Id17fcb9154c5337908f29b7ce3a282b6a4b72d64
Signed-off-by: Billy McFall <bmcfall@redhat.com>
diff --git a/vnet/vnet/adj/adj_glean.c b/vnet/vnet/adj/adj_glean.c
index 290af1f..d48cf21 100644
--- a/vnet/vnet/adj/adj_glean.c
+++ b/vnet/vnet/adj/adj_glean.c
@@ -183,8 +183,8 @@
 u8*
 format_adj_glean (u8* s, va_list *ap)
 {
-    index_t index = va_arg(ap, index_t);
-    CLIB_UNUSED(u32 indent) = va_arg(ap, u32);
+    index_t index = va_arg(*ap, index_t);
+    CLIB_UNUSED(u32 indent) = va_arg(*ap, u32);
     vnet_main_t * vnm = vnet_get_main();
     ip_adjacency_t * adj = adj_get(index);
 
diff --git a/vnet/vnet/adj/adj_midchain.c b/vnet/vnet/adj/adj_midchain.c
index f42e3a9..2fbedae 100644
--- a/vnet/vnet/adj/adj_midchain.c
+++ b/vnet/vnet/adj/adj_midchain.c
@@ -423,8 +423,8 @@
 u8*
 format_adj_midchain (u8* s, va_list *ap)
 {
-    index_t index = va_arg(ap, index_t);
-    u32 indent = va_arg(ap, u32);
+    index_t index = va_arg(*ap, index_t);
+    u32 indent = va_arg(*ap, u32);
     vnet_main_t * vnm = vnet_get_main();
     ip_adjacency_t * adj = adj_get(index);
 
diff --git a/vnet/vnet/adj/adj_nbr.c b/vnet/vnet/adj/adj_nbr.c
index 5351520..7bc5310 100644
--- a/vnet/vnet/adj/adj_nbr.c
+++ b/vnet/vnet/adj/adj_nbr.c
@@ -782,8 +782,8 @@
 u8*
 format_adj_nbr_incomplete (u8* s, va_list *ap)
 {
-    index_t index = va_arg(ap, index_t);
-    CLIB_UNUSED(u32 indent) = va_arg(ap, u32);
+    index_t index = va_arg(*ap, index_t);
+    CLIB_UNUSED(u32 indent) = va_arg(*ap, u32);
     vnet_main_t * vnm = vnet_get_main();
     ip_adjacency_t * adj = adj_get(index);
 
@@ -803,8 +803,8 @@
 u8*
 format_adj_nbr (u8* s, va_list *ap)
 {
-    index_t index = va_arg(ap, index_t);
-    CLIB_UNUSED(u32 indent) = va_arg(ap, u32);
+    index_t index = va_arg(*ap, index_t);
+    CLIB_UNUSED(u32 indent) = va_arg(*ap, u32);
     vnet_main_t * vnm = vnet_get_main();
     ip_adjacency_t * adj = adj_get(index);
 
diff --git a/vnet/vnet/dpo/drop_dpo.c b/vnet/vnet/dpo/drop_dpo.c
index 048518c..26c3e8a 100644
--- a/vnet/vnet/dpo/drop_dpo.c
+++ b/vnet/vnet/dpo/drop_dpo.c
@@ -52,8 +52,8 @@
 static u8*
 format_drop_dpo (u8 *s, va_list *ap)
 {
-    CLIB_UNUSED(index_t index) = va_arg(ap, index_t);
-    CLIB_UNUSED(u32 indent) = va_arg(ap, u32);
+    CLIB_UNUSED(index_t index) = va_arg(*ap, index_t);
+    CLIB_UNUSED(u32 indent) = va_arg(*ap, u32);
 
     return (format(s, "dpo-drop %U", format_dpo_proto, index));
 }
diff --git a/vnet/vnet/dpo/load_balance.c b/vnet/vnet/dpo/load_balance.c
index 6badb0e..8abfc43 100644
--- a/vnet/vnet/dpo/load_balance.c
+++ b/vnet/vnet/dpo/load_balance.c
@@ -148,16 +148,16 @@
 u8*
 format_load_balance (u8 * s, va_list * args)
 {
-    index_t lbi = va_arg(args, index_t);
-    load_balance_format_flags_t flags = va_arg(args, load_balance_format_flags_t);
+    index_t lbi = va_arg(*args, index_t);
+    load_balance_format_flags_t flags = va_arg(*args, load_balance_format_flags_t);
 
     return (load_balance_format(lbi, flags, 0, s));
 }
 static u8*
 format_load_balance_dpo (u8 * s, va_list * args)
 {
-    index_t lbi = va_arg(args, index_t);
-    u32 indent = va_arg(args, u32);
+    index_t lbi = va_arg(*args, index_t);
+    u32 indent = va_arg(*args, u32);
 
     return (load_balance_format(lbi, LOAD_BALANCE_FORMAT_DETAIL, indent, s));
 }
diff --git a/vnet/vnet/dpo/lookup_dpo.c b/vnet/vnet/dpo/lookup_dpo.c
index f775417..ab3a7b9 100644
--- a/vnet/vnet/dpo/lookup_dpo.c
+++ b/vnet/vnet/dpo/lookup_dpo.c
@@ -456,7 +456,8 @@
 lookup_dpo_ip6_inline (vlib_main_t * vm,
                        vlib_node_runtime_t * node,
                        vlib_frame_t * from_frame,
-                       int input_src_addr)
+                       int input_src_addr,
+                       int table_from_interface)
 {
     vlib_combined_counter_main_t * cm = &load_balance_main.lbm_to_counters;
     u32 n_left_from, next_index, * from, * to_next;
@@ -497,7 +498,21 @@
             /* dst lookup was done by ip6 lookup */
             lkdi0 = vnet_buffer(b0)->ip.adj_index[VLIB_TX];
             lkd0 = lookup_dpo_get(lkdi0);
-            fib_index0 = lkd0->lkd_fib_index;
+
+            /*
+             * choose between a lookup using the fib index in the DPO
+             * or getting the FIB index from the interface.
+             */
+            if (table_from_interface)
+            {
+                fib_index0 =
+                    ip4_fib_table_get_index_for_sw_if_index(
+                        vnet_buffer(b0)->sw_if_index[VLIB_RX]);
+            }
+            else
+            {
+                fib_index0 = lkd0->lkd_fib_index;
+            }
 
             /*
              * choose between a source or destination address lookup in the table
@@ -559,7 +574,7 @@
                 vlib_node_runtime_t * node,
                 vlib_frame_t * from_frame)
 {
-    return (lookup_dpo_ip6_inline(vm, node, from_frame, 0 /*use src*/));
+    return (lookup_dpo_ip6_inline(vm, node, from_frame, 0 /*use src*/, 0));
 }
 
 VLIB_REGISTER_NODE (lookup_ip6_dst_node) = {
@@ -572,11 +587,28 @@
 VLIB_NODE_FUNCTION_MULTIARCH (lookup_ip6_dst_node, lookup_ip6_dst)
 
 always_inline uword
+lookup_ip6_dst_itf (vlib_main_t * vm,
+		    vlib_node_runtime_t * node,
+		    vlib_frame_t * from_frame)
+{
+    return (lookup_dpo_ip6_inline(vm, node, from_frame, 0 /*use src*/, 1));
+}
+
+VLIB_REGISTER_NODE (lookup_ip6_dst_itf_node) = {
+    .function = lookup_ip6_dst_itf,
+    .name = "lookup-ip6-dst-itf",
+    .vector_size = sizeof (u32),
+    .format_trace = format_lookup_trace,
+    .sibling_of = "ip6-lookup",
+};
+VLIB_NODE_FUNCTION_MULTIARCH (lookup_ip6_dst_itf_node, lookup_ip6_dst_itf)
+
+always_inline uword
 lookup_ip6_src (vlib_main_t * vm,
                 vlib_node_runtime_t * node,
                 vlib_frame_t * from_frame)
 {
-    return (lookup_dpo_ip6_inline(vm, node, from_frame, 1 /*use src*/));
+    return (lookup_dpo_ip6_inline(vm, node, from_frame, 1, 0));
 }
 
 VLIB_REGISTER_NODE (lookup_ip6_src_node) = {
@@ -834,5 +866,5 @@
     lookup_dpo_sub_types[LOOKUP_SUB_TYPE_DST] =
         dpo_register_new_type(&lkd_vft, lookup_dst_nodes);
     lookup_dpo_sub_types[LOOKUP_SUB_TYPE_DST_TABLE_FROM_INTERFACE] =
-        dpo_register_new_type(&lkd_vft, lookup_dst_nodes);
+        dpo_register_new_type(&lkd_vft, lookup_dst_from_interface_nodes);
 }
diff --git a/vnet/vnet/dpo/punt_dpo.c b/vnet/vnet/dpo/punt_dpo.c
index e27a8ff..d1661dc 100644
--- a/vnet/vnet/dpo/punt_dpo.c
+++ b/vnet/vnet/dpo/punt_dpo.c
@@ -52,8 +52,8 @@
 static u8*
 format_punt_dpo (u8 *s, va_list *ap)
 {
-    CLIB_UNUSED(index_t index) = va_arg(ap, index_t);
-    CLIB_UNUSED(u32 indent) = va_arg(ap, u32);
+    CLIB_UNUSED(index_t index) = va_arg(*ap, index_t);
+    CLIB_UNUSED(u32 indent) = va_arg(*ap, u32);
 
     return (format(s, "dpo-punt"));
 }
diff --git a/vnet/vnet/dpo/receive_dpo.c b/vnet/vnet/dpo/receive_dpo.c
index ad78850..2b2571c 100644
--- a/vnet/vnet/dpo/receive_dpo.c
+++ b/vnet/vnet/dpo/receive_dpo.c
@@ -97,8 +97,8 @@
 static u8*
 format_receive_dpo (u8 *s, va_list *ap)
 {
-    CLIB_UNUSED(index_t index) = va_arg(ap, index_t);
-    CLIB_UNUSED(u32 indent) = va_arg(ap, u32);
+    CLIB_UNUSED(index_t index) = va_arg(*ap, index_t);
+    CLIB_UNUSED(u32 indent) = va_arg(*ap, u32);
     vnet_main_t * vnm = vnet_get_main();
     receive_dpo_t *rd;
 
diff --git a/vnet/vnet/fib/fib_entry_src.c b/vnet/vnet/fib/fib_entry_src.c
index 6ee966b..99ac09e 100644
--- a/vnet/vnet/fib/fib_entry_src.c
+++ b/vnet/vnet/fib/fib_entry_src.c
@@ -34,6 +34,21 @@
     return (fib_entry->fe_prefix.fp_proto);
 }
 
+static dpo_proto_t
+fib_entry_get_payload_proto (const fib_entry_t * fib_entry)
+{
+    switch (fib_entry->fe_prefix.fp_proto)
+    {
+    case FIB_PROTOCOL_IP4:
+    case FIB_PROTOCOL_IP6:
+	return fib_proto_to_dpo(fib_entry->fe_prefix.fp_proto);
+    case FIB_PROTOCOL_MPLS:
+	return fib_entry->fe_prefix.fp_payload_proto;
+    }
+
+    return (fib_entry->fe_prefix.fp_proto);
+}
+
 void
 fib_entry_src_register (fib_source_t source,
 			const fib_entry_src_vft_t *vft)
@@ -329,7 +344,7 @@
         .fct = fct,
     };
 
-    lb_proto = fib_proto_to_dpo(fib_entry_get_proto(fib_entry));
+    lb_proto = fib_entry_get_payload_proto(fib_entry);
 
     fib_path_list_walk(esrc->fes_pl,
                        fib_entry_src_collect_forwarding,
diff --git a/vnet/vnet/ip/ip4_source_and_port_range_check.c b/vnet/vnet/ip/ip4_source_and_port_range_check.c
index c6037c4..0c4d87c 100644
--- a/vnet/vnet/ip/ip4_source_and_port_range_check.c
+++ b/vnet/vnet/ip/ip4_source_and_port_range_check.c
@@ -864,8 +864,8 @@
 static u8 *
 format_ppr_dpo (u8 * s, va_list * args)
 {
-  index_t index = va_arg (args, index_t);
-  CLIB_UNUSED (u32 indent) = va_arg (args, u32);
+  index_t index = va_arg (*args, index_t);
+  CLIB_UNUSED (u32 indent) = va_arg (*args, u32);
 
   protocol_port_range_dpo_t *ppr_dpo;
   int i, j;
diff --git a/vnet/vnet/lisp-gpe/lisp_gpe_adjacency.c b/vnet/vnet/lisp-gpe/lisp_gpe_adjacency.c
index 93a6d01..37a8b08 100644
--- a/vnet/vnet/lisp-gpe/lisp_gpe_adjacency.c
+++ b/vnet/vnet/lisp-gpe/lisp_gpe_adjacency.c
@@ -446,7 +446,7 @@
 {
   lisp_gpe_adjacency_t *ladj = va_arg (*args, lisp_gpe_adjacency_t *);
   lisp_gpe_adjacency_format_flags_t flags =
-    va_arg (args, lisp_gpe_adjacency_format_flags_t);
+    va_arg (*args, lisp_gpe_adjacency_format_flags_t);
 
   if (flags & LISP_GPE_ADJ_FORMAT_FLAG_DETAIL)
     {
diff --git a/vnet/vnet/mpls/interface.c b/vnet/vnet/mpls/interface.c
index 553d7fb..0baf2d3 100644
--- a/vnet/vnet/mpls/interface.c
+++ b/vnet/vnet/mpls/interface.c
@@ -497,14 +497,6 @@
   .flags = VNET_HW_INTERFACE_CLASS_FLAG_P2P,
 };
 
-/**
- * A conversion of DPO next object tpyes to VLIB graph next nodes from
- * the mpls_post_rewrite node
- */
-static const int dpo_next_2_mpls_post_rewrite[DPO_LAST] = {
-    [DPO_LOAD_BALANCE] = IP_LOOKUP_NEXT_LOAD_BALANCE,
-};
-
 static void
 mpls_gre_fixup (vlib_main_t *vm,
 		ip_adjacency_t *adj,