2008-12-09 Dan Williams <dcbw@redhat.com>
authorDan Williams <dcbw@redhat.com>
Tue, 9 Dec 2008 20:01:49 +0000 (20:01 +0000)
committerDan Williams <dcbw@redhat.com>
Tue, 9 Dec 2008 20:01:49 +0000 (20:01 +0000)
* libnm-util/libnm-util.ver
  libnm-util/nm-setting-ip4-config.c
  libnm-util/nm-setting-ip4-config.h
- Add 'never-default' property, which when true indicates that a
connection should never be the default connection

* src/nm-ip4-config.c
  src/nm-ip4-config.h
- (nm_ip4_config_get_never_default, nm_ip4_config_set_never_default):
Add never-default helpers

* src/NetworkManagerUtils.c
- (nm_utils_merge_ip4_config): update never-default when merging the
IP4 setting to the IP4 config

* src/NetworkManagerSystem.c
- (nm_system_apply_ip4_config): if the connection is never-default,
don't add routes without a gateway

* src/NetworkManagerPolicy.c
- (get_best_device): don't let never-default connections be the best
- (update_routing_and_dns): handle never-default for VPN connections

* system-settings/plugins/ifcfg-rh/reader.c
- (make_ip4_setting): handle never-default by checking GATEWAYDEV

git-svn-id: http://svn-archive.gnome.org/svn/NetworkManager/branches/NETWORKMANAGER_0_7@4378 4912f4e0-d625-0410-9fb7-b9a5a253dbdc

ChangeLog
libnm-util/libnm-util.ver
libnm-util/nm-setting-ip4-config.c
libnm-util/nm-setting-ip4-config.h
src/NetworkManagerPolicy.c
src/NetworkManagerSystem.c
src/NetworkManagerUtils.c
src/nm-ip4-config.c
src/nm-ip4-config.h
system-settings/plugins/ifcfg-rh/reader.c

index 57869c0..1d4644a 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,31 @@
+2008-12-09  Dan Williams  <dcbw@redhat.com>
+
+       * libnm-util/libnm-util.ver
+         libnm-util/nm-setting-ip4-config.c
+         libnm-util/nm-setting-ip4-config.h
+               - Add 'never-default' property, which when true indicates that a
+                       connection should never be the default connection
+
+       * src/nm-ip4-config.c
+         src/nm-ip4-config.h
+               - (nm_ip4_config_get_never_default, nm_ip4_config_set_never_default):
+                       Add never-default helpers
+
+       * src/NetworkManagerUtils.c
+               - (nm_utils_merge_ip4_config): update never-default when merging the
+                       IP4 setting to the IP4 config
+
+       * src/NetworkManagerSystem.c
+               - (nm_system_apply_ip4_config): if the connection is never-default,
+                       don't add routes without a gateway
+
+       * src/NetworkManagerPolicy.c
+               - (get_best_device): don't let never-default connections be the best
+               - (update_routing_and_dns): handle never-default for VPN connections
+
+       * system-settings/plugins/ifcfg-rh/reader.c
+               - (make_ip4_setting): handle never-default by checking GATEWAYDEV
+
 2008-12-08  Dan Williams  <dcbw@redhat.com>
 
        * src/vpn-manager/nm-vpn-connection.c
index 483da9e..bc86e08 100644 (file)
@@ -132,6 +132,7 @@ global:
        nm_setting_ip4_config_get_ignore_auto_dns;
        nm_setting_ip4_config_get_dhcp_client_id;
        nm_setting_ip4_config_get_dhcp_hostname;
+       nm_setting_ip4_config_get_never_default;
        nm_setting_need_secrets;
        nm_setting_ppp_error_get_type;
        nm_setting_ppp_error_quark;
index da38771..7157886 100644 (file)
@@ -81,6 +81,7 @@ typedef struct {
        gboolean ignore_auto_dns;
        char *dhcp_client_id;
        char *dhcp_hostname;
+       gboolean never_default;
 } NMSettingIP4ConfigPrivate;
 
 enum {
@@ -94,6 +95,7 @@ enum {
        PROP_IGNORE_AUTO_DNS,
        PROP_DHCP_CLIENT_ID,
        PROP_DHCP_HOSTNAME,
+       PROP_NEVER_DEFAULT,
 
        LAST_PROP
 };
@@ -418,6 +420,14 @@ nm_setting_ip4_config_get_dhcp_hostname (NMSettingIP4Config *setting)
        return NM_SETTING_IP4_CONFIG_GET_PRIVATE (setting)->dhcp_hostname;
 }
 
