aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNeale Ranns <nranns@cisco.com>2016-10-02 16:39:06 +0100
committerNeale Ranns <nranns@cisco.com>2016-10-03 09:56:14 +0100
commitdf089a8a13dcef08f10d6930c4959f129f784a4e (patch)
tree7116fa80ca31da7ed84ad42f64b6a7b6d512bf2f
parentc631f2de6dd06b4cbb92bf8398839b882344fd25 (diff)
(VPP-455) arp doesn't work when ip4 classifier configured with fib 2.0
Change-Id: I046de0c00db75d25ed90e33e9910c9dd0ff95580 Signed-off-by: Neale Ranns <nranns@cisco.com>
-rw-r--r--vnet/vnet/ethernet/arp.c7
-rw-r--r--vnet/vnet/fib/fib_entry.c2
-rw-r--r--vnet/vnet/fib/fib_entry.h6
-rw-r--r--vnet/vnet/fib/fib_entry_src.c44
-rw-r--r--vnet/vnet/ip/ip4_forward.c41
-rw-r--r--vnet/vnet/ip/ip6_forward.c63
-rw-r--r--vnet/vnet/ip/ip6_neighbor.c3
7 files changed, 160 insertions, 6 deletions
diff --git a/vnet/vnet/ethernet/arp.c b/vnet/vnet/ethernet/arp.c
index 7d6184381c9..90d193e86c5 100644
--- a/vnet/vnet/ethernet/arp.c
+++ b/vnet/vnet/ethernet/arp.c
@@ -923,9 +923,12 @@ arp_input (vlib_main_t * vm, vlib_node_runtime_t * node, vlib_frame_t * frame)
dst_fei = ip4_fib_table_lookup (ip4_fib_get (fib_index0),
&arp0->ip4_over_ethernet[1].ip4,
32);
- dst_flags = fib_entry_get_flags (dst_fei);
+ dst_flags = fib_entry_get_flags_for_source (dst_fei,
+ FIB_SOURCE_INTERFACE);
- conn_sw_if_index0 = fib_entry_get_resolving_interface (dst_fei);
+ conn_sw_if_index0 =
+ fib_entry_get_resolving_interface_for_source (dst_fei,
+ FIB_SOURCE_INTERFACE);
if (!(FIB_ENTRY_FLAG_CONNECTED & dst_flags))
{
diff --git a/vnet/vnet/fib/fib_entry.c b/vnet/vnet/fib/fib_entry.c
index 8b63f0dc974..8b275c61912 100644
--- a/vnet/vnet/fib/fib_entry.c
+++ b/vnet/vnet/fib/fib_entry.c
@@ -1299,7 +1299,7 @@ fib_entry_recursive_loop_detect (fib_node_index_t entry_index,
u32
fib_entry_get_resolving_interface (fib_node_index_t entry_index)
{
- fib_entry_t *fib_entry;
+ fib_entry_t *fib_entry;
fib_entry = fib_entry_get(entry_index);
diff --git a/vnet/vnet/fib/fib_entry.h b/vnet/vnet/fib/fib_entry.h
index ac22c170d55..1ed9d619515 100644
--- a/vnet/vnet/fib/fib_entry.h
+++ b/vnet/vnet/fib/fib_entry.h
@@ -480,6 +480,9 @@ extern u32 fib_entry_child_add(fib_node_index_t fib_entry_index,
extern void fib_entry_child_remove(fib_node_index_t fib_entry_index,
u32 sibling_index);
extern u32 fib_entry_get_resolving_interface(fib_node_index_t fib_entry_index);
+extern u32 fib_entry_get_resolving_interface_for_source(
+ fib_node_index_t fib_entry_index,
+ fib_source_t source);
extern void fib_entry_get_prefix(fib_node_index_t fib_entry_index,
fib_prefix_t *pfx);
@@ -491,6 +494,9 @@ extern const void* fib_entry_get_source_data(fib_node_index_t fib_entry_index,
fib_source_t source);
extern fib_entry_flag_t fib_entry_get_flags(fib_node_index_t fib_entry_index);
+extern fib_entry_flag_t fib_entry_get_flags_for_source(
+ fib_node_index_t fib_entry_index,
+ fib_source_t source);
extern fib_source_t fib_entry_get_best_source(fib_node_index_t fib_entry_index);
extern int fib_entry_is_sourced(fib_node_index_t fib_entry_index,
fib_source_t source);
diff --git a/vnet/vnet/fib/fib_entry_src.c b/vnet/vnet/fib/fib_entry_src.c
index f7d84e5ea34..70550069356 100644
--- a/vnet/vnet/fib/fib_entry_src.c
+++ b/vnet/vnet/fib/fib_entry_src.c
@@ -1038,8 +1038,8 @@ fib_entry_src_action_path_swap (fib_entry_t *fib_entry,
ASSERT(NULL != fib_entry_src_vft[source].fesv_path_swap);
- pl_flags = fib_entry_src_flags_2_path_list_flags(
- fib_entry_get_flags_i(fib_entry));
+ pl_flags = fib_entry_src_flags_2_path_list_flags(flags);
+
vec_foreach(rpath, rpaths)
{
fib_entry_flags_update(fib_entry, rpath, &pl_flags, esrc);
@@ -1205,6 +1205,46 @@ fib_entry_get_dpo_for_source (fib_node_index_t fib_entry_index,
return (0);
}
+u32
+fib_entry_get_resolving_interface_for_source (fib_node_index_t entry_index,
+ fib_source_t source)
+{
+ fib_entry_t *fib_entry;
+ fib_entry_src_t *esrc;
+
+ fib_entry = fib_entry_get(entry_index);
+
+ esrc = fib_entry_src_find(fib_entry, source, NULL);
+
+ if (NULL != esrc)
+ {
+ if (FIB_NODE_INDEX_INVALID != esrc->fes_pl)
+ {
+ return (fib_path_list_get_resolving_interface(esrc->fes_pl));
+ }
+ }
+ return (~0);
+}
+
+fib_entry_flag_t
+fib_entry_get_flags_for_source (fib_node_index_t entry_index,
+ fib_source_t source)
+{
+ fib_entry_t *fib_entry;
+ fib_entry_src_t *esrc;
+
+ fib_entry = fib_entry_get(entry_index);
+
+ esrc = fib_entry_src_find(fib_entry, source, NULL);
+
+ if (NULL != esrc)
+ {
+ return (esrc->fes_entry_flags);
+ }
+
+ return (FIB_ENTRY_FLAG_NONE);
+}
+
fib_entry_flag_t
fib_entry_get_flags_i (const fib_entry_t *fib_entry)
{
diff --git a/vnet/vnet/ip/ip4_forward.c b/vnet/vnet/ip/ip4_forward.c
index 8105d74a8b6..08fe8162260 100644
--- a/vnet/vnet/ip/ip4_forward.c
+++ b/vnet/vnet/ip/ip4_forward.c
@@ -3058,6 +3058,7 @@ int vnet_set_ip4_classify_intfc (vlib_main_t * vm, u32 sw_if_index,
ip4_main_t * ipm = &ip4_main;
ip_lookup_main_t * lm = &ipm->lookup_main;
vnet_classify_main_t * cm = &vnet_classify_main;
+ ip4_address_t *if_addr;
if (pool_is_free_index (im->sw_interfaces, sw_if_index))
return VNET_API_ERROR_NO_MATCHING_INTERFACE;
@@ -3068,6 +3069,46 @@ int vnet_set_ip4_classify_intfc (vlib_main_t * vm, u32 sw_if_index,
vec_validate (lm->classify_table_index_by_sw_if_index, sw_if_index);
lm->classify_table_index_by_sw_if_index [sw_if_index] = table_index;
+ if_addr = ip4_interface_first_address (ipm, sw_if_index, NULL);
+
+ if (NULL != if_addr)
+ {
+ fib_prefix_t pfx = {
+ .fp_len = 32,
+ .fp_proto = FIB_PROTOCOL_IP4,
+ .fp_addr.ip4 = *if_addr,
+ };
+ u32 fib_index;
+
+ fib_index = fib_table_get_index_for_sw_if_index(FIB_PROTOCOL_IP4,
+ sw_if_index);
+
+
+ if (table_index != (u32) ~0)
+ {
+ dpo_id_t dpo = DPO_NULL;
+
+ dpo_set(&dpo,
+ DPO_CLASSIFY,
+ DPO_PROTO_IP4,
+ classify_dpo_create(FIB_PROTOCOL_IP4,
+ table_index));
+
+ fib_table_entry_special_dpo_add(fib_index,
+ &pfx,
+ FIB_SOURCE_CLASSIFY,
+ FIB_ENTRY_FLAG_NONE,
+ &dpo);
+ dpo_reset(&dpo);
+ }
+ else
+ {
+ fib_table_entry_special_remove(fib_index,
+ &pfx,
+ FIB_SOURCE_CLASSIFY);
+ }
+ }
+
return 0;
}
diff --git a/vnet/vnet/ip/ip6_forward.c b/vnet/vnet/ip/ip6_forward.c
index 56892d4132f..65e87595d06 100644
--- a/vnet/vnet/ip/ip6_forward.c
+++ b/vnet/vnet/ip/ip6_forward.c
@@ -457,6 +457,28 @@ ip6_sw_interface_enable_disable (u32 sw_if_index,
}
}
+/* get first interface address */
+ip6_address_t *
+ip6_interface_first_address (ip6_main_t * im,
+ u32 sw_if_index,
+ ip_interface_address_t ** result_ia)
+{
+ ip_lookup_main_t * lm = &im->lookup_main;
+ ip_interface_address_t * ia = 0;
+ ip6_address_t * result = 0;
+
+ foreach_ip_interface_address (lm, ia, sw_if_index,
+ 1 /* honor unnumbered */,
+ ({
+ ip6_address_t * a = ip_interface_address_get_address (lm, ia);
+ result = a;
+ break;
+ }));
+ if (result_ia)
+ *result_ia = result ? ia : 0;
+ return result;
+}
+
clib_error_t *
ip6_add_del_interface_address (vlib_main_t * vm,
u32 sw_if_index,
@@ -2866,6 +2888,7 @@ int vnet_set_ip6_classify_intfc (vlib_main_t * vm, u32 sw_if_index,
ip6_main_t * ipm = &ip6_main;
ip_lookup_main_t * lm = &ipm->lookup_main;
vnet_classify_main_t * cm = &vnet_classify_main;
+ ip6_address_t *if_addr;
if (pool_is_free_index (im->sw_interfaces, sw_if_index))
return VNET_API_ERROR_NO_MATCHING_INTERFACE;
@@ -2876,6 +2899,46 @@ int vnet_set_ip6_classify_intfc (vlib_main_t * vm, u32 sw_if_index,
vec_validate (lm->classify_table_index_by_sw_if_index, sw_if_index);
lm->classify_table_index_by_sw_if_index [sw_if_index] = table_index;
+ if_addr = ip6_interface_first_address (ipm, sw_if_index, NULL);
+
+ if (NULL != if_addr)
+ {
+ fib_prefix_t pfx = {
+ .fp_len = 128,
+ .fp_proto = FIB_PROTOCOL_IP6,
+ .fp_addr.ip6 = *if_addr,
+ };
+ u32 fib_index;
+
+ fib_index = fib_table_get_index_for_sw_if_index(FIB_PROTOCOL_IP4,
+ sw_if_index);
+
+
+ if (table_index != (u32) ~0)
+ {
+ dpo_id_t dpo = DPO_NULL;
+
+ dpo_set(&dpo,
+ DPO_CLASSIFY,
+ DPO_PROTO_IP4,
+ classify_dpo_create(FIB_PROTOCOL_IP4,
+ table_index));
+
+ fib_table_entry_special_dpo_add(fib_index,
+ &pfx,
+ FIB_SOURCE_CLASSIFY,
+ FIB_ENTRY_FLAG_NONE,
+ &dpo);
+ dpo_reset(&dpo);
+ }
+ else
+ {
+ fib_table_entry_special_remove(fib_index,
+ &pfx,
+ FIB_SOURCE_CLASSIFY);
+ }
+ }
+
return 0;
}
diff --git a/vnet/vnet/ip/ip6_neighbor.c b/vnet/vnet/ip/ip6_neighbor.c
index 5d059e9b9cf..a03701b8e80 100644
--- a/vnet/vnet/ip/ip6_neighbor.c
+++ b/vnet/vnet/ip/ip6_neighbor.c
@@ -812,7 +812,8 @@ icmp6_neighbor_solicitation_or_advertisement (vlib_main_t * vm,
128);
if (FIB_NODE_INDEX_INVALID == fei ||
- !(FIB_ENTRY_FLAG_LOCAL & fib_entry_get_flags(fei)))
+ !(FIB_ENTRY_FLAG_LOCAL &
+ fib_entry_get_flags_for_source(fei, FIB_SOURCE_INTERFACE)))
{
error0 = ICMP6_ERROR_NEIGHBOR_SOLICITATION_SOURCE_UNKNOWN;
}