aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorNeale Ranns <nranns@cisco.com>2019-10-07 22:40:54 -0700
committerAndrew Yourtchenko <ayourtch@gmail.com>2019-10-22 11:14:47 +0000
commitd3b170254bc41495cca90c6bfe77ffb02aaa661a (patch)
treea39972b401671293aad24b65e54d607c101d7709 /src
parent15800e94423623ef574a1cde70f4fd0e34a1f95b (diff)
ip: only install IPv6 prefixes in FIB when the interface is up
otherwise they get installed twice and the reference counting means they are not removed. This is the same behaviour as IPv4. Type: fix Change-Id: I9266e04ccff6ff06a577e85973a2ddbeb9dfc52b Signed-off-by: Neale Ranns <nranns@cisco.com> (cherry picked from commit 1ff3c15b3c7607c9b590ad44d18dea5eb1cb8c4e)
Diffstat (limited to 'src')
-rw-r--r--src/vnet/ip/ip6_forward.c75
1 files changed, 36 insertions, 39 deletions
diff --git a/src/vnet/ip/ip6_forward.c b/src/vnet/ip/ip6_forward.c
index a7a41eea419..47fb57ae201 100644
--- a/src/vnet/ip/ip6_forward.c
+++ b/src/vnet/ip/ip6_forward.c
@@ -68,24 +68,21 @@ ip6_add_interface_prefix_routes (ip6_main_t * im,
ip_lookup_main_t *lm = &im->lookup_main;
ip_interface_prefix_t *if_prefix;
+ /* *INDENT-OFF* */
ip_interface_prefix_key_t key = {
.prefix = {
- .fp_len = address_length,
- .fp_proto = FIB_PROTOCOL_IP6,
- .fp_addr.ip6 = {
- .as_u64 = {
- address->as_u64[0] &
- im->fib_masks[address_length].
- as_u64[0],
- address->
- as_u64[1] &
- im->fib_masks[address_length].
- as_u64[1],
- },
- },
- },
+ .fp_len = address_length,
+ .fp_proto = FIB_PROTOCOL_IP6,
+ .fp_addr.ip6 = {
+ .as_u64 = {
+ address->as_u64[0] & im->fib_masks[address_length].as_u64[0],
+ address->as_u64[1] & im->fib_masks[address_length].as_u64[1],
+ },
+ },
+ },
.sw_if_index = sw_if_index,
};
+ /* *INDENT-ON* */
/* If prefix already set on interface, just increment ref count & return */
if_prefix = ip_get_interface_prefix (lm, &key);
@@ -178,24 +175,21 @@ ip6_del_interface_prefix_routes (ip6_main_t * im,
ip_lookup_main_t *lm = &im->lookup_main;
ip_interface_prefix_t *if_prefix;
+ /* *INDENT-OFF* */
ip_interface_prefix_key_t key = {
.prefix = {
- .fp_len = address_length,
- .fp_proto = FIB_PROTOCOL_IP6,
- .fp_addr.ip6 = {
- .as_u64 = {
- address->as_u64[0] &
- im->fib_masks[address_length].
- as_u64[0],
- address->
- as_u64[1] &
- im->fib_masks[address_length].
- as_u64[1],
- },
- },
- },
+ .fp_len = address_length,
+ .fp_proto = FIB_PROTOCOL_IP6,
+ .fp_addr.ip6 = {
+ .as_u64 = {
+ address->as_u64[0] & im->fib_masks[address_length].as_u64[0],
+ address->as_u64[1] & im->fib_masks[address_length].as_u64[1],
+ },
+ },
+ },
.sw_if_index = sw_if_index,
};
+ /* *INDENT-ON* */
if_prefix = ip_get_interface_prefix (lm, &key);
if (!if_prefix)
@@ -210,12 +204,11 @@ ip6_del_interface_prefix_routes (ip6_main_t * im,
if (if_prefix->ref_count > 0)
return;
- /* length <= 30, delete glean route */
+ /* length <= 128, delete glean route */
if (address_length <= 128)
{
/* remove glean route for prefix */
fib_table_entry_delete (fib_index, &key.prefix, FIB_SOURCE_INTERFACE);
-
}
mhash_unset (&lm->prefix_to_if_prefix_index, &key, 0 /* old_value */ );
@@ -416,15 +409,19 @@ ip6_add_del_interface_address (vlib_main_t * vm,
ip6_sw_interface_enable_disable (sw_if_index, !is_del);
- if (is_del)
- ip6_del_interface_routes (sw_if_index,
- im, ip6_af.fib_index, address, address_length);
- else
- ip6_add_interface_routes (vnm, sw_if_index,
- im, ip6_af.fib_index,
- pool_elt_at_index (lm->if_address_pool,
- if_address_index));
-
+ /* intf addr routes are added/deleted on admin up/down */
+ if (vnet_sw_interface_is_admin_up (vnm, sw_if_index))
+ {
+ if (is_del)
+ ip6_del_interface_routes (sw_if_index,
+ im, ip6_af.fib_index, address,
+ address_length);
+ else
+ ip6_add_interface_routes (vnm, sw_if_index,
+ im, ip6_af.fib_index,
+ pool_elt_at_index (lm->if_address_pool,
+ if_address_index));
+ }
{
ip6_add_del_interface_address_callback_t *cb;
vec_foreach (cb, im->add_del_interface_address_callbacks)