diff --git a/interface-definitions/interfaces_ethernet.xml.in b/interface-definitions/interfaces_ethernet.xml.in
index 89f990d411d..b3559a6261c 100644
--- a/interface-definitions/interfaces_ethernet.xml.in
+++ b/interface-definitions/interfaces_ethernet.xml.in
@@ -56,6 +56,12 @@
auto
+
+
+ Enables switchdev mode on interface
+
+
+
#include
diff --git a/python/vyos/ifconfig/ethernet.py b/python/vyos/ifconfig/ethernet.py
index 50dd0f39614..dd11d5e199a 100644
--- a/python/vyos/ifconfig/ethernet.py
+++ b/python/vyos/ifconfig/ethernet.py
@@ -14,6 +14,7 @@
# License along with this library. If not, see .
import os
+import re
from glob import glob
@@ -417,6 +418,29 @@ def set_ring_buffer(self, rx_tx, size):
print(f'could not set "{rx_tx}" ring-buffer for {ifname}')
return output
+ def set_switchdev(self, enable):
+ ifname = self.config['ifname']
+ if not bool(re.match(r"^eth[0-9]+$", ifname)):
+ print(f'switchdev mode is only possible on physical interfaces!')
+ return
+
+ addr, code = self._popen(f'ethtool -i {ifname} | grep bus-info | awk \'{{print $2}}\'')
+ if code != 0:
+ print(f'could not resolve PCIe address of {ifname}')
+ return
+
+ enabled = False
+ state, code = self._popen(f'devlink dev eswitch show pci/0000:01:00.1 | awk \'{{print $3}}\'')
+ if code == 0 and state == 'switchdev':
+ enabled = True
+
+ if enable and not enabled:
+ output, code = self._popen(f'/sbin/devlink dev eswitch set pci/{addr} mode switchdev')
+ if code != 0:
+ print(f'{ifname} does not support switchdev mode')
+ elif not enable and enabled:
+ self._cmd(f'/sbin/devlink dev eswitch set pci/{addr} mode legacy')
+
def update(self, config):
""" General helper function which works on a dictionary retrived by
get_config_dict(). It's main intention is to consolidate the scattered
@@ -463,6 +487,8 @@ def update(self, config):
for rx_tx, size in config['ring_buffer'].items():
self.set_ring_buffer(rx_tx, size)
+ self.set_switchdev('switchdev' in config)
+
# call base class last
super().update(config)
diff --git a/smoketest/scripts/cli/test_interfaces_ethernet.py b/smoketest/scripts/cli/test_interfaces_ethernet.py
index 3d12364f70e..6d7da77366c 100755
--- a/smoketest/scripts/cli/test_interfaces_ethernet.py
+++ b/smoketest/scripts/cli/test_interfaces_ethernet.py
@@ -222,5 +222,15 @@ def test_ethtool_evpn_uplink_tarcking(self):
frrconfig = self.getFRRconfig(f'interface {interface}', daemon='zebra')
self.assertIn(f' evpn mh uplink', frrconfig)
+ def test_switchdev(self):
+ interface = self._interfaces[0]
+ self.cli_set(self._base_path + [interface, 'switchdev'])
+
+ # check validate() - virtual interfaces do not support switchdev
+ with self.assertRaises(ConfigSessionError):
+ self.cli_commit()
+
+ self.cli_delete(self._base_path + [interface, 'switchdev'])
+
if __name__ == '__main__':
unittest.main(verbosity=2)