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;
{
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;
#include "log.h"
#include "privs.h"
#include "if.h"
+#include "vrf.h"
#include "pimd.h"
#include "pim_mroute.h"
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;
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)
#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,