diff options
Diffstat (limited to 'zebra')
| -rw-r--r-- | zebra/irdp_main.c | 2 | ||||
| -rw-r--r-- | zebra/redistribute.c | 25 | ||||
| -rw-r--r-- | zebra/rib.h | 6 | ||||
| -rw-r--r-- | zebra/subdir.am | 4 | ||||
| -rw-r--r-- | zebra/zapi_msg.c | 38 | ||||
| -rw-r--r-- | zebra/zebra_fpm.c | 2 | ||||
| -rw-r--r-- | zebra/zebra_mlag_private.c | 2 | ||||
| -rw-r--r-- | zebra/zebra_mpls.c | 12 | ||||
| -rw-r--r-- | zebra/zebra_nhg.c | 94 | ||||
| -rw-r--r-- | zebra/zebra_nhg.h | 6 | ||||
| -rw-r--r-- | zebra/zebra_ptm.c | 2 | ||||
| -rw-r--r-- | zebra/zebra_rib.c | 181 | ||||
| -rw-r--r-- | zebra/zebra_routemap.c | 2 | ||||
| -rw-r--r-- | zebra/zebra_snmp.c | 2 | ||||
| -rw-r--r-- | zebra/zebra_vty.c | 29 |
15 files changed, 325 insertions, 82 deletions
diff --git a/zebra/irdp_main.c b/zebra/irdp_main.c index 600fc3f2fc..66a6bd0545 100644 --- a/zebra/irdp_main.c +++ b/zebra/irdp_main.c @@ -51,7 +51,7 @@ #include "privs.h" #include "libfrr.h" #include "lib_errors.h" -#include "version.h" +#include "lib/version.h" #include "zebra/interface.h" #include "zebra/rtadv.h" #include "zebra/rib.h" diff --git a/zebra/redistribute.c b/zebra/redistribute.c index 9e675011ee..6f24ec4225 100644 --- a/zebra/redistribute.c +++ b/zebra/redistribute.c @@ -347,17 +347,12 @@ void zebra_redistribute_add(ZAPI_HANDLER_ARGS) zvrf_id(zvrf), afi); } } else { - if (!vrf_bitmap_check(client->redist[afi][type], - zvrf_id(zvrf))) { - if (IS_ZEBRA_DEBUG_EVENT) - zlog_debug( - "%s: setting vrf %s(%u) redist bitmap", - __func__, VRF_LOGNAME(zvrf->vrf), - zvrf_id(zvrf)); - vrf_bitmap_set(client->redist[afi][type], - zvrf_id(zvrf)); - zebra_redistribute(client, type, 0, zvrf_id(zvrf), afi); - } + if (IS_ZEBRA_DEBUG_EVENT) + zlog_debug("%s: setting vrf %s(%u) redist bitmap", + __func__, VRF_LOGNAME(zvrf->vrf), + zvrf_id(zvrf)); + vrf_bitmap_set(client->redist[afi][type], zvrf_id(zvrf)); + zebra_redistribute(client, type, 0, zvrf_id(zvrf), afi); } stream_failure: @@ -374,6 +369,14 @@ void zebra_redistribute_delete(ZAPI_HANDLER_ARGS) STREAM_GETC(msg, type); STREAM_GETW(msg, instance); + if (IS_ZEBRA_DEBUG_EVENT) + zlog_debug( + "%s: client proto %s afi=%d, no longer wants %s, vrf %s(%u), instance=%d", + __func__, zebra_route_string(client->proto), afi, + zebra_route_string(type), VRF_LOGNAME(zvrf->vrf), + zvrf_id(zvrf), instance); + + if (afi == 0 || afi >= AFI_MAX) { flog_warn(EC_ZEBRA_REDISTRIBUTE_UNKNOWN_AF, "%s: Specified afi %d does not exist", __func__, afi); diff --git a/zebra/rib.h b/zebra/rib.h index e7676a1324..75d7ae1b67 100644 --- a/zebra/rib.h +++ b/zebra/rib.h @@ -426,7 +426,11 @@ extern int rib_queue_add(struct route_node *rn); struct nhg_ctx; /* Forward declaration */ -extern int rib_queue_nhg_add(struct nhg_ctx *ctx); +/* Enqueue incoming nhg from OS for processing */ +extern int rib_queue_nhg_ctx_add(struct nhg_ctx *ctx); + +/* Enqueue incoming nhg from proto daemon for processing */ +extern int rib_queue_nhe_add(struct nhg_hash_entry *nhe); extern void meta_queue_free(struct meta_queue *mq); extern int zebra_rib_labeled_unicast(struct route_entry *re); diff --git a/zebra/subdir.am b/zebra/subdir.am index 80ea9ac7b8..6fc8ef0df5 100644 --- a/zebra/subdir.am +++ b/zebra/subdir.am @@ -193,7 +193,7 @@ zebra_zebra_irdp_la_SOURCES = \ zebra_zebra_irdp_la_LDFLAGS = -avoid-version -module -shared -export-dynamic zebra_zebra_snmp_la_SOURCES = zebra/zebra_snmp.c -zebra_zebra_snmp_la_CFLAGS = $(WERROR) $(SNMP_CFLAGS) -std=gnu11 +zebra_zebra_snmp_la_CFLAGS = $(AM_CFLAGS) $(SNMP_CFLAGS) -std=gnu11 zebra_zebra_snmp_la_LDFLAGS = -avoid-version -module -shared -export-dynamic zebra_zebra_snmp_la_LIBADD = lib/libfrrsnmp.la @@ -232,7 +232,7 @@ zebra_dplane_fpm_nl_la_SOURCES = zebra/dplane_fpm_nl.c zebra_dplane_fpm_nl_la_LDFLAGS = -avoid-version -module -shared -export-dynamic zebra_dplane_fpm_nl_la_LIBADD = -vtysh_scan += $(top_srcdir)/zebra/dplane_fpm_nl.c +vtysh_scan += zebra/dplane_fpm_nl.c endif if NETLINK_DEBUG diff --git a/zebra/zapi_msg.c b/zebra/zapi_msg.c index e854d7ff3a..77a9188fe8 100644 --- a/zebra/zapi_msg.c +++ b/zebra/zapi_msg.c @@ -727,8 +727,8 @@ int zsend_nhg_notify(uint16_t type, uint16_t instance, uint32_t session_id, } if (IS_ZEBRA_DEBUG_SEND) - zlog_debug("%s: type %d, id %d, note %d", - __func__, type, id, note); + zlog_debug("%s: type %d, id %d, note %s", + __func__, type, id, zapi_nhg_notify_owner2str(note)); s = stream_new(ZEBRA_MAX_PACKET_SIZ); stream_reset(s); @@ -1921,27 +1921,35 @@ static void zread_nhg_add(ZAPI_HANDLER_ARGS) return; } - /* - * Create the nhg - */ - nhe = zebra_nhg_proto_add(api_nhg.id, api_nhg.proto, client->instance, - client->session_id, nhg, 0); + /* Create a temporary nhe */ + nhe = zebra_nhg_alloc(); + nhe->id = api_nhg.id; + nhe->type = api_nhg.proto; + nhe->zapi_instance = client->instance; + nhe->zapi_session = client->session_id; - nexthop_group_delete(&nhg); - zebra_nhg_backup_free(&bnhg); + /* Take over the list(s) of nexthops */ + nhe->nhg.nexthop = nhg->nexthop; + nhg->nexthop = NULL; + + if (bnhg) { + nhe->backup_info = bnhg; + bnhg = NULL; + } /* * TODO: * Assume fully resolved for now and install. - * * Resolution is going to need some more work. */ - /* If there's a failure, notify sender immediately */ - if (nhe == NULL) - zsend_nhg_notify(api_nhg.proto, client->instance, - client->session_id, api_nhg.id, - ZAPI_NHG_FAIL_INSTALL); + /* Enqueue to workqueue for processing */ + rib_queue_nhe_add(nhe); + + /* Free any local allocations */ + nexthop_group_delete(&nhg); + zebra_nhg_backup_free(&bnhg); + } static void zread_route_add(ZAPI_HANDLER_ARGS) diff --git a/zebra/zebra_fpm.c b/zebra/zebra_fpm.c index 5fe8934a82..07a8288605 100644 --- a/zebra/zebra_fpm.c +++ b/zebra/zebra_fpm.c @@ -29,7 +29,7 @@ #include "thread.h" #include "network.h" #include "command.h" -#include "version.h" +#include "lib/version.h" #include "jhash.h" #include "zebra/rib.h" diff --git a/zebra/zebra_mlag_private.c b/zebra/zebra_mlag_private.c index aaf93b4dc1..b1bba831d2 100644 --- a/zebra/zebra_mlag_private.c +++ b/zebra/zebra_mlag_private.c @@ -28,7 +28,7 @@ #include "thread.h" #include "frr_pthread.h" #include "libfrr.h" -#include "version.h" +#include "lib/version.h" #include "network.h" #include "lib/stream.h" diff --git a/zebra/zebra_mpls.c b/zebra/zebra_mpls.c index 6d42957b24..a923782bfe 100644 --- a/zebra/zebra_mpls.c +++ b/zebra/zebra_mpls.c @@ -2018,6 +2018,7 @@ void zebra_mpls_process_dplane_notify(struct zebra_dplane_ctx *ctx) int start_count = 0, end_count = 0; /* Installed counts */ bool changed_p = false; bool is_debug = (IS_ZEBRA_DEBUG_DPLANE | IS_ZEBRA_DEBUG_MPLS); + enum zebra_sr_policy_update_label_mode update_mode; if (is_debug) zlog_debug("LSP dplane notif, in-label %u", @@ -2091,10 +2092,21 @@ void zebra_mpls_process_dplane_notify(struct zebra_dplane_ctx *ctx) if (end_count > 0) { SET_FLAG(lsp->flags, LSP_FLAG_INSTALLED); + /* SR-TE update too */ + if (start_count == 0) + update_mode = ZEBRA_SR_POLICY_LABEL_CREATED; + else + update_mode = ZEBRA_SR_POLICY_LABEL_UPDATED; + zebra_sr_policy_label_update(lsp->ile.in_label, update_mode); + if (changed_p) dplane_lsp_notif_update(lsp, DPLANE_OP_LSP_UPDATE, ctx); } else { + /* SR-TE update too */ + zebra_sr_policy_label_update(lsp->ile.in_label, + ZEBRA_SR_POLICY_LABEL_REMOVED); + UNSET_FLAG(lsp->flags, LSP_FLAG_INSTALLED); clear_nhlfe_installed(lsp); } diff --git a/zebra/zebra_nhg.c b/zebra/zebra_nhg.c index 7edf022892..47651318a4 100644 --- a/zebra/zebra_nhg.c +++ b/zebra/zebra_nhg.c @@ -845,6 +845,8 @@ static bool zebra_nhe_find(struct nhg_hash_entry **nhe, /* return value */ SET_FLAG(backup_nhe->flags, NEXTHOP_GROUP_RECURSIVE); done: + /* Reset time since last update */ + (*nhe)->uptime = monotime(NULL); return created; } @@ -990,7 +992,7 @@ static struct nhg_ctx *nhg_ctx_new(void) return new; } -static void nhg_ctx_free(struct nhg_ctx **ctx) +void nhg_ctx_free(struct nhg_ctx **ctx) { struct nexthop *nh; @@ -1191,6 +1193,13 @@ static int nhg_ctx_process_new(struct nhg_ctx *ctx) if (IS_ZEBRA_DEBUG_NHG_DETAIL) zlog_debug("%s: nhe %p (%u) is new", __func__, nhe, nhe->id); + /* + * If daemon nhg from the kernel, add a refcnt here to indicate the + * daemon owns it. + */ + if (PROTO_OWNED(nhe)) + zebra_nhg_increment_ref(nhe); + SET_FLAG(nhe->flags, NEXTHOP_GROUP_VALID); SET_FLAG(nhe->flags, NEXTHOP_GROUP_INSTALLED); @@ -1233,7 +1242,7 @@ static int queue_add(struct nhg_ctx *ctx) if (nhg_ctx_get_status(ctx) == NHG_CTX_QUEUED) return 0; - if (rib_queue_nhg_add(ctx)) { + if (rib_queue_nhg_ctx_add(ctx)) { nhg_ctx_set_status(ctx, NHG_CTX_FAILURE); return -1; } @@ -1811,12 +1820,11 @@ static int resolve_backup_nexthops(const struct nexthop *nexthop, int i, j, idx; const struct nexthop *bnh; struct nexthop *nh, *newnh; + mpls_label_t labels[MPLS_MAX_LABELS]; + uint8_t num_labels; assert(nexthop->backup_num <= NEXTHOP_MAX_BACKUPS); - if (resolve_nhe->backup_info->nhe == NULL) - resolve_nhe->backup_info->nhe = zebra_nhg_alloc(); - /* Locate backups from the original nexthop's backup index and nhe */ for (i = 0; i < nexthop->backup_num; i++) { idx = nexthop->backup_idx[i]; @@ -1832,6 +1840,8 @@ static int resolve_backup_nexthops(const struct nexthop *nexthop, map->map[j].new_idx; resolved->backup_num++; + SET_FLAG(resolved->flags, NEXTHOP_FLAG_HAS_BACKUP); + if (IS_ZEBRA_DEBUG_RIB_DETAILED) zlog_debug("%s: found map idx orig %d, new %d", __func__, map->map[j].orig_idx, @@ -1856,9 +1866,46 @@ static int resolve_backup_nexthops(const struct nexthop *nexthop, if (bnh == NULL) continue; + if (resolve_nhe->backup_info == NULL) + resolve_nhe->backup_info = zebra_nhg_backup_alloc(); + /* Update backup info in the resolving nexthop and its nhe */ newnh = nexthop_dup_no_recurse(bnh, NULL); + /* We may need some special handling for mpls labels: the new + * backup needs to carry the recursive nexthop's labels, + * if any: they may be vrf labels e.g. + * The original/inner labels are in the stack of 'resolve_nhe', + * if that is longer than the stack in 'nexthop'. + */ + if (newnh->nh_label && resolved->nh_label && + nexthop->nh_label) { + if (resolved->nh_label->num_labels > + nexthop->nh_label->num_labels) { + /* Prepare new label stack */ + num_labels = 0; + for (j = 0; j < newnh->nh_label->num_labels; + j++) { + labels[j] = newnh->nh_label->label[j]; + num_labels++; + } + + /* Include inner labels */ + for (j = nexthop->nh_label->num_labels; + j < resolved->nh_label->num_labels; + j++) { + labels[num_labels] = + resolved->nh_label->label[j]; + num_labels++; + } + + /* Replace existing label stack in the backup */ + nexthop_del_labels(newnh); + nexthop_add_labels(newnh, bnh->nh_label_type, + num_labels, labels); + } + } + /* Need to compute the new backup index in the new * backup list, and add to map struct. */ @@ -1871,6 +1918,7 @@ static int resolve_backup_nexthops(const struct nexthop *nexthop, } nh->next = newnh; + j++; } else /* First one */ resolve_nhe->backup_info->nhe->nhg.nexthop = newnh; @@ -1879,6 +1927,8 @@ static int resolve_backup_nexthops(const struct nexthop *nexthop, resolved->backup_idx[resolved->backup_num] = j; resolved->backup_num++; + SET_FLAG(resolved->flags, NEXTHOP_FLAG_HAS_BACKUP); + if (IS_ZEBRA_DEBUG_RIB_DETAILED) zlog_debug("%s: added idx orig %d, new %d", __func__, idx, j); @@ -2559,7 +2609,7 @@ int nexthop_active_update(struct route_node *rn, struct route_entry *re) struct nhg_hash_entry *curr_nhe; uint32_t curr_active = 0, backup_active = 0; - if (re->nhe->id >= ZEBRA_NHG_PROTO_LOWER) + if (PROTO_OWNED(re->nhe)) return proto_nhg_nexthop_active_update(&re->nhe->nhg); afi_t rt_afi = family2afi(rn->p.family); @@ -2861,13 +2911,13 @@ void zebra_nhg_dplane_result(struct zebra_dplane_ctx *ctx) zebra_nhg_handle_install(nhe); /* If daemon nhg, send it an update */ - if (nhe->id >= ZEBRA_NHG_PROTO_LOWER) + if (PROTO_OWNED(nhe)) zsend_nhg_notify(nhe->type, nhe->zapi_instance, nhe->zapi_session, nhe->id, ZAPI_NHG_INSTALLED); } else { /* If daemon nhg, send it an update */ - if (nhe->id >= ZEBRA_NHG_PROTO_LOWER) + if (PROTO_OWNED(nhe)) zsend_nhg_notify(nhe->type, nhe->zapi_instance, nhe->zapi_session, nhe->id, ZAPI_NHG_FAIL_INSTALL); @@ -2927,7 +2977,31 @@ static void zebra_nhg_sweep_entry(struct hash_bucket *bucket, void *arg) nhe = (struct nhg_hash_entry *)bucket->data; - /* If its being ref'd, just let it be uninstalled via a route removal */ + /* + * same logic as with routes. + * + * If older than startup time, we know we read them in from the + * kernel and have not gotten and update for them since startup + * from an upper level proto. + */ + if (zrouter.startup_time < nhe->uptime) + return; + + /* + * If it's proto-owned and not being used by a route, remove it since + * we haven't gotten an update about it from the proto since startup. + * This means that either the config for it was removed or the daemon + * didn't get started. This handles graceful restart & retain scenario. + */ + if (PROTO_OWNED(nhe) && nhe->refcnt == 1) { + zebra_nhg_decrement_ref(nhe); + return; + } + + /* + * If its being ref'd by routes, just let it be uninstalled via a route + * removal. + */ if (ZEBRA_NHG_CREATED(nhe) && nhe->refcnt <= 0) zebra_nhg_uninstall_kernel(nhe); } @@ -3201,7 +3275,7 @@ static void zebra_nhg_score_proto_entry(struct hash_bucket *bucket, void *arg) iter = arg; /* Needs to match type and outside zebra ID space */ - if (nhe->type == iter->type && nhe->id >= ZEBRA_NHG_PROTO_LOWER) { + if (nhe->type == iter->type && PROTO_OWNED(nhe)) { if (IS_ZEBRA_DEBUG_NHG_DETAIL) zlog_debug( "%s: found nhe %p (%u), vrf %d, type %s after client disconnect", diff --git a/zebra/zebra_nhg.h b/zebra/zebra_nhg.h index 38015bf557..3fbf778be2 100644 --- a/zebra/zebra_nhg.h +++ b/zebra/zebra_nhg.h @@ -51,6 +51,9 @@ struct nhg_hash_entry { afi_t afi; vrf_id_t vrf_id; + /* Time since last update */ + time_t uptime; + /* Source protocol - zebra or another daemon */ int type; @@ -147,6 +150,8 @@ enum nhg_type { /* Is this an NHE owned by zebra and not an upper level protocol? */ #define ZEBRA_OWNED(NHE) (NHE->type == ZEBRA_ROUTE_NHG) +#define PROTO_OWNED(NHE) (NHE->id >= ZEBRA_NHG_PROTO_LOWER) + /* * Backup nexthops: this is a group object itself, so * that the backup nexthops can use the same code as a normal object. @@ -269,6 +274,7 @@ extern bool zebra_nhg_hash_id_equal(const void *arg1, const void *arg2); * the rib meta queue. */ extern int nhg_ctx_process(struct nhg_ctx *ctx); +void nhg_ctx_free(struct nhg_ctx **ctx); /* Find via kernel nh creation */ extern int zebra_nhg_kernel_find(uint32_t id, struct nexthop *nh, diff --git a/zebra/zebra_ptm.c b/zebra/zebra_ptm.c index bea855d1af..37d9399054 100644 --- a/zebra/zebra_ptm.c +++ b/zebra/zebra_ptm.c @@ -31,7 +31,7 @@ #include "ptm_lib.h" #include "rib.h" #include "stream.h" -#include "version.h" +#include "lib/version.h" #include "vrf.h" #include "vty.h" #include "lib_errors.h" diff --git a/zebra/zebra_rib.c b/zebra/zebra_rib.c index 82a0e6d015..bdacd411bd 100644 --- a/zebra/zebra_rib.c +++ b/zebra/zebra_rib.c @@ -62,6 +62,7 @@ DEFINE_MGROUP(ZEBRA, "zebra"); DEFINE_MTYPE(ZEBRA, RE, "Route Entry"); DEFINE_MTYPE_STATIC(ZEBRA, RIB_DEST, "RIB destination"); DEFINE_MTYPE_STATIC(ZEBRA, RIB_UPDATE_CTX, "Rib update context object"); +DEFINE_MTYPE_STATIC(ZEBRA, WQ_NHG_WRAPPER, "WQ nhg wrapper"); /* * Event, list, and mutex for delivery of dataplane results @@ -117,6 +118,20 @@ static const struct { /* no entry/default: 150 */ }; +/* Wrapper struct for nhg workqueue items; a 'ctx' is an incoming update + * from the OS, and an 'nhe' is a nhe update. + */ +struct wq_nhg_wrapper { + int type; + union { + struct nhg_ctx *ctx; + struct nhg_hash_entry *nhe; + } u; +}; + +#define WQ_NHG_WRAPPER_TYPE_CTX 0x01 +#define WQ_NHG_WRAPPER_TYPE_NHG 0x02 + static void PRINTFRR(5, 6) _rnode_zlog(const char *_func, vrf_id_t vrf_id, struct route_node *rn, int priority, const char *msgfmt, ...) @@ -908,6 +923,7 @@ static void rib_process_update_fib(struct zebra_vrf *zvrf, if (nh_active) { if (IS_ZEBRA_DEBUG_RIB) { char buf[SRCDEST2STR_BUFFER]; + srcdest_rnode2str(rn, buf, sizeof(buf)); if (new != old) zlog_debug( @@ -1068,12 +1084,6 @@ static struct route_entry *rib_choose_best(struct route_entry *current, return current; } -/* Core function for processing nexthop group contexts's off metaq */ -static void rib_nhg_process(struct nhg_ctx *ctx) -{ - nhg_ctx_process(ctx); -} - /* Core function for processing routing information base. */ static void rib_process(struct route_node *rn) { @@ -2289,21 +2299,60 @@ done: dplane_ctx_fini(&ctx); } +/* + * Process the nexthop-group workqueue subqueue + */ static void process_subq_nhg(struct listnode *lnode) { - struct nhg_ctx *ctx = NULL; + struct nhg_ctx *ctx; + struct nhg_hash_entry *nhe, *newnhe; + struct wq_nhg_wrapper *w; uint8_t qindex = route_info[ZEBRA_ROUTE_NHG].meta_q_map; - ctx = listgetdata(lnode); + w = listgetdata(lnode); - if (!ctx) + if (!w) return; - if (IS_ZEBRA_DEBUG_RIB_DETAILED) - zlog_debug("NHG Context id=%u dequeued from sub-queue %u", - ctx->id, qindex); + /* Two types of object - an update from the local kernel, or + * an nhg update from a daemon. + */ + if (w->type == WQ_NHG_WRAPPER_TYPE_CTX) { + ctx = w->u.ctx; + + if (IS_ZEBRA_DEBUG_RIB_DETAILED) + zlog_debug( + "NHG Context id=%u dequeued from sub-queue %u", + ctx->id, qindex); + + + /* Process nexthop group updates coming 'up' from the OS */ + nhg_ctx_process(ctx); - rib_nhg_process(ctx); + } else if (w->type == WQ_NHG_WRAPPER_TYPE_NHG) { + nhe = w->u.nhe; + + if (IS_ZEBRA_DEBUG_RIB_DETAILED) + zlog_debug("NHG %u dequeued from sub-queue %u", + nhe->id, qindex); + + /* Process incoming nhg update, probably from a proto daemon */ + newnhe = zebra_nhg_proto_add(nhe->id, nhe->type, + nhe->zapi_instance, + nhe->zapi_session, + &nhe->nhg, 0); + + /* Report error to daemon via ZAPI */ + if (newnhe == NULL) + zsend_nhg_notify(nhe->type, nhe->zapi_instance, + nhe->zapi_session, nhe->id, + ZAPI_NHG_FAIL_INSTALL); + + /* Free temp nhe - we own that memory. */ + zebra_nhg_free(nhe); + } + + XFREE(MTYPE_WQ_NHG_WRAPPER, w); } static void process_subq_route(struct listnode *lnode, uint8_t qindex) @@ -2335,8 +2384,8 @@ static void process_subq_route(struct listnode *lnode, uint8_t qindex) srcdest_rnode2str(rnode, buf, sizeof(buf)); zlog_debug("%s(%u:%u):%s: rn %p dequeued from sub-queue %u", - zvrf_name(zvrf), zvrf_id(zvrf), re ? re->table : 0, buf, - rnode, qindex); + zvrf_name(zvrf), zvrf_id(zvrf), re ? re->table : 0, + buf, rnode, qindex); } if (rnode->info) @@ -2369,8 +2418,7 @@ static unsigned int process_subq(struct list *subq, uint8_t qindex) /* Dispatch the meta queue by picking, processing and unlocking the next RN from * a non-empty sub-queue with lowest priority. wq is equal to zebra->ribq and - * data - * is pointed to the meta queue structure. + * data is pointed to the meta queue structure. */ static wq_item_status meta_queue_process(struct work_queue *dummy, void *data) { @@ -2463,17 +2511,23 @@ static int rib_meta_queue_add(struct meta_queue *mq, void *data) return 0; } -static int rib_meta_queue_nhg_add(struct meta_queue *mq, void *data) +static int rib_meta_queue_nhg_ctx_add(struct meta_queue *mq, void *data) { struct nhg_ctx *ctx = NULL; uint8_t qindex = route_info[ZEBRA_ROUTE_NHG].meta_q_map; + struct wq_nhg_wrapper *w; ctx = (struct nhg_ctx *)data; if (!ctx) return -1; - listnode_add(mq->subq[qindex], ctx); + w = XCALLOC(MTYPE_WQ_NHG_WRAPPER, sizeof(struct wq_nhg_wrapper)); + + w->type = WQ_NHG_WRAPPER_TYPE_CTX; + w->u.ctx = ctx; + + listnode_add(mq->subq[qindex], w); mq->size++; if (IS_ZEBRA_DEBUG_RIB_DETAILED) @@ -2483,6 +2537,32 @@ static int rib_meta_queue_nhg_add(struct meta_queue *mq, void *data) return 0; } +static int rib_meta_queue_nhg_add(struct meta_queue *mq, void *data) +{ + struct nhg_hash_entry *nhe = NULL; + uint8_t qindex = route_info[ZEBRA_ROUTE_NHG].meta_q_map; + struct wq_nhg_wrapper *w; + + nhe = (struct nhg_hash_entry *)data; + + if (!nhe) + return -1; + + w = XCALLOC(MTYPE_WQ_NHG_WRAPPER, sizeof(struct wq_nhg_wrapper)); + + w->type = WQ_NHG_WRAPPER_TYPE_NHG; + w->u.nhe = nhe; + + listnode_add(mq->subq[qindex], w); + mq->size++; + + if (IS_ZEBRA_DEBUG_RIB_DETAILED) + zlog_debug("NHG id=%u queued into sub-queue %u", + nhe->id, qindex); + + return 0; +} + static int mq_add_handler(void *data, int (*mq_add_func)(struct meta_queue *mq, void *data)) { @@ -2520,14 +2600,50 @@ int rib_queue_add(struct route_node *rn) return -1; } - return mq_add_handler(rn, &rib_meta_queue_add); + return mq_add_handler(rn, rib_meta_queue_add); } -int rib_queue_nhg_add(struct nhg_ctx *ctx) +/* + * Enqueue incoming nhg info from OS for processing + */ +int rib_queue_nhg_ctx_add(struct nhg_ctx *ctx) { assert(ctx); - return mq_add_handler(ctx, &rib_meta_queue_nhg_add); + return mq_add_handler(ctx, rib_meta_queue_nhg_ctx_add); +} + +/* + * Enqueue incoming nhg from proto daemon for processing + */ +int rib_queue_nhe_add(struct nhg_hash_entry *nhe) +{ + if (nhe == NULL) + return -1; + + return mq_add_handler(nhe, rib_meta_queue_nhg_add); +} + +/* Clean up the nhg meta-queue list */ +static void nhg_meta_queue_free(struct list *l) +{ + struct wq_nhg_wrapper *w; + struct listnode *node; + + /* Free the node wrapper object, and the struct it wraps */ + while ((node = listhead(l)) != NULL) { + w = node->data; + node->data = NULL; + + if (w->type == WQ_NHG_WRAPPER_TYPE_CTX) + nhg_ctx_free(&w->u.ctx); + else if (w->type == WQ_NHG_WRAPPER_TYPE_NHG) + zebra_nhg_free(w->u.nhe); + + XFREE(MTYPE_WQ_NHG_WRAPPER, w); + + list_delete_node(l, node); + } } /* Create new meta queue. @@ -2552,8 +2668,13 @@ void meta_queue_free(struct meta_queue *mq) { unsigned i; - for (i = 0; i < MQ_SIZE; i++) + for (i = 0; i < MQ_SIZE; i++) { + /* Some subqueues may need cleanup - nhgs for example */ + if (i == route_info[ZEBRA_ROUTE_NHG].meta_q_map) + nhg_meta_queue_free(mq->subq[i]); + list_delete(&mq->subq[i]); + } XFREE(MTYPE_WORK_QUEUE, mq); } @@ -2765,6 +2886,7 @@ static void _route_entry_dump_nh(const struct route_entry *re, char backup_str[50]; char wgt_str[50]; char temp_str[10]; + char label_str[MPLS_LABEL_STRLEN]; int i; struct interface *ifp; struct vrf *vrf = vrf_lookup_by_id(nexthop->vrf_id); @@ -2789,6 +2911,15 @@ static void _route_entry_dump_nh(const struct route_entry *re, break; } + /* Label stack */ + label_str[0] = '\0'; + if (nexthop->nh_label && nexthop->nh_label->num_labels > 0) { + mpls_label2str(nexthop->nh_label->num_labels, + nexthop->nh_label->label, label_str, + sizeof(label_str), 0 /*pretty*/); + strlcat(label_str, ", ", sizeof(label_str)); + } + backup_str[0] = '\0'; if (CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_HAS_BACKUP)) { snprintf(backup_str, sizeof(backup_str), "backup "); @@ -2803,9 +2934,9 @@ static void _route_entry_dump_nh(const struct route_entry *re, if (nexthop->weight) snprintf(wgt_str, sizeof(wgt_str), "wgt %d,", nexthop->weight); - zlog_debug("%s: %s %s[%u] vrf %s(%u) %s%s with flags %s%s%s%s%s%s%s%s", + zlog_debug("%s: %s %s[%u] %svrf %s(%u) %s%s with flags %s%s%s%s%s%s%s%s", straddr, (nexthop->rparent ? " NH" : "NH"), nhname, - nexthop->ifindex, vrf ? vrf->name : "Unknown", + nexthop->ifindex, label_str, vrf ? vrf->name : "Unknown", nexthop->vrf_id, wgt_str, backup_str, (CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_ACTIVE) diff --git a/zebra/zebra_routemap.c b/zebra/zebra_routemap.c index 6a42c682ad..d07a49fb6e 100644 --- a/zebra/zebra_routemap.c +++ b/zebra/zebra_routemap.c @@ -30,7 +30,7 @@ #include "plist.h" #include "nexthop.h" #include "northbound_cli.h" -#include "route_types.h" +#include "lib/route_types.h" #include "vrf.h" #include "frrstr.h" diff --git a/zebra/zebra_snmp.c b/zebra/zebra_snmp.c index 3e08d83724..6fe24dfa54 100644 --- a/zebra/zebra_snmp.c +++ b/zebra/zebra_snmp.c @@ -36,7 +36,7 @@ #include "vrf.h" #include "hook.h" #include "libfrr.h" -#include "version.h" +#include "lib/version.h" #include "zebra/rib.h" #include "zebra/zserv.h" diff --git a/zebra/zebra_vty.c b/zebra/zebra_vty.c index 283a3e52d6..8061f34d2b 100644 --- a/zebra/zebra_vty.c +++ b/zebra/zebra_vty.c @@ -445,6 +445,16 @@ static void zebra_show_ip_route_opaque(struct vty *vty, struct route_entry *re, } } +static void uptime2str(time_t uptime, char *buf, size_t bufsize) +{ + time_t cur; + + cur = monotime(NULL); + cur -= uptime; + + frrtime_to_interval(cur, buf, bufsize); +} + /* New RIB. Detailed information for IPv4 route. */ static void vty_show_ip_route_detail(struct vty *vty, struct route_node *rn, int mcast, bool use_fib, bool show_ng) @@ -499,12 +509,7 @@ static void vty_show_ip_route_detail(struct vty *vty, struct route_node *rn, vty_out(vty, ", best"); vty_out(vty, "\n"); - time_t uptime; - - uptime = monotime(NULL); - uptime -= re->uptime; - - frrtime_to_interval(uptime, buf, sizeof(buf)); + uptime2str(re->uptime, buf, sizeof(buf)); vty_out(vty, " Last update %s ago\n", buf); @@ -839,17 +844,13 @@ static void vty_show_ip_route(struct vty *vty, struct route_node *rn, json_object *json_nexthops = NULL; json_object *json_nexthop = NULL; json_object *json_route = NULL; - time_t uptime; const rib_dest_t *dest = rib_dest_from_rnode(rn); const struct nexthop_group *nhg; char up_str[MONOTIME_STRLEN]; bool first_p = true; bool nhg_from_backup = false; - uptime = monotime(NULL); - uptime -= re->uptime; - - frrtime_to_interval(uptime, up_str, sizeof(up_str)); + uptime2str(re->uptime, up_str, sizeof(up_str)); /* If showing fib information, use the fib view of the * nexthops. @@ -1339,9 +1340,13 @@ static void show_nexthop_group_out(struct vty *vty, struct nhg_hash_entry *nhe) struct nexthop *nexthop = NULL; struct nhg_connected *rb_node_dep = NULL; struct nexthop_group *backup_nhg; + char up_str[MONOTIME_STRLEN]; + + uptime2str(nhe->uptime, up_str, sizeof(up_str)); vty_out(vty, "ID: %u (%s)\n", nhe->id, zebra_route_string(nhe->type)); - vty_out(vty, " RefCnt: %d\n", nhe->refcnt); + vty_out(vty, " RefCnt: %u\n", nhe->refcnt); + vty_out(vty, " Uptime: %s\n", up_str); vty_out(vty, " VRF: %s\n", vrf_id_to_name(nhe->vrf_id)); if (CHECK_FLAG(nhe->flags, NEXTHOP_GROUP_VALID)) { |
