about summary refs log tree commit diff
path: root/src/libnm-core-impl
diff options
context:
space:
mode:
Diffstat (limited to 'src/libnm-core-impl')
-rw-r--r--src/libnm-core-impl/gen-metadata-nm-settings-libnm-core.xml.in4
-rw-r--r--src/libnm-core-impl/nm-connection.c39
-rw-r--r--src/libnm-core-impl/nm-setting-bond-port.c50
-rw-r--r--src/libnm-core-impl/nm-setting-infiniband.c54
-rw-r--r--src/libnm-core-impl/tests/test-general.c62
5 files changed, 180 insertions, 29 deletions
diff --git a/src/libnm-core-impl/gen-metadata-nm-settings-libnm-core.xml.in b/src/libnm-core-impl/gen-metadata-nm-settings-libnm-core.xml.in
index a40b8695..4a6e70fe 100644
--- a/src/libnm-core-impl/gen-metadata-nm-settings-libnm-core.xml.in
+++ b/src/libnm-core-impl/gen-metadata-nm-settings-libnm-core.xml.in
@@ -582,6 +582,10 @@
     <setting name="bond-port"
              gtype="NMSettingBondPort"
              >
+        <property name="prio"
+                  dbus-type="i"
+                  gprop-type="gint"
+                  />
         <property name="queue-id"
                   dbus-type="u"
                   gprop-type="guint"
diff --git a/src/libnm-core-impl/nm-connection.c b/src/libnm-core-impl/nm-connection.c
index 3a9eda0e..b017a6e5 100644
--- a/src/libnm-core-impl/nm-connection.c
+++ b/src/libnm-core-impl/nm-connection.c
@@ -1332,18 +1332,41 @@ _normalize_ip_config(NMConnection *self, GHashTable *parameters)
 }
 
 static gboolean
-_normalize_infiniband_mtu(NMConnection *self)
+_normalize_infiniband(NMConnection *self)
 {
     NMSettingInfiniband *s_infini = nm_connection_get_setting_infiniband(self);
+    gboolean             changed  = FALSE;
+    const char          *interface_name;
+    int                  p_key;
 
-    if (!s_infini || nm_setting_infiniband_get_mtu(s_infini) <= NM_INFINIBAND_MAX_MTU
-        || !NM_IN_STRSET(nm_setting_infiniband_get_transport_mode(s_infini),
-                         "datagram",
-                         "connected"))
+    if (!s_infini)
         return FALSE;
 
-    g_object_set(s_infini, NM_SETTING_INFINIBAND_MTU, (guint) NM_INFINIBAND_MAX_MTU, NULL);
-    return TRUE;
+    if (nm_setting_infiniband_get_mtu(s_infini) > NM_INFINIBAND_MAX_MTU) {
+        if (NM_IN_STRSET(nm_setting_infiniband_get_transport_mode(s_infini),
+                         "datagram",
+                         "connected")) {
+            g_object_set(s_infini, NM_SETTING_INFINIBAND_MTU, (guint) NM_INFINIBAND_MAX_MTU, NULL);
+            changed = TRUE;
+        }
+    }
+
+    if ((p_key = nm_setting_infiniband_get_p_key(s_infini)) != -1
+        && (interface_name = nm_connection_get_interface_name(self))) {
+        const char *virtual_iface_name;
+
+        virtual_iface_name = nm_setting_infiniband_get_virtual_interface_name(s_infini);
+
+        if (!nm_streq0(interface_name, virtual_iface_name)) {
+            g_object_set(nm_connection_get_setting_connection(self),
+                         NM_SETTING_CONNECTION_INTERFACE_NAME,
+                         virtual_iface_name,
+                         NULL);
+            changed = TRUE;
+        }
+    }
+
+    return changed;
 }
 
 static gboolean
@@ -1986,7 +2009,7 @@ _connection_normalize(NMConnection *connection,
     was_modified |= _normalize_invalid_slave_port_settings(connection);
     was_modified |= _normalize_ip_config(connection, parameters);
     was_modified |= _normalize_ethernet_link_neg(connection);
-    was_modified |= _normalize_infiniband_mtu(connection);
+    was_modified |= _normalize_infiniband(connection);
     was_modified |= _normalize_bond_mode(connection);
     was_modified |= _normalize_bond_options(connection);
     was_modified |= _normalize_wireless_mac_address_randomization(connection);
diff --git a/src/libnm-core-impl/nm-setting-bond-port.c b/src/libnm-core-impl/nm-setting-bond-port.c
index 7ea82a76..16512a6a 100644
--- a/src/libnm-core-impl/nm-setting-bond-port.c
+++ b/src/libnm-core-impl/nm-setting-bond-port.c
@@ -22,9 +22,10 @@
 
 /*****************************************************************************/
 
-NM_GOBJECT_PROPERTIES_DEFINE(NMSettingBondPort, PROP_QUEUE_ID, );
+NM_GOBJECT_PROPERTIES_DEFINE(NMSettingBondPort, PROP_QUEUE_ID, PROP_PRIO, );
 
 typedef struct {
+    gint32  prio;
     guint32 queue_id;
 } NMSettingBondPortPrivate;
 
@@ -65,6 +66,22 @@ nm_setting_bond_port_get_queue_id(NMSettingBondPort *setting)
     return NM_SETTING_BOND_PORT_GET_PRIVATE(setting)->queue_id;
 }
 
