diff --git a/src/devices/nm-device.c b/src/devices/nm-device.c index 2b576add4a..a67401c3f5 100644 --- a/src/devices/nm-device.c +++ b/src/devices/nm-device.c @@ -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; } diff --git a/src/dhcp-manager/nm-dhcp-client.c b/src/dhcp-manager/nm-dhcp-client.c index c8a94616fa..03c11c74d4 100644 --- a/src/dhcp-manager/nm-dhcp-client.c +++ b/src/dhcp-manager/nm-dhcp-client.c @@ -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, diff --git a/src/dhcp-manager/nm-dhcp-client.h b/src/dhcp-manager/nm-dhcp-client.h index 104a08b153..ad18926af9 100644 --- a/src/dhcp-manager/nm-dhcp-client.h +++ b/src/dhcp-manager/nm-dhcp-client.h @@ -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" diff --git a/src/dhcp-manager/nm-dhcp-manager.c b/src/dhcp-manager/nm-dhcp-manager.c index dd59416e8d..ab6966cbb6 100644 --- a/src/dhcp-manager/nm-dhcp-manager.c +++ b/src/dhcp-manager/nm-dhcp-manager.c @@ -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 diff --git a/src/dhcp-manager/nm-dhcp-manager.h b/src/dhcp-manager/nm-dhcp-manager.h index d684f20bcf..efdd43788b 100644 --- a/src/dhcp-manager/nm-dhcp-manager.h +++ b/src/dhcp-manager/nm-dhcp-manager.h @@ -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, diff --git a/src/nm-ip4-config.c b/src/nm-ip4-config.c index 4d149f25ab..26a6ead719 100644 --- a/src/nm-ip4-config.c +++ b/src/nm-ip4-config.c @@ -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); } diff --git a/src/nm-ip4-config.h b/src/nm-ip4-config.h index dfe84770a9..d0e0df028e 100644 --- a/src/nm-ip4-config.h +++ b/src/nm-ip4-config.h @@ -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); diff --git a/src/nm-ip6-config.c b/src/nm-ip6-config.c index bbb0b1065f..26b0530630 100644 --- a/src/nm-ip6-config.c +++ b/src/nm-ip6-config.c @@ -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); } diff --git a/src/nm-ip6-config.h b/src/nm-ip6-config.h index 07ca0e6d7f..8fb03e2014 100644 --- a/src/nm-ip6-config.h +++ b/src/nm-ip6-config.h @@ -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); diff --git a/src/vpn-manager/nm-vpn-connection.c b/src/vpn-manager/nm-vpn-connection.c index 730bcee1b0..17664ad1a9 100644 --- a/src/vpn-manager/nm-vpn-connection.c +++ b/src/vpn-manager/nm-vpn-connection.c @@ -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