+gboolean
+nm_setting_ip4_config_get_never_default (NMSettingIP4Config *setting)
+{
+       g_return_val_if_fail (NM_IS_SETTING_IP4_CONFIG (setting), FALSE);
+
+       return NM_SETTING_IP4_CONFIG_GET_PRIVATE (setting)->never_default;
+}
+
 static gboolean
 verify (NMSetting *setting, GSList *all_settings, GError **error)
 {
@@ -611,6 +621,9 @@ set_property (GObject *object, guint prop_id,
                g_free (priv->dhcp_hostname);
                priv->dhcp_hostname = g_value_dup_string (value);
                break;
+       case PROP_NEVER_DEFAULT:
+               priv->never_default = g_value_get_boolean (value);
+               break;
        default:
                G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
                break;
@@ -652,6 +665,9 @@ get_property (GObject *object, guint prop_id,
        case PROP_DHCP_HOSTNAME:
                g_value_set_string (value, nm_setting_ip4_config_get_dhcp_hostname (setting));
                break;
+       case PROP_NEVER_DEFAULT:
+               g_value_set_boolean (value, priv->never_default);
+               break;
        default:
                G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
                break;
@@ -744,6 +760,14 @@ nm_setting_ip4_config_class_init (NMSettingIP4ConfigClass *setting_class)
                                                   "DHCP Hostname",
                                                   NULL,
                                                   G_PARAM_READWRITE | NM_SETTING_PARAM_SERIALIZE));
+
+       g_object_class_install_property
+               (object_class, PROP_NEVER_DEFAULT,
+                g_param_spec_boolean (NM_SETTING_IP4_CONFIG_NEVER_DEFAULT,
+                                                  "Never default",
+                                                  "Never make this connection the default IPv4 connection",
+                                                  FALSE,
+                                                  G_PARAM_READWRITE | NM_SETTING_PARAM_SERIALIZE));
 }
 
 
index f02afb6..91a1c69 100644 (file)
@@ -62,6 +62,7 @@ GQuark nm_setting_ip4_config_error_quark (void);
 #define NM_SETTING_IP4_CONFIG_IGNORE_AUTO_DNS    "ignore-auto-dns"
 #define NM_SETTING_IP4_CONFIG_DHCP_CLIENT_ID     "dhcp-client-id"
 #define NM_SETTING_IP4_CONFIG_DHCP_HOSTNAME      "dhcp-hostname"
+#define NM_SETTING_IP4_CONFIG_NEVER_DEFAULT      "never-default"
 
 #define NM_SETTING_IP4_CONFIG_METHOD_AUTO       "auto"
 #define NM_SETTING_IP4_CONFIG_METHOD_LINK_LOCAL "link-local"
