summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDonald Sharp <sharpd@cumulusnetworks.com>2016-06-29 03:50:49 +0200
committerDonald Sharp <sharpd@cumulusnetworks.com>2016-06-29 03:50:49 +0200
commit61ea3951a2ecd0d439cb772d566f43e544c8ba48 (patch)
tree1662320fd1967d4f57ca5eb1daeaa44724e204ac
parentMerge branch 'cmaster-next' of ssh://stash.cumulusnetworks.com:7999/quag/quag... (diff)
downloadfrr-61ea3951a2ecd0d439cb772d566f43e544c8ba48.tar.xz
frr-61ea3951a2ecd0d439cb772d566f43e544c8ba48.zip
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>
-rw-r--r--pimd/pim_igmp.c2
-rw-r--r--pimd/pim_pim.c2
-rw-r--r--pimd/pim_sock.c30
-rw-r--r--pimd/pim_sock.h3
4 files changed, 33 insertions, 4 deletions
diff --git a/pimd/pim_igmp.c b/pimd/pim_igmp.c
index 43fac9a16..176470e20 100644
--- a/pimd/pim_igmp.c
+++ b/pimd/pim_igmp.c
@@ -54,7 +54,7 @@ static int igmp_sock_open(struct in_addr ifaddr, int ifindex, uint32_t pim_optio
int join = 0;
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)
return -1;
diff --git a/pimd/pim_pim.c b/pimd/pim_pim.c
index a3136b61b..60507970d 100644
--- a/pimd/pim_pim.c
+++ b/pimd/pim_pim.c
@@ -389,7 +389,7 @@ static int pim_sock_open(struct in_addr ifaddr, int ifindex)
{
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)
return -1;
diff --git a/pimd/pim_sock.c b/pimd/pim_sock.c
index 278a0972f..a2e166f79 100644
--- a/pimd/pim_sock.c
+++ b/pimd/pim_sock.c
@@ -34,6 +34,7 @@
#include "log.h"
#include "privs.h"
#include "if.h"
+#include "vrf.h"
#include "pimd.h"
#include "pim_mroute.h"
@@ -67,7 +68,7 @@ int pim_socket_raw(int protocol)
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;
@@ -78,6 +79,33 @@ int pim_socket_mcast(int protocol, struct in_addr ifaddr, int loop)
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() */
{
#if defined(HAVE_IP_PKTINFO)
diff --git a/pimd/pim_sock.h b/pimd/pim_sock.h
index cfe39ad1e..9a9b64a4a 100644
--- a/pimd/pim_sock.h
+++ b/pimd/pim_sock.h
@@ -36,9 +36,10 @@
#define PIM_SOCK_ERR_NONBLOCK_GETFL (-8) /* Get 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_BIND (-11) /* Can't bind to interface */
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,
struct in_addr ifaddr, int ifindex);
int pim_socket_join_source(int fd, int ifindex,