#include "vty.h"
#include "plist.h"
#include "sockopt.h"
+#include "lib_errors.h"
#include "pimd.h"
#include "pim_rpf.h"
static int pim_mroute_set(struct pim_instance *pim, int enable)
{
int err;
- int opt;
- socklen_t opt_len = sizeof(opt);
+ int opt, data;
+ socklen_t data_len = sizeof(data);
long flags;
/*
* We need to create the VRF table for the pim mroute_socket
*/
if (pim->vrf_id != VRF_DEFAULT) {
- if (pimd_privs.change(ZPRIVS_RAISE))
- zlog_err(
- "pim_mroute_socket_enable: could not raise privs, %s",
- safe_strerror(errno));
+ frr_elevate_privs(&pimd_privs) {
+
+ data = pim->vrf->data.l.table_id;
+ err = setsockopt(pim->mroute_socket, IPPROTO_IP,
+ MRT_TABLE,
+ &data, data_len);
+ if (err) {
+ zlog_warn(
+ "%s %s: failure: setsockopt(fd=%d,IPPROTO_IP, MRT_TABLE=%d): errno=%d: %s",
+ __FILE__, __PRETTY_FUNCTION__,
+ pim->mroute_socket, data, errno,
+ safe_strerror(errno));
+ return -1;
+ }
+
+ }
+ }
- opt = pim->vrf->data.l.table_id;
- err = setsockopt(pim->mroute_socket, IPPROTO_IP, MRT_TABLE,
- &opt, opt_len);
+ frr_elevate_privs(&pimd_privs) {
+ opt = enable ? MRT_INIT : MRT_DONE;
+ /*
+ * *BSD *cares* about what value we pass down
+ * here
+ */
+ data = 1;
+ err = setsockopt(pim->mroute_socket, IPPROTO_IP,
+ opt, &data, data_len);
if (err) {
zlog_warn(
- "%s %s: failure: setsockopt(fd=%d,IPPROTO_IP, MRT_TABLE=%d): errno=%d: %s",
- __FILE__, __PRETTY_FUNCTION__,
- pim->mroute_socket, opt, errno,
- safe_strerror(errno));
+ "%s %s: failure: setsockopt(fd=%d,IPPROTO_IP,%s=%d): errno=%d: %s",
+ __FILE__, __PRETTY_FUNCTION__,
+ pim->mroute_socket,
+ enable ? "MRT_INIT" : "MRT_DONE", data, errno,
+ safe_strerror(errno));
return -1;
}
-
- if (pimd_privs.change(ZPRIVS_LOWER))
- zlog_err(
- "pim_mroute_socket_enable: could not lower privs, %s",
- safe_strerror(errno));
- }
-
- opt = enable ? MRT_INIT : MRT_DONE;
- err = setsockopt(pim->mroute_socket, IPPROTO_IP, opt, &opt, opt_len);
- if (err) {
- zlog_warn(
- "%s %s: failure: setsockopt(fd=%d,IPPROTO_IP,%s=%d): errno=%d: %s",
- __FILE__, __PRETTY_FUNCTION__, pim->mroute_socket,
- enable ? "MRT_INIT" : "MRT_DONE", opt, errno,
- safe_strerror(errno));
- return -1;
}
#if defined(HAVE_IP_PKTINFO)
if (enable) {
/* Linux and Solaris IP_PKTINFO */
- opt = 1;
- if (setsockopt(pim->mroute_socket, IPPROTO_IP, IP_PKTINFO, &opt,
- sizeof(opt))) {
+ data = 1;
+ if (setsockopt(pim->mroute_socket, IPPROTO_IP, IP_PKTINFO,
+ &data, data_len)) {
zlog_warn(
"Could not set IP_PKTINFO on socket fd=%d: errno=%d: %s",
pim->mroute_socket, errno,
struct pim_rpf *rpg;
struct prefix_sg sg;
- rpg = RP(pim_ifp->pim, msg->im_dst);
+ rpg = pim_ifp ? RP(pim_ifp->pim, msg->im_dst) : NULL;
/*
* If the incoming interface is unknown OR
* the Interface type is SSM we don't need to
* do anything here
*/
- if ((pim_rpf_addr_is_inaddr_none(rpg)) || (!pim_ifp)
- || (!(PIM_I_am_DR(pim_ifp)))) {
+ if (!rpg || pim_rpf_addr_is_inaddr_none(rpg)) {
if (PIM_DEBUG_MROUTE_DETAIL)
zlog_debug(
- "%s: Interface is not configured correctly to handle incoming packet: Could be !DR, !pim_ifp, !SM, !RP",
+ "%s: Interface is not configured correctly to handle incoming packet: Could be !pim_ifp, !SM, !RP",
__PRETTY_FUNCTION__);
+
return 0;
}
sg.src = msg->im_src;
sg.grp = msg->im_dst;
+ if (!(PIM_I_am_DR(pim_ifp))) {
+ struct channel_oil *c_oil;
+
+ if (PIM_DEBUG_MROUTE_DETAIL)
+ zlog_debug("%s: Interface is not the DR blackholing incoming traffic for %s",
+ __PRETTY_FUNCTION__, pim_str_sg_dump(&sg));
+
+ /*
+ * We are not the DR, but we are still receiving packets
+ * Let's blackhole those packets for the moment
+ * As that they will be coming up to the cpu
+ * and causing us to consider them.
+ */
+ c_oil = pim_channel_oil_add(pim_ifp->pim, &sg,
+ pim_ifp->mroute_vif_index);
+ pim_mroute_add(c_oil, __PRETTY_FUNCTION__);
+
+ return 0;
+ }
+
up = pim_upstream_find_or_add(&sg, ifp, PIM_UPSTREAM_FLAG_MASK_FHR,
__PRETTY_FUNCTION__);
if (!up) {
pim_ifp = up->rpf.source_nexthop.interface->info;
- rpg = RP(pim_ifp->pim, sg.grp);
+ rpg = pim_ifp ? RP(pim_ifp->pim, sg.grp) : NULL;
if ((pim_rpf_addr_is_inaddr_none(rpg)) || (!pim_ifp)
|| (!(PIM_I_am_DR(pim_ifp)))) {
return -2;
}
PIM_UPSTREAM_FLAG_SET_SRC_STREAM(up->flags);
- pim_upstream_keep_alive_timer_start(up, pim_ifp->pim->keep_alive_time);
+ pim_upstream_keep_alive_timer_start(
+ up, pim_ifp->pim->keep_alive_time);
up->channel_oil = oil;
up->channel_oil->cc.pktcnt++;
pim_register_join(up);
{
int fd;
- if (pimd_privs.change(ZPRIVS_RAISE))
- zlog_err("pim_mroute_socket_enable: could not raise privs, %s",
- safe_strerror(errno));
+ frr_elevate_privs(&pimd_privs) {
+
+ fd = socket(AF_INET, SOCK_RAW, IPPROTO_IGMP);
- fd = socket(AF_INET, SOCK_RAW, IPPROTO_IGMP);
+ if (fd < 0) {
+ zlog_warn("Could not create mroute socket: errno=%d: %s",
+ errno,
+ safe_strerror(errno));
+ return -2;
+ }
#ifdef SO_BINDTODEVICE
- setsockopt(fd, SOL_SOCKET, SO_BINDTODEVICE, pim->vrf->name,
- strlen(pim->vrf->name));
+ if (pim->vrf->vrf_id != VRF_DEFAULT
+ && setsockopt(fd, SOL_SOCKET, SO_BINDTODEVICE,
+ pim->vrf->name, strlen(pim->vrf->name))) {
+ zlog_warn("Could not setsockopt SO_BINDTODEVICE: %s",
+ safe_strerror(errno));
+ close(fd);
+ return -3;
+ }
#endif
- if (pimd_privs.change(ZPRIVS_LOWER))
- zlog_err("pim_mroute_socket_enable: could not lower privs, %s",
- safe_strerror(errno));
-
- if (fd < 0) {
- zlog_warn("Could not create mroute socket: errno=%d: %s", errno,
- safe_strerror(errno));
- return -2;
}
pim->mroute_socket = fd;
if (PIM_DEBUG_MROUTE)
zlog_debug("%s: Add Vif %d (%s[%s])", __PRETTY_FUNCTION__,
- pim_ifp->mroute_vif_index,
- ifp->name, pim_ifp->pim->vrf->name);
+ pim_ifp->mroute_vif_index, ifp->name,
+ pim_ifp->pim->vrf->name);
memset(&vc, 0, sizeof(vc));
vc.vifc_vifi = pim_ifp->mroute_vif_index;
zlog_warn(
"%s: failure: setsockopt(fd=%d,IPPROTO_IP,MRT_ADD_VIF,vif_index=%d,ifaddr=%s,flag=%d): errno=%d: %s",
- __PRETTY_FUNCTION__,
- pim_ifp->pim->mroute_socket, ifp->ifindex, ifaddr_str,
- flags, errno, safe_strerror(errno));
+ __PRETTY_FUNCTION__, pim_ifp->pim->mroute_socket,
+ ifp->ifindex, ifaddr_str, flags, errno,
+ safe_strerror(errno));
return -2;
}
int err;
if (PIM_DEBUG_MROUTE)
- zlog_debug("%s: Del Vif %d (%s[%s])", __PRETTY_FUNCTION__,
- pim_ifp->mroute_vif_index,
- ifp->name, pim_ifp->pim->vrf->name);
+ zlog_debug("%s: Del Vif %d (%s[%s])", __PRETTY_FUNCTION__,
+ pim_ifp->mroute_vif_index, ifp->name,
+ pim_ifp->pim->vrf->name);
memset(&vc, 0, sizeof(vc));
vc.vifc_vifi = pim_ifp->mroute_vif_index;
if (PIM_DEBUG_MROUTE) {
char buf[1000];
- zlog_debug("%s(%s), vrf %s Added Route: %s", __PRETTY_FUNCTION__, name,
- pim->vrf->name,
+ zlog_debug("%s(%s), vrf %s Added Route: %s",
+ __PRETTY_FUNCTION__, name, pim->vrf->name,
pim_channel_oil_dump(c_oil, buf, sizeof(buf)));
}
if (PIM_DEBUG_MROUTE) {
char buf[1000];
- zlog_debug("%s(%s), vrf %s Deleted Route: %s", __PRETTY_FUNCTION__,
- name, pim->vrf->name,
+ zlog_debug("%s(%s), vrf %s Deleted Route: %s",
+ __PRETTY_FUNCTION__, name, pim->vrf->name,
pim_channel_oil_dump(c_oil, buf, sizeof(buf)));
}