pimd: Fixup kernel callbacks to handle them better

This patch sets up the handling of the 3 basic kernel callbacks:
IGMPMSG_WRONGVIF - When a multicast message comes in the wrong vif
IGMPMSG_NOCACHE - There is no multicast route associated with a received(S,G)
IGMPMSG_WHOLEPKT - There is no outgoing interface for a packet.

The code's debugs are cleaned up to be covered by debug statements

Signed-off-by: Donald Sharp <sharpd@cumulusnetworks.com>
This commit is contained in:
Donald Sharp 2015-10-20 06:00:02 -07:00 committed by Donald Sharp
parent b45cefcb44
commit e355e30fcb

View File

@ -61,40 +61,30 @@ static int pim_mroute_set(int fd, int enable)
return 0; return 0;
} }
int pim_mroute_msg(int fd, const char *buf, int buf_size) static const char *igmpmsgtype2str[IGMPMSG_WHOLEPKT + 1] = {
"<unknown_upcall?>",
"NOCACHE",
"WRONGVIF",
"WHOLEPKT", };
static int
pim_mroute_msg_nocache (int fd, struct interface *ifp, const struct igmpmsg *msg,
const char *src_str, const char *grp_str)
{ {
struct interface *ifp;
const struct ip *ip_hdr;
const struct igmpmsg *msg;
const char *upcall;
char src_str[100];
char grp_str[100];
ip_hdr = (const struct ip *) buf;
/* kernel upcall must have protocol=0 */
if (ip_hdr->ip_p) {
/* this is not a kernel upcall */
#ifdef PIM_UNEXPECTED_KERNEL_UPCALL
zlog_warn("%s: not a kernel upcall proto=%d msg_size=%d",
__PRETTY_FUNCTION__, ip_hdr->ip_p, buf_size);
#endif
return 0; return 0;
} }
msg = (const struct igmpmsg *) buf; static int
pim_mroute_msg_wholepkt (int fd, struct interface *ifp, const struct igmpmsg *msg,
switch (msg->im_msgtype) { const char *src_str, const char *grp_str)
case IGMPMSG_NOCACHE: upcall = "NOCACHE"; break; {
case IGMPMSG_WRONGVIF: upcall = "WRONGVIF"; break; return 0;
case IGMPMSG_WHOLEPKT: upcall = "WHOLEPKT"; break;
default: upcall = "<unknown_upcall?>";
} }
ifp = pim_if_find_by_vif_index(msg->im_vif);
pim_inet4_dump("<src?>", msg->im_src, src_str, sizeof(src_str));
pim_inet4_dump("<grp?>", msg->im_dst, grp_str, sizeof(grp_str));
if (msg->im_msgtype == IGMPMSG_WRONGVIF) { static int
pim_mroute_msg_wrongvif (int fd, struct interface *ifp, const struct igmpmsg *msg,
const char *src_str, const char *grp_str)
{
struct pim_ifchannel *ch; struct pim_ifchannel *ch;
struct pim_interface *pim_ifp; struct pim_interface *pim_ifp;
@ -109,36 +99,32 @@ int pim_mroute_msg(int fd, const char *buf, int buf_size)
} }
*/ */
if (PIM_DEBUG_PIM_TRACE) {
zlog_debug("%s: WRONGVIF from fd=%d for (S,G)=(%s,%s) on %s vifi=%d",
__PRETTY_FUNCTION__,
fd,
src_str,
grp_str,
ifp ? ifp->name : "<ifname?>",
msg->im_vif);
}
if (!ifp) { if (!ifp) {
zlog_warn("%s: WRONGVIF (S,G)=(%s,%s) could not find input interface for input_vif_index=%d", if (PIM_DEBUG_PIM_TRACE) {
zlog_debug("%s: WRONGVIF (S,G)=(%s,%s) could not find input interface for input_vif_index=%d",
__PRETTY_FUNCTION__, __PRETTY_FUNCTION__,
src_str, grp_str, msg->im_vif); src_str, grp_str, msg->im_vif);
}
return -1; return -1;
} }
pim_ifp = ifp->info; pim_ifp = ifp->info;
if (!pim_ifp) { if (!pim_ifp) {
zlog_warn("%s: WRONGVIF (S,G)=(%s,%s) multicast not enabled on interface %s", if (PIM_DEBUG_PIM_TRACE) {
zlog_debug("%s: WRONGVIF (S,G)=(%s,%s) multicast not enabled on interface %s",
__PRETTY_FUNCTION__, __PRETTY_FUNCTION__,
src_str, grp_str, ifp->name); src_str, grp_str, ifp->name);
}
return -2; return -2;
} }
ch = pim_ifchannel_find(ifp, msg->im_src, msg->im_dst); ch = pim_ifchannel_find(ifp, msg->im_src, msg->im_dst);
if (!ch) { if (!ch) {
zlog_warn("%s: WRONGVIF (S,G)=(%s,%s) could not find channel on interface %s", if (PIM_DEBUG_PIM_TRACE) {
zlog_debug("%s: WRONGVIF (S,G)=(%s,%s) could not find channel on interface %s",
__PRETTY_FUNCTION__, __PRETTY_FUNCTION__,
src_str, grp_str, ifp->name); src_str, grp_str, ifp->name);
}
return -3; return -3;
} }
@ -157,32 +143,65 @@ int pim_mroute_msg(int fd, const char *buf, int buf_size)
*/ */
if (ch->ifassert_state != PIM_IFASSERT_NOINFO) { if (ch->ifassert_state != PIM_IFASSERT_NOINFO) {
zlog_warn("%s: WRONGVIF (S,G)=(%s,%s) channel is not on Assert NoInfo state for interface %s", if (PIM_DEBUG_PIM_TRACE) {
zlog_debug("%s: WRONGVIF (S,G)=(%s,%s) channel is not on Assert NoInfo state for interface %s",
__PRETTY_FUNCTION__, __PRETTY_FUNCTION__,
src_str, grp_str, ifp->name); src_str, grp_str, ifp->name);
}
return -4; return -4;
} }
if (!PIM_IF_FLAG_TEST_COULD_ASSERT(ch->flags)) { if (!PIM_IF_FLAG_TEST_COULD_ASSERT(ch->flags)) {
zlog_warn("%s: WRONGVIF (S,G)=(%s,%s) interface %s is not downstream for channel", if (PIM_DEBUG_PIM_TRACE) {
zlog_debug("%s: WRONGVIF (S,G)=(%s,%s) interface %s is not downstream for channel",
__PRETTY_FUNCTION__, __PRETTY_FUNCTION__,
src_str, grp_str, ifp->name); src_str, grp_str, ifp->name);
}
return -5; return -5;
} }
if (assert_action_a1(ch)) { if (assert_action_a1(ch)) {
zlog_warn("%s: WRONGVIF (S,G)=(%s,%s) assert_action_a1 failure on interface %s", if (PIM_DEBUG_PIM_TRACE) {
zlog_debug("%s: WRONGVIF (S,G)=(%s,%s) assert_action_a1 failure on interface %s",
__PRETTY_FUNCTION__, __PRETTY_FUNCTION__,
src_str, grp_str, ifp->name); src_str, grp_str, ifp->name);
}
return -6; return -6;
} }
return 0; return 0;
} /* IGMPMSG_WRONGVIF */ }
int pim_mroute_msg(int fd, const char *buf, int buf_size)
{
struct interface *ifp;
const struct ip *ip_hdr;
const struct igmpmsg *msg;
char src_str[100] = "<src?>";
char grp_str[100] = "<grp?>";
ip_hdr = (const struct ip *) buf;
/* kernel upcall must have protocol=0 */
if (ip_hdr->ip_p) {
/* this is not a kernel upcall */
if (PIM_DEBUG_PIM_TRACE) {
zlog_debug("%s: not a kernel upcall proto=%d msg_size=%d",
__PRETTY_FUNCTION__, ip_hdr->ip_p, buf_size);
}
return 0;
}
msg = (const struct igmpmsg *) buf;
ifp = pim_if_find_by_vif_index(msg->im_vif);
if (PIM_DEBUG_PIM_TRACE) {
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: kernel upcall %s type=%d ip_p=%d from fd=%d for (S,G)=(%s,%s) on %s vifi=%d", zlog_warn("%s: kernel upcall %s type=%d ip_p=%d from fd=%d for (S,G)=(%s,%s) on %s vifi=%d",
__PRETTY_FUNCTION__, __PRETTY_FUNCTION__,
upcall, igmpmsgtype2str[msg->im_msgtype],
msg->im_msgtype, msg->im_msgtype,
ip_hdr->ip_p, ip_hdr->ip_p,
fd, fd,
@ -190,6 +209,21 @@ int pim_mroute_msg(int fd, const char *buf, int buf_size)
grp_str, grp_str,
ifp ? ifp->name : "<ifname?>", ifp ? ifp->name : "<ifname?>",
msg->im_vif); msg->im_vif);
}
switch (msg->im_msgtype) {
case IGMPMSG_WRONGVIF:
return pim_mroute_msg_wrongvif(fd, ifp, msg, src_str, grp_str);
break;
case IGMPMSG_NOCACHE:
return pim_mroute_msg_nocache(fd, ifp, msg, src_str, grp_str);
break;
case IGMPMSG_WHOLEPKT:
return pim_mroute_msg_wholepkt(fd, ifp, msg, src_str, grp_str);
break;
default:
break;
}
return 0; return 0;
} }