diff options
Diffstat (limited to 'zebra/zebra_dplane.c')
| -rw-r--r-- | zebra/zebra_dplane.c | 234 |
1 files changed, 228 insertions, 6 deletions
diff --git a/zebra/zebra_dplane.c b/zebra/zebra_dplane.c index 6fbad2f71e..928169a862 100644 --- a/zebra/zebra_dplane.c +++ b/zebra/zebra_dplane.c @@ -26,7 +26,7 @@ #include "lib/zebra.h" #include "zebra/zebra_router.h" #include "zebra/zebra_memory.h" -#include "zebra/zserv.h" +#include "zebra/zebra_router.h" #include "zebra/zebra_dplane.h" #include "zebra/rt.h" #include "zebra/debug.h" @@ -102,6 +102,23 @@ struct dplane_route_info { }; /* + * Pseudowire info for the dataplane + */ +struct dplane_pw_info { + char ifname[IF_NAMESIZE]; + ifindex_t ifindex; + int type; + int af; + int status; + uint32_t flags; + union g_addr nexthop; + mpls_label_t local_label; + mpls_label_t remote_label; + + union pw_protocol_fields fields; +}; + +/* * The context block used to exchange info about route updates across * the boundary between the zebra main context (and pthread) and the * dataplane layer (and pthread). @@ -136,6 +153,7 @@ struct zebra_dplane_ctx { union { struct dplane_route_info rinfo; zebra_lsp_t lsp; + struct dplane_pw_info pw; } u; /* Namespace info, used especially for netlink kernel communication */ @@ -237,10 +255,11 @@ static struct zebra_dplane_globals { _Atomic uint32_t dg_other_errors; _Atomic uint32_t dg_lsps_in; - _Atomic uint32_t dg_lsps_queued; - _Atomic uint32_t dg_lsps_queued_max; _Atomic uint32_t dg_lsp_errors; + _Atomic uint32_t dg_pws_in; + _Atomic uint32_t dg_pw_errors; + _Atomic uint32_t dg_update_yields; /* Dataplane pthread */ @@ -276,6 +295,8 @@ 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, enum dplane_op_e op); +static enum zebra_dplane_result pw_update_internal(struct zebra_pw *pw, + enum dplane_op_e op); /* * Public APIs @@ -363,6 +384,8 @@ static void dplane_ctx_free(struct zebra_dplane_ctx **pctx) break; } + case DPLANE_OP_PW_INSTALL: + case DPLANE_OP_PW_UNINSTALL: case DPLANE_OP_NONE: break; } @@ -490,6 +513,13 @@ const char *dplane_op2str(enum dplane_op_e op) ret = "LSP_DELETE"; break; + case DPLANE_OP_PW_INSTALL: + ret = "PW_INSTALL"; + break; + case DPLANE_OP_PW_UNINSTALL: + ret = "PW_UNINSTALL"; + break; + }; return ret; @@ -735,6 +765,71 @@ uint32_t dplane_ctx_get_lsp_num_ecmp(const struct zebra_dplane_ctx *ctx) return ctx->u.lsp.num_ecmp; } +const char *dplane_ctx_get_pw_ifname(const struct zebra_dplane_ctx *ctx) +{ + DPLANE_CTX_VALID(ctx); + + return ctx->u.pw.ifname; +} + +mpls_label_t dplane_ctx_get_pw_local_label(const struct zebra_dplane_ctx *ctx) +{ + DPLANE_CTX_VALID(ctx); + + return ctx->u.pw.local_label; +} + +mpls_label_t dplane_ctx_get_pw_remote_label(const struct zebra_dplane_ctx *ctx) +{ + DPLANE_CTX_VALID(ctx); + + return ctx->u.pw.remote_label; +} + +int dplane_ctx_get_pw_type(const struct zebra_dplane_ctx *ctx) +{ + DPLANE_CTX_VALID(ctx); + + return ctx->u.pw.type; +} + +int dplane_ctx_get_pw_af(const struct zebra_dplane_ctx *ctx) +{ + DPLANE_CTX_VALID(ctx); + + return ctx->u.pw.af; +} + +uint32_t dplane_ctx_get_pw_flags(const struct zebra_dplane_ctx *ctx) +{ + DPLANE_CTX_VALID(ctx); + + return ctx->u.pw.flags; +} + +int dplane_ctx_get_pw_status(const struct zebra_dplane_ctx *ctx) +{ + DPLANE_CTX_VALID(ctx); + + return ctx->u.pw.status; +} + +const union g_addr *dplane_ctx_get_pw_nexthop( + const struct zebra_dplane_ctx *ctx) +{ + DPLANE_CTX_VALID(ctx); + + return &(ctx->u.pw.nexthop); +} + +const union pw_protocol_fields *dplane_ctx_get_pw_proto( + const struct zebra_dplane_ctx *ctx) +{ + DPLANE_CTX_VALID(ctx); + + return &(ctx->u.pw.fields); +} + /* * End of dplane context accessors */ @@ -938,6 +1033,47 @@ static int dplane_ctx_lsp_init(struct zebra_dplane_ctx *ctx, } /* + * Capture information for an LSP update in a dplane context. + */ +static int dplane_ctx_pw_init(struct zebra_dplane_ctx *ctx, + enum dplane_op_e op, + struct zebra_pw *pw) +{ + int ret = AOK; + + if (IS_ZEBRA_DEBUG_DPLANE_DETAIL) + zlog_debug("init dplane ctx %s: pw '%s', loc %u, rem %u", + dplane_op2str(op), pw->ifname, pw->local_label, + pw->remote_label); + + ctx->zd_op = op; + ctx->zd_status = ZEBRA_DPLANE_REQUEST_SUCCESS; + + /* Capture namespace info: no netlink support as of 12/18, + * but just in case... + */ + dplane_ctx_ns_init(ctx, zebra_ns_lookup(NS_DEFAULT), false); + + memset(&ctx->u.pw, 0, sizeof(ctx->u.pw)); + + /* This name appears to be c-string, so we use string copy. */ + strlcpy(ctx->u.pw.ifname, pw->ifname, sizeof(ctx->u.pw.ifname)); + ctx->zd_vrf_id = pw->vrf_id; + ctx->u.pw.ifindex = pw->ifindex; + ctx->u.pw.type = pw->type; + ctx->u.pw.af = pw->af; + ctx->u.pw.local_label = pw->local_label; + ctx->u.pw.remote_label = pw->remote_label; + ctx->u.pw.flags = pw->flags; + + ctx->u.pw.nexthop = pw->nexthop; + + ctx->u.pw.fields = pw->data; + + return ret; +} + +/* * Enqueue a new route update, * and ensure an event is active for the dataplane pthread. */ @@ -1141,6 +1277,22 @@ enum zebra_dplane_result dplane_lsp_delete(zebra_lsp_t *lsp) } /* + * Enqueue pseudowire install for the dataplane. + */ +enum zebra_dplane_result dplane_pw_install(struct zebra_pw *pw) +{ + return pw_update_internal(pw, DPLANE_OP_PW_INSTALL); +} + +/* + * Enqueue pseudowire un-install for the dataplane. + */ +enum zebra_dplane_result dplane_pw_uninstall(struct zebra_pw *pw) +{ + return pw_update_internal(pw, DPLANE_OP_PW_UNINSTALL); +} + +/* * Common internal LSP update utility */ static enum zebra_dplane_result lsp_update_internal(zebra_lsp_t *lsp, @@ -1181,6 +1333,45 @@ done: } /* + * Internal, common handler for pseudowire updates. + */ +static enum zebra_dplane_result pw_update_internal(struct zebra_pw *pw, + enum dplane_op_e op) +{ + enum zebra_dplane_result result = ZEBRA_DPLANE_REQUEST_FAILURE; + int ret; + struct zebra_dplane_ctx *ctx = NULL; + + ctx = dplane_ctx_alloc(); + if (ctx == NULL) { + ret = ENOMEM; + goto done; + } + + ret = dplane_ctx_pw_init(ctx, op, pw); + if (ret != AOK) + goto done; + + ret = dplane_route_enqueue(ctx); + +done: + /* Update counter */ + atomic_fetch_add_explicit(&zdplane_info.dg_pws_in, 1, + memory_order_relaxed); + + if (ret == AOK) + result = ZEBRA_DPLANE_REQUEST_QUEUED; + else { + atomic_fetch_add_explicit(&zdplane_info.dg_pw_errors, 1, + memory_order_relaxed); + if (ctx) + dplane_ctx_free(&ctx); + } + + return result; +} + +/* * Handler for 'show dplane' */ int dplane_show_helper(struct vty *vty, bool detailed) @@ -1512,6 +1703,32 @@ kernel_dplane_lsp_update(struct zebra_dplane_ctx *ctx) } /* + * Handler for kernel pseudowire updates + */ +static enum zebra_dplane_result +kernel_dplane_pw_update(struct zebra_dplane_ctx *ctx) +{ + enum zebra_dplane_result res; + + if (IS_ZEBRA_DEBUG_DPLANE_DETAIL) + zlog_debug("Dplane pw %s: op %s af %d loc: %u rem: %u", + dplane_ctx_get_pw_ifname(ctx), + dplane_op2str(ctx->zd_op), + dplane_ctx_get_pw_af(ctx), + dplane_ctx_get_pw_local_label(ctx), + dplane_ctx_get_pw_remote_label(ctx)); + + res = kernel_pw_update(ctx); + + if (res != ZEBRA_DPLANE_REQUEST_SUCCESS) + atomic_fetch_add_explicit( + &zdplane_info.dg_pw_errors, 1, + memory_order_relaxed); + + return res; +} + +/* * Handler for kernel route updates */ static enum zebra_dplane_result @@ -1577,6 +1794,11 @@ static int kernel_dplane_process_func(struct zebra_dplane_provider *prov) res = kernel_dplane_lsp_update(ctx); break; + case DPLANE_OP_PW_INSTALL: + case DPLANE_OP_PW_UNINSTALL: + res = kernel_dplane_pw_update(ctx); + break; + default: atomic_fetch_add_explicit( &zdplane_info.dg_other_errors, 1, @@ -1802,7 +2024,7 @@ static int dplane_check_shutdown_status(struct thread *event) /* We appear to be done - schedule a final callback event * for the zebra main pthread. */ - thread_add_event(zebrad.master, zebra_finalize, NULL, 0, NULL); + thread_add_event(zrouter.master, zebra_finalize, NULL, 0, NULL); } return 0; @@ -2052,7 +2274,7 @@ void zebra_dplane_shutdown(void) /* * Initialize the dataplane module during startup, internal/private version */ -static void zebra_dplane_init_internal(struct zebra_t *zebra) +static void zebra_dplane_init_internal(void) { memset(&zdplane_info, 0, sizeof(zdplane_info)); @@ -2101,6 +2323,6 @@ void zebra_dplane_start(void) */ void zebra_dplane_init(int (*results_fp)(struct dplane_ctx_q *)) { - zebra_dplane_init_internal(&zebrad); + zebra_dplane_init_internal(); zdplane_info.dg_results_cb = results_fp; } |
