diff options
author | Alexander Chernavin <achernavin@netgate.com> | 2019-10-31 10:38:43 -0400 |
---|---|---|
committer | Andrew Yourtchenko <ayourtch@gmail.com> | 2020-08-07 21:45:43 +0000 |
commit | fde70884d4854546a0ddcfece068cd97968eb529 (patch) | |
tree | 65adab96e212dcc2f52dc4141739ba080b1414af | |
parent | 47214ee1e0a6043d9b2a0fa2b7a204787218b906 (diff) |
bfd: allow IPv6 link-local address as local address
Type: fix
Change-Id: Ia3dacd2628591f7ba9710e8e4d68df97ae21935c
Signed-off-by: Alexander Chernavin <achernavin@netgate.com>
(cherry picked from commit 845f51ffe2a2176dd3187e1eb96c00caee98980a)
-rw-r--r-- | src/vnet/bfd/bfd_udp.c | 45 |
1 files changed, 30 insertions, 15 deletions
diff --git a/src/vnet/bfd/bfd_udp.c b/src/vnet/bfd/bfd_udp.c index cc3b40c4075..c545042c978 100644 --- a/src/vnet/bfd/bfd_udp.c +++ b/src/vnet/bfd/bfd_udp.c @@ -29,6 +29,7 @@ #include <vnet/ip/ip4.h> #include <vnet/ip/ip6.h> #include <vnet/ip/ip6_packet.h> +#include <vnet/ip/ip6_neighbor.h> #include <vnet/adj/adj.h> #include <vnet/adj/adj_nbr.h> #include <vnet/dpo/receive_dpo.h> @@ -608,21 +609,35 @@ bfd_udp_validate_api_input (u32 sw_if_index, "IP family mismatch (local is ipv6, peer is ipv4)"); return VNET_API_ERROR_INVALID_ARGUMENT; } - ip6_main_t *im = &ip6_main; - /* *INDENT-OFF* */ - foreach_ip_interface_address ( - &im->lookup_main, ia, sw_if_index, 0 /* honor unnumbered */, ({ - ip6_address_t *x = - ip_interface_address_get_address (&im->lookup_main, ia); - if (local_addr->ip6.as_u64[0] == x->as_u64[0] && - local_addr->ip6.as_u64[1] == x->as_u64[1]) - { - /* valid address for this interface */ - local_ip_valid = 1; - break; - } - })); - /* *INDENT-ON* */ + + if (ip6_address_is_link_local_unicast (&local_addr->ip6)) + { + ip6_address_t ll_addr; + ll_addr = ip6_neighbor_get_link_local_address (sw_if_index); + if (ip6_address_is_equal (&ll_addr, &local_addr->ip6)) + { + /* valid address for this interface */ + local_ip_valid = 1; + } + } + else + { + ip6_main_t *im = &ip6_main; + /* *INDENT-OFF* */ + foreach_ip_interface_address ( + &im->lookup_main, ia, sw_if_index, 0 /* honor unnumbered */, ({ + ip6_address_t *x = + ip_interface_address_get_address (&im->lookup_main, ia); + if (local_addr->ip6.as_u64[0] == x->as_u64[0] && + local_addr->ip6.as_u64[1] == x->as_u64[1]) + { + /* valid address for this interface */ + local_ip_valid = 1; + break; + } + })); + /* *INDENT-ON* */ + } } if (!local_ip_valid) |