]> git.puffer.fish Git - mirror/frr.git/commitdiff
pim6d: Changes done in pim_ssmpingd to support v6 10653/head
authorBalaji Gurudoss <G_Balaji1@dell.com>
Fri, 25 Feb 2022 10:29:03 +0000 (15:59 +0530)
committerBalaji Gurudoss <G_Balaji1@dell.com>
Wed, 16 Mar 2022 08:24:24 +0000 (13:54 +0530)
Signed-off-by: Balaji Gurudoss <G_Balaji1@dell.com>
pimd/pim_instance.h
pimd/pim_nb_config.c
pimd/pim_ssmpingd.c
pimd/pim_ssmpingd.h
pimd/pim_vty.c

index 68c5b9167bb0c7cc2ca6f8576ea8e94cb2bf5f82..4ac9ef7f5195809d9bd7f6b353d8b364f7f7e4a6 100644 (file)
@@ -176,7 +176,7 @@ struct pim_instance {
        struct pim_vxlan_instance vxlan;
 
        struct list *ssmpingd_list;
-       struct in_addr ssmpingd_group_addr;
+       pim_addr ssmpingd_group_addr;
 
        unsigned int igmp_group_count;
        unsigned int igmp_watermark_limit;
index 21f57e2d11c7db4e031c82f8a3ebd5d602bc797e..2fabee5dfd1a151a772699e751ef1c594bae5eae 100644 (file)
@@ -930,7 +930,7 @@ int routing_control_plane_protocols_control_plane_protocol_pim_address_family_ss
        struct vrf *vrf;
        struct pim_instance *pim;
        int result;
-       struct ipaddr source_addr;
+       pim_addr source_addr;
 
        switch (args->event) {
        case NB_EV_VALIDATE:
@@ -940,16 +940,14 @@ int routing_control_plane_protocols_control_plane_protocol_pim_address_family_ss
        case NB_EV_APPLY:
                vrf = nb_running_get_entry(args->dnode, NULL, true);
                pim = vrf->info;
-               yang_dnode_get_ip(&source_addr, args->dnode, NULL);
-               result = pim_ssmpingd_start(pim, source_addr.ip._v4_addr);
+               yang_dnode_get_pimaddr(&source_addr, args->dnode,
+                                      "./source-addr");
+               result = pim_ssmpingd_start(pim, source_addr);
                if (result) {
-                       char source_str[INET_ADDRSTRLEN];
-
-                       ipaddr2str(&source_addr, source_str,
-                                       sizeof(source_str));
-                       snprintf(args->errmsg, args->errmsg_len,
-                                "%% Failure starting ssmpingd for source %s: %d",
-                                source_str, result);
+                       snprintf(
+                               args->errmsg, args->errmsg_len,
+                               "%% Failure starting ssmpingd for source %pPA: %d",
+                               &source_addr, result);
                        return NB_ERR_INCONSISTENCY;
                }
        }
@@ -963,7 +961,7 @@ int routing_control_plane_protocols_control_plane_protocol_pim_address_family_ss
        struct vrf *vrf;
        struct pim_instance *pim;
        int result;
-       struct ipaddr source_addr;
+       pim_addr source_addr;
 
        switch (args->event) {
        case NB_EV_VALIDATE:
@@ -973,16 +971,14 @@ int routing_control_plane_protocols_control_plane_protocol_pim_address_family_ss
        case NB_EV_APPLY:
                vrf = nb_running_get_entry(args->dnode, NULL, true);
                pim = vrf->info;
-               yang_dnode_get_ip(&source_addr, args->dnode, NULL);
-               result = pim_ssmpingd_stop(pim, source_addr.ip._v4_addr);
+               yang_dnode_get_pimaddr(&source_addr, args->dnode,
+                                      "./source-addr");
+               result = pim_ssmpingd_stop(pim, source_addr);
                if (result) {
-                       char source_str[INET_ADDRSTRLEN];
-
-                       ipaddr2str(&source_addr, source_str,
-                                  sizeof(source_str));
-                       snprintf(args->errmsg, args->errmsg_len,
-                                "%% Failure stopping ssmpingd for source %s: %d",
-                                 source_str, result);
+                       snprintf(
+                               args->errmsg, args->errmsg_len,
+                               "%% Failure stopping ssmpingd for source %pPA: %d",
+                               &source_addr, result);
                        return NB_ERR_INCONSISTENCY;
                }
 
index e43b46604c857c5df185edbfb097b35133f62cc5..da903bd9802acea01e4ab89a1e67cd4e409c5ecd 100644 (file)
 #include "pim_ssmpingd.h"
 #include "pim_time.h"
 #include "pim_sock.h"
+#include "network.h"
 
+#if PIM_IPV == 4
 static const char *const PIM_SSMPINGD_REPLY_GROUP = "232.43.211.234";
+#else
+static const char *const PIM_SSMPINGD_REPLY_GROUP = "ff3e::4321:1234";
+#endif
 
 enum { PIM_SSMPINGD_REQUEST = 'Q', PIM_SSMPINGD_REPLY = 'A' };
 
@@ -43,7 +48,7 @@ void pim_ssmpingd_init(struct pim_instance *pim)
 
        assert(!pim->ssmpingd_list);
 
-       result = inet_pton(AF_INET, PIM_SSMPINGD_REPLY_GROUP,
+       result = inet_pton(PIM_AF, PIM_SSMPINGD_REPLY_GROUP,
                           &pim->ssmpingd_group_addr);
 
        assert(result > 0);
@@ -56,7 +61,7 @@ void pim_ssmpingd_destroy(struct pim_instance *pim)
 }
 
 static struct ssmpingd_sock *ssmpingd_find(struct pim_instance *pim,
-                                          struct in_addr source_addr)
+                                          pim_addr source_addr)
 {
        struct listnode *node;
        struct ssmpingd_sock *ss;
@@ -65,7 +70,7 @@ static struct ssmpingd_sock *ssmpingd_find(struct pim_instance *pim,
                return 0;
 
        for (ALL_LIST_ELEMENTS_RO(pim->ssmpingd_list, node, ss))
-               if (source_addr.s_addr == ss->source_addr.s_addr)
+               if (!pim_addr_cmp(source_addr, ss->source_addr))
                        return ss;
 
        return 0;
@@ -76,73 +81,50 @@ static void ssmpingd_free(struct ssmpingd_sock *ss)
        XFREE(MTYPE_PIM_SSMPINGD, ss);
 }
 
-static int ssmpingd_socket(struct in_addr addr, int port, int mttl)
+#if PIM_IPV == 4
+static inline int ssmpingd_setsockopt(int fd, pim_addr addr, int mttl)
 {
-       struct sockaddr_in sockaddr;
-       int fd;
-
-       fd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
-       if (fd < 0) {
-               flog_err_sys(EC_LIB_SOCKET,
-                            "%s: could not create socket: errno=%d: %s",
-                            __func__, errno, safe_strerror(errno));
-               return -1;
+       /* 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(
+                       "%s: could not set IP_PKTINFO on socket fd=%d: errno=%d: %s",
+                       __func__, fd, errno, safe_strerror(errno));
        }
+#elif defined(HAVE_IP_RECVDSTADDR)
+       /* BSD IP_RECVDSTADDR */
+       int opt = 1;
+       if (setsockopt(fd, IPPROTO_IP, IP_RECVDSTADDR, &opt, sizeof(opt))) {
+               zlog_warn(
+                       "%s: could not set IP_RECVDSTADDR on socket fd=%d: errno=%d: %s",
+                       __func__, fd, errno, safe_strerror(errno));
+       }
+#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 -1;
+#endif
 
-       sockaddr.sin_family = AF_INET;
-       sockaddr.sin_addr = addr;
-       sockaddr.sin_port = htons(port);
-
-       if (bind(fd, (struct sockaddr *)&sockaddr, sizeof(sockaddr))) {
-               char addr_str[INET_ADDRSTRLEN];
-               pim_inet4_dump("<addr?>", addr, addr_str, sizeof(addr_str));
+       if (setsockopt_ipv4_multicast_loop(fd, 0)) {
                zlog_warn(
-                       "%s: bind(fd=%d,addr=%s,port=%d,len=%zu) failure: errno=%d: %s",
-                       __func__, fd, addr_str, port, sizeof(sockaddr), errno,
-                       safe_strerror(errno));
+                       "%s: could not disable Multicast Loopback Option on socket fd=%d: errno=%d: %s",
+                       __func__, fd, errno, safe_strerror(errno));
                close(fd);
-               return -1;
+               return PIM_SOCK_ERR_LOOP;
        }
 
-       /* 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(
-                               "%s: could not set IP_PKTINFO on socket fd=%d: errno=%d: %s",
-                               __func__, fd, errno, safe_strerror(errno));
-               }
-#elif defined(HAVE_IP_RECVDSTADDR)
-               /* BSD IP_RECVDSTADDR */
-               int opt = 1;
-               if (setsockopt(fd, IPPROTO_IP, IP_RECVDSTADDR, &opt,
-                              sizeof(opt))) {
-                       zlog_warn(
-                               "%s: could not set IP_RECVDSTADDR on socket fd=%d: errno=%d: %s",
-                               __func__, fd, errno, safe_strerror(errno));
-               }
-#else
-               flog_err(
-                       EC_LIB_DEVELOPMENT,
-                       "%s %s: missing IP_PKTINFO and IP_RECVDSTADDR: unable to get dst addr from recvmsg()",
-                       __FILE__, __func__);
+       if (setsockopt(fd, IPPROTO_IP, IP_MULTICAST_IF, (void *)&addr,
+                      sizeof(addr))) {
+               zlog_warn(
+                       "%s: could not set Outgoing Interface Option on socket fd=%d: errno=%d: %s",
+                       __func__, fd, errno, safe_strerror(errno));
                close(fd);
                return -1;
-#endif
-       }
-
-       {
-               int reuse = 1;
-               if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (void *)&reuse,
-                              sizeof(reuse))) {
-                       zlog_warn(
-                               "%s: could not set Reuse Address Option on socket fd=%d: errno=%d: %s",
-                               __func__, fd, errno, safe_strerror(errno));
-                       close(fd);
-                       return -1;
-               }
        }
 
        if (setsockopt(fd, IPPROTO_IP, IP_MULTICAST_TTL, (void *)&mttl,
@@ -154,7 +136,15 @@ static int ssmpingd_socket(struct in_addr addr, int port, int mttl)
                return -1;
        }
 
-       if (setsockopt_ipv4_multicast_loop(fd, 0)) {
+       return 0;
+}
+#else
+static inline int ssmpingd_setsockopt(int fd, pim_addr addr, int mttl)
+{
+       setsockopt_ipv6_pktinfo(fd, 1);
+       setsockopt_ipv6_multicast_hops(fd, mttl);
+
+       if (setsockopt_ipv6_multicast_loop(fd, 0)) {
                zlog_warn(
                        "%s: could not disable Multicast Loopback Option on socket fd=%d: errno=%d: %s",
                        __func__, fd, errno, safe_strerror(errno));
@@ -162,7 +152,7 @@ static int ssmpingd_socket(struct in_addr addr, int port, int mttl)
                return PIM_SOCK_ERR_LOOP;
        }
 
-       if (setsockopt(fd, IPPROTO_IP, IP_MULTICAST_IF, (void *)&addr,
+       if (setsockopt(fd, IPPROTO_IPV6, IPV6_MULTICAST_IF, (void *)&addr,
                       sizeof(addr))) {
                zlog_warn(
                        "%s: could not set Outgoing Interface Option on socket fd=%d: errno=%d: %s",
@@ -170,26 +160,45 @@ static int ssmpingd_socket(struct in_addr addr, int port, int mttl)
                close(fd);
                return -1;
        }
+       return 0;
+}
+#endif
 
-       {
-               long flags;
 
-               flags = fcntl(fd, F_GETFL, 0);
-               if (flags < 0) {
-                       zlog_warn(
-                               "%s: could not get fcntl(F_GETFL,O_NONBLOCK) on socket fd=%d: errno=%d: %s",
-                               __func__, fd, errno, safe_strerror(errno));
-                       close(fd);
-                       return -1;
-               }
+static int ssmpingd_socket(pim_addr addr, int port, int mttl)
+{
+       struct sockaddr_storage sockaddr;
+       int fd;
+       int ret;
+       socklen_t len = sizeof(sockaddr);
 
-               if (fcntl(fd, F_SETFL, flags | O_NONBLOCK)) {
-                       zlog_warn(
-                               "%s: could not set fcntl(F_SETFL,O_NONBLOCK) on socket fd=%d: errno=%d: %s",
-                               __func__, fd, errno, safe_strerror(errno));
-                       close(fd);
-                       return -1;
-               }
+       fd = socket(PIM_AF, SOCK_DGRAM, IPPROTO_UDP);
+       if (fd < 0) {
+               flog_err_sys(EC_LIB_SOCKET,
+                            "%s: could not create socket: errno=%d: %s",
+                            __func__, errno, safe_strerror(errno));
+               return -1;
+       }
+
+       pim_socket_getsockname(fd, (struct sockaddr *)&sockaddr, &len);
+
+       if (bind(fd, (struct sockaddr *)&sockaddr, sizeof(sockaddr))) {
+               zlog_warn(
+                       "%s: bind(fd=%d,addr=%pSUp,port=%d,len=%zu) failure: errno=%d: %s",
+                       __func__, fd, &sockaddr, port, sizeof(sockaddr), errno,
+                       safe_strerror(errno));
+               close(fd);
+               return -1;
+       }
+
+       set_nonblocking(fd);
+       sockopt_reuseaddr(fd);
+
+       ret = ssmpingd_setsockopt(fd, addr, mttl);
+       if (ret) {
+               zlog_warn("ssmpingd_setsockopt failed");
+               close(fd);
+               return -1;
        }
 
        return fd;
@@ -202,12 +211,9 @@ static void ssmpingd_delete(struct ssmpingd_sock *ss)
        THREAD_OFF(ss->t_sock_read);
 
        if (close(ss->sock_fd)) {
-               char source_str[INET_ADDRSTRLEN];
-               pim_inet4_dump("<src?>", ss->source_addr, source_str,
-                              sizeof(source_str));
                zlog_warn(
-                       "%s: failure closing ssmpingd sock_fd=%d for source %s: errno=%d: %s",
-                       __func__, ss->sock_fd, source_str, errno,
+                       "%s: failure closing ssmpingd sock_fd=%d for source %pI4: errno=%d: %s",
+                       __func__, ss->sock_fd, &ss->source_addr, errno,
                        safe_strerror(errno));
                /* warning only */
        }
@@ -217,7 +223,7 @@ static void ssmpingd_delete(struct ssmpingd_sock *ss)
 }
 
 static void ssmpingd_sendto(struct ssmpingd_sock *ss, const uint8_t *buf,
-                           int len, struct sockaddr_in to)
+                           int len, struct sockaddr_storage to)
 {
        socklen_t tolen = sizeof(to);
        int sent;
@@ -225,18 +231,15 @@ static void ssmpingd_sendto(struct ssmpingd_sock *ss, const uint8_t *buf,
        sent = sendto(ss->sock_fd, buf, len, MSG_DONTWAIT,
                      (struct sockaddr *)&to, tolen);
        if (sent != len) {
-               char to_str[INET_ADDRSTRLEN];
-               pim_inet4_dump("<to?>", to.sin_addr, to_str, sizeof(to_str));
                if (sent < 0) {
                        zlog_warn(
-                               "%s: sendto() failure to %s,%d: fd=%d len=%d: errno=%d: %s",
-                               __func__, to_str, ntohs(to.sin_port),
-                               ss->sock_fd, len, errno, safe_strerror(errno));
+                               "%s: sendto() failure to %pSUp,fd=%d len=%d: errno=%d: %s",
+                               __func__, &to, ss->sock_fd, len, errno,
+                               safe_strerror(errno));
                } else {
                        zlog_warn(
-                               "%s: sendto() partial to %s,%d: fd=%d len=%d: sent=%d",
-                               __func__, to_str, ntohs(to.sin_port),
-                               ss->sock_fd, len, sent);
+                               "%s: sendto() partial to %pSUp, fd=%d len=%d: sent=%d",
+                               __func__, &to, ss->sock_fd, len, sent);
                }
        }
 }
@@ -285,14 +288,12 @@ static int ssmpingd_read_msg(struct ssmpingd_sock *ss)
 
        buf[0] = PIM_SSMPINGD_REPLY;
 
-       struct sockaddr_in *from_addr = (struct sockaddr_in *)&from;
-
        /* unicast reply */
-       ssmpingd_sendto(ss, buf, len, *from_addr);
+       ssmpingd_sendto(ss, buf, len, from);
 
        /* multicast reply */
-       from_addr->sin_addr = ss->pim->ssmpingd_group_addr;
-       ssmpingd_sendto(ss, buf, len, *from_addr);
+       memcpy(&from, &ss->pim->ssmpingd_group_addr, sizeof(pim_addr));
+       ssmpingd_sendto(ss, buf, len, from);
 
        return 0;
 }
@@ -316,7 +317,7 @@ static void ssmpingd_read_on(struct ssmpingd_sock *ss)
 }
 
 static struct ssmpingd_sock *ssmpingd_new(struct pim_instance *pim,
-                                         struct in_addr source_addr)
+                                         pim_addr source_addr)
 {
        struct ssmpingd_sock *ss;
        int sock_fd;
@@ -329,11 +330,8 @@ static struct ssmpingd_sock *ssmpingd_new(struct pim_instance *pim,
        sock_fd =
                ssmpingd_socket(source_addr, /* port: */ 4321, /* mTTL: */ 64);
        if (sock_fd < 0) {
-               char source_str[INET_ADDRSTRLEN];
-               pim_inet4_dump("<src?>", source_addr, source_str,
-                              sizeof(source_str));
-               zlog_warn("%s: ssmpingd_socket() failure for source %s",
-                         __func__, source_str);
+               zlog_warn("%s: ssmpingd_socket() failure for source %pI4",
+                         __func__, &source_addr);
                return 0;
        }
 
@@ -353,7 +351,7 @@ static struct ssmpingd_sock *ssmpingd_new(struct pim_instance *pim,
        return ss;
 }
 
-int pim_ssmpingd_start(struct pim_instance *pim, struct in_addr source_addr)
+int pim_ssmpingd_start(struct pim_instance *pim, pim_addr source_addr)
 {
        struct ssmpingd_sock *ss;
 
@@ -364,47 +362,33 @@ int pim_ssmpingd_start(struct pim_instance *pim, struct in_addr source_addr)
        }
 
        {
-               char source_str[INET_ADDRSTRLEN];
-               pim_inet4_dump("<src?>", source_addr, source_str,
-                              sizeof(source_str));
-               zlog_info("%s: starting ssmpingd for source %s", __func__,
-                         source_str);
+               zlog_info("%s: starting ssmpingd for source %pPAs", __func__,
+                         &source_addr);
        }
 
        ss = ssmpingd_new(pim, source_addr);
        if (!ss) {
-               char source_str[INET_ADDRSTRLEN];
-               pim_inet4_dump("<src?>", source_addr, source_str,
-                              sizeof(source_str));
-               zlog_warn("%s: ssmpingd_new() failure for source %s", __func__,
-                         source_str);
+               zlog_warn("%s: ssmpingd_new() failure for source %pPAs",
+                         __func__, &source_addr);
                return -1;
        }
 
        return 0;
 }
 
-int pim_ssmpingd_stop(struct pim_instance *pim, struct in_addr source_addr)
+int pim_ssmpingd_stop(struct pim_instance *pim, pim_addr source_addr)
 {
        struct ssmpingd_sock *ss;
 
        ss = ssmpingd_find(pim, source_addr);
        if (!ss) {
-               char source_str[INET_ADDRSTRLEN];
-               pim_inet4_dump("<src?>", source_addr, source_str,
-                              sizeof(source_str));
-               zlog_warn("%s: could not find ssmpingd for source %s", __func__,
-                         source_str);
+               zlog_warn("%s: could not find ssmpingd for source %pPAs",
+                         __func__, &source_addr);
                return -1;
        }
 
-       {
-               char source_str[INET_ADDRSTRLEN];
-               pim_inet4_dump("<src?>", source_addr, source_str,
-                              sizeof(source_str));
-               zlog_info("%s: stopping ssmpingd for source %s", __func__,
-                         source_str);
-       }
+       zlog_info("%s: stopping ssmpingd for source %pPAs", __func__,
+                 &source_addr);
 
        ssmpingd_delete(ss);
 
index fafdd7ade128b1c555660f0793a8c4f19f21b7c5..c4376bd0e4c6ca947bac0af68a445cb3b0cb7bfb 100644 (file)
@@ -31,14 +31,14 @@ struct ssmpingd_sock {
 
        int sock_fd;                /* socket */
        struct thread *t_sock_read; /* thread for reading socket */
-       struct in_addr source_addr; /* source address */
+       pim_addr source_addr;       /* source address */
        int64_t creation;          /* timestamp of socket creation */
        int64_t requests;          /* counter */
 };
 
 void pim_ssmpingd_init(struct pim_instance *pim);
 void pim_ssmpingd_destroy(struct pim_instance *pim);
-int pim_ssmpingd_start(struct pim_instance *pim, struct in_addr source_addr);
-int pim_ssmpingd_stop(struct pim_instance *pim, struct in_addr source_addr);
+int pim_ssmpingd_start(struct pim_instance *pim, pim_addr source_addr);
+int pim_ssmpingd_stop(struct pim_instance *pim, pim_addr source_addr);
 
 #endif /* PIM_SSMPINGD_H */
index 6de3a04b66035927abf93ddaa3fb4c3ac43c5084..79deceee15b9328c2c11c070539f045f80b7f21a 100644 (file)
@@ -259,10 +259,8 @@ int pim_global_config_write_worker(struct pim_instance *pim, struct vty *vty)
                struct ssmpingd_sock *ss;
                ++writes;
                for (ALL_LIST_ELEMENTS_RO(pim->ssmpingd_list, node, ss)) {
-                       char source_str[INET_ADDRSTRLEN];
-                       pim_inet4_dump("<src?>", ss->source_addr, source_str,
-                                      sizeof(source_str));
-                       vty_out(vty, "%sip ssmpingd %s\n", spaces, source_str);
+                       vty_out(vty, "%sip ssmpingd %pI4\n", spaces,
+                               &ss->source_addr);
                        ++writes;
                }
        }