From cb3e23ac5dedb04129f140b75a11477ef5fe5ca3 Mon Sep 17 00:00:00 2001 From: Wen Liang Date: Sun, 8 May 2022 20:17:38 -0400 Subject: [PATCH] infiniband: Reject the interface name for the ipoib connection If the `p_key` is specified, then ipoib (IP over Infiniband) connection will be created. In this case, the interface name must be unset. NM only allows the user to set the interface name to a fixed value based on the interface name of the parent and the value of the `p_key`, for example, if the interface name of the parent is `ib0` and the `p_key` is `0x000a`, then the `interface_name` for the ipoib connection must be `ib0.000a` or unset. But this kind of validation in NM is pointless because it is not useful at all to have the interface name for the ipoib connection, NM should has also rejected setting the interface name for the ipoib connection initially. Signed-off-by: Wen Liang --- .../network_lsr/argument_validator.py | 17 +- tests/unit/test_network_connections.py | 148 ++++++++++++++++++ 2 files changed, 163 insertions(+), 2 deletions(-) diff --git a/module_utils/network_lsr/argument_validator.py b/module_utils/network_lsr/argument_validator.py index 8157902..b1299cd 100644 --- a/module_utils/network_lsr/argument_validator.py +++ b/module_utils/network_lsr/argument_validator.py @@ -2097,6 +2097,14 @@ class ArgValidator_DictConnection(ArgValidatorDict): "a infiniband device with 'infiniband.p_key' " "property also needs 'mac' or 'parent' property", ) + if "interface_name" in result: + raise ValidationError( + name + ".interface_name", + "the 'interface_name' must be unset for the ipoib " + "connection, instead it is {0}".format( + result["interface_name"] + ), + ) else: if "infiniband" in result: raise ValidationError( @@ -2126,8 +2134,13 @@ class ArgValidator_DictConnection(ArgValidatorDict): "invalid 'interface_name' '%s'" % (result["interface_name"]), ) else: - if not result.get("mac") and ( - not result.get("match") or not result["match"].get("path") + if ( + not result.get("mac") + and (not result.get("match") or not result["match"].get("path")) + and not ( + result["type"] == "infiniband" + and result["infiniband"]["p_key"] != -1 + ) ): if not Util.ifname_valid(result["name"]): raise ValidationError( diff --git a/tests/unit/test_network_connections.py b/tests/unit/test_network_connections.py index bd253a4..d3d6368 100644 --- a/tests/unit/test_network_connections.py +++ b/tests/unit/test_network_connections.py @@ -2347,6 +2347,154 @@ class TestValidator(Python26CompatTestCase): ], ) + def test_infiniband3(self): + self.maxDiff = None + self.do_connections_validate( + [ + { + "actions": ["present"], + "autoconnect": True, + "check_iface_exists": True, + "ethtool": ETHTOOL_DEFAULTS, + "ignore_errors": None, + "infiniband": {"p_key": -1, "transport_mode": "datagram"}, + "interface_name": "ib0", + "ip": { + "address": [], + "auto_gateway": None, + "auto6": True, + "dhcp4": True, + "dhcp4_send_hostname": None, + "dns": [], + "dns_options": [], + "dns_search": [], + "gateway4": None, + "gateway6": None, + "ipv6_disabled": False, + "route": [], + "route_append_only": False, + "route_metric4": None, + "route_metric6": None, + "routing_rule": [], + "rule_append_only": False, + }, + "mac": None, + "match": {}, + "controller": None, + "ieee802_1x": None, + "wireless": None, + "mtu": None, + "name": "infiniband.3", + "parent": None, + "persistent_state": "present", + "port_type": None, + "state": None, + "type": "infiniband", + "zone": None, + }, + { + "actions": ["present", "up"], + "autoconnect": True, + "check_iface_exists": True, + "ethtool": ETHTOOL_DEFAULTS, + "force_state_change": None, + "ignore_errors": None, + "infiniband": {"p_key": 10, "transport_mode": "datagram"}, + "interface_name": None, + "ip": { + "address": [], + "auto_gateway": None, + "auto6": True, + "dhcp4": True, + "dhcp4_send_hostname": None, + "dns": [], + "dns_options": [], + "dns_search": [], + "gateway4": None, + "gateway6": None, + "ipv6_disabled": False, + "route": [], + "route_append_only": False, + "route_metric4": None, + "route_metric6": None, + "routing_rule": [], + "rule_append_only": False, + }, + "mac": "11:22:33:44:55:66:77:88:99:00:" + "11:22:33:44:55:66:77:88:99:00", + "match": {}, + "controller": None, + "ieee802_1x": None, + "wireless": None, + "mtu": None, + "name": "infiniband.3-10", + "parent": "infiniband.3", + "persistent_state": "present", + "port_type": None, + "state": "up", + "type": "infiniband", + "wait": None, + "zone": None, + }, + ], + [ + { + "name": "infiniband.3", + "interface_name": "ib0", + "type": "infiniband", + }, + { + "name": "infiniband.3-10", + "state": "up", + "type": "infiniband", + "parent": "infiniband.3", + "mac": "11:22:33:44:55:66:77:88:99:00:" + "11:22:33:44:55:66:77:88:99:00", + "infiniband_p_key": 10, + }, + ], + initscripts_dict_expected=[ + { + "ifcfg": { + "BOOTPROTO": "dhcp", + "CONNECTED_MODE": "no", + "DEVICE": "ib0", + "IPV6INIT": "yes", + "IPV6_AUTOCONF": "yes", + "NM_CONTROLLED": "no", + "ONBOOT": "yes", + "TYPE": "InfiniBand", + }, + "keys": None, + "route": None, + "route6": None, + "rule": None, + "rule6": None, + }, + { + "ifcfg": { + "BOOTPROTO": "dhcp", + "CONNECTED_MODE": "no", + "HWADDR": "11:22:33:44:55:66:77:88:99:00:" + "11:22:33:44:55:66:77:88:99:00", + "IPV6INIT": "yes", + "IPV6_AUTOCONF": "yes", + "NM_CONTROLLED": "no", + "ONBOOT": "yes", + "PHYSDEV": "ib0", + "PKEY": "yes", + "PKEY_ID": "10", + "TYPE": "InfiniBand", + }, + "keys": None, + "route": None, + "route6": None, + "rule": None, + "rule6": None, + }, + ], + ) + def test_route_metric_prefix(self): self.maxDiff = None self.do_connections_validate(