diff --git a/pimd/pim_mroute.c b/pimd/pim_mroute.c index f1fd2ef735..3d15666dd6 100644 --- a/pimd/pim_mroute.c +++ b/pimd/pim_mroute.c @@ -47,6 +47,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) { @@ -160,19 +162,36 @@ 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; - 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; } @@ -181,22 +200,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 @@ -217,6 +235,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 @@ -240,6 +264,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; }