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 dd92ff1b28..406183db86 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;  }  | 
