diff options
Diffstat (limited to 'zebra/zebra_dplane.c')
| -rw-r--r-- | zebra/zebra_dplane.c | 365 |
1 files changed, 305 insertions, 60 deletions
diff --git a/zebra/zebra_dplane.c b/zebra/zebra_dplane.c index 04411fa0d2..9e9844390d 100644 --- a/zebra/zebra_dplane.c +++ b/zebra/zebra_dplane.c @@ -37,11 +37,12 @@ #include "zebra/zebra_pbr.h" #include "printfrr.h" -/* Memory type for context blocks */ +/* Memory types */ DEFINE_MTYPE_STATIC(ZEBRA, DP_CTX, "Zebra DPlane Ctx"); DEFINE_MTYPE_STATIC(ZEBRA, DP_INTF, "Zebra DPlane Intf"); DEFINE_MTYPE_STATIC(ZEBRA, DP_PROV, "Zebra DPlane Provider"); DEFINE_MTYPE_STATIC(ZEBRA, DP_NETFILTER, "Zebra Netfilter Internal Object"); +DEFINE_MTYPE_STATIC(ZEBRA, DP_NS, "DPlane NSes"); #ifndef AOK # define AOK 0 @@ -259,6 +260,14 @@ struct dplane_ctx_rule { uint8_t dsfield; struct prefix src_ip; struct prefix dst_ip; + uint8_t ip_proto; + + uint8_t action_pcp; + uint16_t action_vlan_id; + uint16_t action_vlan_flags; + + uint32_t action_queue_id; + char ifname[INTERFACE_NAMSIZ + 1]; }; @@ -323,7 +332,7 @@ struct zebra_dplane_ctx { /* Support info for different kinds of updates */ union { struct dplane_route_info rinfo; - zebra_lsp_t lsp; + struct zebra_lsp lsp; struct dplane_pw_info pw; struct dplane_br_port_info br_port; struct dplane_intf_info intf; @@ -401,6 +410,19 @@ struct zebra_dplane_provider { TAILQ_ENTRY(zebra_dplane_provider) dp_prov_link; }; +/* Declare types for list of zns info objects */ +PREDECL_DLIST(zns_info_list); + +struct dplane_zns_info { + struct zebra_dplane_info info; + + /* Read event */ + struct thread *t_read; + + /* List linkage */ + struct zns_info_list_item link; +}; + /* * Globals */ @@ -423,6 +445,9 @@ static struct zebra_dplane_globals { /* Ordered list of providers */ TAILQ_HEAD(zdg_prov_q, zebra_dplane_provider) dg_providers_q; + /* List of info about each zns */ + struct zns_info_list_head dg_zns_list; + /* Counter used to assign internal ids to providers */ uint32_t dg_provider_id; @@ -497,6 +522,9 @@ static struct zebra_dplane_globals { } zdplane_info; +/* Instantiate zns list type */ +DECLARE_DLIST(zns_info_list, struct dplane_zns_info, link); + /* * Lock and unlock for interactions with the zebra 'core' pthread */ @@ -514,7 +542,7 @@ static struct zebra_dplane_globals { static int dplane_thread_loop(struct thread *event); static void dplane_info_from_zns(struct zebra_dplane_info *ns_info, struct zebra_ns *zns); -static enum zebra_dplane_result lsp_update_internal(zebra_lsp_t *lsp, +static enum zebra_dplane_result lsp_update_internal(struct zebra_lsp *lsp, enum dplane_op_e op); static enum zebra_dplane_result pw_update_internal(struct zebra_pw *pw, enum dplane_op_e op); @@ -640,7 +668,7 @@ static void dplane_ctx_free_internal(struct zebra_dplane_ctx *ctx) case DPLANE_OP_LSP_DELETE: case DPLANE_OP_LSP_NOTIFY: { - zebra_nhlfe_t *nhlfe; + struct zebra_nhlfe *nhlfe; /* Unlink and free allocated NHLFEs */ frr_each_safe(nhlfe_list, &ctx->u.lsp.nhlfe_list, nhlfe) { @@ -689,6 +717,8 @@ static void dplane_ctx_free_internal(struct zebra_dplane_ctx *ctx) case DPLANE_OP_ADDR_INSTALL: case DPLANE_OP_ADDR_UNINSTALL: + case DPLANE_OP_INTF_ADDR_ADD: + case DPLANE_OP_INTF_ADDR_DEL: /* Maybe free label string, if allocated */ if (ctx->u.intf.label != NULL && ctx->u.intf.label != ctx->u.intf.label_buf) { @@ -1010,6 +1040,12 @@ const char *dplane_op2str(enum dplane_op_e op) case DPLANE_OP_GRE_SET: ret = "GRE_SET"; break; + + case DPLANE_OP_INTF_ADDR_ADD: + return "INTF_ADDR_ADD"; + + case DPLANE_OP_INTF_ADDR_DEL: + return "INTF_ADDR_DEL"; } return ret; @@ -1107,6 +1143,21 @@ vrf_id_t dplane_ctx_get_vrf(const struct zebra_dplane_ctx *ctx) return ctx->zd_vrf_id; } +/* In some paths we have only a namespace id */ +void dplane_ctx_set_ns_id(struct zebra_dplane_ctx *ctx, ns_id_t nsid) +{ + DPLANE_CTX_VALID(ctx); + + ctx->zd_ns_info.ns_id = nsid; +} + +ns_id_t dplane_ctx_get_ns_id(const struct zebra_dplane_ctx *ctx) +{ + DPLANE_CTX_VALID(ctx); + + return ctx->zd_ns_info.ns_id; +} + bool dplane_ctx_is_from_notif(const struct zebra_dplane_ctx *ctx) { DPLANE_CTX_VALID(ctx); @@ -1153,6 +1204,13 @@ ifindex_t dplane_ctx_get_ifindex(const struct zebra_dplane_ctx *ctx) return ctx->zd_ifindex; } +void dplane_ctx_set_ifindex(struct zebra_dplane_ctx *ctx, ifindex_t ifindex) +{ + DPLANE_CTX_VALID(ctx); + + ctx->zd_ifindex = ifindex; +} + void dplane_ctx_set_type(struct zebra_dplane_ctx *ctx, int type) { DPLANE_CTX_VALID(ctx); @@ -1511,15 +1569,14 @@ const struct nhlfe_list_head *dplane_ctx_get_backup_nhlfe_list( return &(ctx->u.lsp.backup_nhlfe_list); } -zebra_nhlfe_t *dplane_ctx_add_nhlfe(struct zebra_dplane_ctx *ctx, - enum lsp_types_t lsp_type, - enum nexthop_types_t nh_type, - const union g_addr *gate, - ifindex_t ifindex, - uint8_t num_labels, - mpls_label_t *out_labels) +struct zebra_nhlfe *dplane_ctx_add_nhlfe(struct zebra_dplane_ctx *ctx, + enum lsp_types_t lsp_type, + enum nexthop_types_t nh_type, + const union g_addr *gate, + ifindex_t ifindex, uint8_t num_labels, + mpls_label_t *out_labels) { - zebra_nhlfe_t *nhlfe; + struct zebra_nhlfe *nhlfe; DPLANE_CTX_VALID(ctx); @@ -1530,15 +1587,12 @@ zebra_nhlfe_t *dplane_ctx_add_nhlfe(struct zebra_dplane_ctx *ctx, return nhlfe; } -zebra_nhlfe_t *dplane_ctx_add_backup_nhlfe(struct zebra_dplane_ctx *ctx, - enum lsp_types_t lsp_type, - enum nexthop_types_t nh_type, - const union g_addr *gate, - ifindex_t ifindex, - uint8_t num_labels, - mpls_label_t *out_labels) +struct zebra_nhlfe *dplane_ctx_add_backup_nhlfe( + struct zebra_dplane_ctx *ctx, enum lsp_types_t lsp_type, + enum nexthop_types_t nh_type, const union g_addr *gate, + ifindex_t ifindex, uint8_t num_labels, mpls_label_t *out_labels) { - zebra_nhlfe_t *nhlfe; + struct zebra_nhlfe *nhlfe; DPLANE_CTX_VALID(ctx); @@ -1550,7 +1604,7 @@ zebra_nhlfe_t *dplane_ctx_add_backup_nhlfe(struct zebra_dplane_ctx *ctx, return nhlfe; } -const zebra_nhlfe_t * +const struct zebra_nhlfe * dplane_ctx_get_best_nhlfe(const struct zebra_dplane_ctx *ctx) { DPLANE_CTX_VALID(ctx); @@ -1558,9 +1612,9 @@ dplane_ctx_get_best_nhlfe(const struct zebra_dplane_ctx *ctx) return ctx->u.lsp.best_nhlfe; } -const zebra_nhlfe_t * +const struct zebra_nhlfe * dplane_ctx_set_best_nhlfe(struct zebra_dplane_ctx *ctx, - zebra_nhlfe_t *nhlfe) + struct zebra_nhlfe *nhlfe) { DPLANE_CTX_VALID(ctx); @@ -1672,6 +1726,13 @@ uint32_t dplane_ctx_get_intf_metric(const struct zebra_dplane_ctx *ctx) return ctx->u.intf.metric; } +void dplane_ctx_set_intf_metric(struct zebra_dplane_ctx *ctx, uint32_t metric) +{ + DPLANE_CTX_VALID(ctx); + + ctx->u.intf.metric = metric; +} + /* Is interface addr p2p? */ bool dplane_ctx_intf_is_connected(const struct zebra_dplane_ctx *ctx) { @@ -1694,6 +1755,27 @@ bool dplane_ctx_intf_is_broadcast(const struct zebra_dplane_ctx *ctx) return (ctx->u.intf.flags & DPLANE_INTF_BROADCAST); } +void dplane_ctx_intf_set_connected(struct zebra_dplane_ctx *ctx) +{ + DPLANE_CTX_VALID(ctx); + + ctx->u.intf.flags |= DPLANE_INTF_CONNECTED; +} + +void dplane_ctx_intf_set_secondary(struct zebra_dplane_ctx *ctx) +{ + DPLANE_CTX_VALID(ctx); + + ctx->u.intf.flags |= DPLANE_INTF_SECONDARY; +} + +void dplane_ctx_intf_set_broadcast(struct zebra_dplane_ctx *ctx) +{ + DPLANE_CTX_VALID(ctx); + + ctx->u.intf.flags |= DPLANE_INTF_BROADCAST; +} + const struct prefix *dplane_ctx_get_intf_addr( const struct zebra_dplane_ctx *ctx) { @@ -1702,6 +1784,14 @@ const struct prefix *dplane_ctx_get_intf_addr( return &(ctx->u.intf.prefix); } +void dplane_ctx_set_intf_addr(struct zebra_dplane_ctx *ctx, + const struct prefix *p) +{ + DPLANE_CTX_VALID(ctx); + + prefix_copy(&(ctx->u.intf.prefix), p); +} + bool dplane_ctx_intf_has_dest(const struct zebra_dplane_ctx *ctx) { DPLANE_CTX_VALID(ctx); @@ -1714,10 +1804,15 @@ const struct prefix *dplane_ctx_get_intf_dest( { DPLANE_CTX_VALID(ctx); - if (ctx->u.intf.flags & DPLANE_INTF_HAS_DEST) - return &(ctx->u.intf.dest_prefix); - else - return NULL; + return &(ctx->u.intf.dest_prefix); +} + +void dplane_ctx_set_intf_dest(struct zebra_dplane_ctx *ctx, + const struct prefix *p) +{ + DPLANE_CTX_VALID(ctx); + + prefix_copy(&(ctx->u.intf.dest_prefix), p); } bool dplane_ctx_intf_has_label(const struct zebra_dplane_ctx *ctx) @@ -1734,6 +1829,35 @@ const char *dplane_ctx_get_intf_label(const struct zebra_dplane_ctx *ctx) return ctx->u.intf.label; } +void dplane_ctx_set_intf_label(struct zebra_dplane_ctx *ctx, const char *label) +{ + size_t len; + + DPLANE_CTX_VALID(ctx); + + if (ctx->u.intf.label && ctx->u.intf.label != ctx->u.intf.label_buf) + free(ctx->u.intf.label); + + ctx->u.intf.label = NULL; + + if (label) { + ctx->u.intf.flags |= DPLANE_INTF_HAS_LABEL; + + /* Use embedded buffer if it's adequate; else allocate. */ + len = strlen(label); + + if (len < sizeof(ctx->u.intf.label_buf)) { + strlcpy(ctx->u.intf.label_buf, label, + sizeof(ctx->u.intf.label_buf)); + ctx->u.intf.label = ctx->u.intf.label_buf; + } else { + ctx->u.intf.label = strdup(label); + } + } else { + ctx->u.intf.flags &= ~DPLANE_INTF_HAS_LABEL; + } +} + /* Accessors for MAC information */ vlanid_t dplane_ctx_mac_get_vlan(const struct zebra_dplane_ctx *ctx) { @@ -1929,6 +2053,20 @@ uint32_t dplane_ctx_rule_get_old_fwmark(const struct zebra_dplane_ctx *ctx) return ctx->u.rule.old.fwmark; } +uint8_t dplane_ctx_rule_get_ipproto(const struct zebra_dplane_ctx *ctx) +{ + DPLANE_CTX_VALID(ctx); + + return ctx->u.rule.new.ip_proto; +} + +uint8_t dplane_ctx_rule_get_old_ipproto(const struct zebra_dplane_ctx *ctx) +{ + DPLANE_CTX_VALID(ctx); + + return ctx->u.rule.old.ip_proto; +} + uint8_t dplane_ctx_rule_get_dsfield(const struct zebra_dplane_ctx *ctx) { DPLANE_CTX_VALID(ctx); @@ -2166,9 +2304,9 @@ static int dplane_ctx_ns_init(struct zebra_dplane_ctx *ctx, * two messages in some 'update' cases. */ if (is_update) - zns->netlink_dplane.seq += 2; + zns->netlink_dplane_out.seq += 2; else - zns->netlink_dplane.seq++; + zns->netlink_dplane_out.seq++; #endif /* HAVE_NETLINK */ return AOK; @@ -2187,7 +2325,7 @@ int dplane_ctx_route_init(struct zebra_dplane_ctx *ctx, enum dplane_op_e op, struct zebra_ns *zns; struct zebra_vrf *zvrf; struct nexthop *nexthop; - zebra_l3vni_t *zl3vni; + struct zebra_l3vni *zl3vni; const struct interface *ifp; struct dplane_intf_extra *if_extra; @@ -2389,10 +2527,10 @@ done: * Capture information for an LSP update in a dplane context. */ int dplane_ctx_lsp_init(struct zebra_dplane_ctx *ctx, enum dplane_op_e op, - zebra_lsp_t *lsp) + struct zebra_lsp *lsp) { int ret = AOK; - zebra_nhlfe_t *nhlfe, *new_nhlfe; + struct zebra_nhlfe *nhlfe, *new_nhlfe; ctx->zd_op = op; ctx->zd_status = ZEBRA_DPLANE_REQUEST_SUCCESS; @@ -2636,8 +2774,15 @@ static void dplane_ctx_rule_init_single(struct dplane_ctx_rule *dplane_rule, dplane_rule->filter_bm = rule->rule.filter.filter_bm; dplane_rule->fwmark = rule->rule.filter.fwmark; dplane_rule->dsfield = rule->rule.filter.dsfield; + dplane_rule->ip_proto = rule->rule.filter.ip_proto; prefix_copy(&(dplane_rule->dst_ip), &rule->rule.filter.dst_ip); prefix_copy(&(dplane_rule->src_ip), &rule->rule.filter.src_ip); + + dplane_rule->action_pcp = rule->rule.action.pcp; + dplane_rule->action_vlan_flags = rule->rule.action.vlan_flags; + dplane_rule->action_vlan_id = rule->rule.action.vlan_id; + dplane_rule->action_queue_id = rule->rule.action.queue_id; + strlcpy(dplane_rule->ifname, rule->ifname, INTERFACE_NAMSIZ); } @@ -2672,7 +2817,7 @@ static int dplane_ctx_rule_init(struct zebra_dplane_ctx *ctx, ctx->zd_is_update = (op == DPLANE_OP_RULE_UPDATE); ctx->zd_vrf_id = new_rule->vrf_id; - memcpy(ctx->zd_ifname, new_rule->ifname, sizeof(new_rule->ifname)); + strlcpy(ctx->zd_ifname, new_rule->ifname, sizeof(ctx->zd_ifname)); ctx->u.rule.sock = new_rule->sock; ctx->u.rule.unique = new_rule->rule.unique; @@ -3211,7 +3356,7 @@ enum zebra_dplane_result dplane_nexthop_delete(struct nhg_hash_entry *nhe) /* * Enqueue LSP add for the dataplane. */ -enum zebra_dplane_result dplane_lsp_add(zebra_lsp_t *lsp) +enum zebra_dplane_result dplane_lsp_add(struct zebra_lsp *lsp) { enum zebra_dplane_result ret = lsp_update_internal(lsp, DPLANE_OP_LSP_INSTALL); @@ -3222,7 +3367,7 @@ enum zebra_dplane_result dplane_lsp_add(zebra_lsp_t *lsp) /* * Enqueue LSP update for the dataplane. */ -enum zebra_dplane_result dplane_lsp_update(zebra_lsp_t *lsp) +enum zebra_dplane_result dplane_lsp_update(struct zebra_lsp *lsp) { enum zebra_dplane_result ret = lsp_update_internal(lsp, DPLANE_OP_LSP_UPDATE); @@ -3233,7 +3378,7 @@ enum zebra_dplane_result dplane_lsp_update(zebra_lsp_t *lsp) /* * Enqueue LSP delete for the dataplane. */ -enum zebra_dplane_result dplane_lsp_delete(zebra_lsp_t *lsp) +enum zebra_dplane_result dplane_lsp_delete(struct zebra_lsp *lsp) { enum zebra_dplane_result ret = lsp_update_internal(lsp, DPLANE_OP_LSP_DELETE); @@ -3243,15 +3388,14 @@ enum zebra_dplane_result dplane_lsp_delete(zebra_lsp_t *lsp) /* Update or un-install resulting from an async notification */ enum zebra_dplane_result -dplane_lsp_notif_update(zebra_lsp_t *lsp, - enum dplane_op_e op, +dplane_lsp_notif_update(struct zebra_lsp *lsp, enum dplane_op_e op, struct zebra_dplane_ctx *notif_ctx) { enum zebra_dplane_result result = ZEBRA_DPLANE_REQUEST_FAILURE; int ret = EINVAL; struct zebra_dplane_ctx *ctx = NULL; struct nhlfe_list_head *head; - zebra_nhlfe_t *nhlfe, *new_nhlfe; + struct zebra_nhlfe *nhlfe, *new_nhlfe; /* Obtain context block */ ctx = dplane_ctx_alloc(); @@ -3323,7 +3467,7 @@ enum zebra_dplane_result dplane_pw_uninstall(struct zebra_pw *pw) /* * Common internal LSP update utility */ -static enum zebra_dplane_result lsp_update_internal(zebra_lsp_t *lsp, +static enum zebra_dplane_result lsp_update_internal(struct zebra_lsp *lsp, enum dplane_op_e op) { enum zebra_dplane_result result = ZEBRA_DPLANE_REQUEST_FAILURE; @@ -3479,18 +3623,6 @@ enum zebra_dplane_result dplane_intf_addr_set(const struct interface *ifp, return ZEBRA_DPLANE_REQUEST_FAILURE; } - - /* Ensure that no existing installed v4 route conflicts with - * the new interface prefix. This check must be done in the - * zebra pthread context, and any route delete (if needed) - * is enqueued before the interface address programming attempt. - */ - if (ifc->address->family == AF_INET) { - struct prefix_ipv4 *p; - - p = (struct prefix_ipv4 *)ifc->address; - rib_lookup_and_pushup(p, ifp->vrf_id); - } #endif return intf_addr_update_internal(ifp, ifc, DPLANE_OP_ADDR_INSTALL); @@ -3640,14 +3772,10 @@ enum zebra_dplane_result dplane_neigh_ip_update(enum dplane_op_e op, uint16_t state = 0; uint32_t update_flags; - if (IS_ZEBRA_DEBUG_DPLANE_DETAIL) { - char buf1[PREFIX_STRLEN], buf2[PREFIX_STRLEN]; + if (IS_ZEBRA_DEBUG_DPLANE_DETAIL) + zlog_debug("%s: init link ctx %s: ifp %s, link_ip %pIA ip %pIA", + __func__, dplane_op2str(op), ifp->name, link_ip, ip); - ipaddr2str(link_ip, buf1, sizeof(buf1)); - ipaddr2str(ip, buf2, sizeof(buf2)); - zlog_debug("init link ctx %s: ifp %s, ip %s link %s", - dplane_op2str(op), ifp->name, buf1, buf2); - } if (ndm_state == ZEBRA_NEIGH_STATE_REACHABLE) state = DPLANE_NUD_REACHABLE; else if (ndm_state == ZEBRA_NEIGH_STATE_FAILED) @@ -4714,10 +4842,92 @@ static void dplane_info_from_zns(struct zebra_dplane_info *ns_info, #if defined(HAVE_NETLINK) ns_info->is_cmd = true; - ns_info->nls = zns->netlink_dplane; + ns_info->nls = zns->netlink_dplane_out; #endif /* NETLINK */ } +#ifdef HAVE_NETLINK +/* + * Callback when an OS (netlink) incoming event read is ready. This runs + * in the dplane pthread. + */ +static int dplane_incoming_read(struct thread *event) +{ + struct dplane_zns_info *zi = THREAD_ARG(event); + + kernel_dplane_read(&zi->info); + + /* Re-start read task */ + thread_add_read(zdplane_info.dg_master, dplane_incoming_read, zi, + zi->info.nls.sock, &zi->t_read); + + return 0; +} +#endif /* HAVE_NETLINK */ + +/* + * Notify dplane when namespaces are enabled and disabled. The dplane + * needs to start and stop reading incoming events from the zns. In the + * common case where vrfs are _not_ namespaces, there will only be one + * of these. + * + * This is called in the main pthread. + */ +void zebra_dplane_ns_enable(struct zebra_ns *zns, bool enabled) +{ + struct dplane_zns_info *zi; + + if (IS_ZEBRA_DEBUG_DPLANE) + zlog_debug("%s: %s for nsid %u", __func__, + (enabled ? "ENABLED" : "DISABLED"), zns->ns_id); + + /* Search for an existing zns info entry */ + frr_each (zns_info_list, &zdplane_info.dg_zns_list, zi) { + if (zi->info.ns_id == zns->ns_id) + break; + } + + if (enabled) { + /* Create a new entry if necessary; start reading. */ + if (zi == NULL) { + zi = XCALLOC(MTYPE_DP_NS, sizeof(*zi)); + + zi->info.ns_id = zns->ns_id; + + zns_info_list_add_tail(&zdplane_info.dg_zns_list, zi); + + if (IS_ZEBRA_DEBUG_DPLANE) + zlog_debug("%s: nsid %u, new zi %p", __func__, + zns->ns_id, zi); + } + + /* Make sure we're up-to-date with the zns object */ +#if defined(HAVE_NETLINK) + zi->info.is_cmd = false; + zi->info.nls = zns->netlink_dplane_in; + + /* Start read task for the dplane pthread. */ + if (zdplane_info.dg_master) + thread_add_read(zdplane_info.dg_master, + dplane_incoming_read, zi, + zi->info.nls.sock, &zi->t_read); +#endif + } else if (zi) { + if (IS_ZEBRA_DEBUG_DPLANE) + zlog_debug("%s: nsid %u, deleting zi %p", __func__, + zns->ns_id, zi); + + /* Stop reading, free memory */ + zns_info_list_del(&zdplane_info.dg_zns_list, zi); + + if (zdplane_info.dg_master) + thread_cancel_async(zdplane_info.dg_master, &zi->t_read, + NULL); + + XFREE(MTYPE_DP_NS, zi); + } +} + /* * Provider api to signal that work/events are available * for the dataplane pthread. @@ -4883,6 +5093,14 @@ static void kernel_dplane_log_detail(struct zebra_dplane_ctx *ctx) dplane_ctx_get_ifname(ctx), ctx->u.gre.link_ifindex); break; + + case DPLANE_OP_INTF_ADDR_ADD: + case DPLANE_OP_INTF_ADDR_DEL: + zlog_debug("Dplane incoming op %s, intf %s, addr %pFX", + dplane_op2str(dplane_ctx_get_op(ctx)), + dplane_ctx_get_ifname(ctx), + dplane_ctx_get_intf_addr(ctx)); + break; } } @@ -5025,6 +5243,11 @@ static void kernel_dplane_handle_result(struct zebra_dplane_ctx *ctx) case DPLANE_OP_BR_PORT_UPDATE: break; + /* TODO -- error counters for incoming events? */ + case DPLANE_OP_INTF_ADDR_ADD: + case DPLANE_OP_INTF_ADDR_DEL: + break; + case DPLANE_OP_NONE: if (res != ZEBRA_DPLANE_REQUEST_SUCCESS) atomic_fetch_add_explicit(&zdplane_info.dg_other_errors, @@ -5360,9 +5583,21 @@ done: */ static int dplane_check_shutdown_status(struct thread *event) { + struct dplane_zns_info *zi; + if (IS_ZEBRA_DEBUG_DPLANE) zlog_debug("Zebra dataplane shutdown status check called"); + /* Remove any zns info entries as we stop the dplane pthread. */ + frr_each_safe (zns_info_list, &zdplane_info.dg_zns_list, zi) { + zns_info_list_del(&zdplane_info.dg_zns_list, zi); + + if (zdplane_info.dg_master) + thread_cancel(&zi->t_read); + + XFREE(MTYPE_DP_NS, zi); + } + if (dplane_work_pending()) { /* Reschedule dplane check on a short timer */ thread_add_timer_msec(zdplane_info.dg_master, @@ -5657,6 +5892,7 @@ static void zebra_dplane_init_internal(void) TAILQ_INIT(&zdplane_info.dg_update_ctx_q); TAILQ_INIT(&zdplane_info.dg_providers_q); + zns_info_list_init(&zdplane_info.dg_zns_list); zdplane_info.dg_updates_per_cycle = DPLANE_DEFAULT_NEW_WORK; @@ -5672,6 +5908,7 @@ static void zebra_dplane_init_internal(void) */ void zebra_dplane_start(void) { + struct dplane_zns_info *zi; struct zebra_dplane_provider *prov; struct frr_pthread_attr pattr = { .start = frr_pthread_attr_default.start, @@ -5691,6 +5928,14 @@ void zebra_dplane_start(void) thread_add_event(zdplane_info.dg_master, dplane_thread_loop, NULL, 0, &zdplane_info.dg_t_update); + /* Enqueue reads if necessary */ + frr_each (zns_info_list, &zdplane_info.dg_zns_list, zi) { +#if defined(HAVE_NETLINK) + thread_add_read(zdplane_info.dg_master, dplane_incoming_read, + zi, zi->info.nls.sock, &zi->t_read); +#endif + } + /* Call start callbacks for registered providers */ DPLANE_LOCK(); |
