ip: The check for 'same packet' must include the FIB index

Type: fix

otherwise if two packets arrive with the same source address but from different VRFs, then they are treated as the same and they use the same LB and thus share the same fate. but the lookup, when done, results in two different LBs, and hence the fate can be different.

Signed-off-by: Neale Ranns <neale@graphiant.com>
Change-Id: Id6e16f7c577a561d9ddd7066339fa4385361d07f
diff --git a/src/vnet/ip/ip4_forward.c b/src/vnet/ip/ip4_forward.c
index 3556d35..c1bfc7d 100644
--- a/src/vnet/ip/ip4_forward.c
+++ b/src/vnet/ip/ip4_forward.c
@@ -1517,7 +1517,9 @@
 
 typedef struct
 {
+  /* The src and fib-index together determine if packet n is the same as n-1 */
   ip4_address_t src;
+  u32 fib_index;
   u32 lbi;
   u8 error;
   u8 first;
@@ -1551,7 +1553,8 @@
    * vnet_buffer()->ip.adj_index[VLIB_TX] will be set to the index of the
    *  adjacency for the source address (the remote sender's address)
    */
-  if (PREDICT_TRUE (last_check->src.as_u32 != ip0->src_address.as_u32) ||
+  if (PREDICT_TRUE ((last_check->src.as_u32 != ip0->src_address.as_u32)) ||
+      (last_check->fib_index != vnet_buffer (b)->ip.fib_index) ||
       last_check->first)
     {
       lbi0 = ip4_fib_forwarding_lookup (vnet_buffer (b)->ip.fib_index,
@@ -1587,6 +1590,7 @@
       last_check->lbi = lbi0;
       last_check->error = *error0;
       last_check->first = 0;
+      last_check->fib_index = vnet_buffer (b)->ip.fib_index;
     }
   else
     {
@@ -1621,6 +1625,9 @@
     vnet_buffer (b[1])->sw_if_index[VLIB_TX] :
     vnet_buffer (b[1])->ip.fib_index;
 
+  not_last_hit |= vnet_buffer (b[0])->ip.fib_index ^ last_check->fib_index;
+  not_last_hit |= vnet_buffer (b[1])->ip.fib_index ^ last_check->fib_index;
+
   if (is_receive_dpo)
     {
       const receive_dpo_t *rd0, *rd1;
@@ -1683,6 +1690,7 @@
       last_check->lbi = lbi[1];
       last_check->error = error[1];
       last_check->first = 0;
+      last_check->fib_index = vnet_buffer (b[1])->ip.fib_index;
     }
   else
     {
@@ -1752,10 +1760,11 @@
      * member to make sure the .lbi is initialised for the first
      * packet.
      */
-    .src = {.as_u32 = 0},
+    .src = { .as_u32 = 0 },
     .lbi = ~0,
     .error = IP4_ERROR_UNKNOWN_PROTOCOL,
     .first = 1,
+    .fib_index = 0,
   };
 
   from = vlib_frame_vector_args (frame);