summaryrefslogtreecommitdiff
path: root/bfdd
diff options
context:
space:
mode:
authorRafael Zalamena <rzalamena@opensourcerouting.org>2018-07-25 22:44:41 -0300
committerRafael Zalamena <rzalamena@opensourcerouting.org>2018-08-08 18:25:08 -0300
commit43adc702e15d9cd11a74e27a5355dbaa5a4ff30b (patch)
treef100c34e5614644b3bf963053ddb85c09bf665bd /bfdd
parent788378fefac03d0a51be8409b4d0d20b723ca234 (diff)
bfdd: fix IPv6 peers using link-local address
When using link-local address we must specify the scope-id for the address in order to bind to the interface. Signed-off-by: Rafael Zalamena <rzalamena@opensourcerouting.org>
Diffstat (limited to 'bfdd')
-rw-r--r--bfdd/bfd.c9
-rw-r--r--bfdd/bfd_packet.c19
2 files changed, 18 insertions, 10 deletions
diff --git a/bfdd/bfd.c b/bfdd/bfd.c
index ff62cd356b..28b6beadcb 100644
--- a/bfdd/bfd.c
+++ b/bfdd/bfd.c
@@ -605,9 +605,16 @@ struct bfd_session *ptm_bfd_sess_new(struct bfd_peer_cfg *bpc)
if (bpc->bpc_has_vxlan)
BFD_SET_FLAG(bfd->flags, BFD_SESS_FLAG_VXLAN);
- if (bpc->bpc_ipv4 == false)
+ if (bpc->bpc_ipv4 == false) {
BFD_SET_FLAG(bfd->flags, BFD_SESS_FLAG_IPV6);
+ /* Set the IPv6 scope id for link-local addresses. */
+ if (IN6_IS_ADDR_LINKLOCAL(&bpc->bpc_local.sa_sin6.sin6_addr))
+ bpc->bpc_local.sa_sin6.sin6_scope_id = bfd->ifindex;
+ if (IN6_IS_ADDR_LINKLOCAL(&bpc->bpc_peer.sa_sin6.sin6_addr))
+ bpc->bpc_peer.sa_sin6.sin6_scope_id = bfd->ifindex;
+ }
+
/* Initialize the session */
bfd->ses_state = PTM_BFD_DOWN;
bfd->discrs.my_discr = ptm_bfd_gen_ID();
diff --git a/bfdd/bfd_packet.c b/bfdd/bfd_packet.c
index 177d6307e4..19cb8547ab 100644
--- a/bfdd/bfd_packet.c
+++ b/bfdd/bfd_packet.c
@@ -819,6 +819,7 @@ ssize_t bfd_recv_ipv6(int sd, bool is_mhop, char *port, size_t portlen,
{
struct cmsghdr *cm;
struct in6_pktinfo *pi6 = NULL;
+ int ifindex = 0;
ssize_t mlen;
memset(port, 0, portlen);
@@ -860,10 +861,17 @@ ssize_t bfd_recv_ipv6(int sd, bool is_mhop, char *port, size_t portlen,
local->sa_sin6.sin6_addr = pi6->ipi6_addr;
fetch_portname_from_ifindex(pi6->ipi6_ifindex,
port, portlen);
+ ifindex = pi6->ipi6_ifindex;
}
}
}
+ /* Set scope ID for link local addresses. */
+ if (IN6_IS_ADDR_LINKLOCAL(&peer->sa_sin6.sin6_addr))
+ peer->sa_sin6.sin6_scope_id = ifindex;
+ if (IN6_IS_ADDR_LINKLOCAL(&local->sa_sin6.sin6_addr))
+ local->sa_sin6.sin6_scope_id = ifindex;
+
return mlen;
}
@@ -1397,16 +1405,9 @@ int bp_peer_socketv6(struct bfd_peer_cfg *bpc)
sin6.sin6_len = sizeof(sin6);
#endif /* HAVE_STRUCT_SOCKADDR_SA_LEN */
sin6 = bpc->bpc_local.sa_sin6;
- if (sin6.sin6_family != AF_INET6) {
-#if 0 /* XXX what is this? */
- ifindex = ptm_bfd_fetch_ifindex(bpc->bpc_localif);
- if (IN6_IS_ADDR_LINKLOCAL(&sin6.sin6_addr))
- sin6.sin6_scope_id = ifindex;
-#endif
- } else if (bpc->bpc_has_localif) {
- ifindex = ptm_bfd_fetch_ifindex(bpc->bpc_localif);
+ ifindex = ptm_bfd_fetch_ifindex(bpc->bpc_localif);
+ if (IN6_IS_ADDR_LINKLOCAL(&sin6.sin6_addr))
sin6.sin6_scope_id = ifindex;
- }
if (bpc->bpc_has_localif) {
if (bp_bind_dev(sd, bpc->bpc_localif) != 0) {