BIER API and load-balancing fixes
[vpp.git] / src / vnet / bier / bier_table.c
index 80231fd..3ecda10 100644 (file)
@@ -510,9 +510,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;
@@ -552,7 +553,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)
     {
@@ -562,11 +579,51 @@ bier_table_route_add (const bier_table_id_t *btid,
 }
 
 void
-bier_table_route_remove (const bier_table_id_t *btid,
-                         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)
+{
+    bier_table_t *bt;
+    index_t bei;
+
+    bt = bier_table_find(btid);
+
+    if (NULL == bt) {
+        return;
+    }
+
+    bei = bier_table_lookup(bt, bp);
+
+    if (INDEX_INVALID == bei)
+    {
+        /* no such entry */
+        return;
+    }
+
+    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;
+    fib_route_path_t *brp = NULL, *t_paths = NULL;
     index_t bfmi, bti, bei;
     bier_table_t *bt;
     u32 ii;
@@ -616,12 +673,19 @@ bier_table_route_remove (const bier_table_id_t *btid,
         return;
     }
 
-    if (0 == bier_entry_path_remove(bei, brps))
+    vec_foreach(brp, brps)
     {
-        /* 0 remaining paths */
-        bier_table_remove(bt, bp);
-        bier_entry_delete(bei);
+        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