diff options
author | Neale Ranns <nranns@cisco.com> | 2016-10-02 16:39:06 +0100 |
---|---|---|
committer | Neale Ranns <nranns@cisco.com> | 2016-10-03 09:56:14 +0100 |
commit | df089a8a13dcef08f10d6930c4959f129f784a4e (patch) | |
tree | 7116fa80ca31da7ed84ad42f64b6a7b6d512bf2f /vnet/vnet/ip/ip6_forward.c | |
parent | c631f2de6dd06b4cbb92bf8398839b882344fd25 (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.c | 63 |
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; } |