ip: Fix crash in ip address add on sub-int without exact-match
[vpp.git] / src / vnet / ip / ip4_forward.c
index 36f05a2..57ad658 100644 (file)
@@ -653,12 +653,9 @@ ip4_add_del_interface_address_internal (vlib_main_t * vm,
   u32 if_address_index;
   ip4_address_fib_t ip4_af, *addr_fib = 0;
 
-  /* local0 interface doesn't support IP addressing  */
-  if (sw_if_index == 0)
-    {
-      return
-       clib_error_create ("local0 interface doesn't support IP addressing");
-    }
+  error = vnet_sw_interface_supports_addressing (vnm, sw_if_index);
+  if (error)
+    return error;
 
   vec_validate (im->fib_index_by_sw_if_index, sw_if_index);
   ip4_addr_fib_init (&ip4_af, address,
@@ -1517,8 +1514,6 @@ static inline void
 ip4_local_check_src (vlib_buffer_t * b, ip4_header_t * ip0,
                     ip4_local_last_check_t * last_check, u8 * error0)
 {
-  ip4_fib_mtrie_leaf_t leaf0;
-  ip4_fib_mtrie_t *mtrie0;
   const dpo_id_t *dpo0;
   load_balance_t *lb0;
   u32 lbi0;
@@ -1536,11 +1531,8 @@ ip4_local_check_src (vlib_buffer_t * b, ip4_header_t * ip0,
   if (PREDICT_TRUE (last_check->src.as_u32 != ip0->src_address.as_u32) ||
       last_check->first)
     {
-      mtrie0 = &ip4_fib_get (vnet_buffer (b)->ip.fib_index)->mtrie;
-      leaf0 = ip4_fib_mtrie_lookup_step_one (mtrie0, &ip0->src_address);
-      leaf0 = ip4_fib_mtrie_lookup_step (mtrie0, leaf0, &ip0->src_address, 2);
-      leaf0 = ip4_fib_mtrie_lookup_step (mtrie0, leaf0, &ip0->src_address, 3);
-      lbi0 = ip4_fib_mtrie_leaf_get_adj_index (leaf0);
+      lbi0 = ip4_fib_forwarding_lookup (vnet_buffer (b)->ip.fib_index,
+                                       &ip0->src_address);
 
       vnet_buffer (b)->ip.adj_index[VLIB_RX] =
        vnet_buffer (b)->ip.adj_index[VLIB_TX];
@@ -1586,8 +1578,6 @@ static inline void
 ip4_local_check_src_x2 (vlib_buffer_t ** b, ip4_header_t ** ip,
                        ip4_local_last_check_t * last_check, u8 * error)
 {
-  ip4_fib_mtrie_leaf_t leaf[2];
-  ip4_fib_mtrie_t *mtrie[2];
   const dpo_id_t *dpo[2];
   load_balance_t *lb[2];
   u32 not_last_hit;
@@ -1615,24 +1605,9 @@ ip4_local_check_src_x2 (vlib_buffer_t ** b, ip4_header_t ** ip,
    */
   if (PREDICT_TRUE (not_last_hit))
     {
-      mtrie[0] = &ip4_fib_get (vnet_buffer (b[0])->ip.fib_index)->mtrie;
-      mtrie[1] = &ip4_fib_get (vnet_buffer (b[1])->ip.fib_index)->mtrie;
-
-      leaf[0] = ip4_fib_mtrie_lookup_step_one (mtrie[0], &ip[0]->src_address);
-      leaf[1] = ip4_fib_mtrie_lookup_step_one (mtrie[1], &ip[1]->src_address);
-
-      leaf[0] = ip4_fib_mtrie_lookup_step (mtrie[0], leaf[0],
-                                          &ip[0]->src_address, 2);
-      leaf[1] = ip4_fib_mtrie_lookup_step (mtrie[1], leaf[1],
-                                          &ip[1]->src_address, 2);
-
-      leaf[0] = ip4_fib_mtrie_lookup_step (mtrie[0], leaf[0],
-                                          &ip[0]->src_address, 3);
-      leaf[1] = ip4_fib_mtrie_lookup_step (mtrie[1], leaf[1],
-                                          &ip[1]->src_address, 3);
-
-      lbi[0] = ip4_fib_mtrie_leaf_get_adj_index (leaf[0]);
-      lbi[1] = ip4_fib_mtrie_leaf_get_adj_index (leaf[1]);
+      ip4_fib_forwarding_lookup_x2 (
+       vnet_buffer (b[0])->ip.fib_index, vnet_buffer (b[1])->ip.fib_index,
+       &ip[0]->src_address, &ip[1]->src_address, &lbi[0], &lbi[1]);
 
       vnet_buffer (b[0])->ip.adj_index[VLIB_RX] =
        vnet_buffer (b[0])->ip.adj_index[VLIB_TX];
@@ -1762,8 +1737,8 @@ ip4_local_inline (vlib_main_t * vm,
        vlib_prefetch_buffer_header (b[4], LOAD);
        vlib_prefetch_buffer_header (b[5], LOAD);
 
-       CLIB_PREFETCH (b[4]->data, CLIB_CACHE_LINE_BYTES, LOAD);
-       CLIB_PREFETCH (b[5]->data, CLIB_CACHE_LINE_BYTES, LOAD);
+       clib_prefetch_load (b[4]->data);
+       clib_prefetch_load (b[5]->data);
       }
 
       error[0] = error[1] = IP4_ERROR_UNKNOWN_PROTOCOL;
@@ -2148,12 +2123,12 @@ ip4_rewrite_inline (vlib_main_t *vm, vlib_node_runtime_t *node,
       vnet_buffer (b[1])->ip.save_rewrite_length = rw_len1;
 
       p = vlib_buffer_get_current (b[2]);
-      CLIB_PREFETCH (p - CLIB_CACHE_LINE_BYTES, CLIB_CACHE_LINE_BYTES, STORE);
-      CLIB_PREFETCH (p, CLIB_CACHE_LINE_BYTES, LOAD);
+      clib_prefetch_store (p - CLIB_CACHE_LINE_BYTES);
+      clib_prefetch_load (p);
 
       p = vlib_buffer_get_current (b[3]);
-      CLIB_PREFETCH (p - CLIB_CACHE_LINE_BYTES, CLIB_CACHE_LINE_BYTES, STORE);
-      CLIB_PREFETCH (p, CLIB_CACHE_LINE_BYTES, LOAD);
+      clib_prefetch_store (p - CLIB_CACHE_LINE_BYTES);
+      clib_prefetch_load (p);
 
       /* Check MTU of outgoing interface. */
       u16 ip0_len = clib_net_to_host_u16 (ip0->length);
@@ -2663,103 +2638,6 @@ VLIB_REGISTER_NODE (ip4_midchain_node) = {
 };
 /* *INDENT-ON */
 
-static int
-ip4_lookup_validate (ip4_address_t * a, u32 fib_index0)
-{
-  ip4_fib_mtrie_t *mtrie0;
-  ip4_fib_mtrie_leaf_t leaf0;
-  u32 lbi0;
-
-  mtrie0 = &ip4_fib_get (fib_index0)->mtrie;
-
-  leaf0 = ip4_fib_mtrie_lookup_step_one (mtrie0, a);
-  leaf0 = ip4_fib_mtrie_lookup_step (mtrie0, leaf0, a, 2);
-  leaf0 = ip4_fib_mtrie_lookup_step (mtrie0, leaf0, a, 3);
-
-  lbi0 = ip4_fib_mtrie_leaf_get_adj_index (leaf0);
-
-  return lbi0 == ip4_fib_table_lookup_lb (ip4_fib_get (fib_index0), a);
-}
-
-static clib_error_t *
-test_lookup_command_fn (vlib_main_t * vm,
-                       unformat_input_t * input, vlib_cli_command_t * cmd)
-{
-  ip4_fib_t *fib;
-  u32 table_id = 0;
-  f64 count = 1;
-  u32 n;
-  int i;
-  ip4_address_t ip4_base_address;
-  u64 errors = 0;
-
-  while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
-    {
-      if (unformat (input, "table %d", &table_id))
-       {
-         /* Make sure the entry exists. */
-         fib = ip4_fib_get (table_id);
-         if ((fib) && (fib->index != table_id))
-           return clib_error_return (0, "<fib-index> %d does not exist",
-                                     table_id);
-       }
-      else if (unformat (input, "count %f", &count))
-       ;
-
-      else if (unformat (input, "%U",
-                        unformat_ip4_address, &ip4_base_address))
-       ;
-      else
-       return clib_error_return (0, "unknown input `%U'",
-                                 format_unformat_error, input);
-    }
-
-  n = count;
-
-  for (i = 0; i < n; i++)
-    {
-      if (!ip4_lookup_validate (&ip4_base_address, table_id))
-       errors++;
-
-      ip4_base_address.as_u32 =
-       clib_host_to_net_u32 (1 +
-                             clib_net_to_host_u32 (ip4_base_address.as_u32));
-    }
-
-  if (errors)
-    vlib_cli_output (vm, "%llu errors out of %d lookups\n", errors, n);
-  else
-    vlib_cli_output (vm, "No errors in %d lookups\n", n);
-
-  return 0;
-}
-
-/*?
- * Perform a lookup of an IPv4 Address (or range of addresses) in the
- * given FIB table to determine if there is a conflict with the
- * adjacency table. The fib-id can be determined by using the
- * '<em>show ip fib</em>' command. If fib-id is not entered, default value
- * of 0 is used.
- *
- * @todo This command uses fib-id, other commands use table-id (not
- * just a name, they are different indexes). Would like to change this
- * to table-id for consistency.
- *
- * @cliexpar
- * Example of how to run the test lookup command:
- * @cliexstart{test lookup 172.16.1.1 table 1 count 2}
- * No errors in 2 lookups
- * @cliexend
-?*/
-/* *INDENT-OFF* */
-VLIB_CLI_COMMAND (lookup_test_command, static) =
-{
-  .path = "test lookup",
-  .short_help = "test lookup <ipv4-addr> [table <fib-id>] [count <nn>]",
-  .function = test_lookup_command_fn,
-};
-/* *INDENT-ON* */
-
 static clib_error_t *
 set_ip_flow_hash_command_fn (vlib_main_t * vm,
                             unformat_input_t * input,