summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAlexander Chernavin <achernavin@netgate.com>2019-10-31 10:38:43 -0400
committerAndrew Yourtchenko <ayourtch@gmail.com>2020-08-07 21:45:43 +0000
commitfde70884d4854546a0ddcfece068cd97968eb529 (patch)
tree65adab96e212dcc2f52dc4141739ba080b1414af
parent47214ee1e0a6043d9b2a0fa2b7a204787218b906 (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.c45
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)