aboutsummaryrefslogtreecommitdiffstats
path: root/vnet/vnet/ip/ip6_forward.c
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 /vnet/vnet/ip/ip6_forward.c
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>
Diffstat (limited to 'vnet/vnet/ip/ip6_forward.c')
-rw-r--r--vnet/vnet/ip/ip6_forward.c63
1 files changed, 63 insertions, 0 deletions
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;
}