From dbd596f63755124d4e810a5289ace04bc4697c61 Mon Sep 17 00:00:00 2001 From: David Lamparter Date: Thu, 10 Mar 2022 13:59:26 +0100 Subject: [PATCH 1/3] pimd: make logs useful for input drops This path here is pretty far on top of the list of issues that operators will run into and have to debug when setting up PIM. Make the log messages actually tell what's going on. Also escalate some from `debug mroute detail` to `debug mroute`. Signed-off-by: David Lamparter --- pimd/pim_mroute.c | 47 +++++++++++++++++++++++++++++++---------------- 1 file changed, 31 insertions(+), 16 deletions(-) diff --git a/pimd/pim_mroute.c b/pimd/pim_mroute.c index af510ce29e..4fecc2a80b 100644 --- a/pimd/pim_mroute.c +++ b/pimd/pim_mroute.c @@ -148,18 +148,34 @@ int pim_mroute_msg_nocache(int fd, struct interface *ifp, const kernmsg *msg) struct pim_rpf *rpg; pim_sgaddr sg; - rpg = pim_ifp ? RP(pim_ifp->pim, msg->msg_im_dst) : NULL; + memset(&sg, 0, sizeof(sg)); + sg.src = msg->msg_im_src; + sg.grp = msg->msg_im_dst; + + if (!pim_ifp) { + if (PIM_DEBUG_MROUTE) + zlog_debug( + "%s: PIM not enabled on interface, dropping packet to %pSG", + ifp->name, &sg); + return 0; + } + + rpg = RP(pim_ifp->pim, msg->msg_im_dst); /* * If the incoming interface is unknown OR * the Interface type is SSM we don't need to * do anything here */ - if (!rpg || pim_rpf_addr_is_inaddr_any(rpg)) { - if (PIM_DEBUG_MROUTE_DETAIL) - zlog_debug( - "%s: Interface is not configured correctly to handle incoming packet: Could be !pim_ifp, !SM, !RP", - __func__); - + if (!rpg) { + if (PIM_DEBUG_MROUTE) + zlog_debug("%s: no RPF for packet to %pSG", ifp->name, + &sg); + return 0; + } + if (pim_rpf_addr_is_inaddr_any(rpg)) { + if (PIM_DEBUG_MROUTE) + zlog_debug("%s: null RPF for packet to %pSG", ifp->name, + &sg); return 0; } @@ -168,22 +184,21 @@ int pim_mroute_msg_nocache(int fd, struct interface *ifp, const kernmsg *msg) * us */ if (!pim_if_connected_to_source(ifp, msg->msg_im_src)) { - if (PIM_DEBUG_MROUTE_DETAIL) + if (PIM_DEBUG_MROUTE) zlog_debug( - "%s: Received incoming packet that doesn't originate on our seg", - __func__); + "%s: incoming packet to %pSG from non-connected source", + ifp->name, &sg); return 0; } - memset(&sg, 0, sizeof(sg)); - sg.src = msg->msg_im_src; - sg.grp = msg->msg_im_dst; - if (!(PIM_I_am_DR(pim_ifp))) { + /* unlike the other debug messages, this one is further in the + * "normal operation" category and thus under _DETAIL + */ if (PIM_DEBUG_MROUTE_DETAIL) zlog_debug( - "%s: Interface is not the DR blackholing incoming traffic for %pSG", - __func__, &sg); + "%s: not DR on interface, not forwarding traffic for %pSG", + ifp->name, &sg); /* * We are not the DR, but we are still receiving packets From d650b3c79a010ce3aa07284586c1a74fa655c18d Mon Sep 17 00:00:00 2001 From: David Lamparter Date: Wed, 1 Jun 2022 09:54:31 +0200 Subject: [PATCH 2/3] pimd: try to reinstall MFC when we get NOCACHE Whether due to a pimd bug, some expiry, or someone just deleting MFC entries, when we're in NOCACHE we *know* there's no MFC entry. Add an install call to make sure pimd's MFC view aligns with the actual kernel MFC. Signed-off-by: David Lamparter --- pimd/pim_mroute.c | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/pimd/pim_mroute.c b/pimd/pim_mroute.c index 4fecc2a80b..05e4b5da91 100644 --- a/pimd/pim_mroute.c +++ b/pimd/pim_mroute.c @@ -34,6 +34,8 @@ #include "pim_msg.h" static void mroute_read_on(struct pim_instance *pim); +static int pim_upstream_mroute_update(struct channel_oil *c_oil, + const char *name); int pim_mroute_set(struct pim_instance *pim, int enable) { @@ -147,6 +149,7 @@ int pim_mroute_msg_nocache(int fd, struct interface *ifp, const kernmsg *msg) struct pim_upstream *up; struct pim_rpf *rpg; pim_sgaddr sg; + bool desync = false; memset(&sg, 0, sizeof(sg)); sg.src = msg->msg_im_src; @@ -219,6 +222,12 @@ int pim_mroute_msg_nocache(int fd, struct interface *ifp, const kernmsg *msg) up = pim_upstream_find_or_add(&sg, ifp, PIM_UPSTREAM_FLAG_MASK_FHR, __func__); + if (up->channel_oil->installed) { + zlog_warn( + "%s: NOCACHE for %pSG, MFC entry disappeared - reinstalling", + ifp->name, &sg); + desync = true; + } /* * I moved this debug till after the actual add because @@ -242,6 +251,11 @@ int pim_mroute_msg_nocache(int fd, struct interface *ifp, const kernmsg *msg) /* if we have receiver, inherit from parent */ pim_upstream_inherited_olist_decide(pim_ifp->pim, up); + /* we just got NOCACHE from the kernel, so... MFC is not in the + * kernel for some reason or another. Try installing again. + */ + if (desync) + pim_upstream_mroute_update(up->channel_oil, __func__); return 0; } From c86b4ff4ba1241dce0b052f825383df65f64b954 Mon Sep 17 00:00:00 2001 From: David Lamparter Date: Fri, 6 May 2022 15:39:26 +0200 Subject: [PATCH 3/3] pimd: don't try to check RPF for incoming SSM data For incoming no-receiver SSM traffic, there isn't going to be a RP, much less a RPF. We should install an MFC entry with empty oif regardless, so we don't get swamped with further notifications. Signed-off-by: David Lamparter --- pimd/pim_mroute.c | 41 +++++++++++++++++++++++------------------ 1 file changed, 23 insertions(+), 18 deletions(-) diff --git a/pimd/pim_mroute.c b/pimd/pim_mroute.c index 05e4b5da91..02b50c9af2 100644 --- a/pimd/pim_mroute.c +++ b/pimd/pim_mroute.c @@ -147,7 +147,6 @@ int pim_mroute_msg_nocache(int fd, struct interface *ifp, const kernmsg *msg) { struct pim_interface *pim_ifp = ifp->info; struct pim_upstream *up; - struct pim_rpf *rpg; pim_sgaddr sg; bool desync = false; @@ -163,23 +162,29 @@ int pim_mroute_msg_nocache(int fd, struct interface *ifp, const kernmsg *msg) return 0; } - rpg = RP(pim_ifp->pim, msg->msg_im_dst); - /* - * If the incoming interface is unknown OR - * the Interface type is SSM we don't need to - * do anything here - */ - if (!rpg) { - if (PIM_DEBUG_MROUTE) - zlog_debug("%s: no RPF for packet to %pSG", ifp->name, - &sg); - return 0; - } - if (pim_rpf_addr_is_inaddr_any(rpg)) { - if (PIM_DEBUG_MROUTE) - zlog_debug("%s: null RPF for packet to %pSG", ifp->name, - &sg); - return 0; + if (!pim_is_grp_ssm(pim_ifp->pim, sg.grp)) { + /* for ASM, check that we have enough information (i.e. path + * to RP) to make a decision on what to do with this packet. + * + * for SSM, this is meaningless, everything is join-driven, + * and for NOCACHE we need to install an empty OIL MFC entry + * so the kernel doesn't keep nagging us. + */ + struct pim_rpf *rpg; + + rpg = RP(pim_ifp->pim, msg->msg_im_dst); + if (!rpg) { + if (PIM_DEBUG_MROUTE) + zlog_debug("%s: no RPF for packet to %pSG", + ifp->name, &sg); + return 0; + } + if (pim_rpf_addr_is_inaddr_any(rpg)) { + if (PIM_DEBUG_MROUTE) + zlog_debug("%s: null RPF for packet to %pSG", + ifp->name, &sg); + return 0; + } } /*