ip: Use the IP4 lookup functions
[vpp.git] / src / vnet / fib / fib_entry_src_rr.c
index b6f4bc3..d8bc09c 100644 (file)
 #include <vnet/dpo/drop_dpo.h>
 
 #include "fib_entry_src.h"
+#include "fib_entry_src_rr.h"
 #include "fib_entry_cover.h"
 #include "fib_entry.h"
 #include "fib_table.h"
+#include "fib_path_ext.h"
 
 /*
  * fib_entry_src_rr_resolve_via_connected
  *
  * Resolve via a connected cover.
  */
-static void
+void
 fib_entry_src_rr_resolve_via_connected (fib_entry_src_t *src,
                                        const fib_entry_t *fib_entry,
                                        const fib_entry_t *cover)
@@ -53,7 +55,8 @@ fib_entry_src_rr_resolve_via_connected (fib_entry_src_t *src,
      * shortly to over-rule this RR source.
      */
     src->fes_pl = fib_path_list_create(FIB_PATH_LIST_FLAG_NONE, paths);
-    src->fes_entry_flags = fib_entry_get_flags(fib_entry_get_index(cover));
+    src->fes_entry_flags |= (fib_entry_get_flags(fib_entry_get_index(cover)) &
+                             FIB_ENTRY_FLAGS_RR_INHERITED);
 
     vec_free(paths);
 }
