diff options
| author | Russ White <russ@riw.us> | 2020-11-03 07:44:45 -0500 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2020-11-03 07:44:45 -0500 |
| commit | 7dcd8af02486b4447e838c0ae9ef6585736dda1e (patch) | |
| tree | 8bdf4862b2efb6cad50b2f998163d2ce688c59a2 /zebra/zebra_dplane.c | |
| parent | a6b628c27bd114e983acabdc9bd3ccbd1f01c06b (diff) | |
| parent | 5917df094a324ce6cb1cc2d71dcaee2d5cc28377 (diff) | |
Merge pull request #7427 from mjstapp/dplane_intf_info
zebra: add optional extra data about routes' interfaces
Diffstat (limited to 'zebra/zebra_dplane.c')
| -rw-r--r-- | zebra/zebra_dplane.c | 104 |
1 files changed, 102 insertions, 2 deletions
diff --git a/zebra/zebra_dplane.c b/zebra/zebra_dplane.c index d3bcffe960..22cc234b2f 100644 --- a/zebra/zebra_dplane.c +++ b/zebra/zebra_dplane.c @@ -40,12 +40,18 @@ /* Memory type for context blocks */ 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") #ifndef AOK # define AOK 0 #endif +/* Control for collection of extra interface info with route updates; a plugin + * can enable the extra info via a dplane api. + */ +static bool dplane_collect_extra_intf_info; + /* Enable test dataplane provider */ /*#define DPLANE_TEST_PROVIDER 1 */ @@ -85,6 +91,18 @@ struct dplane_nexthop_info { }; /* + * Optional extra info about interfaces used in route updates' nexthops. + */ +struct dplane_intf_extra { + vrf_id_t vrf_id; + uint32_t ifindex; + uint32_t flags; + uint32_t status; + + TAILQ_ENTRY(dplane_intf_extra) link; +}; + +/* * Route information captured for route updates. */ struct dplane_route_info { @@ -127,8 +145,8 @@ struct dplane_route_info { struct nexthop_group zd_old_ng; struct nexthop_group old_backup_ng; - /* TODO -- use fixed array of nexthops, to avoid mallocs? */ - + /* Optional list of extra interface info */ + TAILQ_HEAD(dp_intf_extra_q, dplane_intf_extra) intf_extra_q; }; /* @@ -507,6 +525,8 @@ void dplane_enable_sys_route_notifs(void) */ static void dplane_ctx_free_internal(struct zebra_dplane_ctx *ctx) { + struct dplane_intf_extra *if_extra, *if_tmp; + /* * Some internal allocations may need to be freed, depending on * the type of info captured in the ctx. @@ -549,6 +569,14 @@ static void dplane_ctx_free_internal(struct zebra_dplane_ctx *ctx) ctx->u.rinfo.old_backup_ng.nexthop = NULL; } + /* Optional extra interface info */ + TAILQ_FOREACH_SAFE(if_extra, &ctx->u.rinfo.intf_extra_q, + link, if_tmp) { + TAILQ_REMOVE(&ctx->u.rinfo.intf_extra_q, if_extra, + link); + XFREE(MTYPE_DP_INTF, if_extra); + } + break; case DPLANE_OP_NH_INSTALL: @@ -1819,6 +1847,45 @@ dplane_ctx_get_br_port_backup_nhg_id(const struct zebra_dplane_ctx *ctx) * End of dplane context accessors */ +/* Optional extra info about interfaces in nexthops - a plugin must enable + * this extra info. + */ +const struct dplane_intf_extra * +dplane_ctx_get_intf_extra(const struct zebra_dplane_ctx *ctx) +{ + return TAILQ_FIRST(&ctx->u.rinfo.intf_extra_q); +} + +const struct dplane_intf_extra * +dplane_ctx_intf_extra_next(const struct zebra_dplane_ctx *ctx, + const struct dplane_intf_extra *ptr) +{ + return TAILQ_NEXT(ptr, link); +} + +vrf_id_t dplane_intf_extra_get_vrfid(const struct dplane_intf_extra *ptr) +{ + return ptr->vrf_id; +} + +uint32_t dplane_intf_extra_get_ifindex(const struct dplane_intf_extra *ptr) +{ + return ptr->ifindex; +} + +uint32_t dplane_intf_extra_get_flags(const struct dplane_intf_extra *ptr) +{ + return ptr->flags; +} + +uint32_t dplane_intf_extra_get_status(const struct dplane_intf_extra *ptr) +{ + return ptr->status; +} + +/* + * End of interface extra info accessors + */ /* * Retrieve the limit on the number of pending, unprocessed updates. @@ -1887,10 +1954,14 @@ int dplane_ctx_route_init(struct zebra_dplane_ctx *ctx, enum dplane_op_e op, struct zebra_vrf *zvrf; struct nexthop *nexthop; zebra_l3vni_t *zl3vni; + const struct interface *ifp; + struct dplane_intf_extra *if_extra; if (!ctx || !rn || !re) goto done; + TAILQ_INIT(&ctx->u.rinfo.intf_extra_q); + ctx->zd_op = op; ctx->zd_status = ZEBRA_DPLANE_REQUEST_SUCCESS; @@ -1952,6 +2023,27 @@ int dplane_ctx_route_init(struct zebra_dplane_ctx *ctx, enum dplane_op_e op, nexthop->nh_encap_type = NET_VXLAN; nexthop->nh_encap.vni = zl3vni->vni; } + + /* Optionally capture extra interface info while we're in the + * main zebra pthread - a plugin has to ask for this info. + */ + if (dplane_collect_extra_intf_info) { + ifp = if_lookup_by_index(nexthop->ifindex, + nexthop->vrf_id); + + if (ifp) { + if_extra = XCALLOC( + MTYPE_DP_INTF, + sizeof(struct dplane_intf_extra)); + if_extra->vrf_id = nexthop->vrf_id; + if_extra->ifindex = nexthop->ifindex; + if_extra->flags = ifp->flags; + if_extra->status = ifp->status; + + TAILQ_INSERT_TAIL(&ctx->u.rinfo.intf_extra_q, + if_extra, link); + } + } } /* Don't need some info when capturing a system notification */ @@ -4244,6 +4336,14 @@ bool dplane_is_in_shutdown(void) } /* + * Enable collection of extra info about interfaces in route updates. + */ +void dplane_enable_intf_extra_info(void) +{ + dplane_collect_extra_intf_info = true; +} + +/* * Early or pre-shutdown, de-init notification api. This runs pretty * early during zebra shutdown, as a signal to stop new work and prepare * for updates generated by shutdown/cleanup activity, as zebra tries to |
