From 722c90343b637fe50cde52fb679a304c32905e1f Mon Sep 17 00:00:00 2001 From: Dan Winship Date: Wed, 4 Jun 2014 11:14:55 -0400 Subject: [PATCH 1/4] 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"). --- src/devices/nm-device.c | 8 ++++-- src/dhcp-manager/nm-dhcp-client.c | 44 +++++++++++++++++++++++------ src/dhcp-manager/nm-dhcp-client.h | 1 + src/dhcp-manager/nm-dhcp-manager.c | 11 ++++++-- src/dhcp-manager/nm-dhcp-manager.h | 2 ++ src/nm-ip4-config.c | 9 ++---- src/nm-ip4-config.h | 2 +- src/nm-ip6-config.c | 9 ++---- src/nm-ip6-config.h | 2 +- src/vpn-manager/nm-vpn-connection.c | 24 ++++++++++++++-- 10 files changed, 82 insertions(+), 30 deletions(-) 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 From e644745d85a20529c6bbb0f6f479acfa45edca86 Mon Sep 17 00:00:00 2001 From: Dan Winship Date: Thu, 15 May 2014 15:19:59 -0400 Subject: [PATCH 2/4] trivial: route-related whitespace/indentation fixes --- src/nm-policy.c | 48 ++++++++++++++++++++++++-------- src/platform/nm-fake-platform.c | 10 ++++--- src/platform/nm-linux-platform.c | 12 ++++++-- src/platform/nm-platform.c | 10 +++---- src/platform/nm-platform.h | 12 +++++--- src/platform/tests/test-route.c | 48 +++++++++++++++++++++----------- 6 files changed, 96 insertions(+), 44 deletions(-) diff --git a/src/nm-policy.c b/src/nm-policy.c index c85f3217d3..13099e3693 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, + 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)) 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, + 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)) { 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, + 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)) { 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, + 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)) 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..1fe11bdd31 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, + in_addr_t network, int plen, in_addr_t gateway, + int metric, int mss) { NMFakePlatformPrivate *priv = NM_FAKE_PLATFORM_GET_PRIVATE (platform); NMPlatformIP4Route route; @@ -1077,8 +1078,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, + struct in6_addr network, int plen, struct in6_addr gateway, + int metric, int mss) { NMFakePlatformPrivate *priv = NM_FAKE_PLATFORM_GET_PRIVATE (platform); NMPlatformIP6Route route; diff --git a/src/platform/nm-linux-platform.c b/src/platform/nm-linux-platform.c index 6aa8b650e2..5831a6eceb 100644 --- a/src/platform/nm-linux-platform.c +++ b/src/platform/nm-linux-platform.c @@ -3315,7 +3315,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, + gconstpointer network, int plen, gconstpointer gateway, + int metric, int mss) { guint32 network_clean[4]; struct rtnl_route *rtnlroute; @@ -3353,13 +3355,17 @@ 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, + 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)); } 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, + 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)); } diff --git a/src/platform/nm-platform.c b/src/platform/nm-platform.c index 42b31453c3..35525cf5d7 100644 --- a/src/platform/nm-platform.c +++ b/src/platform/nm-platform.c @@ -1712,8 +1712,8 @@ 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) + in_addr_t network, int plen, + in_addr_t gateway, int metric, int mss) { reset_error (); @@ -1740,7 +1740,8 @@ nm_platform_ip4_route_add (int ifindex, gboolean nm_platform_ip6_route_add (int ifindex, - struct in6_addr network, int plen, struct in6_addr gateway, int metric, int mss) + 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); @@ -1776,8 +1777,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 (); diff --git a/src/platform/nm-platform.h b/src/platform/nm-platform.h index 9a2487125c..d6f3fe0ba2 100644 --- a/src/platform/nm-platform.h +++ b/src/platform/nm-platform.h @@ -429,9 +429,11 @@ 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); + 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); + 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); @@ -571,9 +573,11 @@ 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); + 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); + 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/test-route.c b/src/platform/tests/test-route.c index d07749d494..24bd089cf8 100644 --- a/src/platform/tests/test-route.c +++ b/src/platform/tests/test-route.c @@ -66,13 +66,17 @@ 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, 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, 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 */ @@ -81,9 +85,12 @@ test_ip4_route () 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, 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 */ @@ -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,13 +161,17 @@ 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, 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, 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 */ @@ -168,9 +180,12 @@ test_ip6_route () 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, 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 */ @@ -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); From 662ade1e47bf2612dbd0087804441a854cc4122a Mon Sep 17 00:00:00 2001 From: Dan Winship Date: Thu, 8 May 2014 14:50:02 -0400 Subject: [PATCH 3/4] platform: improve tracking of route sources NMIP[46]Route had a "source" field, but it was always set to KERNEL for routes read from the kernel (even if they were originally added by NM). Fix things a bit by translating between our "source" field and the kernel's "protocol" field. https://bugzilla.gnome.org/show_bug.cgi?id=729203 --- src/nm-policy.c | 24 ++++++------ src/platform/nm-fake-platform.c | 6 ++- src/platform/nm-linux-platform.c | 64 ++++++++++++++++++++++++------- src/platform/nm-platform.c | 12 ++++-- src/platform/nm-platform.h | 8 ++-- src/platform/tests/platform.c | 8 +++- src/platform/tests/test-cleanup.c | 12 +++--- src/platform/tests/test-route.c | 20 +++++----- 8 files changed, 100 insertions(+), 54 deletions(-) diff --git a/src/nm-policy.c b/src/nm-policy.c index 13099e3693..f307f999c6 100644 --- a/src/nm-policy.c +++ b/src/nm-policy.c @@ -658,13 +658,13 @@ update_ip4_routing (NMPolicy *policy, gboolean force_update) if (ip_ifindex <= 0) ip_ifindex = parent_ifindex; - if (!nm_platform_ip4_route_add (ip_ifindex, + 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, + (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, + 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."); @@ -675,13 +675,13 @@ 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, + 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, + (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, + 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."); @@ -864,13 +864,13 @@ update_ip6_routing (NMPolicy *policy, gboolean force_update) if (ip_ifindex <= 0) ip_ifindex = parent_ifindex; - if (!nm_platform_ip6_route_add (ip_ifindex, + 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, + (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, + 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."); @@ -881,13 +881,13 @@ 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, + 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, + (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, + 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 1fe11bdd31..46272217d0 100644 --- a/src/platform/nm-fake-platform.c +++ b/src/platform/nm-fake-platform.c @@ -1039,7 +1039,7 @@ ip6_route_get_all (NMPlatform *platform, int ifindex, gboolean include_default) } static gboolean -ip4_route_add (NMPlatform *platform, int ifindex, +ip4_route_add (NMPlatform *platform, int ifindex, NMPlatformSource source, in_addr_t network, int plen, in_addr_t gateway, int metric, int mss) { @@ -1050,6 +1050,7 @@ ip4_route_add (NMPlatform *platform, int ifindex, 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; @@ -1078,7 +1079,7 @@ ip4_route_add (NMPlatform *platform, int ifindex, } static gboolean -ip6_route_add (NMPlatform *platform, int ifindex, +ip6_route_add (NMPlatform *platform, int ifindex, NMPlatformSource source, struct in6_addr network, int plen, struct in6_addr gateway, int metric, int mss) { @@ -1089,6 +1090,7 @@ ip6_route_add (NMPlatform *platform, int ifindex, 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 5831a6eceb..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,7 @@ clear_host_address (int family, const void *network, int plen, void *dst) } static struct nl_object * -build_rtnl_route (int family, int ifindex, +build_rtnl_route (int family, int ifindex, NMPlatformSource source, gconstpointer network, int plen, gconstpointer gateway, int metric, int mss) { @@ -3341,6 +3378,7 @@ build_rtnl_route (int family, int ifindex, 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); @@ -3355,19 +3393,19 @@ build_rtnl_route (int family, int ifindex, } static gboolean -ip4_route_add (NMPlatform *platform, int ifindex, +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, +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 * @@ -3424,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; @@ -3465,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)); @@ -3487,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 35525cf5d7..463822c7d9 100644 --- a/src/platform/nm-platform.c +++ b/src/platform/nm-platform.c @@ -1711,7 +1711,7 @@ nm_platform_ip6_route_get_all (int ifindex, gboolean include_default) } gboolean -nm_platform_ip4_route_add (int ifindex, +nm_platform_ip4_route_add (int ifindex, NMPlatformSource source, in_addr_t network, int plen, in_addr_t gateway, int metric, int mss) { @@ -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,11 +1736,11 @@ 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, +nm_platform_ip6_route_add (int ifindex, NMPlatformSource source, struct in6_addr network, int plen, struct in6_addr gateway, int metric, int mss) { @@ -1753,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; @@ -1761,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 @@ -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 d6f3fe0ba2..cde551b258 100644 --- a/src/platform/nm-platform.h +++ b/src/platform/nm-platform.h @@ -428,10 +428,10 @@ 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, + 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, + 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); @@ -572,10 +572,10 @@ 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, +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, +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); 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 24bd089cf8..6ad4ba3089 100644 --- a/src/platform/tests/test-route.c +++ b/src/platform/tests/test-route.c @@ -66,35 +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)); + 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)); + 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)); + 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); @@ -161,35 +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)); + 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)); + 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)); + 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); From 9f195559d29f697e6dce40bc99f251c770196325 Mon Sep 17 00:00:00 2001 From: Dan Winship Date: Thu, 8 May 2014 14:56:59 -0400 Subject: [PATCH 4/4] core: look at route sources when assuming a connection When generating an NMConnection to match the current state of a device, don't add its RA-provided and DHCP-provided routes to the NMSettingIP4Config/NMSettingIP6Config, since those routes didn't come from the connection profile before. https://bugzilla.gnome.org/show_bug.cgi?id=729203 --- src/nm-ip4-config.c | 4 ++++ src/nm-ip6-config.c | 4 ++++ 2 files changed, 8 insertions(+) diff --git a/src/nm-ip4-config.c b/src/nm-ip4-config.c index 26a6ead719..6a7904328a 100644 --- a/src/nm-ip4-config.c +++ b/src/nm-ip4-config.c @@ -444,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-ip6-config.c b/src/nm-ip6-config.c index 26b0530630..66fa395352 100644 --- a/src/nm-ip6-config.c +++ b/src/nm-ip6-config.c @@ -551,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);