[PATCH] IpAddress.py: Change TODO to be to replace with ipaddress module
by pgagne@redhat.com
From: Perry Gagne <pgagne(a)redhat.com>
I happened upon this todo when looking at this code for MPTCP.
IMHO we should probably replace this with the builtin ipaddress module, or perhaps a customized subclass of it.
The ipaddress module contains many tools that can generate address, for example iterating though a subnet, and others.
https://docs.python.org/3/library/ipaddress.html#module-ipaddress
Refactoring this might be a lot of work, so I don't want to do it now, but I figured I would atleast update this todo as reminder to anyone who might be looking at the IpAddress code and want to do it.
Signed-off-by: Perry Gagne <pgagne(a)redhat.com>
---
lnst/Common/IpAddress.py | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/lnst/Common/IpAddress.py b/lnst/Common/IpAddress.py
index 26400077..e572f32b 100644
--- a/lnst/Common/IpAddress.py
+++ b/lnst/Common/IpAddress.py
@@ -15,8 +15,9 @@ import socket
from socket import inet_pton, inet_ntop, AF_INET, AF_INET6
from lnst.Common.LnstError import LnstError
-#TODO create various generators for IPNetworks and IPaddresses in the same
-#network
+#TODO Replace this with Python's builtin ipaddress module.
+# To make use of its IP address generators.
+# https://docs.python.org/3/library/ipaddress.html#module-ipaddress
class BaseIpAddress(object):
def __init__(self, addr, flags=None):
--
2.30.2
2 years, 4 months
[PATCH] NonzeroFlowEvaluator: add support for "metrics_to_evaluate"
by olichtne@redhat.com
From: Ondrej Lichtner <olichtne(a)redhat.com>
Similar to the BaselineFlowEvaluator, this adds support for selecting
which metrics should be evaluated for the "non zero state". This can be
useful in case there is a known metrics/test that always reports a 0.
Signed-off-by: Ondrej Lichtner <olichtne(a)redhat.com>
---
.../Perf/Evaluators/NonzeroFlowEvaluator.py | 34 +++++++++++++------
1 file changed, 23 insertions(+), 11 deletions(-)
diff --git a/lnst/RecipeCommon/Perf/Evaluators/NonzeroFlowEvaluator.py b/lnst/RecipeCommon/Perf/Evaluators/NonzeroFlowEvaluator.py
index 897d1e22..16384c55 100644
--- a/lnst/RecipeCommon/Perf/Evaluators/NonzeroFlowEvaluator.py
+++ b/lnst/RecipeCommon/Perf/Evaluators/NonzeroFlowEvaluator.py
@@ -10,6 +10,15 @@
class NonzeroFlowEvaluator(BaseResultEvaluator):
+ def __init__(self, metrics_to_evaluate: List[str] = None):
+ if metrics_to_evaluate is not None:
+ self._metrics_to_evaluate = metrics_to_evaluate
+ else:
+ self._metrics_to_evaluate = [
+ "generator_results",
+ "receiver_results",
+ ]
+
def evaluate_results(
self,
recipe: BaseRecipe,
@@ -22,16 +31,19 @@ def evaluate_results(
"Nonzero evaluation of flow:",
"{}".format(flow_results.flow),
]
- if flow_results.generator_results.average > 0:
- result_text.append("Generator reported non-zero throughput")
- else:
- result = False
- result_text.append("Generator reported zero throughput")
-
- if flow_results.receiver_results.average > 0:
- result_text.append("Receiver reported non-zero throughput")
- else:
- result = False
- result_text.append("Receiver reported zero throughput")
+ for metric_name in self._metrics_to_evaluate:
+ metric = getattr(flow_results, metric_name, None)
+ if metric:
+ if metric.average > 0:
+ result_text.append(
+ "{} reported non-zero throughput".format(
+ metric_name
+ )
+ )
+ else:
+ result = False
+ result_text.append(
+ "{} reported zero throughput".format(metric_name)
+ )
recipe.add_result(result, "\n".join(result_text))
--
2.31.1
2 years, 4 months
[PATCH v3 0/5] Fix namespaces
by Jan Tluka
This patchset fixes namespace in LNST that is currently broken. The
fundamental problem was in use of libc calls with improper parameter
types.
Thanks to Ondrej for the additional patch in [1].
v2:
Include additional fix for the test module synchronization in network namespaces.
v3:
I unified use of the bytestrings in the libc calls. I added a code
comment on making the namespace directory shared between the namespaces.
Jan Tluka (5):
Controller.NetNamespace: rename _nsname to _name
lnst.NetTestSlave: fix namespace creation/deletion
Controller.Host: pass NetNamespace to add_netns()
Controller.Machine: update add_namespace and del_namespace arguments
Controller.Machine: fix test module synchronization for network
namespaces
lnst/Controller/Host.py | 2 +-
lnst/Controller/Machine.py | 24 ++++++++------
lnst/Controller/NetNamespace.py | 2 +-
lnst/Slave/NetTestSlave.py | 55 ++++++++++++++++++++++++++-------
4 files changed, 59 insertions(+), 24 deletions(-)
--
2.26.3
2 years, 4 months
[PATCH v2 0/2] Tunnel recipes
by Jan Tluka
This patchset adds two new classes to ENRT recipe package, the
BaseTunnelRecipe and GreTunnelRecipe.
The BaseTunnelRecipe extends the BaremetalEnrtRecipe class and defines a
common API for recipes that want to configure any type of tunnels.
The API consists of three methods.
The configure_underlying_network() involves configuration of the network
stack below the tunnel and returning back the endpoints that should be
connected by the tunnel.
The create_tunnel() then takes care of configuration of the tunnel between
the endpoints.
The get_packet_assert_config() method supports the
PacketAssertTestAndEvaluate class by defining the packet capture filter
and grep patterns to test the functionality of a tunnel.
The second patch in the series adds an implementation of a recipe for
the GRE tunnel.
Both patches also extends the LNST documentation.
v2:
- moved CommonHWSubConfigMixin and OffloadSubConfigMixin from
BaseTunnelRecipe to GreTunnelRecipe
- wait_tentative_ips moved to configure_underlying_network() and
create_tunnel()
- removed the endpoints parameter of create_tunnel() and added the tunnel
endpoints to the configuration object
- reversed the order of device deletion in test_wide_deconfiguration()
- added offload_nics property to GreTunnelRecipe
Jan Tluka (2):
Recipes.ENRT: add BaseTunnelRecipe
Recipes.ENRT: add GreTunnelRecipe
docs/source/base_enrt_tunnel_class.rst | 6 +
docs/source/enrt_recipes.rst | 1 +
docs/source/specific_scenarios.rst | 1 +
lnst/Recipes/ENRT/BaseTunnelRecipe.py | 140 +++++++++++++++++++
lnst/Recipes/ENRT/GreTunnelRecipe.py | 181 +++++++++++++++++++++++++
lnst/Recipes/ENRT/__init__.py | 2 +
6 files changed, 331 insertions(+)
create mode 100644 docs/source/base_enrt_tunnel_class.rst
create mode 100644 lnst/Recipes/ENRT/BaseTunnelRecipe.py
create mode 100644 lnst/Recipes/ENRT/GreTunnelRecipe.py
--
2.26.3
2 years, 4 months
[PATCH] docs: add implementing_new_device.rst
by Jan Tluka
This adds documentation on how to create a new device type class.
Signed-off-by: Jan Tluka <jtluka(a)redhat.com>
---
docs/source/implementing_new_device.rst | 296 ++++++++++++++++++++++++
docs/source/tester_api.rst | 1 +
2 files changed, 297 insertions(+)
create mode 100644 docs/source/implementing_new_device.rst
diff --git a/docs/source/implementing_new_device.rst b/docs/source/implementing_new_device.rst
new file mode 100644
index 00000000..778a2adf
--- /dev/null
+++ b/docs/source/implementing_new_device.rst
@@ -0,0 +1,296 @@
+==========================================
+How to implement a new network device type
+==========================================
+
+This guide will explain how to extend the LNST with a new network device type.
+
+Each device type supported by LNST is implemented as a separate class in
+:mod:`lnst.Devices` module.
+
+User can import such device using the following code:
+
+.. code-block:: python
+
+ from lnst.Devices import VlanDevice
+
+To implement a class for new network device type several steps need to be done.
+
+This guide will use **gre** tunnel device as an example.
+
+.. contents:: :local:
+
+SoftDevice class
+----------------
+
+All virtual devices should inherit from the :any:`SoftDevice` class.
+
+.. code-block:: python
+
+ from lnst.Devices.SoftDevice import SoftDevice
+
+ class GreDevice(SoftDevice):
+ pass
+
+Device name template
+--------------------
+
+The new device class should define the name template for the created devices.
+If the template is not defined a generic one defined by the :any:`SoftDevice`
+class will be used instead.
+
+.. code-block:: python
+
+ from lnst.Devices.SoftDevice import SoftDevice
+
+ class GreDevice(SoftDevice):
+ _name_template = "t_gre"
+
+Device type
+-----------
+
+User must also define the device type through the ``_link_type`` class attribute.
+The value matches the link type that is used by iproute2's ``ip link`` utility.
+
+For example, the gre device is created by following command:
+
+.. code-block:: shell
+
+ ip link add new_gre_device type gre remote 192.168.200.2
+
+The `type gre` part of the command above should be used in the ``_link_type``.
+
+For other link types user can check the output of the following command:
+
+.. code-block:: shell
+
+ ip link help
+ ip -6 link help # for ipv6 specific devices
+
+So, the device code will look like this:
+
+.. code-block:: python
+
+ from lnst.Devices.SoftDevice import SoftDevice
+
+ class GreDevice(SoftDevice):
+ _name_template = "t_gre"
+ _link_type = "gre"
+
+Device parameters
+-----------------
+
+The device class may define any parameters available for the network device type.
+
+For example, the **gre** device uses the **local** and **remote** parameters
+as in the following command:
+
+.. code-block:: shell
+
+ ip link add new_gre_device type gre local 192.168.100.1 remote 192.168.200.2
+
+These parameters have to be defined as class properties with their setters.
+They have to use :any:`SoftDevice` methods to configure the device's
+parameters through kernel's netlink API:
+
+- ``_get_linkinfo_data_attr()``
+- ``_set_linkinfo_data_attr()`` for the property setters
+
+The code extended with the **remote** parameter would look like this:
+
+.. code-block:: python
+
+ @property
+ def remote(self):
+ try:
+ return ipaddress(self._get_linkinfo_data_attr("IFLA_GRE_LOCAL"))
+ except:
+ return None
+
+ @remote.setter
+ def remote(self, val):
+ self._set_linkinfo_data_attr("IFLA_GRE_LOCAL", str(ipaddress(val)))
+ self._nl_link_sync("set")
+
+In the code above the ``remote`` property returns an IP address retrieved
+through the netlink by calling the :meth:`_get_linkinfo_data_attr()` with the
+netlink's representation of the **remote** parameter, that is **IFLA_GRE_LOCAL**.
+
+The ``remote.setter`` configures the **remote** device parameter by calling
+the :meth:`_set_linkinfo_data_attr()` with the netlink's representation of the
+parameter **IFLA_GRE_LOCAL** and the IP address as the value of the parameter.
+
+The setters must always include call of the :meth:`_nl_link_sync()` to commit
+the changes through netlink.
+
+For the device specific ``IFLA_*`` strings refer to `Finding out the IFLA_* strings`_
+
+With the code above the user can now use the device class in a recipe,
+for example:
+
+.. code-block:: python
+
+ from lnst.Controller import Controller, HostReq, DeviceReq, BaseRecipe
+ from lnst.Devices.GreDevice import GreDevice
+
+ class GreRecipe(BaseRecipe):
+ machine1 = HostReq()
+ machine1.nic1 = DeviceReq(label="net1")
+
+ def test(self):
+ machine1.gre = GreDevice(remote="192.168.200.2")
+
+ ctl = Controller()
+ recipe_instance = GreRecipe()
+ ctl.run(recipe_instance)
+
+Explanation of the netlink update bulking in LNST
+-------------------------------------------------
+
+Feel free to skip this section if you're not interested in the deeper
+understanding of the device configuration in LNST.
+
+In the previous section I stated that the device parameter's setters must
+include the :meth:`_nl_link_sync()` method call to propagate the changes to
+the kernel through netlink.
+
+We might assume that configuration of a device parameter is done instantly,
+by immediately sending the update to the netlink. This however does not
+work when multiple parameters are required while the device is created.
+Additionally we want to avoid unnecessary multiple calls to the netlink.
+
+LNST solves this problem by using a bulk mode for the netlink updates.
+In short, the bulk mode is postponing of sending the netlink updates for a
+device until a bulk transfer is explicitly requested with
+``_nl_link_sync(bulk=True)``.
+
+Each :any:`SoftDevice` has bulk mode automatically enabled in the ``__init__()``
+phase, so that specifying of multiple device parameters during instantiation
+would generate just one netlink message to create the device.
+
+The bulk mode is disabled once the device is created. After that changing
+any of the properties would immediately result in propagation through the
+netlink.
+
+More information about the bulking concept is described in this
+`commit <https://github.com/LNST-project/lnst/commit/e9f1d2a5722c7a4067649fc81ef3c...>`_
+
+
+Mandatory device parameters
+---------------------------
+
+A device may require some parameters to be specified, for example a **gre**
+device requires **remote** parameter.
+
+You can specify such parameters in the class attribute ``_mandatory_params``:
+
+.. code-block:: python
+
+ class GreDevice(SoftDevice):
+ _name_template = "t_gre"
+ _link_type = "gre"
+ _mandatory_opts = ["remote"]
+
+LNST will automatically check if the mandatory parameters where specified
+in the device instance and report back a failure.
+
+Finding out the IFLA_* strings
+------------------------------
+
+The device parameters are configured through the kernel's netlink API.
+
+In the code above we have mentioned two :any:`SoftDevice` methods used for
+setting or retrieving the device parameters, the :meth:`_get_linkinfo_data_attr()`
+and :meth:`_set_linkinfo_data_attr()`. Both methods takes a name of the device
+parameter as an argument, these are prefixed with **IFLA_** string.
+
+What becomes challenging is to find out the corresponding ``IFLA_*`` strings
+for a specific network device. These are unique for each device.
+
+Here the **pyroute2** comes handy. The pyroute2 is a Python module that
+provides also an API for interacting with the kernel's netlink. LNST uses
+this module for the device management.
+
+To find out what parameters are needed to configure the test device simply
+follow the procedure below.
+
+Save the following code to file named watch_netlink.py
+
+.. code-block:: python
+
+ from pyroute2 import IPRoute
+ from pprint import pprint
+
+ with IPRoute() as ipr:
+ while True:
+ ipr.bind()
+ for message in ipr.get():
+ pprint(message)
+
+Run the script in background and run an iproute command to create a gre
+tunnel device (or any other device of your interest).
+
+.. code-block:: shell
+
+ ./watch_netlink.py &
+
+ ip link add mygre type gre local 192.168.200.1 remote 192.168.200.2
+
+The ``watch_netlink.py`` script should print the complete netlink message
+including the details of ``IFLA_LINKINFO``. So simply find the message that
+contains ``('IFLA_IFNAME', 'mygre')`` (**mygre** matches the device name used
+in the ``ip link`` command above).
+
+.. code-block::
+ :emphasize-lines: 2,27
+
+ {'__align': (),
+ 'attrs': [('IFLA_IFNAME', 'mygre'),
+ ('IFLA_TXQLEN', 1000),
+ ('IFLA_OPERSTATE', 'DOWN'),
+ ('IFLA_LINKMODE', 0),
+ ('IFLA_MTU', 1476),
+ ('UNKNOWN', {'header': {'length': 8, 'type': 50}}),
+ ('UNKNOWN', {'header': {'length': 8, 'type': 51}}),
+ ('IFLA_GROUP', 0),
+ ('IFLA_PROMISCUITY', 0),
+ ('IFLA_NUM_TX_QUEUES', 1),
+ ('IFLA_GSO_MAX_SEGS', 65535),
+ ('IFLA_GSO_MAX_SIZE', 65536),
+ ('IFLA_NUM_RX_QUEUES', 1),
+ ('IFLA_CARRIER', 1),
+ ('IFLA_QDISC', 'noop'),
+ ('IFLA_CARRIER_CHANGES', 0),
+ ('IFLA_PROTO_DOWN', 0),
+ ('IFLA_CARRIER_UP_COUNT', 0),
+ ('IFLA_CARRIER_DOWN_COUNT', 0),
+ ('IFLA_MAP', {'mem_start': 0, 'mem_end': 0, 'base_addr': 0, 'irq': 0, 'dma': 0, 'port': 0}),
+ ('IFLA_ADDRESS', 'c0:a8:c8:01:08:00'),
+ ('IFLA_BROADCAST', 'c0:a8:c8:02:c4:00'),
+ ('IFLA_STATS64', {'rx_packets': 0, 'tx_packets': 0, 'rx_bytes': 0, 'tx_bytes': 0, 'rx_errors': 0, 'tx_errors': 0, 'rx_dropped': 0, 'tx_dropped': 0, 'multicast': 0, 'collisions': 0, 'rx_length_errors': 0, 'rx_over_errors': 0, 'rx_crc_errors': 0, 'rx_frame_errors': 0, 'rx_fifo_errors': 0, 'rx_missed_errors': 0, 'tx_aborted_errors': 0, 'tx_carrier_errors': 0, 'tx_fifo_errors': 0, 'tx_heartbeat_errors': 0, 'tx_window_errors': 0, 'rx_compressed': 0, 'tx_compressed': 0}),
+ ('IFLA_STATS', {'rx_packets': 0, 'tx_packets': 0, 'rx_bytes': 0, 'tx_bytes': 0, 'rx_errors': 0, 'tx_errors': 0, 'rx_dropped': 0, 'tx_dropped': 0, 'multicast': 0, 'collisions': 0, 'rx_length_errors': 0, 'rx_over_errors': 0, 'rx_crc_errors': 0, 'rx_frame_errors': 0, 'rx_fifo_errors': 0, 'rx_missed_errors': 0, 'tx_aborted_errors': 0, 'tx_carrier_errors': 0, 'tx_fifo_errors': 0, 'tx_heartbeat_errors': 0, 'tx_window_errors': 0, 'rx_compressed': 0, 'tx_compressed': 0}),
+ ('IFLA_XDP', '05:00:02:00:00:00:00:00'),
+ ('IFLA_LINKINFO', {'attrs': [('IFLA_INFO_KIND', 'gre'), ('IFLA_INFO_DATA', {'attrs': [('UNKNOWN', {'header': {'length': 5, 'type': 22}}), ('IFLA_GRE_LINK', 0), ('IFLA_GRE_IFLAGS', 0), ('IFLA_GRE_OFLAGS', 0), ('IFLA_GRE_IKEY', 0), ('IFLA_GRE_OKEY', 0), ('IFLA_GRE_LOCAL', '192.168.200.1'), ('IFLA_GRE_REMOTE', '192.168.200.2'), ('IFLA_GRE_TTL', 0), ('IFLA_GRE_TOS', 0), ('IFLA_GRE_PMTUDISC', 1), ('IFLA_GRE_FWMARK', 0), ('IFLA_GRE_ENCAP_TYPE', 0), ('IFLA_GRE_ENCAP_SPORT', 0), ('IFLA_GRE_ENCAP_DPORT', 0), ('IFLA_GRE_ENCAP_FLAGS', 0), ('IFLA_GRE_IGNORE_DF', 0)]})]}),
+ ('IFLA_LINK', 0),
+ ('UNKNOWN', {'header': {'length': 8, 'type': 54}}),
+ ('IFLA_AF_SPEC', {'attrs': [('AF_INET', {'dummy': 65668, 'forwarding': 0, 'mc_forwarding': 0, 'proxy_arp': 0, 'accept_redirects': 1, 'secure_redirects': 1, 'send_redirects': 1, 'shared_media': 1, 'rp_filter': 0, 'accept_source_route': 1, 'bootp_relay': 0, 'log_martians': 0, 'tag': 0, 'arpfilter': 0, 'medium_id': 0, 'noxfrm': 0, 'nopolicy': 0, 'force_igmp_version': 0, 'arp_announce': 0, 'arp_ignore': 0, 'promote_secondaries': 0, 'arp_accept': 0, 'arp_notify': 0, 'accept_local': 0, 'src_vmark': 0, 'proxy_arp_pvlan': 0, 'route_localnet': 0, 'igmpv2_unsolicited_report_interval': 10000, 'igmpv3_unsolicited_report_interval': 1000})]})],
+ 'change': 0,
+ 'event': 'RTM_NEWLINK',
+ 'family': 0,
+ 'flags': 144,
+ 'header': {'error': None,
+ 'flags': 0,
+ 'length': 860,
+ 'pid': 0,
+ 'sequence_number': 0,
+ 'stats': Stats(qsize=0, delta=0, delay=0),
+ 'target': 'localhost',
+ 'type': 16},
+ 'ifi_type': 778,
+ 'index': 116,
+ 'state': 'down'}
+
+So, inspecting the output above, the relevant ``IFLA_*`` strings are found
+under **IFLA_LINKINFO** / **IFLA_INFO_DATA** (in highlighted lines):
+
+- ``('IFLA_GRE_LOCAL', '192.168.200.1')``
+- ``('IFLA_GRE_REMOTE', '192.168.200.2')``
diff --git a/docs/source/tester_api.rst b/docs/source/tester_api.rst
index 65a2e1bd..7a21b0cf 100644
--- a/docs/source/tester_api.rst
+++ b/docs/source/tester_api.rst
@@ -9,3 +9,4 @@ Test developer API
controller_api
parameters
recipe_run_export
+ implementing_new_device
--
2.26.3
2 years, 4 months
[PATCH v2] Devices: add Ip6GreDevice
by Jan Tluka
This patch adds new device Ip6GreDevice to setup a ip6gre tunnel device.
v2:
Use "t_ip6gre" for the _name_template to avoid confusion with the gre
devices.
Signed-off-by: Jan Tluka <jtluka(a)redhat.com>
---
lnst/Devices/Ip6GreDevice.py | 44 ++++++++++++++++++++++++++++++++++++
lnst/Devices/__init__.py | 2 ++
2 files changed, 46 insertions(+)
create mode 100644 lnst/Devices/Ip6GreDevice.py
diff --git a/lnst/Devices/Ip6GreDevice.py b/lnst/Devices/Ip6GreDevice.py
new file mode 100644
index 00000000..873d00ed
--- /dev/null
+++ b/lnst/Devices/Ip6GreDevice.py
@@ -0,0 +1,44 @@
+"""
+Defines the Ip6GreDevice class.
+
+Copyright 2021 Red Hat, Inc.
+Licensed under the GNU General Public License, version 2 as
+published by the Free Software Foundation; see COPYING for details.
+"""
+
+__author__ = """
+jtluka(a)redhat.com (Jan Tluka)
+"""
+
+from lnst.Common.IpAddress import ipaddress
+from lnst.Devices.SoftDevice import SoftDevice
+
+
+class Ip6GreDevice(SoftDevice):
+ _name_template = "t_ip6gre"
+ _link_type = "ip6gre"
+ _mandatory_opts = ["remote"]
+
+ @property
+ def local(self):
+ try:
+ return ipaddress(self._get_linkinfo_data_attr("IFLA_IP6GRE_LOCAL"))
+ except:
+ return None
+
+ @local.setter
+ def local(self, val):
+ self._set_linkinfo_data_attr("IFLA_IP6GRE_LOCAL", str(ipaddress(val)))
+ self._nl_link_sync("set")
+
+ @property
+ def remote(self):
+ try:
+ return ipaddress(self._get_linkinfo_data_attr("IFLA_IP6GRE_REMOTE"))
+ except:
+ return None
+
+ @remote.setter
+ def remote(self, val):
+ self._set_linkinfo_data_attr("IFLA_IP6GRE_REMOTE", str(ipaddress(val)))
+ self._nl_link_sync("set")
diff --git a/lnst/Devices/__init__.py b/lnst/Devices/__init__.py
index ddc462e8..2a604de8 100644
--- a/lnst/Devices/__init__.py
+++ b/lnst/Devices/__init__.py
@@ -8,6 +8,7 @@ from lnst.Devices.MacvlanDevice import MacvlanDevice
from lnst.Devices.VlanDevice import VlanDevice
from lnst.Devices.VxlanDevice import VxlanDevice
from lnst.Devices.GreDevice import GreDevice
+from lnst.Devices.Ip6GreDevice import Ip6GreDevice
from lnst.Devices.VtiDevice import VtiDevice, Vti6Device
from lnst.Devices.VethDevice import VethDevice, PairedVethDevice
from lnst.Devices.VethPair import VethPair
@@ -22,6 +23,7 @@ device_classes = [
("VlanDevice", VlanDevice),
("VxlanDevice", VxlanDevice),
("GreDevice", GreDevice),
+ ("Ip6GreDevice", Ip6GreDevice),
("VethDevice", VethDevice),
("PairedVethDevice", PairedVethDevice),
("VtiDevice", VtiDevice),
--
2.26.3
2 years, 4 months
[PATCH] Device: add a wait metchanism to _ip_add_one method
by olichtne@redhat.com
From: Ondrej Lichtner <olichtne(a)redhat.com>
Unfortunatelly when an ip address is configured via netlink (a create ip
address message is sent) we don't receive a response message that would
indicate success or failure.
Because of that we've sometimes seen race condition issues with
configuring ipv6 addresses (that take slightly longer to create) on the
controller that was trying wait for the "tentative" state to disappear
from the ip addresses (because the address wasn't created yet there was
nothing to wait for).
By adding a wait loop here the race condition disappears - either the ip
address appears or an exception is raised indicationg a potential
problem with the configuration.
Signed-off-by: Ondrej Lichtner <olichtne(a)redhat.com>
---
lnst/Devices/Device.py | 8 ++++++++
1 file changed, 8 insertions(+)
diff --git a/lnst/Devices/Device.py b/lnst/Devices/Device.py
index 30b82f06..c31a018f 100644
--- a/lnst/Devices/Device.py
+++ b/lnst/Devices/Device.py
@@ -558,6 +558,14 @@ def _ip_add_one(self, addr):
if ip not in self.ips:
self._ipr_wrapper("addr", "add", index=self.ifindex,
address=str(ip), mask=ip.prefixlen)
+ for i in range(5):
+ logging.debug("Waiting for ip address to be added {} of 5".format(i))
+ time.sleep(1)
+ self._if_manager.rescan_devices()
+ if addr in self.ips:
+ break
+ else:
+ raise DeviceError("Failed to configure ip address {}".format(str(ip)))
def ip_add(self, addr):
"""add an ip address or a list of ip addresses
--
2.31.1
2 years, 4 months
[PATCH 0/2] Tunnel recipes
by Jan Tluka
This patchset adds two new classes to ENRT recipe package, the
BaseTunnelRecipe and GreTunnelRecipe.
The BaseTunnelRecipe extends the BaremetalEnrtRecipe class and defines a
common API for recipes that want to configure any type of tunnels.
The API consists of three methods.
The configure_underlying_network() involves configuration of the network
stack below the tunnel and returning back the endpoints that should be
connected by the tunnel.
The create_tunnel() then takes care of configuration of the tunnel between
the endpoints.
The get_packet_assert_config() method supports the
PacketAssertTestAndEvaluate class by defining the packet capture filter
and grep patterns to test the functionality of a tunnel.
The second patch in the series adds an implementation of a recipe for
the GRE tunnel.
Both patches also extends the LNST documentation.
Jan Tluka (2):
Recipes.ENRT: add BaseTunnelRecipe
Recipes.ENRT: add GreTunnelRecipe
docs/source/base_enrt_tunnel_class.rst | 6 +
docs/source/enrt_recipes.rst | 1 +
docs/source/specific_scenarios.rst | 1 +
lnst/Recipes/ENRT/BaseTunnelRecipe.py | 157 ++++++++++++++++++++++++
lnst/Recipes/ENRT/GreTunnelRecipe.py | 160 +++++++++++++++++++++++++
lnst/Recipes/ENRT/__init__.py | 2 +
6 files changed, 327 insertions(+)
create mode 100644 docs/source/base_enrt_tunnel_class.rst
create mode 100644 lnst/Recipes/ENRT/BaseTunnelRecipe.py
create mode 100644 lnst/Recipes/ENRT/GreTunnelRecipe.py
--
2.26.3
2 years, 5 months
[PATCH v2 0/5] Fix namespaces
by Jan Tluka
This patchset fixes namespace in LNST that is currently broken. The
fundamental problem was in use of libc calls with improper parameter
types.
Thanks to Ondrej for the additional patch in [1].
v2:
Include additional fix for the test module synchronization in network namespaces.
[1] https://github.com/LNST-project/lnst/issues/202#issuecomment-820398056
Jan Tluka (5):
Controller.NetNamespace: rename _nsname to _name
lnst.NetTestSlave: fix namespace creation/deletion
Controller.Host: pass NetNamespace to add_netns()
Controller.Machine: update add_namespace and del_namespace arguments
Controller.Machine: fix test module synchronization for network
namespaces
lnst/Controller/Host.py | 2 +-
lnst/Controller/Machine.py | 26 ++++++++++--------
lnst/Controller/NetNamespace.py | 2 +-
lnst/Slave/NetTestSlave.py | 47 +++++++++++++++++++++++++--------
4 files changed, 53 insertions(+), 24 deletions(-)
--
2.26.3
2 years, 5 months
[PATCH] Devices: add GreDevice
by Jan Tluka
This patch adds new device GreDevice to setup a gre tunnel device.
Signed-off-by: Jan Tluka <jtluka(a)redhat.com>
---
lnst/Devices/GreDevice.py | 44 +++++++++++++++++++++++++++++++++++++++
lnst/Devices/__init__.py | 2 ++
2 files changed, 46 insertions(+)
create mode 100644 lnst/Devices/GreDevice.py
diff --git a/lnst/Devices/GreDevice.py b/lnst/Devices/GreDevice.py
new file mode 100644
index 00000000..d1affbc3
--- /dev/null
+++ b/lnst/Devices/GreDevice.py
@@ -0,0 +1,44 @@
+"""
+Defines the GreDevice class.
+
+Copyright 2021 Red Hat, Inc.
+Licensed under the GNU General Public License, version 2 as
+published by the Free Software Foundation; see COPYING for details.
+"""
+
+__author__ = """
+jtluka(a)redhat.com (Jan Tluka)
+"""
+
+from lnst.Common.IpAddress import ipaddress
+from lnst.Devices.SoftDevice import SoftDevice
+
+
+class GreDevice(SoftDevice):
+ _name_template = "t_gre"
+ _link_type = "gre"
+ _mandatory_opts = ["remote"]
+
+ @property
+ def local(self):
+ try:
+ return ipaddress(self._get_linkinfo_data_attr("IFLA_GRE_LOCAL"))
+ except:
+ return None
+
+ @local.setter
+ def local(self, val):
+ self._set_linkinfo_data_attr("IFLA_GRE_LOCAL", str(ipaddress(val)))
+ self._nl_link_sync("set")
+
+ @property
+ def remote(self):
+ try:
+ return ipaddress(self._get_linkinfo_data_attr("IFLA_GRE_REMOTE"))
+ except:
+ return None
+
+ @remote.setter
+ def remote(self, val):
+ self._set_linkinfo_data_attr("IFLA_GRE_REMOTE", str(ipaddress(val)))
+ self._nl_link_sync("set")
diff --git a/lnst/Devices/__init__.py b/lnst/Devices/__init__.py
index b38d1b60..ddc462e8 100644
--- a/lnst/Devices/__init__.py
+++ b/lnst/Devices/__init__.py
@@ -7,6 +7,7 @@ from lnst.Devices.TeamDevice import TeamDevice
from lnst.Devices.MacvlanDevice import MacvlanDevice
from lnst.Devices.VlanDevice import VlanDevice
from lnst.Devices.VxlanDevice import VxlanDevice
+from lnst.Devices.GreDevice import GreDevice
from lnst.Devices.VtiDevice import VtiDevice, Vti6Device
from lnst.Devices.VethDevice import VethDevice, PairedVethDevice
from lnst.Devices.VethPair import VethPair
@@ -20,6 +21,7 @@ device_classes = [
("MacvlanDevice", MacvlanDevice),
("VlanDevice", VlanDevice),
("VxlanDevice", VxlanDevice),
+ ("GreDevice", GreDevice),
("VethDevice", VethDevice),
("PairedVethDevice", PairedVethDevice),
("VtiDevice", VtiDevice),
--
2.26.3
2 years, 5 months