From: Christos Sfakianakis csfakian@redhat.com
Hi,
this patch includes ports for simple_macsec and short_lived_connections of phase 3. Note that, due to current issue with iperf, ShortLivedConnectionsRecipe cannot be tested yet. In terms of SimpleMacsecRecipe, ip commands were chosen for the creation of the devices, as pyroute2 seems to have issue handling IFLA_MACSEC_ENCRYPT.
Christos
Christos Sfakianakis (5): lnst.RecipeCommon.Perf.Measurements.BaseFlowMeasurement: add Flow msg_size setter lnst.Controller.Host: allow device removal lnst.Devices: add MacsecDevice lnst.Recipes.ENRT: add ShortLivedConnectionsRecipe lnst.Recipes.ENRT: add SimpleMacsecRecipe
lnst/Controller/Host.py | 6 + lnst/Devices/MacsecDevice.py | 67 +++++ lnst/Devices/__init__.py | 4 +- .../Perf/Measurements/BaseFlowMeasurement.py | 4 + .../ENRT/ShortLivedConnectionsRecipe.py | 74 +++++ lnst/Recipes/ENRT/SimpleMacsecRecipe.py | 270 ++++++++++++++++++ 6 files changed, 424 insertions(+), 1 deletion(-) create mode 100644 lnst/Devices/MacsecDevice.py create mode 100644 lnst/Recipes/ENRT/ShortLivedConnectionsRecipe.py create mode 100644 lnst/Recipes/ENRT/SimpleMacsecRecipe.py
From: Christos Sfakianakis csfakian@redhat.com
Allow 'msg_size' property of a Flow object to be set (to be used with ShortLivedConnectionsRecipe).
Signed-off-by: Christos Sfakianakis csfakian@redhat.com --- lnst/RecipeCommon/Perf/Measurements/BaseFlowMeasurement.py | 4 ++++ 1 file changed, 4 insertions(+)
diff --git a/lnst/RecipeCommon/Perf/Measurements/BaseFlowMeasurement.py b/lnst/RecipeCommon/Perf/Measurements/BaseFlowMeasurement.py index c4448b7..81cd02c 100644 --- a/lnst/RecipeCommon/Perf/Measurements/BaseFlowMeasurement.py +++ b/lnst/RecipeCommon/Perf/Measurements/BaseFlowMeasurement.py @@ -46,6 +46,10 @@ class Flow(object): def msg_size(self): return self._msg_size
+ @msg_size.setter + def msg_size(self, value): + self._msg_size = value + @property def duration(self): return self._duration
From: Christos Sfakianakis csfakian@redhat.com
Allow device removal. Destroy the device, remove it from the database and log a relevant message. This is useful when a new device with the same name identifier needs to be created.
Signed-off-by: Christos Sfakianakis csfakian@redhat.com --- lnst/Controller/Host.py | 6 ++++++ 1 file changed, 6 insertions(+)
diff --git a/lnst/Controller/Host.py b/lnst/Controller/Host.py index ee36803..70fece5 100644 --- a/lnst/Controller/Host.py +++ b/lnst/Controller/Host.py @@ -15,6 +15,7 @@ from lnst.Common.Parameters import Parameters from lnst.Controller.Common import ControllerError from lnst.Controller.Namespace import Namespace from lnst.Controller.NetNamespace import NetNamespace +import logging
class Hosts(object): """Container object for Host class instances @@ -82,3 +83,8 @@ class Host(Namespace): self._machine.send_class(cls)
return self._machine.init_remote_class(cls, *args, **kwargs) + + def remove_dev(self, dev): + logging.debug("Device %s is being removed intentionally." % dev.name) + dev.destroy() + self._unset(dev)
From: Christos Sfakianakis csfakian@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@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)
Fri, May 24, 2019 at 07:12:48PM CEST, csfakian@redhat.com wrote:
From: Christos Sfakianakis csfakian@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@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)
I've checked the 'ip link' man page and it's not clear what is the default value for encrypt parameter if not specified. It would be better if this is explicit in LNST code, either on or off. Is this device parameter mandatory?
-Jan
- 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 _______________________________________________ LNST-developers mailing list -- lnst-developers@lists.fedorahosted.org To unsubscribe send an email to lnst-developers-leave@lists.fedorahosted.org Fedora Code of Conduct: https://getfedora.org/code-of-conduct.html List Guidelines: https://fedoraproject.org/wiki/Mailing_list_guidelines List Archives: https://lists.fedorahosted.org/archives/list/lnst-developers@lists.fedorahos...
From: Christos Sfakianakis csfakian@redhat.com
Add ShortLivedConnectionsRecipe, which accounts for short_lived_connections of old phase 3.
Signed-off-by: Christos Sfakianakis csfakian@redhat.com --- .../ENRT/ShortLivedConnectionsRecipe.py | 74 +++++++++++++++++++ 1 file changed, 74 insertions(+) create mode 100644 lnst/Recipes/ENRT/ShortLivedConnectionsRecipe.py
diff --git a/lnst/Recipes/ENRT/ShortLivedConnectionsRecipe.py b/lnst/Recipes/ENRT/ShortLivedConnectionsRecipe.py new file mode 100644 index 0000000..e311fa2 --- /dev/null +++ b/lnst/Recipes/ENRT/ShortLivedConnectionsRecipe.py @@ -0,0 +1,74 @@ +""" +Implements scenario similar to regression_tests/phase3/ +(short_lived_connections.xml + short_lived_connections.py) +""" +from lnst.Common.IpAddress import ipaddress +from lnst.Controller import HostReq, DeviceReq, RecipeParam +from lnst.Recipes.ENRT.BaseEnrtRecipe import BaseEnrtRecipe, EnrtConfiguration +from lnst.Common.Parameters import Param, IntParam, ListParam + +class ShortLivedConnectionsRecipe(BaseEnrtRecipe): + host1 = HostReq() + host1.eth0 = DeviceReq(label="to_switch", driver=RecipeParam("driver")) + + host2 = HostReq() + host2.eth0 = DeviceReq(label="to_switch", driver=RecipeParam("driver")) + + perf_tests = Param(default=("TCP_RR", "TCP_CRR")) + ip_versions = Param(default=("ipv4",)) + perf_parallel_streams = IntParam(default=2) + perf_msg_size = ListParam(default=[1000, 5000, 7000, 10000, 12000]) + + def generate_ping_configurations(self, main_config, sub_config): + return [] + + def generate_flow_combinations(self, main_config, sub_config): + for size in self.params.perf_msg_size: + for flow in super(ShortLivedConnectionsRecipe, self).generate_flow_combinations( + main_config, sub_config): + flow[0].msg_size = size + yield flow + + def test_wide_configuration(self): + host1, host2 = self.matched.host1, self.matched.host2 + + for host in [host1, host2]: + host.eth0.down() + + net_addr = "192.168.101" + + for i, host in enumerate([host1, host2], 10): + host.eth0.ip_add(ipaddress(net_addr + "." + str(i) + "/24")) + + #Due to limitations in the current EnrtConfiguration + #class, a single vlan test pair is chosen + configuration = EnrtConfiguration() + configuration.endpoint1 = host1.eth0 + configuration.endpoint2 = host2.eth0 + + if "mtu" in self.params: + for host in [host1, host2]: + host.eth0.mtu = self.params.mtu + + for host in [host1, host2]: + host.eth0.up() + + #TODO better service handling through HostAPI + if "dev_intr_cpu" in self.params: + for host in [host1, host2]: + host.run("service irqbalance stop") + self._pin_dev_interrupts(host.eth0, self.params.dev_intr_cpu) + + if self.params.perf_parallel_streams > 1: + for host in [host1, host2]: + host.run("tc qdisc replace dev %s root mq" % host.eth0.name) + + return configuration + + def test_wide_deconfiguration(self, config): + host1, host2 = self.matched.host1, self.matched.host2 + + #TODO better service handling through HostAPI + if "dev_intr_cpu" in self.params: + for host in [host1, host2]: + host.run("service irqbalance start")
Fri, May 24, 2019 at 07:12:49PM CEST, csfakian@redhat.com wrote:
From: Christos Sfakianakis csfakian@redhat.com
Add ShortLivedConnectionsRecipe, which accounts for short_lived_connections of old phase 3.
So does this test currently do something (since we want to use iperf that does not implement the test instead of netperf)?
If not the commit message or the code should include a note that the test is incomplete.
Another comment few lines below.
Signed-off-by: Christos Sfakianakis csfakian@redhat.com
.../ENRT/ShortLivedConnectionsRecipe.py | 74 +++++++++++++++++++ 1 file changed, 74 insertions(+) create mode 100644 lnst/Recipes/ENRT/ShortLivedConnectionsRecipe.py
diff --git a/lnst/Recipes/ENRT/ShortLivedConnectionsRecipe.py b/lnst/Recipes/ENRT/ShortLivedConnectionsRecipe.py new file mode 100644 index 0000000..e311fa2 --- /dev/null +++ b/lnst/Recipes/ENRT/ShortLivedConnectionsRecipe.py @@ -0,0 +1,74 @@ +""" +Implements scenario similar to regression_tests/phase3/ +(short_lived_connections.xml + short_lived_connections.py) +""" +from lnst.Common.IpAddress import ipaddress +from lnst.Controller import HostReq, DeviceReq, RecipeParam +from lnst.Recipes.ENRT.BaseEnrtRecipe import BaseEnrtRecipe, EnrtConfiguration +from lnst.Common.Parameters import Param, IntParam, ListParam
+class ShortLivedConnectionsRecipe(BaseEnrtRecipe):
- host1 = HostReq()
- host1.eth0 = DeviceReq(label="to_switch", driver=RecipeParam("driver"))
- host2 = HostReq()
- host2.eth0 = DeviceReq(label="to_switch", driver=RecipeParam("driver"))
- perf_tests = Param(default=("TCP_RR", "TCP_CRR"))
- ip_versions = Param(default=("ipv4",))
- perf_parallel_streams = IntParam(default=2)
- perf_msg_size = ListParam(default=[1000, 5000, 7000, 10000, 12000])
- def generate_ping_configurations(self, main_config, sub_config):
return []
- def generate_flow_combinations(self, main_config, sub_config):
for size in self.params.perf_msg_size:
for flow in super(ShortLivedConnectionsRecipe, self).generate_flow_combinations(
main_config, sub_config):
flow[0].msg_size = size
yield flow
- def test_wide_configuration(self):
host1, host2 = self.matched.host1, self.matched.host2
for host in [host1, host2]:
host.eth0.down()
net_addr = "192.168.101"
for i, host in enumerate([host1, host2], 10):
host.eth0.ip_add(ipaddress(net_addr + "." + str(i) + "/24"))
#Due to limitations in the current EnrtConfiguration
#class, a single vlan test pair is chosen
There are no vlans in this test - the comment is likely a copy-paste issue.
-Jan
configuration = EnrtConfiguration()
configuration.endpoint1 = host1.eth0
configuration.endpoint2 = host2.eth0
if "mtu" in self.params:
for host in [host1, host2]:
host.eth0.mtu = self.params.mtu
for host in [host1, host2]:
host.eth0.up()
#TODO better service handling through HostAPI
if "dev_intr_cpu" in self.params:
for host in [host1, host2]:
host.run("service irqbalance stop")
self._pin_dev_interrupts(host.eth0, self.params.dev_intr_cpu)
if self.params.perf_parallel_streams > 1:
for host in [host1, host2]:
host.run("tc qdisc replace dev %s root mq" % host.eth0.name)
return configuration
- def test_wide_deconfiguration(self, config):
host1, host2 = self.matched.host1, self.matched.host2
#TODO better service handling through HostAPI
if "dev_intr_cpu" in self.params:
for host in [host1, host2]:
host.run("service irqbalance start")
-- 2.17.1 _______________________________________________ LNST-developers mailing list -- lnst-developers@lists.fedorahosted.org To unsubscribe send an email to lnst-developers-leave@lists.fedorahosted.org Fedora Code of Conduct: https://getfedora.org/code-of-conduct.html List Guidelines: https://fedoraproject.org/wiki/Mailing_list_guidelines List Archives: https://lists.fedorahosted.org/archives/list/lnst-developers@lists.fedorahos...
From: Christos Sfakianakis csfakian@redhat.com
Add SimpleMacsecRecipe, corresponding to old simple_macsec recipe of phase 3.
Signed-off-by: Christos Sfakianakis csfakian@redhat.com --- lnst/Recipes/ENRT/SimpleMacsecRecipe.py | 270 ++++++++++++++++++++++++ 1 file changed, 270 insertions(+) create mode 100644 lnst/Recipes/ENRT/SimpleMacsecRecipe.py
diff --git a/lnst/Recipes/ENRT/SimpleMacsecRecipe.py b/lnst/Recipes/ENRT/SimpleMacsecRecipe.py new file mode 100644 index 0000000..ffa772e --- /dev/null +++ b/lnst/Recipes/ENRT/SimpleMacsecRecipe.py @@ -0,0 +1,270 @@ +""" +Implements scenario similar to regression_tests/phase3/ +(simple_macsec.xml + simple_macsec.py) +""" +import logging +from lnst.Common.IpAddress import ipaddress +from lnst.Common.IpAddress import AF_INET, AF_INET6 +from lnst.Common.LnstError import LnstError +from lnst.Controller import HostReq, DeviceReq, RecipeParam +from lnst.Devices import MacsecDevice +from lnst.Recipes.ENRT.BaseEnrtRecipe import BaseEnrtRecipe, EnrtConfiguration, EnrtSubConfiguration +from lnst.RecipeCommon.Perf.Recipe import RecipeConf as PerfRecipeConf +from lnst.RecipeCommon.Perf.Measurements import Flow as PerfFlow +from lnst.RecipeCommon.Ping import PingConf + +class MacsecEnrtConfiguration(EnrtConfiguration): + def __init__(self): + super(MacsecEnrtConfiguration, self).__init__() + self._host1 = None + self._host2 = None + + @property + def host1(self): + return self._host1 + + @host1.setter + def host1(self, value): + self._host1 = value + + @property + def host2(self): + return self._host2 + + @host2.setter + def host2(self, value): + self._host2 = value + +class MacsecEnrtSubConfiguration(EnrtSubConfiguration): + def __init__(self): + super(MacsecEnrtSubConfiguration, self).__init__() + self._ip_vers = ('ipv4',) + self._encrypt = None + + @property + def encrypt(self): + return self._encrypt + + @encrypt.setter + def encrypt(self, value): + self._encrypt = value + + @property + def ip_vers(self): + return self._ip_vers + + @ip_vers.setter + def ip_vers(self, value): + self._ip_vers = value + +class SimpleMacsecRecipe(BaseEnrtRecipe): + host1 = HostReq() + host1.eth0 = DeviceReq(label="to_switch", driver=RecipeParam("driver")) + + host2 = HostReq() + host2.eth0 = DeviceReq(label="to_switch", driver=RecipeParam("driver")) + + macsec_settings = [None, 'on', 'off'] + ids = ['00', '01'] + keys = ["7a16780284000775d4f0a3c0f0e092c0", "3212ef5c4cc5d0e4210b17208e88779e"] + + def generate_sub_configurations(self, main_config): + for encryption in self.macsec_settings: + sub_config = MacsecEnrtSubConfiguration() + sub_config.encrypt = encryption + if encryption: + sub_config.ip_vers = self.params.ip_versions + yield sub_config + + def apply_sub_configuration(self, main_config, sub_config): + if not sub_config.encrypt: + main_config.endpoint1.up() + main_config.endpoint2.up() + else: + net_addr = "192.168.100" + net_addr6 = "fc00:0:0:0" + host1, host2 = main_config.host1, main_config.host2 + k_ids = zip(self.ids, self.keys) + hosts_and_keys = [(host1, host2, k_ids), (host2, host1, k_ids[::-1])] + for host_a, host_b, k_ids in hosts_and_keys: + host_a.msec0 = MacsecDevice(realdev=host_a.eth0, encrypt=sub_config.encrypt) + rx_kwargs = dict(port=1, address=host_b.eth0.hwaddr) + tx_sa_kwargs = dict(sa=0, pn=1, enable='on', id=k_ids[0][0], key=k_ids[0][1]) + rx_sa_kwargs = rx_kwargs.copy() + rx_sa_kwargs.update(tx_sa_kwargs) + rx_sa_kwargs['id'] = k_ids[1][0] + rx_sa_kwargs['key'] = k_ids[1][1] + host_a.msec0.rx('add', **rx_kwargs) + host_a.msec0.tx_sa('add', **tx_sa_kwargs) + host_a.msec0.rx_sa('add', **rx_sa_kwargs) + for i, host in enumerate([host1, host2]): + host.msec0.ip_add(ipaddress(net_addr + "." + str(i+1) + "/24")) + host.msec0.ip_add(ipaddress(net_addr6 + "::" + str(i+1) + "/64")) + host.eth0.up() + host.msec0.up() + + def remove_sub_configuration(self, main_config, sub_config): + if sub_config.encrypt: + host1, host2 = main_config.host1, main_config.host2 + for host in (host1, host2): + host.msec0.netns.remove_dev(host.msec0) + main_config.endpoint1.down() + main_config.endpoint2.down() + + def generate_ping_configurations(self, main_config, sub_config): + if not sub_config.encrypt: + client_nic = main_config.endpoint1 + server_nic = main_config.endpoint2 + ip_vers = ('ipv4',) + else: + client_nic = main_config.host1.msec0 + server_nic = main_config.host2.msec0 + ip_vers = self.params.ip_versions + + count = self.params.ping_count + interval = self.params.ping_interval + size = self.params.ping_psize + common_args = {'count' : count, 'interval' : interval, 'size' : size} + + for ipv in ip_vers: + kwargs = {} + if ipv == "ipv4": + kwargs.update(family = AF_INET) + elif ipv == "ipv6": + kwargs.update(family = AF_INET6) + kwargs.update(link_local = False) + + client_ips = client_nic.ips_filter(**kwargs) + server_ips = server_nic.ips_filter(**kwargs) + if ipv == "ipv6": + client_ips = client_ips[::-1] + server_ips = server_ips[::-1] + + if len(client_ips) != len(server_ips) or len(client_ips) * len(server_ips) == 0: + raise LnstError("Source/destination ip lists are of different size or empty.") + + for src_addr, dst_addr in zip(client_ips, server_ips): + pconf = PingConf(client = client_nic.netns, + client_bind = src_addr, + destination = server_nic.netns, + destination_address = dst_addr, + **common_args) + + yield [pconf] + + def generate_perf_configurations(self, main_config, sub_config): + if sub_config.encrypt: + client_nic = main_config.host1.msec0 + server_nic = main_config.host2.msec0 + client_netns = client_nic.netns + server_netns = server_nic.netns + + flow_combinations = self.generate_flow_combinations( + main_config, sub_config + ) + + for flows in flow_combinations: + perf_recipe_conf=dict( + main_config=main_config, + sub_config=sub_config, + flows=flows, + ) + + flows_measurement = self.params.net_perf_tool( + flows, + perf_recipe_conf + ) + + cpu_measurement = self.params.cpu_perf_tool( + [client_netns, server_netns], + perf_recipe_conf, + ) + + perf_conf = PerfRecipeConf( + measurements=[cpu_measurement, flows_measurement], + iterations=self.params.perf_iterations, + ) + + perf_conf.register_evaluators( + cpu_measurement, self.cpu_perf_evaluators + ) + perf_conf.register_evaluators( + flows_measurement, self.net_perf_evaluators + ) + + yield perf_conf + + def generate_flow_combinations(self, main_config, sub_config): + client_nic = main_config.host1.msec0 + server_nic = main_config.host2.msec0 + client_netns = client_nic.netns + server_netns = server_nic.netns + + for ipv in self.params.ip_versions: + if ipv == "ipv4": + family = AF_INET + elif ipv == "ipv6": + family = AF_INET6 + + client_bind = client_nic.ips_filter(family=family)[0] + server_bind = server_nic.ips_filter(family=family)[0] + + for perf_test in self.params.perf_tests: + flow = PerfFlow( + type = perf_test, + generator = client_netns, + generator_bind = client_bind, + receiver = server_netns, + receiver_bind = server_bind, + msg_size = self.params.perf_msg_size, + duration = self.params.perf_duration, + parallel_streams = self.params.perf_parallel_streams, + cpupin = self.params.perf_tool_cpu if "perf_tool_cpu" in self.params else None + ) + yield [flow] + + def test_wide_configuration(self): + host1, host2 = self.matched.host1, self.matched.host2 + + for host in [host1, host2]: + host.eth0.down() + + net_addr = "192.168.0" + + for i, host in enumerate([host1, host2]): + host.eth0.ip_add(ipaddress(net_addr + '.' + str(i+1) + "/24")) + + #Due to limitations in the current EnrtConfiguration + #class, a single vlan test pair is chosen + configuration = EnrtConfiguration() + configuration.endpoint1 = host1.eth0 + configuration.endpoint2 = host2.eth0 + configuration.host1 = host1 + configuration.host2 = host2 + + cond = (self.params.ping_parallel or self.params.ping_bidirect or + self.params.perf_reverse) + if cond: + logging.debug("Parallelism in pings or reverse perf tests are " + "not supported for this recipe, ping_parallel/bidirect " + " or perf_reverse will be ignored.") + + if "mtu" in self.params: + for host in [host1, host2]: + host.eth0.mtu = self.params.mtu + + #TODO better service handling through HostAPI + if "dev_intr_cpu" in self.params: + for host in [host1, host2]: + host.run("service irqbalance stop") + self._pin_dev_interrupts(host.eth0, self.params.dev_intr_cpu) + + return configuration + + def test_wide_deconfiguration(self, config): + host1, host2 = self.matched.host1, self.matched.host2 + + #TODO better service handling through HostAPI + if "dev_intr_cpu" in self.params: + for host in [host1, host2]: + host.run("service irqbalance start")
lnst-developers@lists.fedorahosted.org