diff options
Diffstat (limited to 'zebra/zebra_dplane.c')
| -rw-r--r-- | zebra/zebra_dplane.c | 1024 |
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() */ |
