From: Christos Sfakianakis <csfakian(a)redhat.com>
Add a class to account for the creation of link of type macsec.
For now, use only the master device and possibly the encryption setting
for creating it. Provide methods that map to corresponding 'ip macsec'
commands.
Signed-off-by: Christos Sfakianakis <csfakian(a)redhat.com>
---
lnst/Devices/MacsecDevice.py | 67 ++++++++++++++++++++++++++++++++++++
lnst/Devices/__init__.py | 4 ++-
2 files changed, 70 insertions(+), 1 deletion(-)
create mode 100644 lnst/Devices/MacsecDevice.py
diff --git a/lnst/Devices/MacsecDevice.py b/lnst/Devices/MacsecDevice.py
new file mode 100644
index 0000000..799ea9e
--- /dev/null
+++ b/lnst/Devices/MacsecDevice.py
@@ -0,0 +1,67 @@
+import pyroute2
+from lnst.Common.ExecCmd import exec_cmd
+from lnst.Common.DeviceError import DeviceConfigError
+from lnst.Devices.Device import Device
+from lnst.Devices.SoftDevice import SoftDevice
+
+class MacsecDevice(SoftDevice):
+ _name_template = "t_macsec"
+ _cmd = ''
+
+ def __init__(self, ifmanager, *args, **kwargs):
+ super(MacsecDevice, self).__init__(ifmanager)
+ self._kwargs = kwargs
+
+ def _create(self):
+ realdev = self._kwargs.pop("realdev")
+ encrypt = self._kwargs.pop("encrypt", None)
+ cmd = "ip link add link %s %s type macsec" % (realdev.name, self.name)
+ if encrypt:
+ cmd += " encrypt %s" % encrypt
+ exec_cmd(cmd)
+
+ def destroy(self):
+ exec_cmd("ip link delete %s" % self.name)
+
+ def rx(self, op, **kwargs):
+ self._sci(op, kwargs)
+ if op != 'del':
+ try:
+ self._cmd += "%s" % kwargs.pop('enable')
+ except KeyError:
+ pass
+ self._chk_exec(op, kwargs)
+
+ def rx_sa(self, op, **kwargs):
+ self._sci(op, kwargs)
+ self._sa_pn_key(op, kwargs)
+
+ def tx_sa(self, op, **kwargs):
+ self._cmd = "ip macsec %s %s tx " % (op, self.name)
+ self._sa_pn_key(op, kwargs)
+
+ def _sci(self, op, kwargs):
+ self._cmd = "ip macsec %s %s rx " % (op, self.name)
+ try:
+ self._cmd += "sci %s " % kwargs.pop('sci')
+ except KeyError:
+ self._cmd += "port %s address %s " % (kwargs.pop('port'),
+ kwargs.pop('address'))
+
+ def _sa_pn_key(self, op, kwargs):
+ self._cmd += "sa %s " % kwargs.pop('sa')
+ if op != 'del':
+ try:
+ self._cmd += "pn %s " % kwargs.pop('pn')
+ self._cmd += "%s " % kwargs.pop('enable')
+ except KeyError:
+ pass
+ if op == 'add':
+ self._cmd += "key %s " % kwargs.pop('id')
+ self._cmd += "%s" % kwargs.pop('key')
+ self._chk_exec(op, kwargs)
+
+ def _chk_exec(self, op, kwargs):
+ if kwargs:
+ raise DeviceConfigError("Unexpected options with %s: %s" % (op,
kwargs))
+ exec_cmd(self._cmd)
diff --git a/lnst/Devices/__init__.py b/lnst/Devices/__init__.py
index 675db3c..b38d1b6 100644
--- a/lnst/Devices/__init__.py
+++ b/lnst/Devices/__init__.py
@@ -10,6 +10,7 @@ from lnst.Devices.VxlanDevice import VxlanDevice
from lnst.Devices.VtiDevice import VtiDevice, Vti6Device
from lnst.Devices.VethDevice import VethDevice, PairedVethDevice
from lnst.Devices.VethPair import VethPair
+from lnst.Devices.MacsecDevice import MacsecDevice
from lnst.Devices.RemoteDevice import RemoteDevice, remotedev_decorator
device_classes = [
@@ -24,7 +25,8 @@ device_classes = [
("VtiDevice", VtiDevice),
("Vti6Device", Vti6Device),
("BondDevice", BondDevice),
- ("TeamDevice", TeamDevice)]
+ ("TeamDevice", TeamDevice),
+ ("MacsecDevice", MacsecDevice)]
for name, cls in device_classes:
globals()[name] = remotedev_decorator(cls)
--
2.17.1