aboutsummaryrefslogtreecommitdiffstats
path: root/src/vnet/ip
diff options
context:
space:
mode:
authorNeale Ranns <nranns@cisco.com>2017-03-01 15:12:11 -0800
committerNeale Ranns <nranns@cisco.com>2017-04-07 09:12:12 +0000
commit0f26c5a0138ac86d7ebd197c31a09d8d624c35fe (patch)
tree5cee4659885432c439e44d7346fd5e482df5f0e6 /src/vnet/ip
parentc14f31c2c62fb66d98aef4402a6f1bda09683fd3 (diff)
MPLS Mcast
1 - interface-DPO Used in the Data-plane to change a packet's input interface 2 - MPLS multicast FIB entry Same as a unicast entry but it links to a replicate not a load-balance DPO 3 - Multicast MPLS tunnel Update MPLS tunnels to use a FIB path-list to describe the endpoint[s]. Use the path-list to generate the forwarding chain (DPOs) to link to . 4 - Resolve a path via a local label (of an mLDP LSP) For IP multicast entries to use an LSP in the replication list, we need to decribe the 'resolve-via-label' where the label is that of a multicast LSP. 5 - MPLS disposition path sets RPF-ID For a interface-less LSP (i.e. mLDP not RSVP-TE) at the tail of the LSP we still need to perform an RPF check. An MPLS disposition DPO performs the MPLS pop validation checks and sets the RPF-ID in the packet. 6 - RPF check with per-entry RPF-ID An RPF-ID is used instead of a real interface SW if index in the case the IP traffic arrives from an LSP that does not have an associated interface. Change-Id: Ib92e177be919147bafeb599729abf3d1abc2f4b3 Signed-off-by: Neale Ranns <nranns@cisco.com>
Diffstat (limited to 'src/vnet/ip')
-rw-r--r--src/vnet/ip/ip.api3
-rw-r--r--src/vnet/ip/ip4_forward.c20
-rw-r--r--src/vnet/ip/ip6_forward.c23
-rw-r--r--src/vnet/ip/ip6_neighbor.c1
-rw-r--r--src/vnet/ip/ip_api.c98
-rwxr-xr-xsrc/vnet/ip/lookup.c3
6 files changed, 108 insertions, 40 deletions
diff --git a/src/vnet/ip/ip.api b/src/vnet/ip/ip.api
index 5c2df32cfd0..6af1714f34d 100644
--- a/src/vnet/ip/ip.api
+++ b/src/vnet/ip/ip.api
@@ -478,6 +478,7 @@ define ip_mroute_add_del
u32 table_id;
u32 entry_flags;
u32 itf_flags;
+ u32 rpf_id;
u16 grp_address_length;
u8 create_vrf_if_needed;
u8 is_add;
@@ -518,6 +519,8 @@ manual_endian manual_print define ip_mfib_details
{
u32 context;
u32 table_id;
+ u32 entry_flags;
+ u32 rpf_id;
u8 address_length;
u8 grp_address[4];
u8 src_address[4];
diff --git a/src/vnet/ip/ip4_forward.c b/src/vnet/ip/ip4_forward.c
index fdfe7f63dfc..9fdf9b3cee1 100644
--- a/src/vnet/ip/ip4_forward.c
+++ b/src/vnet/ip/ip4_forward.c
@@ -2752,6 +2752,16 @@ ip4_rewrite_mcast (vlib_main_t * vm,
return ip4_rewrite_inline (vm, node, frame, 0, 0, 1);
}
+static uword
+ip4_mcast_midchain (vlib_main_t * vm,
+ vlib_node_runtime_t * node, vlib_frame_t * frame)
+{
+ if (adj_are_counters_enabled ())
+ return ip4_rewrite_inline (vm, node, frame, 1, 1, 1);
+ else
+ return ip4_rewrite_inline (vm, node, frame, 0, 1, 1);
+}
+
/* *INDENT-OFF* */
VLIB_REGISTER_NODE (ip4_rewrite_node) = {
.function = ip4_rewrite,
@@ -2778,6 +2788,16 @@ VLIB_REGISTER_NODE (ip4_rewrite_mcast_node) = {
};
VLIB_NODE_FUNCTION_MULTIARCH (ip4_rewrite_mcast_node, ip4_rewrite_mcast)
+VLIB_REGISTER_NODE (ip4_mcast_midchain_node, static) = {
+ .function = ip4_mcast_midchain,
+ .name = "ip4-mcast-midchain",
+ .vector_size = sizeof (u32),
+
+ .format_trace = format_ip4_rewrite_trace,
+ .sibling_of = "ip4-rewrite",
+};
+VLIB_NODE_FUNCTION_MULTIARCH (ip4_mcast_midchain_node, ip4_mcast_midchain)
+
VLIB_REGISTER_NODE (ip4_midchain_node) = {
.function = ip4_midchain,
.name = "ip4-midchain",
diff --git a/src/vnet/ip/ip6_forward.c b/src/vnet/ip/ip6_forward.c
index c2fc4f873f2..a369f79fbb8 100644
--- a/src/vnet/ip/ip6_forward.c
+++ b/src/vnet/ip/ip6_forward.c
@@ -2246,6 +2246,16 @@ ip6_midchain (vlib_main_t * vm,
return ip6_rewrite_inline (vm, node, frame, 0, 1, 0);
}
+static uword
+ip6_mcast_midchain (vlib_main_t * vm,
+ vlib_node_runtime_t * node, vlib_frame_t * frame)
+{
+ if (adj_are_counters_enabled ())
+ return ip6_rewrite_inline (vm, node, frame, 1, 1, 1);
+ else
+ return ip6_rewrite_inline (vm, node, frame, 1, 1, 1);
+}
+
/* *INDENT-OFF* */
VLIB_REGISTER_NODE (ip6_midchain_node) =
{
@@ -2290,6 +2300,19 @@ VLIB_REGISTER_NODE (ip6_rewrite_mcast_node) =
VLIB_NODE_FUNCTION_MULTIARCH (ip6_rewrite_mcast_node, ip6_rewrite_mcast);
+/* *INDENT-OFF* */
+VLIB_REGISTER_NODE (ip6_mcast_midchain_node, static) =
+{
+ .function = ip6_mcast_midchain,
+ .name = "ip6-mcast-midchain",
+ .vector_size = sizeof (u32),
+ .format_trace = format_ip6_rewrite_trace,
+ .sibling_of = "ip6-rewrite",
+};
+/* *INDENT-ON* */
+
+VLIB_NODE_FUNCTION_MULTIARCH (ip6_mcast_midchain_node, ip6_mcast_midchain);
+
/*
* Hop-by-Hop handling
*/
diff --git a/src/vnet/ip/ip6_neighbor.c b/src/vnet/ip/ip6_neighbor.c
index 2af546df8de..58b997aa0db 100644
--- a/src/vnet/ip/ip6_neighbor.c
+++ b/src/vnet/ip/ip6_neighbor.c
@@ -557,6 +557,7 @@ ip6_ethernet_update_adjacency (vnet_main_t * vnm, u32 sw_if_index, u32 ai)
case IP_LOOKUP_NEXT_PUNT:
case IP_LOOKUP_NEXT_LOCAL:
case IP_LOOKUP_NEXT_REWRITE:
+ case IP_LOOKUP_NEXT_MCAST_MIDCHAIN:
case IP_LOOKUP_NEXT_MIDCHAIN:
case IP_LOOKUP_NEXT_ICMP_ERROR:
case IP_LOOKUP_N_NEXT:
diff --git a/src/vnet/ip/ip_api.c b/src/vnet/ip/ip_api.c
index b9f1782b342..9c9cb4a445a 100644
--- a/src/vnet/ip/ip_api.c
+++ b/src/vnet/ip/ip_api.c
@@ -438,17 +438,20 @@ vl_api_ip6_fib_dump_t_handler (vl_api_ip6_fib_dump_t * mp)
}
static void
-send_ip_mfib_details (vpe_api_main_t * am,
- unix_shared_memory_queue_t * q,
- u32 table_id,
- mfib_prefix_t * pfx,
- fib_route_path_encode_t * api_rpaths, u32 context)
+send_ip_mfib_details (unix_shared_memory_queue_t * q,
+ u32 context, u32 table_id, fib_node_index_t mfei)
{
+ fib_route_path_encode_t *api_rpath, *api_rpaths = NULL;
vl_api_ip_mfib_details_t *mp;
- fib_route_path_encode_t *api_rpath;
+ mfib_entry_t *mfib_entry;
vl_api_fib_path_t *fp;
+ mfib_prefix_t pfx;
int path_count;
+ mfib_entry = mfib_entry_get (mfei);
+ mfib_entry_get_prefix (mfei, &pfx);
+ mfib_entry_encode (mfei, &api_rpaths);
+
path_count = vec_len (api_rpaths);
mp = vl_msg_api_alloc (sizeof (*mp) + path_count * sizeof (*fp));
if (!mp)
@@ -457,12 +460,14 @@ send_ip_mfib_details (vpe_api_main_t * am,
mp->_vl_msg_id = ntohs (VL_API_IP_FIB_DETAILS);
mp->context = context;
+ mp->rpf_id = mfib_entry->mfe_rpf_id;
+ mp->entry_flags = mfib_entry->mfe_flags;
mp->table_id = htonl (table_id);
- mp->address_length = pfx->fp_len;
- memcpy (mp->grp_address, &pfx->fp_grp_addr.ip4,
- sizeof (pfx->fp_grp_addr.ip4));
- memcpy (mp->src_address, &pfx->fp_src_addr.ip4,
- sizeof (pfx->fp_src_addr.ip4));
+ mp->address_length = pfx.fp_len;
+ memcpy (mp->grp_address, &pfx.fp_grp_addr.ip4,
+ sizeof (pfx.fp_grp_addr.ip4));
+ memcpy (mp->src_address, &pfx.fp_src_addr.ip4,
+ sizeof (pfx.fp_src_addr.ip4));
mp->count = htonl (path_count);
fp = mp->path;
@@ -475,6 +480,7 @@ send_ip_mfib_details (vpe_api_main_t * am,
copy_fib_next_hop (api_rpath, fp);
fp++;
}
+ vec_free (api_rpaths);
vl_msg_api_send_shmem (q, (u8 *) & mp);
}
@@ -497,13 +503,10 @@ vl_api_ip_mfib_table_dump_walk (fib_node_index_t fei, void *arg)
static void
vl_api_ip_mfib_dump_t_handler (vl_api_ip_mfib_dump_t * mp)
{
- vpe_api_main_t *am = &vpe_api_main;
unix_shared_memory_queue_t *q;
ip4_main_t *im = &ip4_main;
mfib_table_t *mfib_table;
fib_node_index_t *mfeip;
- mfib_prefix_t pfx;
- fib_route_path_encode_t *api_rpaths = NULL;
vl_api_ip_mfib_dump_ctc_t ctx = {
.entries = NULL,
};
@@ -524,21 +527,16 @@ vl_api_ip_mfib_dump_t_handler (vl_api_ip_mfib_dump_t * mp)
vec_foreach (mfeip, ctx.entries)
{
- mfib_entry_get_prefix (*mfeip, &pfx);
- mfib_entry_encode (*mfeip, &api_rpaths);
- send_ip_mfib_details (am, q,
+ send_ip_mfib_details (q, mp->context,
mfib_table->mft_table_id,
- &pfx, api_rpaths,
- mp->context);
+ *mfeip);
}
- vec_reset_length (api_rpaths);
vec_reset_length (ctx.entries);
}));
/* *INDENT-ON* */
vec_free (ctx.entries);
- vec_free (api_rpaths);
}
static void
@@ -705,10 +703,13 @@ add_del_route_t_handler (u8 is_multipath,
u8 is_unreach,
u8 is_prohibit,
u8 is_local,
+ u8 is_multicast,
u8 is_classify,
u32 classify_table_index,
u8 is_resolve_host,
u8 is_resolve_attached,
+ u8 is_interface_rx,
+ u8 is_rpf_id,
u32 fib_index,
const fib_prefix_t * prefix,
u8 next_hop_proto_is_ip4,
@@ -731,16 +732,24 @@ add_del_route_t_handler (u8 is_multipath,
.frp_label_stack = next_hop_out_label_stack,
};
fib_route_path_t *paths = NULL;
+ fib_entry_flag_t entry_flags = FIB_ENTRY_FLAG_NONE;
if (MPLS_LABEL_INVALID != next_hop_via_label)
{
path.frp_proto = FIB_PROTOCOL_MPLS;
path.frp_local_label = next_hop_via_label;
+ path.frp_eos = MPLS_NON_EOS;
}
if (is_resolve_host)
path_flags |= FIB_ROUTE_PATH_RESOLVE_VIA_HOST;
if (is_resolve_attached)
path_flags |= FIB_ROUTE_PATH_RESOLVE_VIA_ATTACHED;
+ if (is_interface_rx)
+ path_flags |= FIB_ROUTE_PATH_INTF_RX;
+ if (is_rpf_id)
+ path_flags |= FIB_ROUTE_PATH_RPF_ID;
+ if (is_multicast)
+ entry_flags |= FIB_ENTRY_FLAG_MULTICAST;
path.frp_flags = path_flags;
@@ -754,8 +763,7 @@ add_del_route_t_handler (u8 is_multipath,
if (is_add)
fib_table_entry_path_add2 (fib_index,
prefix,
- FIB_SOURCE_API,
- FIB_ENTRY_FLAG_NONE, paths);
+ FIB_SOURCE_API, entry_flags, paths);
else
fib_table_entry_path_remove2 (fib_index,
prefix, FIB_SOURCE_API, paths);
@@ -826,8 +834,7 @@ add_del_route_t_handler (u8 is_multipath,
{
vec_add1 (paths, path);
fib_table_entry_update (fib_index,
- prefix,
- FIB_SOURCE_API, FIB_ENTRY_FLAG_NONE, paths);
+ prefix, FIB_SOURCE_API, entry_flags, paths);
vec_free (paths);
}
else
@@ -847,7 +854,7 @@ add_del_route_check (fib_protocol_t table_proto,
fib_protocol_t next_hop_table_proto,
u32 next_hop_table_id,
u8 create_missing_tables,
- u32 * fib_index, u32 * next_hop_fib_index)
+ u8 is_rpf_id, u32 * fib_index, u32 * next_hop_fib_index)
{
vnet_main_t *vnm = vnet_get_main ();
@@ -866,7 +873,7 @@ add_del_route_check (fib_protocol_t table_proto,
}
}
- if (~0 != ntohl (next_hop_sw_if_index))
+ if (!is_rpf_id && ~0 != ntohl (next_hop_sw_if_index))
{
if (pool_is_free_index (vnm->interface_main.sw_interfaces,
ntohl (next_hop_sw_if_index)))
@@ -876,16 +883,27 @@ add_del_route_check (fib_protocol_t table_proto,
}
else
{
- *next_hop_fib_index = fib_table_find (next_hop_table_proto,
- ntohl (next_hop_table_id));
+ if (is_rpf_id)
+ *next_hop_fib_index = mfib_table_find (next_hop_table_proto,
+ ntohl (next_hop_table_id));
+ else
+ *next_hop_fib_index = fib_table_find (next_hop_table_proto,
+ ntohl (next_hop_table_id));
if (~0 == *next_hop_fib_index)
{
if (create_missing_tables)
{
- *next_hop_fib_index =
- fib_table_find_or_create_and_lock (next_hop_table_proto,
- ntohl (next_hop_table_id));
+ if (is_rpf_id)
+ *next_hop_fib_index =
+ mfib_table_find_or_create_and_lock (next_hop_table_proto,
+ ntohl
+ (next_hop_table_id));
+ else
+ *next_hop_fib_index =
+ fib_table_find_or_create_and_lock (next_hop_table_proto,
+ ntohl
+ (next_hop_table_id));
}
else
{
@@ -910,7 +928,7 @@ ip4_add_del_route_t_handler (vl_api_ip_add_del_route_t * mp)
mp->next_hop_sw_if_index,
FIB_PROTOCOL_IP4,
mp->next_hop_table_id,
- mp->create_vrf_if_needed,
+ mp->create_vrf_if_needed, 0,
&fib_index, &next_hop_fib_index);
if (0 != rv)
@@ -943,11 +961,11 @@ ip4_add_del_route_t_handler (vl_api_ip_add_del_route_t * mp)
mp->is_drop,
mp->is_unreach,
mp->is_prohibit,
- mp->is_local,
+ mp->is_local, 0,
mp->is_classify,
mp->classify_table_index,
mp->is_resolve_host,
- mp->is_resolve_attached,
+ mp->is_resolve_attached, 0, 0,
fib_index, &pfx, 1,
&nh,
ntohl (mp->next_hop_sw_if_index),
@@ -969,7 +987,7 @@ ip6_add_del_route_t_handler (vl_api_ip_add_del_route_t * mp)
mp->next_hop_sw_if_index,
FIB_PROTOCOL_IP6,
mp->next_hop_table_id,
- mp->create_vrf_if_needed,
+ mp->create_vrf_if_needed, 0,
&fib_index, &next_hop_fib_index);
if (0 != rv)
@@ -1002,11 +1020,11 @@ ip6_add_del_route_t_handler (vl_api_ip_add_del_route_t * mp)
mp->is_drop,
mp->is_unreach,
mp->is_prohibit,
- mp->is_local,
+ mp->is_local, 0,
mp->is_classify,
mp->classify_table_index,
mp->is_resolve_host,
- mp->is_resolve_attached,
+ mp->is_resolve_attached, 0, 0,
fib_index, &pfx, 0,
&nh, ntohl (mp->next_hop_sw_if_index),
next_hop_fib_index,
@@ -1075,6 +1093,7 @@ mroute_add_del_handler (u8 is_add,
u32 fib_index,
const mfib_prefix_t * prefix,
u32 entry_flags,
+ fib_rpf_id_t rpf_id,
u32 next_hop_sw_if_index, u32 itf_flags)
{
stats_dslock_with_hint (1 /* release hint */ , 2 /* tag */ );
@@ -1091,7 +1110,7 @@ mroute_add_del_handler (u8 is_add,
if (!is_local && ~0 == next_hop_sw_if_index)
{
mfib_table_entry_update (fib_index, prefix,
- MFIB_SOURCE_API, entry_flags);
+ MFIB_SOURCE_API, rpf_id, entry_flags);
}
else
{
@@ -1152,6 +1171,7 @@ api_mroute_add_del_t_handler (vl_api_ip_mroute_add_del_t * mp)
mp->is_local,
fib_index, &pfx,
ntohl (mp->entry_flags),
+ ntohl (mp->rpf_id),
ntohl (mp->next_hop_sw_if_index),
ntohl (mp->itf_flags)));
}
diff --git a/src/vnet/ip/lookup.c b/src/vnet/ip/lookup.c
index ec9a1f97ac9..597de06b5e3 100755
--- a/src/vnet/ip/lookup.c
+++ b/src/vnet/ip/lookup.c
@@ -450,6 +450,7 @@ vnet_ip_route_cmd (vlib_main_t * vm,
unformat_mpls_unicast_label, &rpath.frp_local_label))
{
rpath.frp_weight = 1;
+ rpath.frp_eos = MPLS_NON_EOS;
rpath.frp_proto = FIB_PROTOCOL_MPLS;
rpath.frp_sw_if_index = ~0;
vec_add1 (rpaths, rpath);
@@ -923,7 +924,7 @@ vnet_ip_mroute_cmd (vlib_main_t * vm,
else if (eflags)
{
mfib_table_entry_update (fib_index, &pfx, MFIB_SOURCE_CLI,
- eflags);
+ MFIB_RPF_ID_NONE, eflags);
}
else
{