]> git.puffer.fish Git - mirror/frr.git/commitdiff
pim6d: pim6d socket changes 10399/head
authorBalaji Gurudoss <G_Balaji1@dell.com>
Thu, 3 Mar 2022 06:54:19 +0000 (12:24 +0530)
committerDavid Lamparter <equinox@opensourcerouting.org>
Sat, 12 Mar 2022 14:59:01 +0000 (15:59 +0100)
socket changes to support IPv6 PIM

Signed-off-by: Balaji Gurudoss <G_Balaji1@dell.com>
[DL: cleaned up & refactored a whole bunch more.]
Signed-off-by: David Lamparter <equinox@opensourcerouting.org>
pimd/pim_igmp.c
pimd/pim_pim.c
pimd/pim_sock.c
pimd/pim_sock.h
pimd/pim_ssmpingd.c

index 5cdefd2828b70b633e5f1b0d6357d59d9ea2df18..2494c6fda9928035af9bead5e31cc39d44898e9e 100644 (file)
@@ -1016,8 +1016,8 @@ static void pim_igmp_read(struct thread *t)
 {
        uint8_t buf[10000];
        struct gm_sock *igmp = (struct gm_sock *)THREAD_ARG(t);
-       struct sockaddr_in from;
-       struct sockaddr_in to;
+       struct sockaddr_storage from;
+       struct sockaddr_storage to;
        socklen_t fromlen = sizeof(from);
        socklen_t tolen = sizeof(to);
        ifindex_t ifindex = -1;
index 5cc0d63e317d75cf2673b6071d077217dd22fda7..d3edc5d0fed1bff20d3a90f234d8d8f6b39942d2 100644 (file)
@@ -331,8 +331,8 @@ static void pim_sock_read(struct thread *t)
        struct interface *ifp, *orig_ifp;
        struct pim_interface *pim_ifp;
        int fd;
-       struct sockaddr_in from;
-       struct sockaddr_in to;
+       struct sockaddr_storage from;
+       struct sockaddr_storage to;
        socklen_t fromlen = sizeof(from);
        socklen_t tolen = sizeof(to);
        uint8_t buf[PIM_PIM_BUFSIZE_READ];
index 8d3fbabd27b40ea3306bdd8a781e5ae6136853a1..92e2d184517e64c9ab7211908d0d6eb325c386cb 100644 (file)
 #include "vrf.h"
 #include "sockopt.h"
 #include "lib_errors.h"
+#include "network.h"
 
 #include "pimd.h"
 #include "pim_mroute.h"
 #include "pim_sock.h"
 #include "pim_str.h"
 
-/* GLOBAL VARS */
+#if PIM_IPV == 4
+#define setsockopt_iptos setsockopt_ipv4_tos
+#define setsockopt_multicast_loop setsockopt_ipv4_multicast_loop
+#else
+#define setsockopt_iptos setsockopt_ipv6_tclass
+#define setsockopt_multicast_loop setsockopt_ipv6_multicast_loop
+#endif
 
 int pim_socket_raw(int protocol)
 {
        int fd;
 
        frr_with_privs(&pimd_privs) {
-
-               fd = socket(AF_INET, SOCK_RAW, protocol);
-
+               fd = socket(PIM_AF, SOCK_RAW, protocol);
        }
 
        if (fd < 0) {
@@ -66,10 +71,16 @@ void pim_socket_ip_hdr(int fd)
        const int on = 1;
 
        frr_with_privs(&pimd_privs) {
-
+#if PIM_IPV == 4
                if (setsockopt(fd, IPPROTO_IP, IP_HDRINCL, &on, sizeof(on)))
-                       zlog_err("%s: Could not turn on IP_HDRINCL option: %s",
-                                __func__, safe_strerror(errno));
+                       zlog_err("%s: Could not turn on IP_HDRINCL option: %m",
+                                __func__);
+#else
+               if (setsockopt(fd, IPPROTO_IPV6, IPV6_HDRINCL, &on, sizeof(on)))
+                       zlog_err(
+                               "%s: Could not turn on IPV6_HDRINCL option: %m",
+                               __func__);
+#endif
        }
 }
 
@@ -80,248 +91,252 @@ void pim_socket_ip_hdr(int fd)
 int pim_socket_bind(int fd, struct interface *ifp)
 {
        int ret = 0;
-#ifdef SO_BINDTODEVICE
 
+#ifdef SO_BINDTODEVICE
        frr_with_privs(&pimd_privs) {
-
                ret = setsockopt(fd, SOL_SOCKET, SO_BINDTODEVICE, ifp->name,
                                 strlen(ifp->name));
-
        }
-
 #endif
        return ret;
 }
 
-int pim_socket_mcast(int protocol, struct in_addr ifaddr, struct interface *ifp,
-                    uint8_t loop)
+#if PIM_IPV == 4
+static inline int pim_setsockopt(int protocol, int fd, struct interface *ifp)
 {
-       int rcvbuf = 1024 * 1024 * 8;
-#ifdef HAVE_STRUCT_IP_MREQN_IMR_IFINDEX
-       struct ip_mreqn mreq;
-#else
-       struct ip_mreq mreq;
-#endif
-       int fd;
+       int one = 1;
+       int ttl = 1;
 
-       fd = pim_socket_raw(protocol);
-       if (fd < 0) {
-               zlog_warn("Could not create multicast socket: errno=%d: %s",
-                         errno, safe_strerror(errno));
-               return PIM_SOCK_ERR_SOCKET;
-       }
-
-#ifdef SO_BINDTODEVICE
-       int ret;
-
-       ret = pim_socket_bind(fd, ifp);
-       if (ret) {
-               close(fd);
-               zlog_warn(
-                       "Could not set fd: %d for interface: %s to device",
-                       fd, ifp->name);
-               return PIM_SOCK_ERR_BIND;
-       }
-#else
-/* XXX: use IP_PKTINFO / IP_RECVIF to emulate behaviour?  Or change to
- * only use 1 socket for all interfaces? */
-#endif
-
-       /* Needed to obtain destination address from recvmsg() */
-       {
 #if defined(HAVE_IP_PKTINFO)
-               /* Linux and Solaris IP_PKTINFO */
-               int opt = 1;
-               if (setsockopt(fd, IPPROTO_IP, IP_PKTINFO, &opt, sizeof(opt))) {
-                       zlog_warn(
-                               "Could not set IP_PKTINFO on socket fd=%d: errno=%d: %s",
-                               fd, errno, safe_strerror(errno));
-               }
+       /* Linux and Solaris IP_PKTINFO */
+       if (setsockopt(fd, IPPROTO_IP, IP_PKTINFO, &one, sizeof(one)))
+               zlog_warn("Could not set PKTINFO on socket fd=%d: %m", fd);
 #elif defined(HAVE_IP_RECVDSTADDR)
-               /* BSD IP_RECVDSTADDR */
-               int opt = 1;
-               if (setsockopt(fd, IPPROTO_IP, IP_RECVDSTADDR, &opt,
-                              sizeof(opt))) {
-                       zlog_warn(
-                               "Could not set IP_RECVDSTADDR on socket fd=%d: errno=%d: %s",
-                               fd, errno, safe_strerror(errno));
-               }
+       /* BSD IP_RECVDSTADDR */
+       if (setsockopt(fd, IPPROTO_IP, IP_RECVDSTADDR, &one, sizeof(one)))
+               zlog_warn("Could not set IP_RECVDSTADDR on socket fd=%d: %m",
+                         fd);
 #else
-               flog_err(
-                       EC_LIB_DEVELOPMENT,
-                       "%s %s: Missing IP_PKTINFO and IP_RECVDSTADDR: unable to get dst addr from recvmsg()",
-                       __FILE__, __func__);
-               close(fd);
-               return PIM_SOCK_ERR_DSTADDR;
+       flog_err(
+               EC_LIB_DEVELOPMENT,
+               "Missing IP_PKTINFO and IP_RECVDSTADDR: unable to get dst addr from recvmsg()");
+       close(fd);
+       return PIM_SOCK_ERR_DSTADDR;
 #endif
-       }
-
 
-       /* Set router alert (RFC 2113) for all IGMP messages (RFC 3376 4.
-        * Message Formats)*/
+       /* Set router alert (RFC 2113) for all IGMP messages (RFC
+        * 3376 4. Message Formats)*/
        if (protocol == IPPROTO_IGMP) {
                uint8_t ra[4];
+
                ra[0] = 148;
                ra[1] = 4;
                ra[2] = 0;
                ra[3] = 0;
                if (setsockopt(fd, IPPROTO_IP, IP_OPTIONS, ra, 4)) {
                        zlog_warn(
-                               "Could not set Router Alert Option on socket fd=%d: errno=%d: %s",
-                               fd, errno, safe_strerror(errno));
+                               "Could not set Router Alert Option on socket fd=%d: %m",
+                               fd);
                        close(fd);
                        return PIM_SOCK_ERR_RA;
                }
        }
 
-       {
-               int reuse = 1;
-               if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (void *)&reuse,
-                              sizeof(reuse))) {
-                       zlog_warn(
-                               "Could not set Reuse Address Option on socket fd=%d: errno=%d: %s",
-                               fd, errno, safe_strerror(errno));
-                       close(fd);
-                       return PIM_SOCK_ERR_REUSE;
-               }
-       }
-
-       {
-               const int MTTL = 1;
-               int ttl = MTTL;
-               if (setsockopt(fd, IPPROTO_IP, IP_MULTICAST_TTL, (void *)&ttl,
-                              sizeof(ttl))) {
-                       zlog_warn(
-                               "Could not set multicast TTL=%d on socket fd=%d: errno=%d: %s",
-                               MTTL, fd, errno, safe_strerror(errno));
-                       close(fd);
-                       return PIM_SOCK_ERR_TTL;
-               }
+       if (setsockopt(fd, IPPROTO_IP, IP_MULTICAST_TTL, &ttl, sizeof(ttl))) {
+               zlog_warn("Could not set multicast TTL=%d on socket fd=%d: %m",
+                         ttl, fd);
+               close(fd);
+               return PIM_SOCK_ERR_TTL;
        }
 
-       if (setsockopt_ipv4_multicast_loop(fd, loop)) {
+       if (setsockopt_ipv4_multicast_if(fd, PIMADDR_ANY, ifp->ifindex)) {
                zlog_warn(
-                       "Could not %s Multicast Loopback Option on socket fd=%d: errno=%d: %s",
-                       loop ? "enable" : "disable", fd, errno,
-                       safe_strerror(errno));
+                       "Could not set Outgoing Interface Option on socket fd=%d: %m",
+                       fd);
                close(fd);
-               return PIM_SOCK_ERR_LOOP;
+               return PIM_SOCK_ERR_IFACE;
        }
 
-       memset(&mreq, 0, sizeof(mreq));
-#ifdef HAVE_STRUCT_IP_MREQN_IMR_IFINDEX
-       mreq.imr_ifindex = ifp->ifindex;
-#else
-/*
- * I am not sure what to do here yet for *BSD
- */
-// mreq.imr_interface = ifindex;
-#endif
+       return 0;
+}
+#else /* PIM_IPV != 4 */
+static inline int pim_setsockopt(int protocol, int fd, struct interface *ifp)
+{
+       int ttl = 1;
+       struct ipv6_mreq mreq = {};
+
+       setsockopt_ipv6_pktinfo(fd, 1);
+       setsockopt_ipv6_multicast_hops(fd, ttl);
 
-       if (setsockopt(fd, IPPROTO_IP, IP_MULTICAST_IF, (void *)&mreq,
+       mreq.ipv6mr_interface = ifp->ifindex;
+       if (setsockopt(fd, IPPROTO_IPV6, IPV6_MULTICAST_IF, &mreq,
                       sizeof(mreq))) {
                zlog_warn(
-                       "Could not set Outgoing Interface Option on socket fd=%d: errno=%d: %s",
-                       fd, errno, safe_strerror(errno));
+                       "Could not set Outgoing Interface Option on socket fd=%d: %m",
+                       fd);
                close(fd);
                return PIM_SOCK_ERR_IFACE;
        }
 
-       if (setsockopt(fd, SOL_SOCKET, SO_RCVBUF, &rcvbuf, sizeof(rcvbuf)))
-               zlog_warn("%s: Failure to set buffer size to %d", __func__,
-                         rcvbuf);
+       return 0;
+}
+#endif
 
-       {
-               long flags;
+int pim_socket_mcast(int protocol, pim_addr ifaddr, struct interface *ifp,
+                    uint8_t loop)
+{
+       int fd;
+       int ret;
 
-               flags = fcntl(fd, F_GETFL, 0);
-               if (flags < 0) {
-                       zlog_warn(
-                               "Could not get fcntl(F_GETFL,O_NONBLOCK) on socket fd=%d: errno=%d: %s",
-                               fd, errno, safe_strerror(errno));
-                       close(fd);
-                       return PIM_SOCK_ERR_NONBLOCK_GETFL;
-               }
+       fd = pim_socket_raw(protocol);
+       if (fd < 0) {
+               zlog_warn("Could not create multicast socket: errno=%d: %s",
+                         errno, safe_strerror(errno));
+               return PIM_SOCK_ERR_SOCKET;
+       }
 
-               if (fcntl(fd, F_SETFL, flags | O_NONBLOCK)) {
-                       zlog_warn(
-                               "Could not set fcntl(F_SETFL,O_NONBLOCK) on socket fd=%d: errno=%d: %s",
-                               fd, errno, safe_strerror(errno));
-                       close(fd);
-                       return PIM_SOCK_ERR_NONBLOCK_SETFL;
-               }
+       /* XXX: if SO_BINDTODEVICE isn't available, use IP_PKTINFO / IP_RECVIF
+        * to emulate behaviour?  Or change to only use 1 socket for all
+        * interfaces? */
+       ret = pim_socket_bind(fd, ifp);
+       if (ret) {
+               close(fd);
+               zlog_warn("Could not set fd: %d for interface: %s to device",
+                         fd, ifp->name);
+               return PIM_SOCK_ERR_BIND;
        }
 
-       /* Set Tx socket DSCP byte */
-       if (setsockopt_ipv4_tos(fd, IPTOS_PREC_INTERNETCONTROL)) {
-               zlog_warn("can't set sockopt IP_TOS to PIM/IGMP socket %d: %s",
-                         fd, safe_strerror(errno));
+       set_nonblocking(fd);
+       sockopt_reuseaddr(fd);
+       setsockopt_so_recvbuf(fd, 8 * 1024 * 1024);
+
+       ret = pim_setsockopt(protocol, fd, ifp);
+       if (ret) {
+               zlog_warn("pim_setsockopt failed for interface: %s to device ",
+                         ifp->name);
+               return ret;
        }
 
+       /* leftover common sockopts */
+       if (setsockopt_multicast_loop(fd, loop)) {
+               zlog_warn(
+                       "Could not %s Multicast Loopback Option on socket fd=%d: %m",
+                       loop ? "enable" : "disable", fd);
+               close(fd);
+               return PIM_SOCK_ERR_LOOP;
+       }
+
+       /* Set Tx socket DSCP byte */
+       if (setsockopt_iptos(fd, IPTOS_PREC_INTERNETCONTROL))
+               zlog_warn("can't set sockopt IP[V6]_TOS to socket %d: %m", fd);
+
        return fd;
 }
 
-int pim_socket_join(int fd, struct in_addr group, struct in_addr ifaddr,
-                   ifindex_t ifindex)
+int pim_socket_join(int fd, pim_addr group, pim_addr ifaddr, ifindex_t ifindex)
 {
        int ret;
 
-#ifdef HAVE_STRUCT_IP_MREQN_IMR_IFINDEX
-       struct ip_mreqn opt;
+#if PIM_IPV == 4
+       ret = setsockopt_ipv4_multicast(fd, IP_ADD_MEMBERSHIP, ifaddr,
+                                       group.s_addr, ifindex);
 #else
-       struct ip_mreq opt;
-#endif
-
-       opt.imr_multiaddr = group;
+       struct ipv6_mreq opt;
 
-#ifdef HAVE_STRUCT_IP_MREQN_IMR_IFINDEX
-       opt.imr_address = ifaddr;
-       opt.imr_ifindex = ifindex;
-#else
-       opt.imr_interface = ifaddr;
+       memcpy(&opt.ipv6mr_multiaddr, &group, 16);
+       opt.ipv6mr_interface = ifindex;
+       ret = setsockopt(fd, IPPROTO_IPV6, IPV6_JOIN_GROUP, &opt, sizeof(opt));
 #endif
 
-       ret = setsockopt(fd, IPPROTO_IP, IP_ADD_MEMBERSHIP, &opt, sizeof(opt));
        if (ret) {
-               char group_str[INET_ADDRSTRLEN];
-               char ifaddr_str[INET_ADDRSTRLEN];
-               if (!inet_ntop(AF_INET, &group, group_str, sizeof(group_str)))
-                       snprintf(group_str, sizeof(group_str), "<group?>");
-               if (!inet_ntop(AF_INET, &ifaddr, ifaddr_str,
-                              sizeof(ifaddr_str)))
-                       snprintf(ifaddr_str, sizeof(ifaddr_str), "<ifaddr?>");
-
                flog_err(
                        EC_LIB_SOCKET,
-                       "Failure socket joining fd=%d group %s on interface address %s: errno=%d: %s",
-                       fd, group_str, ifaddr_str, errno, safe_strerror(errno));
+                       "Failure socket joining fd=%d group %pPAs on interface address %pPAs: %m",
+                       fd, &group, &ifaddr);
                return ret;
        }
 
-       if (PIM_DEBUG_TRACE) {
-               char group_str[INET_ADDRSTRLEN];
-               char ifaddr_str[INET_ADDRSTRLEN];
-               if (!inet_ntop(AF_INET, &group, group_str, sizeof(group_str)))
-                       snprintf(group_str, sizeof(group_str), "<group?>");
-               if (!inet_ntop(AF_INET, &ifaddr, ifaddr_str,
-                              sizeof(ifaddr_str)))
-                       snprintf(ifaddr_str, sizeof(ifaddr_str), "<ifaddr?>");
-
+       if (PIM_DEBUG_TRACE)
                zlog_debug(
-                       "Socket fd=%d joined group %s on interface address %s",
-                       fd, group_str, ifaddr_str);
+                       "Socket fd=%d joined group %pPAs on interface address %pPAs",
+                       fd, &group, &ifaddr);
+       return ret;
+}
+
+#if PIM_IPV == 4
+static void cmsg_getdstaddr(struct msghdr *mh, struct sockaddr_storage *dst,
+                           ifindex_t *ifindex)
+{
+       struct cmsghdr *cmsg;
+       struct sockaddr_in *dst4 = (struct sockaddr_in *)dst;
+
+       for (cmsg = CMSG_FIRSTHDR(mh); cmsg != NULL;
+            cmsg = CMSG_NXTHDR(mh, cmsg)) {
+#ifdef HAVE_IP_PKTINFO
+               if ((cmsg->cmsg_level == IPPROTO_IP) &&
+                   (cmsg->cmsg_type == IP_PKTINFO)) {
+                       struct in_pktinfo *i;
+
+                       i = (struct in_pktinfo *)CMSG_DATA(cmsg);
+                       if (dst4)
+                               dst4->sin_addr = i->ipi_addr;
+                       if (ifindex)
+                               *ifindex = i->ipi_ifindex;
+
+                       break;
+               }
+#endif
+
+#ifdef HAVE_IP_RECVDSTADDR
+               if ((cmsg->cmsg_level == IPPROTO_IP) &&
+                   (cmsg->cmsg_type == IP_RECVDSTADDR)) {
+                       struct in_addr *i = (struct in_addr *)CMSG_DATA(cmsg);
+
+                       if (dst4)
+                               dst4->sin_addr = *i;
+
+                       break;
+               }
+#endif
+
+#if defined(HAVE_IP_RECVIF) && defined(CMSG_IFINDEX)
+               if (cmsg->cmsg_type == IP_RECVIF)
+                       if (ifindex)
+                               *ifindex = CMSG_IFINDEX(cmsg);
+#endif
        }
+}
+#else  /* PIM_IPV != 4 */
+static void cmsg_getdstaddr(struct msghdr *mh, struct sockaddr_storage *dst,
+                           ifindex_t *ifindex)
+{
+       struct cmsghdr *cmsg;
+       struct sockaddr_in6 *dst6 = (struct sockaddr_in6 *)dst;
 
-       return ret;
+       for (cmsg = CMSG_FIRSTHDR(mh); cmsg != NULL;
+            cmsg = CMSG_NXTHDR(mh, cmsg)) {
+               if ((cmsg->cmsg_level == IPPROTO_IPV6) &&
+                   (cmsg->cmsg_type == IPV6_PKTINFO)) {
+                       struct in6_pktinfo *i;
+
+                       i = (struct in6_pktinfo *)CMSG_DATA(cmsg);
+
+                       if (dst6)
+                               dst6->sin6_addr = i->ipi6_addr;
+                       if (ifindex)
+                               *ifindex = i->ipi6_ifindex;
+                       break;
+               }
+       }
 }
+#endif /* PIM_IPV != 4 */
 
 int pim_socket_recvfromto(int fd, uint8_t *buf, size_t len,
-                         struct sockaddr_in *from, socklen_t *fromlen,
-                         struct sockaddr_in *to, socklen_t *tolen,
+                         struct sockaddr_storage *from, socklen_t *fromlen,
+                         struct sockaddr_storage *to, socklen_t *tolen,
                          ifindex_t *ifindex)
 {
        struct msghdr msgh;
-       struct cmsghdr *cmsg;
        struct iovec iov;
        char cbuf[1000];
        int err;
@@ -331,19 +346,12 @@ int pim_socket_recvfromto(int fd, uint8_t *buf, size_t len,
         * Use getsockname() to get sin_port.
         */
        if (to) {
-               struct sockaddr_in si;
-               socklen_t si_len = sizeof(si);
-
-               memset(&si, 0, sizeof(si));
-               to->sin_family = AF_INET;
-
-               pim_socket_getsockname(fd, (struct sockaddr *)&si, &si_len);
+               socklen_t to_len = sizeof(*to);
 
-               to->sin_port = si.sin_port;
-               to->sin_addr = si.sin_addr;
+               pim_socket_getsockname(fd, (struct sockaddr *)to, &to_len);
 
                if (tolen)
-                       *tolen = sizeof(si);
+                       *tolen = sizeof(*to);
        }
 
        memset(&msgh, 0, sizeof(struct msghdr));
@@ -364,45 +372,7 @@ int pim_socket_recvfromto(int fd, uint8_t *buf, size_t len,
        if (fromlen)
                *fromlen = msgh.msg_namelen;
 
-       for (cmsg = CMSG_FIRSTHDR(&msgh); cmsg != NULL;
-            cmsg = CMSG_NXTHDR(&msgh, cmsg)) {
-
-#ifdef HAVE_IP_PKTINFO
-               if ((cmsg->cmsg_level == IPPROTO_IP)
-                   && (cmsg->cmsg_type == IP_PKTINFO)) {
-                       struct in_pktinfo *i =
-                               (struct in_pktinfo *)CMSG_DATA(cmsg);
-                       if (to)
-                               to->sin_addr = i->ipi_addr;
-                       if (tolen)
-                               *tolen = sizeof(struct sockaddr_in);
-                       if (ifindex)
-                               *ifindex = i->ipi_ifindex;
-
-                       break;
-               }
-#endif
-
-#ifdef HAVE_IP_RECVDSTADDR
-               if ((cmsg->cmsg_level == IPPROTO_IP)
-                   && (cmsg->cmsg_type == IP_RECVDSTADDR)) {
-                       struct in_addr *i = (struct in_addr *)CMSG_DATA(cmsg);
-                       if (to)
-                               to->sin_addr = *i;
-                       if (tolen)
-                               *tolen = sizeof(struct sockaddr_in);
-
-                       break;
-               }
-#endif
-
-#if defined(HAVE_IP_RECVIF) && defined(CMSG_IFINDEX)
-               if (cmsg->cmsg_type == IP_RECVIF)
-                       if (ifindex)
-                               *ifindex = CMSG_IFINDEX(cmsg);
-#endif
-
-       } /* for (cmsg) */
+       cmsg_getdstaddr(&msgh, to, ifindex);
 
        return err; /* len */
 }
index 7081e38f818155fe38ba1581b3688f341e68c5e8..97cbda0c10c9120a30ff4cb0281e5ac0cd4d056e 100644 (file)
 int pim_socket_bind(int fd, struct interface *ifp);
 void pim_socket_ip_hdr(int fd);
 int pim_socket_raw(int protocol);
-int pim_socket_mcast(int protocol, struct in_addr ifaddr, struct interface *ifp,
+int pim_socket_mcast(int protocol, pim_addr ifaddr, struct interface *ifp,
                     uint8_t loop);
-int pim_socket_join(int fd, struct in_addr group, struct in_addr ifaddr,
-                   ifindex_t ifindex);
+int pim_socket_join(int fd, pim_addr group, pim_addr ifaddr, ifindex_t ifindex);
+
 int pim_socket_recvfromto(int fd, uint8_t *buf, size_t len,
-                         struct sockaddr_in *from, socklen_t *fromlen,
-                         struct sockaddr_in *to, socklen_t *tolen,
+                         struct sockaddr_storage *from, socklen_t *fromlen,
+                         struct sockaddr_storage *to, socklen_t *tolen,
                          ifindex_t *ifindex);
 
 int pim_socket_getsockname(int fd, struct sockaddr *name, socklen_t *namelen);
index 596b06cb38e36dfea6bd338ca6f1779af18e1683..e43b46604c857c5df185edbfb097b35133f62cc5 100644 (file)
@@ -244,8 +244,8 @@ static void ssmpingd_sendto(struct ssmpingd_sock *ss, const uint8_t *buf,
 static int ssmpingd_read_msg(struct ssmpingd_sock *ss)
 {
        struct interface *ifp;
-       struct sockaddr_in from;
-       struct sockaddr_in to;
+       struct sockaddr_storage from;
+       struct sockaddr_storage to;
        socklen_t fromlen = sizeof(from);
        socklen_t tolen = sizeof(to);
        ifindex_t ifindex = -1;
@@ -256,13 +256,11 @@ static int ssmpingd_read_msg(struct ssmpingd_sock *ss)
 
        len = pim_socket_recvfromto(ss->sock_fd, buf, sizeof(buf), &from,
                                    &fromlen, &to, &tolen, &ifindex);
+
        if (len < 0) {
-               char source_str[INET_ADDRSTRLEN];
-               pim_inet4_dump("<src?>", ss->source_addr, source_str,
-                              sizeof(source_str));
                zlog_warn(
-                       "%s: failure receiving ssmping for source %s on fd=%d: errno=%d: %s",
-                       __func__, source_str, ss->sock_fd, errno,
+                       "%s: failure receiving ssmping for source %pI4 on fd=%d: errno=%d: %s",
+                       __func__, &ss->source_addr, ss->sock_fd, errno,
                        safe_strerror(errno));
                return -1;
        }
@@ -270,47 +268,31 @@ static int ssmpingd_read_msg(struct ssmpingd_sock *ss)
        ifp = if_lookup_by_index(ifindex, ss->pim->vrf->vrf_id);
 
        if (buf[0] != PIM_SSMPINGD_REQUEST) {
-               char source_str[INET_ADDRSTRLEN];
-               char from_str[INET_ADDRSTRLEN];
-               char to_str[INET_ADDRSTRLEN];
-               pim_inet4_dump("<src?>", ss->source_addr, source_str,
-                              sizeof(source_str));
-               pim_inet4_dump("<from?>", from.sin_addr, from_str,
-                              sizeof(from_str));
-               pim_inet4_dump("<to?>", to.sin_addr, to_str, sizeof(to_str));
                zlog_warn(
-                       "%s: bad ssmping type=%d from %s,%d to %s,%d on interface %s ifindex=%d fd=%d src=%s",
-                       __func__, buf[0], from_str, ntohs(from.sin_port),
-                       to_str, ntohs(to.sin_port),
+                       "%s: bad ssmping type=%d from %pSUp to %pSUp on interface %s ifindex=%d fd=%d src=%pI4",
+                       __func__, buf[0], &from, &to,
                        ifp ? ifp->name : "<iface?>", ifindex, ss->sock_fd,
-                       source_str);
+                       &ss->source_addr);
                return 0;
        }
 
        if (PIM_DEBUG_SSMPINGD) {
-               char source_str[INET_ADDRSTRLEN];
-               char from_str[INET_ADDRSTRLEN];
-               char to_str[INET_ADDRSTRLEN];
-               pim_inet4_dump("<src?>", ss->source_addr, source_str,
-                              sizeof(source_str));
-               pim_inet4_dump("<from?>", from.sin_addr, from_str,
-                              sizeof(from_str));
-               pim_inet4_dump("<to?>", to.sin_addr, to_str, sizeof(to_str));
                zlog_debug(
-                       "%s: recv ssmping from %s,%d to %s,%d on interface %s ifindex=%d fd=%d src=%s",
-                       __func__, from_str, ntohs(from.sin_port), to_str,
-                       ntohs(to.sin_port), ifp ? ifp->name : "<iface?>",
-                       ifindex, ss->sock_fd, source_str);
+                       "%s: recv ssmping from %pSUp, to %pSUp, on interface %s ifindex=%d fd=%d src=%pI4",
+                       __func__, &from, &to, ifp ? ifp->name : "<iface?>",
+                       ifindex, ss->sock_fd, &ss->source_addr);
        }
 
        buf[0] = PIM_SSMPINGD_REPLY;
 
+       struct sockaddr_in *from_addr = (struct sockaddr_in *)&from;
+
        /* unicast reply */
-       ssmpingd_sendto(ss, buf, len, from);
+       ssmpingd_sendto(ss, buf, len, *from_addr);
 
        /* multicast reply */
-       from.sin_addr = ss->pim->ssmpingd_group_addr;
-       ssmpingd_sendto(ss, buf, len, from);
+       from_addr->sin_addr = ss->pim->ssmpingd_group_addr;
+       ssmpingd_sendto(ss, buf, len, *from_addr);
 
        return 0;
 }