@@ -65,8 +68,8 @@ fib_entry_src_rr_resolve_via_connected (fib_entry_src_t *src,
 static void
 fib_entry_src_rr_init (fib_entry_src_t *src)
 {
-    src->rr.fesr_cover = FIB_NODE_INDEX_INVALID;
-    src->rr.fesr_sibling = FIB_NODE_INDEX_INVALID;
+    src->u.rr.fesr_cover = FIB_NODE_INDEX_INVALID;
+    src->u.rr.fesr_sibling = FIB_NODE_INDEX_INVALID;
 }
 
 
@@ -77,20 +80,21 @@ fib_entry_src_rr_init (fib_entry_src_t *src)
  * and there would be 2 locks on the path-list; one since its used
  * by the cover, and 1 from here. The first lock will go when the
  * cover is removed, the second, and last, when the covered walk
- * occurs during the cover's removel - this is not a place where
+ * occurs during the cover's removal - this is not a place where
  * we can handle last lock gone.
  * In short, don't let the loop form. The usual rules of 'we must
  * let it form so we know when it breaks' don't apply here, since
  * the loop will break when the cover changes, and this function
  * will be called again when that happens.
  */
-static void
+void
 fib_entry_src_rr_use_covers_pl (fib_entry_src_t *src,
                                 const fib_entry_t *fib_entry,
                                 const fib_entry_t *cover)
 {
     fib_node_index_t *entries = NULL;
     dpo_proto_t proto;
+    fib_entry_src_t *s;
 
     proto = fib_proto_to_dpo(fib_entry->fe_prefix.fp_proto);
     vec_add1(entries, fib_entry_get_index(fib_entry));
@@ -105,6 +109,14 @@ fib_entry_src_rr_use_covers_pl (fib_entry_src_t *src,
     else
     {
         src->fes_pl = cover->fe_parent;
+        vec_foreach (s,cover->fe_srcs)
+          {
+            if (s->fes_pl != cover->fe_parent)
+              continue;
+
+            src->fes_path_exts.fpel_exts = vec_dup (s->fes_path_exts.fpel_exts);
+            break;
+          }
     }
     vec_free(entries);
 }
@@ -132,14 +144,14 @@ fib_entry_src_rr_activate (fib_entry_src_t *src,
        return (!0);
     }
 
-    src->rr.fesr_cover = fib_table_get_less_specific(fib_entry->fe_fib_index,
+    src->u.rr.fesr_cover = fib_table_get_less_specific(fib_entry->fe_fib_index,
                                                     &fib_entry->fe_prefix);
 
-    ASSERT(FIB_NODE_INDEX_INVALID != src->rr.fesr_cover);
+    ASSERT(FIB_NODE_INDEX_INVALID != src->u.rr.fesr_cover);
 
-    cover = fib_entry_get(src->rr.fesr_cover);
+    cover = fib_entry_get(src->u.rr.fesr_cover);
 
-    src->rr.fesr_sibling =
+    src->u.rr.fesr_sibling =
        fib_entry_cover_track(cover, fib_entry_get_index(fib_entry));
 
     /*
@@ -173,21 +185,31 @@ fib_entry_src_rr_deactivate (fib_entry_src_t *src,
     fib_entry_t *cover;
 
     /*
-     * remove the depednecy on the covering entry
+     * remove the dependency on the covering entry
      */
-    if (FIB_NODE_INDEX_INVALID != src->rr.fesr_cover)
+    if (FIB_NODE_INDEX_INVALID != src->u.rr.fesr_cover)
     {
-       cover = fib_entry_get(src->rr.fesr_cover);
-       fib_entry_cover_untrack(cover, src->rr.fesr_sibling);
-       src->rr.fesr_cover = FIB_NODE_INDEX_INVALID;
+        fib_node_index_t *entries = NULL;
+
+       cover = fib_entry_get(src->u.rr.fesr_cover);
+       fib_entry_cover_untrack(cover, src->u.rr.fesr_sibling);
+       src->u.rr.fesr_cover = FIB_NODE_INDEX_INVALID;
+
+        if (FIB_NODE_INDEX_INVALID != cover->fe_parent)
+        {
+            fib_path_list_recursive_loop_detect(cover->fe_parent, &entries);
+
+            vec_free(entries);
+        }
     }
 
     fib_path_list_unlock(src->fes_pl);
     src->fes_pl = FIB_NODE_INDEX_INVALID;
+    vec_free (src->fes_path_exts.fpel_exts);
     src->fes_entry_flags = FIB_ENTRY_FLAG_NONE;
 }
 
-static fib_entry_src_cover_res_t
+fib_entry_src_cover_res_t
 fib_entry_src_rr_cover_change (fib_entry_src_t *src,
                               const fib_entry_t *fib_entry)
 {
@@ -196,7 +218,7 @@ fib_entry_src_rr_cover_change (fib_entry_src_t *src,
        .bw_reason = FIB_NODE_BW_REASON_FLAG_NONE,
     };
 
-    if (FIB_NODE_INDEX_INVALID == src->rr.fesr_cover)
+    if (FIB_NODE_INDEX_INVALID == src->u.rr.fesr_cover)
     {
        /*
         * the source may be added, but it is not active
@@ -210,7 +232,7 @@ fib_entry_src_rr_cover_change (fib_entry_src_t *src,
      * entry inserted benaeth it. That does not necessarily mean that this
      * entry is covered by the new prefix. check that
      */
-    if (src->rr.fesr_cover != fib_table_get_less_specific(fib_entry->fe_fib_index,
+    if (src->u.rr.fesr_cover != fib_table_get_less_specific(fib_entry->fe_fib_index,
                                                          &fib_entry->fe_prefix))
     {
        fib_entry_src_rr_deactivate(src, fib_entry);
@@ -230,7 +252,7 @@ fib_entry_src_rr_cover_change (fib_entry_src_t *src,
  * This entry's cover has updated its forwarding info. This entry
  * will need to re-inheret.
  */
-static fib_entry_src_cover_res_t
+fib_entry_src_cover_res_t
 fib_entry_src_rr_cover_update (fib_entry_src_t *src,
                               const fib_entry_t *fib_entry)
 {
@@ -241,7 +263,7 @@ fib_entry_src_rr_cover_update (fib_entry_src_t *src,
     fib_node_index_t old_path_list;
     fib_entry_t *cover;
 
-    if (FIB_NODE_INDEX_INVALID == src->rr.fesr_cover)
+    if (FIB_NODE_INDEX_INVALID == src->u.rr.fesr_cover)
     {
        /*
         * the source may be added, but it is not active
@@ -250,7 +272,7 @@ fib_entry_src_rr_cover_update (fib_entry_src_t *src,
        return (res);
     }
 
-    cover = fib_entry_get(src->rr.fesr_cover);
+    cover = fib_entry_get(src->u.rr.fesr_cover);
     old_path_list = src->fes_pl;
 
     /*
@@ -280,7 +302,7 @@ static u8*
 fib_entry_src_rr_format (fib_entry_src_t *src,
                         u8* s)
 {
-    return (format(s, " cover:%d", src->rr.fesr_cover));
+    return (format(s, " cover:%d", src->u.rr.fesr_cover));
 }
 
 const static fib_entry_src_vft_t rr_src_vft = {
@@ -295,6 +317,5 @@ const static fib_entry_src_vft_t rr_src_vft = {
 void
 fib_entry_src_rr_register (void)
 {
-    fib_entry_src_register(FIB_SOURCE_RR, &rr_src_vft);    
-    fib_entry_src_register(FIB_SOURCE_URPF_EXEMPT, &rr_src_vft);    
+    fib_entry_src_behaviour_register(FIB_SOURCE_BH_RR, &rr_src_vft);
 }