]> git.proxmox.com Git - mirror_frr.git/commitdiff
bfdd: fix IPv6 peers using link-local address
authorRafael Zalamena <rzalamena@opensourcerouting.org>
Thu, 26 Jul 2018 01:44:41 +0000 (22:44 -0300)
committerRafael Zalamena <rzalamena@opensourcerouting.org>
Wed, 8 Aug 2018 21:25:08 +0000 (18:25 -0300)
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>
bfdd/bfd.c
bfdd/bfd_packet.c

index ff62cd356badda00f2f99cc5cec62a127afebf38..28b6beadcbee8c5374b1e6d8ebf584372f50b699 100644 (file)
@@ -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();
index 177d6307e4e2032a71be1e799f64132b15f407d8..19cb8547ab3368a936018fa40d52a749bcc10a47 100644 (file)
@@ -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) {