summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--bgpd/bgp_network.c14
-rw-r--r--bgpd/rfapi/rfapi_import.c15
-rw-r--r--pimd/pim_mroute.c76
3 files changed, 76 insertions, 29 deletions
diff --git a/bgpd/bgp_network.c b/bgpd/bgp_network.c
index df67e2a72c..1c2e686e1c 100644
--- a/bgpd/bgp_network.c
+++ b/bgpd/bgp_network.c
@@ -506,10 +506,16 @@ static void bgp_accept(struct thread *thread)
* is shutdown.
*/
if (BGP_PEER_START_SUPPRESSED(peer1)) {
- if (bgp_debug_neighbor_events(peer1))
- zlog_debug(
- "[Event] Incoming BGP connection rejected from %s due to maximum-prefix or shutdown",
- peer1->host);
+ if (bgp_debug_neighbor_events(peer1)) {
+ if (peer1->shut_during_cfg)
+ zlog_debug(
+ "[Event] Incoming BGP connection rejected from %s due to configuration being currently read in",
+ peer1->host);
+ else
+ zlog_debug(
+ "[Event] Incoming BGP connection rejected from %s due to maximum-prefix or shutdown",
+ peer1->host);
+ }
close(bgp_sock);
return;
}
diff --git a/bgpd/rfapi/rfapi_import.c b/bgpd/rfapi/rfapi_import.c
index a504405361..5c68545398 100644
--- a/bgpd/rfapi/rfapi_import.c
+++ b/bgpd/rfapi/rfapi_import.c
@@ -2337,8 +2337,7 @@ static void rfapiMonitorEncapDelete(struct bgp_path_info *vpn_bpi)
}
/*
- * quagga lib/thread.h says this must return int even though
- * it doesn't do anything with the return value
+ * Timer callback for withdraw
*/
static void rfapiWithdrawTimerVPN(struct thread *t)
{
@@ -2348,19 +2347,27 @@ static void rfapiWithdrawTimerVPN(struct thread *t)
const struct prefix *p;
struct rfapi_monitor_vpn *moved;
afi_t afi;
+ bool early_exit = false;
if (bgp == NULL) {
vnc_zlog_debug_verbose(
"%s: NULL BGP pointer, assume shutdown race condition!!!",
__func__);
- return;
+ early_exit = true;
}
- if (CHECK_FLAG(bgp->flags, BGP_FLAG_DELETE_IN_PROGRESS)) {
+ if (bgp && CHECK_FLAG(bgp->flags, BGP_FLAG_DELETE_IN_PROGRESS)) {
vnc_zlog_debug_verbose(
"%s: BGP delete in progress, assume shutdown race condition!!!",
__func__);
+ early_exit = true;
+ }
+
+ /* This callback is responsible for the withdraw object's memory */
+ if (early_exit) {
+ XFREE(MTYPE_RFAPI_WITHDRAW, wcb);
return;
}
+
assert(wcb->node);
assert(bpi);
assert(wcb->import_table);
diff --git a/pimd/pim_mroute.c b/pimd/pim_mroute.c
index af510ce29e..02b50c9af2 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)
{
@@ -145,45 +147,66 @@ 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;
- rpg = pim_ifp ? RP(pim_ifp->pim, msg->msg_im_dst) : NULL;
- /*
- * 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__);
+ 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;
}
+ 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;
+ }
+ }
+
/*
* If we've received a multicast packet that isn't connected to
* 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
@@ -204,6 +227,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
@@ -227,6 +256,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;
}