Merge pull request #10399 from g-balaji1/pimv6-sock

pim6d: PIMv6 socket related changes
This commit is contained in:
Donald Sharp 2022-03-13 10:03:45 -04:00 committed by GitHub
commit 6ea4244514
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 239 additions and 321 deletions

View File

@ -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");

View File

@ -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;

View 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];

View File

@ -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",
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)) {
/* leftover common sockopts */
if (setsockopt_multicast_loop(fd, loop)) {
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)) {
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), "<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;
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)) {

View File

@ -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);

View 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;
}