+/**
+ * nm_setting_bond_port_get_prio:
+ * @setting: the #NMSettingBondPort
+ *
+ * Returns: the #NMSettingBondPort:prio property of the setting
+ *
+ * Since: 1.44, 1.42.8
+ **/
+gint32
+nm_setting_bond_port_get_prio(NMSettingBondPort *setting)
+{
+    g_return_val_if_fail(NM_IS_SETTING_BOND_PORT(setting), 0);
+
+    return NM_SETTING_BOND_PORT_GET_PRIVATE(setting)->prio;
+}
+
 /*****************************************************************************/
 
 static gboolean
@@ -148,7 +165,7 @@ nm_setting_bond_port_class_init(NMSettingBondPortClass *klass)
      **/
     /* ---ifcfg-rh---
      * property: queue-id
-     * variable: BONDING_OPTS: queue-id=
+     * variable: BOND_PORT_QUEUE_ID(+)
      * values: 0 - 65535
      * default: 0
      * description: Queue ID.
@@ -165,6 +182,35 @@ nm_setting_bond_port_class_init(NMSettingBondPortClass *klass)
                                               NMSettingBondPort,
                                               _priv.queue_id);
 
+    /**
+     * NMSettingBondPort:prio:
+     *
+     * The port priority for bond active port re-selection during failover. A
+     * higher number means a higher priority in selection. The primary port has
+     * the highest priority. This option is only compatible with active-backup,
+     * balance-tlb and balance-alb modes.
+     *
+     * Since: 1.44, 1.42.8
+     **/
+    /* ---ifcfg-rh---
+     * property: prio
+     * variable: BOND_PORT_PRIO(+)
+     * values: -2147483648 - 2147483647
+     * default: 0
+     * description: Port priority.
+     * ---end---
+     */
+    _nm_setting_property_define_direct_int32(properties_override,
+                                             obj_properties,
+                                             NM_SETTING_BOND_PORT_PRIO,
+                                             PROP_PRIO,
+                                             G_MININT32,
+                                             G_MAXINT32,
+                                             NM_BOND_PORT_PRIO_DEF,
+                                             NM_SETTING_PARAM_INFERRABLE,
+                                             NMSettingBondPort,
+                                             _priv.prio);
+
     g_object_class_install_properties(object_class, _PROPERTY_ENUMS_LAST, obj_properties);
 
     _nm_setting_class_commit(setting_class,
diff --git a/src/libnm-core-impl/nm-setting-infiniband.c b/src/libnm-core-impl/nm-setting-infiniband.c
index 410f1f06..a3bda692 100644
--- a/src/libnm-core-impl/nm-setting-infiniband.c
+++ b/src/libnm-core-impl/nm-setting-infiniband.c
@@ -10,6 +10,7 @@
 #include <stdlib.h>
 #include <linux/if_infiniband.h>
 
+#include "libnm-platform/nmp-base.h"
 #include "nm-utils.h"
 #include "nm-utils-private.h"
 #include "nm-setting-private.h"
@@ -144,6 +145,17 @@ nm_setting_infiniband_get_parent(NMSettingInfiniband *setting)
     return NM_SETTING_INFINIBAND_GET_PRIVATE(setting)->parent;
 }
 
