diff options
Diffstat (limited to 'pimd/pim_ssmpingd.c')
-rw-r--r-- | pimd/pim_ssmpingd.c | 685 |
1 files changed, 353 insertions, 332 deletions
diff --git a/pimd/pim_ssmpingd.c b/pimd/pim_ssmpingd.c index dd92ff1b2..406183db8 100644 --- a/pimd/pim_ssmpingd.c +++ b/pimd/pim_ssmpingd.c @@ -30,402 +30,423 @@ #include "pim_time.h" #include "pim_sock.h" -static const char * const PIM_SSMPINGD_REPLY_GROUP = "232.43.211.234"; +static const char *const PIM_SSMPINGD_REPLY_GROUP = "232.43.211.234"; -enum { - PIM_SSMPINGD_REQUEST = 'Q', - PIM_SSMPINGD_REPLY = 'A' -}; +enum { PIM_SSMPINGD_REQUEST = 'Q', PIM_SSMPINGD_REPLY = 'A' }; static void ssmpingd_read_on(struct ssmpingd_sock *ss); void pim_ssmpingd_init() { - int result; + int result; - zassert(!qpim_ssmpingd_list); + zassert(!qpim_ssmpingd_list); - result = inet_pton(AF_INET, PIM_SSMPINGD_REPLY_GROUP, &qpim_ssmpingd_group_addr); - - zassert(result > 0); + result = inet_pton(AF_INET, PIM_SSMPINGD_REPLY_GROUP, + &qpim_ssmpingd_group_addr); + + zassert(result > 0); } void pim_ssmpingd_destroy() { - if (qpim_ssmpingd_list) { - list_free(qpim_ssmpingd_list); - qpim_ssmpingd_list = 0; - } + if (qpim_ssmpingd_list) { + list_free(qpim_ssmpingd_list); + qpim_ssmpingd_list = 0; + } } static struct ssmpingd_sock *ssmpingd_find(struct in_addr source_addr) { - struct listnode *node; - struct ssmpingd_sock *ss; + struct listnode *node; + struct ssmpingd_sock *ss; - if (!qpim_ssmpingd_list) - return 0; + if (!qpim_ssmpingd_list) + return 0; - for (ALL_LIST_ELEMENTS_RO(qpim_ssmpingd_list, node, ss)) - if (source_addr.s_addr == ss->source_addr.s_addr) - return ss; + for (ALL_LIST_ELEMENTS_RO(qpim_ssmpingd_list, node, ss)) + if (source_addr.s_addr == ss->source_addr.s_addr) + return ss; - return 0; + return 0; } static void ssmpingd_free(struct ssmpingd_sock *ss) { - XFREE(MTYPE_PIM_SSMPINGD, ss); + XFREE(MTYPE_PIM_SSMPINGD, ss); } static int ssmpingd_socket(struct in_addr addr, int port, int mttl) { - struct sockaddr_in sockaddr; - int fd; - - fd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); - if (fd < 0) { - zlog_err("%s: could not create socket: errno=%d: %s", - __PRETTY_FUNCTION__, errno, safe_strerror(errno)); - return -1; - } - - 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)); - zlog_warn("%s: bind(fd=%d,addr=%s,port=%d,len=%zu) failure: errno=%d: %s", - __PRETTY_FUNCTION__, - fd, addr_str, port, sizeof(sockaddr), - errno, safe_strerror(errno)); - close(fd); - return -1; - } - - /* Needed to obtain destination address from recvmsg() */ - { + struct sockaddr_in sockaddr; + int fd; + + fd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); + if (fd < 0) { + zlog_err("%s: could not create socket: errno=%d: %s", + __PRETTY_FUNCTION__, errno, safe_strerror(errno)); + return -1; + } + + 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)); + zlog_warn( + "%s: bind(fd=%d,addr=%s,port=%d,len=%zu) failure: errno=%d: %s", + __PRETTY_FUNCTION__, fd, addr_str, port, + sizeof(sockaddr), errno, safe_strerror(errno)); + close(fd); + 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", - __PRETTY_FUNCTION__, fd, errno, safe_strerror(errno)); - } + /* 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", + __PRETTY_FUNCTION__, 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", - __PRETTY_FUNCTION__, fd, errno, safe_strerror(errno)); - } + /* 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", + __PRETTY_FUNCTION__, fd, errno, + safe_strerror(errno)); + } #else - zlog_err("%s %s: missing IP_PKTINFO and IP_RECVDSTADDR: unable to get dst addr from recvmsg()", - __FILE__, __PRETTY_FUNCTION__); - close(fd); - return -1; + zlog_err( + "%s %s: missing IP_PKTINFO and IP_RECVDSTADDR: unable to get dst addr from recvmsg()", + __FILE__, __PRETTY_FUNCTION__); + 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", - __PRETTY_FUNCTION__, fd, errno, safe_strerror(errno)); - close(fd); - return -1; - } - } - - if (setsockopt(fd, IPPROTO_IP, IP_MULTICAST_TTL, - (void *) &mttl, sizeof(mttl))) { - zlog_warn("%s: could not set multicast TTL=%d on socket fd=%d: errno=%d: %s", - __PRETTY_FUNCTION__, mttl, fd, errno, safe_strerror(errno)); - close(fd); - return -1; - } - - if (setsockopt_ipv4_multicast_loop (fd, 0)) { - zlog_warn("%s: could not disable Multicast Loopback Option on socket fd=%d: errno=%d: %s", - __PRETTY_FUNCTION__, - fd, errno, safe_strerror(errno)); - close(fd); - return PIM_SOCK_ERR_LOOP; - } - - 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", - __PRETTY_FUNCTION__, fd, errno, safe_strerror(errno)); - close(fd); - return -1; - } - - { - 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", - __PRETTY_FUNCTION__, fd, errno, safe_strerror(errno)); - close(fd); - return -1; - } - - 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", - __PRETTY_FUNCTION__, fd, errno, safe_strerror(errno)); - close(fd); - return -1; - } - } - - return fd; + } + + { + 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", + __PRETTY_FUNCTION__, fd, errno, + safe_strerror(errno)); + close(fd); + return -1; + } + } + + if (setsockopt(fd, IPPROTO_IP, IP_MULTICAST_TTL, (void *)&mttl, + sizeof(mttl))) { + zlog_warn( + "%s: could not set multicast TTL=%d on socket fd=%d: errno=%d: %s", + __PRETTY_FUNCTION__, mttl, fd, errno, + safe_strerror(errno)); + close(fd); + return -1; + } + + if (setsockopt_ipv4_multicast_loop(fd, 0)) { + zlog_warn( + "%s: could not disable Multicast Loopback Option on socket fd=%d: errno=%d: %s", + __PRETTY_FUNCTION__, fd, errno, safe_strerror(errno)); + close(fd); + return PIM_SOCK_ERR_LOOP; + } + + 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", + __PRETTY_FUNCTION__, fd, errno, safe_strerror(errno)); + close(fd); + return -1; + } + + { + 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", + __PRETTY_FUNCTION__, fd, errno, + safe_strerror(errno)); + close(fd); + return -1; + } + + 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", + __PRETTY_FUNCTION__, fd, errno, + safe_strerror(errno)); + close(fd); + return -1; + } + } + + return fd; } static void ssmpingd_delete(struct ssmpingd_sock *ss) { - zassert(ss); - zassert(qpim_ssmpingd_list); - - 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", - __PRETTY_FUNCTION__, - ss->sock_fd, source_str, errno, safe_strerror(errno)); - /* warning only */ - } - - listnode_delete(qpim_ssmpingd_list, ss); - ssmpingd_free(ss); + zassert(ss); + zassert(qpim_ssmpingd_list); + + 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", + __PRETTY_FUNCTION__, ss->sock_fd, source_str, errno, + safe_strerror(errno)); + /* warning only */ + } + + listnode_delete(qpim_ssmpingd_list, ss); + ssmpingd_free(ss); } -static void ssmpingd_sendto(struct ssmpingd_sock *ss, - const uint8_t *buf, - int len, - struct sockaddr_in to) +static void ssmpingd_sendto(struct ssmpingd_sock *ss, const uint8_t *buf, + int len, struct sockaddr_in to) { - socklen_t tolen = sizeof(to); - int sent; - - 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", - __PRETTY_FUNCTION__, - to_str, ntohs(to.sin_port), ss->sock_fd, len, - errno, safe_strerror(errno)); - } - else { - zlog_warn("%s: sendto() partial to %s,%d: fd=%d len=%d: sent=%d", - __PRETTY_FUNCTION__, - to_str, ntohs(to.sin_port), ss->sock_fd, - len, sent); - } - } + socklen_t tolen = sizeof(to); + int sent; + + 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", + __PRETTY_FUNCTION__, to_str, ntohs(to.sin_port), + ss->sock_fd, len, errno, safe_strerror(errno)); + } else { + zlog_warn( + "%s: sendto() partial to %s,%d: fd=%d len=%d: sent=%d", + __PRETTY_FUNCTION__, to_str, ntohs(to.sin_port), + ss->sock_fd, len, sent); + } + } } static int ssmpingd_read_msg(struct ssmpingd_sock *ss) { - struct interface *ifp; - struct sockaddr_in from; - struct sockaddr_in to; - socklen_t fromlen = sizeof(from); - socklen_t tolen = sizeof(to); - ifindex_t ifindex = -1; - uint8_t buf[1000]; - int len; - - ++ss->requests; - - 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", - __PRETTY_FUNCTION__, source_str, ss->sock_fd, errno, safe_strerror(errno)); - return -1; - } - - ifp = if_lookup_by_index(ifindex, VRF_DEFAULT); - - 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", - __PRETTY_FUNCTION__, - buf[0], - from_str, ntohs(from.sin_port), - to_str, ntohs(to.sin_port), - ifp ? ifp->name : "<iface?>", - ifindex, ss->sock_fd, - source_str); - 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", - __PRETTY_FUNCTION__, - from_str, ntohs(from.sin_port), - to_str, ntohs(to.sin_port), - ifp ? ifp->name : "<iface?>", - ifindex, ss->sock_fd, - source_str); - } - - buf[0] = PIM_SSMPINGD_REPLY; - - /* unicast reply */ - ssmpingd_sendto(ss, buf, len, from); - - /* multicast reply */ - from.sin_addr = qpim_ssmpingd_group_addr; - ssmpingd_sendto(ss, buf, len, from); - - return 0; + struct interface *ifp; + struct sockaddr_in from; + struct sockaddr_in to; + socklen_t fromlen = sizeof(from); + socklen_t tolen = sizeof(to); + ifindex_t ifindex = -1; + uint8_t buf[1000]; + int len; + + ++ss->requests; + + 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", + __PRETTY_FUNCTION__, source_str, ss->sock_fd, errno, + safe_strerror(errno)); + return -1; + } + + ifp = if_lookup_by_index(ifindex, VRF_DEFAULT); + + 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", + __PRETTY_FUNCTION__, buf[0], from_str, + ntohs(from.sin_port), to_str, ntohs(to.sin_port), + ifp ? ifp->name : "<iface?>", ifindex, ss->sock_fd, + source_str); + 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", + __PRETTY_FUNCTION__, from_str, ntohs(from.sin_port), + to_str, ntohs(to.sin_port), + ifp ? ifp->name : "<iface?>", ifindex, ss->sock_fd, + source_str); + } + + buf[0] = PIM_SSMPINGD_REPLY; + + /* unicast reply */ + ssmpingd_sendto(ss, buf, len, from); + + /* multicast reply */ + from.sin_addr = qpim_ssmpingd_group_addr; + ssmpingd_sendto(ss, buf, len, from); + + return 0; } static int ssmpingd_sock_read(struct thread *t) { - struct ssmpingd_sock *ss; - int result; + struct ssmpingd_sock *ss; + int result; - ss = THREAD_ARG(t); + ss = THREAD_ARG(t); - result = ssmpingd_read_msg(ss); + result = ssmpingd_read_msg(ss); - /* Keep reading */ - ssmpingd_read_on(ss); + /* Keep reading */ + ssmpingd_read_on(ss); - return result; + return result; } static void ssmpingd_read_on(struct ssmpingd_sock *ss) { - thread_add_read(master, ssmpingd_sock_read, ss, ss->sock_fd, - &ss->t_sock_read); + thread_add_read(master, ssmpingd_sock_read, ss, ss->sock_fd, + &ss->t_sock_read); } static struct ssmpingd_sock *ssmpingd_new(struct in_addr source_addr) { - struct ssmpingd_sock *ss; - int sock_fd; - - if (!qpim_ssmpingd_list) { - qpim_ssmpingd_list = list_new(); - if (!qpim_ssmpingd_list) { - zlog_err("%s %s: failure: qpim_ssmpingd_list=list_new()", - __FILE__, __PRETTY_FUNCTION__); - return 0; - } - qpim_ssmpingd_list->del = (void (*)(void *)) ssmpingd_free; - } - - 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", - __PRETTY_FUNCTION__, source_str); - return 0; - } - - ss = XCALLOC(MTYPE_PIM_SSMPINGD, sizeof(*ss)); - if (!ss) { - char source_str[INET_ADDRSTRLEN]; - pim_inet4_dump("<src?>", source_addr, source_str, sizeof(source_str)); - zlog_err("%s: XCALLOC(%zu) failure for ssmpingd source %s", - __PRETTY_FUNCTION__, - sizeof(*ss), source_str); - close(sock_fd); - return 0; - } - - ss->sock_fd = sock_fd; - ss->t_sock_read = NULL; - ss->source_addr = source_addr; - ss->creation = pim_time_monotonic_sec(); - ss->requests = 0; - - listnode_add(qpim_ssmpingd_list, ss); - - ssmpingd_read_on(ss); - - return ss; + struct ssmpingd_sock *ss; + int sock_fd; + + if (!qpim_ssmpingd_list) { + qpim_ssmpingd_list = list_new(); + if (!qpim_ssmpingd_list) { + zlog_err( + "%s %s: failure: qpim_ssmpingd_list=list_new()", + __FILE__, __PRETTY_FUNCTION__); + return 0; + } + qpim_ssmpingd_list->del = (void (*)(void *))ssmpingd_free; + } + + 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", + __PRETTY_FUNCTION__, source_str); + return 0; + } + + ss = XCALLOC(MTYPE_PIM_SSMPINGD, sizeof(*ss)); + if (!ss) { + char source_str[INET_ADDRSTRLEN]; + pim_inet4_dump("<src?>", source_addr, source_str, + sizeof(source_str)); + zlog_err("%s: XCALLOC(%zu) failure for ssmpingd source %s", + __PRETTY_FUNCTION__, sizeof(*ss), source_str); + close(sock_fd); + return 0; + } + + ss->sock_fd = sock_fd; + ss->t_sock_read = NULL; + ss->source_addr = source_addr; + ss->creation = pim_time_monotonic_sec(); + ss->requests = 0; + + listnode_add(qpim_ssmpingd_list, ss); + + ssmpingd_read_on(ss); + + return ss; } int pim_ssmpingd_start(struct in_addr source_addr) { - struct ssmpingd_sock *ss; - - ss = ssmpingd_find(source_addr); - if (ss) { - /* silently ignore request to recreate entry */ - return 0; - } - - { - char source_str[INET_ADDRSTRLEN]; - pim_inet4_dump("<src?>", source_addr, source_str, sizeof(source_str)); - zlog_info("%s: starting ssmpingd for source %s", - __PRETTY_FUNCTION__, source_str); - } - - ss = ssmpingd_new(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", - __PRETTY_FUNCTION__, source_str); - return -1; - } - - return 0; + struct ssmpingd_sock *ss; + + ss = ssmpingd_find(source_addr); + if (ss) { + /* silently ignore request to recreate entry */ + return 0; + } + + { + char source_str[INET_ADDRSTRLEN]; + pim_inet4_dump("<src?>", source_addr, source_str, + sizeof(source_str)); + zlog_info("%s: starting ssmpingd for source %s", + __PRETTY_FUNCTION__, source_str); + } + + ss = ssmpingd_new(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", + __PRETTY_FUNCTION__, source_str); + return -1; + } + + return 0; } int pim_ssmpingd_stop(struct in_addr source_addr) { - struct ssmpingd_sock *ss; - - ss = ssmpingd_find(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", - __PRETTY_FUNCTION__, source_str); - 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", - __PRETTY_FUNCTION__, source_str); - } - - ssmpingd_delete(ss); - - return 0; + struct ssmpingd_sock *ss; + + ss = ssmpingd_find(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", + __PRETTY_FUNCTION__, source_str); + 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", + __PRETTY_FUNCTION__, source_str); + } + + ssmpingd_delete(ss); + + return 0; } |