VPP-488: Fix build errors, which uncovered IPv6 load balance lookup bug.
[vpp.git] / vnet / vnet / fib / fib_entry_src.c
index 6107e3e..99ac09e 100644 (file)
@@ -34,6 +34,21 @@ fib_entry_get_proto (const fib_entry_t * fib_entry)
     return (fib_entry->fe_prefix.fp_proto);
 }
 
+static dpo_proto_t
+fib_entry_get_payload_proto (const fib_entry_t * fib_entry)
+{
+    switch (fib_entry->fe_prefix.fp_proto)
+    {
+    case FIB_PROTOCOL_IP4:
+    case FIB_PROTOCOL_IP6:
+       return fib_proto_to_dpo(fib_entry->fe_prefix.fp_proto);
+    case FIB_PROTOCOL_MPLS:
+       return fib_entry->fe_prefix.fp_payload_proto;
+    }
+
+    return (fib_entry->fe_prefix.fp_proto);
+}
+
 void
 fib_entry_src_register (fib_source_t source,
                        const fib_entry_src_vft_t *vft)
@@ -329,7 +344,7 @@ fib_entry_src_mk_lb (fib_entry_t *fib_entry,
         .fct = fct,
     };
 
-    lb_proto = fib_proto_to_dpo(fib_entry_get_proto(fib_entry));
+    lb_proto = fib_entry_get_payload_proto(fib_entry);
 
     fib_path_list_walk(esrc->fes_pl,
                        fib_entry_src_collect_forwarding,
@@ -369,6 +384,7 @@ fib_entry_src_mk_lb (fib_entry_t *fib_entry,
     load_balance_multipath_update(dpo_lb,
                                   ctx.next_hops,
                                   fib_entry_calc_lb_flags(&ctx));
+    vec_free(ctx.next_hops);
 
     /*
      * if this entry is sourced by the uRPF-exempt source then we
@@ -408,21 +424,33 @@ fib_entry_src_action_install (fib_entry_t *fib_entry,
      */
     fib_forward_chain_type_t fct;
     fib_entry_src_t *esrc;
+    int insert;
 
     fct = fib_entry_get_default_chain_type(fib_entry);
     esrc = fib_entry_src_find(fib_entry, source, NULL);
 
+    /*
+     * Every entry has its own load-balance object. All changes to the entry's
+     * forwarding result in an inplace modify of the load-balance. This means
+     * the load-balance object only needs to be added to the forwarding
+     * DB once, when it is created.
+     */
+    insert = !dpo_id_is_valid(&fib_entry->fe_lb[fct]);
+
     fib_entry_src_mk_lb(fib_entry, esrc, fct, &fib_entry->fe_lb[fct]);
 
-    FIB_ENTRY_DBG(fib_entry, "install: %d",
-                 fib_entry->fe_lb[fct]);
+    ASSERT(dpo_id_is_valid(&fib_entry->fe_lb[fct]));
+    FIB_ENTRY_DBG(fib_entry, "install: %d", fib_entry->fe_lb[fct]);
 
     /*
      * insert the adj into the data-plane forwarding trie
      */
-    fib_table_fwding_dpo_update(fib_entry->fe_fib_index,
-                               &fib_entry->fe_prefix,
-                               &fib_entry->fe_lb[fct]);
+    if (insert)
+    {
+       fib_table_fwding_dpo_update(fib_entry->fe_fib_index,
+                                   &fib_entry->fe_prefix,
+                                   &fib_entry->fe_lb[fct]);
+    }
 
     if (FIB_FORW_CHAIN_TYPE_UNICAST_IP4 == fct ||
        FIB_FORW_CHAIN_TYPE_UNICAST_IP6 == fct)