core: set route metrics earlier

Instead of creating most routes with metric 0 and then fixing them
just before applying them, create the routes with the correct metric
in the first place (so that NMIP4Config and NMIP6Config don't have to
try to guess whether "metric 0" means "unset" or "actually metric 0").
This commit is contained in:
Dan Winship
2014-06-04 11:14:55 -04:00
parent d3a51b6e4a
commit 722c90343b
10 changed files with 82 additions and 30 deletions

View File

@@ -2483,6 +2483,7 @@ aipd_get_ip4_config (NMDevice *self, guint32 lla)
route.network = htonl (0xE0000000L);
route.plen = 4;
route.source = NM_PLATFORM_SOURCE_IP4LL;
route.metric = nm_device_get_priority (self);
nm_ip4_config_add_route (config, &route);
return config;
@@ -2885,6 +2886,7 @@ dhcp4_start (NMDevice *self,
nm_device_get_ip_iface (self),
tmp,
nm_connection_get_uuid (connection),
nm_device_get_priority (self),
s_ip4,
priv->dhcp_timeout,
priv->dhcp_anycast_address);
@@ -3325,6 +3327,7 @@ dhcp6_start (NMDevice *self,
nm_device_get_ip_iface (self),
tmp,
nm_connection_get_uuid (connection),
nm_device_get_priority (self),
nm_connection_get_setting_ip6_config (connection),
priv->dhcp_timeout,
priv->dhcp_anycast_address,
@@ -3623,6 +3626,7 @@ rdisc_config_changed (NMRDisc *rdisc, NMRDiscConfigMap changed, NMDevice *device
route.plen = discovered_route->plen;
route.gateway = discovered_route->gateway;
route.source = NM_PLATFORM_SOURCE_RDISC;
route.metric = nm_device_get_priority (device);
nm_ip6_config_add_route (priv->ac_ip6_config, &route);
}
@@ -5279,7 +5283,7 @@ nm_device_set_ip4_config (NMDevice *self,
/* Always commit to nm-platform to update lifetimes */
if (commit && new_config) {
success = nm_ip4_config_commit (new_config, ip_ifindex, nm_device_get_priority (self));
success = nm_ip4_config_commit (new_config, ip_ifindex);
if (!success)
reason_local = NM_DEVICE_STATE_REASON_CONFIG_FAILED;
}
@@ -5387,7 +5391,7 @@ nm_device_set_ip6_config (NMDevice *self,
/* Always commit to nm-platform to update lifetimes */
if (commit && new_config) {
success = nm_ip6_config_commit (new_config, ip_ifindex, nm_device_get_priority (self));
success = nm_ip6_config_commit (new_config, ip_ifindex);
if (!success)
reason_local = NM_DEVICE_STATE_REASON_CONFIG_FAILED;
}

View File

@@ -39,6 +39,7 @@ typedef struct {
GByteArray * hwaddr;
gboolean ipv6;
char * uuid;
guint priority;
guint32 timeout;
GByteArray * duid;
@@ -72,6 +73,7 @@ enum {
PROP_HWADDR,
PROP_IPV6,
PROP_UUID,
PROP_PRIORITY,
PROP_TIMEOUT,
LAST_PROP
};
@@ -795,10 +797,12 @@ nm_dhcp_client_foreach_option (NMDHCPClient *self,
/********************************************/
static gboolean
ip4_process_dhcpcd_rfc3442_routes (const char *str,
ip4_process_dhcpcd_rfc3442_routes (NMDHCPClient *self,
const char *str,
NMIP4Config *ip4_config,
guint32 *gwaddr)
{
NMDHCPClientPrivate *priv = NM_DHCP_CLIENT_GET_PRIVATE (self);
char **routes, **r;
gboolean have_routes = FALSE;
@@ -847,6 +851,7 @@ ip4_process_dhcpcd_rfc3442_routes (const char *str,
route.plen = rt_cidr;
route.gateway = rt_route;
route.source = NM_PLATFORM_SOURCE_DHCP;
route.metric = priv->priority;
nm_ip4_config_add_route (ip4_config, &route);
}
}
@@ -918,10 +923,12 @@ error:
}
static gboolean
ip4_process_dhclient_rfc3442_routes (const char *str,
ip4_process_dhclient_rfc3442_routes (NMDHCPClient *self,
const char *str,
NMIP4Config *ip4_config,
guint32 *gwaddr)
{
NMDHCPClientPrivate *priv = NM_DHCP_CLIENT_GET_PRIVATE (self);
char **octets, **o;
gboolean have_routes = FALSE;
NMPlatformIP4Route route;
@@ -950,6 +957,7 @@ ip4_process_dhclient_rfc3442_routes (const char *str,
/* normal route */
route.source = NM_PLATFORM_SOURCE_DHCP;
route.metric = priv->priority;
nm_ip4_config_add_route (ip4_config, &route);
nm_log_info (LOGD_DHCP4, " classless static route %s/%d gw %s",
@@ -964,7 +972,8 @@ out:
}
static gboolean
ip4_process_classless_routes (GHashTable *options,
ip4_process_classless_routes (NMDHCPClient *self,
GHashTable *options,
NMIP4Config *ip4_config,
guint32 *gwaddr)
{
@@ -1020,15 +1029,16 @@ ip4_process_classless_routes (GHashTable *options,
if (strchr (str, '/')) {
/* dhcpcd format */
return ip4_process_dhcpcd_rfc3442_routes (str, ip4_config, gwaddr);
return ip4_process_dhcpcd_rfc3442_routes (self, str, ip4_config, gwaddr);
}
return ip4_process_dhclient_rfc3442_routes (str, ip4_config, gwaddr);
return ip4_process_dhclient_rfc3442_routes (self, str, ip4_config, gwaddr);
}
static void
process_classful_routes (GHashTable *options, NMIP4Config *ip4_config)
process_classful_routes (NMDHCPClient *self, GHashTable *options, NMIP4Config *ip4_config)
{
NMDHCPClientPrivate *priv = NM_DHCP_CLIENT_GET_PRIVATE (self);
const char *str;
char **searches, **s;
@@ -1070,6 +1080,7 @@ process_classful_routes (GHashTable *options, NMIP4Config *ip4_config)
}
route.gateway = rt_route;
route.source = NM_PLATFORM_SOURCE_DHCP;
route.metric = priv->priority;
nm_ip4_config_add_route (ip4_config, &route);
nm_log_info (LOGD_DHCP, " static route %s",
@@ -1166,8 +1177,8 @@ ip4_options_to_config (NMDHCPClient *self)
/* Routes: if the server returns classless static routes, we MUST ignore
* the 'static_routes' option.
*/
if (!ip4_process_classless_routes (priv->options, ip4_config, &gwaddr))
process_classful_routes (priv->options, ip4_config);
if (!ip4_process_classless_routes (self, priv->options, ip4_config, &gwaddr))
process_classful_routes (self, priv->options, ip4_config);
if (gwaddr) {
nm_log_info (LOGD_DHCP4, " gateway %s", nm_utils_inet4_ntop (gwaddr, NULL));
@@ -1220,6 +1231,8 @@ ip4_options_to_config (NMDHCPClient *self)
route.plen = 32;
/* this will be a device route if gwaddr is 0 */
route.gateway = gwaddr;
route.source = NM_PLATFORM_SOURCE_DHCP;
route.metric = priv->priority;
nm_ip4_config_add_route (ip4_config, &route);
nm_log_dbg (LOGD_IP, "adding route for server identifier: %s",
nm_platform_ip4_route_to_string (&route));
@@ -1499,6 +1512,9 @@ get_property (GObject *object, guint prop_id,
case PROP_UUID:
g_value_set_string (value, priv->uuid);
break;
case PROP_PRIORITY:
g_value_set_uint (value, priv->priority);
break;
case PROP_TIMEOUT:
g_value_set_uint (value, priv->timeout);
break;
@@ -1531,6 +1547,10 @@ set_property (GObject *object, guint prop_id,
/* construct-only */
priv->uuid = g_value_dup_string (value);
break;
case PROP_PRIORITY:
/* construct-only */
priv->priority = g_value_get_uint (value);
break;
case PROP_TIMEOUT:
priv->timeout = g_value_get_uint (value);
break;
@@ -1622,6 +1642,14 @@ nm_dhcp_client_class_init (NMDHCPClientClass *client_class)
NULL,
G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
g_object_class_install_property
(object_class, PROP_PRIORITY,
g_param_spec_uint (NM_DHCP_CLIENT_PRIORITY,
"priority",
"Priority",
0, G_MAXUINT, 0,
G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
g_object_class_install_property
(object_class, PROP_TIMEOUT,
g_param_spec_uint (NM_DHCP_CLIENT_TIMEOUT,

View File

@@ -38,6 +38,7 @@
#define NM_DHCP_CLIENT_HWADDR "hwaddr"
#define NM_DHCP_CLIENT_IPV6 "ipv6"
#define NM_DHCP_CLIENT_UUID "uuid"
#define NM_DHCP_CLIENT_PRIORITY "priority"
#define NM_DHCP_CLIENT_TIMEOUT "timeout"
#define NM_DHCP_CLIENT_SIGNAL_TIMEOUT "timeout"

View File

@@ -384,6 +384,7 @@ client_start (NMDHCPManager *self,
const char *iface,
const GByteArray *hwaddr,
const char *uuid,
guint priority,
gboolean ipv6,
const char *dhcp_client_id,
guint32 timeout,
@@ -418,6 +419,7 @@ client_start (NMDHCPManager *self,
NM_DHCP_CLIENT_HWADDR, hwaddr,
NM_DHCP_CLIENT_IPV6, ipv6,
NM_DHCP_CLIENT_UUID, uuid,
NM_DHCP_CLIENT_PRIORITY, priority,
NM_DHCP_CLIENT_TIMEOUT, timeout ? timeout : DHCP_TIMEOUT,
NULL);
g_return_val_if_fail (client != NULL, NULL);
@@ -452,6 +454,7 @@ nm_dhcp_manager_start_ip4 (NMDHCPManager *self,
const char *iface,
const GByteArray *hwaddr,
const char *uuid,
guint priority,
NMSettingIP4Config *s_ip4,
guint32 timeout,
GByteArray *dhcp_anycast_addr)
@@ -469,7 +472,9 @@ nm_dhcp_manager_start_ip4 (NMDHCPManager *self,
if (send_hostname)
hostname = get_send_hostname (self, nm_setting_ip4_config_get_dhcp_hostname (s_ip4));
return client_start (self, iface, hwaddr, uuid, FALSE, nm_setting_ip4_config_get_dhcp_client_id (s_ip4), timeout, dhcp_anycast_addr, hostname, FALSE);
return client_start (self, iface, hwaddr, uuid, priority, FALSE,
nm_setting_ip4_config_get_dhcp_client_id (s_ip4),
timeout, dhcp_anycast_addr, hostname, FALSE);
}
/* Caller owns a reference to the NMDHCPClient on return */
@@ -478,6 +483,7 @@ nm_dhcp_manager_start_ip6 (NMDHCPManager *self,
const char *iface,
const GByteArray *hwaddr,
const char *uuid,
guint priority,
NMSettingIP6Config *s_ip6,
guint32 timeout,
GByteArray *dhcp_anycast_addr,
@@ -489,7 +495,8 @@ nm_dhcp_manager_start_ip6 (NMDHCPManager *self,
hostname = get_send_hostname (self, nm_setting_ip6_config_get_dhcp_hostname (s_ip6));
return client_start (self, iface, hwaddr, uuid, TRUE, NULL, timeout, dhcp_anycast_addr, hostname, info_only);
return client_start (self, iface, hwaddr, uuid, priority, TRUE,
NULL, timeout, dhcp_anycast_addr, hostname, info_only);
}
void

View File

@@ -68,6 +68,7 @@ NMDHCPClient * nm_dhcp_manager_start_ip4 (NMDHCPManager *manager,
const char *iface,
const GByteArray *hwaddr,
const char *uuid,
guint priority,
NMSettingIP4Config *s_ip4,
guint32 timeout,
GByteArray *dhcp_anycast_addr);
@@ -76,6 +77,7 @@ NMDHCPClient * nm_dhcp_manager_start_ip6 (NMDHCPManager *manager,
const char *iface,
const GByteArray *hwaddr,
const char *uuid,
guint priority,
NMSettingIP6Config *s_ip6,
guint32 timeout,
GByteArray *dhcp_anycast_addr,

View File

@@ -244,7 +244,7 @@ nm_ip4_config_capture (int ifindex, gboolean capture_resolv_conf)
}
gboolean
nm_ip4_config_commit (const NMIP4Config *config, int ifindex, int priority)
nm_ip4_config_commit (const NMIP4Config *config, int ifindex)
{
NMIP4ConfigPrivate *priv = NM_IP4_CONFIG_GET_PRIVATE (config);
int mtu = nm_ip4_config_get_mtu (config);
@@ -273,17 +273,12 @@ nm_ip4_config_commit (const NMIP4Config *config, int ifindex, int priority)
&& nm_ip4_config_destination_is_direct (config, route.network, route.plen))
continue;
/* Don't add the default route when and the connection
/* Don't add the default route if the connection
* is never supposed to be the default connection.
*/
if (nm_ip4_config_get_never_default (config) && route.network == 0)
continue;
/* Use the default metric only if the route was created by NM and
* didn't already specify a metric.
*/
if (route.source != NM_PLATFORM_SOURCE_KERNEL && !route.metric)
route.metric = priority ? priority : NM_PLATFORM_ROUTE_METRIC_DEFAULT;
g_array_append_val (routes, route);
}

View File

@@ -60,7 +60,7 @@ const char * nm_ip4_config_get_dbus_path (const NMIP4Config *config);
/* Integration with nm-platform and nm-setting */
NMIP4Config *nm_ip4_config_capture (int ifindex, gboolean capture_resolv_conf);
gboolean nm_ip4_config_commit (const NMIP4Config *config, int ifindex, int priority);
gboolean nm_ip4_config_commit (const NMIP4Config *config, int ifindex);
void nm_ip4_config_merge_setting (NMIP4Config *config, NMSettingIP4Config *setting);
NMSetting *nm_ip4_config_create_setting (const NMIP4Config *config);

View File

@@ -356,7 +356,7 @@ nm_ip6_config_capture (int ifindex, gboolean capture_resolv_conf, NMSettingIP6Co
}
gboolean
nm_ip6_config_commit (const NMIP6Config *config, int ifindex, int priority)
nm_ip6_config_commit (const NMIP6Config *config, int ifindex)
{
NMIP6ConfigPrivate *priv = NM_IP6_CONFIG_GET_PRIVATE (config);
int i;
@@ -384,17 +384,12 @@ nm_ip6_config_commit (const NMIP6Config *config, int ifindex, int priority)
&& nm_ip6_config_destination_is_direct (config, &route.network, route.plen))
continue;
/* Don't add the default route when and the connection
/* Don't add the default route if the connection
* is never supposed to be the default connection.
*/
if (nm_ip6_config_get_never_default (config) && IN6_IS_ADDR_UNSPECIFIED (&route.network))
continue;
/* Use the default metric only if the route was created by NM and
* didn't already specify a metric.
*/
if (route.source != NM_PLATFORM_SOURCE_KERNEL && !route.metric)
route.metric = priority ? priority : NM_PLATFORM_ROUTE_METRIC_DEFAULT;
g_array_append_val (routes, route);
}

View File

@@ -59,7 +59,7 @@ const char * nm_ip6_config_get_dbus_path (const NMIP6Config *config);
/* Integration with nm-platform and nm-setting */
NMIP6Config *nm_ip6_config_capture (int ifindex, gboolean capture_resolv_conf, NMSettingIP6ConfigPrivacy use_temporary);
gboolean nm_ip6_config_commit (const NMIP6Config *config, int ifindex, int priority);
gboolean nm_ip6_config_commit (const NMIP6Config *config, int ifindex);
void nm_ip6_config_merge_setting (NMIP6Config *config, NMSettingIP6Config *setting);
NMSetting *nm_ip6_config_create_setting (const NMIP6Config *config);

View File

@@ -334,6 +334,7 @@ add_ip4_vpn_gateway_route (NMIP4Config *config, NMDevice *parent_device, guint32
route.gateway = 0;
route.source = NM_PLATFORM_SOURCE_VPN;
route.metric = nm_device_get_priority (parent_device);
nm_ip4_config_add_route (config, &route);
/* Ensure there's a route to the parent device's gateway through the
@@ -345,6 +346,7 @@ add_ip4_vpn_gateway_route (NMIP4Config *config, NMDevice *parent_device, guint32
route.network = parent_gw;
route.plen = 32;
route.source = NM_PLATFORM_SOURCE_VPN;
route.metric = nm_device_get_priority (parent_device);
nm_ip4_config_add_route (config, &route);
}
@@ -381,6 +383,7 @@ add_ip6_vpn_gateway_route (NMIP6Config *config,
route.gateway = in6addr_any;
route.source = NM_PLATFORM_SOURCE_VPN;
route.metric = nm_device_get_priority (parent_device);
nm_ip6_config_add_route (config, &route);
/* Ensure there's a route to the parent device's gateway through the
@@ -392,6 +395,7 @@ add_ip6_vpn_gateway_route (NMIP6Config *config,
route.network = *parent_gw;
route.plen = 128;
route.source = NM_PLATFORM_SOURCE_VPN;
route.metric = nm_device_get_priority (parent_device);
nm_ip6_config_add_route (config, &route);
}
@@ -694,12 +698,12 @@ nm_vpn_connection_apply_config (NMVPNConnection *connection)
nm_platform_link_set_up (priv->ip_ifindex);
if (priv->ip4_config) {
if (!nm_ip4_config_commit (priv->ip4_config, priv->ip_ifindex, 0))
if (!nm_ip4_config_commit (priv->ip4_config, priv->ip_ifindex))
return FALSE;
}
if (priv->ip6_config) {
if (!nm_ip6_config_commit (priv->ip6_config, priv->ip_ifindex, 0))
if (!nm_ip6_config_commit (priv->ip6_config, priv->ip_ifindex))
return FALSE;
}
@@ -907,6 +911,20 @@ nm_vpn_connection_config_get (DBusGProxy *proxy,
g_clear_object (&priv->ip6_config);
}
static guint
vpn_routing_metric (NMVPNConnection *connection)
{
NMVPNConnectionPrivate *priv = NM_VPN_CONNECTION_GET_PRIVATE (connection);
if (priv->ip_ifindex)
return NM_PLATFORM_ROUTE_METRIC_DEFAULT;
else {
NMDevice *parent_dev = nm_active_connection_get_device (NM_ACTIVE_CONNECTION (connection));
return nm_device_get_priority (parent_dev);
}
}
static void
nm_vpn_connection_ip4_config_get (DBusGProxy *proxy,
GHashTable *config_hash,
@@ -1033,6 +1051,7 @@ nm_vpn_connection_ip4_config_get (DBusGProxy *proxy,
route.plen = nm_ip4_route_get_prefix (item);
route.gateway = nm_ip4_route_get_next_hop (item);
route.source = NM_PLATFORM_SOURCE_VPN;
route.metric = vpn_routing_metric (connection);
/* Ignore host routes to the VPN gateway since NM adds one itself
* below. Since NM knows more about the routing situation than
@@ -1179,6 +1198,7 @@ nm_vpn_connection_ip6_config_get (DBusGProxy *proxy,
route.plen = nm_ip6_route_get_prefix (item);
route.gateway = *nm_ip6_route_get_next_hop (item);
route.source = NM_PLATFORM_SOURCE_VPN;
route.metric = vpn_routing_metric (connection);
/* Ignore host routes to the VPN gateway since NM adds one itself
* below. Since NM knows more about the routing situation than