[PATCH] ifcfg-rh: ifcfg-rh: global GATEWAY controls never-default, not address gateways (rh #896198)



A GATEWAY in /etc/sysconfig/network is used by network-functions to determine
the default route, while previousl the ifcfg-rh plugin mistaken used it to
set the gateway of every IP address of every connection, due to a misunderstanding
of how the shellscript substitions were done long ago.

If any connection has an IPv4 address with a gateway that matches the global
GATEWAY value, that connection can get the default route.  If a connection has
IP addresses that have no gateway or has no addresses with gateways that match
the global GATEWAY, that connection cannot get the default route and is thus
marked never-default.
---
 src/settings/plugins/ifcfg-rh/reader.c             |  46 ++++--
 .../ifcfg-test-wired-global-gateway                |   1 +
 .../ifcfg-test-wired-global-gateway-never-default  |  14 ++
 .../plugins/ifcfg-rh/tests/test-ifcfg-rh.c         | 172 +++++++++++----------
 4 files changed, 137 insertions(+), 96 deletions(-)
 create mode 100644 
src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wired-global-gateway-never-default

diff --git a/src/settings/plugins/ifcfg-rh/reader.c b/src/settings/plugins/ifcfg-rh/reader.c
index 961bd93..15f712f 100644
--- a/src/settings/plugins/ifcfg-rh/reader.c
+++ b/src/settings/plugins/ifcfg-rh/reader.c
@@ -582,7 +582,6 @@ read_full_ip4_address (shvarFile *ifcfg,
        char *ip_tag, *prefix_tag, *netmask_tag, *gw_tag;
        guint32 tmp;
        gboolean success = FALSE;
-       shvarFile *network_ifcfg;
        char *value;
 
        g_return_val_if_fail (which >= -1, NULL);
@@ -618,19 +617,6 @@ read_full_ip4_address (shvarFile *ifcfg,
                goto error;
        if (tmp)
                nm_ip4_address_set_gateway (addr, tmp);
-       else {
-               gboolean read_success;
-
-               /* If no gateway in the ifcfg, try /etc/sysconfig/network instead */
-               network_ifcfg = svNewFile (network_file);
-               if (network_ifcfg) {
-                       read_success = read_ip4_address (network_ifcfg, "GATEWAY", &tmp, error);
-                       svCloseFile (network_ifcfg);
-                       if (!read_success)
-                               goto error;
-                       nm_ip4_address_set_gateway (addr, tmp);
-               }
-       }
 
        /* Prefix */
        value = svGetValue (ifcfg, prefix_tag, FALSE);
@@ -1200,7 +1186,8 @@ make_ip4_setting (shvarFile *ifcfg,
        char *value = NULL;
        char *route_path = NULL;
        char *method = NM_SETTING_IP4_CONFIG_METHOD_MANUAL;
-       gint32 i;
+       char *gateway_str = NULL;
+       gint32 i, gateway = 0;
        shvarFile *network_ifcfg;
        shvarFile *route_ifcfg;
        gboolean never_default = FALSE, tmp_success;
@@ -1222,6 +1209,12 @@ make_ip4_setting (shvarFile *ifcfg,
                /* Get the connection ifcfg device name and the global gateway device */
                value = svGetValue (ifcfg, "DEVICE", FALSE);
                gatewaydev = svGetValue (network_ifcfg, "GATEWAYDEV", FALSE);
+               gateway_str = svGetValue (network_ifcfg, "GATEWAY", FALSE);
+               if (gateway_str) {
+                       if (inet_pton (AF_INET, gateway_str, (void *) &gateway) <= 0)
+                               gateway = 0;
+                       g_free (gateway_str);
+               }
 
                /* If there was a global gateway device specified, then only connections
                 * for that device can be the default connection.
@@ -1366,6 +1359,29 @@ make_ip4_setting (shvarFile *ifcfg,
                g_free (value);
        }
 
+       /* /etc/sysconfig/network GATEWAY handling; any static connection that does
+        * not contain an address with a gateway of GATEWAY gets set never-default.
+        * Obviously not done for automatic connections because we don't know their
+        * addresses at this time, plus this is better done with DEFROUTE=no
+        * in the ifcfg anyway.
+        */
+       if (gateway) {
+               gboolean found = FALSE;
+               guint numaddr = nm_setting_ip4_config_get_num_addresses (s_ip4);
+
+               for (i = 0; i < numaddr; i++) {
+                       NMIP4Address *a = nm_setting_ip4_config_get_address (s_ip4, i);
+
+                       if (nm_ip4_address_get_gateway (a) == gateway) {
+                               found = TRUE;
+                               break;
+                       }
+               }
+
+               if (numaddr > 0)
+                       g_object_set (s_ip4, NM_SETTING_IP4_CONFIG_NEVER_DEFAULT, !found, NULL);
+       }
+
        /* DNS servers
         * Pick up just IPv4 addresses (IPv6 addresses are taken by make_ip6_setting())
         */
diff --git a/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wired-global-gateway 
b/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wired-global-gateway
index 98d9105..7d4874a 100644
--- a/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wired-global-gateway
+++ b/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wired-global-gateway
@@ -10,5 +10,6 @@ NM_CONTROLLED=yes
 DNS1=4.2.2.1
 DNS2=4.2.2.2
 IPADDR=192.168.1.5
+GATEWAY=192.168.1.2
 PREFIX=24
 
diff --git 
a/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wired-global-gateway-never-default 
b/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wired-global-gateway-never-default
new file mode 100644
index 0000000..98d9105
--- /dev/null
+++ b/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wired-global-gateway-never-default
@@ -0,0 +1,14 @@
+# Intel Corporation 82540EP Gigabit Ethernet Controller (Mobile)
+TYPE=Ethernet
+DEVICE=eth0
+HWADDR=00:11:22:33:44:ee
+BOOTPROTO=none
+ONBOOT=yes
+USERCTL=yes
+IPV6INIT=no
+NM_CONTROLLED=yes
+DNS1=4.2.2.1
+DNS2=4.2.2.2
+IPADDR=192.168.1.5
+PREFIX=24
+
diff --git a/src/settings/plugins/ifcfg-rh/tests/test-ifcfg-rh.c 
b/src/settings/plugins/ifcfg-rh/tests/test-ifcfg-rh.c
index 6c3bd05..1f5d500 100644
--- a/src/settings/plugins/ifcfg-rh/tests/test-ifcfg-rh.c
+++ b/src/settings/plugins/ifcfg-rh/tests/test-ifcfg-rh.c
@@ -1184,11 +1184,8 @@ test_read_wired_dhcp (void)
        g_object_unref (connection);
 }
 
-#define TEST_IFCFG_WIRED_GLOBAL_GATEWAY TEST_IFCFG_DIR"/network-scripts/ifcfg-test-wired-global-gateway"
-#define TEST_NETWORK_WIRED_GLOBAL_GATEWAY TEST_IFCFG_DIR"/network-scripts/network-test-wired-global-gateway"
-
 static void
-test_read_wired_global_gateway (void)
+test_read_wired_global_gateway_default (void)
 {
        NMConnection *connection;
        NMSettingConnection *s_con;
@@ -1200,15 +1197,15 @@ test_read_wired_global_gateway (void)
        char *route6file = NULL;
        gboolean ignore_error = FALSE;
        GError *error = NULL;
-       const char *tmp;
        const char *expected_id = "System test-wired-global-gateway";
        struct in_addr addr;
        const char *expected_address1 = "192.168.1.5";
        const char *expected_address1_gw = "192.168.1.2";
        NMIP4Address *ip4_addr;
+       gboolean success;
 
-       connection = connection_from_file (TEST_IFCFG_WIRED_GLOBAL_GATEWAY,
-                                          TEST_NETWORK_WIRED_GLOBAL_GATEWAY,
+       connection = connection_from_file (TEST_IFCFG_DIR "/network-scripts/ifcfg-test-wired-global-gateway",
+                                          TEST_IFCFG_DIR 
"/network-scripts/network-test-wired-global-gateway",
                                           TYPE_ETHERNET,
                                           NULL,
                                           &unmanaged,
@@ -1217,95 +1214,107 @@ test_read_wired_global_gateway (void)
                                           &route6file,
                                           &error,
                                           &ignore_error);
-       ASSERT (connection != NULL,
-               "wired-global-gateway-read", "failed to read %s: %s", TEST_IFCFG_WIRED_GLOBAL_GATEWAY, 
error->message);
+       g_assert (connection);
+       success = nm_connection_verify (connection, &error);
+       g_assert_no_error (error);
+       g_assert (success);
+       g_assert_cmpstr (unmanaged, ==, NULL);
 
-       ASSERT (nm_connection_verify (connection, &error),
-               "wired-global-gateway-verify", "failed to verify %s: %s", TEST_IFCFG_WIRED_GLOBAL_GATEWAY, 
error->message);
+       /* ===== CONNECTION SETTING ===== */
+       s_con = nm_connection_get_setting_connection (connection);
+       g_assert (s_con);
+       g_assert_cmpstr (nm_setting_connection_get_id (s_con), ==, expected_id);
 
-       ASSERT (unmanaged == NULL,
-               "wired-global-gateway-verify", "failed to verify %s: unexpected unmanaged value", 
TEST_IFCFG_WIRED_GLOBAL_GATEWAY);
+       /* ===== WIRED SETTING ===== */
+       s_wired = nm_connection_get_setting_wired (connection);
+       g_assert (s_wired);
 
-       /* ===== CONNECTION SETTING ===== */
+       /* ===== IPv4 SETTING ===== */
+       s_ip4 = nm_connection_get_setting_ip4_config (connection);
+       g_assert (s_ip4);
+       g_assert_cmpstr (nm_setting_ip4_config_get_method (s_ip4), ==, NM_SETTING_IP4_CONFIG_METHOD_MANUAL);
 
-       s_con = nm_connection_get_setting_connection (connection);
-       ASSERT (s_con != NULL,
-               "wired-global-gateway-verify-connection", "failed to verify %s: missing %s setting",
-               TEST_IFCFG_WIRED_GLOBAL_GATEWAY,
-               NM_SETTING_CONNECTION_SETTING_NAME);
+       /* Address #1 */
+       ip4_addr = nm_setting_ip4_config_get_address (s_ip4, 0);
+       g_assert (ip4_addr);
+       g_assert_cmpint (nm_ip4_address_get_prefix (ip4_addr), ==, 24);
 
-       /* ID */
-       tmp = nm_setting_connection_get_id (s_con);
-       ASSERT (tmp != NULL,
-               "wired-global-gateway-verify-connection", "failed to verify %s: missing %s / %s key",
-               TEST_IFCFG_WIRED_GLOBAL_GATEWAY,
-               NM_SETTING_CONNECTION_SETTING_NAME,
-               NM_SETTING_CONNECTION_ID);
-       ASSERT (strcmp (tmp, expected_id) == 0,
-               "wired-global-gateway-verify-connection", "failed to verify %s: unexpected %s / %s key value",
-               TEST_IFCFG_WIRED_GLOBAL_GATEWAY,
-               NM_SETTING_CONNECTION_SETTING_NAME,
-               NM_SETTING_CONNECTION_ID);
+       g_assert_cmpint (inet_pton (AF_INET, expected_address1, &addr), >, 0);
+       g_assert_cmpint (nm_ip4_address_get_address (ip4_addr), ==, addr.s_addr);
 
-       /* ===== WIRED SETTING ===== */
+       g_assert_cmpint (inet_pton (AF_INET, expected_address1_gw, &addr), >, 0);
+       g_assert_cmpint (nm_ip4_address_get_gateway (ip4_addr), ==, addr.s_addr);
+
+       /* Due to the GATEWAY match from /etc/sysconfig/network, always default */
+       g_assert (nm_setting_ip4_config_get_never_default (s_ip4) == FALSE);
+
+       g_free (unmanaged);
+       g_free (keyfile);
+       g_free (routefile);
+       g_free (route6file);
+       g_object_unref (connection);
+}
 
+static void
+test_read_wired_global_gateway_never_default (void)
+{
+       NMConnection *connection;
+       NMSettingConnection *s_con;
+       NMSettingWired *s_wired;
+       NMSettingIP4Config *s_ip4;
+       char *unmanaged = NULL;
+       char *keyfile = NULL;
+       char *routefile = NULL;
+       char *route6file = NULL;
+       gboolean ignore_error = FALSE;
+       GError *error = NULL;
+       const char *expected_id = "System test-wired-global-gateway-never-default";
+       struct in_addr addr;
+       const char *expected_address1 = "192.168.1.5";
+       NMIP4Address *ip4_addr;
+       gboolean success;
+
+       connection = connection_from_file (TEST_IFCFG_DIR 
"/network-scripts/ifcfg-test-wired-global-gateway-never-default",
+                                          TEST_IFCFG_DIR 
"/network-scripts/network-test-wired-global-gateway",
+                                          TYPE_ETHERNET,
+                                          NULL,
+                                          &unmanaged,
+                                          &keyfile,
+                                          &routefile,
+                                          &route6file,
+                                          &error,
+                                          &ignore_error);
+       g_assert (connection);
+       success = nm_connection_verify (connection, &error);
+       g_assert_no_error (error);
+       g_assert (success);
+       g_assert_cmpstr (unmanaged, ==, NULL);
+
+       /* ===== CONNECTION SETTING ===== */
+       s_con = nm_connection_get_setting_connection (connection);
+       g_assert (s_con);
+       g_assert_cmpstr (nm_setting_connection_get_id (s_con), ==, expected_id);
+
+       /* ===== WIRED SETTING ===== */
        s_wired = nm_connection_get_setting_wired (connection);
-       ASSERT (s_wired != NULL,
-               "wired-global-gateway-verify-wired", "failed to verify %s: missing %s setting",
-               TEST_IFCFG_WIRED_GLOBAL_GATEWAY,
-               NM_SETTING_WIRED_SETTING_NAME);
+       g_assert (s_wired);
 
        /* ===== IPv4 SETTING ===== */
-
        s_ip4 = nm_connection_get_setting_ip4_config (connection);
-       ASSERT (s_ip4 != NULL,
-               "wired-global-gateway-verify-ip4", "failed to verify %s: missing %s setting",
-               TEST_IFCFG_WIRED_GLOBAL_GATEWAY,
-               NM_SETTING_IP4_CONFIG_SETTING_NAME);
-
-       /* Method */
-       tmp = nm_setting_ip4_config_get_method (s_ip4);
-       ASSERT (strcmp (tmp, NM_SETTING_IP4_CONFIG_METHOD_MANUAL) == 0,
-               "wired-global-gateway-verify-ip4", "failed to verify %s: unexpected %s / %s key value",
-               TEST_IFCFG_WIRED_GLOBAL_GATEWAY,
-               NM_SETTING_IP4_CONFIG_SETTING_NAME,
-               NM_SETTING_IP4_CONFIG_METHOD);
+       g_assert (s_ip4);
+       g_assert_cmpstr (nm_setting_ip4_config_get_method (s_ip4), ==, NM_SETTING_IP4_CONFIG_METHOD_MANUAL);
 
        /* Address #1 */
        ip4_addr = nm_setting_ip4_config_get_address (s_ip4, 0);
-       ASSERT (ip4_addr,
-               "wired-global-gateway-verify-ip4", "failed to verify %s: missing IP4 address #1",
-               TEST_IFCFG_WIRED_GLOBAL_GATEWAY,
-               NM_SETTING_IP4_CONFIG_SETTING_NAME,
-               NM_SETTING_IP4_CONFIG_ADDRESSES);
+       g_assert (ip4_addr);
+       g_assert_cmpint (nm_ip4_address_get_prefix (ip4_addr), ==, 24);
 
-       ASSERT (nm_ip4_address_get_prefix (ip4_addr) == 24,
-               "wired-global-gateway-verify-ip4", "failed to verify %s: unexpected IP4 address #1 prefix",
-               TEST_IFCFG_WIRED_GLOBAL_GATEWAY,
-               NM_SETTING_IP4_CONFIG_SETTING_NAME,
-               NM_SETTING_IP4_CONFIG_ADDRESSES);
+       g_assert_cmpint (inet_pton (AF_INET, expected_address1, &addr), >, 0);
+       g_assert_cmpint (nm_ip4_address_get_address (ip4_addr), ==, addr.s_addr);
+       g_assert_cmpint (nm_ip4_address_get_gateway (ip4_addr), ==, 0);
 
-       ASSERT (inet_pton (AF_INET, expected_address1, &addr) > 0,
-               "wired-global-gateway-verify-ip4", "failed to verify %s: couldn't convert IP address #1",
-               TEST_IFCFG_WIRED_GLOBAL_GATEWAY,
-               NM_SETTING_IP4_CONFIG_SETTING_NAME,
-               NM_SETTING_IP4_CONFIG_DNS);
-       ASSERT (nm_ip4_address_get_address (ip4_addr) == addr.s_addr,
-               "wired-global-gateway-verify-ip4", "failed to verify %s: unexpected IP4 address #1",
-               TEST_IFCFG_WIRED_GLOBAL_GATEWAY,
-               NM_SETTING_IP4_CONFIG_SETTING_NAME,
-               NM_SETTING_IP4_CONFIG_ADDRESSES);
-
-       ASSERT (inet_pton (AF_INET, expected_address1_gw, &addr) > 0,
-               "wired-global-gateway-verify-ip4", "failed to verify %s: couldn't convert IP address #1 
gateway",
-               TEST_IFCFG_WIRED_GLOBAL_GATEWAY,
-               NM_SETTING_IP4_CONFIG_SETTING_NAME,
-               NM_SETTING_IP4_CONFIG_ADDRESSES);
-       ASSERT (nm_ip4_address_get_gateway (ip4_addr) == addr.s_addr,
-               "wired-global-gateway-verify-ip4", "failed to verify %s: unexpected IP4 address #1 gateway",
-               TEST_IFCFG_WIRED_GLOBAL_GATEWAY,
-               NM_SETTING_IP4_CONFIG_SETTING_NAME,
-               NM_SETTING_IP4_CONFIG_ADDRESSES);
+       /* Due to the GATEWAY mis-match from /etc/sysconfig/network, never default */
+       g_assert (nm_setting_ip4_config_get_never_default (s_ip4));
 
        g_free (unmanaged);
        g_free (keyfile);
@@ -13002,7 +13011,8 @@ int main (int argc, char **argv)
        test_read_wired_static_no_prefix (16);
        test_read_wired_static_no_prefix (24);
        test_read_wired_dhcp ();
-       test_read_wired_global_gateway ();
+       test_read_wired_global_gateway_default ();
+       test_read_wired_global_gateway_never_default ();
        test_read_wired_never_default ();
        test_read_wired_defroute_no ();
        test_read_wired_defroute_no_gatewaydev_yes ();
-- 
1.8.1.4




[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]