pimd: Bind pim sockets to interface they are associated with

When pim is receiving packets, each interface's fd is receiving
packets for all interfaces.  Modify the code to bind the
pim interface sockets to the interface they were created for.

Signed-off-by: Donald Sharp <sharpd@cumulusnetworks.com>
This commit is contained in:
Donald Sharp 2016-06-28 21:50:49 -04:00
parent bab3cf0a8e
commit 61ea3951a2
4 changed files with 33 additions and 4 deletions

View File

@ -54,7 +54,7 @@ static int igmp_sock_open(struct in_addr ifaddr, int ifindex, uint32_t pim_optio
int join = 0; int join = 0;
struct in_addr group; struct in_addr group;
fd = pim_socket_mcast(IPPROTO_IGMP, ifaddr, 1 /* loop=true */); fd = pim_socket_mcast(IPPROTO_IGMP, ifaddr, ifindex, 1 /* loop=true */);
if (fd < 0) if (fd < 0)
return -1; return -1;

View File

@ -389,7 +389,7 @@ static int pim_sock_open(struct in_addr ifaddr, int ifindex)
{ {
int fd; int fd;
fd = pim_socket_mcast(IPPROTO_PIM, ifaddr, 0 /* loop=false */); fd = pim_socket_mcast(IPPROTO_PIM, ifaddr, ifindex, 0 /* loop=false */);
if (fd < 0) if (fd < 0)
return -1; return -1;

View File

@ -34,6 +34,7 @@
#include "log.h" #include "log.h"
#include "privs.h" #include "privs.h"
#include "if.h" #include "if.h"
#include "vrf.h"
#include "pimd.h" #include "pimd.h"
#include "pim_mroute.h" #include "pim_mroute.h"
@ -67,7 +68,7 @@ int pim_socket_raw(int protocol)
return fd; return fd;
} }
int pim_socket_mcast(int protocol, struct in_addr ifaddr, int loop) int pim_socket_mcast(int protocol, struct in_addr ifaddr, int ifindex, int loop)
{ {
int fd; int fd;
@ -78,6 +79,33 @@ int pim_socket_mcast(int protocol, struct in_addr ifaddr, int loop)
return PIM_SOCK_ERR_SOCKET; return PIM_SOCK_ERR_SOCKET;
} }
if (protocol == IPPROTO_PIM)
{
int ret;
struct interface *ifp = NULL;
ifp = if_lookup_by_index_vrf (ifindex, VRF_DEFAULT);
if (pimd_privs.change (ZPRIVS_RAISE))
zlog_err ("%s: could not raise privs, %s",
__PRETTY_FUNCTION__, safe_strerror (errno));
ret = setsockopt (fd, SOL_SOCKET,
SO_BINDTODEVICE, ifp->name, strlen (ifp->name));
if (pimd_privs.change (ZPRIVS_LOWER))
zlog_err ("%s: could not lower privs, %s",
__PRETTY_FUNCTION__, safe_strerror (errno));
if (ret)
{
zlog_warn("Could not set fd: %d for interface: %s to device",
fd, ifp->name);
return PIM_SOCK_ERR_BIND;
}
}
/* Needed to obtain destination address from recvmsg() */ /* Needed to obtain destination address from recvmsg() */
{ {
#if defined(HAVE_IP_PKTINFO) #if defined(HAVE_IP_PKTINFO)

View File

@ -36,9 +36,10 @@
#define PIM_SOCK_ERR_NONBLOCK_GETFL (-8) /* Get O_NONBLOCK */ #define PIM_SOCK_ERR_NONBLOCK_GETFL (-8) /* Get O_NONBLOCK */
#define PIM_SOCK_ERR_NONBLOCK_SETFL (-9) /* Set O_NONBLOCK */ #define PIM_SOCK_ERR_NONBLOCK_SETFL (-9) /* Set O_NONBLOCK */
#define PIM_SOCK_ERR_NAME (-10) /* Socket name (getsockname) */ #define PIM_SOCK_ERR_NAME (-10) /* Socket name (getsockname) */
#define PIM_SOCK_ERR_BIND (-11) /* Can't bind to interface */
int pim_socket_raw(int protocol); int pim_socket_raw(int protocol);
int pim_socket_mcast(int protocol, struct in_addr ifaddr, int loop); int pim_socket_mcast(int protocol, struct in_addr ifaddr, int ifindex, int loop);
int pim_socket_join(int fd, struct in_addr group, int pim_socket_join(int fd, struct in_addr group,
struct in_addr ifaddr, int ifindex); struct in_addr ifaddr, int ifindex);
int pim_socket_join_source(int fd, int ifindex, int pim_socket_join_source(int fd, int ifindex,