diff --git a/ChangeLog b/ChangeLog index 57869c09af..1d4644a667 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,31 @@ +2008-12-09 Dan Williams + + * 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 * src/vpn-manager/nm-vpn-connection.c diff --git a/libnm-util/libnm-util.ver b/libnm-util/libnm-util.ver index 483da9e439..bc86e0818f 100644 --- a/libnm-util/libnm-util.ver +++ b/libnm-util/libnm-util.ver @@ -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; diff --git a/libnm-util/nm-setting-ip4-config.c b/libnm-util/nm-setting-ip4-config.c index da38771825..7157886a31 100644 --- a/libnm-util/nm-setting-ip4-config.c +++ b/libnm-util/nm-setting-ip4-config.c @@ -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)); } diff --git a/libnm-util/nm-setting-ip4-config.h b/libnm-util/nm-setting-ip4-config.h index f02afb6d1c..91a1c69b4b 100644 --- a/libnm-util/nm-setting-ip4-config.h +++ b/libnm-util/nm-setting-ip4-config.h @@ -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 */ diff --git a/src/NetworkManagerPolicy.c b/src/NetworkManagerPolicy.c index de85d4caff..2de01f897d 100644 --- a/src/NetworkManagerPolicy.c +++ b/src/NetworkManagerPolicy.c @@ -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); + NMConnection *vpn_connection; + NMSettingIP4Config *s_ip4; + gboolean can_default = TRUE; + NMVPNConnectionState vpn_state; - 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); + /* 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; - /* 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) { + 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) { diff --git a/src/NetworkManagerSystem.c b/src/NetworkManagerSystem.c index 3b4191772e..533098cd9c 100644 --- a/src/NetworkManagerSystem.c +++ b/src/NetworkManagerSystem.c @@ -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), diff --git a/src/NetworkManagerUtils.c b/src/NetworkManagerUtils.c index 28fe165fbd..874d4bd54c 100644 --- a/src/NetworkManagerUtils.c +++ b/src/NetworkManagerUtils.c @@ -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 diff --git a/src/nm-ip4-config.c b/src/nm-ip4-config.c index 39f3190618..4caeb1508d 100644 --- a/src/nm-ip4-config.c +++ b/src/nm-ip4-config.c @@ -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) diff --git a/src/nm-ip4-config.h b/src/nm-ip4-config.h index 05e381245b..2e9de5095b 100644 --- a/src/nm-ip4-config.h +++ b/src/nm-ip4-config.h @@ -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 diff --git a/system-settings/plugins/ifcfg-rh/reader.c b/system-settings/plugins/ifcfg-rh/reader.c index 392d83de9d..931e0911aa 100644 --- a/system-settings/plugins/ifcfg-rh/reader.c +++ b/system-settings/plugins/ifcfg-rh/reader.c @@ -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 */