From a1494c250ccf6737135f52b5bf660ca071e1c43f Mon Sep 17 00:00:00 2001 From: Donald Sharp Date: Fri, 8 Feb 2019 17:14:30 -0500 Subject: [PATCH] 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 --- zebra/connected.c | 6 +++--- zebra/rib.h | 2 ++ zebra/zebra_mpls.h | 33 +++++++++++++++++++++++---------- zebra/zebra_rib.c | 32 ++++++++++++++++++++------------ 4 files changed, 48 insertions(+), 25 deletions(-) diff --git a/zebra/connected.c b/zebra/connected.c index 128f397552..7114a3286b 100644 --- a/zebra/connected.c +++ b/zebra/connected.c @@ -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); } } diff --git a/zebra/rib.h b/zebra/rib.h index 3c68daf76c..e26831e1a6 100644 --- a/zebra/rib.h +++ b/zebra/rib.h @@ -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). */ diff --git a/zebra/zebra_mpls.h b/zebra/zebra_mpls.h index f8c6c794a4..3a131e1aaf 100644 --- a/zebra/zebra_mpls.h +++ b/zebra/zebra_mpls.h @@ -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; + table = zvrf->table[family2afi(p->family)][SAFI_UNICAST]; + if (!table) + return; + + 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 void mpls_unmark_lsps_for_processing(struct zebra_vrf *zvrf) +static inline void mpls_unmark_lsps_for_processing(struct route_node *rn) { - if (!zvrf) - return; + rib_dest_t *dest = rib_dest_from_rnode(rn); - zvrf->mpls_flags &= ~MPLS_FLAG_SCHEDULE_LSPS; + UNSET_FLAG(dest->flags, RIB_DEST_UPDATE_LSPS); } -static inline int mpls_should_lsps_be_processed(struct zebra_vrf *zvrf) +static inline int mpls_should_lsps_be_processed(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); + return !!CHECK_FLAG(dest->flags, RIB_DEST_UPDATE_LSPS); } /* Global variables. */ diff --git a/zebra/zebra_rib.c b/zebra/zebra_rib.c index adf2f3928e..557e6876e2 100644 --- a/zebra/zebra_rib.c +++ b/zebra/zebra_rib.c @@ -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 -- 2.39.5