diff --git a/pimd/pim_igmp.c b/pimd/pim_igmp.c index 43fac9a166..176470e201 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 a3136b61b2..60507970d9 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 278a0972f8..a2e166f796 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 cfe39ad1e7..9a9b64a4a3 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,