Typos. A bunch of typos I've been collecting.
[vpp.git] / src / vnet / bier / bier_table.c
index 191ac01..a9f8a6d 100644 (file)
@@ -20,6 +20,7 @@
 #include <vnet/bier/bier_update.h>
 #include <vnet/bier/bier_fmask_db.h>
 #include <vnet/bier/bier_fmask.h>
+#include <vnet/bier/bier_bift_table.h>
 
 #include <vnet/fib/mpls_fib.h>
 #include <vnet/mpls/mpls.h>
@@ -96,9 +97,6 @@ bier_table_init (bier_table_t *bt,
                                         num_entries,
                                         INDEX_INVALID,
                                         CLIB_CACHE_LINE_BYTES);
-        fib_table_find_or_create_and_lock(FIB_PROTOCOL_MPLS,
-                                          MPLS_FIB_DEFAULT_TABLE_ID,
-                                          FIB_SOURCE_BIER);
     }
     else
     {
@@ -109,6 +107,33 @@ bier_table_init (bier_table_t *bt,
     }
 }
 
+static void
+bier_table_rm_bift (bier_table_t *bt)
+{
+    ASSERT(MPLS_LABEL_INVALID == bt->bt_ll);
+
+    bier_bift_table_entry_remove(bier_bift_id_encode(bt->bt_id.bti_set,
+                                                     bt->bt_id.bti_sub_domain,
+                                                     bt->bt_id.bti_hdr_len));
+}
+
+static void
+bier_table_mk_bift (bier_table_t *bt)
+{
+    dpo_id_t dpo = DPO_INVALID;
+
+    ASSERT(MPLS_LABEL_INVALID == bt->bt_ll);
+
+    bier_table_contribute_forwarding(bier_table_get_index(bt), &dpo);
+
+    bier_bift_table_entry_add(bier_bift_id_encode(bt->bt_id.bti_set,
+                                                  bt->bt_id.bti_sub_domain,
+                                                  bt->bt_id.bti_hdr_len),
+                               &dpo);
+
+    dpo_reset(&dpo);
+}
+
 static void
 bier_table_rm_lfib (bier_table_t *bt)
 {
@@ -116,6 +141,9 @@ bier_table_rm_lfib (bier_table_t *bt)
     {
         fib_table_entry_delete_index(bt->bt_lfei,
                                      FIB_SOURCE_BIER);
+        fib_table_unlock(MPLS_FIB_DEFAULT_TABLE_ID,
+                         FIB_PROTOCOL_MPLS,
+                         FIB_SOURCE_BIER);
     }
     bt->bt_lfei = FIB_NODE_INDEX_INVALID;
 }
