]> git.puffer.fish Git - matthieu/frr.git/commitdiff
pimd: Bind pim sockets to interface they are associated with
authorDonald Sharp <sharpd@cumulusnetworks.com>
Wed, 29 Jun 2016 01:50:49 +0000 (21:50 -0400)
committerDonald Sharp <sharpd@cumulusnetworks.com>
Wed, 29 Jun 2016 01:50:49 +0000 (21:50 -0400)
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>
pimd/pim_igmp.c
pimd/pim_pim.c
pimd/pim_sock.c
pimd/pim_sock.h

index 43fac9a1663772d952f1b7b772365fd28c9fd98a..176470e201249c573021995ac8ee1499800c74d8 100644 (file)
@@ -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;
 
index a3136b61b24a95fed0a25d0c4ecb92067389b42d..60507970d9c33874047b70710be62d811fd9c68c 100644 (file)
@@ -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;
 
index 278a0972f815e8f5685159d524c1f8a455aa7355..a2e166f79677b011af76df95fbf265c5a4604a83 100644 (file)
@@ -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)
index cfe39ad1e7c4b50042a064af014251b321e6cd86..9a9b64a4a36e2f422e85e405b4ee23324609d245 100644 (file)
 #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,