summaryrefslogtreecommitdiff
path: root/pimd/pim_mroute.c
diff options
context:
space:
mode:
Diffstat (limited to 'pimd/pim_mroute.c')
-rw-r--r--pimd/pim_mroute.c1568
1 files changed, 796 insertions, 772 deletions
diff --git a/pimd/pim_mroute.c b/pimd/pim_mroute.c
index 01747268a3..a92b01ca00 100644
--- a/pimd/pim_mroute.c
+++ b/pimd/pim_mroute.c
@@ -47,358 +47,360 @@ static void mroute_read_on(void);
static int pim_mroute_set(int fd, int enable)
{
- int err;
- int opt = enable ? MRT_INIT : MRT_DONE;
- socklen_t opt_len = sizeof(opt);
- int rcvbuf = 1024 * 1024 * 8;
- long flags;
-
- err = setsockopt(fd, 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__,
- fd, enable ? "MRT_INIT" : "MRT_DONE", opt, errno, safe_strerror(errno));
- return -1;
- }
-
- err = setsockopt(fd, SOL_SOCKET, SO_RCVBUF, &rcvbuf, sizeof(rcvbuf));
- if (err) {
- zlog_warn("%s: failure: setsockopt(fd=%d, SOL_SOCKET, %d): errno=%d: %s",
- __PRETTY_FUNCTION__, fd, rcvbuf, errno, safe_strerror(errno));
- }
-
- flags = fcntl(fd, F_GETFL, 0);
- if (flags < 0)
- {
- zlog_warn("Could not get flags on socket fd:%d %d %s",
- fd, errno, safe_strerror(errno));
- close (fd);
- return -1;
- }
- if (fcntl(fd, F_SETFL, flags | O_NONBLOCK))
- {
- zlog_warn("Could not set O_NONBLOCK on socket fd:%d %d %s",
- fd, errno, safe_strerror(errno));
- close(fd);
- return -1;
- }
+ int err;
+ int opt = enable ? MRT_INIT : MRT_DONE;
+ socklen_t opt_len = sizeof(opt);
+ int rcvbuf = 1024 * 1024 * 8;
+ long flags;
+
+ err = setsockopt(fd, 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__, fd,
+ enable ? "MRT_INIT" : "MRT_DONE", opt, errno,
+ safe_strerror(errno));
+ return -1;
+ }
- if (enable)
- {
+ err = setsockopt(fd, SOL_SOCKET, SO_RCVBUF, &rcvbuf, sizeof(rcvbuf));
+ if (err) {
+ zlog_warn(
+ "%s: failure: setsockopt(fd=%d, SOL_SOCKET, %d): errno=%d: %s",
+ __PRETTY_FUNCTION__, fd, rcvbuf, errno,
+ safe_strerror(errno));
+ }
+
+ flags = fcntl(fd, F_GETFL, 0);
+ if (flags < 0) {
+ zlog_warn("Could not get flags on socket fd:%d %d %s", fd,
+ errno, safe_strerror(errno));
+ close(fd);
+ return -1;
+ }
+ if (fcntl(fd, F_SETFL, flags | O_NONBLOCK)) {
+ zlog_warn("Could not set O_NONBLOCK on socket fd:%d %d %s", fd,
+ errno, safe_strerror(errno));
+ close(fd);
+ return -1;
+ }
+
+ if (enable) {
#if defined linux
- int upcalls = IGMPMSG_WRVIFWHOLE;
- opt = MRT_PIM;
-
- err = setsockopt (fd, IPPROTO_IP, opt, &upcalls, sizeof (upcalls));
- if (err)
- {
- zlog_warn ("Failure to register for VIFWHOLE and WRONGVIF upcalls %d %s",
- errno, safe_strerror (errno));
- return -1;
- }
+ int upcalls = IGMPMSG_WRVIFWHOLE;
+ opt = MRT_PIM;
+
+ err = setsockopt(fd, IPPROTO_IP, opt, &upcalls,
+ sizeof(upcalls));
+ if (err) {
+ zlog_warn(
+ "Failure to register for VIFWHOLE and WRONGVIF upcalls %d %s",
+ errno, safe_strerror(errno));
+ return -1;
+ }
#else
- zlog_warn ("PIM-SM will not work properly on this platform, until the ability to receive the WRVIFWHOLE upcall");
+ zlog_warn(
+ "PIM-SM will not work properly on this platform, until the ability to receive the WRVIFWHOLE upcall");
#endif
- }
-
- return 0;
+ }
+
+ return 0;
}
static const char *igmpmsgtype2str[IGMPMSG_WRVIFWHOLE + 1] = {
- "<unknown_upcall?>",
- "NOCACHE",
- "WRONGVIF",
- "WHOLEPKT",
- "WRVIFWHOLE" };
-
-static int
-pim_mroute_msg_nocache (int fd, struct interface *ifp, const struct igmpmsg *msg)
+ "<unknown_upcall?>", "NOCACHE", "WRONGVIF", "WHOLEPKT", "WRVIFWHOLE"};
+
+static int pim_mroute_msg_nocache(int fd, struct interface *ifp,
+ const struct igmpmsg *msg)
{
- struct pim_interface *pim_ifp = ifp->info;
- struct pim_upstream *up;
- struct pim_rpf *rpg;
- struct prefix_sg sg;
-
- rpg = RP(msg->im_dst);
- /*
- * 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 (PIM_DEBUG_MROUTE_DETAIL)
- zlog_debug ("%s: Interface is not configured correctly to handle incoming packet: Could be !DR, !pim_ifp, !SM, !RP",
- __PRETTY_FUNCTION__);
- return 0;
- }
+ struct pim_interface *pim_ifp = ifp->info;
+ struct pim_upstream *up;
+ struct pim_rpf *rpg;
+ struct prefix_sg sg;
+
+ rpg = RP(msg->im_dst);
+ /*
+ * 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 (PIM_DEBUG_MROUTE_DETAIL)
+ zlog_debug(
+ "%s: Interface is not configured correctly to handle incoming packet: Could be !DR, !pim_ifp, !SM, !RP",
+ __PRETTY_FUNCTION__);
+ return 0;
+ }
- /*
- * If we've received a multicast packet that isn't connected to
- * us
- */
- if (!pim_if_connected_to_source (ifp, msg->im_src))
- {
- if (PIM_DEBUG_MROUTE_DETAIL)
- zlog_debug ("%s: Received incoming packet that doesn't originate on our seg",
- __PRETTY_FUNCTION__);
- return 0;
- }
+ /*
+ * If we've received a multicast packet that isn't connected to
+ * us
+ */
+ if (!pim_if_connected_to_source(ifp, msg->im_src)) {
+ if (PIM_DEBUG_MROUTE_DETAIL)
+ zlog_debug(
+ "%s: Received incoming packet that doesn't originate on our seg",
+ __PRETTY_FUNCTION__);
+ return 0;
+ }
- memset (&sg, 0, sizeof (struct prefix_sg));
- sg.src = msg->im_src;
- sg.grp = msg->im_dst;
+ memset(&sg, 0, sizeof(struct prefix_sg));
+ sg.src = msg->im_src;
+ sg.grp = msg->im_dst;
+
+ up = pim_upstream_find_or_add(&sg, ifp, PIM_UPSTREAM_FLAG_MASK_FHR,
+ __PRETTY_FUNCTION__);
+ if (!up) {
+ if (PIM_DEBUG_MROUTE) {
+ zlog_debug(
+ "%s: Failure to add upstream information for %s",
+ __PRETTY_FUNCTION__, pim_str_sg_dump(&sg));
+ }
+ return 0;
+ }
- up = pim_upstream_find_or_add (&sg, ifp, PIM_UPSTREAM_FLAG_MASK_FHR, __PRETTY_FUNCTION__);
- if (!up)
- {
- if (PIM_DEBUG_MROUTE)
- {
- zlog_debug("%s: Failure to add upstream information for %s",
- __PRETTY_FUNCTION__,
- pim_str_sg_dump (&sg));
- }
- return 0;
- }
+ /*
+ * I moved this debug till after the actual add because
+ * I want to take advantage of the up->sg_str being filled in.
+ */
+ if (PIM_DEBUG_MROUTE) {
+ zlog_debug("%s: Adding a Route %s for WHOLEPKT consumption",
+ __PRETTY_FUNCTION__, up->sg_str);
+ }
- /*
- * I moved this debug till after the actual add because
- * I want to take advantage of the up->sg_str being filled in.
- */
- if (PIM_DEBUG_MROUTE) {
- zlog_debug("%s: Adding a Route %s for WHOLEPKT consumption",
- __PRETTY_FUNCTION__, up->sg_str);
- }
-
- PIM_UPSTREAM_FLAG_SET_SRC_STREAM(up->flags);
- pim_upstream_keep_alive_timer_start (up, qpim_keep_alive_time);
-
- up->channel_oil->cc.pktcnt++;
- PIM_UPSTREAM_FLAG_SET_FHR(up->flags);
- // resolve mfcc_parent prior to mroute_add in channel_add_oif
- if (up->channel_oil->oil.mfcc_parent >= MAXVIFS)
- {
- int vif_index = 0;
- vif_index =
- pim_if_find_vifindex_by_ifindex (up->rpf.source_nexthop.
- interface->ifindex);
- up->channel_oil->oil.mfcc_parent = vif_index;
- }
- pim_register_join (up);
+ PIM_UPSTREAM_FLAG_SET_SRC_STREAM(up->flags);
+ pim_upstream_keep_alive_timer_start(up, qpim_keep_alive_time);
+
+ up->channel_oil->cc.pktcnt++;
+ PIM_UPSTREAM_FLAG_SET_FHR(up->flags);
+ // resolve mfcc_parent prior to mroute_add in channel_add_oif
+ if (up->channel_oil->oil.mfcc_parent >= MAXVIFS) {
+ int vif_index = 0;
+ vif_index = pim_if_find_vifindex_by_ifindex(
+ up->rpf.source_nexthop.interface->ifindex);
+ up->channel_oil->oil.mfcc_parent = vif_index;
+ }
+ pim_register_join(up);
- return 0;
+ return 0;
}
-static int
-pim_mroute_msg_wholepkt (int fd, struct interface *ifp, const char *buf)
+static int pim_mroute_msg_wholepkt(int fd, struct interface *ifp,
+ const char *buf)
{
- struct pim_interface *pim_ifp;
- struct prefix_sg sg;
- struct pim_rpf *rpg;
- const struct ip *ip_hdr;
- struct pim_upstream *up;
-
- ip_hdr = (const struct ip *)buf;
-
- memset (&sg, 0, sizeof (struct prefix_sg));
- sg.src = ip_hdr->ip_src;
- sg.grp = ip_hdr->ip_dst;
-
- up = pim_upstream_find(&sg);
- if (!up) {
- struct prefix_sg star = sg;
- star.src.s_addr = INADDR_ANY;
-
- up = pim_upstream_find(&star);
-
- if (up && PIM_UPSTREAM_FLAG_TEST_SRC_IGMP(up->flags))
- {
- up = pim_upstream_add (&sg, ifp, PIM_UPSTREAM_FLAG_MASK_SRC_LHR, __PRETTY_FUNCTION__);
- if (!up)
- {
- if (PIM_DEBUG_MROUTE)
- zlog_debug ("%s: Unable to create upstream information for %s",
- __PRETTY_FUNCTION__, pim_str_sg_dump (&sg));
- return 0;
- }
- pim_upstream_keep_alive_timer_start (up, qpim_keep_alive_time);
- pim_upstream_inherited_olist (up);
- pim_upstream_switch(up, PIM_UPSTREAM_JOINED);
-
- if (PIM_DEBUG_MROUTE)
- zlog_debug ("%s: Creating %s upstream on LHR",
- __PRETTY_FUNCTION__, up->sg_str);
- return 0;
- }
- if (PIM_DEBUG_MROUTE_DETAIL) {
- zlog_debug("%s: Unable to find upstream channel WHOLEPKT%s",
- __PRETTY_FUNCTION__, pim_str_sg_dump (&sg));
- }
- return 0;
- }
+ struct pim_interface *pim_ifp;
+ struct prefix_sg sg;
+ struct pim_rpf *rpg;
+ const struct ip *ip_hdr;
+ struct pim_upstream *up;
+
+ ip_hdr = (const struct ip *)buf;
+
+ memset(&sg, 0, sizeof(struct prefix_sg));
+ sg.src = ip_hdr->ip_src;
+ sg.grp = ip_hdr->ip_dst;
+
+ up = pim_upstream_find(&sg);
+ if (!up) {
+ struct prefix_sg star = sg;
+ star.src.s_addr = INADDR_ANY;
+
+ up = pim_upstream_find(&star);
+
+ if (up && PIM_UPSTREAM_FLAG_TEST_SRC_IGMP(up->flags)) {
+ up = pim_upstream_add(&sg, ifp,
+ PIM_UPSTREAM_FLAG_MASK_SRC_LHR,
+ __PRETTY_FUNCTION__);
+ if (!up) {
+ if (PIM_DEBUG_MROUTE)
+ zlog_debug(
+ "%s: Unable to create upstream information for %s",
+ __PRETTY_FUNCTION__,
+ pim_str_sg_dump(&sg));
+ return 0;
+ }
+ pim_upstream_keep_alive_timer_start(
+ up, qpim_keep_alive_time);
+ pim_upstream_inherited_olist(up);
+ pim_upstream_switch(up, PIM_UPSTREAM_JOINED);
+
+ if (PIM_DEBUG_MROUTE)
+ zlog_debug("%s: Creating %s upstream on LHR",
+ __PRETTY_FUNCTION__, up->sg_str);
+ return 0;
+ }
+ if (PIM_DEBUG_MROUTE_DETAIL) {
+ zlog_debug(
+ "%s: Unable to find upstream channel WHOLEPKT%s",
+ __PRETTY_FUNCTION__, pim_str_sg_dump(&sg));
+ }
+ return 0;
+ }
- pim_ifp = up->rpf.source_nexthop.interface->info;
+ pim_ifp = up->rpf.source_nexthop.interface->info;
- rpg = RP(sg.grp);
+ rpg = RP(sg.grp);
- if ((pim_rpf_addr_is_inaddr_none (rpg)) ||
- (!pim_ifp) ||
- (!(PIM_I_am_DR(pim_ifp)))) {
- if (PIM_DEBUG_MROUTE) {
- zlog_debug("%s: Failed Check send packet", __PRETTY_FUNCTION__);
- }
- return 0;
- }
+ if ((pim_rpf_addr_is_inaddr_none(rpg)) || (!pim_ifp)
+ || (!(PIM_I_am_DR(pim_ifp)))) {
+ if (PIM_DEBUG_MROUTE) {
+ zlog_debug("%s: Failed Check send packet",
+ __PRETTY_FUNCTION__);
+ }
+ return 0;
+ }
- /*
- * If we've received a register suppress
- */
- if (!up->t_rs_timer)
- {
- if (pim_is_grp_ssm (sg.grp))
- {
- if (PIM_DEBUG_PIM_REG)
- zlog_debug ("%s register forward skipped as group is SSM",
- pim_str_sg_dump (&sg));
- return 0;
- }
- pim_register_send((uint8_t *)buf + sizeof(struct ip),
- ntohs (ip_hdr->ip_len) - sizeof (struct ip),
- pim_ifp->primary_address, rpg, 0, up);
- }
- return 0;
+ /*
+ * If we've received a register suppress
+ */
+ if (!up->t_rs_timer) {
+ if (pim_is_grp_ssm(sg.grp)) {
+ if (PIM_DEBUG_PIM_REG)
+ zlog_debug(
+ "%s register forward skipped as group is SSM",
+ pim_str_sg_dump(&sg));
+ return 0;
+ }
+ pim_register_send((uint8_t *)buf + sizeof(struct ip),
+ ntohs(ip_hdr->ip_len) - sizeof(struct ip),
+ pim_ifp->primary_address, rpg, 0, up);
+ }
+ return 0;
}
-static int
-pim_mroute_msg_wrongvif (int fd, struct interface *ifp, const struct igmpmsg *msg)
+static int pim_mroute_msg_wrongvif(int fd, struct interface *ifp,
+ const struct igmpmsg *msg)
{
- struct pim_ifchannel *ch;
- struct pim_interface *pim_ifp;
- struct prefix_sg sg;
+ struct pim_ifchannel *ch;
+ struct pim_interface *pim_ifp;
+ struct prefix_sg sg;
+
+ memset(&sg, 0, sizeof(struct prefix_sg));
+ sg.src = msg->im_src;
+ sg.grp = msg->im_dst;
+
+ /*
+ Send Assert(S,G) on iif as response to WRONGVIF kernel upcall.
+
+ RFC 4601 4.8.2. PIM-SSM-Only Routers
+
+ iif is the incoming interface of the packet.
+ if (iif is in inherited_olist(S,G)) {
+ send Assert(S,G) on iif
+ }
+ */
+
+ if (!ifp) {
+ if (PIM_DEBUG_MROUTE)
+ zlog_debug(
+ "%s: WRONGVIF (S,G)=%s could not find input interface for input_vif_index=%d",
+ __PRETTY_FUNCTION__, pim_str_sg_dump(&sg),
+ msg->im_vif);
+ return -1;
+ }
- memset (&sg, 0, sizeof (struct prefix_sg));
- sg.src = msg->im_src;
- sg.grp = msg->im_dst;
+ pim_ifp = ifp->info;
+ if (!pim_ifp) {
+ if (PIM_DEBUG_MROUTE)
+ zlog_debug(
+ "%s: WRONGVIF (S,G)=%s multicast not enabled on interface %s",
+ __PRETTY_FUNCTION__, pim_str_sg_dump(&sg),
+ ifp->name);
+ return -2;
+ }
- /*
- Send Assert(S,G) on iif as response to WRONGVIF kernel upcall.
+ ch = pim_ifchannel_find(ifp, &sg);
+ if (!ch) {
+ struct prefix_sg star_g = sg;
+ if (PIM_DEBUG_MROUTE)
+ zlog_debug(
+ "%s: WRONGVIF (S,G)=%s could not find channel on interface %s",
+ __PRETTY_FUNCTION__, pim_str_sg_dump(&sg),
+ ifp->name);
+
+ star_g.src.s_addr = INADDR_ANY;
+ ch = pim_ifchannel_find(ifp, &star_g);
+ if (!ch) {
+ if (PIM_DEBUG_MROUTE)
+ zlog_debug(
+ "%s: WRONGVIF (*,G)=%s could not find channel on interface %s",
+ __PRETTY_FUNCTION__,
+ pim_str_sg_dump(&star_g), ifp->name);
+ return -3;
+ }
+ }
- RFC 4601 4.8.2. PIM-SSM-Only Routers
+ /*
+ RFC 4601: 4.6.1. (S,G) Assert Message State Machine
+
+ Transitions from NoInfo State
+
+ An (S,G) data packet arrives on interface I, AND
+ CouldAssert(S,G,I)==TRUE An (S,G) data packet arrived on an
+ downstream interface that is in our (S,G) outgoing interface
+ list. We optimistically assume that we will be the assert
+ winner for this (S,G), and so we transition to the "I am Assert
+ Winner" state and perform Actions A1 (below), which will
+ initiate the assert negotiation for (S,G).
+ */
+
+ if (ch->ifassert_state != PIM_IFASSERT_NOINFO) {
+ if (PIM_DEBUG_MROUTE) {
+ zlog_debug(
+ "%s: WRONGVIF (S,G)=%s channel is not on Assert NoInfo state for interface %s",
+ __PRETTY_FUNCTION__, ch->sg_str, ifp->name);
+ }
+ return -4;
+ }
- iif is the incoming interface of the packet.
- if (iif is in inherited_olist(S,G)) {
- send Assert(S,G) on iif
- }
- */
-
- if (!ifp) {
- if (PIM_DEBUG_MROUTE)
- zlog_debug("%s: WRONGVIF (S,G)=%s could not find input interface for input_vif_index=%d",
- __PRETTY_FUNCTION__,
- pim_str_sg_dump (&sg), msg->im_vif);
- return -1;
- }
-
- pim_ifp = ifp->info;
- if (!pim_ifp) {
- if (PIM_DEBUG_MROUTE)
- zlog_debug("%s: WRONGVIF (S,G)=%s multicast not enabled on interface %s",
- __PRETTY_FUNCTION__,
- pim_str_sg_dump (&sg), ifp->name);
- return -2;
- }
-
- ch = pim_ifchannel_find(ifp, &sg);
- if (!ch) {
- struct prefix_sg star_g = sg;
- if (PIM_DEBUG_MROUTE)
- zlog_debug("%s: WRONGVIF (S,G)=%s could not find channel on interface %s",
- __PRETTY_FUNCTION__,
- pim_str_sg_dump(&sg), ifp->name);
-
- star_g.src.s_addr = INADDR_ANY;
- ch = pim_ifchannel_find(ifp, &star_g);
- if (!ch) {
- if (PIM_DEBUG_MROUTE)
- zlog_debug("%s: WRONGVIF (*,G)=%s could not find channel on interface %s",
- __PRETTY_FUNCTION__,
- pim_str_sg_dump(&star_g), ifp->name);
- return -3;
- }
- }
-
- /*
- RFC 4601: 4.6.1. (S,G) Assert Message State Machine
-
- Transitions from NoInfo State
-
- An (S,G) data packet arrives on interface I, AND
- CouldAssert(S,G,I)==TRUE An (S,G) data packet arrived on an
- downstream interface that is in our (S,G) outgoing interface
- list. We optimistically assume that we will be the assert
- winner for this (S,G), and so we transition to the "I am Assert
- Winner" state and perform Actions A1 (below), which will
- initiate the assert negotiation for (S,G).
- */
-
- if (ch->ifassert_state != PIM_IFASSERT_NOINFO) {
- if (PIM_DEBUG_MROUTE) {
- zlog_debug("%s: WRONGVIF (S,G)=%s channel is not on Assert NoInfo state for interface %s",
- __PRETTY_FUNCTION__,
- ch->sg_str, ifp->name);
- }
- return -4;
- }
-
- if (!PIM_IF_FLAG_TEST_COULD_ASSERT(ch->flags)) {
- if (PIM_DEBUG_MROUTE) {
- zlog_debug("%s: WRONGVIF (S,G)=%s interface %s is not downstream for channel",
- __PRETTY_FUNCTION__,
- ch->sg_str, ifp->name);
- }
- return -5;
- }
-
- if (assert_action_a1(ch)) {
- if (PIM_DEBUG_MROUTE) {
- zlog_debug("%s: WRONGVIF (S,G)=%s assert_action_a1 failure on interface %s",
- __PRETTY_FUNCTION__,
- ch->sg_str, ifp->name);
- }
- return -6;
- }
+ if (!PIM_IF_FLAG_TEST_COULD_ASSERT(ch->flags)) {
+ if (PIM_DEBUG_MROUTE) {
+ zlog_debug(
+ "%s: WRONGVIF (S,G)=%s interface %s is not downstream for channel",
+ __PRETTY_FUNCTION__, ch->sg_str, ifp->name);
+ }
+ return -5;
+ }
+
+ if (assert_action_a1(ch)) {
+ if (PIM_DEBUG_MROUTE) {
+ zlog_debug(
+ "%s: WRONGVIF (S,G)=%s assert_action_a1 failure on interface %s",
+ __PRETTY_FUNCTION__, ch->sg_str, ifp->name);
+ }
+ return -6;
+ }
- return 0;
+ return 0;
}
-static int
-pim_mroute_msg_wrvifwhole (int fd, struct interface *ifp, const char *buf)
+static int pim_mroute_msg_wrvifwhole(int fd, struct interface *ifp,
+ const char *buf)
{
- const struct ip *ip_hdr = (const struct ip *)buf;
- struct pim_interface *pim_ifp;
- struct pim_ifchannel *ch;
- struct pim_upstream *up;
- struct prefix_sg star_g;
- struct prefix_sg sg;
- struct channel_oil *oil;
-
- memset (&sg, 0, sizeof (struct prefix_sg));
- sg.src = ip_hdr->ip_src;
- sg.grp = ip_hdr->ip_dst;
-
- ch = pim_ifchannel_find(ifp, &sg);
- if (ch)
- {
- if (PIM_DEBUG_MROUTE)
- zlog_debug ("WRVIFWHOLE (S,G)=%s found ifchannel on interface %s",
- ch->sg_str, ifp->name);
- return -1;
- }
+ const struct ip *ip_hdr = (const struct ip *)buf;
+ struct pim_interface *pim_ifp;
+ struct pim_ifchannel *ch;
+ struct pim_upstream *up;
+ struct prefix_sg star_g;
+ struct prefix_sg sg;
+ struct channel_oil *oil;
+
+ memset(&sg, 0, sizeof(struct prefix_sg));
+ sg.src = ip_hdr->ip_src;
+ sg.grp = ip_hdr->ip_dst;
+
+ ch = pim_ifchannel_find(ifp, &sg);
+ if (ch) {
+ if (PIM_DEBUG_MROUTE)
+ zlog_debug(
+ "WRVIFWHOLE (S,G)=%s found ifchannel on interface %s",
+ ch->sg_str, ifp->name);
+ return -1;
+ }
- star_g = sg;
- star_g.src.s_addr = INADDR_ANY;
+ star_g = sg;
+ star_g.src.s_addr = INADDR_ANY;
#if 0
ch = pim_ifchannel_find(ifp, &star_g);
if (ch)
@@ -410,290 +412,313 @@ pim_mroute_msg_wrvifwhole (int fd, struct interface *ifp, const char *buf)
}
#endif
- up = pim_upstream_find (&sg);
- if (up)
- {
- struct pim_upstream *parent;
- struct pim_nexthop source;
- struct pim_rpf *rpf = RP (sg.grp);
- if (!rpf || !rpf->source_nexthop.interface)
- return 0;
-
- /*
- * If we have received a WRVIFWHOLE and are at this
- * point, we could be receiving the packet on the *,G
- * tree, let's check and if so we can safely drop
- * it.
- */
- parent = pim_upstream_find (&star_g);
- if (parent && parent->rpf.source_nexthop.interface == ifp)
- return 0;
-
- pim_ifp = rpf->source_nexthop.interface->info;
-
- memset (&source, 0, sizeof (source));
- /*
- * If we are the fhr that means we are getting a callback during
- * the pimreg period, so I believe we can ignore this packet
- */
- if (!PIM_UPSTREAM_FLAG_TEST_FHR(up->flags))
- {
- //No if channel, but upstream we are at the RP.
- if (pim_nexthop_lookup (&source, up->upstream_register, 0) == 0)
- pim_register_stop_send(source.interface, &sg, pim_ifp->primary_address, up->upstream_register);
- if (!up->channel_oil)
- up->channel_oil = pim_channel_oil_add (&sg, pim_ifp->mroute_vif_index);
- pim_upstream_inherited_olist (up);
- if (!up->channel_oil->installed)
- pim_mroute_add (up->channel_oil, __PRETTY_FUNCTION__);
- pim_upstream_set_sptbit (up, ifp);
- }
- else
- {
- if (I_am_RP (up->sg.grp))
- {
- if (pim_nexthop_lookup (&source, up->upstream_register, 0) == 0)
- pim_register_stop_send(source.interface, &sg, pim_ifp->primary_address, up->upstream_register);
- up->sptbit = PIM_UPSTREAM_SPTBIT_TRUE;
- }
- pim_upstream_keep_alive_timer_start (up, qpim_keep_alive_time);
- pim_upstream_inherited_olist (up);
- pim_mroute_msg_wholepkt (fd, ifp, buf);
- }
- return 0;
- }
+ up = pim_upstream_find(&sg);
+ if (up) {
+ struct pim_upstream *parent;
+ struct pim_nexthop source;
+ struct pim_rpf *rpf = RP(sg.grp);
+ if (!rpf || !rpf->source_nexthop.interface)
+ return 0;
+
+ /*
+ * If we have received a WRVIFWHOLE and are at this
+ * point, we could be receiving the packet on the *,G
+ * tree, let's check and if so we can safely drop
+ * it.
+ */
+ parent = pim_upstream_find(&star_g);
+ if (parent && parent->rpf.source_nexthop.interface == ifp)
+ return 0;
+
+ pim_ifp = rpf->source_nexthop.interface->info;
+
+ memset(&source, 0, sizeof(source));
+ /*
+ * If we are the fhr that means we are getting a callback during
+ * the pimreg period, so I believe we can ignore this packet
+ */
+ if (!PIM_UPSTREAM_FLAG_TEST_FHR(up->flags)) {
+ // No if channel, but upstream we are at the RP.
+ if (pim_nexthop_lookup(&source, up->upstream_register,
+ 0)
+ == 0)
+ pim_register_stop_send(source.interface, &sg,
+ pim_ifp->primary_address,
+ up->upstream_register);
+ if (!up->channel_oil)
+ up->channel_oil = pim_channel_oil_add(
+ &sg, pim_ifp->mroute_vif_index);
+ pim_upstream_inherited_olist(up);
+ if (!up->channel_oil->installed)
+ pim_mroute_add(up->channel_oil,
+ __PRETTY_FUNCTION__);
+ pim_upstream_set_sptbit(up, ifp);
+ } else {
+ if (I_am_RP(up->sg.grp)) {
+ if (pim_nexthop_lookup(&source,
+ up->upstream_register, 0)
+ == 0)
+ pim_register_stop_send(
+ source.interface, &sg,
+ pim_ifp->primary_address,
+ up->upstream_register);
+ up->sptbit = PIM_UPSTREAM_SPTBIT_TRUE;
+ }
+ pim_upstream_keep_alive_timer_start(
+ up, qpim_keep_alive_time);
+ pim_upstream_inherited_olist(up);
+ pim_mroute_msg_wholepkt(fd, ifp, buf);
+ }
+ return 0;
+ }
- pim_ifp = ifp->info;
- oil = pim_channel_oil_add (&sg, pim_ifp->mroute_vif_index);
- if (!oil->installed)
- pim_mroute_add (oil, __PRETTY_FUNCTION__);
- if (pim_if_connected_to_source (ifp, sg.src))
- {
- up = pim_upstream_add (&sg, ifp, PIM_UPSTREAM_FLAG_MASK_FHR, __PRETTY_FUNCTION__);
- if (!up)
- {
- if (PIM_DEBUG_MROUTE)
- zlog_debug ("%s: WRONGVIF%s unable to create upstream on interface",
- pim_str_sg_dump (&sg), ifp->name);
- return -2;
- }
- PIM_UPSTREAM_FLAG_SET_SRC_STREAM(up->flags);
- pim_upstream_keep_alive_timer_start (up, qpim_keep_alive_time);
- up->channel_oil = oil;
- up->channel_oil->cc.pktcnt++;
- pim_register_join (up);
- pim_upstream_inherited_olist (up);
-
- // Send the packet to the RP
- pim_mroute_msg_wholepkt (fd, ifp, buf);
- }
+ pim_ifp = ifp->info;
+ oil = pim_channel_oil_add(&sg, pim_ifp->mroute_vif_index);
+ if (!oil->installed)
+ pim_mroute_add(oil, __PRETTY_FUNCTION__);
+ if (pim_if_connected_to_source(ifp, sg.src)) {
+ up = pim_upstream_add(&sg, ifp, PIM_UPSTREAM_FLAG_MASK_FHR,
+ __PRETTY_FUNCTION__);
+ if (!up) {
+ if (PIM_DEBUG_MROUTE)
+ zlog_debug(
+ "%s: WRONGVIF%s unable to create upstream on interface",
+ pim_str_sg_dump(&sg), ifp->name);
+ return -2;
+ }
+ PIM_UPSTREAM_FLAG_SET_SRC_STREAM(up->flags);
+ pim_upstream_keep_alive_timer_start(up, qpim_keep_alive_time);
+ up->channel_oil = oil;
+ up->channel_oil->cc.pktcnt++;
+ pim_register_join(up);
+ pim_upstream_inherited_olist(up);
+
+ // Send the packet to the RP
+ pim_mroute_msg_wholepkt(fd, ifp, buf);
+ }
- return 0;
+ return 0;
}
int pim_mroute_msg(int fd, const char *buf, int buf_size)
{
- struct interface *ifp;
- struct pim_interface *pim_ifp;
- const struct ip *ip_hdr;
- const struct igmpmsg *msg;
- char ip_src_str[INET_ADDRSTRLEN] = "";
- char ip_dst_str[INET_ADDRSTRLEN] = "";
- char src_str[INET_ADDRSTRLEN] = "<src?>";
- char grp_str[INET_ADDRSTRLEN] = "<grp?>";
- struct in_addr ifaddr;
- struct igmp_sock *igmp;
-
- ip_hdr = (const struct ip *) buf;
-
- if (ip_hdr->ip_p == IPPROTO_IGMP) {
-
- /* We have the IP packet but we do not know which interface this packet was
- * received on. Find the interface that is on the same subnet as the source
- * of the IP packet.
- */
- ifp = pim_if_lookup_address_vrf (ip_hdr->ip_src, VRF_DEFAULT);
-
- if (!ifp) {
- if (PIM_DEBUG_MROUTE_DETAIL) {
- pim_inet4_dump("<src?>", ip_hdr->ip_src, ip_src_str, sizeof(ip_src_str));
- pim_inet4_dump("<dst?>", ip_hdr->ip_dst, ip_dst_str, sizeof(ip_dst_str));
-
- zlog_warn("%s: igmp kernel upcall could not find usable interface for %s -> %s",
- __PRETTY_FUNCTION__,
- ip_src_str,
- ip_dst_str);
- }
- return 0;
- }
- pim_ifp = ifp->info;
- ifaddr = pim_find_primary_addr(ifp);
- igmp = pim_igmp_sock_lookup_ifaddr(pim_ifp->igmp_socket_list, ifaddr);
-
- if (PIM_DEBUG_MROUTE) {
- pim_inet4_dump("<src?>", ip_hdr->ip_src, ip_src_str, sizeof(ip_src_str));
- pim_inet4_dump("<dst?>", ip_hdr->ip_dst, ip_dst_str, sizeof(ip_dst_str));
-
- zlog_warn("%s: igmp kernel upcall on %s(%p) for %s -> %s",
- __PRETTY_FUNCTION__, ifp->name, igmp, ip_src_str, ip_dst_str);
- }
- if (igmp)
- pim_igmp_packet(igmp, (char *)buf, buf_size);
-
- } else if (ip_hdr->ip_p) {
- if (PIM_DEBUG_MROUTE_DETAIL) {
- pim_inet4_dump("<src?>", ip_hdr->ip_src, src_str, sizeof(src_str));
- pim_inet4_dump("<grp?>", ip_hdr->ip_dst, grp_str, sizeof(grp_str));
- zlog_debug("%s: no kernel upcall proto=%d src: %s dst: %s msg_size=%d",
- __PRETTY_FUNCTION__, ip_hdr->ip_p, src_str, grp_str, buf_size);
- }
-
- } else {
- msg = (const struct igmpmsg *) buf;
-
- ifp = pim_if_find_by_vif_index(msg->im_vif);
-
- if (!ifp)
- return 0;
- if (PIM_DEBUG_MROUTE) {
- pim_inet4_dump("<src?>", msg->im_src, src_str, sizeof(src_str));
- pim_inet4_dump("<grp?>", msg->im_dst, grp_str, sizeof(grp_str));
- zlog_warn("%s: pim kernel upcall %s type=%d ip_p=%d from fd=%d for (S,G)=(%s,%s) on %s vifi=%d size=%d",
- __PRETTY_FUNCTION__,
- igmpmsgtype2str[msg->im_msgtype],
- msg->im_msgtype,
- ip_hdr->ip_p,
- fd,
- src_str,
- grp_str,
- ifp->name,
- msg->im_vif, buf_size);
- }
-
- switch (msg->im_msgtype) {
- case IGMPMSG_WRONGVIF:
- return pim_mroute_msg_wrongvif(fd, ifp, msg);
- break;
- case IGMPMSG_NOCACHE:
- return pim_mroute_msg_nocache(fd, ifp, msg);
- break;
- case IGMPMSG_WHOLEPKT:
- return pim_mroute_msg_wholepkt(fd, ifp, (const char *)msg);
- break;
- case IGMPMSG_WRVIFWHOLE:
- return pim_mroute_msg_wrvifwhole (fd, ifp, (const char *)msg);
- break;
- default:
- break;
- }
- }
+ struct interface *ifp;
+ struct pim_interface *pim_ifp;
+ const struct ip *ip_hdr;
+ const struct igmpmsg *msg;
+ char ip_src_str[INET_ADDRSTRLEN] = "";
+ char ip_dst_str[INET_ADDRSTRLEN] = "";
+ char src_str[INET_ADDRSTRLEN] = "<src?>";
+ char grp_str[INET_ADDRSTRLEN] = "<grp?>";
+ struct in_addr ifaddr;
+ struct igmp_sock *igmp;
+
+ ip_hdr = (const struct ip *)buf;
+
+ if (ip_hdr->ip_p == IPPROTO_IGMP) {
+
+ /* We have the IP packet but we do not know which interface this
+ * packet was
+ * received on. Find the interface that is on the same subnet as
+ * the source
+ * of the IP packet.
+ */
+ ifp = pim_if_lookup_address_vrf(ip_hdr->ip_src, VRF_DEFAULT);
+
+ if (!ifp) {
+ if (PIM_DEBUG_MROUTE_DETAIL) {
+ pim_inet4_dump("<src?>", ip_hdr->ip_src,
+ ip_src_str, sizeof(ip_src_str));
+ pim_inet4_dump("<dst?>", ip_hdr->ip_dst,
+ ip_dst_str, sizeof(ip_dst_str));
+
+ zlog_warn(
+ "%s: igmp kernel upcall could not find usable interface for %s -> %s",
+ __PRETTY_FUNCTION__, ip_src_str,
+ ip_dst_str);
+ }
+ return 0;
+ }
+ pim_ifp = ifp->info;
+ ifaddr = pim_find_primary_addr(ifp);
+ igmp = pim_igmp_sock_lookup_ifaddr(pim_ifp->igmp_socket_list,
+ ifaddr);
+
+ if (PIM_DEBUG_MROUTE) {
+ pim_inet4_dump("<src?>", ip_hdr->ip_src, ip_src_str,
+ sizeof(ip_src_str));
+ pim_inet4_dump("<dst?>", ip_hdr->ip_dst, ip_dst_str,
+ sizeof(ip_dst_str));
+
+ zlog_warn(
+ "%s: igmp kernel upcall on %s(%p) for %s -> %s",
+ __PRETTY_FUNCTION__, ifp->name, igmp,
+ ip_src_str, ip_dst_str);
+ }
+ if (igmp)
+ pim_igmp_packet(igmp, (char *)buf, buf_size);
+
+ } else if (ip_hdr->ip_p) {
+ if (PIM_DEBUG_MROUTE_DETAIL) {
+ pim_inet4_dump("<src?>", ip_hdr->ip_src, src_str,
+ sizeof(src_str));
+ pim_inet4_dump("<grp?>", ip_hdr->ip_dst, grp_str,
+ sizeof(grp_str));
+ zlog_debug(
+ "%s: no kernel upcall proto=%d src: %s dst: %s msg_size=%d",
+ __PRETTY_FUNCTION__, ip_hdr->ip_p, src_str,
+ grp_str, buf_size);
+ }
+
+ } else {
+ msg = (const struct igmpmsg *)buf;
+
+ ifp = pim_if_find_by_vif_index(msg->im_vif);
+
+ if (!ifp)
+ return 0;
+ if (PIM_DEBUG_MROUTE) {
+ pim_inet4_dump("<src?>", msg->im_src, src_str,
+ sizeof(src_str));
+ pim_inet4_dump("<grp?>", msg->im_dst, grp_str,
+ sizeof(grp_str));
+ zlog_warn(
+ "%s: pim kernel upcall %s type=%d ip_p=%d from fd=%d for (S,G)=(%s,%s) on %s vifi=%d size=%d",
+ __PRETTY_FUNCTION__,
+ igmpmsgtype2str[msg->im_msgtype],
+ msg->im_msgtype, ip_hdr->ip_p, fd, src_str,
+ grp_str, ifp->name, msg->im_vif, buf_size);
+ }
+
+ switch (msg->im_msgtype) {
+ case IGMPMSG_WRONGVIF:
+ return pim_mroute_msg_wrongvif(fd, ifp, msg);
+ break;
+ case IGMPMSG_NOCACHE:
+ return pim_mroute_msg_nocache(fd, ifp, msg);
+ break;
+ case IGMPMSG_WHOLEPKT:
+ return pim_mroute_msg_wholepkt(fd, ifp,
+ (const char *)msg);
+ break;
+ case IGMPMSG_WRVIFWHOLE:
+ return pim_mroute_msg_wrvifwhole(fd, ifp,
+ (const char *)msg);
+ break;
+ default:
+ break;
+ }
+ }
- return 0;
+ return 0;
}
static int mroute_read(struct thread *t)
{
- static long long count;
- char buf[10000];
- int result = 0;
- int cont = 1;
- int fd;
- int rd;
-
- fd = THREAD_FD(t);
-
- while (cont)
- {
- rd = read(fd, buf, sizeof(buf));
- if (rd < 0) {
- if (errno == EINTR)
- continue;
- if (errno == EWOULDBLOCK || errno == EAGAIN)
- break;
-
- if (PIM_DEBUG_MROUTE)
- zlog_warn("%s: failure reading fd=%d: errno=%d: %s",
- __PRETTY_FUNCTION__, fd, errno, safe_strerror(errno));
- goto done;
- }
-
- result = pim_mroute_msg(fd, buf, rd);
-
- count++;
- if (count % qpim_packet_process == 0)
- cont = 0;
- }
- /* Keep reading */
- done:
- mroute_read_on();
+ static long long count;
+ char buf[10000];
+ int result = 0;
+ int cont = 1;
+ int fd;
+ int rd;
+
+ fd = THREAD_FD(t);
+
+ while (cont) {
+ rd = read(fd, buf, sizeof(buf));
+ if (rd < 0) {
+ if (errno == EINTR)
+ continue;
+ if (errno == EWOULDBLOCK || errno == EAGAIN)
+ break;
+
+ if (PIM_DEBUG_MROUTE)
+ zlog_warn(
+ "%s: failure reading fd=%d: errno=%d: %s",
+ __PRETTY_FUNCTION__, fd, errno,
+ safe_strerror(errno));
+ goto done;
+ }
+
+ result = pim_mroute_msg(fd, buf, rd);
+
+ count++;
+ if (count % qpim_packet_process == 0)
+ cont = 0;
+ }
+/* Keep reading */
+done:
+ mroute_read_on();
- return result;
+ return result;
}
static void mroute_read_on()
{
- thread_add_read(master, mroute_read, 0, qpim_mroute_socket_fd,
- &qpim_mroute_socket_reader);
+ thread_add_read(master, mroute_read, 0, qpim_mroute_socket_fd,
+ &qpim_mroute_socket_reader);
}
static void mroute_read_off()
{
- THREAD_OFF(qpim_mroute_socket_reader);
+ THREAD_OFF(qpim_mroute_socket_reader);
}
int pim_mroute_socket_enable()
{
- int fd;
+ int fd;
- if ( pimd_privs.change (ZPRIVS_RAISE) )
- zlog_err ("pim_mroute_socket_enable: could not raise privs, %s",
- safe_strerror (errno) );
+ if (pimd_privs.change(ZPRIVS_RAISE))
+ zlog_err("pim_mroute_socket_enable: could not raise privs, %s",
+ safe_strerror(errno));
- fd = socket(AF_INET, SOCK_RAW, IPPROTO_IGMP);
+ fd = socket(AF_INET, SOCK_RAW, IPPROTO_IGMP);
- if ( pimd_privs.change (ZPRIVS_LOWER) )
- zlog_err ("pim_mroute_socket_enable: could not lower privs, %s",
- safe_strerror (errno) );
+ 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;
- }
+ if (fd < 0) {
+ zlog_warn("Could not create mroute socket: errno=%d: %s", errno,
+ safe_strerror(errno));
+ return -2;
+ }
- if (pim_mroute_set(fd, 1)) {
- zlog_warn("Could not enable mroute on socket fd=%d: errno=%d: %s",
- fd, errno, safe_strerror(errno));
- close(fd);
- return -3;
- }
+ if (pim_mroute_set(fd, 1)) {
+ zlog_warn(
+ "Could not enable mroute on socket fd=%d: errno=%d: %s",
+ fd, errno, safe_strerror(errno));
+ close(fd);
+ return -3;
+ }
- qpim_mroute_socket_fd = fd;
+ qpim_mroute_socket_fd = fd;
- qpim_mroute_socket_creation = pim_time_monotonic_sec();
- mroute_read_on();
+ qpim_mroute_socket_creation = pim_time_monotonic_sec();
+ mroute_read_on();
- return 0;
+ return 0;
}
int pim_mroute_socket_disable()
{
- if (pim_mroute_set(qpim_mroute_socket_fd, 0)) {
- zlog_warn("Could not disable mroute on socket fd=%d: errno=%d: %s",
- qpim_mroute_socket_fd, errno, safe_strerror(errno));
- return -2;
- }
-
- if (close(qpim_mroute_socket_fd)) {
- zlog_warn("Failure closing mroute socket: fd=%d errno=%d: %s",
- qpim_mroute_socket_fd, errno, safe_strerror(errno));
- return -3;
- }
-
- mroute_read_off();
- qpim_mroute_socket_fd = -1;
-
- return 0;
+ if (pim_mroute_set(qpim_mroute_socket_fd, 0)) {
+ zlog_warn(
+ "Could not disable mroute on socket fd=%d: errno=%d: %s",
+ qpim_mroute_socket_fd, errno, safe_strerror(errno));
+ return -2;
+ }
+
+ if (close(qpim_mroute_socket_fd)) {
+ zlog_warn("Failure closing mroute socket: fd=%d errno=%d: %s",
+ qpim_mroute_socket_fd, errno, safe_strerror(errno));
+ return -3;
+ }
+
+ mroute_read_off();
+ qpim_mroute_socket_fd = -1;
+
+ return 0;
}
/*
@@ -701,249 +726,248 @@ int pim_mroute_socket_disable()
would be used for multicast forwarding, a corresponding multicast
interface must be added to the kernel.
*/
-int pim_mroute_add_vif(struct interface *ifp, struct in_addr ifaddr, unsigned char flags)
+int pim_mroute_add_vif(struct interface *ifp, struct in_addr ifaddr,
+ unsigned char flags)
{
- struct pim_interface *pim_ifp = ifp->info;
- struct vifctl vc;
- int err;
+ struct pim_interface *pim_ifp = ifp->info;
+ struct vifctl vc;
+ int err;
- memset(&vc, 0, sizeof(vc));
- vc.vifc_vifi = pim_ifp->mroute_vif_index;
+ memset(&vc, 0, sizeof(vc));
+ vc.vifc_vifi = pim_ifp->mroute_vif_index;
#ifdef VIFF_USE_IFINDEX
- vc.vifc_lcl_ifindex = ifp->ifindex;
+ vc.vifc_lcl_ifindex = ifp->ifindex;
#else
- if (ifaddr.s_addr == INADDR_ANY) {
- zlog_warn("%s: unnumbered interfaces are not supported on this platform",
- __PRETTY_FUNCTION__);
- return -1;
- }
- memcpy(&vc.vifc_lcl_addr, &ifaddr, sizeof(vc.vifc_lcl_addr));
+ if (ifaddr.s_addr == INADDR_ANY) {
+ zlog_warn(
+ "%s: unnumbered interfaces are not supported on this platform",
+ __PRETTY_FUNCTION__);
+ return -1;
+ }
+ memcpy(&vc.vifc_lcl_addr, &ifaddr, sizeof(vc.vifc_lcl_addr));
#endif
- vc.vifc_flags = flags;
- vc.vifc_threshold = PIM_MROUTE_MIN_TTL;
- vc.vifc_rate_limit = 0;
-
-#ifdef PIM_DVMRP_TUNNEL
- if (vc.vifc_flags & VIFF_TUNNEL) {
- memcpy(&vc.vifc_rmt_addr, &vif_remote_addr, sizeof(vc.vifc_rmt_addr));
- }
+ vc.vifc_flags = flags;
+ vc.vifc_threshold = PIM_MROUTE_MIN_TTL;
+ vc.vifc_rate_limit = 0;
+
+#ifdef PIM_DVMRP_TUNNEL
+ if (vc.vifc_flags & VIFF_TUNNEL) {
+ memcpy(&vc.vifc_rmt_addr, &vif_remote_addr,
+ sizeof(vc.vifc_rmt_addr));
+ }
#endif
- err = setsockopt(qpim_mroute_socket_fd, IPPROTO_IP, MRT_ADD_VIF, (void*) &vc, sizeof(vc));
- if (err) {
- char ifaddr_str[INET_ADDRSTRLEN];
+ err = setsockopt(qpim_mroute_socket_fd, IPPROTO_IP, MRT_ADD_VIF,
+ (void *)&vc, sizeof(vc));
+ if (err) {
+ char ifaddr_str[INET_ADDRSTRLEN];
- pim_inet4_dump("<ifaddr?>", ifaddr, ifaddr_str, sizeof(ifaddr_str));
+ pim_inet4_dump("<ifaddr?>", ifaddr, ifaddr_str,
+ sizeof(ifaddr_str));
- zlog_warn("%s %s: failure: setsockopt(fd=%d,IPPROTO_IP,MRT_ADD_VIF,vif_index=%d,ifaddr=%s,flag=%d): errno=%d: %s",
- __FILE__, __PRETTY_FUNCTION__,
- qpim_mroute_socket_fd, ifp->ifindex, ifaddr_str, flags,
- errno, safe_strerror(errno));
- return -2;
- }
+ zlog_warn(
+ "%s %s: failure: setsockopt(fd=%d,IPPROTO_IP,MRT_ADD_VIF,vif_index=%d,ifaddr=%s,flag=%d): errno=%d: %s",
+ __FILE__, __PRETTY_FUNCTION__, qpim_mroute_socket_fd,
+ ifp->ifindex, ifaddr_str, flags, errno,
+ safe_strerror(errno));
+ return -2;
+ }
- return 0;
+ return 0;
}
int pim_mroute_del_vif(int vif_index)
{
- struct vifctl vc;
- int err;
-
- if (PIM_DEBUG_MROUTE)
- {
- struct interface *ifp = pim_if_find_by_vif_index (vif_index);
- zlog_debug ("%s %s: Del Vif %d (%s) ", __FILE__,
- __PRETTY_FUNCTION__, vif_index, ifp ? ifp->name : "NULL");
- }
-
- memset(&vc, 0, sizeof(vc));
- vc.vifc_vifi = vif_index;
+ struct vifctl vc;
+ int err;
+
+ if (PIM_DEBUG_MROUTE) {
+ struct interface *ifp = pim_if_find_by_vif_index(vif_index);
+ zlog_debug("%s %s: Del Vif %d (%s) ", __FILE__,
+ __PRETTY_FUNCTION__, vif_index,
+ ifp ? ifp->name : "NULL");
+ }
- err = setsockopt(qpim_mroute_socket_fd, IPPROTO_IP, MRT_DEL_VIF, (void*) &vc, sizeof(vc));
- if (err) {
- zlog_warn("%s %s: failure: setsockopt(fd=%d,IPPROTO_IP,MRT_DEL_VIF,vif_index=%d): errno=%d: %s",
- __FILE__, __PRETTY_FUNCTION__,
- qpim_mroute_socket_fd, vif_index,
- errno, safe_strerror(errno));
- return -2;
- }
+ memset(&vc, 0, sizeof(vc));
+ vc.vifc_vifi = vif_index;
+
+ err = setsockopt(qpim_mroute_socket_fd, IPPROTO_IP, MRT_DEL_VIF,
+ (void *)&vc, sizeof(vc));
+ if (err) {
+ zlog_warn(
+ "%s %s: failure: setsockopt(fd=%d,IPPROTO_IP,MRT_DEL_VIF,vif_index=%d): errno=%d: %s",
+ __FILE__, __PRETTY_FUNCTION__, qpim_mroute_socket_fd,
+ vif_index, errno, safe_strerror(errno));
+ return -2;
+ }
- return 0;
+ return 0;
}
int pim_mroute_add(struct channel_oil *c_oil, const char *name)
{
- int err;
- int orig = 0;
- int orig_iif_vif = 0;
-
- qpim_mroute_add_last = pim_time_monotonic_sec();
- ++qpim_mroute_add_events;
-
- /* Do not install route if incoming interface is undefined. */
- if (c_oil->oil.mfcc_parent >= MAXVIFS)
- {
- if (PIM_DEBUG_MROUTE)
- {
- char buf[1000];
- zlog_debug("%s(%s) %s Attempting to add vifi that is invalid to mroute table",
- __PRETTY_FUNCTION__, name, pim_channel_oil_dump (c_oil, buf, sizeof(buf)));
- }
- return -2;
- }
-
- /* The linux kernel *expects* the incoming
- * vif to be part of the outgoing list
- * in the case of a (*,G).
- */
- if (c_oil->oil.mfcc_origin.s_addr == INADDR_ANY)
- {
- orig = c_oil->oil.mfcc_ttls[c_oil->oil.mfcc_parent];
- c_oil->oil.mfcc_ttls[c_oil->oil.mfcc_parent] = 1;
- }
+ int err;
+ int orig = 0;
+ int orig_iif_vif = 0;
+
+ qpim_mroute_add_last = pim_time_monotonic_sec();
+ ++qpim_mroute_add_events;
+
+ /* Do not install route if incoming interface is undefined. */
+ if (c_oil->oil.mfcc_parent >= MAXVIFS) {
+ if (PIM_DEBUG_MROUTE) {
+ char buf[1000];
+ zlog_debug(
+ "%s(%s) %s Attempting to add vifi that is invalid to mroute table",
+ __PRETTY_FUNCTION__, name,
+ pim_channel_oil_dump(c_oil, buf, sizeof(buf)));
+ }
+ return -2;
+ }
- /*
- * If we have an unresolved cache entry for the S,G
- * it is owned by the pimreg for the incoming IIF
- * So set pimreg as the IIF temporarily to cause
- * the packets to be forwarded. Then set it
- * to the correct IIF afterwords.
- */
- if (!c_oil->installed && c_oil->oil.mfcc_origin.s_addr != INADDR_ANY &&
- c_oil->oil.mfcc_parent != 0)
- {
- orig_iif_vif = c_oil->oil.mfcc_parent;
- c_oil->oil.mfcc_parent = 0;
- }
- err = setsockopt(qpim_mroute_socket_fd, IPPROTO_IP, MRT_ADD_MFC,
- &c_oil->oil, sizeof(c_oil->oil));
+ /* The linux kernel *expects* the incoming
+ * vif to be part of the outgoing list
+ * in the case of a (*,G).
+ */
+ if (c_oil->oil.mfcc_origin.s_addr == INADDR_ANY) {
+ orig = c_oil->oil.mfcc_ttls[c_oil->oil.mfcc_parent];
+ c_oil->oil.mfcc_ttls[c_oil->oil.mfcc_parent] = 1;
+ }
- if (!err && !c_oil->installed && c_oil->oil.mfcc_origin.s_addr != INADDR_ANY &&
- orig_iif_vif != 0)
- {
- c_oil->oil.mfcc_parent = orig_iif_vif;
- err = setsockopt (qpim_mroute_socket_fd, IPPROTO_IP, MRT_ADD_MFC,
- &c_oil->oil, sizeof (c_oil->oil));
- }
+ /*
+ * If we have an unresolved cache entry for the S,G
+ * it is owned by the pimreg for the incoming IIF
+ * So set pimreg as the IIF temporarily to cause
+ * the packets to be forwarded. Then set it
+ * to the correct IIF afterwords.
+ */
+ if (!c_oil->installed && c_oil->oil.mfcc_origin.s_addr != INADDR_ANY
+ && c_oil->oil.mfcc_parent != 0) {
+ orig_iif_vif = c_oil->oil.mfcc_parent;
+ c_oil->oil.mfcc_parent = 0;
+ }
+ err = setsockopt(qpim_mroute_socket_fd, IPPROTO_IP, MRT_ADD_MFC,
+ &c_oil->oil, sizeof(c_oil->oil));
+
+ if (!err && !c_oil->installed
+ && c_oil->oil.mfcc_origin.s_addr != INADDR_ANY
+ && orig_iif_vif != 0) {
+ c_oil->oil.mfcc_parent = orig_iif_vif;
+ err = setsockopt(qpim_mroute_socket_fd, IPPROTO_IP, MRT_ADD_MFC,
+ &c_oil->oil, sizeof(c_oil->oil));
+ }
- if (c_oil->oil.mfcc_origin.s_addr == INADDR_ANY)
- c_oil->oil.mfcc_ttls[c_oil->oil.mfcc_parent] = orig;
+ if (c_oil->oil.mfcc_origin.s_addr == INADDR_ANY)
+ c_oil->oil.mfcc_ttls[c_oil->oil.mfcc_parent] = orig;
- if (err) {
- zlog_warn("%s %s: failure: setsockopt(fd=%d,IPPROTO_IP,MRT_ADD_MFC): errno=%d: %s",
- __FILE__, __PRETTY_FUNCTION__,
- qpim_mroute_socket_fd,
- errno, safe_strerror(errno));
- return -2;
- }
+ if (err) {
+ zlog_warn(
+ "%s %s: failure: setsockopt(fd=%d,IPPROTO_IP,MRT_ADD_MFC): errno=%d: %s",
+ __FILE__, __PRETTY_FUNCTION__, qpim_mroute_socket_fd,
+ errno, safe_strerror(errno));
+ return -2;
+ }
- if (PIM_DEBUG_MROUTE)
- {
- char buf[1000];
- zlog_debug("%s(%s), Added Route: %s",
- __PRETTY_FUNCTION__, name,
- pim_channel_oil_dump (c_oil, buf, sizeof(buf)));
- }
+ if (PIM_DEBUG_MROUTE) {
+ char buf[1000];
+ zlog_debug("%s(%s), Added Route: %s", __PRETTY_FUNCTION__, name,
+ pim_channel_oil_dump(c_oil, buf, sizeof(buf)));
+ }
- c_oil->installed = 1;
- return 0;
+ c_oil->installed = 1;
+ return 0;
}
-int pim_mroute_del (struct channel_oil *c_oil, const char *name)
+int pim_mroute_del(struct channel_oil *c_oil, const char *name)
{
- int err;
-
- qpim_mroute_del_last = pim_time_monotonic_sec();
- ++qpim_mroute_del_events;
+ int err;
+
+ qpim_mroute_del_last = pim_time_monotonic_sec();
+ ++qpim_mroute_del_events;
+
+ if (!c_oil->installed) {
+ if (PIM_DEBUG_MROUTE) {
+ char buf[1000];
+ zlog_debug(
+ "%s %s: vifi %d for route is %s not installed, do not need to send del req. ",
+ __FILE__, __PRETTY_FUNCTION__,
+ c_oil->oil.mfcc_parent,
+ pim_channel_oil_dump(c_oil, buf, sizeof(buf)));
+ }
+ return -2;
+ }
- if (!c_oil->installed)
- {
- if (PIM_DEBUG_MROUTE)
- {
- char buf[1000];
- zlog_debug("%s %s: vifi %d for route is %s not installed, do not need to send del req. ",
- __FILE__, __PRETTY_FUNCTION__, c_oil->oil.mfcc_parent,
- pim_channel_oil_dump (c_oil, buf, sizeof(buf)));
- }
- return -2;
- }
+ err = setsockopt(qpim_mroute_socket_fd, IPPROTO_IP, MRT_DEL_MFC,
+ &c_oil->oil, sizeof(c_oil->oil));
+ if (err) {
+ if (PIM_DEBUG_MROUTE)
+ zlog_warn(
+ "%s %s: failure: setsockopt(fd=%d,IPPROTO_IP,MRT_DEL_MFC): errno=%d: %s",
+ __FILE__, __PRETTY_FUNCTION__,
+ qpim_mroute_socket_fd, errno,
+ safe_strerror(errno));
+ return -2;
+ }
- err = setsockopt(qpim_mroute_socket_fd, IPPROTO_IP, MRT_DEL_MFC, &c_oil->oil, sizeof(c_oil->oil));
- if (err) {
- if (PIM_DEBUG_MROUTE)
- zlog_warn("%s %s: failure: setsockopt(fd=%d,IPPROTO_IP,MRT_DEL_MFC): errno=%d: %s",
- __FILE__, __PRETTY_FUNCTION__,
- qpim_mroute_socket_fd,
- errno, safe_strerror(errno));
- return -2;
- }
-
- if (PIM_DEBUG_MROUTE)
- {
- char buf[1000];
- zlog_debug("%s(%s), Deleted Route: %s",
- __PRETTY_FUNCTION__, name,
- pim_channel_oil_dump (c_oil, buf, sizeof(buf)));
- }
+ if (PIM_DEBUG_MROUTE) {
+ char buf[1000];
+ zlog_debug("%s(%s), Deleted Route: %s", __PRETTY_FUNCTION__,
+ name, pim_channel_oil_dump(c_oil, buf, sizeof(buf)));
+ }
- //Reset kernel installed flag
- c_oil->installed = 0;
+ // Reset kernel installed flag
+ c_oil->installed = 0;
- return 0;
+ return 0;
}
-void
-pim_mroute_update_counters (struct channel_oil *c_oil)
+void pim_mroute_update_counters(struct channel_oil *c_oil)
{
- struct sioc_sg_req sgreq;
-
- c_oil->cc.oldpktcnt = c_oil->cc.pktcnt;
- c_oil->cc.oldbytecnt = c_oil->cc.bytecnt;
- c_oil->cc.oldwrong_if = c_oil->cc.wrong_if;
-
- if (!c_oil->installed)
- {
- c_oil->cc.lastused = 100 * qpim_keep_alive_time;
- if (PIM_DEBUG_MROUTE)
- {
- struct prefix_sg sg;
-
- sg.src = c_oil->oil.mfcc_origin;
- sg.grp = c_oil->oil.mfcc_mcastgrp;
- if (PIM_DEBUG_MROUTE)
- zlog_debug("Channel(%s) is not installed no need to collect data from kernel",
- pim_str_sg_dump (&sg));
+ struct sioc_sg_req sgreq;
+
+ c_oil->cc.oldpktcnt = c_oil->cc.pktcnt;
+ c_oil->cc.oldbytecnt = c_oil->cc.bytecnt;
+ c_oil->cc.oldwrong_if = c_oil->cc.wrong_if;
+
+ if (!c_oil->installed) {
+ c_oil->cc.lastused = 100 * qpim_keep_alive_time;
+ if (PIM_DEBUG_MROUTE) {
+ struct prefix_sg sg;
+
+ sg.src = c_oil->oil.mfcc_origin;
+ sg.grp = c_oil->oil.mfcc_mcastgrp;
+ if (PIM_DEBUG_MROUTE)
+ zlog_debug(
+ "Channel(%s) is not installed no need to collect data from kernel",
+ pim_str_sg_dump(&sg));
+ }
+ return;
}
- return;
- }
-
- memset (&sgreq, 0, sizeof(sgreq));
- sgreq.src = c_oil->oil.mfcc_origin;
- sgreq.grp = c_oil->oil.mfcc_mcastgrp;
-
- pim_zlookup_sg_statistics (c_oil);
- if (ioctl (qpim_mroute_socket_fd, SIOCGETSGCNT, &sgreq))
- {
- if (PIM_DEBUG_MROUTE)
- {
- struct prefix_sg sg;
- sg.src = c_oil->oil.mfcc_origin;
- sg.grp = c_oil->oil.mfcc_mcastgrp;
-
- zlog_warn ("ioctl(SIOCGETSGCNT=%lu) failure for (S,G)=(%s): errno=%d: %s",
- (unsigned long)SIOCGETSGCNT,
- pim_str_sg_dump (&sg),
- errno,
- safe_strerror(errno));
+ memset(&sgreq, 0, sizeof(sgreq));
+ sgreq.src = c_oil->oil.mfcc_origin;
+ sgreq.grp = c_oil->oil.mfcc_mcastgrp;
+
+ pim_zlookup_sg_statistics(c_oil);
+ if (ioctl(qpim_mroute_socket_fd, SIOCGETSGCNT, &sgreq)) {
+ if (PIM_DEBUG_MROUTE) {
+ struct prefix_sg sg;
+
+ sg.src = c_oil->oil.mfcc_origin;
+ sg.grp = c_oil->oil.mfcc_mcastgrp;
+
+ zlog_warn(
+ "ioctl(SIOCGETSGCNT=%lu) failure for (S,G)=(%s): errno=%d: %s",
+ (unsigned long)SIOCGETSGCNT,
+ pim_str_sg_dump(&sg), errno,
+ safe_strerror(errno));
+ }
+ return;
}
- return;
- }
- c_oil->cc.pktcnt = sgreq.pktcnt;
- c_oil->cc.bytecnt = sgreq.bytecnt;
- c_oil->cc.wrong_if = sgreq.wrong_if;
+ c_oil->cc.pktcnt = sgreq.pktcnt;
+ c_oil->cc.bytecnt = sgreq.bytecnt;
+ c_oil->cc.wrong_if = sgreq.wrong_if;
- return;
+ return;
}