MTRIE Optimisations 2
[vpp.git] / src / vnet / fib / fib_table.c
index 76db42d..6c3162e 100644 (file)
@@ -47,7 +47,7 @@ fib_table_lookup_i (fib_table_t *fib_table,
     switch (prefix->fp_proto)
     {
     case FIB_PROTOCOL_IP4:
-       return (ip4_fib_table_lookup(&fib_table->v4,
+       return (ip4_fib_table_lookup(ip4_fib_get(fib_table->ft_index),
                                     &prefix->fp_addr.ip4,
                                     prefix->fp_len));
     case FIB_PROTOCOL_IP6:
@@ -55,7 +55,7 @@ fib_table_lookup_i (fib_table_t *fib_table,
                                     &prefix->fp_addr.ip6,
                                     prefix->fp_len));
     case FIB_PROTOCOL_MPLS:
-       return (mpls_fib_table_lookup(&fib_table->mpls,
+       return (mpls_fib_table_lookup(mpls_fib_get(fib_table->ft_index),
                                      prefix->fp_label,
                                      prefix->fp_eos));
     }
@@ -76,7 +76,7 @@ fib_table_lookup_exact_match_i (const fib_table_t *fib_table,
     switch (prefix->fp_proto)
     {
     case FIB_PROTOCOL_IP4:
-       return (ip4_fib_table_lookup_exact_match(&fib_table->v4,
+       return (ip4_fib_table_lookup_exact_match(ip4_fib_get(fib_table->ft_index),
                                                 &prefix->fp_addr.ip4,
                                                 prefix->fp_len));
     case FIB_PROTOCOL_IP6:
@@ -84,7 +84,7 @@ fib_table_lookup_exact_match_i (const fib_table_t *fib_table,
                                                 &prefix->fp_addr.ip6,
                                                 prefix->fp_len));
     case FIB_PROTOCOL_MPLS:
-       return (mpls_fib_table_lookup(&fib_table->mpls,
+       return (mpls_fib_table_lookup(mpls_fib_get(fib_table->ft_index),
                                      prefix->fp_label,
                                      prefix->fp_eos));
     }
@@ -148,7 +148,7 @@ fib_table_entry_remove (fib_table_t *fib_table,
     switch (prefix->fp_proto)
     {
     case FIB_PROTOCOL_IP4:
-       ip4_fib_table_entry_remove(&fib_table->v4,
+       ip4_fib_table_entry_remove(ip4_fib_get(fib_table->ft_index),
                                   &prefix->fp_addr.ip4,
                                   prefix->fp_len);
        break;
@@ -158,7 +158,7 @@ fib_table_entry_remove (fib_table_t *fib_table,
                                   prefix->fp_len);
        break;
     case FIB_PROTOCOL_MPLS:
-       mpls_fib_table_entry_remove(&fib_table->mpls,
+       mpls_fib_table_entry_remove(mpls_fib_get(fib_table->ft_index),
                                    prefix->fp_label,
                                    prefix->fp_eos);
        break;
@@ -208,7 +208,7 @@ fib_table_entry_insert (fib_table_t *fib_table,
     switch (prefix->fp_proto)
     {
     case FIB_PROTOCOL_IP4:
-       ip4_fib_table_entry_insert(&fib_table->v4,
+       ip4_fib_table_entry_insert(ip4_fib_get(fib_table->ft_index),
                                   &prefix->fp_addr.ip4,
                                   prefix->fp_len,
                                   fib_entry_index);
@@ -220,7 +220,7 @@ fib_table_entry_insert (fib_table_t *fib_table,
                                   fib_entry_index);
        break;
     case FIB_PROTOCOL_MPLS:
-       mpls_fib_table_entry_insert(&fib_table->mpls,
+       mpls_fib_table_entry_insert(mpls_fib_get(fib_table->ft_index),
                                    prefix->fp_label,
                                    prefix->fp_eos,
                                    fib_entry_index);
@@ -270,7 +270,9 @@ fib_table_fwding_dpo_remove (u32 fib_index,
        return (ip4_fib_table_fwding_dpo_remove(ip4_fib_get(fib_index),
                                                &prefix->fp_addr.ip4,
                                                prefix->fp_len,
-                                               dpo));
+                                               dpo,
+                                                fib_table_get_less_specific(fib_index,
+                                                                            prefix)));
     case FIB_PROTOCOL_IP6:
        return (ip6_fib_table_fwding_dpo_remove(fib_index,
                                                &prefix->fp_addr.ip6,
@@ -480,6 +482,7 @@ fib_table_route_path_fixup (const fib_prefix_t *prefix,
        path->frp_sw_if_index != ~0)
     {
        path->frp_addr = prefix->fp_addr;
+        path->frp_flags |= FIB_ROUTE_PATH_ATTACHED;
     }
 }                
 
@@ -1033,13 +1036,33 @@ fib_table_destroy (fib_table_t *fib_table)
     switch (fib_table->ft_proto)
     {
     case FIB_PROTOCOL_IP4:
-       ip4_fib_table_destroy(&fib_table->v4);
+       ip4_fib_table_destroy(fib_table->ft_index);
        break;
     case FIB_PROTOCOL_IP6:
        ip6_fib_table_destroy(fib_table->ft_index);
        break;
     case FIB_PROTOCOL_MPLS:
-       mpls_fib_table_destroy(&fib_table->mpls);
+       mpls_fib_table_destroy(fib_table->ft_index);
+       break;
+    }
+}
+
+void
+fib_table_walk (u32 fib_index,
+                fib_protocol_t proto,
+                fib_table_walk_fn_t fn,
+                void *ctx)
+{
+    switch (proto)
+    {
+    case FIB_PROTOCOL_IP4:
+       ip4_fib_table_walk(ip4_fib_get(fib_index), fn, ctx);
+       break;
+    case FIB_PROTOCOL_IP6:
+       ip6_fib_table_walk(fib_index, fn, ctx);
+       break;
+    case FIB_PROTOCOL_MPLS:
+       mpls_fib_table_walk(mpls_fib_get(fib_index), fn, ctx);
        break;
     }
 }
@@ -1094,11 +1117,56 @@ format_fib_table_name (u8* s, va_list ap)
     return (s);
 }
 
+/**
+ * @brief Table flush context. Store the indicies of matching FIB entries
+ * that need to be removed.
+ */
+typedef struct fib_table_flush_ctx_t_
+{
+    /**
+     * The list of entries to flush
+     */
+    fib_node_index_t *ftf_entries;
+
+    /**
+     * The source we are flushing
+     */
+    fib_source_t ftf_source;
+} fib_table_flush_ctx_t;
+
+static int
+fib_table_flush_cb (fib_node_index_t fib_entry_index,
+                    void *arg)
+{
+    fib_table_flush_ctx_t *ctx = arg;
+
+    if (fib_entry_is_sourced(fib_entry_index, ctx->ftf_source))
+    {
+        vec_add1(ctx->ftf_entries, fib_entry_index);
+    }
+    return (1);
+}
+
+
 void
 fib_table_flush (u32 fib_index,
                 fib_protocol_t proto,
                 fib_source_t source)
 {
-    // FIXME
-    ASSERT(0);
+    fib_node_index_t *fib_entry_index;
+    fib_table_flush_ctx_t ctx = {
+        .ftf_entries = NULL,
+        .ftf_source = source,
+    };
+
+    fib_table_walk(fib_index, proto,
+                   fib_table_flush_cb,
+                   &ctx);
+
+    vec_foreach(fib_entry_index, ctx.ftf_entries)
+    {
+        fib_table_entry_delete_index(*fib_entry_index, source);
+    }
+
+    vec_free(ctx.ftf_entries);
 }