From 02fd1fa77f6b8b34fc932db5e5d7fe13a0fe0f68 Mon Sep 17 00:00:00 2001 From: Jan Tluka Date: Fri, 27 Oct 2023 15:40:07 +0200 Subject: [PATCH 1/6] Recipes/ENRT: add BaseSRIOVNetnsTcRecipe.py Signed-off-by: Jan Tluka --- lnst/Recipes/ENRT/BaseSRIOVNetnsTcRecipe.py | 260 ++++++++++++++++++++ 1 file changed, 260 insertions(+) create mode 100644 lnst/Recipes/ENRT/BaseSRIOVNetnsTcRecipe.py diff --git a/lnst/Recipes/ENRT/BaseSRIOVNetnsTcRecipe.py b/lnst/Recipes/ENRT/BaseSRIOVNetnsTcRecipe.py new file mode 100644 index 000000000..ea9f24990 --- /dev/null +++ b/lnst/Recipes/ENRT/BaseSRIOVNetnsTcRecipe.py @@ -0,0 +1,260 @@ +from collections.abc import Collection +import time + +from lnst.Common.Parameters import ( + Param, + StrParam, + IPv4NetworkParam, + IPv6NetworkParam, +) +from lnst.Common.IpAddress import interface_addresses +from lnst.Controller import HostReq, DeviceReq, RecipeParam +from lnst.Controller.NetNamespace import NetNamespace +from lnst.RecipeCommon.endpoints import EndpointPair, IPEndpoint +from lnst.RecipeCommon.Perf.Recipe import RecipeConf +from lnst.Recipes.ENRT.helpers import ip_endpoint_pairs +from lnst.Recipes.ENRT.BaremetalEnrtRecipe import BaremetalEnrtRecipe +from lnst.RecipeCommon.Ping.PingEndpoints import PingEndpoints +from lnst.Recipes.ENRT.BaseEnrtRecipe import EnrtConfiguration +from lnst.Recipes.ENRT.ConfigMixins.OffloadSubConfigMixin import ( + OffloadSubConfigMixin, +) +from lnst.Recipes.ENRT.ConfigMixins.CommonHWSubConfigMixin import ( + CommonHWSubConfigMixin, +) + +class BaseSRIOVNetnsTcRecipe( + CommonHWSubConfigMixin, OffloadSubConfigMixin, BaremetalEnrtRecipe +): + """ + This base class provides common network configuration for tests + that aims for TC hardware offload testing. + + The class does following tasks that are common to these setups: + * sets NICs to switchdev mode + * prepare virtual functions and their representors + * moves the virtual function device to network namespace + * enables hardware offload on the PF and VF representor + + .. code-block:: none + + +--------+ + +------+ switch +-------+ + | +--------+ | + +--|--+ +--|--+ + +-------|eth0|-------+ +-------|eth0|-------+ + | +----+ | | +----+ | + | | | | | | + | vf0_representor | | vf0_representor | + | | | | | | + | +----------------+ | | +----------------+ | + | | | | | | | | | | + | | vf0 | | | | vf0 | | + | | | | | | | | + | | netns | | | | netns | | + | +----------------+ | | +----------------+ | + | | | | + | host1 | | host2 | + +--------------------+ +--------------------+ + + All sub configurations are included via Mixin classes. + + The actual test machinery is implemented in the :any:`BaseEnrtRecipe` class. + """ + host1 = HostReq() + host1.eth0 = DeviceReq(label="net1", driver=RecipeParam("driver")) + + host2 = HostReq() + host2.eth0 = DeviceReq(label="net1", driver=RecipeParam("driver")) + + """ + This parameter was created due to the difference between various kernel and distro + versions, not having consistent naming scheme of virtual function. + + Solution here is to expect deterministic VF name, which is derived from the PF name. + With specific kernel parameter `biosdevname=1` we can expect default suffix on + VF to be created to be `_n`, where n is the index of VF created. + """ + vf_suffix = StrParam(default="_0") + + offload_combinations = Param(default=( + dict(gro="on", gso="on", tso="on", tx="on", rx="on"), + dict(gro="off", gso="on", tso="on", tx="on", rx="on"), + dict(gro="on", gso="off", tso="off", tx="on", rx="on"), + dict(gro="on", gso="on", tso="off", tx="off", rx="on"), + dict(gro="on", gso="on", tso="on", tx="on", rx="off"))) + + vf_net_ipv4 = IPv4NetworkParam(default="192.168.101.0/24") + vf_net_ipv6 = IPv6NetworkParam(default="fc00::/64") + + def test_wide_configuration(self): + """ + Test wide configuration for this recipe involves switching the device to switchdev + mode, adding single VF and mapping the VF, as well as its representor. + + New namespace is created to mimic container networking, where the VF is moved. + Next, VF is assigned an IPv4 and IPv6 address on both hosts. + + host1.eth0 = 192.168.101.1/24 and fc00::1/64 + + host2.eth0 = 192.168.101.2/24 and fc00::2/64 + + Derived classes has to implement :method:`add_tc_filter_rules`. + + The derived class can also override :method:`add_network_layers`. + """ + host1, host2 = self.matched.host1, self.matched.host2 + config = super().test_wide_configuration() + + # create virtual functions + for host in [host1, host2]: + host.run(f"devlink dev eswitch set pci/{host.eth0.bus_info} mode switchdev") + time.sleep(2) + host.run(f"echo 1 > /sys/class/net/{host.eth0.name}/device/sriov_numvfs") + time.sleep(3) + + vf_ifname = dict(ifname=f"{host.eth0.name}{self.params.vf_suffix}") + host.map_device("vf_eth0", vf_ifname) + + host.newns = NetNamespace("lnst") + host.newns.vf_eth0 = host.vf_eth0 + + vf_representor_ifname = dict(ifname="eth0") + host.map_device("vf_representor_eth0", vf_representor_ifname) + + host.run(f"ethtool -K {host.vf_representor_eth0.name} hw-tc-offload on") + host.run(f"ethtool -K {host.eth0.name} hw-tc-offload on") + + vf_ipv4_addr = interface_addresses(self.params.vf_net_ipv4) + vf_ipv6_addr = interface_addresses(self.params.vf_net_ipv6) + + for host in [host1, host2]: + config.configure_and_track_ip(host.newns.vf_eth0, next(vf_ipv4_addr)) + config.configure_and_track_ip(host.newns.vf_eth0, next(vf_ipv6_addr)) + + for dev in [ + host.eth0, + host.newns.vf_eth0, + host.vf_representor_eth0, + ]: + dev.up() + + self.wait_tentative_ips(config.configured_devices) + + self.add_network_layers(config) + self.add_tc_filter_rules(config) + + return config + + def add_tc_filter_rules(self, config): + """ + This method must be implemented by derived class. + + It should configure tc qdiscs and filters used to bypass the software + path and instead use the tc hardware offload functionality of the + network devices. + + The class has to store all devices for which the ingress qdiscs have + been configured in `config.ingress_devices` list so that these can be + removed automatically in :method:`test_wide_deconfiguration`. + """ + raise NotImplementedError() + + def add_network_layers(self, config): + """ + This method is called during test wide configuration and can be used to + add additional network layers, for example tunnels to the setup. + """ + return config + + def perf_test(self, recipe_conf: RecipeConf): + result = super().perf_test(recipe_conf) + self._dump_tc_rules() + + return result + + def _dump_tc_rules(self): + for dev in self.dump_tc_rules_devices: + dev.host.run(f"tc -s filter show dev {dev.name} ingress") + + @property + def dump_tc_rules_devices(self): + return [dev for host in self.matched for dev in [host.eth0, host.vf_representor_eth0]] + + def generate_test_wide_description(self, config: EnrtConfiguration): + desc = super().generate_test_wide_description(config) + for host in [self.matched.host1, self.matched.host2]: + desc += [ + f"Configured {host.hostid}.{host.eth0.name}.driver = switchdev\n" + f"Created virtual function on {host.hostid}.{host.eth0.name} = {host.newns.vf_eth0.name}\n" + f"Created network_namespace on {host.hostid} = {host.newns.name}\n" + f"Moved interface {host.newns.vf_eth0.name} from {host.hostid} root namespace to {host.hostid}.{host.newns.name} namespace\n" + f"Created tc rules for the connectivity between virtual functions\n" + ] + desc += [ + f"Configured {dev.host.hostid}.{dev.name}.ips = {dev.ips}" + for dev in config.configured_devices + ] + return desc + + def test_wide_deconfiguration(self, config): + """ + Test wide deconfiguration deletes all the virtual function devices, + ingress filter rules and returns the control over the physical + function to base driver. + + Derived classes need to provide a list of devices for which tc ingress + qdisc was set previously through `config.ingress_devices` list. + """ + for dev in config.ingress_devices: + dev.host.run(f"tc qdisc del dev {dev.name} ingress") + + config.ingress_devices = [] + + for host in [self.matched.host1, self.matched.host2]: + host.run(f"echo 0 > /sys/class/net/{host.eth0.name}/device/sriov_numvfs") + time.sleep(2) + host.run(f"devlink dev eswitch set pci/{host.eth0.bus_info} mode legacy") + time.sleep(3) + + super().test_wide_deconfiguration(config) + + def generate_ping_endpoints(self, config): + """ + The ping endpoints for this recipe are the virtual function devices + + host1.newns.vf_eth0 and host2.newns.vf_eth0 + """ + return [PingEndpoints(self.matched.host1.newns.vf_eth0, self.matched.host2.newns.vf_eth0)] + + def generate_perf_endpoints(self, config: EnrtConfiguration) -> list[Collection[EndpointPair[IPEndpoint]]]: + """ + The perf endpoints for this recipe are the virtual function devices + + host1.newns.vf_eth0 and host2.newns.vf_eth0 + """ + return [ip_endpoint_pairs(config, (self.matched.host1.newns.vf_eth0, self.matched.host2.newns.vf_eth0))] + + @property + def pause_frames_dev_list(self): + raise NotImplementedError() + + @property + def offload_nics(self): + raise NotImplementedError() + + @property + def mtu_hw_config_dev_list(self): + raise NotImplementedError() + + @property + def coalescing_hw_config_dev_list(self): + raise NotImplementedError() + + @property + def dev_interrupt_hw_config_dev_list(self): + raise NotImplementedError() + + @property + def parallel_stream_qdisc_hw_config_dev_list(self): + raise NotImplementedError() From 5d66f859a0e098532c320db8eefdfab0e3e8572e Mon Sep 17 00:00:00 2001 From: Jan Tluka Date: Thu, 26 Oct 2023 18:39:28 +0200 Subject: [PATCH 2/6] Recipes/ENRT: add SRIOVNetnsVxlanTcRecipe Signed-off-by: Jan Tluka --- lnst/Recipes/ENRT/SRIOVNetnsVxlanTcRecipe.py | 216 +++++++++++++++++++ lnst/Recipes/ENRT/__init__.py | 1 + 2 files changed, 217 insertions(+) create mode 100644 lnst/Recipes/ENRT/SRIOVNetnsVxlanTcRecipe.py diff --git a/lnst/Recipes/ENRT/SRIOVNetnsVxlanTcRecipe.py b/lnst/Recipes/ENRT/SRIOVNetnsVxlanTcRecipe.py new file mode 100644 index 000000000..124aa4827 --- /dev/null +++ b/lnst/Recipes/ENRT/SRIOVNetnsVxlanTcRecipe.py @@ -0,0 +1,216 @@ +from lnst.Common.IpAddress import interface_addresses, AF_INET +from lnst.Common.Parameters import IPv4NetworkParam +from lnst.Devices import VxlanDevice +from lnst.Recipes.ENRT.BaseSRIOVNetnsTcRecipe import BaseSRIOVNetnsTcRecipe + + +class SRIOVNetnsVxlanTcRecipe( + BaseSRIOVNetnsTcRecipe +): + """ + This recipe implements Enrt testing for a SRIOV network scenario + with VF located in the network namespace to mimic container network. + The traffic between the virtual functions is tunneled through VXLAN. + Tc rules are created to achieve full connectivity between VF of + the hosts. + + .. code-block:: none + + +--------+ + +------+ switch +-------+ + | +--------+ | + +-------|------+ +-------|------+ + | +--|--+ | | +--|--+ | + +--|----|eth0|--- |--+ +--|----|eth0|--- |--+ + | | +----+ | | | | +----+ | | + | | | | | | | | | | + | | vxlan10 | | | | vxlan10 | | + | | | | | | | | | | + | |vf_representor| | | |vf_representor| | + | | | | | | | | + | +--TC filter---+ | | +--TC filter---+ | + | | | | | | + | +-namespace-+ | | +-namespace-+ | + | | vf0 | | | | vf0 | | + | +-----------+ | | +-----------+ | + | host1 | | host2 | + +--------------------+ +--------------------+ + + All sub configurations are included via Mixin classes. + + The actual test machinery is implemented in the :any:`BaseEnrtRecipe` class. + """ + + tunnel_net_ipv4 = IPv4NetworkParam(default="192.168.200.0/24") + + def add_network_layers(self, config): + """ + VXLAN tunnel is created between PFs on the hosts. + """ + + host1, host2 = self.matched.host1, self.matched.host2 + + # TODO: support also IPv6 + tunnel_network = interface_addresses(self.params.tunnel_net_ipv4) + for host in [host1, host2]: + config.configure_and_track_ip(host.eth0, next(tunnel_network)) + + for host in [host1, host2]: + # TODO: support also IPv6 + ip_filter = {"family": AF_INET} + host.vxlan10 = VxlanDevice( + vxlan_id=10, + realdev=host.eth0, + remote=host2.eth0.ips_filter(**ip_filter)[0] if host == host1 else host1.eth0.ips_filter(**ip_filter)[0], + dst_port=4789, + ) + + for dev in [host.newns.vf_eth0, host.vf_representor_eth0]: + # TODO: support IPv6, set to 1430 + dev.mtu = 1450 + + host.vxlan10.up() + + self.wait_tentative_ips(config.configured_devices) + + def add_tc_filter_rules(self, config): + """ + Encapsulation/decapsulation filters are added for ARP an IP traffic. + """ + host1, host2 = self.matched.host1, self.matched.host2 + + config.ingress_devices = [] + # tc configuration + for host in [host1, host2]: + host.run(f"tc qdisc add dev {host.eth0.name} ingress") + host.run(f"tc qdisc add dev {host.vf_representor_eth0.name} ingress") + host.run(f"tc qdisc add dev {host.vxlan10.name} ingress") + config.ingress_devices.extend([host.eth0, host.vf_representor_eth0, host.vxlan10]) + + # encap rules + # host1 + host1.run( + f"tc filter add dev {host1.vf_representor_eth0.name} protocol ip ingress prio 1 " + f"flower src_mac {host1.newns.vf_eth0.hwaddr} dst_mac {host2.newns.vf_eth0.hwaddr} " + f"action tunnel_key set src_ip {host1.eth0.ips_filter(family=AF_INET)[0]} dst_ip {host2.eth0.ips_filter(family=AF_INET)[0]} " + f"dst_port 4789 id 10 " + f"action mirred egress redirect dev {host1.vxlan10.name} " + ) + host1.run( + f"tc filter add dev {host1.vf_representor_eth0.name} protocol arp ingress prio 2 " + f"flower src_mac {host1.newns.vf_eth0.hwaddr} dst_mac {host2.newns.vf_eth0.hwaddr} " + f"action tunnel_key set src_ip {host1.eth0.ips_filter(family=AF_INET)[0]} dst_ip {host2.eth0.ips_filter(family=AF_INET)[0]} " + f"dst_port 4789 id 10 " + f"action mirred egress redirect dev {host1.vxlan10.name} " + ) + host1.run( + f"tc filter add dev {host1.vf_representor_eth0.name} protocol arp ingress prio 3 " + f"flower src_mac {host1.newns.vf_eth0.hwaddr} dst_mac ff:ff:ff:ff:ff:ff " + f"action tunnel_key set src_ip {host1.eth0.ips_filter(family=AF_INET)[0]} dst_ip {host2.eth0.ips_filter(family=AF_INET)[0]} " + f"dst_port 4789 id 10 " + f"action mirred egress redirect dev {host1.vxlan10.name} " + ) + + # host2 + host2.run( + f"tc filter add dev {host2.vf_representor_eth0.name} protocol ip ingress prio 1 " + f"flower src_mac {host2.newns.vf_eth0.hwaddr} dst_mac {host1.newns.vf_eth0.hwaddr} " + f"action tunnel_key set src_ip {host2.eth0.ips_filter(family=AF_INET)[0]} dst_ip {host1.eth0.ips_filter(family=AF_INET)[0]} " + f"dst_port 4789 id 10 " + f"action mirred egress redirect dev {host2.vxlan10.name} " + ) + host2.run( + f"tc filter add dev {host2.vf_representor_eth0.name} protocol arp ingress prio 2 " + f"flower src_mac {host2.newns.vf_eth0.hwaddr} dst_mac {host1.newns.vf_eth0.hwaddr} " + f"action tunnel_key set src_ip {host2.eth0.ips_filter(family=AF_INET)[0]} dst_ip {host1.eth0.ips_filter(family=AF_INET)[0]} " + f"dst_port 4789 id 10 " + f"action mirred egress redirect dev {host2.vxlan10.name} " + ) + host2.run( + f"tc filter add dev {host2.vf_representor_eth0.name} protocol arp ingress prio 3 " + f"flower src_mac {host2.newns.vf_eth0.hwaddr} dst_mac ff:ff:ff:ff:ff:ff " + f"action tunnel_key set src_ip {host2.eth0.ips_filter(family=AF_INET)[0]} dst_ip {host1.eth0.ips_filter(family=AF_INET)[0]} " + f"dst_port 4789 id 10 " + f"action mirred egress redirect dev {host2.vxlan10.name} " + ) + + # decap rules + # host1 + host1.run( + f"tc filter add dev {host1.vxlan10.name} protocol ip ingress prio 1 " + f"flower src_mac {host2.newns.vf_eth0.hwaddr} dst_mac {host1.newns.vf_eth0.hwaddr} " + f"enc_src_ip {host2.eth0.ips_filter(family=AF_INET)[0]} enc_dst_ip {host1.eth0.ips_filter(family=AF_INET)[0]} " + f"enc_dst_port 4789 enc_key_id 10 " + f"action tunnel_key unset " + f"action mirred egress redirect dev {host1.vf_representor_eth0.name} " + ) + host1.run( + f"tc filter add dev {host1.vxlan10.name} protocol arp ingress prio 2 " + f"flower src_mac {host2.newns.vf_eth0.hwaddr} dst_mac {host1.newns.vf_eth0.hwaddr} " + f"enc_src_ip {host2.eth0.ips_filter(family=AF_INET)[0]} enc_dst_ip {host1.eth0.ips_filter(family=AF_INET)[0]} " + f"enc_dst_port 4789 enc_key_id 10 " + f"action tunnel_key unset " + f"action mirred egress redirect dev {host1.vf_representor_eth0.name} " + ) + host1.run( + f"tc filter add dev {host1.vxlan10.name} protocol arp ingress prio 3 " + f"flower src_mac {host2.newns.vf_eth0.hwaddr} dst_mac ff:ff:ff:ff:ff:ff " + f"enc_src_ip {host2.eth0.ips_filter(family=AF_INET)[0]} enc_dst_ip {host1.eth0.ips_filter(family=AF_INET)[0]} " + f"enc_dst_port 4789 enc_key_id 10 " + f"action tunnel_key unset " + f"action mirred egress redirect dev {host1.vf_representor_eth0.name} " + ) + + # host2 + host2.run( + f"tc filter add dev {host2.vxlan10.name} protocol ip ingress prio 1 " + f"flower src_mac {host1.newns.vf_eth0.hwaddr} dst_mac {host2.newns.vf_eth0.hwaddr} " + f"enc_src_ip {host1.eth0.ips_filter(family=AF_INET)[0]} enc_dst_ip {host2.eth0.ips_filter(family=AF_INET)[0]} " + f"enc_dst_port 4789 enc_key_id 10 " + f"action tunnel_key unset " + f"action mirred egress redirect dev {host2.vf_representor_eth0.name} " + ) + host2.run( + f"tc filter add dev {host2.vxlan10.name} protocol arp ingress prio 2 " + f"flower src_mac {host1.newns.vf_eth0.hwaddr} dst_mac {host2.newns.vf_eth0.hwaddr} " + f"enc_src_ip {host1.eth0.ips_filter(family=AF_INET)[0]} enc_dst_ip {host2.eth0.ips_filter(family=AF_INET)[0]} " + f"enc_dst_port 4789 enc_key_id 10 " + f"action tunnel_key unset " + f"action mirred egress redirect dev {host2.vf_representor_eth0.name} " + ) + host2.run( + f"tc filter add dev {host2.vxlan10.name} protocol arp ingress prio 3 " + f"flower src_mac {host1.newns.vf_eth0.hwaddr} dst_mac ff:ff:ff:ff:ff:ff " + f"enc_src_ip {host1.eth0.ips_filter(family=AF_INET)[0]} enc_dst_ip {host2.eth0.ips_filter(family=AF_INET)[0]} " + f"enc_dst_port 4789 enc_key_id 10 " + f"action tunnel_key unset " + f"action mirred egress redirect dev {host2.vf_representor_eth0.name} " + ) + + @property + def dump_tc_rules_devices(self): + return [dev for host in self.matched for dev in [host.vxlan10, host.vf_representor_eth0]] + + @property + def pause_frames_dev_list(self): + return [self.matched.host1.newns.vf_eth0, self.matched.host2.newns.vf_eth0] + + @property + def offload_nics(self): + return [self.matched.host1.newns.vf_eth0, self.matched.host2.newns.vf_eth0] + + @property + def mtu_hw_config_dev_list(self): + return [self.matched.host1.newns.vf_eth0, self.matched.host2.newns.vf_eth0] + + @property + def coalescing_hw_config_dev_list(self): + return [self.matched.host1.newns.vf_eth0, self.matched.host2.newns.vf_eth0] + + @property + def dev_interrupt_hw_config_dev_list(self): + return [self.matched.host1.newns.vf_eth0, self.matched.host2.newns.vf_eth0] + + @property + def parallel_stream_qdisc_hw_config_dev_list(self): + return [self.matched.host1.newns.vf_eth0, self.matched.host2.newns.vf_eth0] diff --git a/lnst/Recipes/ENRT/__init__.py b/lnst/Recipes/ENRT/__init__.py index b9b7e0310..98f4e9fe6 100644 --- a/lnst/Recipes/ENRT/__init__.py +++ b/lnst/Recipes/ENRT/__init__.py @@ -103,6 +103,7 @@ from lnst.Recipes.ENRT.MPTCPRecipe import MPTCPRecipe from lnst.Recipes.ENRT.SRIOVNetnsOvSRecipe import SRIOVNetnsOvSRecipe from lnst.Recipes.ENRT.SRIOVNetnsTcRecipe import SRIOVNetnsTcRecipe +from lnst.Recipes.ENRT.SRIOVNetnsVxlanTcRecipe import SRIOVNetnsVxlanTcRecipe from lnst.Recipes.ENRT.LinuxBridgeRecipe import LinuxBridgeRecipe from lnst.Recipes.ENRT.LinuxBridgeOverBondRecipe import LinuxBridgeOverBondRecipe from lnst.Recipes.ENRT.TrafficControlRecipe import TrafficControlRecipe From bc4134a285b31c0278d8a39d77669984cebbff07 Mon Sep 17 00:00:00 2001 From: Jan Tluka Date: Fri, 27 Oct 2023 15:49:51 +0200 Subject: [PATCH 3/6] Recipes: use BaseSRIOVNetnsRecipe for SRIOVNetnsTcRecipe Signed-off-by: Jan Tluka --- lnst/Recipes/ENRT/SRIOVNetnsTcRecipe.py | 165 +----------------------- 1 file changed, 5 insertions(+), 160 deletions(-) diff --git a/lnst/Recipes/ENRT/SRIOVNetnsTcRecipe.py b/lnst/Recipes/ENRT/SRIOVNetnsTcRecipe.py index fc1d226e2..a7b3d0781 100644 --- a/lnst/Recipes/ENRT/SRIOVNetnsTcRecipe.py +++ b/lnst/Recipes/ENRT/SRIOVNetnsTcRecipe.py @@ -1,32 +1,7 @@ -from collections.abc import Collection -import time +from lnst.Recipes.ENRT.BaseSRIOVNetnsTcRecipe import BaseSRIOVNetnsTcRecipe -from lnst.Common.Parameters import ( - Param, - StrParam, - IPv4NetworkParam, - IPv6NetworkParam, -) -from lnst.Common.IpAddress import interface_addresses -from lnst.Controller import HostReq, DeviceReq, RecipeParam -from lnst.Controller.NetNamespace import NetNamespace -from lnst.RecipeCommon.endpoints import EndpointPair, IPEndpoint -from lnst.Recipes.ENRT.helpers import ip_endpoint_pairs -from lnst.Recipes.ENRT.BaremetalEnrtRecipe import BaremetalEnrtRecipe -from lnst.RecipeCommon.Ping.PingEndpoints import PingEndpoints -from lnst.RecipeCommon.Perf.Recipe import RecipeConf -from lnst.Recipes.ENRT.BaseEnrtRecipe import EnrtConfiguration -from lnst.Recipes.ENRT.ConfigMixins.OffloadSubConfigMixin import ( - OffloadSubConfigMixin, -) -from lnst.Recipes.ENRT.ConfigMixins.CommonHWSubConfigMixin import ( - CommonHWSubConfigMixin, -) - -class SRIOVNetnsTcRecipe( - CommonHWSubConfigMixin, OffloadSubConfigMixin, BaremetalEnrtRecipe -): +class SRIOVNetnsTcRecipe(BaseSRIOVNetnsTcRecipe): """ This recipe implements Enrt testing for a SRIOV network scenario with VF located in the network namespace to mimic container network. @@ -57,77 +32,14 @@ class SRIOVNetnsTcRecipe( The actual test machinery is implemented in the :any:`BaseEnrtRecipe` class. """ - host1 = HostReq() - host1.eth0 = DeviceReq(label="net1", driver=RecipeParam("driver")) - - host2 = HostReq() - host2.eth0 = DeviceReq(label="net1", driver=RecipeParam("driver")) - - """ - This parameter was created due to the difference between various kernel and distro - versions, not having consistent naming scheme of virtual function. - - Solution here is to expect deterministic VF name, which is derived from the PF name. - With specific kernel parameter `biosdevname=1` we can expect default suffix on - VF to be created to be `_n`, where n is the index of VF created. - """ - vf_suffix = StrParam(default="_0") - - offload_combinations = Param(default=( - dict(gro="on", gso="on", tso="on", tx="on", rx="on"), - dict(gro="off", gso="on", tso="on", tx="on", rx="on"), - dict(gro="on", gso="off", tso="off", tx="on", rx="on"), - dict(gro="on", gso="on", tso="off", tx="off", rx="on"), - dict(gro="on", gso="on", tso="on", tx="on", rx="off"))) - - net_ipv4 = IPv4NetworkParam(default="192.168.101.0/24") - net_ipv6 = IPv6NetworkParam(default="fc00::/64") - - def test_wide_configuration(self): - """ - Test wide configuration for this recipe involves switching the device to switchdev - mode, adding single VF and mapping the VF, as well as its representor. - New namespace is created to mimic container networking, where the VF is moved. - Next, VF is assigned an IPv4 and IPv6 address on both hosts. - Tc qdiscs and filters are used to bypass the software path and instead - use the tc hardware offload functionality in the network devices. - - host1.eth0 = 192.168.101.1/24 and fc00::1/64 - - host2.eth0 = 192.168.101.2/24 and fc00::2/64 - """ + def add_tc_filter_rules(self, config): host1, host2 = self.matched.host1, self.matched.host2 - config = super().test_wide_configuration() - - ipv4_addr = interface_addresses(self.params.net_ipv4) - ipv6_addr = interface_addresses(self.params.net_ipv6) + config.ingress_devices = [] for host in [host1, host2]: - host.run(f"devlink dev eswitch set pci/{host.eth0.bus_info} mode switchdev") - time.sleep(2) - host.run(f"echo 1 > /sys/class/net/{host.eth0.name}/device/sriov_numvfs") - time.sleep(3) - - vf_ifname = dict(ifname=f"{host.eth0.name}{self.params.vf_suffix}") - host.map_device("vf_eth0", vf_ifname) - - host.newns = NetNamespace("lnst") - host.newns.vf_eth0 = host.vf_eth0 - - vf_representor_ifname = dict(ifname="eth0") - host.map_device("vf_representor_eth0", vf_representor_ifname) - - host.run(f"ethtool -K {host.vf_representor_eth0.name} hw-tc-offload on") - host.run(f"ethtool -K {host.eth0.name} hw-tc-offload on") - host.run(f"tc qdisc add dev {host.vf_representor_eth0.name} ingress") host.run(f"tc qdisc add dev {host.eth0.name} ingress") - - for dev in [host.eth0, host.newns.vf_eth0, host.vf_representor_eth0]: - dev.up() - - config.configure_and_track_ip(host.newns.vf_eth0, next(ipv4_addr)) - config.configure_and_track_ip(host.newns.vf_eth0, next(ipv6_addr)) + config.ingress_devices.extend([host.vf_representor_eth0, host.eth0]) host1.run(f"tc filter add dev {host1.eth0.name} " f"protocol ip ingress flower skip_sw " @@ -201,73 +113,6 @@ def test_wide_configuration(self): f"dst_mac FF:FF:FF:FF:FF:FF " f"action mirred egress redirect dev {host2.eth0.name}") - self.wait_tentative_ips(config.configured_devices) - - return config - - def perf_test(self, recipe_conf: RecipeConf): - result = super().perf_test(recipe_conf) - self._dump_tc_rules() - - return result - - def _dump_tc_rules(self): - for host in self.matched: - for dev in [host.eth0, host.vf_representor_eth0]: - host.run(f"tc -s filter show dev {dev.name} ingress") - - def generate_test_wide_description(self, config: EnrtConfiguration): - desc = super().generate_test_wide_description(config) - for host in [self.matched.host1, self.matched.host2]: - desc += [ - f"Configured {host.hostid}.{host.eth0.name}.driver = switchdev\n" - f"Created virtual function on {host.hostid}.{host.eth0.name} = {host.newns.vf_eth0.name}\n" - f"Created network_namespace on {host.hostid} = {host.newns.name}\n" - f"Moved interface {host.newns.vf_eth0.name} from {host.hostid} root namespace to {host.hostid}.{host.newns.name} namespace\n" - f"Created tc rules for the connectivity between virtual functions\n" - ] - desc += [ - f"Configured {dev.host.hostid}.{dev.name}.ips = {dev.ips}" - for dev in config.configured_devices - ] - return desc - - def test_wide_deconfiguration(self, config): - """ - Test wide deconfiguration means deleting the Linux bridge and returning the - control over the physical function to base driver. - Finally virtual function is deleted. - """ - for host in [self.matched.host1, self.matched.host2]: - host.run(f"echo 0 > /sys/class/net/{host.eth0.name}/device/sriov_numvfs") - time.sleep(2) - host.run(f"tc qdisc del dev {host.eth0.name} ingress") - time.sleep(2) - host.run(f"devlink dev eswitch set pci/{host.eth0.bus_info} mode legacy") - time.sleep(3) - - super().test_wide_deconfiguration(config) - - def generate_ping_endpoints(self, config): - """ - The ping endpoints for this recipe are simply the two matched NICs: - - host1.newns.vf_eth0 and host2.newns.vf_eth0 - - Returned as:: - - [PingEndpoints(self.matched.host1.eth0, self.matched.host2.eth0)] - """ - return [PingEndpoints(self.matched.host1.newns.vf_eth0, self.matched.host2.newns.vf_eth0)] - - def generate_perf_endpoints(self, config: EnrtConfiguration) -> list[Collection[EndpointPair[IPEndpoint]]]: - """ - The perf endpoints for this recipe are simply the two matched NICs: - - host1.newns.vf_eth0 and host2.newns.vf_eth0 - """ - return [ip_endpoint_pairs(config, (self.matched.host1.newns.vf_eth0, self.matched.host2.newns.vf_eth0))] - @property def pause_frames_dev_list(self): return [self.matched.host1.newns.vf_eth0, self.matched.host2.newns.vf_eth0] From 65f49f483735d00474bd6a9bf1649781e665ca5c Mon Sep 17 00:00:00 2001 From: Jan Tluka Date: Mon, 30 Oct 2023 12:55:50 +0100 Subject: [PATCH 4/6] Recipes/ENRT: add SRIOVNetnsGeneveTcRecipe Signed-off-by: Jan Tluka --- lnst/Recipes/ENRT/SRIOVNetnsGeneveTcRecipe.py | 216 ++++++++++++++++++ lnst/Recipes/ENRT/__init__.py | 1 + 2 files changed, 217 insertions(+) create mode 100644 lnst/Recipes/ENRT/SRIOVNetnsGeneveTcRecipe.py diff --git a/lnst/Recipes/ENRT/SRIOVNetnsGeneveTcRecipe.py b/lnst/Recipes/ENRT/SRIOVNetnsGeneveTcRecipe.py new file mode 100644 index 000000000..6d552c111 --- /dev/null +++ b/lnst/Recipes/ENRT/SRIOVNetnsGeneveTcRecipe.py @@ -0,0 +1,216 @@ +from lnst.Common.IpAddress import interface_addresses, AF_INET +from lnst.Common.Parameters import IPv4NetworkParam +from lnst.Devices import GeneveDevice +from lnst.Recipes.ENRT.BaseSRIOVNetnsTcRecipe import BaseSRIOVNetnsTcRecipe + + +class SRIOVNetnsGeneveTcRecipe( + BaseSRIOVNetnsTcRecipe +): + """ + This recipe implements Enrt testing for a SRIOV network scenario + with VF located in the network namespace to mimic container network. + The traffic between the virtual functions is tunneled through Geneve. + Tc rules are created to achieve full connectivity between VF of + the hosts. + + .. code-block:: none + + +--------+ + +------+ switch +-------+ + | +--------+ | + +-------|------+ +-------|------+ + | +--|--+ | | +--|--+ | + +--|----|eth0|--- |--+ +--|----|eth0|--- |--+ + | | +----+ | | | | +----+ | | + | | | | | | | | | | + | | gnv10 | | | | gnv10 | | + | | | | | | | | | | + | |vf_representor| | | |vf_representor| | + | | | | | | | | + | +--TC filter---+ | | +--TC filter---+ | + | | | | | | + | +-namespace-+ | | +-namespace-+ | + | | vf0 | | | | vf0 | | + | +-----------+ | | +-----------+ | + | host1 | | host2 | + +--------------------+ +--------------------+ + + All sub configurations are included via Mixin classes. + + The actual test machinery is implemented in the :any:`BaseEnrtRecipe` class. + """ + + tunnel_net_ipv4 = IPv4NetworkParam(default="192.168.200.0/24") + + def add_network_layers(self, config): + """ + Geneve tunnel is created between PFs on the hosts. + """ + + host1, host2 = self.matched.host1, self.matched.host2 + + # TODO: support also IPv6 + tunnel_network = interface_addresses(self.params.tunnel_net_ipv4) + for host in [host1, host2]: + config.configure_and_track_ip(host.eth0, next(tunnel_network)) + + for host in [host1, host2]: + # TODO: support also IPv6 + ip_filter = {"family": AF_INET} + host.gnv10 = GeneveDevice( + id=10, + realdev=host.eth0, + remote=host2.eth0.ips_filter(**ip_filter)[0] if host == host1 else host1.eth0.ips_filter(**ip_filter)[0], + dst_port=6081, + ) + + for dev in [host.newns.vf_eth0, host.vf_representor_eth0]: + # TODO: support IPv6 + dev.mtu = 1442 + + host.gnv10.up() + + self.wait_tentative_ips(config.configured_devices) + + def add_tc_filter_rules(self, config): + """ + Encapsulation/decapsulation filters are added for ARP an IP traffic. + """ + host1, host2 = self.matched.host1, self.matched.host2 + + config.ingress_devices = [] + # tc configuration + for host in [host1, host2]: + host.run(f"tc qdisc add dev {host.eth0.name} ingress") + host.run(f"tc qdisc add dev {host.vf_representor_eth0.name} ingress") + host.run(f"tc qdisc add dev {host.gnv10.name} ingress") + config.ingress_devices.extend([host.eth0, host.vf_representor_eth0, host.gnv10]) + + # encap rules + # host1 + host1.run( + f"tc filter add dev {host1.vf_representor_eth0.name} protocol ip ingress prio 1 " + f"flower src_mac {host1.newns.vf_eth0.hwaddr} dst_mac {host2.newns.vf_eth0.hwaddr} " + f"action tunnel_key set src_ip {host1.eth0.ips_filter(family=AF_INET)[0]} dst_ip {host2.eth0.ips_filter(family=AF_INET)[0]} " + f"dst_port 6081 id 10 " + f"action mirred egress redirect dev {host1.gnv10.name} " + ) + host1.run( + f"tc filter add dev {host1.vf_representor_eth0.name} protocol arp ingress prio 2 " + f"flower src_mac {host1.newns.vf_eth0.hwaddr} dst_mac {host2.newns.vf_eth0.hwaddr} " + f"action tunnel_key set src_ip {host1.eth0.ips_filter(family=AF_INET)[0]} dst_ip {host2.eth0.ips_filter(family=AF_INET)[0]} " + f"dst_port 6081 id 10 " + f"action mirred egress redirect dev {host1.gnv10.name} " + ) + host1.run( + f"tc filter add dev {host1.vf_representor_eth0.name} protocol arp ingress prio 3 " + f"flower src_mac {host1.newns.vf_eth0.hwaddr} dst_mac ff:ff:ff:ff:ff:ff " + f"action tunnel_key set src_ip {host1.eth0.ips_filter(family=AF_INET)[0]} dst_ip {host2.eth0.ips_filter(family=AF_INET)[0]} " + f"dst_port 6081 id 10 " + f"action mirred egress redirect dev {host1.gnv10.name} " + ) + + # host2 + host2.run( + f"tc filter add dev {host2.vf_representor_eth0.name} protocol ip ingress prio 1 " + f"flower src_mac {host2.newns.vf_eth0.hwaddr} dst_mac {host1.newns.vf_eth0.hwaddr} " + f"action tunnel_key set src_ip {host2.eth0.ips_filter(family=AF_INET)[0]} dst_ip {host1.eth0.ips_filter(family=AF_INET)[0]} " + f"dst_port 6081 id 10 " + f"action mirred egress redirect dev {host2.gnv10.name} " + ) + host2.run( + f"tc filter add dev {host2.vf_representor_eth0.name} protocol arp ingress prio 2 " + f"flower src_mac {host2.newns.vf_eth0.hwaddr} dst_mac {host1.newns.vf_eth0.hwaddr} " + f"action tunnel_key set src_ip {host2.eth0.ips_filter(family=AF_INET)[0]} dst_ip {host1.eth0.ips_filter(family=AF_INET)[0]} " + f"dst_port 6081 id 10 " + f"action mirred egress redirect dev {host2.gnv10.name} " + ) + host2.run( + f"tc filter add dev {host2.vf_representor_eth0.name} protocol arp ingress prio 3 " + f"flower src_mac {host2.newns.vf_eth0.hwaddr} dst_mac ff:ff:ff:ff:ff:ff " + f"action tunnel_key set src_ip {host2.eth0.ips_filter(family=AF_INET)[0]} dst_ip {host1.eth0.ips_filter(family=AF_INET)[0]} " + f"dst_port 6081 id 10 " + f"action mirred egress redirect dev {host2.gnv10.name} " + ) + + # decap rules + # host1 + host1.run( + f"tc filter add dev {host1.gnv10.name} protocol ip ingress prio 1 " + f"flower src_mac {host2.newns.vf_eth0.hwaddr} dst_mac {host1.newns.vf_eth0.hwaddr} " + f"enc_src_ip {host2.eth0.ips_filter(family=AF_INET)[0]} enc_dst_ip {host1.eth0.ips_filter(family=AF_INET)[0]} " + f"enc_dst_port 6081 enc_key_id 10 " + f"action tunnel_key unset " + f"action mirred egress redirect dev {host1.vf_representor_eth0.name} " + ) + host1.run( + f"tc filter add dev {host1.gnv10.name} protocol arp ingress prio 2 " + f"flower src_mac {host2.newns.vf_eth0.hwaddr} dst_mac {host1.newns.vf_eth0.hwaddr} " + f"enc_src_ip {host2.eth0.ips_filter(family=AF_INET)[0]} enc_dst_ip {host1.eth0.ips_filter(family=AF_INET)[0]} " + f"enc_dst_port 6081 enc_key_id 10 " + f"action tunnel_key unset " + f"action mirred egress redirect dev {host1.vf_representor_eth0.name} " + ) + host1.run( + f"tc filter add dev {host1.gnv10.name} protocol arp ingress prio 3 " + f"flower src_mac {host2.newns.vf_eth0.hwaddr} dst_mac ff:ff:ff:ff:ff:ff " + f"enc_src_ip {host2.eth0.ips_filter(family=AF_INET)[0]} enc_dst_ip {host1.eth0.ips_filter(family=AF_INET)[0]} " + f"enc_dst_port 6081 enc_key_id 10 " + f"action tunnel_key unset " + f"action mirred egress redirect dev {host1.vf_representor_eth0.name} " + ) + + # host2 + host2.run( + f"tc filter add dev {host2.gnv10.name} protocol ip ingress prio 1 " + f"flower src_mac {host1.newns.vf_eth0.hwaddr} dst_mac {host2.newns.vf_eth0.hwaddr} " + f"enc_src_ip {host1.eth0.ips_filter(family=AF_INET)[0]} enc_dst_ip {host2.eth0.ips_filter(family=AF_INET)[0]} " + f"enc_dst_port 6081 enc_key_id 10 " + f"action tunnel_key unset " + f"action mirred egress redirect dev {host2.vf_representor_eth0.name} " + ) + host2.run( + f"tc filter add dev {host2.gnv10.name} protocol arp ingress prio 2 " + f"flower src_mac {host1.newns.vf_eth0.hwaddr} dst_mac {host2.newns.vf_eth0.hwaddr} " + f"enc_src_ip {host1.eth0.ips_filter(family=AF_INET)[0]} enc_dst_ip {host2.eth0.ips_filter(family=AF_INET)[0]} " + f"enc_dst_port 6081 enc_key_id 10 " + f"action tunnel_key unset " + f"action mirred egress redirect dev {host2.vf_representor_eth0.name} " + ) + host2.run( + f"tc filter add dev {host2.gnv10.name} protocol arp ingress prio 3 " + f"flower src_mac {host1.newns.vf_eth0.hwaddr} dst_mac ff:ff:ff:ff:ff:ff " + f"enc_src_ip {host1.eth0.ips_filter(family=AF_INET)[0]} enc_dst_ip {host2.eth0.ips_filter(family=AF_INET)[0]} " + f"enc_dst_port 6081 enc_key_id 10 " + f"action tunnel_key unset " + f"action mirred egress redirect dev {host2.vf_representor_eth0.name} " + ) + + @property + def dump_tc_rules_devices(self): + return [dev for host in self.matched for dev in [host.gnv10, host.vf_representor_eth0]] + + @property + def pause_frames_dev_list(self): + return [self.matched.host1.newns.vf_eth0, self.matched.host2.newns.vf_eth0] + + @property + def offload_nics(self): + return [self.matched.host1.newns.vf_eth0, self.matched.host2.newns.vf_eth0] + + @property + def mtu_hw_config_dev_list(self): + return [self.matched.host1.newns.vf_eth0, self.matched.host2.newns.vf_eth0] + + @property + def coalescing_hw_config_dev_list(self): + return [self.matched.host1.newns.vf_eth0, self.matched.host2.newns.vf_eth0] + + @property + def dev_interrupt_hw_config_dev_list(self): + return [self.matched.host1.newns.vf_eth0, self.matched.host2.newns.vf_eth0] + + @property + def parallel_stream_qdisc_hw_config_dev_list(self): + return [self.matched.host1.newns.vf_eth0, self.matched.host2.newns.vf_eth0] diff --git a/lnst/Recipes/ENRT/__init__.py b/lnst/Recipes/ENRT/__init__.py index 98f4e9fe6..72df67b64 100644 --- a/lnst/Recipes/ENRT/__init__.py +++ b/lnst/Recipes/ENRT/__init__.py @@ -104,6 +104,7 @@ from lnst.Recipes.ENRT.SRIOVNetnsOvSRecipe import SRIOVNetnsOvSRecipe from lnst.Recipes.ENRT.SRIOVNetnsTcRecipe import SRIOVNetnsTcRecipe from lnst.Recipes.ENRT.SRIOVNetnsVxlanTcRecipe import SRIOVNetnsVxlanTcRecipe +from lnst.Recipes.ENRT.SRIOVNetnsGeneveTcRecipe import SRIOVNetnsGeneveTcRecipe from lnst.Recipes.ENRT.LinuxBridgeRecipe import LinuxBridgeRecipe from lnst.Recipes.ENRT.LinuxBridgeOverBondRecipe import LinuxBridgeOverBondRecipe from lnst.Recipes.ENRT.TrafficControlRecipe import TrafficControlRecipe From ee231d6dbc1b2fa3ac2216c0770d893504e7173f Mon Sep 17 00:00:00 2001 From: Jan Tluka Date: Wed, 1 Nov 2023 16:20:03 +0100 Subject: [PATCH 5/6] SRIOVNetnsVxlanTcRecipe.py: use config.ips_for_device() Signed-off-by: Jan Tluka --- lnst/Recipes/ENRT/SRIOVNetnsVxlanTcRecipe.py | 27 ++++++++++---------- 1 file changed, 13 insertions(+), 14 deletions(-) diff --git a/lnst/Recipes/ENRT/SRIOVNetnsVxlanTcRecipe.py b/lnst/Recipes/ENRT/SRIOVNetnsVxlanTcRecipe.py index 124aa4827..248083b92 100644 --- a/lnst/Recipes/ENRT/SRIOVNetnsVxlanTcRecipe.py +++ b/lnst/Recipes/ENRT/SRIOVNetnsVxlanTcRecipe.py @@ -57,11 +57,10 @@ def add_network_layers(self, config): for host in [host1, host2]: # TODO: support also IPv6 - ip_filter = {"family": AF_INET} host.vxlan10 = VxlanDevice( vxlan_id=10, realdev=host.eth0, - remote=host2.eth0.ips_filter(**ip_filter)[0] if host == host1 else host1.eth0.ips_filter(**ip_filter)[0], + remote=config.ips_for_device(host2.eth0, family=AF_INET)[0] if host == host1 else config.ips_for_device(host1.eth0, family=AF_INET)[0], dst_port=4789, ) @@ -92,21 +91,21 @@ def add_tc_filter_rules(self, config): host1.run( f"tc filter add dev {host1.vf_representor_eth0.name} protocol ip ingress prio 1 " f"flower src_mac {host1.newns.vf_eth0.hwaddr} dst_mac {host2.newns.vf_eth0.hwaddr} " - f"action tunnel_key set src_ip {host1.eth0.ips_filter(family=AF_INET)[0]} dst_ip {host2.eth0.ips_filter(family=AF_INET)[0]} " + f"action tunnel_key set src_ip {config.ips_for_device(host1.eth0, family=AF_INET)[0]} dst_ip {config.ips_for_device(host2.eth0, family=AF_INET)[0]} " f"dst_port 4789 id 10 " f"action mirred egress redirect dev {host1.vxlan10.name} " ) host1.run( f"tc filter add dev {host1.vf_representor_eth0.name} protocol arp ingress prio 2 " f"flower src_mac {host1.newns.vf_eth0.hwaddr} dst_mac {host2.newns.vf_eth0.hwaddr} " - f"action tunnel_key set src_ip {host1.eth0.ips_filter(family=AF_INET)[0]} dst_ip {host2.eth0.ips_filter(family=AF_INET)[0]} " + f"action tunnel_key set src_ip {config.ips_for_device(host1.eth0, family=AF_INET)[0]} dst_ip {config.ips_for_device(host2.eth0, family=AF_INET)[0]} " f"dst_port 4789 id 10 " f"action mirred egress redirect dev {host1.vxlan10.name} " ) host1.run( f"tc filter add dev {host1.vf_representor_eth0.name} protocol arp ingress prio 3 " f"flower src_mac {host1.newns.vf_eth0.hwaddr} dst_mac ff:ff:ff:ff:ff:ff " - f"action tunnel_key set src_ip {host1.eth0.ips_filter(family=AF_INET)[0]} dst_ip {host2.eth0.ips_filter(family=AF_INET)[0]} " + f"action tunnel_key set src_ip {config.ips_for_device(host1.eth0, family=AF_INET)[0]} dst_ip {config.ips_for_device(host2.eth0, family=AF_INET)[0]} " f"dst_port 4789 id 10 " f"action mirred egress redirect dev {host1.vxlan10.name} " ) @@ -115,21 +114,21 @@ def add_tc_filter_rules(self, config): host2.run( f"tc filter add dev {host2.vf_representor_eth0.name} protocol ip ingress prio 1 " f"flower src_mac {host2.newns.vf_eth0.hwaddr} dst_mac {host1.newns.vf_eth0.hwaddr} " - f"action tunnel_key set src_ip {host2.eth0.ips_filter(family=AF_INET)[0]} dst_ip {host1.eth0.ips_filter(family=AF_INET)[0]} " + f"action tunnel_key set src_ip {config.ips_for_device(host2.eth0, family=AF_INET)[0]} dst_ip {config.ips_for_device(host1.eth0, family=AF_INET)[0]} " f"dst_port 4789 id 10 " f"action mirred egress redirect dev {host2.vxlan10.name} " ) host2.run( f"tc filter add dev {host2.vf_representor_eth0.name} protocol arp ingress prio 2 " f"flower src_mac {host2.newns.vf_eth0.hwaddr} dst_mac {host1.newns.vf_eth0.hwaddr} " - f"action tunnel_key set src_ip {host2.eth0.ips_filter(family=AF_INET)[0]} dst_ip {host1.eth0.ips_filter(family=AF_INET)[0]} " + f"action tunnel_key set src_ip {config.ips_for_device(host2.eth0, family=AF_INET)[0]} dst_ip {config.ips_for_device(host1.eth0, family=AF_INET)[0]} " f"dst_port 4789 id 10 " f"action mirred egress redirect dev {host2.vxlan10.name} " ) host2.run( f"tc filter add dev {host2.vf_representor_eth0.name} protocol arp ingress prio 3 " f"flower src_mac {host2.newns.vf_eth0.hwaddr} dst_mac ff:ff:ff:ff:ff:ff " - f"action tunnel_key set src_ip {host2.eth0.ips_filter(family=AF_INET)[0]} dst_ip {host1.eth0.ips_filter(family=AF_INET)[0]} " + f"action tunnel_key set src_ip {config.ips_for_device(host2.eth0, family=AF_INET)[0]} dst_ip {config.ips_for_device(host1.eth0, family=AF_INET)[0]} " f"dst_port 4789 id 10 " f"action mirred egress redirect dev {host2.vxlan10.name} " ) @@ -139,7 +138,7 @@ def add_tc_filter_rules(self, config): host1.run( f"tc filter add dev {host1.vxlan10.name} protocol ip ingress prio 1 " f"flower src_mac {host2.newns.vf_eth0.hwaddr} dst_mac {host1.newns.vf_eth0.hwaddr} " - f"enc_src_ip {host2.eth0.ips_filter(family=AF_INET)[0]} enc_dst_ip {host1.eth0.ips_filter(family=AF_INET)[0]} " + f"enc_src_ip {config.ips_for_device(host2.eth0, family=AF_INET)[0]} enc_dst_ip {config.ips_for_device(host1.eth0, family=AF_INET)[0]} " f"enc_dst_port 4789 enc_key_id 10 " f"action tunnel_key unset " f"action mirred egress redirect dev {host1.vf_representor_eth0.name} " @@ -147,7 +146,7 @@ def add_tc_filter_rules(self, config): host1.run( f"tc filter add dev {host1.vxlan10.name} protocol arp ingress prio 2 " f"flower src_mac {host2.newns.vf_eth0.hwaddr} dst_mac {host1.newns.vf_eth0.hwaddr} " - f"enc_src_ip {host2.eth0.ips_filter(family=AF_INET)[0]} enc_dst_ip {host1.eth0.ips_filter(family=AF_INET)[0]} " + f"enc_src_ip {config.ips_for_device(host2.eth0, family=AF_INET)[0]} enc_dst_ip {config.ips_for_device(host1.eth0, family=AF_INET)[0]} " f"enc_dst_port 4789 enc_key_id 10 " f"action tunnel_key unset " f"action mirred egress redirect dev {host1.vf_representor_eth0.name} " @@ -155,7 +154,7 @@ def add_tc_filter_rules(self, config): host1.run( f"tc filter add dev {host1.vxlan10.name} protocol arp ingress prio 3 " f"flower src_mac {host2.newns.vf_eth0.hwaddr} dst_mac ff:ff:ff:ff:ff:ff " - f"enc_src_ip {host2.eth0.ips_filter(family=AF_INET)[0]} enc_dst_ip {host1.eth0.ips_filter(family=AF_INET)[0]} " + f"enc_src_ip {config.ips_for_device(host2.eth0, family=AF_INET)[0]} enc_dst_ip {config.ips_for_device(host1.eth0, family=AF_INET)[0]} " f"enc_dst_port 4789 enc_key_id 10 " f"action tunnel_key unset " f"action mirred egress redirect dev {host1.vf_representor_eth0.name} " @@ -165,7 +164,7 @@ def add_tc_filter_rules(self, config): host2.run( f"tc filter add dev {host2.vxlan10.name} protocol ip ingress prio 1 " f"flower src_mac {host1.newns.vf_eth0.hwaddr} dst_mac {host2.newns.vf_eth0.hwaddr} " - f"enc_src_ip {host1.eth0.ips_filter(family=AF_INET)[0]} enc_dst_ip {host2.eth0.ips_filter(family=AF_INET)[0]} " + f"enc_src_ip {config.ips_for_device(host1.eth0, family=AF_INET)[0]} enc_dst_ip {config.ips_for_device(host2.eth0, family=AF_INET)[0]} " f"enc_dst_port 4789 enc_key_id 10 " f"action tunnel_key unset " f"action mirred egress redirect dev {host2.vf_representor_eth0.name} " @@ -173,7 +172,7 @@ def add_tc_filter_rules(self, config): host2.run( f"tc filter add dev {host2.vxlan10.name} protocol arp ingress prio 2 " f"flower src_mac {host1.newns.vf_eth0.hwaddr} dst_mac {host2.newns.vf_eth0.hwaddr} " - f"enc_src_ip {host1.eth0.ips_filter(family=AF_INET)[0]} enc_dst_ip {host2.eth0.ips_filter(family=AF_INET)[0]} " + f"enc_src_ip {config.ips_for_device(host1.eth0, family=AF_INET)[0]} enc_dst_ip {config.ips_for_device(host2.eth0, family=AF_INET)[0]} " f"enc_dst_port 4789 enc_key_id 10 " f"action tunnel_key unset " f"action mirred egress redirect dev {host2.vf_representor_eth0.name} " @@ -181,7 +180,7 @@ def add_tc_filter_rules(self, config): host2.run( f"tc filter add dev {host2.vxlan10.name} protocol arp ingress prio 3 " f"flower src_mac {host1.newns.vf_eth0.hwaddr} dst_mac ff:ff:ff:ff:ff:ff " - f"enc_src_ip {host1.eth0.ips_filter(family=AF_INET)[0]} enc_dst_ip {host2.eth0.ips_filter(family=AF_INET)[0]} " + f"enc_src_ip {config.ips_for_device(host1.eth0, family=AF_INET)[0]} enc_dst_ip {config.ips_for_device(host2.eth0, family=AF_INET)[0]} " f"enc_dst_port 4789 enc_key_id 10 " f"action tunnel_key unset " f"action mirred egress redirect dev {host2.vf_representor_eth0.name} " From cdfe71e8310da2c8d2bda6c6e94f9877bd699620 Mon Sep 17 00:00:00 2001 From: Jan Tluka Date: Wed, 1 Nov 2023 16:24:30 +0100 Subject: [PATCH 6/6] SRIOVNetnsGeneveTcRecipe.py: use config.ips_for_device() Signed-off-by: Jan Tluka --- lnst/Recipes/ENRT/SRIOVNetnsGeneveTcRecipe.py | 27 +++++++++---------- 1 file changed, 13 insertions(+), 14 deletions(-) diff --git a/lnst/Recipes/ENRT/SRIOVNetnsGeneveTcRecipe.py b/lnst/Recipes/ENRT/SRIOVNetnsGeneveTcRecipe.py index 6d552c111..11783f59f 100644 --- a/lnst/Recipes/ENRT/SRIOVNetnsGeneveTcRecipe.py +++ b/lnst/Recipes/ENRT/SRIOVNetnsGeneveTcRecipe.py @@ -57,11 +57,10 @@ def add_network_layers(self, config): for host in [host1, host2]: # TODO: support also IPv6 - ip_filter = {"family": AF_INET} host.gnv10 = GeneveDevice( id=10, realdev=host.eth0, - remote=host2.eth0.ips_filter(**ip_filter)[0] if host == host1 else host1.eth0.ips_filter(**ip_filter)[0], + remote=config.ips_for_device(host2.eth0, family=AF_INET)[0] if host == host1 else config.ips_for_device(host1.eth0, family=AF_INET)[0], dst_port=6081, ) @@ -92,21 +91,21 @@ def add_tc_filter_rules(self, config): host1.run( f"tc filter add dev {host1.vf_representor_eth0.name} protocol ip ingress prio 1 " f"flower src_mac {host1.newns.vf_eth0.hwaddr} dst_mac {host2.newns.vf_eth0.hwaddr} " - f"action tunnel_key set src_ip {host1.eth0.ips_filter(family=AF_INET)[0]} dst_ip {host2.eth0.ips_filter(family=AF_INET)[0]} " + f"action tunnel_key set src_ip {config.ips_for_device(host1.eth0, family=AF_INET)[0]} dst_ip {config.ips_for_device(host2.eth0, family=AF_INET)[0]} " f"dst_port 6081 id 10 " f"action mirred egress redirect dev {host1.gnv10.name} " ) host1.run( f"tc filter add dev {host1.vf_representor_eth0.name} protocol arp ingress prio 2 " f"flower src_mac {host1.newns.vf_eth0.hwaddr} dst_mac {host2.newns.vf_eth0.hwaddr} " - f"action tunnel_key set src_ip {host1.eth0.ips_filter(family=AF_INET)[0]} dst_ip {host2.eth0.ips_filter(family=AF_INET)[0]} " + f"action tunnel_key set src_ip {config.ips_for_device(host1.eth0, family=AF_INET)[0]} dst_ip {config.ips_for_device(host2.eth0, family=AF_INET)[0]} " f"dst_port 6081 id 10 " f"action mirred egress redirect dev {host1.gnv10.name} " ) host1.run( f"tc filter add dev {host1.vf_representor_eth0.name} protocol arp ingress prio 3 " f"flower src_mac {host1.newns.vf_eth0.hwaddr} dst_mac ff:ff:ff:ff:ff:ff " - f"action tunnel_key set src_ip {host1.eth0.ips_filter(family=AF_INET)[0]} dst_ip {host2.eth0.ips_filter(family=AF_INET)[0]} " + f"action tunnel_key set src_ip {config.ips_for_device(host1.eth0, family=AF_INET)[0]} dst_ip {config.ips_for_device(host2.eth0, family=AF_INET)[0]} " f"dst_port 6081 id 10 " f"action mirred egress redirect dev {host1.gnv10.name} " ) @@ -115,21 +114,21 @@ def add_tc_filter_rules(self, config): host2.run( f"tc filter add dev {host2.vf_representor_eth0.name} protocol ip ingress prio 1 " f"flower src_mac {host2.newns.vf_eth0.hwaddr} dst_mac {host1.newns.vf_eth0.hwaddr} " - f"action tunnel_key set src_ip {host2.eth0.ips_filter(family=AF_INET)[0]} dst_ip {host1.eth0.ips_filter(family=AF_INET)[0]} " + f"action tunnel_key set src_ip {config.ips_for_device(host2.eth0, family=AF_INET)[0]} dst_ip {config.ips_for_device(host1.eth0, family=AF_INET)[0]} " f"dst_port 6081 id 10 " f"action mirred egress redirect dev {host2.gnv10.name} " ) host2.run( f"tc filter add dev {host2.vf_representor_eth0.name} protocol arp ingress prio 2 " f"flower src_mac {host2.newns.vf_eth0.hwaddr} dst_mac {host1.newns.vf_eth0.hwaddr} " - f"action tunnel_key set src_ip {host2.eth0.ips_filter(family=AF_INET)[0]} dst_ip {host1.eth0.ips_filter(family=AF_INET)[0]} " + f"action tunnel_key set src_ip {config.ips_for_device(host2.eth0, family=AF_INET)[0]} dst_ip {config.ips_for_device(host1.eth0, family=AF_INET)[0]} " f"dst_port 6081 id 10 " f"action mirred egress redirect dev {host2.gnv10.name} " ) host2.run( f"tc filter add dev {host2.vf_representor_eth0.name} protocol arp ingress prio 3 " f"flower src_mac {host2.newns.vf_eth0.hwaddr} dst_mac ff:ff:ff:ff:ff:ff " - f"action tunnel_key set src_ip {host2.eth0.ips_filter(family=AF_INET)[0]} dst_ip {host1.eth0.ips_filter(family=AF_INET)[0]} " + f"action tunnel_key set src_ip {config.ips_for_device(host2.eth0, family=AF_INET)[0]} dst_ip {config.ips_for_device(host1.eth0, family=AF_INET)[0]} " f"dst_port 6081 id 10 " f"action mirred egress redirect dev {host2.gnv10.name} " ) @@ -139,7 +138,7 @@ def add_tc_filter_rules(self, config): host1.run( f"tc filter add dev {host1.gnv10.name} protocol ip ingress prio 1 " f"flower src_mac {host2.newns.vf_eth0.hwaddr} dst_mac {host1.newns.vf_eth0.hwaddr} " - f"enc_src_ip {host2.eth0.ips_filter(family=AF_INET)[0]} enc_dst_ip {host1.eth0.ips_filter(family=AF_INET)[0]} " + f"enc_src_ip {config.ips_for_device(host2.eth0, family=AF_INET)[0]} enc_dst_ip {config.ips_for_device(host1.eth0, family=AF_INET)[0]} " f"enc_dst_port 6081 enc_key_id 10 " f"action tunnel_key unset " f"action mirred egress redirect dev {host1.vf_representor_eth0.name} " @@ -147,7 +146,7 @@ def add_tc_filter_rules(self, config): host1.run( f"tc filter add dev {host1.gnv10.name} protocol arp ingress prio 2 " f"flower src_mac {host2.newns.vf_eth0.hwaddr} dst_mac {host1.newns.vf_eth0.hwaddr} " - f"enc_src_ip {host2.eth0.ips_filter(family=AF_INET)[0]} enc_dst_ip {host1.eth0.ips_filter(family=AF_INET)[0]} " + f"enc_src_ip {config.ips_for_device(host2.eth0, family=AF_INET)[0]} enc_dst_ip {config.ips_for_device(host1.eth0, family=AF_INET)[0]} " f"enc_dst_port 6081 enc_key_id 10 " f"action tunnel_key unset " f"action mirred egress redirect dev {host1.vf_representor_eth0.name} " @@ -155,7 +154,7 @@ def add_tc_filter_rules(self, config): host1.run( f"tc filter add dev {host1.gnv10.name} protocol arp ingress prio 3 " f"flower src_mac {host2.newns.vf_eth0.hwaddr} dst_mac ff:ff:ff:ff:ff:ff " - f"enc_src_ip {host2.eth0.ips_filter(family=AF_INET)[0]} enc_dst_ip {host1.eth0.ips_filter(family=AF_INET)[0]} " + f"enc_src_ip {config.ips_for_device(host2.eth0, family=AF_INET)[0]} enc_dst_ip {config.ips_for_device(host1.eth0, family=AF_INET)[0]} " f"enc_dst_port 6081 enc_key_id 10 " f"action tunnel_key unset " f"action mirred egress redirect dev {host1.vf_representor_eth0.name} " @@ -165,7 +164,7 @@ def add_tc_filter_rules(self, config): host2.run( f"tc filter add dev {host2.gnv10.name} protocol ip ingress prio 1 " f"flower src_mac {host1.newns.vf_eth0.hwaddr} dst_mac {host2.newns.vf_eth0.hwaddr} " - f"enc_src_ip {host1.eth0.ips_filter(family=AF_INET)[0]} enc_dst_ip {host2.eth0.ips_filter(family=AF_INET)[0]} " + f"enc_src_ip {config.ips_for_device(host1.eth0, family=AF_INET)[0]} enc_dst_ip {config.ips_for_device(host2.eth0, family=AF_INET)[0]} " f"enc_dst_port 6081 enc_key_id 10 " f"action tunnel_key unset " f"action mirred egress redirect dev {host2.vf_representor_eth0.name} " @@ -173,7 +172,7 @@ def add_tc_filter_rules(self, config): host2.run( f"tc filter add dev {host2.gnv10.name} protocol arp ingress prio 2 " f"flower src_mac {host1.newns.vf_eth0.hwaddr} dst_mac {host2.newns.vf_eth0.hwaddr} " - f"enc_src_ip {host1.eth0.ips_filter(family=AF_INET)[0]} enc_dst_ip {host2.eth0.ips_filter(family=AF_INET)[0]} " + f"enc_src_ip {config.ips_for_device(host1.eth0, family=AF_INET)[0]} enc_dst_ip {config.ips_for_device(host2.eth0, family=AF_INET)[0]} " f"enc_dst_port 6081 enc_key_id 10 " f"action tunnel_key unset " f"action mirred egress redirect dev {host2.vf_representor_eth0.name} " @@ -181,7 +180,7 @@ def add_tc_filter_rules(self, config): host2.run( f"tc filter add dev {host2.gnv10.name} protocol arp ingress prio 3 " f"flower src_mac {host1.newns.vf_eth0.hwaddr} dst_mac ff:ff:ff:ff:ff:ff " - f"enc_src_ip {host1.eth0.ips_filter(family=AF_INET)[0]} enc_dst_ip {host2.eth0.ips_filter(family=AF_INET)[0]} " + f"enc_src_ip {config.ips_for_device(host1.eth0, family=AF_INET)[0]} enc_dst_ip {config.ips_for_device(host2.eth0, family=AF_INET)[0]} " f"enc_dst_port 6081 enc_key_id 10 " f"action tunnel_key unset " f"action mirred egress redirect dev {host2.vf_representor_eth0.name} "