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..6a7904328a 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); } @@ -449,6 +444,10 @@ nm_ip4_config_create_setting (const NMIP4Config *config) if (!route->plen) continue; + /* Ignore routes provided by external sources */ + if (route->source != NM_PLATFORM_SOURCE_USER) + continue; + s_route = nm_ip4_route_new (); nm_ip4_route_set_dest (s_route, route->network); nm_ip4_route_set_prefix (s_route, route->plen); 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..66fa395352 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); } @@ -556,6 +551,10 @@ nm_ip6_config_create_setting (const NMIP6Config *config) if (!route->plen) continue; + /* Ignore routes provided by external sources */ + if (route->source != NM_PLATFORM_SOURCE_USER) + continue; + s_route = nm_ip6_route_new (); nm_ip6_route_set_dest (s_route, &route->network); nm_ip6_route_set_prefix (s_route, route->plen); 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/nm-policy.c b/src/nm-policy.c index c85f3217d3..f307f999c6 100644 --- a/src/nm-policy.c +++ b/src/nm-policy.c @@ -658,9 +658,15 @@ update_ip4_routing (NMPolicy *policy, gboolean force_update) if (ip_ifindex <= 0) ip_ifindex = parent_ifindex; - if (!nm_platform_ip4_route_add (ip_ifindex, 0, 0, int_gw, NM_PLATFORM_ROUTE_METRIC_DEFAULT, mss)) { - (void) nm_platform_ip4_route_add (parent_ifindex, gw_addr, 32, 0, NM_PLATFORM_ROUTE_METRIC_DEFAULT, parent_mss); - if (!nm_platform_ip4_route_add (ip_ifindex, 0, 0, int_gw, NM_PLATFORM_ROUTE_METRIC_DEFAULT, mss)) + if (!nm_platform_ip4_route_add (ip_ifindex, NM_PLATFORM_SOURCE_VPN, + 0, 0, int_gw, + NM_PLATFORM_ROUTE_METRIC_DEFAULT, mss)) { + (void) nm_platform_ip4_route_add (parent_ifindex, NM_PLATFORM_SOURCE_VPN, + gw_addr, 32, 0, + NM_PLATFORM_ROUTE_METRIC_DEFAULT, parent_mss); + if (!nm_platform_ip4_route_add (ip_ifindex, NM_PLATFORM_SOURCE_VPN, + 0, 0, int_gw, + NM_PLATFORM_ROUTE_METRIC_DEFAULT, mss)) nm_log_err (LOGD_IP4 | LOGD_VPN, "Failed to set default route."); } @@ -669,9 +675,15 @@ update_ip4_routing (NMPolicy *policy, gboolean force_update) int mss = nm_ip4_config_get_mss (ip4_config); g_assert (ip_iface); - if (!nm_platform_ip4_route_add (ip_ifindex, 0, 0, gw_addr, NM_PLATFORM_ROUTE_METRIC_DEFAULT, mss)) { - (void) nm_platform_ip4_route_add (ip_ifindex, gw_addr, 32, 0, NM_PLATFORM_ROUTE_METRIC_DEFAULT, mss); - if (!nm_platform_ip4_route_add (ip_ifindex, 0, 0, gw_addr, NM_PLATFORM_ROUTE_METRIC_DEFAULT, mss)) { + if (!nm_platform_ip4_route_add (ip_ifindex, NM_PLATFORM_SOURCE_USER, + 0, 0, gw_addr, + NM_PLATFORM_ROUTE_METRIC_DEFAULT, mss)) { + (void) nm_platform_ip4_route_add (ip_ifindex, NM_PLATFORM_SOURCE_USER, + gw_addr, 32, 0, + NM_PLATFORM_ROUTE_METRIC_DEFAULT, mss); + if (!nm_platform_ip4_route_add (ip_ifindex, NM_PLATFORM_SOURCE_USER, + 0, 0, gw_addr, + NM_PLATFORM_ROUTE_METRIC_DEFAULT, mss)) { nm_log_err (LOGD_IP4, "Failed to set default route."); } } @@ -852,9 +864,15 @@ update_ip6_routing (NMPolicy *policy, gboolean force_update) if (ip_ifindex <= 0) ip_ifindex = parent_ifindex; - if (!nm_platform_ip6_route_add (ip_ifindex, in6addr_any, 0, *int_gw, NM_PLATFORM_ROUTE_METRIC_DEFAULT, mss)) { - (void) nm_platform_ip6_route_add (parent_ifindex, *gw_addr, 128, in6addr_any, NM_PLATFORM_ROUTE_METRIC_DEFAULT, parent_mss); - if (!nm_platform_ip6_route_add (ip_ifindex, in6addr_any, 0, *int_gw, NM_PLATFORM_ROUTE_METRIC_DEFAULT, mss)) { + if (!nm_platform_ip6_route_add (ip_ifindex, NM_PLATFORM_SOURCE_VPN, + in6addr_any, 0, *int_gw, + NM_PLATFORM_ROUTE_METRIC_DEFAULT, mss)) { + (void) nm_platform_ip6_route_add (parent_ifindex, NM_PLATFORM_SOURCE_VPN, + *gw_addr, 128, in6addr_any, + NM_PLATFORM_ROUTE_METRIC_DEFAULT, parent_mss); + if (!nm_platform_ip6_route_add (ip_ifindex, NM_PLATFORM_SOURCE_VPN, + in6addr_any, 0, *int_gw, + NM_PLATFORM_ROUTE_METRIC_DEFAULT, mss)) { nm_log_err (LOGD_IP6 | LOGD_VPN, "Failed to set default route."); } } @@ -863,9 +881,15 @@ update_ip6_routing (NMPolicy *policy, gboolean force_update) } else { int mss = nm_ip6_config_get_mss (ip6_config); - if (!nm_platform_ip6_route_add (ip_ifindex, in6addr_any, 0, *gw_addr, NM_PLATFORM_ROUTE_METRIC_DEFAULT, mss)) { - (void) nm_platform_ip6_route_add (ip_ifindex, *gw_addr, 128, in6addr_any, NM_PLATFORM_ROUTE_METRIC_DEFAULT, mss); - if (!nm_platform_ip6_route_add (ip_ifindex, in6addr_any, 0, *gw_addr, NM_PLATFORM_ROUTE_METRIC_DEFAULT, mss)) + if (!nm_platform_ip6_route_add (ip_ifindex, NM_PLATFORM_SOURCE_USER, + in6addr_any, 0, *gw_addr, + NM_PLATFORM_ROUTE_METRIC_DEFAULT, mss)) { + (void) nm_platform_ip6_route_add (ip_ifindex, NM_PLATFORM_SOURCE_USER, + *gw_addr, 128, in6addr_any, + NM_PLATFORM_ROUTE_METRIC_DEFAULT, mss); + if (!nm_platform_ip6_route_add (ip_ifindex, NM_PLATFORM_SOURCE_USER, + in6addr_any, 0, *gw_addr, + NM_PLATFORM_ROUTE_METRIC_DEFAULT, mss)) nm_log_err (LOGD_IP6, "Failed to set default route."); } diff --git a/src/platform/nm-fake-platform.c b/src/platform/nm-fake-platform.c index 4f8f5b28aa..46272217d0 100644 --- a/src/platform/nm-fake-platform.c +++ b/src/platform/nm-fake-platform.c @@ -1039,8 +1039,9 @@ ip6_route_get_all (NMPlatform *platform, int ifindex, gboolean include_default) } static gboolean -ip4_route_add (NMPlatform *platform, int ifindex, in_addr_t network, int plen, - in_addr_t gateway, int metric, int mss) +ip4_route_add (NMPlatform *platform, int ifindex, NMPlatformSource source, + in_addr_t network, int plen, in_addr_t gateway, + int metric, int mss) { NMFakePlatformPrivate *priv = NM_FAKE_PLATFORM_GET_PRIVATE (platform); NMPlatformIP4Route route; @@ -1049,6 +1050,7 @@ ip4_route_add (NMPlatform *platform, int ifindex, in_addr_t network, int plen, memset (&route, 0, sizeof (route)); route.source = NM_PLATFORM_SOURCE_KERNEL; route.ifindex = ifindex; + route.source = source; route.network = network; route.plen = plen; route.gateway = gateway; @@ -1077,8 +1079,9 @@ ip4_route_add (NMPlatform *platform, int ifindex, in_addr_t network, int plen, } static gboolean -ip6_route_add (NMPlatform *platform, int ifindex, struct in6_addr network, int plen, - struct in6_addr gateway, int metric, int mss) +ip6_route_add (NMPlatform *platform, int ifindex, NMPlatformSource source, + struct in6_addr network, int plen, struct in6_addr gateway, + int metric, int mss) { NMFakePlatformPrivate *priv = NM_FAKE_PLATFORM_GET_PRIVATE (platform); NMPlatformIP6Route route; @@ -1087,6 +1090,7 @@ ip6_route_add (NMPlatform *platform, int ifindex, struct in6_addr network, int p memset (&route, 0, sizeof (route)); route.source = NM_PLATFORM_SOURCE_KERNEL; route.ifindex = ifindex; + route.source = source; route.network = network; route.plen = plen; route.gateway = gateway; diff --git a/src/platform/nm-linux-platform.c b/src/platform/nm-linux-platform.c index 6aa8b650e2..f5911c8b70 100644 --- a/src/platform/nm-linux-platform.c +++ b/src/platform/nm-linux-platform.c @@ -1048,6 +1048,43 @@ init_ip6_address (NMPlatformIP6Address *address, struct rtnl_addr *rtnladdr) return TRUE; } +static guint +source_to_rtprot (NMPlatformSource source) +{ + switch (source) { + case NM_PLATFORM_SOURCE_UNKNOWN: + return RTPROT_UNSPEC; + case NM_PLATFORM_SOURCE_KERNEL: + return RTPROT_KERNEL; + case NM_PLATFORM_SOURCE_DHCP: + return RTPROT_DHCP; + case NM_PLATFORM_SOURCE_RDISC: + return RTPROT_RA; + + default: + return RTPROT_STATIC; + } +} + +static NMPlatformSource +rtprot_to_source (guint rtprot) +{ + switch (rtprot) { + case RTPROT_UNSPEC: + return NM_PLATFORM_SOURCE_UNKNOWN; + case RTPROT_REDIRECT: + case RTPROT_KERNEL: + return NM_PLATFORM_SOURCE_KERNEL; + case RTPROT_RA: + return NM_PLATFORM_SOURCE_RDISC; + case RTPROT_DHCP: + return NM_PLATFORM_SOURCE_DHCP; + + default: + return NM_PLATFORM_SOURCE_USER; + } +} + static gboolean init_ip4_route (NMPlatformIP4Route *route, struct rtnl_route *rtnlroute) { @@ -1083,6 +1120,7 @@ init_ip4_route (NMPlatformIP4Route *route, struct rtnl_route *rtnlroute) } route->metric = rtnl_route_get_priority (rtnlroute); rtnl_route_get_metric (rtnlroute, RTAX_ADVMSS, &route->mss); + route->source = rtprot_to_source (rtnl_route_get_protocol (rtnlroute)); return TRUE; } @@ -1122,6 +1160,7 @@ init_ip6_route (NMPlatformIP6Route *route, struct rtnl_route *rtnlroute) } route->metric = rtnl_route_get_priority (rtnlroute); rtnl_route_get_metric (rtnlroute, RTAX_ADVMSS, &route->mss); + route->source = rtprot_to_source (rtnl_route_get_protocol (rtnlroute)); return TRUE; } @@ -3263,7 +3302,6 @@ ip4_route_get_all (NMPlatform *platform, int ifindex, gboolean include_default) for (object = nl_cache_get_first (priv->route_cache); object; object = nl_cache_get_next (object)) { if (_route_match ((struct rtnl_route *) object, AF_INET, ifindex)) { if (init_ip4_route (&route, (struct rtnl_route *) object)) { - route.source = NM_PLATFORM_SOURCE_KERNEL; if (route.plen != 0 || include_default) g_array_append_val (routes, route); } @@ -3286,7 +3324,6 @@ ip6_route_get_all (NMPlatform *platform, int ifindex, gboolean include_default) for (object = nl_cache_get_first (priv->route_cache); object; object = nl_cache_get_next (object)) { if (_route_match ((struct rtnl_route *) object, AF_INET6, ifindex)) { if (init_ip6_route (&route, (struct rtnl_route *) object)) { - route.source = NM_PLATFORM_SOURCE_KERNEL; if (route.plen != 0 || include_default) g_array_append_val (routes, route); } @@ -3315,7 +3352,9 @@ clear_host_address (int family, const void *network, int plen, void *dst) } static struct nl_object * -build_rtnl_route (int family, int ifindex, gconstpointer network, int plen, gconstpointer gateway, int metric, int mss) +build_rtnl_route (int family, int ifindex, NMPlatformSource source, + gconstpointer network, int plen, gconstpointer gateway, + int metric, int mss) { guint32 network_clean[4]; struct rtnl_route *rtnlroute; @@ -3339,6 +3378,7 @@ build_rtnl_route (int family, int ifindex, gconstpointer network, int plen, gcon rtnl_route_set_dst (rtnlroute, dst); rtnl_route_set_priority (rtnlroute, metric); rtnl_route_set_family (rtnlroute, family); + rtnl_route_set_protocol (rtnlroute, source_to_rtprot (source)); nexthop = _nm_rtnl_route_nh_alloc (); rtnl_route_nh_set_ifindex (nexthop, ifindex); @@ -3353,15 +3393,19 @@ build_rtnl_route (int family, int ifindex, gconstpointer network, int plen, gcon } static gboolean -ip4_route_add (NMPlatform *platform, int ifindex, in_addr_t network, int plen, in_addr_t gateway, int metric, int mss) +ip4_route_add (NMPlatform *platform, int ifindex, NMPlatformSource source, + in_addr_t network, int plen, in_addr_t gateway, + int metric, int mss) { - return add_object (platform, build_rtnl_route (AF_INET, ifindex, &network, plen, &gateway, metric, mss)); + return add_object (platform, build_rtnl_route (AF_INET, ifindex, source, &network, plen, &gateway, metric, mss)); } static gboolean -ip6_route_add (NMPlatform *platform, int ifindex, struct in6_addr network, int plen, struct in6_addr gateway, int metric, int mss) +ip6_route_add (NMPlatform *platform, int ifindex, NMPlatformSource source, + struct in6_addr network, int plen, struct in6_addr gateway, + int metric, int mss) { - return add_object (platform, build_rtnl_route (AF_INET6, ifindex, &network, plen, &gateway, metric, mss)); + return add_object (platform, build_rtnl_route (AF_INET6, ifindex, source, &network, plen, &gateway, metric, mss)); } static struct rtnl_route * @@ -3418,7 +3462,7 @@ ip4_route_delete (NMPlatform *platform, int ifindex, in_addr_t network, int plen { in_addr_t gateway = 0; struct rtnl_route *cached_object; - struct nl_object *route = build_rtnl_route (AF_INET, ifindex, &network, plen, &gateway, metric, 0); + struct nl_object *route = build_rtnl_route (AF_INET, ifindex, NM_PLATFORM_SOURCE_UNKNOWN, &network, plen, &gateway, metric, 0); uint8_t scope = RT_SCOPE_NOWHERE; struct nl_cache *cache; @@ -3459,9 +3503,6 @@ ip4_route_delete (NMPlatform *platform, int ifindex, in_addr_t network, int plen } rtnl_route_set_scope ((struct rtnl_route *) route, scope); - /* protocol defaults to RTPROT_STATIC, set to zero so that the kernel ignores the value */ - rtnl_route_set_protocol ((struct rtnl_route *) route, 0); - if (cached_object) rtnl_route_set_tos ((struct rtnl_route *) route, rtnl_route_get_tos (cached_object)); @@ -3481,15 +3522,16 @@ ip6_route_delete (NMPlatform *platform, int ifindex, struct in6_addr network, in { struct in6_addr gateway = IN6ADDR_ANY_INIT; - return delete_object (platform, build_rtnl_route (AF_INET6, ifindex, &network, plen, &gateway, metric, 0), FALSE) && + return delete_object (platform, build_rtnl_route (AF_INET6, ifindex, NM_PLATFORM_SOURCE_UNKNOWN ,&network, plen, &gateway, metric, 0), FALSE) && refresh_route (platform, AF_INET6, ifindex, &network, plen, metric); } static gboolean ip_route_exists (NMPlatform *platform, int family, int ifindex, gpointer network, int plen, int metric) { - auto_nl_object struct nl_object *object = build_rtnl_route (family, ifindex, network, - plen, NULL, metric, 0); + auto_nl_object struct nl_object *object = build_rtnl_route (family, ifindex, + NM_PLATFORM_SOURCE_UNKNOWN, + network, plen, NULL, metric, 0); struct nl_cache *cache = choose_cache (platform, object); auto_nl_object struct nl_object *cached_object = nl_cache_search (cache, object); diff --git a/src/platform/nm-platform.c b/src/platform/nm-platform.c index 42b31453c3..463822c7d9 100644 --- a/src/platform/nm-platform.c +++ b/src/platform/nm-platform.c @@ -1711,9 +1711,9 @@ nm_platform_ip6_route_get_all (int ifindex, gboolean include_default) } gboolean -nm_platform_ip4_route_add (int ifindex, - in_addr_t network, int plen, - in_addr_t gateway, int metric, int mss) +nm_platform_ip4_route_add (int ifindex, NMPlatformSource source, + in_addr_t network, int plen, + in_addr_t gateway, int metric, int mss) { reset_error (); @@ -1727,6 +1727,7 @@ nm_platform_ip4_route_add (int ifindex, NMPlatformIP4Route route = { 0 }; route.ifindex = ifindex; + route.source = source; route.network = network; route.plen = plen; route.gateway = gateway; @@ -1735,12 +1736,13 @@ nm_platform_ip4_route_add (int ifindex, debug ("route: adding or updating IPv4 route: %s", nm_platform_ip4_route_to_string (&route)); } - return klass->ip4_route_add (platform, ifindex, network, plen, gateway, metric, mss); + return klass->ip4_route_add (platform, ifindex, source, network, plen, gateway, metric, mss); } gboolean -nm_platform_ip6_route_add (int ifindex, - struct in6_addr network, int plen, struct in6_addr gateway, int metric, int mss) +nm_platform_ip6_route_add (int ifindex, NMPlatformSource source, + struct in6_addr network, int plen, struct in6_addr gateway, + int metric, int mss) { g_return_val_if_fail (platform, FALSE); g_return_val_if_fail (0 <= plen && plen <= 128, FALSE); @@ -1752,6 +1754,7 @@ nm_platform_ip6_route_add (int ifindex, NMPlatformIP6Route route = { 0 }; route.ifindex = ifindex; + route.source = source; route.network = network; route.plen = plen; route.gateway = gateway; @@ -1760,7 +1763,7 @@ nm_platform_ip6_route_add (int ifindex, debug ("route: adding or updating IPv6 route: %s", nm_platform_ip6_route_to_string (&route)); } - return klass->ip6_route_add (platform, ifindex, network, plen, gateway, metric, mss); + return klass->ip6_route_add (platform, ifindex, source, network, plen, gateway, metric, mss); } gboolean @@ -1776,8 +1779,7 @@ nm_platform_ip4_route_delete (int ifindex, in_addr_t network, int plen, int metr } gboolean -nm_platform_ip6_route_delete (int ifindex, - struct in6_addr network, int plen, int metric) +nm_platform_ip6_route_delete (int ifindex, struct in6_addr network, int plen, int metric) { reset_error (); @@ -1896,6 +1898,7 @@ nm_platform_ip4_route_sync (int ifindex, const GArray *known_routes) /* Ignore routes that already exist */ if (!array_contains_ip4_route (routes, known_route)) { success = nm_platform_ip4_route_add (ifindex, + known_route->source, known_route->network, known_route->plen, known_route->gateway, @@ -1963,6 +1966,7 @@ nm_platform_ip6_route_sync (int ifindex, const GArray *known_routes) /* Ignore routes that already exist */ if (!array_contains_ip6_route (routes, known_route)) { success = nm_platform_ip6_route_add (ifindex, + known_route->source, known_route->network, known_route->plen, known_route->gateway, diff --git a/src/platform/nm-platform.h b/src/platform/nm-platform.h index 9a2487125c..cde551b258 100644 --- a/src/platform/nm-platform.h +++ b/src/platform/nm-platform.h @@ -428,10 +428,12 @@ typedef struct { GArray * (*ip4_route_get_all) (NMPlatform *, int ifindex, gboolean include_default); GArray * (*ip6_route_get_all) (NMPlatform *, int ifindex, gboolean include_default); - gboolean (*ip4_route_add) (NMPlatform *, int ifindex, - in_addr_t network, int plen, in_addr_t gateway, int prio, int mss); - gboolean (*ip6_route_add) (NMPlatform *, int ifindex, - struct in6_addr network, int plen, struct in6_addr gateway, int prio, int mss); + gboolean (*ip4_route_add) (NMPlatform *, int ifindex, NMPlatformSource source, + in_addr_t network, int plen, in_addr_t gateway, + int prio, int mss); + gboolean (*ip6_route_add) (NMPlatform *, int ifindex, NMPlatformSource source, + struct in6_addr network, int plen, struct in6_addr gateway, + int prio, int mss); gboolean (*ip4_route_delete) (NMPlatform *, int ifindex, in_addr_t network, int plen, int metric); gboolean (*ip6_route_delete) (NMPlatform *, int ifindex, struct in6_addr network, int plen, int metric); gboolean (*ip4_route_exists) (NMPlatform *, int ifindex, in_addr_t network, int plen, int metric); @@ -570,10 +572,12 @@ gboolean nm_platform_address_flush (int ifindex); GArray *nm_platform_ip4_route_get_all (int ifindex, gboolean include_default); GArray *nm_platform_ip6_route_get_all (int ifindex, gboolean include_default); gboolean nm_platform_route_set_metric (int ifindex, int metric); -gboolean nm_platform_ip4_route_add (int ifindex, - in_addr_t network, int plen, in_addr_t gateway, int metric, int mss); -gboolean nm_platform_ip6_route_add (int ifindex, - struct in6_addr network, int plen, struct in6_addr gateway, int metric, int mss); +gboolean nm_platform_ip4_route_add (int ifindex, NMPlatformSource source, + in_addr_t network, int plen, in_addr_t gateway, + int metric, int mss); +gboolean nm_platform_ip6_route_add (int ifindex, NMPlatformSource source, + struct in6_addr network, int plen, struct in6_addr gateway, + int metric, int mss); gboolean nm_platform_ip4_route_delete (int ifindex, in_addr_t network, int plen, int metric); gboolean nm_platform_ip6_route_delete (int ifindex, struct in6_addr network, int plen, int metric); gboolean nm_platform_ip4_route_exists (int ifindex, in_addr_t network, int plen, int metric); diff --git a/src/platform/tests/platform.c b/src/platform/tests/platform.c index 1802ac2c08..ea8bd0e3b3 100644 --- a/src/platform/tests/platform.c +++ b/src/platform/tests/platform.c @@ -677,7 +677,9 @@ do_ip4_route_add (char **argv) metric = strtol (*argv++, NULL, 10); mss = strtol (*argv++, NULL, 10); - return nm_platform_ip4_route_add (ifindex, network, plen, gateway, metric, mss); + return nm_platform_ip4_route_add (ifindex, NM_PLATFORM_SOURCE_USER, + network, plen, gateway, + metric, mss); } static gboolean @@ -691,7 +693,9 @@ do_ip6_route_add (char **argv) parse_ip6_address (*argv++, &gateway, NULL); metric = strtol (*argv++, NULL, 10); mss = strtol (*argv++, NULL, 10); - return nm_platform_ip6_route_add (ifindex, network, plen, gateway, metric, mss); + return nm_platform_ip6_route_add (ifindex, NM_PLATFORM_SOURCE_USER, + network, plen, gateway, + metric, mss); } static gboolean diff --git a/src/platform/tests/test-cleanup.c b/src/platform/tests/test-cleanup.c index 5d6036ca44..e60d82f0ed 100644 --- a/src/platform/tests/test-cleanup.c +++ b/src/platform/tests/test-cleanup.c @@ -43,12 +43,12 @@ test_cleanup_internal () /* Add routes and addresses */ g_assert (nm_platform_ip4_address_add (ifindex, addr4, 0, plen4, lifetime, preferred, NULL)); g_assert (nm_platform_ip6_address_add (ifindex, addr6, in6addr_any, plen6, lifetime, preferred, flags)); - g_assert (nm_platform_ip4_route_add (ifindex, gateway4, 32, INADDR_ANY, metric, mss)); - g_assert (nm_platform_ip4_route_add (ifindex, network4, plen4, gateway4, metric, mss)); - g_assert (nm_platform_ip4_route_add (ifindex, 0, 0, gateway4, metric, mss)); - g_assert (nm_platform_ip6_route_add (ifindex, gateway6, 128, in6addr_any, metric, mss)); - g_assert (nm_platform_ip6_route_add (ifindex, network6, plen6, gateway6, metric, mss)); - g_assert (nm_platform_ip6_route_add (ifindex, in6addr_any, 0, gateway6, metric, mss)); + g_assert (nm_platform_ip4_route_add (ifindex, NM_PLATFORM_SOURCE_USER, gateway4, 32, INADDR_ANY, metric, mss)); + g_assert (nm_platform_ip4_route_add (ifindex, NM_PLATFORM_SOURCE_USER, network4, plen4, gateway4, metric, mss)); + g_assert (nm_platform_ip4_route_add (ifindex, NM_PLATFORM_SOURCE_USER, 0, 0, gateway4, metric, mss)); + g_assert (nm_platform_ip6_route_add (ifindex, NM_PLATFORM_SOURCE_USER, gateway6, 128, in6addr_any, metric, mss)); + g_assert (nm_platform_ip6_route_add (ifindex, NM_PLATFORM_SOURCE_USER, network6, plen6, gateway6, metric, mss)); + g_assert (nm_platform_ip6_route_add (ifindex, NM_PLATFORM_SOURCE_USER, in6addr_any, 0, gateway6, metric, mss)); addresses4 = nm_platform_ip4_address_get_all (ifindex); addresses6 = nm_platform_ip6_address_get_all (ifindex); diff --git a/src/platform/tests/test-route.c b/src/platform/tests/test-route.c index d07749d494..6ad4ba3089 100644 --- a/src/platform/tests/test-route.c +++ b/src/platform/tests/test-route.c @@ -66,28 +66,35 @@ test_ip4_route () inet_pton (AF_INET, "198.51.100.1", &gateway); /* Add route to gateway */ - g_assert (nm_platform_ip4_route_add (ifindex, gateway, 32, INADDR_ANY, metric, mss)); no_error (); + g_assert (nm_platform_ip4_route_add (ifindex, NM_PLATFORM_SOURCE_USER, gateway, 32, INADDR_ANY, metric, mss)); + no_error (); accept_signal (route_added); /* Add route */ - g_assert (!nm_platform_ip4_route_exists (ifindex, network, plen, metric)); no_error (); - g_assert (nm_platform_ip4_route_add (ifindex, network, plen, gateway, metric, mss)); no_error (); - g_assert (nm_platform_ip4_route_exists (ifindex, network, plen, metric)); no_error (); + g_assert (!nm_platform_ip4_route_exists (ifindex, network, plen, metric)); + no_error (); + g_assert (nm_platform_ip4_route_add (ifindex, NM_PLATFORM_SOURCE_USER, network, plen, gateway, metric, mss)); + no_error (); + g_assert (nm_platform_ip4_route_exists (ifindex, network, plen, metric)); + no_error (); accept_signal (route_added); /* Add route again */ - g_assert (nm_platform_ip4_route_add (ifindex, network, plen, gateway, metric, mss)); + g_assert (nm_platform_ip4_route_add (ifindex, NM_PLATFORM_SOURCE_USER, network, plen, gateway, metric, mss)); no_error (); accept_signal (route_changed); /* Add default route */ - g_assert (!nm_platform_ip4_route_exists (ifindex, 0, 0, metric)); no_error (); - g_assert (nm_platform_ip4_route_add (ifindex, 0, 0, gateway, metric, mss)); no_error (); - g_assert (nm_platform_ip4_route_exists (ifindex, 0, 0, metric)); no_error (); + g_assert (!nm_platform_ip4_route_exists (ifindex, 0, 0, metric)); + no_error (); + g_assert (nm_platform_ip4_route_add (ifindex, NM_PLATFORM_SOURCE_USER, 0, 0, gateway, metric, mss)); + no_error (); + g_assert (nm_platform_ip4_route_exists (ifindex, 0, 0, metric)); + no_error (); accept_signal (route_added); /* Add default route again */ - g_assert (nm_platform_ip4_route_add (ifindex, 0, 0, gateway, metric, mss)); + g_assert (nm_platform_ip4_route_add (ifindex, NM_PLATFORM_SOURCE_USER, 0, 0, gateway, metric, mss)); no_error (); accept_signal (route_changed); @@ -121,7 +128,8 @@ test_ip4_route () g_array_unref (routes); /* Remove route */ - g_assert (nm_platform_ip4_route_delete (ifindex, network, plen, metric)); no_error (); + g_assert (nm_platform_ip4_route_delete (ifindex, network, plen, metric)); + no_error (); g_assert (!nm_platform_ip4_route_exists (ifindex, network, plen, metric)); accept_signal (route_removed); @@ -153,28 +161,35 @@ test_ip6_route () inet_pton (AF_INET6, "2001:db8:c:d:1:2:3:4", &gateway); /* Add route to gateway */ - g_assert (nm_platform_ip6_route_add (ifindex, gateway, 128, in6addr_any, metric, mss)); no_error (); + g_assert (nm_platform_ip6_route_add (ifindex, NM_PLATFORM_SOURCE_USER, gateway, 128, in6addr_any, metric, mss)); + no_error (); accept_signal (route_added); /* Add route */ - g_assert (!nm_platform_ip6_route_exists (ifindex, network, plen, metric)); no_error (); - g_assert (nm_platform_ip6_route_add (ifindex, network, plen, gateway, metric, mss)); no_error (); - g_assert (nm_platform_ip6_route_exists (ifindex, network, plen, metric)); no_error (); + g_assert (!nm_platform_ip6_route_exists (ifindex, network, plen, metric)); + no_error (); + g_assert (nm_platform_ip6_route_add (ifindex, NM_PLATFORM_SOURCE_USER, network, plen, gateway, metric, mss)); + no_error (); + g_assert (nm_platform_ip6_route_exists (ifindex, network, plen, metric)); + no_error (); accept_signal (route_added); /* Add route again */ - g_assert (nm_platform_ip6_route_add (ifindex, network, plen, gateway, metric, mss)); + g_assert (nm_platform_ip6_route_add (ifindex, NM_PLATFORM_SOURCE_USER, network, plen, gateway, metric, mss)); no_error (); accept_signal (route_changed); /* Add default route */ - g_assert (!nm_platform_ip6_route_exists (ifindex, in6addr_any, 0, metric)); no_error (); - g_assert (nm_platform_ip6_route_add (ifindex, in6addr_any, 0, gateway, metric, mss)); no_error (); - g_assert (nm_platform_ip6_route_exists (ifindex, in6addr_any, 0, metric)); no_error (); + g_assert (!nm_platform_ip6_route_exists (ifindex, in6addr_any, 0, metric)); + no_error (); + g_assert (nm_platform_ip6_route_add (ifindex, NM_PLATFORM_SOURCE_USER, in6addr_any, 0, gateway, metric, mss)); + no_error (); + g_assert (nm_platform_ip6_route_exists (ifindex, in6addr_any, 0, metric)); + no_error (); accept_signal (route_added); /* Add default route again */ - g_assert (nm_platform_ip6_route_add (ifindex, in6addr_any, 0, gateway, metric, mss)); + g_assert (nm_platform_ip6_route_add (ifindex, NM_PLATFORM_SOURCE_USER, in6addr_any, 0, gateway, metric, mss)); no_error (); accept_signal (route_changed); @@ -208,7 +223,8 @@ test_ip6_route () g_array_unref (routes); /* Remove route */ - g_assert (nm_platform_ip6_route_delete (ifindex, network, plen, metric)); no_error (); + g_assert (nm_platform_ip6_route_delete (ifindex, network, plen, metric)); + no_error (); g_assert (!nm_platform_ip6_route_exists (ifindex, network, plen, metric)); accept_signal (route_removed); 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