IPv6 Performance bugs
[vpp.git] / src / vnet / fib / ip6_fib.c
index 343ff55..527f911 100644 (file)
@@ -35,8 +35,7 @@ vnet_ip6_fib_init (u32 fib_index)
     fib_table_entry_special_add(fib_index,
                                &pfx,
                                FIB_SOURCE_DEFAULT_ROUTE,
-                               FIB_ENTRY_FLAG_DROP,
-                               ADJ_INDEX_INVALID);
+                               FIB_ENTRY_FLAG_DROP);
 
     /*
      * all link local for us
@@ -47,31 +46,35 @@ vnet_ip6_fib_init (u32 fib_index)
     fib_table_entry_special_add(fib_index,
                                &pfx,
                                FIB_SOURCE_SPECIAL,
-                               FIB_ENTRY_FLAG_LOCAL,
-                               ADJ_INDEX_INVALID);
+                               FIB_ENTRY_FLAG_LOCAL);
 }
 
 static u32
 create_fib_with_table_id (u32 table_id)
 {
     fib_table_t *fib_table;
+    ip6_fib_t *v6_fib;
 
     pool_get_aligned(ip6_main.fibs, fib_table, CLIB_CACHE_LINE_BYTES);
+    pool_get_aligned(ip6_main.v6_fibs, v6_fib, CLIB_CACHE_LINE_BYTES);
+
     memset(fib_table, 0, sizeof(*fib_table));
+    memset(v6_fib, 0, sizeof(*v6_fib));
 
+    ASSERT((fib_table - ip6_main.fibs) ==
+           (v6_fib - ip6_main.v6_fibs));
+    
     fib_table->ft_proto = FIB_PROTOCOL_IP6;
     fib_table->ft_index =
-       fib_table->v6.index =
-           (fib_table - ip6_main.fibs);
+           v6_fib->index =
+                (fib_table - ip6_main.fibs);
 
     hash_set(ip6_main.fib_index_by_table_id, table_id, fib_table->ft_index);
 
     fib_table->ft_table_id =
-       fib_table->v6.table_id =
+       v6_fib->table_id =
            table_id;
-    fib_table->ft_flow_hash_config = 
-       fib_table->v6.flow_hash_config =
-           IP_FLOW_HASH_DEFAULT;
+    fib_table->ft_flow_hash_config = IP_FLOW_HASH_DEFAULT;
 
     vnet_ip6_fib_init(fib_table->ft_index);
     fib_table_lock(fib_table->ft_index, FIB_PROTOCOL_IP6);
@@ -188,6 +191,7 @@ ip6_fib_table_destroy (u32 fib_index)
     {
        hash_unset (ip6_main.fib_index_by_table_id, fib_table->ft_table_id);
     }
+    pool_put_index(ip6_main.v6_fibs, fib_table->ft_index);
     pool_put(ip6_main.fibs, fib_table);
 }
 
@@ -337,45 +341,6 @@ ip6_fib_table_entry_insert (u32 fib_index,
     compute_prefix_lengths_in_search_order (table);
 }
 
-u32 
-ip6_fib_table_fwding_lookup (ip6_main_t * im,
-                             u32 fib_index,
-                             const ip6_address_t * dst)
-{
-    const ip6_fib_table_instance_t *table;
-    int i, len;
-    int rv;
-    BVT(clib_bihash_kv) kv, value;
-    u64 fib;
-
-    table = &ip6_main.ip6_table[IP6_FIB_TABLE_FWDING];
-    len = vec_len (table->prefix_lengths_in_search_order);
-
-    kv.key[0] = dst->as_u64[0];
-    kv.key[1] = dst->as_u64[1];
-    fib = ((u64)((fib_index))<<32);
-
-    for (i = 0; i < len; i++)
-    {
-       int dst_address_length = table->prefix_lengths_in_search_order[i];
-       ip6_address_t * mask = &ip6_main.fib_masks[dst_address_length];
-      
-       ASSERT(dst_address_length >= 0 && dst_address_length <= 128);
-       //As lengths are decreasing, masks are increasingly specific.
-       kv.key[0] &= mask->as_u64[0];
-       kv.key[1] &= mask->as_u64[1];
-       kv.key[2] = fib | dst_address_length;
-      
-       rv = BV(clib_bihash_search_inline_2)(&table->ip6_hash, &kv, &value);
-       if (rv == 0)
-           return value.value;
-    }
-
-    /* default route is always present */
-    ASSERT(0);
-    return 0;
-}
-
 u32 ip6_fib_table_fwding_lookup_with_if_index (ip6_main_t * im,
                                               u32 sw_if_index,
                                               const ip6_address_t * dst)
