summaryrefslogtreecommitdiff
path: root/zebra/zebra_dplane.c
diff options
context:
space:
mode:
authorRuss White <russ@riw.us>2020-11-03 07:44:45 -0500
committerGitHub <noreply@github.com>2020-11-03 07:44:45 -0500
commit7dcd8af02486b4447e838c0ae9ef6585736dda1e (patch)
tree8bdf4862b2efb6cad50b2f998163d2ce688c59a2 /zebra/zebra_dplane.c
parenta6b628c27bd114e983acabdc9bd3ccbd1f01c06b (diff)
parent5917df094a324ce6cb1cc2d71dcaee2d5cc28377 (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.c104
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