From 7c7b3267a84102a460bba3bfb75eb2d8008496aa Mon Sep 17 00:00:00 2001 From: waleedm Date: Mon, 17 Jan 2022 14:40:33 +0000 Subject: [PATCH] Adding steering_mode config to sriov_pf object The Current behavioure is to enable smfs software steering by default when moving to switchdev, in some cases we need it to be in dmfs mode (FW steering), so adding steering_mode config to sriov_pf object to make it configrable Change-Id: If607c83c4309c636ccbe03789410f2a2301258d2 --- .../samples/sriov_pf_switchdev.json | 3 +- .../samples/sriov_pf_switchdev.yaml | 3 ++ os_net_config/impl_ifcfg.py | 3 +- os_net_config/objects.py | 9 +++- os_net_config/schema.yaml | 7 +++ os_net_config/sriov_config.py | 18 +++++--- os_net_config/tests/test_impl_ifcfg.py | 9 ++-- os_net_config/tests/test_objects.py | 46 +++++++++++++++++++ os_net_config/utils.py | 6 ++- 9 files changed, 89 insertions(+), 15 deletions(-) diff --git a/etc/os-net-config/samples/sriov_pf_switchdev.json b/etc/os-net-config/samples/sriov_pf_switchdev.json index 8b3cb014..391d8ace 100644 --- a/etc/os-net-config/samples/sriov_pf_switchdev.json +++ b/etc/os-net-config/samples/sriov_pf_switchdev.json @@ -6,7 +6,8 @@ "numvfs": 10, "use_dhcp": false, "promisc": true, - "link_mode": "switchdev" + "link_mode": "switchdev", + "steering_mode": "dmfs" }, { "type": "ovs_bridge", diff --git a/etc/os-net-config/samples/sriov_pf_switchdev.yaml b/etc/os-net-config/samples/sriov_pf_switchdev.yaml index 6962ed41..21b11856 100644 --- a/etc/os-net-config/samples/sriov_pf_switchdev.yaml +++ b/etc/os-net-config/samples/sriov_pf_switchdev.yaml @@ -23,6 +23,9 @@ network_config: # - switchdev # - legacy (default) link_mode: switchdev + # (Optional) The flow steering mode, which could be smfs or dmfs + # If it's not set (None), the default will be smfs + steering_mode: dmfs - type: ovs_bridge diff --git a/os_net_config/impl_ifcfg.py b/os_net_config/impl_ifcfg.py index 4a5cadd8..b10f019a 100644 --- a/os_net_config/impl_ifcfg.py +++ b/os_net_config/impl_ifcfg.py @@ -1037,7 +1037,8 @@ class IfcfgNetConfig(os_net_config.NetConfig): utils.update_sriov_pf_map(sriov_pf.name, sriov_pf.numvfs, self.noop, promisc=sriov_pf.promisc, link_mode=sriov_pf.link_mode, - vdpa=sriov_pf.vdpa) + vdpa=sriov_pf.vdpa, + steering_mode=sriov_pf.steering_mode) self.interface_data[sriov_pf.name] = data if sriov_pf.routes: self._add_routes(sriov_pf.name, sriov_pf.routes) diff --git a/os_net_config/objects.py b/os_net_config/objects.py index d4df71d8..d0d44a05 100644 --- a/os_net_config/objects.py +++ b/os_net_config/objects.py @@ -1513,7 +1513,7 @@ class SriovPF(_BaseOpts): defroute=True, dhclient_args=None, dns_servers=None, nm_controlled=False, onboot=True, domain=None, members=None, promisc=None, link_mode='legacy', ethtool_opts=None, - vdpa=False): + vdpa=False, steering_mode=None): addresses = addresses or [] routes = routes or [] rules = rules or [] @@ -1533,6 +1533,7 @@ class SriovPF(_BaseOpts): self.link_mode = link_mode self.ethtool_opts = ethtool_opts self.vdpa = vdpa + self.steering_mode = steering_mode @staticmethod def get_on_off(config): @@ -1553,6 +1554,10 @@ class SriovPF(_BaseOpts): link_mode = json.get('link_mode', 'legacy') ethtool_opts = json.get('ethtool_opts', None) vdpa = json.get('vdpa', False) + steering_mode = json.get('steering_mode') + if steering_mode is not None and steering_mode not in ['smfs', 'dmfs']: + msg = 'Expecting steering_mode to match smfs/dmfs' + raise InvalidConfigException(msg) if vdpa: msg = "" if link_mode != 'switchdev': @@ -1569,7 +1574,7 @@ class SriovPF(_BaseOpts): opts = _BaseOpts.base_opts_from_json(json) return SriovPF(name, numvfs, *opts, promisc=promisc, link_mode=link_mode, ethtool_opts=ethtool_opts, - vdpa=vdpa) + vdpa=vdpa, steering_mode=steering_mode) class OvsDpdkBond(_BaseOpts): diff --git a/os_net_config/schema.yaml b/os_net_config/schema.yaml index 45888b73..78d67856 100644 --- a/os_net_config/schema.yaml +++ b/os_net_config/schema.yaml @@ -38,6 +38,11 @@ definitions: - type: string pattern: "^(legacy|switchdev)$" - $ref: "#/definitions/param" + sriov_steering_mode_or_param: + oneOf: + - type: string + pattern: "^(smfs|dmfs)$" + - $ref: "#/definitions/param" # MAC address type mac_address_string: type: string @@ -365,6 +370,8 @@ definitions: $ref: "#/definitions/sriov_link_mode_or_param" vdpa: $ref: "#/definitions/bool_or_param" + steering_mode: + $ref: "#/definitions/sriov_steering_mode_or_param" required: - type - name diff --git a/os_net_config/sriov_config.py b/os_net_config/sriov_config.py index 9b945581..8150d0cc 100644 --- a/os_net_config/sriov_config.py +++ b/os_net_config/sriov_config.py @@ -362,7 +362,11 @@ def configure_sriov_pf(execution_from_cli=False, restart_openvswitch=False): if not vdpa: # This is used for the sriov_bind_config dpdk_vfs_pcis_list += vf_pcis_list - configure_smfs_software_steering(item['name']) + + # Configure flow steering mode, default to smfs + configure_flow_steering(item['name'], + item.get('steering_mode', 'smfs')) + # Configure switchdev mode configure_switchdev(item['name']) # Adding a udev rule to rename vf-representors @@ -592,17 +596,17 @@ def configure_vdpa_vhost_device(pci): raise -def configure_smfs_software_steering(pf_name): +def configure_flow_steering(pf_name, steering_mode): pf_pci = get_pf_pci(pf_name) try: processutils.execute('/usr/sbin/devlink', 'dev', 'param', 'set', f'pci/{pf_pci}', 'name', 'flow_steering_mode', - 'value', 'smfs', 'cmode', 'runtime') - logger.info(f"{pf_name}: Device pci/{pf_pci} is set to smfs steering " - "mode.") + 'value', steering_mode, 'cmode', 'runtime') + logger.info(f"{pf_name}: Device pci/{pf_pci} is set to" + " {steering_mode} steering mode.") except processutils.ProcessExecutionError as exc: - logger.warning(f"{pf_name}: Could not set pci/{pf_pci} to smfs " - f" steering mode: {exc}") + logger.warning(f"{pf_name}: Could not set pci/{pf_pci} to" + f" {steering_mode} steering mode: {exc}") def run_ip_config_cmd(*cmd, **kwargs): diff --git a/os_net_config/tests/test_impl_ifcfg.py b/os_net_config/tests/test_impl_ifcfg.py index f22af945..47676fa8 100644 --- a/os_net_config/tests/test_impl_ifcfg.py +++ b/os_net_config/tests/test_impl_ifcfg.py @@ -1659,7 +1659,8 @@ NETMASK=255.255.255.0 pf = objects.SriovPF(name='nic3', numvfs=10) def test_update_sriov_pf_map(name, numvfs, noop, promisc=None, - link_mode='legacy', vdpa=False): + link_mode='legacy', vdpa=False, + steering_mode="smfs"): self.assertEqual(name, 'eth2') self.assertEqual(numvfs, 10) self.assertEqual(promisc, None) @@ -1684,7 +1685,8 @@ BOOTPROTO=none pf = objects.SriovPF(name='nic3', numvfs=10, promisc=True) def test_update_sriov_pf_map(name, numvfs, noop, promisc=None, - link_mode='legacy', vdpa=False): + link_mode='legacy', vdpa=False, + steering_mode="smfs"): self.assertEqual(name, 'eth2') self.assertEqual(numvfs, 10) self.assertTrue(promisc) @@ -1709,7 +1711,8 @@ BOOTPROTO=none pf = objects.SriovPF(name='nic3', numvfs=10, promisc=False) def test_update_sriov_pf_map(name, numvfs, noop, promisc=None, - link_mode='legacy', vdpa=False): + link_mode='legacy', vdpa=False, + steering_mode="smfs"): self.assertEqual(name, 'eth2') self.assertEqual(numvfs, 10) self.assertFalse(promisc) diff --git a/os_net_config/tests/test_objects.py b/os_net_config/tests/test_objects.py index 9a9e896d..523556b7 100644 --- a/os_net_config/tests/test_objects.py +++ b/os_net_config/tests/test_objects.py @@ -1997,6 +1997,52 @@ class TestSriovPF(base.TestCase): expected = 'Expecting to have at least 1 numvfs when vdpa is enabled' self.assertIn(expected, str(err)) + def test_from_json_steering_mode_dmfs(self): + data = '{"type": "sriov_pf", "name": "p6p1", "numvfs": 8,' \ + '"use_dhcp": false, "promisc": false, "link_mode":' \ + '"switchdev", "steering_mode": "dmfs"}' + pf = objects.object_from_json(json.loads(data)) + self.assertEqual("p6p1", pf.name) + self.assertEqual(8, pf.numvfs) + self.assertEqual("off", pf.promisc) + self.assertFalse(pf.use_dhcp) + self.assertEqual("switchdev", pf.link_mode) + self.assertEqual("dmfs", pf.steering_mode) + + def test_from_json_steering_mode_smfs(self): + data = '{"type": "sriov_pf", "name": "p6p1", "numvfs": 8,' \ + '"use_dhcp": false, "promisc": false, "link_mode":' \ + '"switchdev", "steering_mode": "smfs"}' + pf = objects.object_from_json(json.loads(data)) + self.assertEqual("p6p1", pf.name) + self.assertEqual(8, pf.numvfs) + self.assertEqual("off", pf.promisc) + self.assertFalse(pf.use_dhcp) + self.assertEqual("switchdev", pf.link_mode) + self.assertEqual("smfs", pf.steering_mode) + + def test_from_json_steering_mode_none(self): + data = '{"type": "sriov_pf", "name": "p6p1", "numvfs": 8,' \ + '"use_dhcp": false, "promisc": false, "link_mode":' \ + '"switchdev"}' + pf = objects.object_from_json(json.loads(data)) + self.assertEqual("p6p1", pf.name) + self.assertEqual(8, pf.numvfs) + self.assertEqual("off", pf.promisc) + self.assertFalse(pf.use_dhcp) + self.assertEqual("switchdev", pf.link_mode) + self.assertIsNone(pf.steering_mode) + + def test_from_json_steering_mode_invalid(self): + data = '{"type": "sriov_pf", "name": "p6p1", "numvfs": 8,' \ + '"use_dhcp": false, "promisc": false, "link_mode":' \ + '"switchdev", "steering_mode": "dmfss"}' + err = self.assertRaises(objects.InvalidConfigException, + objects.object_from_json, + json.loads(data)) + expected = 'Expecting steering_mode to match smfs/dmfs' + self.assertIn(expected, str(err)) + def test_from_json_ethtool_opts(self): data = '{"type": "sriov_pf", "name": "em1", "numvfs": 16, ' \ '"use_dhcp": false, "promisc": false, ' \ diff --git a/os_net_config/utils.py b/os_net_config/utils.py index ba019e21..759c9075 100644 --- a/os_net_config/utils.py +++ b/os_net_config/utils.py @@ -421,7 +421,7 @@ def _get_dpdk_map(): def update_sriov_pf_map(ifname, numvfs, noop, promisc=None, - link_mode='legacy', vdpa=False): + link_mode='legacy', vdpa=False, steering_mode=None): if not noop: cur_numvfs = sriov_config.get_numvfs(ifname) if cur_numvfs > 0 and cur_numvfs != numvfs: @@ -435,6 +435,8 @@ def update_sriov_pf_map(ifname, numvfs, noop, promisc=None, if promisc is not None: item['promisc'] = promisc item['link_mode'] = link_mode + if steering_mode is not None: + item['steering_mode'] = steering_mode break else: new_item = {} @@ -445,6 +447,8 @@ def update_sriov_pf_map(ifname, numvfs, noop, promisc=None, if promisc is not None: new_item['promisc'] = promisc new_item['link_mode'] = link_mode + if steering_mode is not None: + new_item['steering_mode'] = steering_mode sriov_map.append(new_item) write_yaml_config(common.SRIOV_CONFIG_FILE, sriov_map)