History

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).

Or Gerlitz committed 10 years ago

Commit 08f4b591 parent fed9ce23 files · +98 −0Browse files

Unified · Split

3 files
  1. include/net/devlink.h +3 −0
  2. include/uapi/linux/devlink.h +8 −0
  3. net/core/devlink.c +87 −0
include/net/devlink.h+3−0
@@ -90,6 +90,9 @@ struct devlink_ops { · 89 unmodified lines
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+8−0
@@ -57,6 +57,8 @@ enum devlink_command { · 56 unmodified lines
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 { · 32 unmodified lines
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 { · 24 unmodified lines
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+87−0
@@ -1394,6 +1394,78 @@ static int devlink_nl_cmd_sb_occ_max_clear_doit(struct sk_buff *skb, · 1393 unmodified lines
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] = { · 7 unmodified lines
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[] = { · 112 unmodified lines
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 /**