]> git.proxmox.com Git - mirror_frr.git/blobdiff - bfdd/bfd_packet.c
bgpd: [7.1] add addpath ID to adj_out tree sort (#5691)
[mirror_frr.git] / bfdd / bfd_packet.c
index 18d6ad25025d50aef1f2c3cae5bb8390fccb0aad..93677ec85aceeb7709385a07c652682b843d73aa 100644 (file)
@@ -79,7 +79,10 @@ int _ptm_bfd_send(struct bfd_session *bs, uint16_t *port, const void *data,
        if (BFD_CHECK_FLAG(bs->flags, BFD_SESS_FLAG_IPV6)) {
                memset(&sin6, 0, sizeof(sin6));
                sin6.sin6_family = AF_INET6;
-               sin6.sin6_addr = bs->shop.peer.sa_sin6.sin6_addr;
+               memcpy(&sin6.sin6_addr, &bs->key.peer, sizeof(sin6.sin6_addr));
+               if (IN6_IS_ADDR_LINKLOCAL(&sin6.sin6_addr))
+                       sin6.sin6_scope_id = bs->ifp->ifindex;
+
                sin6.sin6_port =
                        (port) ? *port
                               : (BFD_CHECK_FLAG(bs->flags, BFD_SESS_FLAG_MH))
@@ -92,7 +95,7 @@ int _ptm_bfd_send(struct bfd_session *bs, uint16_t *port, const void *data,
        } else {
                memset(&sin, 0, sizeof(sin));
                sin.sin_family = AF_INET;
-               sin.sin_addr = bs->shop.peer.sa_sin.sin_addr;
+               memcpy(&sin.sin_addr, &bs->key.peer, sizeof(sin.sin_addr));
                sin.sin_port =
                        (port) ? *port
                               : (BFD_CHECK_FLAG(bs->flags, BFD_SESS_FLAG_MH))
@@ -120,7 +123,7 @@ int _ptm_bfd_send(struct bfd_session *bs, uint16_t *port, const void *data,
 
 void ptm_bfd_echo_snd(struct bfd_session *bfd)
 {
-       struct sockaddr_any *sa;
+       struct sockaddr *sa;
        socklen_t salen;
        int sd;
        struct bfd_echo_pkt bep;
@@ -135,31 +138,36 @@ void ptm_bfd_echo_snd(struct bfd_session *bfd)
        bep.len = BFD_ECHO_PKT_LEN;
        bep.my_discr = htonl(bfd->discrs.my_discr);
 
-       sa = BFD_CHECK_FLAG(bfd->flags, BFD_SESS_FLAG_MH) ? &bfd->mhop.peer
-                                                         : &bfd->shop.peer;
        if (BFD_CHECK_FLAG(bfd->flags, BFD_SESS_FLAG_IPV6)) {
                sd = bglobal.bg_echov6;
-               sin6 = sa->sa_sin6;
+               memset(&sin6, 0, sizeof(sin6));
+               sin6.sin6_family = AF_INET6;
+               memcpy(&sin6.sin6_addr, &bfd->key.peer, sizeof(sin6.sin6_addr));
+               if (bfd->ifp && IN6_IS_ADDR_LINKLOCAL(&sin6.sin6_addr))
+                       sin6.sin6_scope_id = bfd->ifp->ifindex;
+
                sin6.sin6_port = htons(BFD_DEF_ECHO_PORT);
 #ifdef HAVE_STRUCT_SOCKADDR_SA_LEN
                sin6.sin6_len = sizeof(sin6);
 #endif /* HAVE_STRUCT_SOCKADDR_SA_LEN */
 
-               sa = (struct sockaddr_any *)&sin6;
+               sa = (struct sockaddr *)&sin6;
                salen = sizeof(sin6);
        } else {
                sd = bglobal.bg_echo;
-               sin = sa->sa_sin;
+               memset(&sin6, 0, sizeof(sin6));
+               sin.sin_family = AF_INET;
+               memcpy(&sin.sin_addr, &bfd->key.peer, sizeof(sin.sin_addr));
                sin.sin_port = htons(BFD_DEF_ECHO_PORT);
 #ifdef HAVE_STRUCT_SOCKADDR_SA_LEN
                sin.sin_len = sizeof(sin);
 #endif /* HAVE_STRUCT_SOCKADDR_SA_LEN */
 
-               sa = (struct sockaddr_any *)&sin;
+               sa = (struct sockaddr *)&sin;
                salen = sizeof(sin);
        }
-       if (bp_udp_send(sd, BFD_TTL_VAL, (uint8_t *)&bep, sizeof(bep),
-                       (struct sockaddr *)sa, salen)
+       if (bp_udp_send(sd, BFD_TTL_VAL, (uint8_t *)&bep, sizeof(bep), sa,
+                       salen)
            == -1)
                return;
 
@@ -505,7 +513,7 @@ int bfd_recv_cb(struct thread *t)
        struct bfd_pkt *cp;
        bool is_mhop;
        ssize_t mlen = 0;
-       uint8_t ttl;
+       uint8_t ttl = 0;
        vrf_id_t vrfid = VRF_DEFAULT;
        ifindex_t ifindex = IFINDEX_INTERNAL;
        struct sockaddr_any local, peer;
@@ -544,7 +552,7 @@ int bfd_recv_cb(struct thread *t)
        }
 
        /* Validate packet TTL. */
-       if ((is_mhop == false) && (ttl != BFD_TTL_VAL)) {
+       if ((!is_mhop) && (ttl != BFD_TTL_VAL)) {
                cp_debug(is_mhop, &peer, &local, ifindex, vrfid,
                         "invalid TTL: %d expected %d", ttl, BFD_TTL_VAL);
                return 0;
@@ -602,8 +610,8 @@ int bfd_recv_cb(struct thread *t)
                                 bfd->mh_ttl, BFD_TTL_VAL);
                        return 0;
                }
-       } else if (bfd->local_ip.sa_sin.sin_family == AF_UNSPEC) {
-               bfd->local_ip = local;
+       } else if (bfd->local_address.sa_sin.sin_family == AF_UNSPEC) {
+               bfd->local_address = local;
        }
 
        /*
@@ -617,7 +625,7 @@ int bfd_recv_cb(struct thread *t)
        if ((bfd->discrs.remote_discr != 0)
            && (bfd->discrs.remote_discr != ntohl(cp->discrs.my_discr)))
                cp_debug(is_mhop, &peer, &local, ifindex, vrfid,
-                        "remote discriminator mismatch (expected %d, got %d)",
+                        "remote discriminator mismatch (expected %u, got %u)",
                         bfd->discrs.remote_discr, ntohl(cp->discrs.my_discr));
 
        bfd->discrs.remote_discr = ntohl(cp->discrs.my_discr);
@@ -656,8 +664,13 @@ int bfd_recv_cb(struct thread *t)
         *
         * RFC 5880, Section 6.5.
         */
-       if (BFD_GETPBIT(cp->flags))
+       if (BFD_GETPBIT(cp->flags)) {
+               /* We are finalizing a poll negotiation. */
+               bs_final_handler(bfd);
+
+               /* Send the control packet with the final bit immediately. */
                ptm_bfd_snd(bfd, 1);
+       }
 
        return 0;
 }
@@ -887,7 +900,7 @@ int bp_udp_mhop(void)
        return sd;
 }
 
-int bp_peer_socket(struct bfd_peer_cfg *bpc)
+int bp_peer_socket(const struct bfd_session *bs)
 {
        int sd, pcount;
        struct sockaddr_in sin;
@@ -912,13 +925,14 @@ int bp_peer_socket(struct bfd_peer_cfg *bpc)
                return -1;
        }
 
-       if (bpc->bpc_has_localif) {
-               if (bp_bind_dev(sd, bpc->bpc_localif) != 0) {
+       if (bs->key.ifname[0]) {
+               if (bp_bind_dev(sd, bs->key.ifname) != 0) {
                        close(sd);
                        return -1;
                }
-       } else if (bpc->bpc_mhop && bpc->bpc_has_vrfname) {
-               if (bp_bind_dev(sd, bpc->bpc_vrfname) != 0) {
+       } else if (BFD_CHECK_FLAG(bs->flags, BFD_SESS_FLAG_MH)
+                  && bs->key.vrfname[0]) {
+               if (bp_bind_dev(sd, bs->key.vrfname) != 0) {
                        close(sd);
                        return -1;
                }
@@ -926,14 +940,12 @@ int bp_peer_socket(struct bfd_peer_cfg *bpc)
 
        /* Find an available source port in the proper range */
        memset(&sin, 0, sizeof(sin));
-       sin = bpc->bpc_local.sa_sin;
        sin.sin_family = AF_INET;
 #ifdef HAVE_STRUCT_SOCKADDR_SA_LEN
        sin.sin_len = sizeof(sin);
 #endif /* HAVE_STRUCT_SOCKADDR_SA_LEN */
-       if (bpc->bpc_mhop)
-               sin.sin_addr = bpc->bpc_local.sa_sin.sin_addr;
-       else
+       memcpy(&sin.sin_addr, &bs->key.local, sizeof(sin.sin_addr));
+       if (BFD_CHECK_FLAG(bs->flags, BFD_SESS_FLAG_MH) == 0)
                sin.sin_addr.s_addr = INADDR_ANY;
 
        pcount = 0;
@@ -958,9 +970,8 @@ int bp_peer_socket(struct bfd_peer_cfg *bpc)
  * IPv6 sockets
  */
 
-int bp_peer_socketv6(struct bfd_peer_cfg *bpc)
+int bp_peer_socketv6(const struct bfd_session *bs)
 {
-       struct interface *ifp;
        int sd, pcount;
        struct sockaddr_in6 sin6;
        static int srcPort = BFD_SRCPORTINIT;
@@ -990,20 +1001,18 @@ 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;
-       if (IN6_IS_ADDR_LINKLOCAL(&sin6.sin6_addr)) {
-               ifp = if_lookup_by_name(bpc->bpc_localif, VRF_DEFAULT);
-               sin6.sin6_scope_id =
-                       (ifp != NULL) ? ifp->ifindex : IFINDEX_INTERNAL;
-       }
+       memcpy(&sin6.sin6_addr, &bs->key.local, sizeof(sin6.sin6_addr));
+       if (IN6_IS_ADDR_LINKLOCAL(&sin6.sin6_addr))
+               sin6.sin6_scope_id = bs->ifp->ifindex;
 
-       if (bpc->bpc_has_localif) {
-               if (bp_bind_dev(sd, bpc->bpc_localif) != 0) {
+       if (bs->key.ifname[0]) {
+               if (bp_bind_dev(sd, bs->key.ifname) != 0) {
                        close(sd);
                        return -1;
                }
-       } else if (bpc->bpc_mhop && bpc->bpc_has_vrfname) {
-               if (bp_bind_dev(sd, bpc->bpc_vrfname) != 0) {
+       } else if (BFD_CHECK_FLAG(bs->flags, BFD_SESS_FLAG_MH)
+                  && bs->key.vrfname[0]) {
+               if (bp_bind_dev(sd, bs->key.vrfname) != 0) {
                        close(sd);
                        return -1;
                }