+char *
+nm_setting_infiniband_create_virtual_interface_name(const char *parent, int p_key)
+{
+    char *s;
+
+    s = g_strdup_printf("%s.%04x", parent, (guint) p_key);
+    if (strlen(s) >= NMP_IFNAMSIZ)
+        s[NMP_IFNAMSIZ - 1] = '\0';
+    return s;
+}
+
 /**
  * nm_setting_infiniband_get_virtual_interface_name:
  * @setting: the #NMSettingInfiniband
@@ -172,7 +184,8 @@ nm_setting_infiniband_get_virtual_interface_name(NMSettingInfiniband *setting)
         priv->virtual_iface_name_p_key         = priv->p_key;
         priv->virtual_iface_name_parent_length = len;
         g_free(priv->virtual_iface_name);
-        priv->virtual_iface_name = g_strdup_printf("%s.%04x", priv->parent, priv->p_key);
+        priv->virtual_iface_name =
+            nm_setting_infiniband_create_virtual_interface_name(priv->parent, priv->p_key);
     }
 
     return priv->virtual_iface_name;
@@ -181,8 +194,8 @@ nm_setting_infiniband_get_virtual_interface_name(NMSettingInfiniband *setting)
 static gboolean
 verify(NMSetting *setting, NMConnection *connection, GError **error)
 {
-    NMSettingConnection        *s_con = NULL;
-    NMSettingInfinibandPrivate *priv  = NM_SETTING_INFINIBAND_GET_PRIVATE(setting);
+    NMSettingConnection        *s_con;
+    NMSettingInfinibandPrivate *priv = NM_SETTING_INFINIBAND_GET_PRIVATE(setting);
 
     if (priv->mac_address && !nm_utils_hwaddr_valid(priv->mac_address, INFINIBAND_ALEN)) {
         g_set_error_literal(error,
@@ -251,8 +264,10 @@ verify(NMSetting *setting, NMConnection *connection, GError **error)
         }
     }
 
-    if (connection)
-        s_con = nm_connection_get_setting_connection(connection);
+    /* *** errors above here should be always fatal, below NORMALIZABLE_ERROR *** */
+
+    s_con = connection ? nm_connection_get_setting_connection(connection) : NULL;
+
     if (s_con) {
         const char *interface_name = nm_setting_connection_get_interface_name(s_con);
 
@@ -287,13 +302,11 @@ verify(NMSetting *setting, NMConnection *connection, GError **error)
                                "%s.%s: ",
                                NM_SETTING_CONNECTION_SETTING_NAME,
                                NM_SETTING_CONNECTION_INTERFACE_NAME);
-                return FALSE;
+                return NM_SETTING_VERIFY_NORMALIZABLE_ERROR;
             }
         }
     }
 
-    /* *** errors above here should be always fatal, below NORMALIZABLE_ERROR *** */
-
     if (priv->mtu > NM_INFINIBAND_MAX_MTU) {
         /* Traditionally, MTU for "datagram" mode was limited to 2044
          * and for "connected" mode it was 65520.
@@ -448,18 +461,31 @@ nm_setting_infiniband_class_init(NMSettingInfinibandClass *klass)
     /**
      * NMSettingInfiniband:p-key:
      *
-     * The InfiniBand P_Key to use for this device. A value of -1 means to use
-     * the default P_Key (aka "the P_Key at index 0"). Otherwise, it is a 16-bit
-     * unsigned integer, whose high bit is set if it is a "full membership"
-     * P_Key.
+     * The InfiniBand p-key to use for this device. A value of -1 means to use
+     * the default p-key (aka "the p-key at index 0"). Otherwise, it is a
+     * 16-bit unsigned integer, whose high bit 0x8000 is set if it is a "full
+     * membership" p-key. The values 0 and 0x8000 are not allowed.
+     *
+     * With the p-key set, the interface name is always "$parent.$p_key".
+     * Setting "connection.interface-name" to another name is not supported.
+     *
+     * Note that kernel will internally always set the full membership bit,
+     * although the interface name does not reflect that. Usually the user
+     * would want to configure a full membership p-key with 0x8000 flag set.
      **/
     /* ---ifcfg-rh---
      * property: p-key
-     * variable: PKEY_ID (and PKEY=yes)
+     * variable: PKEY_ID or PKEY_ID_NM(*) (requires PKEY=yes)
      * default: PKEY=no
      * description: InfiniBand P_Key. The value can be a hex number prefixed with "0x"
      *   or a decimal number.
-     *   When PKEY_ID is specified, PHYSDEV and DEVICE also must be specified.
+     *   When PKEY_ID is specified, PHYSDEV must be specified.
+     *   Note that ifcfg-rh format will always automatically set the full membership
+     *   flag 0x8000 for the PKEY_ID variable. To express IDs without the full membership
+     *   flag, use PKEY_ID_NM. Note that kernel internally treats the interface as
+     *   having the full membership flag set, this mainly affects the interface name.
+     *   For the ifcfg file to be supported by initscripts' ifup-ib, the DEVICE=
+     *   must always be set. NetworkManager does not require that.
      * example: PKEY=yes PKEY_ID=2 PHYSDEV=mlx4_ib0 DEVICE=mlx4_ib0.8002
      * ---end---
      */
diff --git a/src/libnm-core-impl/tests/test-general.c b/src/libnm-core-impl/tests/test-general.c
index 8a98265a..87f7b042 100644
--- a/src/libnm-core-impl/tests/test-general.c
+++ b/src/libnm-core-impl/tests/test-general.c
@@ -6156,16 +6156,17 @@ test_connection_normalize_slave_type_2(void)
 }
 
 static void
