diff options
author | Neale Ranns <nranns@cisco.com> | 2019-10-07 22:40:54 -0700 |
---|---|---|
committer | Damjan Marion <dmarion@me.com> | 2019-10-09 06:45:49 +0000 |
commit | 1ff3c15b3c7607c9b590ad44d18dea5eb1cb8c4e (patch) | |
tree | da0dbbdb15594fd4c2e31970e0623d216bb00828 /src/vnet/ip/ip6_forward.c | |
parent | da0e7497ca972f3219352d884b5c51e455503dbb (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>
Diffstat (limited to 'src/vnet/ip/ip6_forward.c')
-rw-r--r-- | src/vnet/ip/ip6_forward.c | 75 |
1 files changed, 36 insertions, 39 deletions
diff --git a/src/vnet/ip/ip6_forward.c b/src/vnet/ip/ip6_forward.c index eb6c89b39d7..ea13116d8aa 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) |