[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <20251016013618.2030940-2-saeed@kernel.org>
Date: Wed, 15 Oct 2025 18:36:16 -0700
From: Saeed Mahameed <saeed@...nel.org>
To: "David S. Miller" <davem@...emloft.net>,
Jakub Kicinski <kuba@...nel.org>,
Paolo Abeni <pabeni@...hat.com>,
Eric Dumazet <edumazet@...gle.com>
Cc: Saeed Mahameed <saeedm@...dia.com>,
netdev@...r.kernel.org,
Tariq Toukan <tariqt@...dia.com>,
Gal Pressman <gal@...dia.com>,
Leon Romanovsky <leonro@...dia.com>,
mbloch@...dia.com,
Parav Pandit <parav@...dia.com>,
Adithya Jayachandran <ajayachandra@...dia.com>
Subject: [PATCH net-next 1/3] devlink: Introduce devlink eswitch state
From: Parav Pandit <parav@...dia.com>
Introduce a new state to eswitch (active/inactive) and
enable user to set it dynamically.
A user can start the eswitch in switchdev mode in either active or
inactive state.
Active: Traffic is enabled on this eswitch FDB.
Inactive: Traffic is ignored/dropped on this eswitch FDB.
An example of starting the switch in active state is following.
1. devlink dev eswitch set pci/0000:08:00.1 mode switchdev
(default is active, backward compatible)
2. devlink dev eswitch set pci/0000:08:00.1 mode switchdev state
active
To bring up the esw in 'inactive' state:
devlink dev eswitch set pci/0000:08:00.1 mode switchdev state
inactive
Signed-off-by: Parav Pandit <parav@...dia.com>
Signed-off-by: Saeed Mahameed <saeedm@...dia.com>
Signed-off-by: Adithya Jayachandran <ajayachandra@...dia.com>
---
Documentation/netlink/specs/devlink.yaml | 13 ++++++++
.../devlink/devlink-eswitch-attr.rst | 15 ++++++++++
include/net/devlink.h | 5 ++++
include/uapi/linux/devlink.h | 7 +++++
net/devlink/dev.c | 30 +++++++++++++++++++
net/devlink/netlink_gen.c | 5 ++--
6 files changed, 73 insertions(+), 2 deletions(-)
diff --git a/Documentation/netlink/specs/devlink.yaml b/Documentation/netlink/specs/devlink.yaml
index 3db59c965869..4242a3431320 100644
--- a/Documentation/netlink/specs/devlink.yaml
+++ b/Documentation/netlink/specs/devlink.yaml
@@ -119,6 +119,14 @@ definitions:
name: none
-
name: basic
+ -
+ type: enum
+ name: eswitch-state
+ entries:
+ -
+ name: none
+ -
+ name: basic
-
type: enum
name: dpipe-header-id
@@ -857,6 +865,10 @@ attribute-sets:
name: health-reporter-burst-period
type: u64
doc: Time (in msec) for recoveries before starting the grace period.
+ -
+ name: eswitch-state
+ type: u8
+ enum: eswitch-state
-
name: dl-dev-stats
subset-of: devlink
@@ -1609,6 +1621,7 @@ operations:
- eswitch-mode
- eswitch-inline-mode
- eswitch-encap-mode
+ - eswitch-state
-
name: eswitch-set
diff --git a/Documentation/networking/devlink/devlink-eswitch-attr.rst b/Documentation/networking/devlink/devlink-eswitch-attr.rst
index 08bb39ab1528..13ad1ed300ee 100644
--- a/Documentation/networking/devlink/devlink-eswitch-attr.rst
+++ b/Documentation/networking/devlink/devlink-eswitch-attr.rst
@@ -57,6 +57,18 @@ The following is a list of E-Switch attributes.
* ``none`` Disable encapsulation support.
* ``basic`` Enable encapsulation support.
+ * - ``state``
+ - enum
+ - The state of the E-Switch.
+ In situations where the user want to bring up the e-switch, they want to
+ have the ability to block traffic towards the FDB until FDB is fully
+ programmed.
+ The state can be one of the following:
+
+ * ``active`` Traffic is enabled on this eswitch FDB - default mode
+ * ``inactive`` Traffic is disabled on this eswitch FDB - no traffic
+ will be forwarded to/from this eswitch FDB
+
Example Usage
=============
@@ -74,3 +86,6 @@ Example Usage
# enable encap-mode with legacy mode
$ devlink dev eswitch set pci/0000:08:00.0 mode legacy inline-mode none encap-mode basic
+
+ # enable switchdev mode in inactive state
+ $ devlink dev eswitch set pci/0000:08:00.0 mode switchdev state inactive
diff --git a/include/net/devlink.h b/include/net/devlink.h
index 8d4362f010e4..aca56a905ab8 100644
--- a/include/net/devlink.h
+++ b/include/net/devlink.h
@@ -1369,6 +1369,11 @@ struct devlink_ops {
int (*eswitch_encap_mode_set)(struct devlink *devlink,
enum devlink_eswitch_encap_mode encap_mode,
struct netlink_ext_ack *extack);
+ int (*eswitch_state_get)(struct devlink *devlink,
+ enum devlink_eswitch_state *state);
+ int (*eswitch_state_set)(struct devlink *devlink,
+ enum devlink_eswitch_state state,
+ struct netlink_ext_ack *extack);
int (*info_get)(struct devlink *devlink, struct devlink_info_req *req,
struct netlink_ext_ack *extack);
/**
diff --git a/include/uapi/linux/devlink.h b/include/uapi/linux/devlink.h
index bcad11a787a5..a01443810658 100644
--- a/include/uapi/linux/devlink.h
+++ b/include/uapi/linux/devlink.h
@@ -195,6 +195,11 @@ enum devlink_eswitch_encap_mode {
DEVLINK_ESWITCH_ENCAP_MODE_BASIC,
};
+enum devlink_eswitch_state {
+ DEVLINK_ESWITCH_STATE_INACTIVE,
+ DEVLINK_ESWITCH_STATE_ACTIVE,
+};
+
enum devlink_port_flavour {
DEVLINK_PORT_FLAVOUR_PHYSICAL, /* Any kind of a port physically
* facing the user.
@@ -638,6 +643,8 @@ enum devlink_attr {
DEVLINK_ATTR_HEALTH_REPORTER_BURST_PERIOD, /* u64 */
+ DEVLINK_ATTR_ESWITCH_STATE, /* u8 */
+
/* Add new attributes above here, update the spec in
* Documentation/netlink/specs/devlink.yaml and re-generate
* net/devlink/netlink_gen.c.
diff --git a/net/devlink/dev.c b/net/devlink/dev.c
index 02602704bdea..1eea3e2c1ade 100644
--- a/net/devlink/dev.c
+++ b/net/devlink/dev.c
@@ -672,6 +672,17 @@ static int devlink_nl_eswitch_fill(struct sk_buff *msg, struct devlink *devlink,
goto nla_put_failure;
}
+ if (ops->eswitch_state_get) {
+ enum devlink_eswitch_state state;
+
+ err = ops->eswitch_state_get(devlink, &state);
+ if (err)
+ return err;
+ err = nla_put_u8(msg, DEVLINK_ATTR_ESWITCH_STATE, state);
+ if (err)
+ return err;
+ }
+
genlmsg_end(msg, hdr);
return 0;
@@ -706,6 +717,7 @@ int devlink_nl_eswitch_set_doit(struct sk_buff *skb, struct genl_info *info)
struct devlink *devlink = info->user_ptr[0];
const struct devlink_ops *ops = devlink->ops;
enum devlink_eswitch_encap_mode encap_mode;
+ enum devlink_eswitch_state state;
u8 inline_mode;
int err = 0;
u16 mode;
@@ -722,6 +734,24 @@ int devlink_nl_eswitch_set_doit(struct sk_buff *skb, struct genl_info *info)
return err;
}
+ state = DEVLINK_ESWITCH_STATE_ACTIVE;
+ if (info->attrs[DEVLINK_ATTR_ESWITCH_STATE]) {
+ if (!ops->eswitch_state_set)
+ return -EOPNOTSUPP;
+ state = nla_get_u8(info->attrs[DEVLINK_ATTR_ESWITCH_STATE]);
+ }
+ /* If user did not supply the state attribute, the default is
+ * active state. If the state was not explicitly set, set the default
+ * state for drivers that support eswitch state.
+ * Keep this after mode-set as state handling can be dependent on
+ * the eswitch mode.
+ */
+ if (ops->eswitch_state_set) {
+ err = ops->eswitch_state_set(devlink, state, info->extack);
+ if (err)
+ return err;
+ }
+
if (info->attrs[DEVLINK_ATTR_ESWITCH_INLINE_MODE]) {
if (!ops->eswitch_inline_mode_set)
return -EOPNOTSUPP;
diff --git a/net/devlink/netlink_gen.c b/net/devlink/netlink_gen.c
index 9fd00977d59e..e0910fb2214d 100644
--- a/net/devlink/netlink_gen.c
+++ b/net/devlink/netlink_gen.c
@@ -226,12 +226,13 @@ static const struct nla_policy devlink_eswitch_get_nl_policy[DEVLINK_ATTR_DEV_NA
};
/* DEVLINK_CMD_ESWITCH_SET - do */
-static const struct nla_policy devlink_eswitch_set_nl_policy[DEVLINK_ATTR_ESWITCH_ENCAP_MODE + 1] = {
+static const struct nla_policy devlink_eswitch_set_nl_policy[DEVLINK_ATTR_ESWITCH_STATE + 1] = {
[DEVLINK_ATTR_BUS_NAME] = { .type = NLA_NUL_STRING, },
[DEVLINK_ATTR_DEV_NAME] = { .type = NLA_NUL_STRING, },
[DEVLINK_ATTR_ESWITCH_MODE] = NLA_POLICY_MAX(NLA_U16, 1),
[DEVLINK_ATTR_ESWITCH_INLINE_MODE] = NLA_POLICY_MAX(NLA_U8, 3),
[DEVLINK_ATTR_ESWITCH_ENCAP_MODE] = NLA_POLICY_MAX(NLA_U8, 1),
+ [DEVLINK_ATTR_ESWITCH_STATE] = NLA_POLICY_MAX(NLA_U8, 1),
};
/* DEVLINK_CMD_DPIPE_TABLE_GET - do */
@@ -822,7 +823,7 @@ const struct genl_split_ops devlink_nl_ops[74] = {
.doit = devlink_nl_eswitch_set_doit,
.post_doit = devlink_nl_post_doit,
.policy = devlink_eswitch_set_nl_policy,
- .maxattr = DEVLINK_ATTR_ESWITCH_ENCAP_MODE,
+ .maxattr = DEVLINK_ATTR_ESWITCH_STATE,
.flags = GENL_ADMIN_PERM | GENL_CMD_CAP_DO,
},
{
--
2.51.0
Powered by blists - more mailing lists