@@ -127,6 +155,15 @@ bier_table_destroy (bier_table_t *bt)
     {
         index_t *bei;
 
+        if (MPLS_LABEL_INVALID != bt->bt_ll)
+        {
+            bier_table_rm_lfib(bt);
+        }
+        else
+        {
+            bier_table_rm_bift(bt);
+        }
+
         fib_path_list_unlock(bt->bt_pl);
         bt->bt_pl = FIB_NODE_INDEX_INVALID;
         /*
@@ -140,10 +177,6 @@ bier_table_destroy (bier_table_t *bt)
             }
         }
         vec_free (bt->bt_entries);
-        fib_table_unlock(fib_table_find(FIB_PROTOCOL_MPLS,
-                                        MPLS_FIB_DEFAULT_TABLE_ID),
-                         FIB_PROTOCOL_MPLS,
-                         FIB_SOURCE_BIER);
     }
     else
     {
@@ -177,7 +210,6 @@ bier_table_unlock_i (bier_table_t *bt)
 
     if (0 == bt->bt_locks)
     {
-        bier_table_rm_lfib(bt);
         bier_table_destroy(bt);
     }
 }
@@ -214,12 +246,17 @@ bier_table_mk_lfib (bier_table_t *bt)
         u32 mpls_fib_index;
         dpo_id_t dpo = DPO_INVALID;
 
+        fib_table_find_or_create_and_lock(FIB_PROTOCOL_MPLS,
+                                          MPLS_FIB_DEFAULT_TABLE_ID,
+                                          FIB_SOURCE_BIER);
+
         /*
-         * stack the entry on the forwarding chain prodcued by the
+         * stack the entry on the forwarding chain produced by the
          * path-list via the ECMP tables.
          */
         fib_path_list_contribute_forwarding(bt->bt_pl,
                                             FIB_FORW_CHAIN_TYPE_BIER,
+                                            FIB_PATH_LIST_FWD_FLAG_COLLAPSE,
                                             &dpo);
 
         mpls_fib_index = fib_table_find(FIB_PROTOCOL_MPLS,
@@ -272,7 +309,7 @@ bier_table_mk_ecmp (index_t bti)
     }
 
     /*
-     * no oppotunity to share, this the resolving ECMP tables are unique
+     * no opportunity to share, this the resolving ECMP tables are unique
      * to this table.
      * no need to be a child of the path list, we can do nothing with any
      * notifications it would generate [not that it will].
@@ -292,50 +329,122 @@ bier_table_mk_ecmp (index_t bti)
     return (bt);
 }
 
-index_t
-bier_table_add_or_lock (const bier_table_id_t *btid,
-                        mpls_label_t local_label)
+
+static index_t
+bier_table_create (const bier_table_id_t *btid,
+                   mpls_label_t local_label)
 {
+    /*
+     * add a new table
+     */
     bier_table_t *bt;
     index_t bti;
+    u32 key;
 
-    bt = bier_table_find(btid);
+    key = bier_table_mk_key(btid);
+
+    pool_get_aligned(bier_table_pool, bt, CLIB_CACHE_LINE_BYTES);
+    bier_table_init(bt, btid, local_label);
+
+    hash_set(bier_tables_by_key, key, bier_table_get_index(bt));
+    bti = bier_table_get_index(bt);
+
+    if (bier_table_is_main(bt))
+    {
+        bt = bier_table_mk_ecmp(bti);
 
-    if (NULL != bt) {
         /*
-         * modify an existing table.
-         * change the lfib entry to the new local label
+         * add whichever mpls-fib or bift we need
          */
-        if (bier_table_is_main(bt) &&
-            (local_label != MPLS_LABEL_INVALID))
+        if (local_label != MPLS_LABEL_INVALID)
         {
-            bier_table_rm_lfib(bt);
-
             bt->bt_ll = local_label;
             bier_table_mk_lfib(bt);
         }
-        bti = bier_table_get_index(bt);
+        else
+        {
+            bier_table_mk_bift(bt);
+        }
+    }
+
+    return (bti);
+}
+
+index_t
+bier_table_lock (const bier_table_id_t *btid)
+{
+    bier_table_t *bt;
+    index_t bti;
+
+    bt = bier_table_find(btid);
+
+    if (NULL == bt)
+    {
+        bti = bier_table_create(btid, MPLS_LABEL_INVALID);
+        bt = bier_table_get(bti);
     }
     else
     {
-        /*
-         * add a new table
-         */
-        u32 key;
+        bti = bier_table_get_index(bt);
+    }
 
-        key = bier_table_mk_key(btid);
+    bier_table_lock_i(bt);
 
-        pool_get_aligned(bier_table_pool, bt, CLIB_CACHE_LINE_BYTES);
-        bier_table_init(bt, btid, local_label);
+    return (bti);
+}
 
-        hash_set(bier_tables_by_key, key, bier_table_get_index(bt));
-        bti = bier_table_get_index(bt);
+index_t
+bier_table_add_or_lock (const bier_table_id_t *btid,
+                        mpls_label_t local_label)
+{
+    bier_table_t *bt;
+    index_t bti;
+
+    bt = bier_table_find(btid);
 
+    if (NULL != bt) {
+        /*
+         * modify an existing table.
+         * change the lfib entry to the new local label
+         */
         if (bier_table_is_main(bt))
         {
-            bt = bier_table_mk_ecmp(bti);
-            bier_table_mk_lfib(bt);
+            /*
+             * remove the mpls-fib or bift entry
+             */
+            if (MPLS_LABEL_INVALID != bt->bt_ll)
+            {
+                bier_table_rm_lfib(bt);
+            }
+            else
+            {
+                bier_table_rm_bift(bt);
+            }
+
+            /*
+             * reset
+             */
+            bt->bt_ll = MPLS_LABEL_INVALID;
+
+            /*
+             * add whichever mpls-fib or bift we need
+             */
+            if (local_label != MPLS_LABEL_INVALID)
+            {
+                bt->bt_ll = local_label;
+                bier_table_mk_lfib(bt);
+            }
+            else
+            {
+                bier_table_mk_bift(bt);
+            }
         }
+        bti = bier_table_get_index(bt);
+    }
+    else
+    {
+        bti = bier_table_create(btid, local_label);
+        bt = bier_table_get(bti);
     }
 
     bier_table_lock_i(bt);
@@ -437,9 +546,10 @@ bier_table_remove (bier_table_t *bt,
 }
 
 void
-bier_table_route_add (const bier_table_id_t *btid,
-                      bier_bp_t bp,
-                      fib_route_path_t *brps)
+bier_table_route_path_update_i (const bier_table_id_t *btid,
+                                bier_bp_t bp,
+                                fib_route_path_t *brps,
+                                u8 is_replace)
 {
     index_t bfmi, bti, bei, *bfmip, *bfmis = NULL;
     fib_route_path_t *brp;
@@ -459,16 +569,19 @@ bier_table_route_add (const bier_table_id_t *btid,
      */
     vec_foreach(brp, brps)
     {
-        bier_fmask_id_t fmid = {
-            .bfmi_nh = brp->frp_addr,
-            .bfmi_hdr_type = BIER_HDR_O_MPLS,
-        };
-        bfmi = bier_fmask_db_find_or_create_and_lock(bier_table_get_index(bt),
-                                                     &fmid,
-                                                     brp);
-
-        brp->frp_bier_fib_index = bti;
+        /*
+         * First use the path to find or construct an FMask object
+         * via the next-hop
+         */
+        bfmi = bier_fmask_db_find_or_create_and_lock(bti, brp);
         vec_add1(bfmis, bfmi);
+
+        /*
+         * then modify the path to resolve via this fmask object
+         * and use it to resolve the BIER entry.
+         */
+        brp->frp_flags = FIB_ROUTE_PATH_BIER_FMASK;
+        brp->frp_bier_fmask = bfmi;
     }
 
     if (INDEX_INVALID == bei)
@@ -476,7 +589,23 @@ bier_table_route_add (const bier_table_id_t *btid,
         bei = bier_entry_create(bti, bp);
         bier_table_insert(bt, bp, bei);
     }
-    bier_entry_path_add(bei, brps);
+
+    if (is_replace)
+    {
+        bier_entry_path_update(bei, brps);
+    }
+    else
+    {
+        fib_route_path_t *t_paths = NULL;
+
+        vec_foreach(brp, brps)
+        {
+            vec_add1(t_paths, *brp);
+            bier_entry_path_add(bei, t_paths);
+            vec_reset_length(t_paths);
+        }
+        vec_free(t_paths);
+    }
 
     vec_foreach(bfmip, bfmis)
     {
@@ -486,15 +615,28 @@ bier_table_route_add (const bier_table_id_t *btid,
 }
 
 void
-bier_table_route_remove (const bier_table_id_t *bti,
-                         bier_bp_t bp,
-                         fib_route_path_t *brps)
+bier_table_route_path_update (const bier_table_id_t *btid,
+                              bier_bp_t bp,
+                              fib_route_path_t *brps)
+{
+    bier_table_route_path_update_i(btid, bp, brps, 1);
+}
+void
+bier_table_route_path_add (const bier_table_id_t *btid,
+                           bier_bp_t bp,
+                           fib_route_path_t *brps)
+{
+    bier_table_route_path_update_i(btid, bp, brps, 0);
+}
+
+void
+bier_table_route_delete (const bier_table_id_t *btid,
+                         bier_bp_t bp)
 {
-    fib_route_path_t *brp = NULL;
     bier_table_t *bt;
     index_t bei;
 
-    bt = bier_table_find(bti);
+    bt = bier_table_find(btid);
 
     if (NULL == bt) {
         return;
@@ -508,17 +650,78 @@ bier_table_route_remove (const bier_table_id_t *bti,
         return;
     }
 
-    vec_foreach(brp, brps)
+    bier_table_remove(bt, bp);
+    bier_entry_delete(bei);
+}
+
+void
+bier_table_route_path_remove (const bier_table_id_t *btid,
+                              bier_bp_t bp,
+                              fib_route_path_t *brps)
+{
+    fib_route_path_t *brp = NULL, *t_paths = NULL;
+    index_t bfmi, bti, bei;
+    bier_table_t *bt;
+    u32 ii;
+
+    bt = bier_table_find(btid);
+
+    if (NULL == bt) {
+        return;
+    }
+
+    bti = bier_table_get_index(bt);
+    bei = bier_table_lookup(bt, bp);
+
+    if (INDEX_INVALID == bei)
     {
-        brp->frp_bier_fib_index = bier_table_get_index(bt);
+        /* no such entry */
+        return;
     }
 
-    if (0 == bier_entry_path_remove(bei, brps))
+    /*
+     * set the FIB index in the path to the BIER table index
+     */
+    vec_foreach_index(ii, brps)
     {
-        /* 0 remaining paths */
-        bier_table_remove(bt, bp);
-        bier_entry_delete(bei);
+        brp = &brps[ii];
+        bfmi = bier_fmask_db_find(bti, brp);
+
+        if (INDEX_INVALID == bfmi)
+        {
+            /*
+             * no matching fmask, not a path we can remove
+             */
+            vec_del1(brps, ii);
+            continue;
+        }
+
+        /*
+         * then modify the path to resolve via this fmask object
+         * and use it to resolve the BIER entry.
+         */
+        brp->frp_flags = FIB_ROUTE_PATH_BIER_FMASK;
+        brp->frp_bier_fmask = bfmi;
+    }
+
+    if (0 == vec_len(brps))
+    {
+        return;
+    }
+
+    vec_foreach(brp, brps)
+    {
+        vec_add1(t_paths, *brp);
+        if (0 == bier_entry_path_remove(bei, t_paths))
+        {
+            /* 0 remaining paths */
+            bier_table_remove(bt, bp);
+            bier_entry_delete(bei);
+            break;
+        }
+        vec_reset_length(t_paths);
     }
+    vec_free(t_paths);
 }
 
 void
@@ -536,6 +739,7 @@ bier_table_contribute_forwarding (index_t bti,
          */
         fib_path_list_contribute_forwarding(bt->bt_pl,
                                             FIB_FORW_CHAIN_TYPE_BIER,
+                                            FIB_PATH_LIST_FWD_FLAG_COLLAPSE,
                                             dpo);
     }
     else
@@ -642,12 +846,12 @@ format_bier_table (u8 *s, va_list *ap)
 
     if (pool_is_free_index(bier_table_pool, bti))
     {
-        return (format(s, "No BIER f-mask %d", bti));
+        return (format(s, "No BIER table %d", bti));
     }
 
     bt = bier_table_get(bti);
 
-    s = format(s, "[@%d] bier-table:[%U local-label:%U]",
+    s = format(s, "[@%d] bier-table:[%U local-label:%U",
                bti,
                format_bier_table_id, &bt->bt_id,
                format_mpls_unicast_label, bt->bt_ll);