tcp: make syn-rcvd timeout configurable
[vpp.git] / src / vnet / fib / fib_table.c
index ac0f2da..b2a32d0 100644 (file)
 
 const static char * fib_table_flags_strings[] = FIB_TABLE_ATTRIBUTES;
 
+/*
+ * Default names for IP4, IP6, and MPLS FIB table index 0.
+ * Nominally like "ipv6-VRF:0", but this will override that name if set
+ * in a config section of the startup.conf file.
+ */
+char *fib_table_default_names[FIB_PROTOCOL_MAX];
+
 fib_table_t *
 fib_table_get (fib_node_index_t index,
               fib_protocol_t proto)
@@ -510,7 +517,7 @@ fib_table_route_path_fixup (const fib_prefix_t *prefix,
         (~0 == path->frp_sw_if_index) &&
         (0 == ip46_address_cmp(&path->frp_addr, &prefix->fp_addr)))
     {
-        /* Prefix recurses via itse;f */
+        /* Prefix recurses via itself */
        path->frp_flags |= FIB_ROUTE_PATH_DROP;
     }
     if (!(path->frp_flags & FIB_ROUTE_PATH_LOCAL) &&
@@ -522,6 +529,24 @@ fib_table_route_path_fixup (const fib_prefix_t *prefix,
        path->frp_addr = prefix->fp_addr;
         path->frp_flags |= FIB_ROUTE_PATH_ATTACHED;
     }
+    else if ((*eflags & FIB_ENTRY_FLAG_CONNECTED) &&
+             !(*eflags & FIB_ENTRY_FLAG_LOCAL))
+    {
+        if (ip46_address_is_zero(&path->frp_addr))
+        {
+            path->frp_flags |= FIB_ROUTE_PATH_GLEAN;
+            fib_prefix_normalize(prefix, &path->frp_connected);
+        }
+    }
+    else if (fib_route_path_is_attached(path))
+    {
+        path->frp_flags |= FIB_ROUTE_PATH_GLEAN;
+        /*
+         * attached prefixes are not suitable as the source of ARP requests
+         * so don't save the prefix in the glean adj
+         */
+        clib_memset(&path->frp_connected, 0, sizeof(path->frp_connected));
+    }
     if (*eflags & FIB_ENTRY_FLAG_DROP)
     {
        path->frp_flags |= FIB_ROUTE_PATH_DROP;
@@ -580,6 +605,13 @@ fib_table_entry_path_add (u32 fib_index,
     return (fib_entry_index);
 }
 
+static int
+fib_route_path_cmp_for_sort (void * v1,
+                            void * v2)
+{
+    return (fib_route_path_cmp(v1, v2));
+}
+
 fib_node_index_t
 fib_table_entry_path_add2 (u32 fib_index,
                           const fib_prefix_t *prefix,
@@ -598,6 +630,11 @@ fib_table_entry_path_add2 (u32 fib_index,
     {
        fib_table_route_path_fixup(prefix, &flags, &rpaths[ii]);
     }
+    /*
+     * sort the paths provided by the control plane. this means
+     * the paths and the extension on the entry will be sorted.
+     */
+    vec_sort_with_function(rpaths, fib_route_path_cmp_for_sort);
 
     if (FIB_NODE_INDEX_INVALID == fib_entry_index)
     {
@@ -740,13 +777,6 @@ fib_table_entry_path_remove (u32 fib_index,
     vec_free(paths);
 }
 
-static int
-fib_route_path_cmp_for_sort (void * v1,
-                            void * v2)
-{
-    return (fib_route_path_cmp(v1, v2));
-}
-
 fib_node_index_t
 fib_table_entry_update (u32 fib_index,
                        const fib_prefix_t *prefix,
@@ -1130,21 +1160,29 @@ fib_table_find_or_create_and_lock_i (fib_protocol_t proto,
 
     fib_table = fib_table_get(fi, proto);
 
-    if (NULL == fib_table->ft_desc)
+    if (fib_table->ft_desc)
+           return fi;
+
+    if (name && name[0])
     {
-        if (name && name[0])
-        {
-            fib_table->ft_desc = format(NULL, "%s", name);
-        }
-        else
-        {
-            fib_table->ft_desc = format(NULL, "%U-VRF:%d",
-                                        format_fib_protocol, proto,
-                                        table_id);
-        }
+        fib_table->ft_desc = format(NULL, "%s", name);
+       return fi;
     }
 
-    return (fi);
+    if (table_id == 0)
+    {
+       char *default_name = fib_table_default_names[proto];
+       if (default_name && default_name[0])
+       {
+           fib_table->ft_desc = format(NULL, "%s", default_name);
+           return fi;
+       }
+    }
+
+    fib_table->ft_desc = format(NULL, "%U-VRF:%d",
+                               format_fib_protocol, proto,
+                               table_id);
+    return fi;
 }
 
 u32
@@ -1241,6 +1279,42 @@ fib_table_walk (u32 fib_index,
     }
 }
 
+typedef struct fib_table_walk_w_src_ctx_t_
+{
+    fib_table_walk_fn_t fn;
+    void *data;
+    fib_source_t src;
+} fib_table_walk_w_src_cxt_t;
+
+static fib_table_walk_rc_t
+fib_table_walk_w_src_cb (fib_node_index_t fei,
+                         void *arg)
+{
+    fib_table_walk_w_src_cxt_t *ctx = arg;
+
+    if (ctx->src == fib_entry_get_best_source(fei))
+    {
+        return (ctx->fn(fei, ctx->data));
+    }
+    return (FIB_TABLE_WALK_CONTINUE);
+}
+
+void
+fib_table_walk_w_src (u32 fib_index,
+                      fib_protocol_t proto,
+                      fib_source_t src,
+                      fib_table_walk_fn_t fn,
+                      void *data)
+{
+    fib_table_walk_w_src_cxt_t ctx = {
+        .fn = fn,
+        .src = src,
+        .data = data,
+    };
+
+    fib_table_walk(fib_index, proto, fib_table_walk_w_src_cb, &ctx);
+}
+
 void
 fib_table_sub_tree_walk (u32 fib_index,
                          fib_protocol_t proto,
@@ -1267,6 +1341,7 @@ fib_table_lock_dec (fib_table_t *fib_table,
 {
     vec_validate(fib_table->ft_locks, source);
 
+    ASSERT(fib_table->ft_locks[source] > 0);
     fib_table->ft_locks[source]--;
     fib_table->ft_total_locks--;
 }
@@ -1282,6 +1357,36 @@ fib_table_lock_inc (fib_table_t *fib_table,
     fib_table->ft_total_locks++;
 }
 
+
+static void
+fib_table_lock_clear (fib_table_t *fib_table,
+                      fib_source_t source)
+{
+    vec_validate(fib_table->ft_locks, source);
+
+    ASSERT(fib_table->ft_locks[source] <= 1);
+    if (fib_table->ft_locks[source])
+    {
+        fib_table->ft_locks[source]--;
+        fib_table->ft_total_locks--;
+    }
+}
+
+static void
+fib_table_lock_set (fib_table_t *fib_table,
+                    fib_source_t source)
+{
+    vec_validate(fib_table->ft_locks, source);
+
+    ASSERT(fib_table->ft_locks[source] <= 1);
+    ASSERT(fib_table->ft_total_locks < (0xffffffff - 1));
+    if (!fib_table->ft_locks[source])
+    {
+        fib_table->ft_locks[source]++;
+        fib_table->ft_total_locks++;
+    }
+}
+
 void
 fib_table_unlock (u32 fib_index,
                  fib_protocol_t proto,
@@ -1290,12 +1395,16 @@ fib_table_unlock (u32 fib_index,
     fib_table_t *fib_table;
 
     fib_table = fib_table_get(fib_index, proto);
-    fib_table_lock_dec(fib_table, source);
+
+    if (source == FIB_SOURCE_API || source == FIB_SOURCE_CLI)
+        fib_table_lock_clear(fib_table, source);
+    else
+        fib_table_lock_dec(fib_table, source);
 
     if (0 == fib_table->ft_total_locks)
     {
         /*
-         * no more locak from any source - kill it
+         * no more lock from any source - kill it
          */
        fib_table_destroy(fib_table);
     }
@@ -1310,7 +1419,10 @@ fib_table_lock (u32 fib_index,
 
     fib_table = fib_table_get(fib_index, proto);
 
-    fib_table_lock_inc(fib_table, source);
+    if (source == FIB_SOURCE_API || source == FIB_SOURCE_CLI)
+        fib_table_lock_set(fib_table, source);
+    else
+        fib_table_lock_inc(fib_table, source);
 }
 
 u32