Skip to content

Commit 08f4b59

Browse files
ogerlitzdavem330
authored andcommitted
net/devlink: Add E-Switch mode control
Add the commands to set and show the mode of SRIOV E-Switch, two modes are supported: * legacy: operating in the "old" L2 based mode (DMAC --> VF vport) * switchdev: the E-Switch is referred to as whitebox switch configured using standard tools such as tc, bridge, openvswitch etc. To allow working with the tools, for each VF, a VF representor netdevice is created by the E-Switch manager vendor device driver instance (e.g PF). Signed-off-by: Or Gerlitz <[email protected]> Signed-off-by: Saeed Mahameed <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent fed9ce2 commit 08f4b59

File tree

3 files changed

+98
-0
lines changed

3 files changed

+98
-0
lines changed

include/net/devlink.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,9 @@ struct devlink_ops {
9090
u16 tc_index,
9191
enum devlink_sb_pool_type pool_type,
9292
u32 *p_cur, u32 *p_max);
93+
94+
int (*eswitch_mode_get)(struct devlink *devlink, u16 *p_mode);
95+
int (*eswitch_mode_set)(struct devlink *devlink, u16 mode);
9396
};
9497

9598
static inline void *devlink_priv(struct devlink *devlink)

include/uapi/linux/devlink.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,8 @@ enum devlink_command {
5757
DEVLINK_CMD_SB_OCC_SNAPSHOT,
5858
DEVLINK_CMD_SB_OCC_MAX_CLEAR,
5959

60+
DEVLINK_CMD_ESWITCH_MODE_GET,
61+
DEVLINK_CMD_ESWITCH_MODE_SET,
6062
/* add new commands above here */
6163

6264
__DEVLINK_CMD_MAX,
@@ -95,6 +97,11 @@ enum devlink_sb_threshold_type {
9597

9698
#define DEVLINK_SB_THRESHOLD_TO_ALPHA_MAX 20
9799

100+
enum devlink_eswitch_mode {
101+
DEVLINK_ESWITCH_MODE_LEGACY,
102+
DEVLINK_ESWITCH_MODE_SWITCHDEV,
103+
};
104+
98105
enum devlink_attr {
99106
/* don't change the order or add anything between, this is ABI! */
100107
DEVLINK_ATTR_UNSPEC,
@@ -125,6 +132,7 @@ enum devlink_attr {
125132
DEVLINK_ATTR_SB_TC_INDEX, /* u16 */
126133
DEVLINK_ATTR_SB_OCC_CUR, /* u32 */
127134
DEVLINK_ATTR_SB_OCC_MAX, /* u32 */
135+
DEVLINK_ATTR_ESWITCH_MODE, /* u16 */
128136

129137
/* add new attributes above here, update the policy in devlink.c */
130138

net/core/devlink.c

Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1394,6 +1394,78 @@ static int devlink_nl_cmd_sb_occ_max_clear_doit(struct sk_buff *skb,
13941394
return -EOPNOTSUPP;
13951395
}
13961396

1397+
static int devlink_eswitch_fill(struct sk_buff *msg, struct devlink *devlink,
1398+
enum devlink_command cmd, u32 portid,
1399+
u32 seq, int flags, u16 mode)
1400+
{
1401+
void *hdr;
1402+
1403+
hdr = genlmsg_put(msg, portid, seq, &devlink_nl_family, flags, cmd);
1404+
if (!hdr)
1405+
return -EMSGSIZE;
1406+
1407+
if (devlink_nl_put_handle(msg, devlink))
1408+
goto nla_put_failure;
1409+
1410+
if (nla_put_u16(msg, DEVLINK_ATTR_ESWITCH_MODE, mode))
1411+
goto nla_put_failure;
1412+
1413+
genlmsg_end(msg, hdr);
1414+
return 0;
1415+
1416+
nla_put_failure:
1417+
genlmsg_cancel(msg, hdr);
1418+
return -EMSGSIZE;
1419+
}
1420+
1421+
static int devlink_nl_cmd_eswitch_mode_get_doit(struct sk_buff *skb,
1422+
struct genl_info *info)
1423+
{
1424+
struct devlink *devlink = info->user_ptr[0];
1425+
const struct devlink_ops *ops = devlink->ops;
1426+
struct sk_buff *msg;
1427+
u16 mode;
1428+
int err;
1429+
1430+
if (!ops || !ops->eswitch_mode_get)
1431+
return -EOPNOTSUPP;
1432+
1433+
err = ops->eswitch_mode_get(devlink, &mode);
1434+
if (err)
1435+
return err;
1436+
1437+
msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
1438+
if (!msg)
1439+
return -ENOMEM;
1440+
1441+
err = devlink_eswitch_fill(msg, devlink, DEVLINK_CMD_ESWITCH_MODE_GET,
1442+
info->snd_portid, info->snd_seq, 0, mode);
1443+
1444+
if (err) {
1445+
nlmsg_free(msg);
1446+
return err;
1447+
}
1448+
1449+
return genlmsg_reply(msg, info);
1450+
}
1451+
1452+
static int devlink_nl_cmd_eswitch_mode_set_doit(struct sk_buff *skb,
1453+
struct genl_info *info)
1454+
{
1455+
struct devlink *devlink = info->user_ptr[0];
1456+
const struct devlink_ops *ops = devlink->ops;
1457+
u16 mode;
1458+
1459+
if (!info->attrs[DEVLINK_ATTR_ESWITCH_MODE])
1460+
return -EINVAL;
1461+
1462+
mode = nla_get_u16(info->attrs[DEVLINK_ATTR_ESWITCH_MODE]);
1463+
1464+
if (ops && ops->eswitch_mode_set)
1465+
return ops->eswitch_mode_set(devlink, mode);
1466+
return -EOPNOTSUPP;
1467+
}
1468+
13971469
static const struct nla_policy devlink_nl_policy[DEVLINK_ATTR_MAX + 1] = {
13981470
[DEVLINK_ATTR_BUS_NAME] = { .type = NLA_NUL_STRING },
13991471
[DEVLINK_ATTR_DEV_NAME] = { .type = NLA_NUL_STRING },
@@ -1407,6 +1479,7 @@ static const struct nla_policy devlink_nl_policy[DEVLINK_ATTR_MAX + 1] = {
14071479
[DEVLINK_ATTR_SB_POOL_THRESHOLD_TYPE] = { .type = NLA_U8 },
14081480
[DEVLINK_ATTR_SB_THRESHOLD] = { .type = NLA_U32 },
14091481
[DEVLINK_ATTR_SB_TC_INDEX] = { .type = NLA_U16 },
1482+
[DEVLINK_ATTR_ESWITCH_MODE] = { .type = NLA_U16 },
14101483
};
14111484

14121485
static const struct genl_ops devlink_nl_ops[] = {
@@ -1525,6 +1598,20 @@ static const struct genl_ops devlink_nl_ops[] = {
15251598
DEVLINK_NL_FLAG_NEED_SB |
15261599
DEVLINK_NL_FLAG_LOCK_PORTS,
15271600
},
1601+
{
1602+
.cmd = DEVLINK_CMD_ESWITCH_MODE_GET,
1603+
.doit = devlink_nl_cmd_eswitch_mode_get_doit,
1604+
.policy = devlink_nl_policy,
1605+
.flags = GENL_ADMIN_PERM,
1606+
.internal_flags = DEVLINK_NL_FLAG_NEED_DEVLINK,
1607+
},
1608+
{
1609+
.cmd = DEVLINK_CMD_ESWITCH_MODE_SET,
1610+
.doit = devlink_nl_cmd_eswitch_mode_set_doit,
1611+
.policy = devlink_nl_policy,
1612+
.flags = GENL_ADMIN_PERM,
1613+
.internal_flags = DEVLINK_NL_FLAG_NEED_DEVLINK,
1614+
},
15281615
};
15291616

15301617
/**

0 commit comments

Comments
 (0)