@@ -384,12 +349,6 @@ u32 ip6_fib_table_fwding_lookup_with_if_index (ip6_main_t * im,
     return ip6_fib_table_fwding_lookup(im, fib_index, dst);
 }
 
-flow_hash_config_t
-ip6_fib_table_get_flow_hash_config (u32 fib_index)
-{
-    return (ip6_fib_get(fib_index)->flow_hash_config);
-}
-
 u32
 ip6_fib_table_get_index_for_sw_if_index (u32 sw_if_index)
 {
@@ -552,12 +511,15 @@ static void
 ip6_fib_table_show_one (ip6_fib_t *fib,
                        vlib_main_t * vm,
                        ip6_address_t *address,
-                       u32 mask_len)
+                       u32 mask_len,
+                        int detail)
 {
     vlib_cli_output(vm, "%U",
                     format_fib_entry,
                     ip6_fib_table_lookup(fib->index, address, mask_len),
-                    FIB_ENTRY_FORMAT_DETAIL);
+                    (detail ?
+                     FIB_ENTRY_FORMAT_DETAIL2:
+                     FIB_ENTRY_FORMAT_DETAIL));
 }
 
 typedef struct {
@@ -565,8 +527,9 @@ typedef struct {
   u64 count_by_prefix_length[129];
 } count_routes_in_fib_at_prefix_length_arg_t;
 
-static void count_routes_in_fib_at_prefix_length 
-(BVT(clib_bihash_kv) * kvp, void *arg)
+static void
+count_routes_in_fib_at_prefix_length (BVT(clib_bihash_kv) * kvp,
+                                      void *arg)
 {
   count_routes_in_fib_at_prefix_length_arg_t * ap = arg;
   int mask_width;
@@ -592,6 +555,7 @@ ip6_show_fib (vlib_main_t * vm,
     ip6_address_t matching_address;
     u32 mask_len  = 128;
     int table_id = -1, fib_index = ~0;
+    int detail = 0;
 
     verbose = 1;
     matching = 0;
@@ -602,6 +566,10 @@ ip6_show_fib (vlib_main_t * vm,
            unformat (input, "summary") ||
            unformat (input, "sum"))
            verbose = 0;
+       else if (unformat (input, "detail")   ||
+                 unformat (input, "det"))
+           detail = 1;
 
        else if (unformat (input, "%U/%d",
                           unformat_ip6_address, &matching_address, &mask_len))
@@ -620,15 +588,16 @@ ip6_show_fib (vlib_main_t * vm,
 
     pool_foreach (fib_table, im6->fibs,
     ({
-       fib = &(fib_table->v6);
+       fib = pool_elt_at_index(im6->v6_fibs, fib_table->ft_index);
        if (table_id >= 0 && table_id != (int)fib->table_id)
            continue;
        if (fib_index != ~0 && fib_index != (int)fib->index)
            continue;
 
-       vlib_cli_output (vm, "%s, fib_index %d, flow hash: %U", 
+       vlib_cli_output (vm, "%s, fib_index:%d, flow hash:[%U] locks:%d", 
                         fib_table->ft_desc, fib->index,
-                        format_ip_flow_hash_config, fib->flow_hash_config);
+                        format_ip_flow_hash_config, fib_table->ft_flow_hash_config,
+                         fib_table->ft_locks);
 
        /* Show summary? */
        if (! verbose)
@@ -659,7 +628,7 @@ ip6_show_fib (vlib_main_t * vm,
        }
        else
        {
-           ip6_fib_table_show_one(fib, vm, &matching_address, mask_len);
+           ip6_fib_table_show_one(fib, vm, &matching_address, mask_len, detail);
        }
     }));
 
@@ -763,7 +732,7 @@ ip6_show_fib (vlib_main_t * vm,
 /* *INDENT-OFF* */
 VLIB_CLI_COMMAND (ip6_show_fib_command, static) = {
     .path = "show ip6 fib",
-    .short_help = "show ip6 fib [summary] [table <table-id>] [index <fib-id>] [<ip6-addr>[/<width>]]",
+    .short_help = "show ip6 fib [summary] [table <table-id>] [index <fib-id>] [<ip6-addr>[/<width>]] [detail]",
     .function = ip6_show_fib,
 };
 /* *INDENT-ON* */