IP Multicast FIB (mfib)
- IPv[46] mfib tables with support for (*,G/m), (*,G) and (S,G) exact and longest prefix match
- Replication represented via a new replicate DPO.
- RPF configuration and data-plane checking
- data-plane signals sent to listening control planes.
The functions of multicast forwarding entries differ from their unicast conterparts, so we introduce a new mfib_table_t and mfib_entry_t objects. However, we re-use the fib_path_list to resolve and build the entry's output list. the fib_path_list provides the service to construct a replicate DPO for multicast.
'make tests' is added to with two new suites; TEST=mfib, this is invocation of the CLI command 'test mfib' which deals with many path add/remove, flag set/unset scenarios, TEST=ip-mcast, data-plane forwarding tests.
Updated applications to use the new MIFB functions;
- IPv6 NS/RA.
- DHCPv6
unit tests for these are undated accordingly.
Change-Id: I49ec37b01f1b170335a5697541c8fd30e6d3a961
Signed-off-by: Neale Ranns <nranns@cisco.com>
diff --git a/src/vnet/fib/fib_path.c b/src/vnet/fib/fib_path.c
index 809e3e1..080057f 100644
--- a/src/vnet/fib/fib_path.c
+++ b/src/vnet/fib/fib_path.c
@@ -23,6 +23,7 @@
#include <vnet/dpo/lookup_dpo.h>
#include <vnet/adj/adj.h>
+#include <vnet/adj/adj_mcast.h>
#include <vnet/fib/fib_path.h>
#include <vnet/fib/fib_node.h>
@@ -960,6 +961,8 @@
cfg_flags |= FIB_PATH_CFG_FLAG_RESOLVE_HOST;
if (rpath->frp_flags & FIB_ROUTE_PATH_RESOLVE_VIA_ATTACHED)
cfg_flags |= FIB_PATH_CFG_FLAG_RESOLVE_ATTACHED;
+ if (rpath->frp_flags & FIB_ROUTE_PATH_LOCAL)
+ cfg_flags |= FIB_PATH_CFG_FLAG_LOCAL;
return (cfg_flags);
}
@@ -1003,28 +1006,25 @@
/*
* deduce the path's tpye from the parementers and save what is needed.
*/
- if (~0 != rpath->frp_sw_if_index)
+ if (path->fp_cfg_flags & FIB_PATH_CFG_FLAG_LOCAL)
{
- if (flags & FIB_PATH_CFG_FLAG_LOCAL)
- {
- path->fp_type = FIB_PATH_TYPE_RECEIVE;
- path->receive.fp_interface = rpath->frp_sw_if_index;
- path->receive.fp_addr = rpath->frp_addr;
- }
- else
- {
- if (ip46_address_is_zero(&rpath->frp_addr))
- {
- path->fp_type = FIB_PATH_TYPE_ATTACHED;
- path->attached.fp_interface = rpath->frp_sw_if_index;
- }
- else
- {
- path->fp_type = FIB_PATH_TYPE_ATTACHED_NEXT_HOP;
- path->attached_next_hop.fp_interface = rpath->frp_sw_if_index;
- path->attached_next_hop.fp_nh = rpath->frp_addr;
- }
- }
+ path->fp_type = FIB_PATH_TYPE_RECEIVE;
+ path->receive.fp_interface = rpath->frp_sw_if_index;
+ path->receive.fp_addr = rpath->frp_addr;
+ }
+ else if (~0 != rpath->frp_sw_if_index)
+ {
+ if (ip46_address_is_zero(&rpath->frp_addr))
+ {
+ path->fp_type = FIB_PATH_TYPE_ATTACHED;
+ path->attached.fp_interface = rpath->frp_sw_if_index;
+ }
+ else
+ {
+ path->fp_type = FIB_PATH_TYPE_ATTACHED_NEXT_HOP;
+ path->attached_next_hop.fp_interface = rpath->frp_sw_if_index;
+ path->attached_next_hop.fp_nh = rpath->frp_addr;
+ }
}
else
{
@@ -1199,7 +1199,7 @@
{
res = (path1->fp_type - path2->fp_type);
}
- if (path1->fp_nh_proto != path2->fp_nh_proto)
+ else if (path1->fp_nh_proto != path2->fp_nh_proto)
{
res = (path1->fp_nh_proto - path2->fp_nh_proto);
}
@@ -1770,8 +1770,11 @@
break;
}
- }
+ case FIB_FORW_CHAIN_TYPE_MCAST_IP4:
+ case FIB_FORW_CHAIN_TYPE_MCAST_IP6:
break;
+ }
+ break;
case FIB_PATH_TYPE_RECURSIVE:
switch (fct)
{
@@ -1781,13 +1784,15 @@
case FIB_FORW_CHAIN_TYPE_MPLS_NON_EOS:
fib_path_recursive_adj_update(path, fct, dpo);
break;
+ case FIB_FORW_CHAIN_TYPE_MCAST_IP4:
+ case FIB_FORW_CHAIN_TYPE_MCAST_IP6:
case FIB_FORW_CHAIN_TYPE_ETHERNET:
ASSERT(0);
break;
}
break;
case FIB_PATH_TYPE_DEAG:
- switch (fct)
+ switch (fct)
{
case FIB_FORW_CHAIN_TYPE_MPLS_NON_EOS:
lookup_dpo_add_or_lock_w_table_id(MPLS_FIB_DEFAULT_TABLE_ID,
@@ -1800,7 +1805,9 @@
case FIB_FORW_CHAIN_TYPE_UNICAST_IP6:
case FIB_FORW_CHAIN_TYPE_MPLS_EOS:
dpo_copy(dpo, &path->fp_dpo);
- break;
+ break;
+ case FIB_FORW_CHAIN_TYPE_MCAST_IP4:
+ case FIB_FORW_CHAIN_TYPE_MCAST_IP6:
case FIB_FORW_CHAIN_TYPE_ETHERNET:
ASSERT(0);
break;
@@ -1810,12 +1817,38 @@
dpo_copy(dpo, &path->exclusive.fp_ex_dpo);
break;
case FIB_PATH_TYPE_ATTACHED:
- case FIB_PATH_TYPE_RECEIVE:
- case FIB_PATH_TYPE_SPECIAL:
- ASSERT(0);
+ switch (fct)
+ {
+ case FIB_FORW_CHAIN_TYPE_MPLS_NON_EOS:
+ case FIB_FORW_CHAIN_TYPE_UNICAST_IP4:
+ case FIB_FORW_CHAIN_TYPE_UNICAST_IP6:
+ case FIB_FORW_CHAIN_TYPE_MPLS_EOS:
+ case FIB_FORW_CHAIN_TYPE_ETHERNET:
+ break;
+ case FIB_FORW_CHAIN_TYPE_MCAST_IP4:
+ case FIB_FORW_CHAIN_TYPE_MCAST_IP6:
+ {
+ adj_index_t ai;
+
+ /*
+ * Create the adj needed for sending IP multicast traffic
+ */
+ ai = adj_mcast_add_or_lock(path->fp_nh_proto,
+ fib_forw_chain_type_to_link_type(fct),
+ path->attached.fp_interface);
+ dpo_set(dpo, DPO_ADJACENCY_MCAST,
+ fib_forw_chain_type_to_dpo_proto(fct),
+ ai);
+ adj_unlock(ai);
+ }
+ break;
+ }
+ break;
+ case FIB_PATH_TYPE_RECEIVE:
+ case FIB_PATH_TYPE_SPECIAL:
+ dpo_copy(dpo, &path->fp_dpo);
break;
}
-
}
}