fib: Source Address Selection
[vpp.git] / src / vnet / fib / fib_entry_src.c
index cd4e470..7f4db6a 100644 (file)
 #include <vnet/fib/fib_table.h>
 #include <vnet/fib/fib_path_ext.h>
 #include <vnet/fib/fib_urpf_list.h>
+#include <vnet/fib/fib_entry_delegate.h>
 
 /*
  * per-source type vft
  */
-static fib_entry_src_vft_t fib_entry_src_vft[FIB_SOURCE_MAX];
+static fib_entry_src_vft_t fib_entry_src_bh_vft[FIB_SOURCE_BH_MAX];
 
 /**
  * Get the VFT for a given source. This is a combination of the source
@@ -36,12 +37,16 @@ static fib_entry_src_vft_t fib_entry_src_vft[FIB_SOURCE_MAX];
 const fib_entry_src_vft_t*
 fib_entry_src_get_vft (const fib_entry_src_t *esrc)
 {
+    fib_source_behaviour_t bh;
+
+    bh = fib_source_get_behaviour(esrc->fes_src);
+
     if (esrc->fes_entry_flags & FIB_ENTRY_FLAG_INTERPOSE)
     {
-        return (&fib_entry_src_vft[FIB_SOURCE_INTERPOSE]);
+        return (&fib_entry_src_bh_vft[FIB_SOURCE_BH_INTERPOSE]);
     }
 
-    return (&fib_entry_src_vft[esrc->fes_src]);
+    return (&fib_entry_src_bh_vft[bh]);
 }
 
 static void
@@ -53,14 +58,14 @@ fib_entry_src_copy_default (const fib_entry_src_t *orig_src,
 }
 
 void
-fib_entry_src_register (fib_source_t source,
-                       const fib_entry_src_vft_t *vft)
+fib_entry_src_behaviour_register (fib_source_behaviour_t bh,
+                                  const fib_entry_src_vft_t *vft)
 {
-    fib_entry_src_vft[source] = *vft;
+    fib_entry_src_bh_vft[bh] = *vft;
 
-    if (NULL == fib_entry_src_vft[source].fesv_copy)
+    if (NULL == fib_entry_src_bh_vft[bh].fesv_copy)
     {
-        fib_entry_src_vft[source].fesv_copy = fib_entry_src_copy_default;
+        fib_entry_src_bh_vft[bh].fesv_copy = fib_entry_src_copy_default;
     }
 }
 
@@ -70,7 +75,8 @@ fib_entry_src_cmp_for_sort (void * v1,
 {
     fib_entry_src_t *esrc1 = v1, *esrc2 = v2;
 
-    return (esrc1->fes_src - esrc2->fes_src);
+    return (fib_source_get_prio(esrc1->fes_src) -
+            fib_source_get_prio(esrc2->fes_src));
 }
 
 static void
@@ -85,7 +91,7 @@ fib_entry_src_action_init (fib_entry_t *fib_entry,
         .fes_entry_flags = flags,
     };
 
-    FIB_ENTRY_SRC_VFT_INVOKE(&esrc, fesv_init, (&esrc));
+    FIB_ENTRY_SRC_VFT_INVOKE(fib_entry, &esrc, fesv_init, (&esrc));
 
     vec_add1(fib_entry->fe_srcs, esrc);
     vec_sort_with_function(fib_entry->fe_srcs,
@@ -121,7 +127,7 @@ fib_entry_src_find_i (const fib_entry_t *fib_entry,
     return (NULL);
 }
 
-static fib_entry_src_t *
+fib_entry_src_t *
 fib_entry_src_find (const fib_entry_t *fib_entry,
                    fib_source_t source)
 
@@ -140,6 +146,44 @@ fib_entry_is_sourced (fib_node_index_t fib_entry_index,
     return (NULL != fib_entry_src_find(fib_entry, source));
 }
 
+int
+fib_entry_is_marked (fib_node_index_t fib_entry_index,
+                      fib_source_t source)
+{
+    fib_entry_t *fib_entry;
+    fib_entry_src_t *esrc;
+
+    fib_entry = fib_entry_get(fib_entry_index);
+
+    esrc = fib_entry_src_find(fib_entry, source);
+
+    if (NULL == esrc)
+    {
+        return (0);
+    }
+    else
+    {
+        return (!!(esrc->fes_flags & FIB_ENTRY_SRC_FLAG_STALE));
+    }
+}
+
+void
+fib_entry_mark (fib_node_index_t fib_entry_index,
+                fib_source_t source)
+{
+    fib_entry_t *fib_entry;
+    fib_entry_src_t *esrc;
+
+    fib_entry = fib_entry_get(fib_entry_index);
+
+    esrc = fib_entry_src_find(fib_entry, source);
+
+    if (NULL != esrc)
+    {
+        esrc->fes_flags |= FIB_ENTRY_SRC_FLAG_STALE;
+    }
+}
+
 static fib_entry_src_t *
 fib_entry_src_find_or_create (fib_entry_t *fib_entry,
                              fib_source_t source,
@@ -169,7 +213,7 @@ fib_entry_src_action_deinit (fib_entry_t *fib_entry,
 
     ASSERT(NULL != esrc);
 
-    FIB_ENTRY_SRC_VFT_INVOKE(esrc, fesv_deinit, (esrc));
+    FIB_ENTRY_SRC_VFT_INVOKE(fib_entry, esrc, fesv_deinit, (esrc));
 
     fib_path_ext_list_flush(&esrc->fes_path_exts);
     vec_del1(fib_entry->fe_srcs, index);
@@ -732,7 +776,7 @@ fib_entry_src_action_copy (fib_entry_t *fib_entry,
                                         orig_src->fes_src,
                                         orig_src->fes_entry_flags);
 
-    FIB_ENTRY_SRC_VFT_INVOKE(esrc, fesv_copy,
+    FIB_ENTRY_SRC_VFT_INVOKE(fib_entry, esrc, fesv_copy,
                              (orig_src, fib_entry, esrc));
 
     fib_path_list_unlock(esrc->fes_pl);
@@ -1051,7 +1095,7 @@ fib_entry_src_action_deactivate (fib_entry_t *fib_entry,
 
     ASSERT(esrc->fes_flags & FIB_ENTRY_SRC_FLAG_ACTIVE);
 
-    FIB_ENTRY_SRC_VFT_INVOKE(esrc, fesv_deactivate,
+    FIB_ENTRY_SRC_VFT_INVOKE(fib_entry, esrc, fesv_deactivate,
                              (esrc, fib_entry));
 
     esrc->fes_flags &= ~(FIB_ENTRY_SRC_FLAG_ACTIVE |
@@ -1090,7 +1134,7 @@ fib_entry_src_action_fwd_update (const fib_entry_t *fib_entry,
 
     vec_foreach(esrc, fib_entry->fe_srcs)
     {
-       FIB_ENTRY_SRC_VFT_INVOKE(esrc, fesv_fwd_update,
+       FIB_ENTRY_SRC_VFT_INVOKE(fib_entry, esrc, fesv_fwd_update,
                                  (esrc, fib_entry, source));
     }
 }
@@ -1179,18 +1223,20 @@ fib_entry_src_action_reactivate (fib_entry_t *fib_entry,
     fib_entry_src_action_fwd_update(fib_entry, source);
 }
 
-void
-fib_entry_src_action_installed (const fib_entry_t *fib_entry,
+fib_entry_t *
+fib_entry_src_action_installed (fib_entry_t *fib_entry,
                                fib_source_t source)
 {
     fib_entry_src_t *esrc;
 
     esrc = fib_entry_src_find(fib_entry, source);
 
-    FIB_ENTRY_SRC_VFT_INVOKE(esrc, fesv_installed,
+    FIB_ENTRY_SRC_VFT_INVOKE(fib_entry, esrc, fesv_installed,
                              (esrc, fib_entry));
 
     fib_entry_src_action_fwd_update(fib_entry, source);
+
+    return (fib_entry);
 }
 
 /*
@@ -1207,7 +1253,6 @@ fib_entry_src_action_add (fib_entry_t *fib_entry,
                          fib_entry_flag_t flags,
                          const dpo_id_t *dpo)
 {
-    fib_node_index_t fib_entry_index;
     fib_entry_src_t *esrc;
 
     esrc = fib_entry_src_find_or_create(fib_entry, source, flags);
@@ -1217,7 +1262,7 @@ fib_entry_src_action_add (fib_entry_t *fib_entry,
 
     if (flags != esrc->fes_entry_flags)
     {
-        FIB_ENTRY_SRC_VFT_INVOKE(esrc, fesv_flags_change,
+        FIB_ENTRY_SRC_VFT_INVOKE(fib_entry, esrc, fesv_flags_change,
                                  (esrc, fib_entry, flags));
     }
     esrc->fes_entry_flags = flags;
@@ -1230,20 +1275,13 @@ fib_entry_src_action_add (fib_entry_t *fib_entry,
         return (fib_entry);
     }
 
-    /*
-     * save variable so we can recover from a fib_entry realloc.
-     */
-    fib_entry_index = fib_entry_get_index(fib_entry);
-
-    FIB_ENTRY_SRC_VFT_INVOKE(esrc, fesv_add,
+    FIB_ENTRY_SRC_VFT_INVOKE(fib_entry, esrc, fesv_add,
                              (esrc,
                               fib_entry,
                               flags,
                               fib_entry_get_dpo_proto(fib_entry),
                               dpo));
 
-    fib_entry = fib_entry_get(fib_entry_index);
-
     esrc->fes_flags |= FIB_ENTRY_SRC_FLAG_ADDED;
 
     fib_path_list_lock(esrc->fes_pl);
@@ -1270,7 +1308,7 @@ fib_entry_src_action_update (fib_entry_t *fib_entry,
                             fib_entry_flag_t flags,
                             const dpo_id_t *dpo)
 {
-    fib_node_index_t fib_entry_index, old_path_list_index;
+    fib_node_index_t old_path_list_index;
     fib_entry_src_t *esrc;
 
     esrc = fib_entry_src_find_or_create(fib_entry, source, flags);
@@ -1283,20 +1321,13 @@ fib_entry_src_action_update (fib_entry_t *fib_entry,
     old_path_list_index = esrc->fes_pl;
     esrc->fes_entry_flags = flags;
 
-    /*
-     * save variable so we can recover from a fib_entry realloc.
-     */
-    fib_entry_index = fib_entry_get_index(fib_entry);
-
-    FIB_ENTRY_SRC_VFT_INVOKE(esrc, fesv_add,
+    FIB_ENTRY_SRC_VFT_INVOKE(fib_entry, esrc, fesv_add,
                              (esrc,
                               fib_entry,
                               flags,
                               fib_entry_get_dpo_proto(fib_entry),
                               dpo));
 
-    fib_entry = fib_entry_get(fib_entry_index);
-
     esrc->fes_flags |= FIB_ENTRY_SRC_FLAG_ADDED;
 
     fib_path_list_lock(esrc->fes_pl);
@@ -1391,14 +1422,14 @@ fib_entry_src_action_remove (fib_entry_t *fib_entry,
     }
     else if (esrc->fes_flags & FIB_ENTRY_SRC_FLAG_CONTRIBUTING)
     {
-        FIB_ENTRY_SRC_VFT_INVOKE(esrc, fesv_deactivate,
+        FIB_ENTRY_SRC_VFT_INVOKE(fib_entry, esrc, fesv_deactivate,
                                  (esrc, fib_entry));
         esrc->fes_flags &= ~FIB_ENTRY_SRC_FLAG_CONTRIBUTING;
     }
 
     old_path_list = esrc->fes_pl;
 
-    FIB_ENTRY_SRC_VFT_INVOKE(esrc, fesv_remove, (esrc));
+    FIB_ENTRY_SRC_VFT_INVOKE(fib_entry, esrc, fesv_remove, (esrc));
 
     fib_path_list_unlock(old_path_list);
     fib_entry_unlock(fib_entry_get_index(fib_entry));
@@ -1460,7 +1491,8 @@ fib_path_is_attached (const fib_route_path_t *rpath)
     {
        return (!0);
     }
-    else if (rpath->frp_flags & FIB_ROUTE_PATH_ATTACHED)
+    else if (rpath->frp_flags & FIB_ROUTE_PATH_ATTACHED ||
+             rpath->frp_flags & FIB_ROUTE_PATH_GLEAN)
     {
         return (!0);
     }
@@ -1540,15 +1572,10 @@ fib_entry_src_action_path_add (fib_entry_t *fib_entry,
                               fib_entry_flag_t flags,
                               const fib_route_path_t *rpaths)
 {
-    fib_node_index_t old_path_list, fib_entry_index;
+    fib_node_index_t old_path_list;
     fib_path_list_flags_t pl_flags;
     fib_entry_src_t *esrc;
 
-    /*
-     * save variable so we can recover from a fib_entry realloc.
-     */
-    fib_entry_index = fib_entry_get_index(fib_entry);
-
     esrc = fib_entry_src_find(fib_entry, source);
     if (NULL == esrc)
     {
@@ -1581,9 +1608,8 @@ fib_entry_src_action_path_add (fib_entry_t *fib_entry,
     pl_flags = fib_entry_src_flags_2_path_list_flags(fib_entry_get_flags_i(fib_entry));
     fib_entry_flags_update(fib_entry, rpaths, &pl_flags, esrc);
 
-    FIB_ENTRY_SRC_VFT_INVOKE(esrc, fesv_path_add,
+    FIB_ENTRY_SRC_VFT_INVOKE(fib_entry, esrc, fesv_path_add,
                              (esrc, fib_entry, pl_flags, rpaths));
-    fib_entry = fib_entry_get(fib_entry_index);
 
     fib_path_list_lock(esrc->fes_pl);
     fib_path_list_unlock(old_path_list);
@@ -1606,17 +1632,12 @@ fib_entry_src_action_path_swap (fib_entry_t *fib_entry,
                                fib_entry_flag_t flags,
                                const fib_route_path_t *rpaths)
 {
-    fib_node_index_t old_path_list, fib_entry_index;
+    fib_node_index_t old_path_list;
     fib_path_list_flags_t pl_flags;
     fib_entry_src_t *esrc;
 
     esrc = fib_entry_src_find(fib_entry, source);
 
-    /*
-     * save variable so we can recover from a fib_entry realloc.
-     */
-    fib_entry_index = fib_entry_get_index(fib_entry);
-
     if (NULL == esrc)
     {
        const dpo_id_t *dpo;
@@ -1637,7 +1658,7 @@ fib_entry_src_action_path_swap (fib_entry_t *fib_entry,
     {
         if (flags != esrc->fes_entry_flags)
         {
-            FIB_ENTRY_SRC_VFT_INVOKE(esrc, fesv_flags_change,
+            FIB_ENTRY_SRC_VFT_INVOKE(fib_entry, esrc, fesv_flags_change,
                                      (esrc, fib_entry, flags));
         }
         esrc->fes_entry_flags = flags;
@@ -1656,12 +1677,10 @@ fib_entry_src_action_path_swap (fib_entry_t *fib_entry,
 
     fib_entry_flags_update(fib_entry, rpaths, &pl_flags, esrc);
 
-    FIB_ENTRY_SRC_VFT_INVOKE(esrc, fesv_path_swap,
+    FIB_ENTRY_SRC_VFT_INVOKE(fib_entry, esrc, fesv_path_swap,
                              (esrc, fib_entry,
                               pl_flags, rpaths));
 
-    fib_entry = fib_entry_get(fib_entry_index);
-
     fib_path_list_lock(esrc->fes_pl);
     fib_path_list_unlock(old_path_list);
 
@@ -1695,7 +1714,7 @@ fib_entry_src_action_path_remove (fib_entry_t *fib_entry,
     pl_flags = fib_entry_src_flags_2_path_list_flags(fib_entry_get_flags_i(fib_entry));
     fib_entry_flags_update(fib_entry, rpaths, &pl_flags, esrc);
 
-    FIB_ENTRY_SRC_VFT_INVOKE(esrc, fesv_path_remove,
+    FIB_ENTRY_SRC_VFT_INVOKE(fib_entry, esrc, fesv_path_remove,
                              (esrc, pl_flags, rpaths));
 
     /*
@@ -1826,27 +1845,22 @@ fib_entry_get_flags_for_source (fib_node_index_t entry_index,
     return (FIB_ENTRY_FLAG_NONE);
 }
 
+fib_source_t
+fib_entry_get_source_i (const fib_entry_t *fib_entry)
+{
+    /* the vector of sources is deliberately arranged in priority order */
+    if (0 == vec_len(fib_entry->fe_srcs))
+        return (FIB_SOURCE_INVALID);
+    return (vec_elt(fib_entry->fe_srcs, 0).fes_src);
+}
+
 fib_entry_flag_t
 fib_entry_get_flags_i (const fib_entry_t *fib_entry)
 {
-    fib_entry_flag_t flags;
-
-    /*
-     * the vector of sources is deliberately arranged in priority order
-     */
+    /* the vector of sources is deliberately arranged in priority order */
     if (0 == vec_len(fib_entry->fe_srcs))
-    {
-       flags = FIB_ENTRY_FLAG_NONE;
-    }
-    else
-    {
-       fib_entry_src_t *esrc;
-
-       esrc = vec_elt_at_index(fib_entry->fe_srcs, 0);
-       flags = esrc->fes_entry_flags;
-    }
-
-    return (flags);
+        return (FIB_ENTRY_FLAG_NONE);
+    return (vec_elt(fib_entry->fe_srcs, 0).fes_entry_flags);
 }
 
 void
@@ -1862,7 +1876,7 @@ fib_entry_set_source_data (fib_node_index_t fib_entry_index,
 
     if (NULL != esrc)
     {
-        FIB_ENTRY_SRC_VFT_INVOKE(esrc, fesv_set_data,
+        FIB_ENTRY_SRC_VFT_INVOKE(fib_entry, esrc, fesv_set_data,
                                  (esrc, fib_entry, data));
     }
 }
@@ -1891,8 +1905,8 @@ fib_entry_src_module_init (void)
     fib_entry_src_rr_register();
     fib_entry_src_interface_register();
     fib_entry_src_interpose_register();
-    fib_entry_src_default_route_register();
-    fib_entry_src_special_register();
+    fib_entry_src_drop_register();
+    fib_entry_src_simple_register();
     fib_entry_src_api_register();
     fib_entry_src_adj_register();
     fib_entry_src_mpls_register();