summaryrefslogtreecommitdiff
path: root/zebra/zebra_dplane.c
diff options
context:
space:
mode:
Diffstat (limited to 'zebra/zebra_dplane.c')
-rw-r--r--zebra/zebra_dplane.c1024
1 files changed, 847 insertions, 177 deletions
diff --git a/zebra/zebra_dplane.c b/zebra/zebra_dplane.c
index f6c1fdd78e..06b34da209 100644
--- a/zebra/zebra_dplane.c
+++ b/zebra/zebra_dplane.c
@@ -2,6 +2,8 @@
/*
* Zebra dataplane layer.
* Copyright (c) 2018 Volta Networks, Inc.
+ * Portions:
+ * Copyright (c) 2021 The MITRE Corporation.
*/
#ifdef HAVE_CONFIG_H
@@ -37,6 +39,13 @@ DEFINE_MTYPE_STATIC(ZEBRA, DP_NS, "DPlane NSes");
# define AOK 0
#endif
+/*
+ * Dataplane API version. This must be updated when any incompatible changes
+ * are made. The minor version (at least) should be updated when new APIs
+ * are introduced.
+ */
+static uint32_t zdplane_version = MAKE_FRRVERSION(2, 0, 0);
+
/* Control for collection of extra interface info with route updates; a plugin
* can enable the extra info via a dplane api.
*/
@@ -180,10 +189,47 @@ struct dplane_br_port_info {
*/
struct dplane_intf_info {
+ enum zebra_iftype zif_type;
+ ifindex_t bond_ifindex;
+ ifindex_t link_ifindex;
+ int32_t mtu;
+ vrf_id_t vrf_id;
+ enum zebra_slave_iftype zif_slave_type;
+ ifindex_t master_ifindex;
+ ifindex_t bridge_ifindex;
+ ns_id_t link_nsid;
+ enum zebra_slave_iftype zslave_type;
+ uint8_t bypass;
+ enum zebra_link_type zltype;
+ bool startup;
+ uint8_t family;
+ struct zebra_vxlan_vni_array *vniarray;
+ bool no_bvinfo_avail;
+ bool no_afspec_avail;
+ struct zebra_dplane_bridge_vlan_info bvinfo;
+ struct zebra_dplane_bridge_vlan_info_array *bvarray;
+
+ char desc[128];
+
+ int32_t hw_addr_len;
+ uint8_t hw_addr[INTERFACE_HWADDR_MAX];
+
+ uint32_t table_id;
+
+ struct zebra_l2info_bridge binfo;
+ struct zebra_l2info_vlan vinfo;
+ struct zebra_l2info_vxlan vxinfo;
+ struct zebra_l2info_gre grinfo;
+
+ uint32_t rc_bitfield;
+
+ uint32_t txqlen;
+
uint32_t metric;
uint32_t flags;
bool protodown;
+ bool protodown_set;
bool pd_reason_val;
#define DPLANE_INTF_CONNECTED (1 << 0) /* Connected peer, p2p */
@@ -191,6 +237,7 @@ struct dplane_intf_info {
#define DPLANE_INTF_BROADCAST (1 << 2)
#define DPLANE_INTF_HAS_DEST DPLANE_INTF_CONNECTED
#define DPLANE_INTF_HAS_LABEL (1 << 4)
+#define DPLANE_INTF_NOPREFIXROUTE (1 << 5)
/* Interface address/prefix */
struct prefix prefix;
@@ -245,28 +292,8 @@ struct dplane_neigh_table {
* Policy based routing rule info for the dataplane
*/
struct dplane_ctx_rule {
- uint32_t priority;
-
- /* The route table pointed by this rule */
- uint32_t table;
-
- /* Filter criteria */
- uint32_t filter_bm;
- uint32_t fwmark;
- uint8_t dsfield;
- struct prefix src_ip;
- struct prefix dst_ip;
- uint8_t ip_proto;
- uint16_t src_port;
- uint16_t dst_port;
-
- uint8_t action_pcp;
- uint16_t action_vlan_id;
- uint16_t action_vlan_flags;
+ struct pbr_rule prule;
- uint32_t action_queue_id;
-
- char ifname[INTERFACE_NAMSIZ + 1];
struct ethaddr smac;
struct ethaddr dmac;
int out_ifindex;
@@ -337,6 +364,13 @@ struct dplane_tc_filter_info {
};
/*
+ * SRv6 encapsulation params context for the dataplane
+ */
+struct dplane_srv6_encap_ctx {
+ struct in6_addr srcaddr;
+};
+
+/*
* 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).
@@ -372,7 +406,7 @@ struct zebra_dplane_ctx {
vrf_id_t zd_vrf_id;
uint32_t zd_table_id;
- char zd_ifname[INTERFACE_NAMSIZ];
+ char zd_ifname[IFNAMSIZ];
ifindex_t zd_ifindex;
/* Support info for different kinds of updates */
@@ -397,6 +431,8 @@ struct zebra_dplane_ctx {
struct dplane_neigh_table neightable;
struct dplane_gre_ctx gre;
struct dplane_netconf_info netconf;
+ enum zebra_dplane_startup_notifications spot;
+ struct dplane_srv6_encap_ctx srv6_encap;
} u;
/* Namespace info, used especially for netlink kernel communication */
@@ -578,6 +614,9 @@ static struct zebra_dplane_globals {
_Atomic uint32_t dg_tcs_in;
_Atomic uint32_t dg_tcs_errors;
+ _Atomic uint32_t dg_srv6_encap_srcaddr_set_in;
+ _Atomic uint32_t dg_srv6_encap_srcaddr_set_errors;
+
/* Dataplane pthread */
struct frr_pthread *dg_pthread;
@@ -632,6 +671,12 @@ neigh_update_internal(enum dplane_op_e op, const struct interface *ifp,
* Public APIs
*/
+/* Access the dplane API version */
+uint32_t zebra_dplane_get_version(void)
+{
+ return zdplane_version;
+}
+
/* Obtain thread_master for dataplane thread */
struct event_loop *dplane_get_thread_master(void)
{
@@ -808,8 +853,14 @@ static void dplane_ctx_free_internal(struct zebra_dplane_ctx *ctx)
case DPLANE_OP_NONE:
case DPLANE_OP_IPSET_ADD:
case DPLANE_OP_IPSET_DELETE:
+ break;
case DPLANE_OP_INTF_INSTALL:
case DPLANE_OP_INTF_UPDATE:
+ if (ctx->u.intf.vniarray)
+ XFREE(MTYPE_TMP, ctx->u.intf.vniarray);
+ if (ctx->u.intf.bvarray)
+ XFREE(MTYPE_TMP, ctx->u.intf.bvarray);
+ break;
case DPLANE_OP_INTF_DELETE:
case DPLANE_OP_TC_QDISC_INSTALL:
case DPLANE_OP_TC_QDISC_UNINSTALL:
@@ -833,6 +884,8 @@ static void dplane_ctx_free_internal(struct zebra_dplane_ctx *ctx)
break;
case DPLANE_OP_GRE_SET:
case DPLANE_OP_INTF_NETCONFIG:
+ case DPLANE_OP_STARTUP_STAGE:
+ case DPLANE_OP_SRV6_ENCAP_SRCADDR_SET:
break;
}
}
@@ -1156,6 +1209,13 @@ const char *dplane_op2str(enum dplane_op_e op)
case DPLANE_OP_TC_FILTER_UPDATE:
ret = "TC__FILTER_UPDATE";
break;
+ case DPLANE_OP_STARTUP_STAGE:
+ ret = "STARTUP_STAGE";
+ break;
+
+ case DPLANE_OP_SRV6_ENCAP_SRCADDR_SET:
+ ret = "SRV6_ENCAP_SRCADDR_SET";
+ break;
}
return ret;
@@ -1297,6 +1357,450 @@ const char *dplane_ctx_get_ifname(const struct zebra_dplane_ctx *ctx)
return ctx->zd_ifname;
}
+void dplane_ctx_set_ifp_bridge_vlan_info_array(
+ struct zebra_dplane_ctx *ctx,
+ struct zebra_dplane_bridge_vlan_info_array *bvarray)
+{
+ DPLANE_CTX_VALID(ctx);
+
+ ctx->u.intf.bvarray = bvarray;
+}
+
+const struct zebra_dplane_bridge_vlan_info_array *
+dplane_ctx_get_ifp_bridge_vlan_info_array(const struct zebra_dplane_ctx *ctx)
+{
+ DPLANE_CTX_VALID(ctx);
+
+ return ctx->u.intf.bvarray;
+}
+
+void dplane_ctx_set_ifp_vxlan_vni_array(struct zebra_dplane_ctx *ctx,
+ struct zebra_vxlan_vni_array *vniarray)
+{
+ DPLANE_CTX_VALID(ctx);
+
+ ctx->u.intf.vniarray = vniarray;
+}
+
+const struct zebra_vxlan_vni_array *
+dplane_ctx_get_ifp_vxlan_vni_array(const struct zebra_dplane_ctx *ctx)
+{
+ DPLANE_CTX_VALID(ctx);
+
+ return ctx->u.intf.vniarray;
+}
+
+void dplane_ctx_set_ifp_no_afspec(struct zebra_dplane_ctx *ctx)
+{
+ DPLANE_CTX_VALID(ctx);
+
+ ctx->u.intf.no_afspec_avail = true;
+}
+
+bool dplane_ctx_get_ifp_no_afspec(const struct zebra_dplane_ctx *ctx)
+{
+ DPLANE_CTX_VALID(ctx);
+
+ return ctx->u.intf.no_afspec_avail;
+}
+
+void dplane_ctx_set_ifp_no_bridge_vlan_info(struct zebra_dplane_ctx *ctx)
+{
+ DPLANE_CTX_VALID(ctx);
+
+ ctx->u.intf.no_bvinfo_avail = true;
+}
+
+bool dplane_ctx_get_ifp_no_bridge_vlan_info(struct zebra_dplane_ctx *ctx)
+{
+ DPLANE_CTX_VALID(ctx);
+
+ return ctx->u.intf.no_bvinfo_avail;
+}
+
+void dplane_ctx_set_ifp_bridge_vlan_info(
+ struct zebra_dplane_ctx *ctx,
+ struct zebra_dplane_bridge_vlan_info *bvinfo)
+{
+ DPLANE_CTX_VALID(ctx);
+
+ ctx->u.intf.bvinfo = *bvinfo;
+}
+
+const struct zebra_dplane_bridge_vlan_info *
+dplane_ctx_get_ifp_bridge_vlan_info(const struct zebra_dplane_ctx *ctx)
+{
+ DPLANE_CTX_VALID(ctx);
+
+ return &ctx->u.intf.bvinfo;
+}
+
+void dplane_ctx_set_ifp_family(struct zebra_dplane_ctx *ctx, uint8_t family)
+{
+ DPLANE_CTX_VALID(ctx);
+
+ ctx->u.intf.family = family;
+}
+
+uint8_t dplane_ctx_get_ifp_family(const struct zebra_dplane_ctx *ctx)
+{
+ DPLANE_CTX_VALID(ctx);
+
+ return ctx->u.intf.family;
+}
+
+void dplane_ctx_set_ifp_zltype(struct zebra_dplane_ctx *ctx,
+ enum zebra_link_type zltype)
+{
+ DPLANE_CTX_VALID(ctx);
+
+ ctx->u.intf.zltype = zltype;
+}
+
+enum zebra_link_type
+dplane_ctx_get_ifp_zltype(const struct zebra_dplane_ctx *ctx)
+{
+ DPLANE_CTX_VALID(ctx);
+
+ return ctx->u.intf.zltype;
+}
+
+void dplane_ctx_set_ifp_link_ifindex(struct zebra_dplane_ctx *ctx,
+ ifindex_t link_ifindex)
+{
+ DPLANE_CTX_VALID(ctx);
+
+ ctx->u.intf.link_ifindex = link_ifindex;
+}
+
+ifindex_t dplane_ctx_get_ifp_link_ifindex(const struct zebra_dplane_ctx *ctx)
+{
+ DPLANE_CTX_VALID(ctx);
+
+ return ctx->u.intf.link_ifindex;
+}
+
+void dplane_ctx_set_ifp_desc(struct zebra_dplane_ctx *ctx, const char *desc)
+{
+ DPLANE_CTX_VALID(ctx);
+
+ strlcpy(ctx->u.intf.desc, desc, sizeof(ctx->u.intf.desc));
+}
+
+char *dplane_ctx_get_ifp_desc(struct zebra_dplane_ctx *ctx)
+{
+ DPLANE_CTX_VALID(ctx);
+
+ return ctx->u.intf.desc;
+}
+
+void dplane_ctx_set_ifp_flags(struct zebra_dplane_ctx *ctx, uint64_t flags)
+{
+ DPLANE_CTX_VALID(ctx);
+
+ ctx->u.intf.flags = flags;
+}
+
+uint64_t dplane_ctx_get_ifp_flags(const struct zebra_dplane_ctx *ctx)
+{
+ DPLANE_CTX_VALID(ctx);
+
+ return ctx->u.intf.flags;
+}
+
+void dplane_ctx_set_ifp_bypass(struct zebra_dplane_ctx *ctx, uint8_t bypass)
+{
+ DPLANE_CTX_VALID(ctx);
+
+ ctx->u.intf.bypass = bypass;
+}
+
+uint8_t dplane_ctx_get_ifp_bypass(const struct zebra_dplane_ctx *ctx)
+{
+ DPLANE_CTX_VALID(ctx);
+
+ return ctx->u.intf.bypass;
+}
+
+void dplane_ctx_set_ifp_bridge_ifindex(struct zebra_dplane_ctx *ctx,
+ ifindex_t bridge_ifindex)
+{
+ DPLANE_CTX_VALID(ctx);
+
+ ctx->u.intf.bridge_ifindex = bridge_ifindex;
+}
+
+ifindex_t dplane_ctx_get_ifp_bridge_ifindex(const struct zebra_dplane_ctx *ctx)
+{
+ DPLANE_CTX_VALID(ctx);
+
+ return ctx->u.intf.bridge_ifindex;
+}
+
+void dplane_ctx_set_ifp_zif_slave_type(struct zebra_dplane_ctx *ctx,
+ enum zebra_slave_iftype zslave_type)
+{
+ DPLANE_CTX_VALID(ctx);
+
+ ctx->u.intf.zslave_type = zslave_type;
+}
+
+enum zebra_slave_iftype
+dplane_ctx_get_ifp_zif_slave_type(const struct zebra_dplane_ctx *ctx)
+{
+ DPLANE_CTX_VALID(ctx);
+
+ return ctx->u.intf.zslave_type;
+}
+
+void dplane_ctx_set_ifp_master_ifindex(struct zebra_dplane_ctx *ctx,
+ ifindex_t master_ifindex)
+{
+ DPLANE_CTX_VALID(ctx);
+
+ ctx->u.intf.master_ifindex = master_ifindex;
+}
+
+ifindex_t dplane_ctx_get_ifp_master_ifindex(const struct zebra_dplane_ctx *ctx)
+{
+ DPLANE_CTX_VALID(ctx);
+
+ return ctx->u.intf.master_ifindex;
+}
+
+void dplane_ctx_set_ifp_mtu(struct zebra_dplane_ctx *ctx, uint32_t mtu)
+{
+ DPLANE_CTX_VALID(ctx);
+
+ ctx->u.intf.mtu = mtu;
+}
+
+uint32_t dplane_ctx_get_ifp_mtu(const struct zebra_dplane_ctx *ctx)
+{
+ DPLANE_CTX_VALID(ctx);
+
+ return ctx->u.intf.mtu;
+}
+
+void dplane_ctx_set_ifp_vrf_id(struct zebra_dplane_ctx *ctx, vrf_id_t vrf_id)
+{
+ DPLANE_CTX_VALID(ctx);
+
+ ctx->u.intf.vrf_id = vrf_id;
+}
+
+vrf_id_t dplane_ctx_get_ifp_vrf_id(const struct zebra_dplane_ctx *ctx)
+{
+ DPLANE_CTX_VALID(ctx);
+
+ return ctx->u.intf.vrf_id;
+}
+
+void dplane_ctx_set_ifp_link_nsid(struct zebra_dplane_ctx *ctx,
+ ns_id_t link_nsid)
+{
+ DPLANE_CTX_VALID(ctx);
+
+ ctx->u.intf.link_nsid = link_nsid;
+}
+
+ns_id_t dplane_ctx_get_ifp_link_nsid(const struct zebra_dplane_ctx *ctx)
+{
+ DPLANE_CTX_VALID(ctx);
+
+ return ctx->u.intf.link_nsid;
+}
+
+void dplane_ctx_set_ifp_startup(struct zebra_dplane_ctx *ctx, bool startup)
+{
+ DPLANE_CTX_VALID(ctx);
+
+ ctx->u.intf.startup = startup;
+}
+
+bool dplane_ctx_get_ifp_startup(const struct zebra_dplane_ctx *ctx)
+{
+ DPLANE_CTX_VALID(ctx);
+
+ return ctx->u.intf.startup;
+}
+
+void dplane_ctx_set_ifp_protodown_set(struct zebra_dplane_ctx *ctx, bool set)
+{
+ DPLANE_CTX_VALID(ctx);
+
+ ctx->u.intf.protodown_set = set;
+}
+
+bool dplane_ctx_get_ifp_protodown_set(const struct zebra_dplane_ctx *ctx)
+{
+ DPLANE_CTX_VALID(ctx);
+
+ return ctx->u.intf.protodown_set;
+}
+
+void dplane_ctx_set_ifp_protodown(struct zebra_dplane_ctx *ctx, bool protodown)
+{
+ DPLANE_CTX_VALID(ctx);
+
+ ctx->u.intf.protodown = protodown;
+}
+
+bool dplane_ctx_get_ifp_protodown(const struct zebra_dplane_ctx *ctx)
+{
+ DPLANE_CTX_VALID(ctx);
+
+ return ctx->u.intf.protodown;
+}
+
+ifindex_t dplane_ctx_get_ifp_bond_ifindex(const struct zebra_dplane_ctx *ctx)
+{
+ DPLANE_CTX_VALID(ctx);
+
+ return ctx->u.intf.bond_ifindex;
+}
+
+void dplane_ctx_set_ifp_rc_bitfield(struct zebra_dplane_ctx *ctx,
+ uint32_t rc_bitfield)
+{
+ DPLANE_CTX_VALID(ctx);
+
+ ctx->u.intf.rc_bitfield = rc_bitfield;
+}
+
+uint32_t dplane_ctx_get_ifp_rc_bitfield(const struct zebra_dplane_ctx *ctx)
+{
+ DPLANE_CTX_VALID(ctx);
+
+ return ctx->u.intf.rc_bitfield;
+}
+
+void dplane_ctx_set_ifp_gre_info(struct zebra_dplane_ctx *ctx,
+ struct zebra_l2info_gre *grinfo)
+{
+ DPLANE_CTX_VALID(ctx);
+
+ ctx->u.intf.grinfo = *grinfo;
+}
+
+const struct zebra_l2info_gre *
+dplane_ctx_get_ifp_gre_info(const struct zebra_dplane_ctx *ctx)
+{
+ DPLANE_CTX_VALID(ctx);
+
+ return &ctx->u.intf.grinfo;
+}
+
+void dplane_ctx_set_ifp_vxlan_info(struct zebra_dplane_ctx *ctx,
+ struct zebra_l2info_vxlan *vxinfo)
+{
+ DPLANE_CTX_VALID(ctx);
+
+ ctx->u.intf.vxinfo = *vxinfo;
+}
+
+const struct zebra_l2info_vxlan *
+dplane_ctx_get_ifp_vxlan_info(const struct zebra_dplane_ctx *ctx)
+{
+ DPLANE_CTX_VALID(ctx);
+
+ return &ctx->u.intf.vxinfo;
+}
+
+void dplane_ctx_set_ifp_vlan_info(struct zebra_dplane_ctx *ctx,
+ struct zebra_l2info_vlan *vinfo)
+{
+ DPLANE_CTX_VALID(ctx);
+
+ ctx->u.intf.vinfo = *vinfo;
+}
+
+const struct zebra_l2info_vlan *
+dplane_ctx_get_ifp_vlan_info(const struct zebra_dplane_ctx *ctx)
+{
+ DPLANE_CTX_VALID(ctx);
+
+ return &ctx->u.intf.vinfo;
+}
+
+void dplane_ctx_set_ifp_bridge_info(struct zebra_dplane_ctx *ctx,
+ struct zebra_l2info_bridge *binfo)
+{
+ DPLANE_CTX_VALID(ctx);
+
+ ctx->u.intf.binfo = *binfo;
+}
+
+const struct zebra_l2info_bridge *
+dplane_ctx_get_ifp_bridge_info(const struct zebra_dplane_ctx *ctx)
+{
+ DPLANE_CTX_VALID(ctx);
+
+ return &ctx->u.intf.binfo;
+}
+
+void dplane_ctx_set_ifp_table_id(struct zebra_dplane_ctx *ctx,
+ uint32_t table_id)
+{
+ DPLANE_CTX_VALID(ctx);
+
+ ctx->u.intf.table_id = table_id;
+}
+
+uint32_t dplane_ctx_get_ifp_table_id(const struct zebra_dplane_ctx *ctx)
+{
+ DPLANE_CTX_VALID(ctx);
+
+ return ctx->u.intf.table_id;
+}
+
+void dplane_ctx_set_ifp_hw_addr(struct zebra_dplane_ctx *ctx,
+ int32_t hw_addr_len, uint8_t *hw_addr)
+{
+ DPLANE_CTX_VALID(ctx);
+
+ ctx->u.intf.hw_addr_len = hw_addr_len;
+ memcpy(ctx->u.intf.hw_addr, hw_addr, hw_addr_len);
+}
+
+int32_t dplane_ctx_get_ifp_hw_addr_len(const struct zebra_dplane_ctx *ctx)
+{
+ DPLANE_CTX_VALID(ctx);
+
+ return ctx->u.intf.hw_addr_len;
+}
+
+const uint8_t *dplane_ctx_get_ifp_hw_addr(const struct zebra_dplane_ctx *ctx)
+{
+ DPLANE_CTX_VALID(ctx);
+
+ return ctx->u.intf.hw_addr;
+}
+
+void dplane_ctx_set_ifp_bond_ifindex(struct zebra_dplane_ctx *ctx,
+ ifindex_t bond_ifindex)
+{
+ DPLANE_CTX_VALID(ctx);
+
+ ctx->u.intf.bond_ifindex = bond_ifindex;
+}
+
+enum zebra_iftype
+dplane_ctx_get_ifp_zif_type(const struct zebra_dplane_ctx *ctx)
+{
+ DPLANE_CTX_VALID(ctx);
+
+ return ctx->u.intf.zif_type;
+}
+
+void dplane_ctx_set_ifp_zif_type(struct zebra_dplane_ctx *ctx,
+ enum zebra_iftype zif_type)
+{
+ DPLANE_CTX_VALID(ctx);
+
+ ctx->u.intf.zif_type = zif_type;
+}
+
void dplane_ctx_set_ifname(struct zebra_dplane_ctx *ctx, const char *ifname)
{
DPLANE_CTX_VALID(ctx);
@@ -2068,6 +2572,13 @@ bool dplane_ctx_intf_is_connected(const struct zebra_dplane_ctx *ctx)
return (ctx->u.intf.flags & DPLANE_INTF_CONNECTED);
}
+bool dplane_ctx_intf_is_noprefixroute(const struct zebra_dplane_ctx *ctx)
+{
+ DPLANE_CTX_VALID(ctx);
+
+ return (ctx->u.intf.flags & DPLANE_INTF_NOPREFIXROUTE);
+}
+
bool dplane_ctx_intf_is_secondary(const struct zebra_dplane_ctx *ctx)
{
DPLANE_CTX_VALID(ctx);
@@ -2096,6 +2607,13 @@ void dplane_ctx_intf_set_secondary(struct zebra_dplane_ctx *ctx)
ctx->u.intf.flags |= DPLANE_INTF_SECONDARY;
}
+void dplane_ctx_intf_set_noprefixroute(struct zebra_dplane_ctx *ctx)
+{
+ DPLANE_CTX_VALID(ctx);
+
+ ctx->u.intf.flags |= DPLANE_INTF_NOPREFIXROUTE;
+}
+
void dplane_ctx_intf_set_broadcast(struct zebra_dplane_ctx *ctx)
{
DPLANE_CTX_VALID(ctx);
@@ -2111,6 +2629,16 @@ const struct prefix *dplane_ctx_get_intf_addr(
return &(ctx->u.intf.prefix);
}
+
+/* Accessors for SRv6 encapsulation source address information */
+const struct in6_addr *
+dplane_ctx_get_srv6_encap_srcaddr(const struct zebra_dplane_ctx *ctx)
+{
+ DPLANE_CTX_VALID(ctx);
+
+ return &(ctx->u.srv6_encap.srcaddr);
+}
+
void dplane_ctx_set_intf_addr(struct zebra_dplane_ctx *ctx,
const struct prefix *p)
{
@@ -2185,6 +2713,20 @@ void dplane_ctx_set_intf_label(struct zebra_dplane_ctx *ctx, const char *label)
}
}
+void dplane_ctx_set_intf_txqlen(struct zebra_dplane_ctx *ctx, uint32_t txqlen)
+{
+ DPLANE_CTX_VALID(ctx);
+
+ ctx->u.intf.txqlen = txqlen;
+}
+
+uint32_t dplane_ctx_get_intf_txqlen(const struct zebra_dplane_ctx *ctx)
+{
+ DPLANE_CTX_VALID(ctx);
+
+ return ctx->u.intf.txqlen;
+}
+
/* Accessors for MAC information */
vlanid_t dplane_ctx_mac_get_vlan(const struct zebra_dplane_ctx *ctx)
{
@@ -2307,6 +2849,25 @@ dplane_ctx_gre_get_info(const struct zebra_dplane_ctx *ctx)
return &ctx->u.gre.info;
}
+/***********************************************************************
+ * PBR RULE ACCESSORS - start
+ **********************************************************************/
+
+/*
+ * This accessor fills one or two lib/pbr structs from the PBR context.
+ * New dataplane modules should use this interface where possible instead
+ * of adding more accessors that return fields from 'struct pbr_rule'.
+ */
+void dplane_ctx_rule_get(const struct zebra_dplane_ctx *ctx,
+ struct pbr_rule *pNew, struct pbr_rule *pOld)
+{
+ DPLANE_CTX_VALID(ctx);
+ if (pNew)
+ *pNew = ctx->u.rule.new.prule;
+ if (pOld)
+ *pOld = ctx->u.rule.old.prule;
+}
+
/* Accessors for PBR rule information */
int dplane_ctx_rule_get_sock(const struct zebra_dplane_ctx *ctx)
{
@@ -2319,7 +2880,7 @@ const char *dplane_ctx_rule_get_ifname(const struct zebra_dplane_ctx *ctx)
{
DPLANE_CTX_VALID(ctx);
- return ctx->u.rule.new.ifname;
+ return ctx->u.rule.new.prule.ifname;
}
int dplane_ctx_rule_get_unique(const struct zebra_dplane_ctx *ctx)
@@ -2340,112 +2901,112 @@ uint32_t dplane_ctx_rule_get_priority(const struct zebra_dplane_ctx *ctx)
{
DPLANE_CTX_VALID(ctx);
- return ctx->u.rule.new.priority;
+ return ctx->u.rule.new.prule.priority;
}
uint32_t dplane_ctx_rule_get_old_priority(const struct zebra_dplane_ctx *ctx)
{
DPLANE_CTX_VALID(ctx);
- return ctx->u.rule.old.priority;
+ return ctx->u.rule.old.prule.priority;
}
uint32_t dplane_ctx_rule_get_table(const struct zebra_dplane_ctx *ctx)
{
DPLANE_CTX_VALID(ctx);
- return ctx->u.rule.new.table;
+ return ctx->u.rule.new.prule.action.table;
}
uint32_t dplane_ctx_rule_get_old_table(const struct zebra_dplane_ctx *ctx)
{
DPLANE_CTX_VALID(ctx);
- return ctx->u.rule.old.table;
+ return ctx->u.rule.old.prule.action.table;
}
uint32_t dplane_ctx_rule_get_filter_bm(const struct zebra_dplane_ctx *ctx)
{
DPLANE_CTX_VALID(ctx);
- return ctx->u.rule.new.filter_bm;
+ return ctx->u.rule.new.prule.filter.filter_bm;
}
uint32_t dplane_ctx_rule_get_old_filter_bm(const struct zebra_dplane_ctx *ctx)
{
DPLANE_CTX_VALID(ctx);
- return ctx->u.rule.old.filter_bm;
+ return ctx->u.rule.old.prule.filter.filter_bm;
}
uint32_t dplane_ctx_rule_get_fwmark(const struct zebra_dplane_ctx *ctx)
{
DPLANE_CTX_VALID(ctx);
- return ctx->u.rule.new.fwmark;
+ return ctx->u.rule.new.prule.filter.fwmark;
}
uint32_t dplane_ctx_rule_get_old_fwmark(const struct zebra_dplane_ctx *ctx)
{
DPLANE_CTX_VALID(ctx);
- return ctx->u.rule.old.fwmark;
+ return ctx->u.rule.old.prule.filter.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;
+ return ctx->u.rule.new.prule.filter.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;
+ return ctx->u.rule.old.prule.filter.ip_proto;
}
uint16_t dplane_ctx_rule_get_src_port(const struct zebra_dplane_ctx *ctx)
{
DPLANE_CTX_VALID(ctx);
- return ctx->u.rule.new.src_port;
+ return ctx->u.rule.new.prule.filter.src_port;
}
uint16_t dplane_ctx_rule_get_old_src_port(const struct zebra_dplane_ctx *ctx)
{
DPLANE_CTX_VALID(ctx);
- return ctx->u.rule.old.src_port;
+ return ctx->u.rule.old.prule.filter.src_port;
}
uint16_t dplane_ctx_rule_get_dst_port(const struct zebra_dplane_ctx *ctx)
{
DPLANE_CTX_VALID(ctx);
- return ctx->u.rule.new.dst_port;
+ return ctx->u.rule.new.prule.filter.dst_port;
}
uint16_t dplane_ctx_rule_get_old_dst_port(const struct zebra_dplane_ctx *ctx)
{
DPLANE_CTX_VALID(ctx);
- return ctx->u.rule.old.dst_port;
+ return ctx->u.rule.old.prule.filter.dst_port;
}
uint8_t dplane_ctx_rule_get_dsfield(const struct zebra_dplane_ctx *ctx)
{
DPLANE_CTX_VALID(ctx);
- return ctx->u.rule.new.dsfield;
+ return ctx->u.rule.new.prule.filter.dsfield;
}
uint8_t dplane_ctx_rule_get_old_dsfield(const struct zebra_dplane_ctx *ctx)
{
DPLANE_CTX_VALID(ctx);
- return ctx->u.rule.old.dsfield;
+ return ctx->u.rule.old.prule.filter.dsfield;
}
const struct prefix *
@@ -2453,7 +3014,7 @@ dplane_ctx_rule_get_src_ip(const struct zebra_dplane_ctx *ctx)
{
DPLANE_CTX_VALID(ctx);
- return &(ctx->u.rule.new.src_ip);
+ return &(ctx->u.rule.new.prule.filter.src_ip);
}
const struct prefix *
@@ -2461,7 +3022,7 @@ dplane_ctx_rule_get_old_src_ip(const struct zebra_dplane_ctx *ctx)
{
DPLANE_CTX_VALID(ctx);
- return &(ctx->u.rule.old.src_ip);
+ return &(ctx->u.rule.old.prule.filter.src_ip);
}
const struct prefix *
@@ -2469,7 +3030,7 @@ dplane_ctx_rule_get_dst_ip(const struct zebra_dplane_ctx *ctx)
{
DPLANE_CTX_VALID(ctx);
- return &(ctx->u.rule.new.dst_ip);
+ return &(ctx->u.rule.new.prule.filter.dst_ip);
}
const struct prefix *
@@ -2477,9 +3038,65 @@ dplane_ctx_rule_get_old_dst_ip(const struct zebra_dplane_ctx *ctx)
{
DPLANE_CTX_VALID(ctx);
- return &(ctx->u.rule.old.dst_ip);
+ return &(ctx->u.rule.old.prule.filter.dst_ip);
+}
+
+const struct ethaddr *
+dplane_ctx_rule_get_smac(const struct zebra_dplane_ctx *ctx)
+{
+ DPLANE_CTX_VALID(ctx);
+
+ return &(ctx->u.rule.new.smac);
+}
+
+const struct ethaddr *
+dplane_ctx_rule_get_dmac(const struct zebra_dplane_ctx *ctx)
+{
+ DPLANE_CTX_VALID(ctx);
+
+ return &(ctx->u.rule.new.dmac);
+}
+
+int dplane_ctx_rule_get_out_ifindex(const struct zebra_dplane_ctx *ctx)
+{
+ DPLANE_CTX_VALID(ctx);
+
+ return ctx->u.rule.new.out_ifindex;
}
+intptr_t dplane_ctx_rule_get_old_dp_flow_ptr(const struct zebra_dplane_ctx *ctx)
+{
+ DPLANE_CTX_VALID(ctx);
+
+ return ctx->u.rule.old.dp_flow_ptr;
+}
+
+intptr_t dplane_ctx_rule_get_dp_flow_ptr(const struct zebra_dplane_ctx *ctx)
+{
+ DPLANE_CTX_VALID(ctx);
+
+ return ctx->u.rule.new.dp_flow_ptr;
+}
+
+void dplane_ctx_rule_set_dp_flow_ptr(struct zebra_dplane_ctx *ctx,
+ intptr_t dp_flow_ptr)
+{
+ DPLANE_CTX_VALID(ctx);
+
+ ctx->u.rule.new.dp_flow_ptr = dp_flow_ptr;
+}
+
+vrf_id_t dplane_ctx_rule_get_vrfid(const struct zebra_dplane_ctx *ctx)
+{
+ DPLANE_CTX_VALID(ctx);
+
+ return ctx->u.rule.new.prule.vrf_id;
+}
+
+/***********************************************************************
+ * PBR RULE ACCESSORS - end
+ **********************************************************************/
+
uint32_t dplane_ctx_get_br_port_flags(const struct zebra_dplane_ctx *ctx)
{
DPLANE_CTX_VALID(ctx);
@@ -2548,55 +3165,6 @@ void dplane_ctx_get_pbr_ipset_entry(const struct zebra_dplane_ctx *ctx,
memcpy(entry, &ctx->u.ipset_entry.entry, sizeof(struct zebra_pbr_ipset_entry));
}
-const struct ethaddr *
-dplane_ctx_rule_get_smac(const struct zebra_dplane_ctx *ctx)
-{
- DPLANE_CTX_VALID(ctx);
-
- return &(ctx->u.rule.new.smac);
-}
-
-const struct ethaddr *
-dplane_ctx_rule_get_dmac(const struct zebra_dplane_ctx *ctx)
-{
- DPLANE_CTX_VALID(ctx);
-
- return &(ctx->u.rule.new.dmac);
-}
-
-int dplane_ctx_rule_get_out_ifindex(const struct zebra_dplane_ctx *ctx)
-{
- DPLANE_CTX_VALID(ctx);
-
- return ctx->u.rule.new.out_ifindex;
-}
-
-intptr_t dplane_ctx_rule_get_old_dp_flow_ptr(const struct zebra_dplane_ctx *ctx)
-{
- DPLANE_CTX_VALID(ctx);
-
- return ctx->u.rule.old.dp_flow_ptr;
-}
-
-intptr_t dplane_ctx_rule_get_dp_flow_ptr(const struct zebra_dplane_ctx *ctx)
-{
- DPLANE_CTX_VALID(ctx);
-
- return ctx->u.rule.new.dp_flow_ptr;
-}
-
-void dplane_ctx_rule_set_dp_flow_ptr(struct zebra_dplane_ctx *ctx,
- intptr_t dp_flow_ptr)
-{
- DPLANE_CTX_VALID(ctx);
-
- ctx->u.rule.new.dp_flow_ptr = dp_flow_ptr;
-}
-
-/*
- * End of dplane context accessors
- */
-
/* Optional extra info about interfaces in nexthops - a plugin must enable
* this extra info.
*/
@@ -2798,7 +3366,7 @@ int dplane_ctx_route_init_basic(struct zebra_dplane_ctx *ctx,
{
int ret = EINVAL;
- if (!ctx || !re)
+ if (!ctx)
return ret;
dplane_intf_extra_list_init(&ctx->u.rinfo.intf_extra_list);
@@ -2806,6 +3374,13 @@ int dplane_ctx_route_init_basic(struct zebra_dplane_ctx *ctx,
ctx->zd_op = op;
ctx->zd_status = ZEBRA_DPLANE_REQUEST_SUCCESS;
+ /* This function may be called to create/init a dplane context, not
+ * necessarily to copy a route object. Let's return if there is no route
+ * object to copy.
+ */
+ if (!re)
+ return AOK;
+
ctx->u.rinfo.zd_type = re->type;
ctx->u.rinfo.zd_old_type = re->type;
@@ -2837,6 +3412,8 @@ int dplane_ctx_route_init_basic(struct zebra_dplane_ctx *ctx,
/*
* Initialize a context block for a route update from zebra data structs.
+ * If the `rn` or `re` parameters are NULL, this function only initializes the
+ * dplane context without copying a route object into it.
*/
int dplane_ctx_route_init(struct zebra_dplane_ctx *ctx, enum dplane_op_e op,
struct route_node *rn, struct route_entry *re)
@@ -2853,10 +3430,18 @@ int dplane_ctx_route_init(struct zebra_dplane_ctx *ctx, enum dplane_op_e op,
const struct interface *ifp;
struct dplane_intf_extra *if_extra;
- if (!ctx || !rn || !re)
+ if (!ctx)
return ret;
/*
+ * Initialize the dplane context and return, if there is no route
+ * object to copy
+ */
+ if (!re || !rn)
+ return dplane_ctx_route_init_basic(ctx, op, NULL, NULL, NULL,
+ AFI_UNSPEC, SAFI_UNSPEC);
+
+ /*
* Let's grab the data from the route_node
* so that we can call a helper function
*/
@@ -3414,24 +3999,8 @@ static void dplane_ctx_rule_init_single(struct dplane_ctx_rule *dplane_rule,
{
struct zebra_neigh_ent *n;
- dplane_rule->priority = rule->rule.priority;
- dplane_rule->table = rule->rule.action.table;
-
- 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;
- dplane_rule->src_port = rule->rule.filter.src_port;
- dplane_rule->dst_port = rule->rule.filter.dst_port;
- prefix_copy(&(dplane_rule->dst_ip), &rule->rule.filter.dst_ip);
- prefix_copy(&(dplane_rule->src_ip), &rule->rule.filter.src_ip);
+ dplane_rule->prule = rule->rule;
- 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);
dplane_rule->dp_flow_ptr = rule->action.dp_flow_ptr;
n = rule->action.neigh;
if (n && (n->flags & ZEBRA_NEIGH_ENT_ACTIVE)) {
@@ -3533,6 +4102,7 @@ static int dplane_ctx_iptable_init(struct zebra_dplane_ctx *ctx,
ctx->zd_vrf_id = iptable->vrf_id;
memcpy(&ctx->u.iptable, iptable, sizeof(struct zebra_pbr_iptable));
+ ctx->u.iptable.interface_name_list = NULL;
if (iptable->nb_interface > 0) {
ctx->u.iptable.interface_name_list = list_new();
ctx->u.iptable.interface_name_list->del =
@@ -3785,18 +4355,12 @@ tc_qdisc_update_internal(enum dplane_op_e op,
/* Obtain context block */
ctx = dplane_ctx_alloc();
- if (!ctx) {
- ret = ENOMEM;
- goto done;
- }
-
/* Init context with info from zebra data structs */
ret = dplane_ctx_tc_qdisc_init(ctx, op, qdisc);
if (ret == AOK)
ret = dplane_update_enqueue(ctx);
-done:
/* Update counter */
atomic_fetch_add_explicit(&zdplane_info.dg_tcs_in, 1,
memory_order_relaxed);
@@ -3805,8 +4369,7 @@ done:
} else {
atomic_fetch_add_explicit(&zdplane_info.dg_tcs_errors, 1,
memory_order_relaxed);
- if (ctx)
- dplane_ctx_free(&ctx);
+ dplane_ctx_free(&ctx);
}
return result;
@@ -3822,18 +4385,12 @@ tc_class_update_internal(enum dplane_op_e op, struct zebra_tc_class *class)
/* Obtain context block */
ctx = dplane_ctx_alloc();
- if (!ctx) {
- ret = ENOMEM;
- goto done;
- }
-
/* Init context with info from zebra data structs */
ret = dplane_ctx_tc_class_init(ctx, op, class);
if (ret == AOK)
ret = dplane_update_enqueue(ctx);
-done:
/* Update counter */
atomic_fetch_add_explicit(&zdplane_info.dg_tcs_in, 1,
memory_order_relaxed);
@@ -3842,8 +4399,7 @@ done:
} else {
atomic_fetch_add_explicit(&zdplane_info.dg_tcs_errors, 1,
memory_order_relaxed);
- if (ctx)
- dplane_ctx_free(&ctx);
+ dplane_ctx_free(&ctx);
}
return result;
@@ -3859,18 +4415,12 @@ tc_filter_update_internal(enum dplane_op_e op, struct zebra_tc_filter *filter)
/* Obtain context block */
ctx = dplane_ctx_alloc();
- if (!ctx) {
- ret = ENOMEM;
- goto done;
- }
-
/* Init context with info from zebra data structs */
ret = dplane_ctx_tc_filter_init(ctx, op, filter);
if (ret == AOK)
ret = dplane_update_enqueue(ctx);
-done:
/* Update counter */
atomic_fetch_add_explicit(&zdplane_info.dg_tcs_in, 1,
memory_order_relaxed);
@@ -3879,8 +4429,7 @@ done:
} else {
atomic_fetch_add_explicit(&zdplane_info.dg_tcs_errors, 1,
memory_order_relaxed);
- if (ctx)
- dplane_ctx_free(&ctx);
+ dplane_ctx_free(&ctx);
}
return result;
@@ -3943,16 +4492,11 @@ dplane_nexthop_update_internal(struct nhg_hash_entry *nhe, enum dplane_op_e op)
/* Obtain context block */
ctx = dplane_ctx_alloc();
- if (!ctx) {
- ret = ENOMEM;
- goto done;
- }
ret = dplane_ctx_nexthop_init(ctx, op, nhe);
if (ret == AOK)
ret = dplane_update_enqueue(ctx);
-done:
/* Update counter */
atomic_fetch_add_explicit(&zdplane_info.dg_nexthops_in, 1,
memory_order_relaxed);
@@ -4083,8 +4627,6 @@ dplane_route_notif_update(struct route_node *rn,
goto done;
new_ctx = dplane_ctx_alloc();
- if (new_ctx == NULL)
- goto done;
/* Init context with info from zebra data structs */
dplane_ctx_route_init(new_ctx, op, rn, re);
@@ -4216,10 +4758,6 @@ dplane_lsp_notif_update(struct zebra_lsp *lsp, enum dplane_op_e op,
/* Obtain context block */
ctx = dplane_ctx_alloc();
- if (ctx == NULL) {
- ret = ENOMEM;
- goto done;
- }
/* Copy info from zebra LSP */
ret = dplane_ctx_lsp_init(ctx, op, lsp);
@@ -4259,8 +4797,7 @@ done:
else {
atomic_fetch_add_explicit(&zdplane_info.dg_lsp_errors, 1,
memory_order_relaxed);
- if (ctx)
- dplane_ctx_free(&ctx);
+ dplane_ctx_free(&ctx);
}
return result;
}
@@ -4589,16 +5126,11 @@ dplane_intf_update_internal(const struct interface *ifp, enum dplane_op_e op)
/* Obtain context block */
ctx = dplane_ctx_alloc();
- if (!ctx) {
- ret = ENOMEM;
- goto done;
- }
ret = dplane_ctx_intf_init(ctx, op, ifp);
if (ret == AOK)
ret = dplane_update_enqueue(ctx);
-done:
/* Update counter */
atomic_fetch_add_explicit(&zdplane_info.dg_intfs_in, 1,
memory_order_relaxed);
@@ -4640,18 +5172,6 @@ enum zebra_dplane_result dplane_intf_update(const struct interface *ifp)
}
/*
- * Enqueue a interface delete for the dataplane.
- */
-enum zebra_dplane_result dplane_intf_delete(const struct interface *ifp)
-{
- enum zebra_dplane_result ret = ZEBRA_DPLANE_REQUEST_FAILURE;
-
- if (ifp)
- ret = dplane_intf_update_internal(ifp, DPLANE_OP_INTF_DELETE);
- return ret;
-}
-
-/*
* Enqueue vxlan/evpn mac add (or update).
*/
enum zebra_dplane_result
@@ -5337,8 +5857,10 @@ dplane_gre_set(struct interface *ifp, struct interface *ifp_link,
ctx = dplane_ctx_alloc();
- if (!ifp)
- return result;
+ if (!ifp) {
+ ret = EINVAL;
+ goto done;
+ }
if (IS_ZEBRA_DEBUG_DPLANE_DETAIL) {
zlog_debug("init dplane ctx %s: if %s link %s%s",
@@ -5350,8 +5872,11 @@ dplane_gre_set(struct interface *ifp, struct interface *ifp_link,
ctx->zd_op = op;
ctx->zd_status = ZEBRA_DPLANE_REQUEST_SUCCESS;
zns = zebra_ns_lookup(ifp->vrf->vrf_id);
- if (!zns)
- return result;
+ if (!zns) {
+ ret = EINVAL;
+ goto done;
+ }
+
dplane_ctx_ns_init(ctx, zns, false);
dplane_ctx_set_ifname(ctx, ifp->name);
@@ -5370,6 +5895,7 @@ dplane_gre_set(struct interface *ifp, struct interface *ifp_link,
/* Enqueue context for processing */
ret = dplane_update_enqueue(ctx);
+done:
/* Update counter */
atomic_fetch_add_explicit(&zdplane_info.dg_gre_set_in, 1,
memory_order_relaxed);
@@ -5387,6 +5913,59 @@ dplane_gre_set(struct interface *ifp, struct interface *ifp_link,
}
/*
+ * Common helper api for SRv6 encapsulation source address set
+ */
+enum zebra_dplane_result
+dplane_srv6_encap_srcaddr_set(const struct in6_addr *addr, ns_id_t ns_id)
+{
+ enum zebra_dplane_result result = ZEBRA_DPLANE_REQUEST_FAILURE;
+ struct zebra_dplane_ctx *ctx = NULL;
+ enum dplane_op_e op = DPLANE_OP_SRV6_ENCAP_SRCADDR_SET;
+ int ret;
+ struct zebra_ns *zns;
+
+ if (!addr)
+ return result;
+
+ if (IS_ZEBRA_DEBUG_DPLANE_DETAIL) {
+ zlog_debug("init dplane ctx %s: addr %pI6", dplane_op2str(op),
+ addr);
+ }
+
+ zns = zebra_ns_lookup(ns_id);
+ if (!zns)
+ return result;
+
+ ctx = dplane_ctx_alloc();
+
+ ctx->zd_op = op;
+ ctx->zd_status = ZEBRA_DPLANE_REQUEST_SUCCESS;
+
+ dplane_ctx_ns_init(ctx, zns, false);
+
+ /* Init the SRv6 encap source address specific data area */
+ memcpy(&ctx->u.srv6_encap.srcaddr, addr,
+ sizeof(ctx->u.srv6_encap.srcaddr));
+
+ /* Update counter */
+ atomic_fetch_add_explicit(&zdplane_info.dg_srv6_encap_srcaddr_set_in, 1,
+ memory_order_relaxed);
+
+ /* Enqueue context for processing */
+ ret = dplane_update_enqueue(ctx);
+
+ if (ret == AOK)
+ result = ZEBRA_DPLANE_REQUEST_QUEUED;
+ else {
+ atomic_fetch_add_explicit(&zdplane_info
+ .dg_srv6_encap_srcaddr_set_errors,
+ 1, memory_order_relaxed);
+ dplane_ctx_free(&ctx);
+ }
+ return result;
+}
+
+/*
* Handler for 'show dplane'
*/
int dplane_show_helper(struct vty *vty, bool detailed)
@@ -5578,7 +6157,7 @@ int dplane_provider_register(const char *name,
struct zebra_dplane_provider **prov_p)
{
int ret = 0;
- struct zebra_dplane_provider *p = NULL, *last;
+ struct zebra_dplane_provider *p = NULL, *last, *prev = NULL;
/* Validate */
if (fp == NULL) {
@@ -5621,10 +6200,11 @@ int dplane_provider_register(const char *name,
frr_each (dplane_prov_list, &zdplane_info.dg_providers, last) {
if (last->dp_priority > p->dp_priority)
break;
+ prev = last;
}
if (last)
- dplane_prov_list_add_after(&zdplane_info.dg_providers, last, p);
+ dplane_prov_list_add_after(&zdplane_info.dg_providers, prev, p);
else
dplane_prov_list_add_tail(&zdplane_info.dg_providers, p);
@@ -5764,12 +6344,27 @@ void dplane_provider_enqueue_out_ctx(struct zebra_dplane_provider *prov,
memory_order_relaxed);
}
+static struct zebra_dplane_ctx *
+dplane_provider_dequeue_out_ctx(struct zebra_dplane_provider *prov)
+{
+ struct zebra_dplane_ctx *ctx;
+
+ ctx = dplane_ctx_list_pop(&(prov->dp_ctx_out_list));
+ if (!ctx)
+ return NULL;
+
+ atomic_fetch_sub_explicit(&(prov->dp_out_queued), 1,
+ memory_order_relaxed);
+
+ return ctx;
+}
+
/*
* Accessor for provider object
*/
bool dplane_provider_is_threaded(const struct zebra_dplane_provider *prov)
{
- return (prov->dp_flags & DPLANE_PROV_FLAG_THREADED);
+ return CHECK_FLAG(prov->dp_flags, DPLANE_PROV_FLAG_THREADED);
}
#ifdef HAVE_NETLINK
@@ -6093,6 +6688,13 @@ static void kernel_dplane_log_detail(struct zebra_dplane_ctx *ctx)
case DPLANE_OP_TC_FILTER_ADD:
case DPLANE_OP_TC_FILTER_DELETE:
case DPLANE_OP_TC_FILTER_UPDATE:
+ case DPLANE_OP_STARTUP_STAGE:
+ break;
+
+ case DPLANE_OP_SRV6_ENCAP_SRCADDR_SET:
+ zlog_debug("Dplane SRv6 encap source address set op %s, addr %pI6",
+ dplane_op2str(dplane_ctx_get_op(ctx)),
+ &ctx->u.srv6_encap.srcaddr);
break;
}
}
@@ -6264,7 +6866,15 @@ static void kernel_dplane_handle_result(struct zebra_dplane_ctx *ctx)
case DPLANE_OP_INTF_NETCONFIG:
break;
+ case DPLANE_OP_SRV6_ENCAP_SRCADDR_SET:
+ if (res != ZEBRA_DPLANE_REQUEST_SUCCESS)
+ atomic_fetch_add_explicit(&zdplane_info
+ .dg_srv6_encap_srcaddr_set_errors,
+ 1, memory_order_relaxed);
+ break;
+
case DPLANE_OP_NONE:
+ case DPLANE_OP_STARTUP_STAGE:
if (res != ZEBRA_DPLANE_REQUEST_SUCCESS)
atomic_fetch_add_explicit(&zdplane_info.dg_other_errors,
1, memory_order_relaxed);
@@ -6371,6 +6981,31 @@ static int kernel_dplane_process_func(struct zebra_dplane_provider *prov)
return 0;
}
+static int kernel_dplane_shutdown_func(struct zebra_dplane_provider *prov,
+ bool early)
+{
+ struct zebra_dplane_ctx *ctx;
+
+ if (early)
+ return 1;
+
+ ctx = dplane_provider_dequeue_in_ctx(prov);
+ while (ctx) {
+ dplane_ctx_free(&ctx);
+
+ ctx = dplane_provider_dequeue_in_ctx(prov);
+ }
+
+ ctx = dplane_provider_dequeue_out_ctx(prov);
+ while (ctx) {
+ dplane_ctx_free(&ctx);
+
+ ctx = dplane_provider_dequeue_out_ctx(prov);
+ }
+
+ return 1;
+}
+
#ifdef DPLANE_TEST_PROVIDER
/*
@@ -6443,12 +7078,10 @@ static void dplane_provider_init(void)
{
int ret;
- ret = dplane_provider_register("Kernel",
- DPLANE_PRIO_KERNEL,
+ ret = dplane_provider_register("Kernel", DPLANE_PRIO_KERNEL,
DPLANE_PROV_FLAGS_DEFAULT, NULL,
kernel_dplane_process_func,
- NULL,
- NULL, NULL);
+ kernel_dplane_shutdown_func, NULL, NULL);
if (ret != AOK)
zlog_err("Unable to register kernel dplane provider: %d",
@@ -6791,7 +7424,7 @@ static void dplane_thread_loop(struct event *event)
dplane_provider_lock(prov);
while (counter < limit) {
- ctx = dplane_ctx_list_pop(&(prov->dp_ctx_out_list));
+ ctx = dplane_provider_dequeue_out_ctx(prov);
if (ctx) {
dplane_ctx_list_add_tail(&work_list, ctx);
counter++;
@@ -6849,6 +7482,7 @@ static void dplane_thread_loop(struct event *event)
void zebra_dplane_shutdown(void)
{
struct zebra_dplane_provider *dp;
+ struct zebra_dplane_ctx *ctx;
if (IS_ZEBRA_DEBUG_DPLANE)
zlog_debug("Zebra dataplane shutdown called");
@@ -6876,8 +7510,25 @@ void zebra_dplane_shutdown(void)
}
/* TODO -- Clean-up provider objects */
+ dp = dplane_prov_list_first(&zdplane_info.dg_providers);
+ while (dp) {
+ dplane_prov_list_del(&zdplane_info.dg_providers, dp);
+ XFREE(MTYPE_DP_PROV, dp);
+
+ dp = dplane_prov_list_first(&zdplane_info.dg_providers);
+ }
/* TODO -- Clean queue(s), free memory */
+ DPLANE_LOCK();
+ {
+ ctx = dplane_ctx_list_pop(&zdplane_info.dg_update_list);
+ while (ctx) {
+ dplane_ctx_free(&ctx);
+
+ ctx = dplane_ctx_list_pop(&zdplane_info.dg_update_list);
+ }
+ }
+ DPLANE_UNLOCK();
}
/*
@@ -6955,6 +7606,25 @@ void zebra_dplane_start(void)
frr_pthread_run(zdplane_info.dg_pthread, NULL);
}
+enum zebra_dplane_startup_notifications
+dplane_ctx_get_startup_spot(struct zebra_dplane_ctx *ctx)
+{
+ return ctx->u.spot;
+}
+
+void zebra_dplane_startup_stage(struct zebra_ns *zns,
+ enum zebra_dplane_startup_notifications spot)
+{
+ struct zebra_dplane_ctx *ctx = dplane_ctx_alloc();
+
+ ctx->zd_op = DPLANE_OP_STARTUP_STAGE;
+ ctx->zd_status = ZEBRA_DPLANE_REQUEST_QUEUED;
+
+ ctx->u.spot = spot;
+ dplane_ctx_set_ns_id(ctx, zns->ns_id);
+
+ dplane_provider_enqueue_to_zebra(ctx);
+}
/*
* Initialize the dataplane module at startup; called by zebra rib_init()
*/