mirror of
https://git.proxmox.com/git/mirror_frr
synced 2025-08-13 14:42:06 +00:00
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:
parent
b45cefcb44
commit
e355e30fcb
@ -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;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user