-test_connection_normalize_infiniband_mtu(void)
+test_connection_normalize_infiniband(void)
 {
     gs_unref_object NMConnection *con = NULL;
     NMSettingInfiniband          *s_infini;
+    NMSettingConnection          *s_con;
     guint                         mtu_regular = nmtst_rand_select(2044, 2045, 65520);
 
-    con = nmtst_create_minimal_connection("test_connection_normalize_infiniband_mtu",
+    con = nmtst_create_minimal_connection("test_connection_normalize_infiniband",
                                           NULL,
                                           NM_SETTING_INFINIBAND_SETTING_NAME,
-                                          NULL);
+                                          &s_con);
 
     s_infini = nm_connection_get_setting_infiniband(con);
     g_object_set(s_infini, NM_SETTING_INFINIBAND_TRANSPORT_MODE, "connected", NULL);
@@ -6213,6 +6214,57 @@ test_connection_normalize_infiniband_mtu(void)
                                                          NM_CONNECTION_ERROR_INVALID_PROPERTY);
     nmtst_connection_normalize(con);
     g_assert_cmpint(65520, ==, nm_setting_infiniband_get_mtu(s_infini));
+
+    g_object_set(s_infini,
+                 NM_SETTING_INFINIBAND_PARENT,
+                 "foo",
+                 NM_SETTING_INFINIBAND_P_KEY,
+                 0x005c,
+                 NULL);
+    nmtst_assert_connection_verifies_without_normalization(con);
+
+    g_object_set(s_con, NM_SETTING_CONNECTION_INTERFACE_NAME, "foo.005c", NULL);
+    nmtst_assert_connection_verifies_without_normalization(con);
+
+    g_object_set(s_con, NM_SETTING_CONNECTION_INTERFACE_NAME, "foo", NULL);
+    nmtst_assert_connection_verifies_after_normalization(con,
+                                                         NM_CONNECTION_ERROR,
+                                                         NM_CONNECTION_ERROR_INVALID_PROPERTY);
+
+    nmtst_connection_normalize(con);
+    g_assert_cmpstr(nm_connection_get_interface_name(con), ==, "foo.005c");
+
+    g_object_set(s_infini,
+                 NM_SETTING_INFINIBAND_PARENT,
+                 "x234567890123",
+                 NM_SETTING_INFINIBAND_P_KEY,
+                 0x005c,
+                 NULL);
+    nmtst_assert_connection_verifies_after_normalization(con,
+                                                         NM_CONNECTION_ERROR,
+                                                         NM_CONNECTION_ERROR_INVALID_PROPERTY);
+
+    nmtst_connection_normalize(con);
+    g_assert_cmpstr(nm_connection_get_interface_name(con), ==, "x234567890123.0");
+
+#define iface_name(parent, p_key, expected)                                                        \
+    G_STMT_START                                                                                   \
+    {                                                                                              \
+        gs_free char *_s = nm_setting_infiniband_create_virtual_interface_name((parent), (p_key)); \
+                                                                                                   \
+        g_assert(nm_utils_ifname_valid_kernel(_s, NULL));                                          \
+        g_assert_cmpstr(_s, ==, (expected));                                                       \
+    }                                                                                              \
+    G_STMT_END
+
+    iface_name("foo", 15, "foo.000f");
+    iface_name("x23456789012345", 15, "x23456789012345");
+    iface_name("x2345678901234", 15, "x2345678901234.");
+    iface_name("x234567890123", 15, "x234567890123.0");
+    iface_name("x23456789012", 15, "x23456789012.00");
+    iface_name("x2345678901", 15, "x2345678901.000");
+    iface_name("x234567890", 15, "x234567890.000f");
+    iface_name("x23456789", 15, "x23456789.000f");
 }
 
 static void
@@ -11511,8 +11563,8 @@ main(int argc, char **argv)
                     test_connection_normalize_slave_type_1);
     g_test_add_func("/core/general/test_connection_normalize_slave_type_2",
                     test_connection_normalize_slave_type_2);
-    g_test_add_func("/core/general/test_connection_normalize_infiniband_mtu",
-                    test_connection_normalize_infiniband_mtu);
+    g_test_add_func("/core/general/test_connection_normalize_infiniband",
+                    test_connection_normalize_infiniband);
     g_test_add_func("/core/general/test_connection_normalize_gateway_never_default",
                     test_connection_normalize_gateway_never_default);
     g_test_add_func("/core/general/test_connection_normalize_may_fail",