zebra: Modify lsp processing to be invoked as needed

LSP processing was a zvrf flag based upon a connected route
coming or going.  But this did not allow us to know
that we should do lsp processing other than after the meta-queue
processing was finished.

Eventually we moved meta-queue processing of do_nht_processing
to after the dataplane sent the main pthread some results.
This of course left us with a timing hole where if a connected
route came in and we received a data plane response *before*
the meta queue was processed we would not do the work as necessary.

Move the lsp processing to a flag off of the rib_dest_t. If it
is marked then we need to process lsps.

Signed-off-by: Donald Sharp <sharpd@cumulusnetworks.com>
This commit is contained in:
Donald Sharp 2019-02-08 17:14:30 -05:00
parent 50872b0804
commit a1494c250c
4 changed files with 50 additions and 27 deletions

View File

@ -272,7 +272,7 @@ void connected_up(struct interface *ifp, struct connected *ifc)
ifp->vrf_id, ifp->name,
prefix2str(&p, buf, sizeof(buf)));
}
mpls_mark_lsps_for_processing(vrf_info_lookup(ifp->vrf_id));
mpls_mark_lsps_for_processing(vrf_info_lookup(ifp->vrf_id), &p);
}
}
@ -437,7 +437,7 @@ void connected_down(struct interface *ifp, struct connected *ifc)
ifp->vrf_id, ifp->name,
prefix2str(&p, buf, sizeof(buf)));
}
mpls_mark_lsps_for_processing(vrf_info_lookup(ifp->vrf_id));
mpls_mark_lsps_for_processing(vrf_info_lookup(ifp->vrf_id), &p);
}
}
@ -471,7 +471,7 @@ static void connected_delete_helper(struct connected *ifc, struct prefix *p)
ifp->vrf_id, ifp->name,
prefix2str(p, buf, sizeof(buf)));
}
mpls_mark_lsps_for_processing(vrf_info_lookup(ifp->vrf_id));
mpls_mark_lsps_for_processing(vrf_info_lookup(ifp->vrf_id), p);
}
}

View File

@ -181,6 +181,8 @@ typedef struct rib_dest_t_ {
*/
#define RIB_DEST_UPDATE_FPM (1 << (ZEBRA_MAX_QINDEX + 2))
#define RIB_DEST_UPDATE_LSPS (1 << (ZEBRA_MAX_QINDEX + 3))
/*
* Macro to iterate over each route for a destination (prefix).
*/

View File

@ -510,28 +510,41 @@ static inline const char *nhlfe_type2str(enum lsp_types_t lsp_type)
return "Unknown";
}
static inline void mpls_mark_lsps_for_processing(struct zebra_vrf *zvrf)
static inline void mpls_mark_lsps_for_processing(struct zebra_vrf *zvrf,
struct prefix *p)
{
struct route_table *table;
struct route_node *rn;
rib_dest_t *dest;
if (!zvrf)
return;
zvrf->mpls_flags |= MPLS_FLAG_SCHEDULE_LSPS;
}
static inline void mpls_unmark_lsps_for_processing(struct zebra_vrf *zvrf)
{
if (!zvrf)
table = zvrf->table[family2afi(p->family)][SAFI_UNICAST];
if (!table)
return;
zvrf->mpls_flags &= ~MPLS_FLAG_SCHEDULE_LSPS;
rn = route_node_match(table, p);
if (!rn)
return;
dest = rib_dest_from_rnode(rn);
SET_FLAG(dest->flags, RIB_DEST_UPDATE_LSPS);
}
static inline int mpls_should_lsps_be_processed(struct zebra_vrf *zvrf)
static inline void mpls_unmark_lsps_for_processing(struct route_node *rn)
{
if (!zvrf)
return 0;
rib_dest_t *dest = rib_dest_from_rnode(rn);
return ((zvrf->mpls_flags & MPLS_FLAG_SCHEDULE_LSPS) ? 1 : 0);
UNSET_FLAG(dest->flags, RIB_DEST_UPDATE_LSPS);
}
static inline int mpls_should_lsps_be_processed(struct route_node *rn)
{
rib_dest_t *dest = rib_dest_from_rnode(rn);
return !!CHECK_FLAG(dest->flags, RIB_DEST_UPDATE_LSPS);
}
/* Global variables. */

View File

@ -1785,6 +1785,24 @@ static void rib_process(struct route_node *rn)
rib_gc_dest(rn);
}
static void zebra_rib_evaluate_mpls(struct route_node *rn)
{
rib_dest_t *dest = rib_dest_from_rnode(rn);
struct zebra_vrf *zvrf = vrf_info_lookup(VRF_DEFAULT);
if (!dest)
return;
if (CHECK_FLAG(dest->flags, RIB_DEST_UPDATE_LSPS)) {
if (IS_ZEBRA_DEBUG_MPLS)
zlog_debug(
"%u: Scheduling all LSPs upon RIB completion",
zvrf_id(zvrf));
zebra_mpls_lsp_schedule(zvrf);
mpls_unmark_lsps_for_processing(rn);
}
}
/*
* Utility to match route with dplane context data
*/
@ -2130,6 +2148,7 @@ static void rib_process_result(struct zebra_dplane_ctx *ctx)
}
zebra_rib_evaluate_rn_nexthops(rn, seq);
zebra_rib_evaluate_mpls(rn);
done:
if (rn)
@ -2184,23 +2203,12 @@ static unsigned int process_subq(struct list *subq, uint8_t qindex)
return 1;
}
/*
* Perform next-hop tracking processing after RIB updates.
*/
static void do_nht_processing(void)
{
struct zebra_vrf *zvrf;
/* Schedule LSPs for processing, if needed. */
zvrf = vrf_info_lookup(VRF_DEFAULT);
if (mpls_should_lsps_be_processed(zvrf)) {
if (IS_ZEBRA_DEBUG_MPLS)
zlog_debug(
"%u: Scheduling all LSPs upon RIB completion",
zvrf_id(zvrf));
zebra_mpls_lsp_schedule(zvrf);
mpls_unmark_lsps_for_processing(zvrf);
}
}
/* Dispatch the meta queue by picking, processing and unlocking the next RN from