From: Rafael Zalamena Date: Thu, 14 Mar 2019 15:28:07 +0000 (-0300) Subject: bfdd: remove scope-id from the session key X-Git-Tag: frr-7.0.1~23^2 X-Git-Url: https://git.puffer.fish/?a=commitdiff_plain;h=refs%2Fpull%2F3948%2Fhead;p=mirror%2Ffrr.git bfdd: remove scope-id from the session key Unbreaks CLI ability to remove IPv6 sessions using link-local addresses. This moves the scope-id logic to the packet sending functions. --- diff --git a/bfdd/bfd.c b/bfdd/bfd.c index 7ab71511a6..fc2d0bea9c 100644 --- a/bfdd/bfd.c +++ b/bfdd/bfd.c @@ -261,6 +261,7 @@ static struct bfd_session *bfd_find_disc(struct sockaddr_any *sa, break; case AF_INET6: sa->sa_sin6.sin6_port = 0; + sa->sa_sin6.sin6_scope_id = 0; if (memcmp(sa, &bs->shop.peer, sizeof(sa->sa_sin6)) == 0) return bs; break; @@ -579,16 +580,9 @@ struct bfd_session *ptm_bfd_sess_new(struct bfd_peer_cfg *bpc) ptm_bfd_fetch_local_mac(bpc->bpc_localif, bfd->local_mac); } - 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(); @@ -963,6 +957,7 @@ static void _shop_key(struct bfd_session *bs, const struct bfd_shop_key *shop) break; case AF_INET6: bs->shop.peer.sa_sin6.sin6_port = 0; + bs->shop.peer.sa_sin6.sin6_scope_id = 0; break; } } @@ -985,7 +980,9 @@ static void _mhop_key(struct bfd_session *bs, const struct bfd_mhop_key *mhop) break; case AF_INET6: bs->mhop.peer.sa_sin6.sin6_port = 0; + bs->mhop.peer.sa_sin6.sin6_scope_id = 0; bs->mhop.local.sa_sin6.sin6_port = 0; + bs->mhop.local.sa_sin6.sin6_scope_id = 0; break; } } diff --git a/bfdd/bfd_packet.c b/bfdd/bfd_packet.c index 606f739b46..e602eb9bc2 100644 --- a/bfdd/bfd_packet.c +++ b/bfdd/bfd_packet.c @@ -88,6 +88,9 @@ int _ptm_bfd_send(struct bfd_session *bs, uint16_t *port, const void *data, ? htons(BFD_DEF_MHOP_DEST_PORT) : htons(BFD_DEFDESTPORT); + if (IN6_IS_ADDR_LINKLOCAL(&sin6.sin6_addr)) + sin6.sin6_scope_id = bs->ifindex; + sd = bs->sock; sa = (struct sockaddr *)&sin6; slen = sizeof(sin6); @@ -146,6 +149,8 @@ void ptm_bfd_echo_snd(struct bfd_session *bfd) #ifdef HAVE_STRUCT_SOCKADDR_SA_LEN sin6.sin6_len = sizeof(sin6); #endif /* HAVE_STRUCT_SOCKADDR_SA_LEN */ + if (IN6_IS_ADDR_LINKLOCAL(&sin6.sin6_addr)) + sin6.sin6_scope_id = bfd->ifindex; sa = (struct sockaddr_any *)&sin6; salen = sizeof(sin6); @@ -359,7 +364,6 @@ ssize_t bfd_recv_ipv6(int sd, uint8_t *msgbuf, size_t msgbuflen, uint8_t *ttl, { struct cmsghdr *cm; struct in6_pktinfo *pi6 = NULL; - int ifindex = 0; ssize_t mlen; uint32_t ttlval; struct sockaddr_in6 msgaddr6; @@ -415,17 +419,10 @@ ssize_t bfd_recv_ipv6(int sd, uint8_t *msgbuf, size_t msgbuflen, uint8_t *ttl, #endif /* HAVE_STRUCT_SOCKADDR_SA_LEN */ 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; } @@ -1046,7 +1043,7 @@ int bp_peer_socket(struct bfd_peer_cfg *bpc) int bp_peer_socketv6(struct bfd_peer_cfg *bpc) { - int sd, pcount, ifindex; + int sd, pcount; struct sockaddr_in6 sin6; static int srcPort = BFD_SRCPORTINIT; @@ -1075,10 +1072,10 @@ int bp_peer_socketv6(struct bfd_peer_cfg *bpc) #ifdef HAVE_STRUCT_SOCKADDR_SA_LEN sin6.sin6_len = sizeof(sin6); #endif /* HAVE_STRUCT_SOCKADDR_SA_LEN */ - sin6 = bpc->bpc_local.sa_sin6; - ifindex = ptm_bfd_fetch_ifindex(bpc->bpc_localif); + memcpy(&sin6.sin6_addr, &bpc->bpc_local.sa_sin6.sin6_addr, + sizeof(sin6.sin6_addr)); if (IN6_IS_ADDR_LINKLOCAL(&sin6.sin6_addr)) - sin6.sin6_scope_id = ifindex; + sin6.sin6_scope_id = ptm_bfd_fetch_ifindex(bpc->bpc_localif); if (bpc->bpc_has_localif) { if (bp_bind_dev(sd, bpc->bpc_localif) != 0) { diff --git a/bfdd/ptm_adapter.c b/bfdd/ptm_adapter.c index f9c7c16fb1..a6be28dbd9 100644 --- a/bfdd/ptm_adapter.c +++ b/bfdd/ptm_adapter.c @@ -381,21 +381,6 @@ static int _ptm_msg_read(struct stream *msg, int command, if (bpc->bpc_has_localif) { STREAM_GET(bpc->bpc_localif, msg, ifnamelen); bpc->bpc_localif[ifnamelen] = 0; - - /* - * IPv6 link-local addresses must use scope id, - * otherwise the session lookup will always fail - * and we'll have multiple sessions showing up. - * - * This problem only happens with single hop - * since it is not possible to have link-local - * address for multi hop sessions. - */ - if (bpc->bpc_ipv4 == false - && IN6_IS_ADDR_LINKLOCAL( - &bpc->bpc_peer.sa_sin6.sin6_addr)) - bpc->bpc_peer.sa_sin6.sin6_scope_id = - ptm_bfd_fetch_ifindex(bpc->bpc_localif); } }