@@ -158,6 +159,8 @@ gboolean      nm_setting_ip4_config_get_ignore_auto_dns    (NMSettingIP4Config *
 const char *  nm_setting_ip4_config_get_dhcp_client_id     (NMSettingIP4Config *setting);
 const char *  nm_setting_ip4_config_get_dhcp_hostname      (NMSettingIP4Config *setting);
 
+gboolean      nm_setting_ip4_config_get_never_default      (NMSettingIP4Config *setting);
+
 G_END_DECLS
 
 #endif /* NM_SETTING_IP4_CONFIG_H */
index de85d4c..2de01f8 100644 (file)
@@ -238,6 +238,10 @@ get_best_device (NMManager *manager, NMActRequest **out_req)
                if (!can_default && !NM_IS_HSO_GSM_DEVICE (dev))
                        continue;
 
+               /* 'never-default' devices can't ever be the default */
+               if (s_ip4 && nm_setting_ip4_config_get_never_default (s_ip4))
+                       continue;
+
                prio = nm_device_get_priority (dev);
                if (prio > 0 && prio < best_prio) {
                        best = dev;
@@ -487,7 +491,6 @@ update_routing_and_dns (NMPolicy *policy, gboolean force_update)
        NMIP4Config *ip4_config = NULL;
        NMIP4Address *addr;
        const char *ip_iface = NULL;
-       NMVPNConnection *vpn = NULL;
        NMConnection *connection = NULL;
        NMSettingConnection *s_con = NULL;
        const char *connection_id;
@@ -502,55 +505,43 @@ update_routing_and_dns (NMPolicy *policy, gboolean force_update)
        vpns = nm_vpn_manager_get_active_connections (policy->vpn_manager);
        for (iter = vpns; iter; iter = g_slist_next (iter)) {
                NMVPNConnection *candidate = NM_VPN_CONNECTION (iter->data);
-
-               if (!vpn && (nm_vpn_connection_get_vpn_state (candidate) == NM_VPN_CONNECTION_STATE_ACTIVATED))
-                       vpn = g_object_ref (candidate);
-               g_object_unref (candidate);
-       }
-       g_slist_free (vpns);
-
-       /* VPNs are the default route only if they don't have custom non-host (ie, /32)
-        * routes.  Custom non-host routes are redundant when the VPN is the default
-        * route because any traffic meant for the custom route would be routed over
-        * the VPN anyway.
-        */
-       if (vpn) {
-               gboolean have_non_host_routes = FALSE;
-               int i;
-
-               ip4_config = nm_vpn_connection_get_ip4_config (vpn);
-               for (i = 0; i < nm_ip4_config_get_num_routes (ip4_config); i++) {
-                       NMIP4Route *route = nm_ip4_config_get_route (ip4_config, i);
-
-                       if (nm_ip4_route_get_prefix (route) != 32) {
-                               have_non_host_routes = TRUE;
-                               break;
-                       }
-               }
-
-
-               if (!have_non_host_routes) {
+               NMConnection *vpn_connection;
+               NMSettingIP4Config *s_ip4;
+               gboolean can_default = TRUE;
+               NMVPNConnectionState vpn_state;
+
+               /* If it's marked 'never-default', don't make it default */
+               vpn_connection = nm_vpn_connection_get_connection (candidate);
+               g_assert (vpn_connection);
+               s_ip4 = (NMSettingIP4Config *) nm_connection_get_setting (vpn_connection, NM_TYPE_SETTING_IP4_CONFIG);
+               if (s_ip4 && nm_setting_ip4_config_get_never_default (s_ip4))
+                       can_default = FALSE;
+
+               vpn_state = nm_vpn_connection_get_vpn_state (candidate);
+               if (can_default && (vpn_state == NM_VPN_CONNECTION_STATE_ACTIVATED)) {
                        NMIP4Config *parent_ip4;
                        NMDevice *parent;
 
-                       ip_iface = nm_vpn_connection_get_ip_iface (vpn);
-                       connection = nm_vpn_connection_get_connection (vpn);
+                       ip_iface = nm_vpn_connection_get_ip_iface (candidate);
+                       connection = nm_vpn_connection_get_connection (candidate);
+                       ip4_config = nm_vpn_connection_get_ip4_config (candidate);
                        addr = nm_ip4_config_get_address (ip4_config, 0);
 
-                       parent = nm_vpn_connection_get_parent_device (vpn);
+                       parent = nm_vpn_connection_get_parent_device (candidate);
                        parent_ip4 = nm_device_get_ip4_config (parent);
 
                        nm_system_replace_default_ip4_route_vpn (ip_iface,
                                                                 nm_ip4_address_get_gateway (addr),
-                                                                nm_vpn_connection_get_ip4_internal_gateway (vpn),
+                                                                nm_vpn_connection_get_ip4_internal_gateway (candidate),
                                                                 nm_ip4_config_get_mss (ip4_config),
                                                                 nm_device_get_ip_iface (parent),
                                                                 nm_ip4_config_get_mss (parent_ip4));
 
                        dns_type = NM_NAMED_IP_CONFIG_TYPE_VPN;
                }
-               g_object_unref (vpn);
+               g_object_unref (candidate);
        }
+       g_slist_free (vpns);
 
        /* The best device gets the default route if a VPN connection didn't */
        if (!ip_iface || !ip4_config) {
index 3b41917..533098c 100644 (file)
@@ -358,6 +358,13 @@ nm_system_apply_ip4_config (const char *iface,
                                                     nm_ip4_route_get_prefix (route)))
                                continue;
 
+                       /* Don't add the route if it doesn't have a gateway and the connection
+                        * is never supposed to be the default connection.
+                        */
+                       if (   nm_ip4_config_get_never_default (config)
+                           && nm_ip4_route_get_dest (route) == 0)
+                               continue;
+
                        tmp = nm_system_device_set_ip4_route (iface,
                                                              nm_ip4_route_get_dest (route),
                                                              nm_ip4_route_get_prefix (route),
index 28fe165..874d4bd 100644 (file)
@@ -359,6 +359,9 @@ nm_utils_merge_ip4_config (NMIP4Config *ip4_config, NMSettingIP4Config *setting)
                if (j == num)
                        nm_ip4_config_add_route (ip4_config, setting_route);
        }
+
+       if (nm_setting_ip4_config_get_never_default (setting))
+               nm_ip4_config_set_never_default (ip4_config, TRUE);
 }
 
 static void
index 39f3190..4caeb15 100644 (file)
@@ -55,6 +55,8 @@ typedef struct {
        GPtrArray *searches;
 
        GSList *routes;
+
+       gboolean never_default;
 } NMIP4ConfigPrivate;
 
 
@@ -364,6 +366,22 @@ void nm_ip4_config_set_mss (NMIP4Config *config, guint32 mss)
        NM_IP4_CONFIG_GET_PRIVATE (config)->mss = mss;
 }
 
+gboolean
+nm_ip4_config_get_never_default (NMIP4Config *config)
+{
+       g_return_val_if_fail (NM_IS_IP4_CONFIG (config), FALSE);
+
+       return NM_IP4_CONFIG_GET_PRIVATE (config)->never_default;
+}
+
+void
+nm_ip4_config_set_never_default (NMIP4Config *config, gboolean never_default)
+{
+       g_return_if_fail (NM_IS_IP4_CONFIG (config));
+
+       NM_IP4_CONFIG_GET_PRIVATE (config)->never_default = never_default;
+}
+
 /* libnl convenience/conversion functions */
 
 static int ip4_addr_to_rtnl_local (guint32 ip4_address, struct rtnl_addr *addr)
index 05e3812..2e9de50 100644 (file)
@@ -89,6 +89,9 @@ void          nm_ip4_config_set_mtu             (NMIP4Config *config, guint32 mt
 guint32       nm_ip4_config_get_mss             (NMIP4Config *config);
 void          nm_ip4_config_set_mss             (NMIP4Config *config, guint32 mss);
 
+gboolean      nm_ip4_config_get_never_default   (NMIP4Config *config);
+void          nm_ip4_config_set_never_default   (NMIP4Config *config, gboolean never_default);
+
 /* Flags for nm_ip4_config_to_rtnl_addr() */
 #define NM_RTNL_ADDR_NONE              0x0000
 #define NM_RTNL_ADDR_ADDR              0x0001
index 392d83d..931e091 100644 (file)
@@ -180,6 +180,27 @@ make_ip4_setting (shvarFile *ifcfg, GError **error)
        NMIP4Address *addr = NULL;
        char *method = NM_SETTING_IP4_CONFIG_METHOD_MANUAL;
        guint32 netmask = 0, tmp = 0;
+       shvarFile *network_ifcfg;
+       gboolean never_default = FALSE;
+
+       network_ifcfg = svNewFile (SYSCONFDIR "/sysconfig/network");
+       if (network_ifcfg) {
+               char *gatewaydev;
+
+               /* Get the connection ifcfg device name and the global gateway device */
+               value = svGetValue (ifcfg, "DEVICE");
+               gatewaydev = svGetValue (network_ifcfg, "GATEWAYDEV");
+
+               /* If there was a global gateway device specified, then only connections
+                * for that device can be the default connection.
+                */
+               if (gatewaydev && value && strcmp (value, gatewaydev))
+                       never_default = TRUE;
+
+               g_free (gatewaydev);
+               g_free (value);
+               svCloseFile (network_ifcfg);
+       }
 
        value = svGetValue (ifcfg, "BOOTPROTO");
        if (value && (!g_ascii_strcasecmp (value, "bootp") || !g_ascii_strcasecmp (value, "dhcp")))
@@ -188,7 +209,10 @@ make_ip4_setting (shvarFile *ifcfg, GError **error)
        if (value && !g_ascii_strcasecmp (value, "autoip")) {
                g_free (value);
                s_ip4 = (NMSettingIP4Config *) nm_setting_ip4_config_new ();
-               g_object_set (s_ip4, NM_SETTING_IP4_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_LINK_LOCAL, NULL);
+               g_object_set (s_ip4,
+                             NM_SETTING_IP4_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_LINK_LOCAL,
+                             NM_SETTING_IP4_CONFIG_NEVER_DEFAULT, never_default,
+                             NULL);
                return NM_SETTING (s_ip4);
        }
 
@@ -210,12 +234,10 @@ make_ip4_setting (shvarFile *ifcfg, GError **error)
 
                /* If no gateway in the ifcfg, try /etc/sysconfig/network instead */
                if (!nm_ip4_address_get_gateway (addr)) {
-                       shvarFile *network;
-
-                       network = svNewFile ("/etc/sysconfig/network");
-                       if (network) {
-                               get_one_ip4_addr (network, "GATEWAY", &tmp, error);
-                               svCloseFile (network);
+                       network_ifcfg = svNewFile (SYSCONFDIR "/sysconfig/network");
+                       if (network_ifcfg) {
+                               get_one_ip4_addr (network_ifcfg, "GATEWAY", &tmp, error);
+                               svCloseFile (network_ifcfg);
                                if (*error)
                                        goto error;
                                nm_ip4_address_set_gateway (addr, tmp);
@@ -261,6 +283,7 @@ make_ip4_setting (shvarFile *ifcfg, GError **error)
        g_object_set (s_ip4,
                      NM_SETTING_IP4_CONFIG_METHOD, method,
                      NM_SETTING_IP4_CONFIG_IGNORE_AUTO_DNS, !svTrueValue (ifcfg, "PEERDNS", 1),
+                     NM_SETTING_IP4_CONFIG_NEVER_DEFAULT, never_default,
                      NULL);
 
        /* DHCP hostname for 'send host-name' option */