diff --git a/pimd/pim_cmd.c b/pimd/pim_cmd.c index 30574bcaa7..8906caf00f 100644 --- a/pimd/pim_cmd.c +++ b/pimd/pim_cmd.c @@ -455,8 +455,7 @@ static void pim_show_membership(struct pim_instance *pim, struct vty *vty, json_object_free(json); } -static void pim_print_ifp_flags(struct vty *vty, struct interface *ifp, - int mloop) +static void pim_print_ifp_flags(struct vty *vty, struct interface *ifp) { vty_out(vty, "Flags\n"); vty_out(vty, "-----\n"); @@ -469,7 +468,6 @@ static void pim_print_ifp_flags(struct vty *vty, struct interface *ifp, vty_out(vty, "Interface Index : %d\n", ifp->ifindex); vty_out(vty, "Multicast : %s\n", if_is_multicast(ifp) ? "yes" : "no"); - vty_out(vty, "Multicast Loop : %d\n", mloop); vty_out(vty, "Promiscuous : %s\n", (ifp->flags & IFF_PROMISC) ? "yes" : "no"); vty_out(vty, "\n"); @@ -576,7 +574,6 @@ static void igmp_show_interfaces_single(struct pim_instance *pim, char other_hhmmss[10]; int found_ifname = 0; int sqi; - int mloop = 0; long gmi_msec; /* Group Membership Interval */ long lmqt_msec; long ohpi_msec; @@ -639,11 +636,6 @@ static void igmp_show_interfaces_single(struct pim_instance *pim, qri_msec = pim_ifp->gm_query_max_response_time_dsec * 100; - if (pim_ifp->pim_sock_fd >= 0) - mloop = pim_socket_mcastloop_get( - pim_ifp->pim_sock_fd); - else - mloop = 0; lmqc = pim_ifp->gm_last_member_query_count; if (uj) { @@ -776,7 +768,7 @@ static void igmp_show_interfaces_single(struct pim_instance *pim, vty_out(vty, "\n"); vty_out(vty, "\n"); - pim_print_ifp_flags(vty, ifp, mloop); + pim_print_ifp_flags(vty, ifp); } } } @@ -903,7 +895,6 @@ static void pim_show_interfaces_single(struct pim_instance *pim, char src_str[INET_ADDRSTRLEN]; char stat_uptime[10]; char uptime[10]; - int mloop = 0; int found_ifname = 0; int print_header; json_object *json = NULL; @@ -945,10 +936,6 @@ static void pim_show_interfaces_single(struct pim_instance *pim, pim_ifp->pim_hello_period); pim_time_uptime(stat_uptime, sizeof(stat_uptime), now - pim_ifp->pim_ifstat_start); - if (pim_ifp->pim_sock_fd >= 0) - mloop = pim_socket_mcastloop_get(pim_ifp->pim_sock_fd); - else - mloop = 0; if (uj) { char pbuf[PREFIX2STR_BUFFER]; @@ -1096,8 +1083,6 @@ static void pim_show_interfaces_single(struct pim_instance *pim, pim_ifp->pim_ifstat_hello_sendfail); json_object_int_add(json_row, "helloGenerationId", pim_ifp->pim_generation_id); - json_object_int_add(json_row, "flagMulticastLoop", - mloop); json_object_int_add( json_row, "effectivePropagationDelay", @@ -1250,7 +1235,7 @@ static void pim_show_interfaces_single(struct pim_instance *pim, vty_out(vty, "\n"); vty_out(vty, "\n"); - pim_print_ifp_flags(vty, ifp, mloop); + pim_print_ifp_flags(vty, ifp); vty_out(vty, "Join Prune Interval\n"); vty_out(vty, "-------------------\n"); diff --git a/pimd/pim_igmp.c b/pimd/pim_igmp.c index 289e8e457d..592cd7ec45 100644 --- a/pimd/pim_igmp.c +++ b/pimd/pim_igmp.c @@ -1185,8 +1185,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; diff --git a/pimd/pim_pim.c b/pimd/pim_pim.c index 5cc0d63e31..d3edc5d0fe 100644 --- a/pimd/pim_pim.c +++ b/pimd/pim_pim.c @@ -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]; diff --git a/pimd/pim_sock.c b/pimd/pim_sock.c index 05b0f92a4b..92e2d18451 100644 --- a/pimd/pim_sock.c +++ b/pimd/pim_sock.c @@ -34,22 +34,27 @@ #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,29 +91,102 @@ void pim_socket_ip_hdr(int fd) int pim_socket_bind(int fd, struct interface *ifp) { int ret = 0; + #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, +#if PIM_IPV == 4 +static inline int pim_setsockopt(int protocol, int fd, struct interface *ifp) +{ + int one = 1; + int ttl = 1; + +#if defined(HAVE_IP_PKTINFO) + /* 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 */ + 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, + "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)*/ + 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: %m", + fd); + close(fd); + return PIM_SOCK_ERR_RA; + } + } + + 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_if(fd, PIMADDR_ANY, ifp->ifindex)) { + zlog_warn( + "Could not set Outgoing Interface Option on socket fd=%d: %m", + fd); + close(fd); + return PIM_SOCK_ERR_IFACE; + } + + 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); + + 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: %m", + fd); + close(fd); + return PIM_SOCK_ERR_IFACE; + } + + return 0; +} +#endif + +int pim_socket_mcast(int protocol, pim_addr ifaddr, struct interface *ifp, uint8_t loop) { - 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 ret; fd = pim_socket_raw(protocol); if (fd < 0) { @@ -111,217 +195,148 @@ int pim_socket_mcast(int protocol, struct in_addr ifaddr, struct interface *ifp, return PIM_SOCK_ERR_SOCKET; } -#ifdef SO_BINDTODEVICE - int ret; - + /* 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); + 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)); - } -#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)); - } -#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; -#endif + 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; } - - /* 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)); - 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_ipv4_multicast_loop(fd, loop)) { + /* leftover common sockopts */ + if (setsockopt_multicast_loop(fd, loop)) { 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 %s Multicast Loopback Option on socket fd=%d: %m", + loop ? "enable" : "disable", fd); close(fd); return PIM_SOCK_ERR_LOOP; } - 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 - - if (setsockopt(fd, IPPROTO_IP, IP_MULTICAST_IF, (void *)&mreq, - sizeof(mreq))) { - zlog_warn( - "Could not set Outgoing Interface Option on socket fd=%d: errno=%d: %s", - fd, errno, safe_strerror(errno)); - 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); - - { - long flags; - - 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; - } - - 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; - } - } - /* 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)); - } + 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; + struct ipv6_mreq opt; + + memcpy(&opt.ipv6mr_multiaddr, &group, 16); + opt.ipv6mr_interface = ifindex; + ret = setsockopt(fd, IPPROTO_IPV6, IPV6_JOIN_GROUP, &opt, sizeof(opt)); #endif - opt.imr_multiaddr = group; - -#ifdef HAVE_STRUCT_IP_MREQN_IMR_IFINDEX - opt.imr_address = ifaddr; - opt.imr_ifindex = ifindex; -#else - opt.imr_interface = ifaddr; -#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), ""); - if (!inet_ntop(AF_INET, &ifaddr, ifaddr_str, - sizeof(ifaddr_str))) - snprintf(ifaddr_str, sizeof(ifaddr_str), ""); - 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), ""); - if (!inet_ntop(AF_INET, &ifaddr, ifaddr_str, - sizeof(ifaddr_str))) - snprintf(ifaddr_str, sizeof(ifaddr_str), ""); - + 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; + + 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); + socklen_t to_len = sizeof(*to); - memset(&si, 0, sizeof(si)); - to->sin_family = AF_INET; - - pim_socket_getsockname(fd, (struct sockaddr *)&si, &si_len); - - 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,66 +372,11 @@ 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 */ } -int pim_socket_mcastloop_get(int fd) -{ - int loop; - socklen_t loop_len = sizeof(loop); - - if (getsockopt(fd, IPPROTO_IP, IP_MULTICAST_LOOP, &loop, &loop_len)) { - int e = errno; - zlog_warn( - "Could not get Multicast Loopback Option on socket fd=%d: errno=%d: %s", - fd, errno, safe_strerror(errno)); - errno = e; - return PIM_SOCK_ERR_LOOP; - } - - return loop; -} - int pim_socket_getsockname(int fd, struct sockaddr *name, socklen_t *namelen) { if (getsockname(fd, name, namelen)) { diff --git a/pimd/pim_sock.h b/pimd/pim_sock.h index 08b0099321..97cbda0c10 100644 --- a/pimd/pim_sock.h +++ b/pimd/pim_sock.h @@ -38,16 +38,14 @@ 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_recvfromto(int fd, uint8_t *buf, size_t len, - struct sockaddr_in *from, socklen_t *fromlen, - struct sockaddr_in *to, socklen_t *tolen, - ifindex_t *ifindex); +int pim_socket_join(int fd, pim_addr group, pim_addr ifaddr, ifindex_t ifindex); -int pim_socket_mcastloop_get(int fd); +int pim_socket_recvfromto(int fd, uint8_t *buf, size_t len, + 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); diff --git a/pimd/pim_ssmpingd.c b/pimd/pim_ssmpingd.c index 596b06cb38..e43b46604c 100644 --- a/pimd/pim_ssmpingd.c +++ b/pimd/pim_ssmpingd.c @@ -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("", 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("", ss->source_addr, source_str, - sizeof(source_str)); - pim_inet4_dump("", from.sin_addr, from_str, - sizeof(from_str)); - pim_inet4_dump("", 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 : "", 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("", ss->source_addr, source_str, - sizeof(source_str)); - pim_inet4_dump("", from.sin_addr, from_str, - sizeof(from_str)); - pim_inet4_dump("", 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 : "", - 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 : "", + 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; }