diff options
author | Thomas Haller <thaller@redhat.com> | 2018-03-21 18:58:42 +0100 |
---|---|---|
committer | Thomas Haller <thaller@redhat.com> | 2018-03-21 18:58:42 +0100 |
commit | 217a7ad55ad4d09f2c195930ba548d46d660ed24 (patch) | |
tree | 8b3b63e353d0d4891e9fad7a80814906fb1114ca | |
parent | c96c374d14be91db7a0ba2307b3d1f35bcd45707 (diff) | |
parent | 1010cc777fc94404ab2b387e85756360fa6b883e (diff) | |
download | NetworkManager-217a7ad55ad4d09f2c195930ba548d46d660ed24.tar.gz |
core: merge branch 'th/ipv6-ll-reapply-rh1552069' (#75)
A larger branch of refactoring and cleanups. This was a spin-off
of pr#75, as the branch grew too large.
https://github.com/NetworkManager/NetworkManager/pull/75
32 files changed, 817 insertions, 1997 deletions
diff --git a/.gitignore b/.gitignore index f0613d6d42..371b93593c 100644 --- a/.gitignore +++ b/.gitignore @@ -266,7 +266,6 @@ test-*.trs /src/tests/test-general-with-expect /src/tests/test-ip4-config /src/tests/test-ip6-config -/src/tests/test-resolvconf-capture /src/tests/test-route-manager-fake /src/tests/test-route-manager-linux /src/tests/test-systemd @@ -313,3 +312,4 @@ test-*.trs /libnm-core/tests/test-setting-bond /libnm-core/tests/test-setting-dcb /src/settings/plugins/ifnet +/src/tests/test-resolvconf-capture diff --git a/Makefile.am b/Makefile.am index bb5b70cd8d..9d5d8e43ce 100644 --- a/Makefile.am +++ b/Makefile.am @@ -1791,10 +1791,6 @@ $(src_dhcp_tests_test_dhcp_utils_OBJECTS): $(libnm_core_lib_h_pub_mkenums) EXTRA_DIST += \ src/dhcp/tests/test-dhclient-duid.leases \ src/dhcp/tests/test-dhclient-commented-duid.leases \ - src/dhcp/tests/leases/basic.leases \ - src/dhcp/tests/leases/malformed1.leases \ - src/dhcp/tests/leases/malformed2.leases \ - src/dhcp/tests/leases/malformed3.leases \ src/dhcp/tests/meson.build ############################################################################### @@ -3101,7 +3097,6 @@ check_programs += \ src/tests/test-ip6-config \ src/tests/test-dcb \ src/tests/test-systemd \ - src/tests/test-resolvconf-capture \ src/tests/test-wired-defname \ src/tests/test-utils @@ -3117,10 +3112,6 @@ src_tests_test_dcb_CPPFLAGS = $(src_tests_cppflags) src_tests_test_dcb_LDFLAGS = $(src_tests_ldflags) src_tests_test_dcb_LDADD = $(src_tests_ldadd) -src_tests_test_resolvconf_capture_CPPFLAGS = $(src_tests_cppflags) -src_tests_test_resolvconf_capture_LDFLAGS = $(src_tests_ldflags) -src_tests_test_resolvconf_capture_LDADD = $(src_tests_ldadd) - src_tests_test_general_CPPFLAGS = $(src_tests_cppflags) src_tests_test_general_LDFLAGS = $(src_tests_ldflags) src_tests_test_general_LDADD = $(src_tests_ldadd) @@ -3140,7 +3131,6 @@ src_tests_test_utils_LDADD = $(src_tests_ldadd) $(src_tests_test_ip4_config_OBJECTS): $(libnm_core_lib_h_pub_mkenums) $(src_tests_test_ip6_config_OBJECTS): $(libnm_core_lib_h_pub_mkenums) $(src_tests_test_dcb_OBJECTS): $(libnm_core_lib_h_pub_mkenums) -$(src_tests_test_resolvconf_capture_OBJECTS): $(libnm_core_lib_h_pub_mkenums) $(src_tests_test_general_OBJECTS): $(libnm_core_lib_h_pub_mkenums) $(src_tests_test_general_with_expect_OBJECTS): $(libnm_core_lib_h_pub_mkenums) $(src_tests_test_wired_defname_OBJECTS): $(libnm_core_lib_h_pub_mkenums) diff --git a/src/devices/nm-device.c b/src/devices/nm-device.c index 6c23a77286..fc7c76b94d 100644 --- a/src/devices/nm-device.c +++ b/src/devices/nm-device.c @@ -234,8 +234,14 @@ typedef struct _NMDevicePrivate { NMDeviceStateReason reason; } queued_state; - guint queued_ip4_config_id; - guint queued_ip6_config_id; + union { + struct { + guint queued_ip_config_id_6; + guint queued_ip_config_id_4; + }; + guint queued_ip_config_id_x[2]; + }; + GSList *pending_actions; GSList *dad6_failed_addrs; @@ -263,6 +269,9 @@ typedef struct _NMDevicePrivate { bool queued_ip4_config_pending:1; bool queued_ip6_config_pending:1; + bool update_ip_config_completed_v4:1; + bool update_ip_config_completed_v6:1; + char * ip_iface; int ip_ifindex; NMDeviceType type; @@ -360,6 +369,11 @@ typedef struct _NMDevicePrivate { NMDeviceAutoconnectBlockedFlags autoconnect_blocked_flags:4; + bool is_enslaved:1; + bool master_ready_handled:1; + + bool ipv6ll_handle:1; /* TRUE if NM handles the device's IPv6LL address */ + /* Generic DHCP stuff */ char * dhcp_anycast_address; @@ -370,17 +384,56 @@ typedef struct _NMDevicePrivate { NMPacrunnerManager *pacrunner_manager; NMPacrunnerCallId *pacrunner_call_id; - /* IP4 configuration info */ - NMIP4Config * ip4_config; /* Combined config from VPN, settings, and device */ + /* IP configuration info. Combined config from VPN, settings, and device */ + union { + struct { + NMIP6Config *ip_config_6; + NMIP4Config *ip_config_4; + }; + NMIPConfig *ip_config_x[2]; + }; + union { const IpState ip4_state; IpState ip4_state_; }; - NMIP4Config * con_ip4_config; /* config from the setting */ AppliedConfig dev_ip4_config; /* Config from DHCP, PPP, LLv4, etc */ - AppliedConfig wwan_ip4_config; /* WWAN configuration */ - NMIP4Config * ext_ip4_config; /* Stuff added outside NM */ - GSList * vpn4_configs; /* VPNs which use this device */ + + /* config from the setting */ + union { + struct { + NMIP6Config *con_ip_config_6; + NMIP4Config *con_ip_config_4; + }; + NMIPConfig *con_ip_config_x[2]; + }; + + /* Stuff added outside NM */ + union { + struct { + NMIP6Config *ext_ip_config_6; + NMIP4Config *ext_ip_config_4; + }; + NMIPConfig *ext_ip_config_x[2]; + }; + + /* VPNs which use this device */ + union { + struct { + GSList *vpn_configs_6; + GSList *vpn_configs_4; + }; + GSList *vpn_configs_x[2]; + }; + + /* WWAN configuration */ + union { + struct { + AppliedConfig wwan_ip_config_6; + AppliedConfig wwan_ip_config_4; + }; + AppliedConfig wwan_ip_config_x[2]; + }; bool v4_has_shadowed_routes; const char *ip4_rp_filter; @@ -425,19 +478,12 @@ typedef struct _NMDevicePrivate { NMArpingManager * announcing; } arping; - /* IP6 configuration info */ - NMIP6Config * ip6_config; union { const IpState ip6_state; IpState ip6_state_; }; - NMIP6Config * con_ip6_config; /* config from the setting */ - AppliedConfig wwan_ip6_config; AppliedConfig ac_ip6_config; /* config from IPv6 autoconfiguration */ - NMIP6Config * ext_ip6_config; /* Stuff added outside NM */ NMIP6Config * ext_ip6_config_captured; /* Configuration captured from platform. */ - GSList * vpn6_configs; /* VPNs which use this device */ - bool nm_ipv6ll; /* TRUE if NM handles the device's IPv6LL address */ NMIP6Config * dad6_ip6_config; GHashTable * rt6_temporary_not_available; @@ -471,8 +517,6 @@ typedef struct _NMDevicePrivate { /* master interface for bridge/bond/team slave */ NMDevice * master; - bool is_enslaved; - bool master_ready_handled; gulong master_ready_id; /* slave management */ @@ -511,27 +555,24 @@ static const GDBusSignalInfo signal_info_state_changed; static void nm_device_set_proxy_config (NMDevice *self, const char *pac_url); -static gboolean update_ext_ip_config (NMDevice *self, int addr_family, gboolean initial, gboolean intersect_configs); +static gboolean update_ext_ip_config (NMDevice *self, int addr_family, gboolean intersect_configs); -static gboolean nm_device_set_ip4_config (NMDevice *self, - NMIP4Config *config, - gboolean commit, - GPtrArray *ip4_dev_route_blacklist); -static gboolean ip4_config_merge_and_apply (NMDevice *self, - gboolean commit); +static gboolean nm_device_set_ip_config (NMDevice *self, + int addr_family, + NMIPConfig *config, + gboolean commit, + GPtrArray *ip4_dev_route_blacklist); -static gboolean nm_device_set_ip6_config (NMDevice *self, - NMIP6Config *config, - gboolean commit); -static gboolean ip6_config_merge_and_apply (NMDevice *self, - gboolean commit); +static gboolean ip_config_merge_and_apply (NMDevice *self, + int addr_family, + gboolean commit); static gboolean nm_device_master_add_slave (NMDevice *self, NMDevice *slave, gboolean configure); static void nm_device_slave_notify_enslave (NMDevice *self, gboolean success); static void nm_device_slave_notify_release (NMDevice *self, NMDeviceStateReason reason); -static gboolean addrconf6_start_with_link_ready (NMDevice *self); -static NMActStageReturn linklocal6_start (NMDevice *self); +static void addrconf6_start_with_link_ready (NMDevice *self); +static gboolean linklocal6_start (NMDevice *self); static void _carrier_wait_check_queued_act_request (NMDevice *self); static gint64 _get_carrier_wait_ms (NMDevice *self); @@ -927,29 +968,18 @@ nm_device_assume_state_reset (NMDevice *self) /*****************************************************************************/ static void -init_ip4_config_dns_priority (NMDevice *self, NMIP4Config *config) -{ - gs_free char *value = NULL; - gint priority; - - value = nm_config_data_get_connection_default (NM_CONFIG_GET_DATA, - "ipv4.dns-priority", - self); - priority = _nm_utils_ascii_str_to_int64 (value, 10, G_MININT, G_MAXINT, 0); - nm_ip4_config_set_dns_priority (config, priority ?: NM_DNS_PRIORITY_DEFAULT_NORMAL); -} - -static void -init_ip6_config_dns_priority (NMDevice *self, NMIP6Config *config) +init_ip_config_dns_priority (NMDevice *self, NMIPConfig *config) { gs_free char *value = NULL; gint priority; value = nm_config_data_get_connection_default (NM_CONFIG_GET_DATA, - "ipv6.dns-priority", + (nm_ip_config_get_addr_family (config) == AF_INET) + ? "ipv4.dns-priority" + : "ipv6.dns-priority", self); priority = _nm_utils_ascii_str_to_int64 (value, 10, G_MININT, G_MAXINT, 0); - nm_ip6_config_set_dns_priority (config, priority ?: NM_DNS_PRIORITY_DEFAULT_NORMAL); + nm_ip_config_set_dns_priority (config, priority ?: NM_DNS_PRIORITY_DEFAULT_NORMAL); } /*****************************************************************************/ @@ -2010,12 +2040,12 @@ nm_device_get_best_default_route (NMDevice *self, switch (addr_family) { case AF_INET: - return priv->ip4_config ? nm_ip4_config_best_default_route_get (priv->ip4_config) : NULL; + return priv->ip_config_4 ? nm_ip4_config_best_default_route_get (priv->ip_config_4) : NULL; case AF_INET6: - return priv->ip6_config ? nm_ip6_config_best_default_route_get (priv->ip6_config) : NULL; + return priv->ip_config_6 ? nm_ip6_config_best_default_route_get (priv->ip_config_6) : NULL; case AF_UNSPEC: - return (priv->ip4_config ? nm_ip4_config_best_default_route_get (priv->ip4_config) : NULL) - ?: (priv->ip6_config ? nm_ip6_config_best_default_route_get (priv->ip6_config) : NULL); + return (priv->ip_config_4 ? nm_ip4_config_best_default_route_get (priv->ip_config_4) : NULL) + ?: (priv->ip_config_6 ? nm_ip6_config_best_default_route_get (priv->ip_config_6) : NULL); default: g_return_val_if_reached (NULL); } @@ -2161,10 +2191,10 @@ update_connectivity_state (NMDevice *self, NMConnectivityState state) if ( priv->state == NM_DEVICE_STATE_ACTIVATED && !nm_device_sys_iface_state_is_external (self)) { if ( nm_device_get_best_default_route (self, AF_INET) - && !ip4_config_merge_and_apply (self, TRUE)) + && !ip_config_merge_and_apply (self, AF_INET, TRUE)) _LOGW (LOGD_IP4, "Failed to update IPv4 route metric"); if ( nm_device_get_best_default_route (self, AF_INET6) - && !ip6_config_merge_and_apply (self, TRUE)) + && !ip_config_merge_and_apply (self, AF_INET6, TRUE)) _LOGW (LOGD_IP6, "Failed to update IPv6 route metric"); } } @@ -2377,7 +2407,7 @@ nm_device_master_enslave_slave (NMDevice *self, NMDevice *slave, NMConnection *c /* Since slave devices don't have their own IP configuration, * set the MTU here. */ - _commit_mtu (slave, NM_DEVICE_GET_PRIVATE (slave)->ip4_config); + _commit_mtu (slave, NM_DEVICE_GET_PRIVATE (slave)->ip_config_4); return success; } @@ -2783,7 +2813,7 @@ ndisc_set_router_config (NMNDisc *ndisc, NMDevice *self) now = nm_utils_get_monotonic_timestamp_s (); - head_entry = nm_ip6_config_lookup_addresses (priv->ip6_config); + head_entry = nm_ip6_config_lookup_addresses (priv->ip_config_6); addresses = g_array_sized_new (FALSE, TRUE, sizeof (NMNDiscAddress), head_entry ? head_entry->len : 0); nm_dedup_multi_iter_for_each (&ipconf_iter, head_entry) { @@ -2826,11 +2856,11 @@ ndisc_set_router_config (NMNDisc *ndisc, NMDevice *self) ndisc_addr->preferred = preferred; } - len = nm_ip6_config_get_num_nameservers (priv->ip6_config); + len = nm_ip6_config_get_num_nameservers (priv->ip_config_6); dns_servers = g_array_sized_new (FALSE, TRUE, sizeof (NMNDiscDNSServer), len); g_array_set_size (dns_servers, len); for (i = 0; i < len; i++) { - const struct in6_addr *nameserver = nm_ip6_config_get_nameserver (priv->ip6_config, i); + const struct in6_addr *nameserver = nm_ip6_config_get_nameserver (priv->ip_config_6, i); NMNDiscDNSServer *ndisc_nameserver; ndisc_nameserver = &g_array_index (dns_servers, NMNDiscDNSServer, i); @@ -2839,11 +2869,11 @@ ndisc_set_router_config (NMNDisc *ndisc, NMDevice *self) ndisc_nameserver->lifetime = NM_NDISC_ROUTER_LIFETIME; } - len = nm_ip6_config_get_num_searches (priv->ip6_config); + len = nm_ip6_config_get_num_searches (priv->ip_config_6); dns_domains = g_array_sized_new (FALSE, TRUE, sizeof (NMNDiscDNSDomain), len); g_array_set_size (dns_domains, len); for (i = 0; i < len; i++) { - const char *search = nm_ip6_config_get_search (priv->ip6_config, i); + const char *search = nm_ip6_config_get_search (priv->ip_config_6, i); NMNDiscDNSDomain *ndisc_search; ndisc_search = &g_array_index (dns_domains, NMNDiscDNSDomain, i); @@ -2969,11 +2999,11 @@ device_link_changed (NMDevice *self) /* the link was down and just came up. That happens for example, while changing MTU. * We must restore IP configuration. */ if (priv->ip4_state == IP_DONE) { - if (!ip4_config_merge_and_apply (self, TRUE)) + if (!ip_config_merge_and_apply (self, AF_INET, TRUE)) _LOGW (LOGD_IP4, "failed applying IP4 config after link comes up again"); } if (priv->ip6_state == IP_DONE) { - if (!ip6_config_merge_and_apply (self, TRUE)) + if (!ip_config_merge_and_apply (self, AF_INET6, TRUE)) _LOGW (LOGD_IP6, "failed applying IP6 config after link comes up again"); } } @@ -3477,8 +3507,8 @@ realize_start_setup (NMDevice *self, g_return_if_fail (nm_device_get_unmanaged_flags (self, NM_UNMANAGED_PLATFORM_INIT)); g_return_if_fail (priv->ip_ifindex <= 0); g_return_if_fail (priv->ip_iface == NULL); - g_return_if_fail (!priv->queued_ip4_config_id); - g_return_if_fail (!priv->queued_ip6_config_id); + g_return_if_fail (!priv->queued_ip_config_id_4); + g_return_if_fail (!priv->queued_ip_config_id_6); _LOGD (LOGD_DEVICE, "start setup of %s, kernel ifindex %d", G_OBJECT_TYPE_NAME (self), plink ? plink->ifindex : 0); @@ -3525,7 +3555,7 @@ realize_start_setup (NMDevice *self, if (nm_platform_check_kernel_support (nm_device_get_platform (self), NM_PLATFORM_KERNEL_SUPPORT_USER_IPV6LL)) - priv->nm_ipv6ll = nm_platform_link_get_user_ipv6ll_enabled (nm_device_get_platform (self), priv->ifindex); + priv->ipv6ll_handle = nm_platform_link_get_user_ipv6ll_enabled (nm_device_get_platform (self), priv->ifindex); if (nm_platform_link_supports_sriov (nm_device_get_platform (self), priv->ifindex)) capabilities |= NM_DEVICE_CAP_SRIOV; @@ -3624,6 +3654,9 @@ nm_device_realize_finish (NMDevice *self, const NMPlatformLink *plink) if (plink) device_recheck_slave_status (self, plink); + priv->update_ip_config_completed_v4 = FALSE; + priv->update_ip_config_completed_v6 = FALSE; + priv->real = TRUE; _notify (self, PROP_REAL); @@ -4327,8 +4360,8 @@ nm_device_removed (NMDevice *self, gboolean unconfigure_ip_config) if (!unconfigure_ip_config) return; - nm_device_set_ip4_config (self, NULL, FALSE, NULL); - nm_device_set_ip6_config (self, NULL, FALSE); + nm_device_set_ip_config (self, AF_INET, NULL, FALSE, NULL); + nm_device_set_ip_config (self, AF_INET6, NULL, FALSE, NULL); } static gboolean @@ -4580,9 +4613,9 @@ device_has_config (NMDevice *self) NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); /* Check for IP configuration. */ - if (priv->ip4_config && nm_ip4_config_get_num_addresses (priv->ip4_config)) + if (priv->ip_config_4 && nm_ip4_config_get_num_addresses (priv->ip_config_4)) return TRUE; - if (priv->ip6_config && nm_ip6_config_get_num_addresses (priv->ip6_config)) + if (priv->ip_config_6 && nm_ip6_config_get_num_addresses (priv->ip_config_6)) return TRUE; /* The existence of a software device is good enough. */ @@ -4707,10 +4740,10 @@ nm_device_generate_connection (NMDevice *self, } } else { /* Only regular and master devices get IP configuration; slaves do not */ - s_ip4 = nm_ip4_config_create_setting (priv->ip4_config); + s_ip4 = nm_ip4_config_create_setting (priv->ip_config_4); nm_connection_add_setting (connection, s_ip4); - s_ip6 = nm_ip6_config_create_setting (priv->ip6_config); + s_ip6 = nm_ip6_config_create_setting (priv->ip_config_6); nm_connection_add_setting (connection, s_ip6); nm_connection_add_setting (connection, nm_setting_proxy_new ()); @@ -5900,7 +5933,7 @@ nm_device_handle_ipv4ll_event (sd_ipv4ll *ll, int event, void *data) nm_device_activate_schedule_ip4_config_result (self, config); } else if (priv->ip4_state == IP_DONE) { applied_config_init (&priv->dev_ip4_config, config); - if (!ip4_config_merge_and_apply (self, TRUE)) { + if (!ip_config_merge_and_apply (self, AF_INET, TRUE)) { _LOGE (LOGD_AUTOIP4, "failed to update IP4 config for autoip change."); nm_device_ip_method_failed (self, AF_INET, NM_DEVICE_STATE_REASON_AUTOIP_FAILED); } @@ -5996,56 +6029,42 @@ ipv4ll_start (NMDevice *self) /*****************************************************************************/ static void -ensure_con_ip4_config (NMDevice *self) +ensure_con_ip_config (NMDevice *self, int addr_family) { NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); NMConnection *connection; + const gboolean IS_IPv4 = (addr_family == AF_INET); + NMIPConfig *con_ip_config; - if (priv->con_ip4_config) + if (priv->con_ip_config_x[IS_IPv4]) return; connection = nm_device_get_applied_connection (self); if (!connection) return; - priv->con_ip4_config = _ip4_config_new (self); - nm_ip4_config_merge_setting (priv->con_ip4_config, - nm_connection_get_setting_ip4_config (connection), - _get_mdns (self), - nm_device_get_route_table (self, AF_INET, TRUE), - nm_device_get_route_metric (self, AF_INET)); + con_ip_config = _ip_config_new (self, addr_family); - if (nm_device_sys_iface_state_is_external_or_assume (self)) { - /* For assumed connections ignore all addresses and routes. */ - nm_ip4_config_reset_addresses (priv->con_ip4_config); - nm_ip4_config_reset_routes (priv->con_ip4_config); + if (IS_IPv4) { + nm_ip4_config_merge_setting (NM_IP4_CONFIG (con_ip_config), + nm_connection_get_setting_ip4_config (connection), + _get_mdns (self), + nm_device_get_route_table (self, addr_family, TRUE), + nm_device_get_route_metric (self, addr_family)); + } else { + nm_ip6_config_merge_setting (NM_IP6_CONFIG (con_ip_config), + nm_connection_get_setting_ip6_config (connection), + nm_device_get_route_table (self, addr_family, TRUE), + nm_device_get_route_metric (self, addr_family)); } -} - -static void -ensure_con_ip6_config (NMDevice *self) -{ - NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); - NMConnection *connection; - - if (priv->con_ip6_config) - return; - - connection = nm_device_get_applied_connection (self); - if (!connection) - return; - - priv->con_ip6_config = _ip6_config_new (self); - nm_ip6_config_merge_setting (priv->con_ip6_config, - nm_connection_get_setting_ip6_config (connection), - nm_device_get_route_table (self, AF_INET6, TRUE), - nm_device_get_route_metric (self, AF_INET6)); if (nm_device_sys_iface_state_is_external_or_assume (self)) { /* For assumed connections ignore all addresses and routes. */ - nm_ip6_config_reset_addresses (priv->con_ip6_config); - nm_ip6_config_reset_routes (priv->con_ip6_config); + nm_ip_config_reset_addresses (con_ip_config); + nm_ip_config_reset_routes (con_ip_config); } + + priv->con_ip_config_x[IS_IPv4] = con_ip_config; } /*****************************************************************************/ @@ -6079,101 +6098,194 @@ dhcp4_cleanup (NMDevice *self, CleanupType cleanup_type, gboolean release) } static gboolean -ip4_config_merge_and_apply (NMDevice *self, - gboolean commit) +ip_config_merge_and_apply (NMDevice *self, + int addr_family, + gboolean commit) { NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); - NMConnection *connection; gboolean success; - NMIP4Config *composite, *config; + gs_unref_object NMIPConfig *composite = NULL; + NMIPConfig *config; + gs_unref_ptrarray GPtrArray *ip4_dev_route_blacklist = NULL; + NMConnection *connection; gboolean ignore_auto_routes = FALSE; gboolean ignore_auto_dns = FALSE; gboolean ignore_default_routes = FALSE; GSList *iter; - gs_unref_ptrarray GPtrArray *ip4_dev_route_blacklist = NULL; + const char *ip6_addr_gen_token = NULL; + const gboolean IS_IPv4 = (addr_family == AF_INET); if (nm_device_sys_iface_state_is_external (self)) - commit = 0; + commit = FALSE; - /* Apply ignore-auto-routes and ignore-auto-dns settings */ connection = nm_device_get_applied_connection (self); + + /* Apply ignore-auto-routes and ignore-auto-dns settings */ if (connection) { - NMSettingIPConfig *s_ip4 = nm_connection_get_setting_ip4_config (connection); + NMSettingIPConfig *s_ip = IS_IPv4 + ? nm_connection_get_setting_ip4_config (connection) + : nm_connection_get_setting_ip6_config (connection); - if (s_ip4) { - ignore_auto_routes = nm_setting_ip_config_get_ignore_auto_routes (s_ip4); - ignore_auto_dns = nm_setting_ip_config_get_ignore_auto_dns (s_ip4); + if (s_ip) { + ignore_auto_routes = nm_setting_ip_config_get_ignore_auto_routes (s_ip); + ignore_auto_dns = nm_setting_ip_config_get_ignore_auto_dns (s_ip); /* if the connection has an explicit gateway, we also ignore * the default routes from other sources. */ - ignore_default_routes = nm_setting_ip_config_get_never_default (s_ip4) - || nm_setting_ip_config_get_gateway (s_ip4); + ignore_default_routes = nm_setting_ip_config_get_never_default (s_ip) + || nm_setting_ip_config_get_gateway (s_ip); + + if (!IS_IPv4) { + NMSettingIP6Config *s_ip6 = NM_SETTING_IP6_CONFIG (s_ip); + + if (nm_setting_ip6_config_get_addr_gen_mode (s_ip6) == NM_SETTING_IP6_CONFIG_ADDR_GEN_MODE_EUI64) + ip6_addr_gen_token = nm_setting_ip6_config_get_token (s_ip6); + } } } - composite = _ip4_config_new (self); - init_ip4_config_dns_priority (self, composite); + composite = _ip_config_new (self, addr_family); + + if (!IS_IPv4) { + nm_ip6_config_set_privacy (NM_IP6_CONFIG (composite), + priv->ndisc + ? priv->ndisc_use_tempaddr + : NM_SETTING_IP6_CONFIG_PRIVACY_UNKNOWN); + } + + init_ip_config_dns_priority (self, composite); if (commit) { - if (priv->queued_ip4_config_id) - update_ext_ip_config (self, AF_INET, FALSE, FALSE); - ensure_con_ip4_config (self); + if (priv->queued_ip_config_id_x[IS_IPv4]) + update_ext_ip_config (self, addr_family, FALSE); + ensure_con_ip_config (self, addr_family); } - if (commit) - priv->default_route_metric_penalty_ip4_has = default_route_metric_penalty_detect (self); + if (commit) { + gboolean v; - config = (NMIP4Config *) applied_config_get_current (&priv->dev_ip4_config); - if (config) { - nm_ip4_config_merge (composite, config, - (ignore_auto_routes ? NM_IP_CONFIG_MERGE_NO_ROUTES : 0) - | (ignore_default_routes ? NM_IP_CONFIG_MERGE_NO_DEFAULT_ROUTES : 0) - | (ignore_auto_dns ? NM_IP_CONFIG_MERGE_NO_DNS : 0), - default_route_metric_penalty_get (self, AF_INET)); + v = default_route_metric_penalty_detect (self); + if (IS_IPv4) + priv->default_route_metric_penalty_ip4_has = v; + else + priv->default_route_metric_penalty_ip6_has = v; + } + + /* Merge all the IP configs into the composite config */ + + if (IS_IPv4) { + config = applied_config_get_current (&priv->dev_ip4_config); + if (config) { + nm_ip4_config_merge (NM_IP4_CONFIG (composite), NM_IP4_CONFIG (config), + (ignore_auto_routes ? NM_IP_CONFIG_MERGE_NO_ROUTES : 0) + | (ignore_default_routes ? NM_IP_CONFIG_MERGE_NO_DEFAULT_ROUTES : 0) + | (ignore_auto_dns ? NM_IP_CONFIG_MERGE_NO_DNS : 0), + default_route_metric_penalty_get (self, addr_family)); + } + } + + if (!IS_IPv4) { + config = applied_config_get_current (&priv->ac_ip6_config); + if (config) { + nm_ip6_config_merge (NM_IP6_CONFIG (composite), NM_IP6_CONFIG (config), + (ignore_auto_routes ? NM_IP_CONFIG_MERGE_NO_ROUTES : 0) + | (ignore_default_routes ? NM_IP_CONFIG_MERGE_NO_DEFAULT_ROUTES : 0) + | (ignore_auto_dns ? NM_IP_CONFIG_MERGE_NO_DNS : 0), + default_route_metric_penalty_get (self, addr_family)); + } } - for (iter = priv->vpn4_configs; iter; iter = iter->next) - nm_ip4_config_merge (composite, iter->data, NM_IP_CONFIG_MERGE_DEFAULT, 0); + if (!IS_IPv4) { + config = applied_config_get_current (&priv->dhcp6.ip6_config); + if (config) { + nm_ip6_config_merge (NM_IP6_CONFIG (composite), NM_IP6_CONFIG (config), + (ignore_auto_routes ? NM_IP_CONFIG_MERGE_NO_ROUTES : 0) + | (ignore_default_routes ? NM_IP_CONFIG_MERGE_NO_DEFAULT_ROUTES : 0) + | (ignore_auto_dns ? NM_IP_CONFIG_MERGE_NO_DNS : 0), + default_route_metric_penalty_get (self, addr_family)); + } + } - if (priv->ext_ip4_config) - nm_ip4_config_merge (composite, priv->ext_ip4_config, NM_IP_CONFIG_MERGE_DEFAULT, 0); + for (iter = priv->vpn_configs_x[IS_IPv4]; iter; iter = iter->next) + nm_ip_config_merge (composite, iter->data, NM_IP_CONFIG_MERGE_DEFAULT, 0); + + if (priv->ext_ip_config_x[IS_IPv4]) + nm_ip_config_merge (composite, priv->ext_ip_config_x[IS_IPv4], NM_IP_CONFIG_MERGE_DEFAULT, 0); /* Merge WWAN config *last* to ensure modem-given settings overwrite * any external stuff set by pppd or other scripts. */ - config = (NMIP4Config *) applied_config_get_current (&priv->wwan_ip4_config); + config = applied_config_get_current (&priv->wwan_ip_config_x[IS_IPv4]); if (config) { - nm_ip4_config_merge (composite, config, - (ignore_auto_routes ? NM_IP_CONFIG_MERGE_NO_ROUTES : 0) - | (ignore_default_routes ? NM_IP_CONFIG_MERGE_NO_DEFAULT_ROUTES : 0) - | (ignore_auto_dns ? NM_IP_CONFIG_MERGE_NO_DNS : 0), - default_route_metric_penalty_get (self, AF_INET)); + nm_ip_config_merge (composite, config, + (ignore_auto_routes ? NM_IP_CONFIG_MERGE_NO_ROUTES : 0) + | (ignore_default_routes ? NM_IP_CONFIG_MERGE_NO_DEFAULT_ROUTES : 0) + | (ignore_auto_dns ? NM_IP_CONFIG_MERGE_NO_DNS : 0), + default_route_metric_penalty_get (self, addr_family)); + } + + if (!IS_IPv4) { + if (priv->rt6_temporary_not_available) { + const NMPObject *o; + GHashTableIter hiter; + + g_hash_table_iter_init (&hiter, priv->rt6_temporary_not_available); + while (g_hash_table_iter_next (&hiter, (gpointer *) &o, NULL)) { + nm_ip6_config_add_route (NM_IP6_CONFIG (composite), + NMP_OBJECT_CAST_IP6_ROUTE (o), + NULL); + } + } } /* Merge user overrides into the composite config. For assumed connections, - * con_ip4_config is empty. */ - if (priv->con_ip4_config) { - nm_ip4_config_merge (composite, priv->con_ip4_config, NM_IP_CONFIG_MERGE_DEFAULT, - default_route_metric_penalty_get (self, AF_INET)); + * con_ip_config_x is empty. */ + if (priv->con_ip_config_x[IS_IPv4]) { + nm_ip_config_merge (composite, priv->con_ip_config_x[IS_IPv4], NM_IP_CONFIG_MERGE_DEFAULT, + default_route_metric_penalty_get (self, addr_family)); } if (commit) { - nm_ip4_config_add_dependent_routes (composite, - nm_device_get_route_table (self, AF_INET, TRUE), - nm_device_get_route_metric (self, AF_INET), - &ip4_dev_route_blacklist); + if (IS_IPv4) { + nm_ip4_config_add_dependent_routes (NM_IP4_CONFIG (composite), + nm_device_get_route_table (self, addr_family, TRUE), + nm_device_get_route_metric (self, addr_family), + &ip4_dev_route_blacklist); + } else { + nm_ip6_config_add_dependent_routes (NM_IP6_CONFIG (composite), + nm_device_get_route_table (self, addr_family, TRUE), + nm_device_get_route_metric (self, addr_family)); + } } - if (commit) { - if (NM_DEVICE_GET_CLASS (self)->ip4_config_pre_commit) - NM_DEVICE_GET_CLASS (self)->ip4_config_pre_commit (self, composite); + if (IS_IPv4) { + if (commit) { + if (NM_DEVICE_GET_CLASS (self)->ip4_config_pre_commit) + NM_DEVICE_GET_CLASS (self)->ip4_config_pre_commit (self, NM_IP4_CONFIG (composite)); + } + } + + if (!IS_IPv4) { + if (commit) { + NMUtilsIPv6IfaceId iid; + + if ( ip6_addr_gen_token + && nm_utils_ipv6_interface_identifier_get_from_token (&iid, ip6_addr_gen_token)) { + nm_platform_link_set_ipv6_token (nm_device_get_platform (self), + nm_device_get_ip_ifindex (self), + iid); + } + } } - success = nm_device_set_ip4_config (self, composite, commit, ip4_dev_route_blacklist); - g_object_unref (composite); + success = nm_device_set_ip_config (self, addr_family, composite, commit, ip4_dev_route_blacklist); + if (commit) { + if (IS_IPv4) + priv->v4_commit_first_time = FALSE; + else + priv->v6_commit_first_time = FALSE; + } - if (commit) - priv->v4_commit_first_time = FALSE; return success; } @@ -6186,7 +6298,7 @@ dhcp4_lease_change (NMDevice *self, NMIP4Config *config) applied_config_init (&priv->dev_ip4_config, config); - if (!ip4_config_merge_and_apply (self, TRUE)) { + if (!ip_config_merge_and_apply (self, AF_INET, TRUE)) { _LOGW (LOGD_DHCP4, "failed to update IPv4 config for DHCP change."); return FALSE; } @@ -6226,8 +6338,8 @@ dhcp4_fail (NMDevice *self, gboolean timeout) * on the interface. */ if ( priv->ip4_state == IP_DONE - && priv->con_ip4_config - && nm_ip4_config_get_num_addresses (priv->con_ip4_config) > 0) + && priv->con_ip_config_4 + && nm_ip4_config_get_num_addresses (priv->con_ip_config_4) > 0) goto clear_config; /* Fail the method in case of timeout or failure during initial @@ -6844,140 +6956,6 @@ dhcp6_cleanup (NMDevice *self, CleanupType cleanup_type, gboolean release) } static gboolean -ip6_config_merge_and_apply (NMDevice *self, - gboolean commit) -{ - NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); - NMConnection *connection; - gboolean success; - NMIP6Config *composite, *config; - gboolean ignore_auto_routes = FALSE; - gboolean ignore_auto_dns = FALSE; - gboolean ignore_default_routes = FALSE; - const char *token = NULL; - GSList *iter; - - if (nm_device_sys_iface_state_is_external (self)) - commit = 0; - - /* Apply ignore-auto-routes and ignore-auto-dns settings */ - connection = nm_device_get_applied_connection (self); - if (connection) { - NMSettingIPConfig *s_ip6 = nm_connection_get_setting_ip6_config (connection); - - if (s_ip6) { - NMSettingIP6Config *ip6 = NM_SETTING_IP6_CONFIG (s_ip6); - - ignore_auto_routes = nm_setting_ip_config_get_ignore_auto_routes (s_ip6); - ignore_auto_dns = nm_setting_ip_config_get_ignore_auto_dns (s_ip6); - - /* if the connection has an explicit gateway, we also ignore - * the default routes from other sources. */ - ignore_default_routes = nm_setting_ip_config_get_never_default (s_ip6) - || nm_setting_ip_config_get_gateway (s_ip6); - - if (nm_setting_ip6_config_get_addr_gen_mode (ip6) == NM_SETTING_IP6_CONFIG_ADDR_GEN_MODE_EUI64) - token = nm_setting_ip6_config_get_token (ip6); - } - } - - composite = _ip6_config_new (self); - nm_ip6_config_set_privacy (composite, - priv->ndisc ? - priv->ndisc_use_tempaddr : - NM_SETTING_IP6_CONFIG_PRIVACY_UNKNOWN); - init_ip6_config_dns_priority (self, composite); - - if (commit) { - if (priv->queued_ip6_config_id) - update_ext_ip_config (self, AF_INET6, FALSE, FALSE); - ensure_con_ip6_config (self); - } - - if (commit) - priv->default_route_metric_penalty_ip6_has = default_route_metric_penalty_detect (self); - - /* Merge all the IP configs into the composite config */ - config = (NMIP6Config *) applied_config_get_current (&priv->ac_ip6_config); - if (config) { - nm_ip6_config_merge (composite, config, - (ignore_auto_routes ? NM_IP_CONFIG_MERGE_NO_ROUTES : 0) - | (ignore_default_routes ? NM_IP_CONFIG_MERGE_NO_DEFAULT_ROUTES : 0) - | (ignore_auto_dns ? NM_IP_CONFIG_MERGE_NO_DNS : 0), - default_route_metric_penalty_get (self, AF_INET6)); - } - - config = (NMIP6Config *) applied_config_get_current (&priv->dhcp6.ip6_config); - if (config) { - nm_ip6_config_merge (composite, config, - (ignore_auto_routes ? NM_IP_CONFIG_MERGE_NO_ROUTES : 0) - | (ignore_default_routes ? NM_IP_CONFIG_MERGE_NO_DEFAULT_ROUTES : 0) - | (ignore_auto_dns ? NM_IP_CONFIG_MERGE_NO_DNS : 0), - default_route_metric_penalty_get (self, AF_INET6)); - } - - for (iter = priv->vpn6_configs; iter; iter = iter->next) - nm_ip6_config_merge (composite, iter->data, NM_IP_CONFIG_MERGE_DEFAULT, 0); - - if (priv->ext_ip6_config) - nm_ip6_config_merge (composite, priv->ext_ip6_config, NM_IP_CONFIG_MERGE_DEFAULT, 0); - - /* Merge WWAN config *last* to ensure modem-given settings overwrite - * any external stuff set by pppd or other scripts. - */ - config = (NMIP6Config *) applied_config_get_current (&priv->wwan_ip6_config); - if (config) { - nm_ip6_config_merge (composite, config, - (ignore_auto_routes ? NM_IP_CONFIG_MERGE_NO_ROUTES : 0) - | (ignore_default_routes ? NM_IP_CONFIG_MERGE_NO_DEFAULT_ROUTES : 0) - | (ignore_auto_dns ? NM_IP_CONFIG_MERGE_NO_DNS : 0), - default_route_metric_penalty_get (self, AF_INET6)); - } - - if (priv->rt6_temporary_not_available) { - const NMPObject *o; - GHashTableIter hiter; - - g_hash_table_iter_init (&hiter, priv->rt6_temporary_not_available); - while (g_hash_table_iter_next (&hiter, (gpointer *) &o, NULL)) { - nm_ip6_config_add_route (composite, - NMP_OBJECT_CAST_IP6_ROUTE (o), - NULL); - } - } - - /* Merge user overrides into the composite config. For assumed connections, - * con_ip6_config is empty. */ - if (priv->con_ip6_config) { - nm_ip6_config_merge (composite, priv->con_ip6_config, NM_IP_CONFIG_MERGE_DEFAULT, - default_route_metric_penalty_get (self, AF_INET6)); - } - - if (commit) { - nm_ip6_config_add_dependent_routes (composite, - nm_device_get_route_table (self, AF_INET6, TRUE), - nm_device_get_route_metric (self, AF_INET6)); - } - - /* Allow setting MTU etc */ - if (commit) { - NMUtilsIPv6IfaceId iid; - - if (token && nm_utils_ipv6_interface_identifier_get_from_token (&iid, token)) { - nm_platform_link_set_ipv6_token (nm_device_get_platform (self), - nm_device_get_ip_ifindex (self), - iid); - } - } - - success = nm_device_set_ip6_config (self, composite, commit); - g_object_unref (composite); - if (commit) - priv->v6_commit_first_time = FALSE; - return success; -} - -static gboolean dhcp6_lease_change (NMDevice *self) { NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); @@ -6994,7 +6972,7 @@ dhcp6_lease_change (NMDevice *self) g_assert (settings_connection); /* Apply the updated config */ - if (!ip6_config_merge_and_apply (self, TRUE)) { + if (!ip_config_merge_and_apply (self, AF_INET6, TRUE)) { _LOGW (LOGD_DHCP6, "failed to update IPv6 config in response to DHCP event"); return FALSE; } @@ -7038,8 +7016,8 @@ dhcp6_fail (NMDevice *self, gboolean timeout) * on the interface. */ if ( priv->ip6_state == IP_DONE - && priv->con_ip6_config - && nm_ip6_config_get_num_addresses (priv->con_ip6_config)) + && priv->con_ip_config_6 + && nm_ip6_config_get_num_addresses (priv->con_ip_config_6)) goto clear_config; /* Fail the method in case of timeout or failure during initial @@ -7205,8 +7183,11 @@ dhcp6_start_with_link_ready (NMDevice *self, NMConnection *connection) s_ip6 = nm_connection_get_setting_ip6_config (connection); g_assert (s_ip6); - if (priv->ext_ip6_config_captured) - ll_addr = nm_ip6_config_get_address_first_nontentative (priv->ext_ip6_config_captured, TRUE); + if (priv->ext_ip6_config_captured) { + ll_addr = nm_ip6_config_find_first_address (priv->ext_ip6_config_captured, + NM_PLATFORM_MATCH_WITH_ADDRTYPE_LINKLOCAL + | NM_PLATFORM_MATCH_WITH_ADDRSTATE_NORMAL); + } if (!ll_addr) { _LOGW (LOGD_DHCP6, "can't start DHCPv6: no link-local address"); @@ -7272,17 +7253,12 @@ dhcp6_start (NMDevice *self, gboolean wait_for_ll) nm_device_add_pending_action (self, NM_PENDING_ACTION_DHCP6, TRUE); if (wait_for_ll) { - NMActStageReturn ret; - /* ensure link local is ready... */ - ret = linklocal6_start (self); - if (ret == NM_ACT_STAGE_RETURN_POSTPONE) { - /* success; wait for the LL address to show up */ + if (!linklocal6_start (self)) { + /* wait for the LL address to show up */ return TRUE; } - - /* success; already have the LL address; kick off DHCP */ - g_assert (ret == NM_ACT_STAGE_RETURN_SUCCESS); + /* already have the LL address; kick off DHCP */ } if (!dhcp6_start_with_link_ready (self, connection)) @@ -7356,7 +7332,7 @@ nm_device_use_ip6_subnet (NMDevice *self, const NMPlatformIP6Address *subnet) subnet->preferred); /* This also updates the ndisc if there are actual changes. */ - if (!ip6_config_merge_and_apply (self, TRUE)) + if (!ip_config_merge_and_apply (self, AF_INET6, TRUE)) _LOGW (LOGD_IP6, "ipv6-pd: failed applying IP6 config for connection sharing"); } @@ -7394,24 +7370,18 @@ nm_device_copy_ip6_dns_config (NMDevice *self, NMDevice *from_device) nm_ip6_config_get_search (from_config, i)); } - if (!ip6_config_merge_and_apply (self, TRUE)) + if (!ip_config_merge_and_apply (self, AF_INET6, TRUE)) _LOGW (LOGD_IP6, "ipv6-pd: failed applying DNS config for connection sharing"); } /*****************************************************************************/ static void -linklocal6_cleanup (NMDevice *self) +linklocal6_failed (NMDevice *self) { NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); nm_clear_g_source (&priv->linklocal6_timeout_id); -} - -static void -linklocal6_failed (NMDevice *self) -{ - linklocal6_cleanup (self); nm_device_activate_schedule_ip6_config_timeout (self); } @@ -7426,17 +7396,26 @@ linklocal6_timeout_cb (gpointer user_data) } static void -linklocal6_complete (NMDevice *self) +linklocal6_check_complete (NMDevice *self) { NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); NMConnection *connection; const char *method; - g_assert (priv->linklocal6_timeout_id); - g_assert (priv->ext_ip6_config_captured); - g_assert (nm_ip6_config_get_address_first_nontentative (priv->ext_ip6_config_captured, TRUE)); + if (!priv->linklocal6_timeout_id) { + /* we are not waiting for linklocal to complete. Nothing to do. */ + return; + } + + if ( !priv->ext_ip6_config_captured + || !nm_ip6_config_find_first_address (priv->ext_ip6_config_captured, + NM_PLATFORM_MATCH_WITH_ADDRTYPE_LINKLOCAL + | NM_PLATFORM_MATCH_WITH_ADDRSTATE_NORMAL)) { + /* we don't have a non-tentative link local address yet. Wait longer. */ + return; + } - linklocal6_cleanup (self); + nm_clear_g_source (&priv->linklocal6_timeout_id); connection = nm_device_get_applied_connection (self); g_assert (connection); @@ -7446,12 +7425,9 @@ linklocal6_complete (NMDevice *self) _LOGD (LOGD_DEVICE, "linklocal6: waiting for link-local addresses successful, continue with method %s", method); if ( strcmp (method, NM_SETTING_IP6_CONFIG_METHOD_AUTO) == 0 - || strcmp (method, NM_SETTING_IP6_CONFIG_METHOD_SHARED) == 0) { - if (!addrconf6_start_with_link_ready (self)) { - /* Time out IPv6 instead of failing the entire activation */ - nm_device_activate_schedule_ip6_config_timeout (self); - } - } else if (strcmp (method, NM_SETTING_IP6_CONFIG_METHOD_DHCP) == 0) { + || strcmp (method, NM_SETTING_IP6_CONFIG_METHOD_SHARED) == 0) + addrconf6_start_with_link_ready (self); + else if (strcmp (method, NM_SETTING_IP6_CONFIG_METHOD_DHCP) == 0) { if (!dhcp6_start_with_link_ready (self, connection)) { /* Time out IPv6 instead of failing the entire activation */ nm_device_activate_schedule_ip6_config_timeout (self); @@ -7472,20 +7448,16 @@ check_and_add_ipv6ll_addr (NMDevice *self) NMSettingIP6Config *s_ip6 = NULL; GError *error = NULL; - if (priv->nm_ipv6ll == FALSE) + if (!priv->ipv6ll_handle) return; - if (priv->ext_ip6_config_captured) { - NMDedupMultiIter ipconf_iter; - const NMPlatformIP6Address *addr; - - nm_ip_config_iter_ip6_address_for_each (&ipconf_iter, priv->ext_ip6_config_captured, &addr) { - if ( IN6_IS_ADDR_LINKLOCAL (&addr->address) - && !(addr->n_ifa_flags & IFA_F_DADFAILED)) { - /* Already have an LL address, nothing to do */ - return; - } - } + if ( priv->ext_ip6_config_captured + && nm_ip6_config_find_first_address (priv->ext_ip6_config_captured, + NM_PLATFORM_MATCH_WITH_ADDRTYPE_LINKLOCAL + | NM_PLATFORM_MATCH_WITH_ADDRSTATE_NORMAL + | NM_PLATFORM_MATCH_WITH_ADDRSTATE_TENTATIVE)) { + /* Already have an LL address, nothing to do */ + return; } memset (&lladdr, 0, sizeof (lladdr)); @@ -7547,18 +7519,20 @@ check_and_add_ipv6ll_addr (NMDevice *self) } } -static NMActStageReturn +static gboolean linklocal6_start (NMDevice *self) { NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); NMConnection *connection; const char *method; - linklocal6_cleanup (self); + nm_clear_g_source (&priv->linklocal6_timeout_id); if ( priv->ext_ip6_config_captured - && nm_ip6_config_get_address_first_nontentative (priv->ext_ip6_config_captured, TRUE)) - return NM_ACT_STAGE_RETURN_SUCCESS; + && nm_ip6_config_find_first_address (priv->ext_ip6_config_captured, + NM_PLATFORM_MATCH_WITH_ADDRTYPE_LINKLOCAL + | NM_PLATFORM_MATCH_WITH_ADDRSTATE_NORMAL)) + return TRUE; connection = nm_device_get_applied_connection (self); g_assert (connection); @@ -7574,8 +7548,7 @@ linklocal6_start (NMDevice *self) * (rh #1101809) */ priv->linklocal6_timeout_id = g_timeout_add_seconds (15, linklocal6_timeout_cb, self); - - return NM_ACT_STAGE_RETURN_POSTPONE; + return FALSE; } /*****************************************************************************/ @@ -7817,7 +7790,7 @@ nm_device_commit_mtu (NMDevice *self) if ( state >= NM_DEVICE_STATE_CONFIG && state < NM_DEVICE_STATE_DEACTIVATING) { _LOGT (LOGD_DEVICE, "mtu: commit-mtu..."); - _commit_mtu (self, NM_DEVICE_GET_PRIVATE (self)->ip4_config); + _commit_mtu (self, NM_DEVICE_GET_PRIVATE (self)->ip_config_4); } else _LOGT (LOGD_DEVICE, "mtu: commit-mtu... skip due to state %s", nm_device_state_to_str (state)); } @@ -7955,16 +7928,21 @@ ndisc_ra_timeout (NMNDisc *ndisc, NMDevice *self) * ever receive one, then time out IPv6. But if there is other * IPv6 configuration, like manual IPv6 addresses or external IPv6 * config, consider that sufficient for IPv6 success. + * + * FIXME: it doesn't seem correct to determine this based on which + * addresses we find inside priv->ip_config_6. */ - if ( priv->ip6_config - && nm_ip6_config_get_address_first_nontentative (priv->ip6_config, FALSE)) + if ( priv->ip_config_6 + && nm_ip6_config_find_first_address (priv->ip_config_6, + NM_PLATFORM_MATCH_WITH_ADDRTYPE_NORMAL + | NM_PLATFORM_MATCH_WITH_ADDRSTATE__ANY)) nm_device_activate_schedule_ip6_config_result (self); else nm_device_activate_schedule_ip6_config_timeout (self); } } -static gboolean +static void addrconf6_start_with_link_ready (NMDevice *self) { NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); @@ -7982,9 +7960,9 @@ addrconf6_start_with_link_ready (NMDevice *self) } /* Apply any manual configuration before starting RA */ - if (!ip6_config_merge_and_apply (self, TRUE)) { + if (!ip_config_merge_and_apply (self, AF_INET6, TRUE)) { _LOGW (LOGD_IP6, "failed to apply manual IPv6 configuration"); - g_clear_object (&priv->con_ip6_config); + g_clear_object (&priv->con_ip_config_6); } /* FIXME: These sysctls would probably be better set by the lndp ndisc itself. */ @@ -8018,7 +7996,7 @@ addrconf6_start_with_link_ready (NMDevice *self) ndisc_set_router_config (priv->ndisc, self); nm_ndisc_start (priv->ndisc); - return TRUE; + return; } static NMNDiscNodeType @@ -8041,7 +8019,6 @@ addrconf6_start (NMDevice *self, NMSettingIP6ConfigPrivacy use_tempaddr) { NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); NMConnection *connection; - NMActStageReturn ret; NMSettingIP6Config *s_ip6 = NULL; GError *error = NULL; NMUtilsStableType stable_type; @@ -8088,15 +8065,14 @@ addrconf6_start (NMDevice *self, NMSettingIP6ConfigPrivacy use_tempaddr) nm_device_add_pending_action (self, NM_PENDING_ACTION_AUTOCONF6, TRUE); /* ensure link local is ready... */ - ret = linklocal6_start (self); - if (ret == NM_ACT_STAGE_RETURN_POSTPONE) { - /* success; wait for the LL address to show up */ + if (!linklocal6_start (self)) { + /* wait for the LL address to show up */ return TRUE; } - /* success; already have the LL address; kick off neighbor discovery */ - g_assert (ret == NM_ACT_STAGE_RETURN_SUCCESS); - return addrconf6_start_with_link_ready (self); + /* already have the LL address; kick off neighbor discovery */ + addrconf6_start_with_link_ready (self); + return TRUE; } static void @@ -8163,7 +8139,8 @@ restore_ip6_properties (NMDevice *self) g_hash_table_iter_init (&iter, priv->ip6_saved_properties); while (g_hash_table_iter_next (&iter, &key, &value)) { /* Don't touch "disable_ipv6" if we're doing userland IPv6LL */ - if (priv->nm_ipv6ll && strcmp (key, "disable_ipv6") == 0) + if ( priv->ipv6ll_handle + && nm_streq (key, "disable_ipv6")) continue; nm_device_ipv6_sysctl_set (self, key, value); } @@ -8173,7 +8150,7 @@ static inline void set_disable_ipv6 (NMDevice *self, const char *value) { /* We only touch disable_ipv6 when NM is not managing the IPv6LL address */ - if (NM_DEVICE_GET_PRIVATE (self)->nm_ipv6ll == FALSE) + if (!NM_DEVICE_GET_PRIVATE (self)->ipv6ll_handle) nm_device_ipv6_sysctl_set (self, "disable_ipv6", value); } @@ -8188,7 +8165,7 @@ set_nm_ipv6ll (NMDevice *self, gboolean enable) NM_PLATFORM_KERNEL_SUPPORT_USER_IPV6LL)) return; - priv->nm_ipv6ll = enable; + priv->ipv6ll_handle = enable; if (ifindex > 0) { NMPlatformError plerr; const char *detail = enable ? "enable" : "disable"; @@ -8337,14 +8314,14 @@ act_stage3_ip6_config_start (NMDevice *self, if (strcmp (method, NM_SETTING_IP6_CONFIG_METHOD_IGNORE) == 0) { if ( !priv->master && !nm_device_sys_iface_state_is_external (self)) { - gboolean old_nm_ipv6ll = priv->nm_ipv6ll; + gboolean ipv6ll_handle_old = priv->ipv6ll_handle; /* When activating an IPv6 'ignore' connection we need to revert back * to kernel IPv6LL, but the kernel won't actually assign an address * to the interface until disable_ipv6 is bounced. */ set_nm_ipv6ll (self, FALSE); - if (old_nm_ipv6ll == TRUE) + if (ipv6ll_handle_old) nm_device_ipv6_sysctl_set (self, "disable_ipv6", "1"); restore_ip6_properties (self); } @@ -8355,7 +8332,7 @@ act_stage3_ip6_config_start (NMDevice *self, * expose any ipv6 sysctls or allow presence of any addresses on the interface, * including LL, which * would make it impossible to autoconfigure MTU to a * correct value. */ - _commit_mtu (self, priv->ip4_config); + _commit_mtu (self, priv->ip_config_4); /* Any method past this point requires an IPv6LL address. Use NM-controlled * IPv6LL if this is not an assumed connection, since assumed connections @@ -8376,7 +8353,6 @@ act_stage3_ip6_config_start (NMDevice *self, priv->ext_ip6_config_captured = nm_ip6_config_capture (nm_device_get_multi_index (self), nm_device_get_platform (self), nm_device_get_ip_ifindex (self), - FALSE, NM_SETTING_IP6_CONFIG_PRIVACY_UNKNOWN); ip6_privacy = _ip6_privacy_get (self); @@ -8389,7 +8365,9 @@ act_stage3_ip6_config_start (NMDevice *self, } else ret = NM_ACT_STAGE_RETURN_POSTPONE; } else if (strcmp (method, NM_SETTING_IP6_CONFIG_METHOD_LINK_LOCAL) == 0) { - ret = linklocal6_start (self); + ret = linklocal6_start (self) + ? NM_ACT_STAGE_RETURN_SUCCESS + : NM_ACT_STAGE_RETURN_POSTPONE; } else if (strcmp (method, NM_SETTING_IP6_CONFIG_METHOD_DHCP) == 0) { priv->dhcp6.mode = NM_NDISC_DHCP_LEVEL_MANAGED; if (!dhcp6_start (self, TRUE)) { @@ -8959,7 +8937,7 @@ activate_stage5_ip4_config_result (NMDevice *self) _LOGW (LOGD_DEVICE, "interface %s not up for IP configuration", nm_device_get_ip_iface (self)); } - if (!ip4_config_merge_and_apply (self, TRUE)) { + if (!ip_config_merge_and_apply (self, AF_INET, TRUE)) { _LOGD (LOGD_DEVICE | LOGD_IP4, "Activation: Stage 5 of 5 (IPv4 Commit) failed"); nm_device_ip_method_failed (self, AF_INET, NM_DEVICE_STATE_REASON_CONFIG_FAILED); return; @@ -8971,7 +8949,7 @@ activate_stage5_ip4_config_result (NMDevice *self) if (strcmp (method, NM_SETTING_IP4_CONFIG_METHOD_SHARED) == 0) { gs_free_error GError *error = NULL; - if (!start_sharing (self, priv->ip4_config, &error)) { + if (!start_sharing (self, priv->ip_config_4, &error)) { _LOGW (LOGD_SHARING, "Activation: Stage 5 of 5 (IPv4 Commit) start sharing failed: %s", error->message); nm_device_ip_method_failed (self, AF_INET, NM_DEVICE_STATE_REASON_SHARED_START_FAILED); return; @@ -9042,8 +9020,8 @@ dad6_get_pending_addresses (NMDevice *self) NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); NMIP6Config *confs[] = { (NMIP6Config *) applied_config_get_current (&priv->ac_ip6_config), (NMIP6Config *) applied_config_get_current (&priv->dhcp6.ip6_config), - priv->con_ip6_config, - (NMIP6Config *) applied_config_get_current (&priv->wwan_ip6_config) }; + priv->con_ip_config_6, + (NMIP6Config *) applied_config_get_current (&priv->wwan_ip_config_6) }; const NMPlatformIP6Address *addr, *pl_addr; NMIP6Config *dad6_config = NULL; NMDedupMultiIter ipconf_iter; @@ -9107,7 +9085,7 @@ activate_stage5_ip6_config_commit (NMDevice *self) _LOGW (LOGD_DEVICE, "interface %s not up for IP configuration", nm_device_get_ip_iface (self)); } - if (ip6_config_merge_and_apply (self, TRUE)) { + if (ip_config_merge_and_apply (self, AF_INET6, TRUE)) { if ( priv->dhcp6.mode != NM_NDISC_DHCP_LEVEL_NONE && priv->ip6_state == IP_CONF) { if (applied_config_get_current (&priv->dhcp6.ip6_config)) { @@ -9277,9 +9255,9 @@ _update_ip4_address (NMDevice *self) g_return_if_fail (NM_IS_DEVICE (self)); - if ( priv->ip4_config + if ( priv->ip_config_4 && ip_config_valid (priv->state) - && (address = nm_ip4_config_get_first_address (priv->ip4_config))) { + && (address = nm_ip4_config_get_first_address (priv->ip_config_4))) { if (address->address != priv->ip4_address) { priv->ip4_address = address->address; _notify (self, PROP_IP4_ADDRESS); @@ -9373,37 +9351,31 @@ delete_on_deactivate_check_and_schedule (NMDevice *self, int ifindex) } static void -_cleanup_ip4_pre (NMDevice *self, CleanupType cleanup_type) +_cleanup_ip_pre (NMDevice *self, int addr_family, CleanupType cleanup_type) { NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); + const gboolean IS_IPv4 = (addr_family == AF_INET); - _set_ip_state (self, AF_INET, IP_NONE); - - if (nm_clear_g_source (&priv->queued_ip4_config_id)) - _LOGD (LOGD_DEVICE, "clearing queued IP4 config change"); - priv->queued_ip4_config_pending = FALSE; + _set_ip_state (self, addr_family, IP_NONE); - dhcp4_cleanup (self, cleanup_type, FALSE); - arp_cleanup (self); - dnsmasq_cleanup (self); - ipv4ll_cleanup (self); -} - -static void -_cleanup_ip6_pre (NMDevice *self, CleanupType cleanup_type) -{ - NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); - - _set_ip_state (self, AF_INET6, IP_NONE); - - if (nm_clear_g_source (&priv->queued_ip6_config_id)) - _LOGD (LOGD_DEVICE, "clearing queued IP6 config change"); - priv->queued_ip6_config_pending = FALSE; + if (nm_clear_g_source (&priv->queued_ip_config_id_x[IS_IPv4])) { + _LOGD (LOGD_DEVICE, "clearing queued IP%c config change", + nm_utils_addr_family_to_char (addr_family)); + } - g_clear_object (&priv->dad6_ip6_config); - dhcp6_cleanup (self, cleanup_type, FALSE); - linklocal6_cleanup (self); - addrconf6_cleanup (self); + if (IS_IPv4) { + priv->queued_ip4_config_pending = FALSE; + dhcp4_cleanup (self, cleanup_type, FALSE); + arp_cleanup (self); + dnsmasq_cleanup (self); + ipv4ll_cleanup (self); + } else { + priv->queued_ip6_config_pending = FALSE; + g_clear_object (&priv->dad6_ip6_config); + dhcp6_cleanup (self, cleanup_type, FALSE); + nm_clear_g_source (&priv->linklocal6_timeout_id); + addrconf6_cleanup (self); + } } gboolean @@ -9482,12 +9454,12 @@ nm_device_reactivate_ip4_config (NMDevice *self, priv = NM_DEVICE_GET_PRIVATE (self); if (priv->ip4_state != IP_NONE) { - g_clear_object (&priv->con_ip4_config); - g_clear_object (&priv->ext_ip4_config); + g_clear_object (&priv->con_ip_config_4); + g_clear_object (&priv->ext_ip_config_4); g_clear_object (&priv->dev_ip4_config.current); - g_clear_object (&priv->wwan_ip4_config.current); - priv->con_ip4_config = _ip4_config_new (self); - nm_ip4_config_merge_setting (priv->con_ip4_config, + g_clear_object (&priv->wwan_ip_config_4.current); + priv->con_ip_config_4 = _ip4_config_new (self); + nm_ip4_config_merge_setting (priv->con_ip_config_4, s_ip4_new, _get_mdns (self), nm_device_get_route_table (self, AF_INET, TRUE), @@ -9501,12 +9473,12 @@ nm_device_reactivate_ip4_config (NMDevice *self, : NM_SETTING_IP4_CONFIG_METHOD_DISABLED; if (!nm_streq0 (method_old, method_new)) { - _cleanup_ip4_pre (self, CLEANUP_TYPE_DECONFIGURE); + _cleanup_ip_pre (self, AF_INET, CLEANUP_TYPE_DECONFIGURE); _set_ip_state (self, AF_INET, IP_WAIT); if (!nm_device_activate_stage3_ip4_start (self)) _LOGW (LOGD_IP4, "Failed to apply IPv4 configuration"); } else { - if (!ip4_config_merge_and_apply (self, TRUE)) + if (!ip_config_merge_and_apply (self, AF_INET, TRUE)) _LOGW (LOGD_IP4, "Failed to reapply IPv4 configuration"); } } @@ -9524,13 +9496,13 @@ nm_device_reactivate_ip6_config (NMDevice *self, priv = NM_DEVICE_GET_PRIVATE (self); if (priv->ip6_state != IP_NONE) { - g_clear_object (&priv->con_ip6_config); - g_clear_object (&priv->ext_ip6_config); + g_clear_object (&priv->con_ip_config_6); + g_clear_object (&priv->ext_ip_config_6); g_clear_object (&priv->ac_ip6_config.current); g_clear_object (&priv->dhcp6.ip6_config.current); - g_clear_object (&priv->wwan_ip6_config.current); - priv->con_ip6_config = _ip6_config_new (self); - nm_ip6_config_merge_setting (priv->con_ip6_config, + g_clear_object (&priv->wwan_ip_config_6.current); + priv->con_ip_config_6 = _ip6_config_new (self); + nm_ip6_config_merge_setting (priv->con_ip_config_6, s_ip6_new, nm_device_get_route_table (self, AF_INET6, TRUE), nm_device_get_route_metric (self, AF_INET6)); @@ -9543,12 +9515,12 @@ nm_device_reactivate_ip6_config (NMDevice *self, : NM_SETTING_IP6_CONFIG_METHOD_IGNORE; if (!nm_streq0 (method_old, method_new)) { - _cleanup_ip6_pre (self, CLEANUP_TYPE_DECONFIGURE); + _cleanup_ip_pre (self, AF_INET6, CLEANUP_TYPE_DECONFIGURE); _set_ip_state (self, AF_INET6, IP_WAIT); if (!nm_device_activate_stage3_ip6_start (self)) _LOGW (LOGD_IP6, "Failed to apply IPv6 configuration"); } else { - if (!ip6_config_merge_and_apply (self, TRUE)) + if (!ip_config_merge_and_apply (self, AF_INET6, TRUE)) _LOGW (LOGD_IP4, "Failed to reapply IPv6 configuration"); } } @@ -10488,95 +10460,132 @@ nm_device_get_ip4_config (NMDevice *self) { g_return_val_if_fail (NM_IS_DEVICE (self), NULL); - return NM_DEVICE_GET_PRIVATE (self)->ip4_config; + return NM_DEVICE_GET_PRIVATE (self)->ip_config_4; } static gboolean -nm_device_set_ip4_config (NMDevice *self, - NMIP4Config *new_config, - gboolean commit, - GPtrArray *ip4_dev_route_blacklist) +nm_device_set_ip_config (NMDevice *self, + int addr_family, + NMIPConfig *new_config, + gboolean commit, + GPtrArray *ip4_dev_route_blacklist) { - NMDevicePrivate *priv; - NMIP4Config *old_config = NULL; + NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); + const gboolean IS_IPv4 = (addr_family == AF_INET); + NMIPConfig *old_config; gboolean has_changes = FALSE; gboolean success = TRUE; + NMSettingsConnection *settings_connection; - g_return_val_if_fail (NM_IS_DEVICE (self), FALSE); - - _LOGD (LOGD_IP4, "ip4-config: update (commit=%d, new-config=%p)", - commit, new_config); - + nm_assert_addr_family (addr_family); + nm_assert (!new_config || nm_ip_config_get_addr_family (new_config) == addr_family); nm_assert ( !new_config || ( new_config && ({ int ip_ifindex = nm_device_get_ip_ifindex (self); ( ip_ifindex > 0 - && ip_ifindex == nm_ip4_config_get_ifindex (new_config)); + && ip_ifindex == nm_ip_config_get_ifindex (new_config)); }))); + nm_assert (IS_IPv4 || !ip4_dev_route_blacklist); - priv = NM_DEVICE_GET_PRIVATE (self); - - old_config = priv->ip4_config; + _LOGD (LOGD_IP_from_af (addr_family), + "ip%c-config: update (commit=%d, new-config=%p)", + nm_utils_addr_family_to_char (addr_family), + commit, + new_config); /* Always commit to nm-platform to update lifetimes */ if (commit && new_config) { - _commit_mtu (self, new_config); - success = nm_ip4_config_commit (new_config, - nm_device_get_platform (self), - nm_device_get_route_table (self, AF_INET, FALSE) - ? NM_IP_ROUTE_TABLE_SYNC_MODE_FULL - : NM_IP_ROUTE_TABLE_SYNC_MODE_MAIN); - nm_platform_ip4_dev_route_blacklist_set (nm_device_get_platform (self), - nm_ip4_config_get_ifindex (new_config), - ip4_dev_route_blacklist); - } - - if (new_config) { - if (old_config) { - /* has_changes is set only on relevant changes, because when the configuration changes, - * this causes a re-read and reset. This should only happen for relevant changes */ - nm_ip4_config_replace (old_config, new_config, &has_changes); - if (has_changes) { - _LOGD (LOGD_IP4, "ip4-config: update IP4Config instance (%s)", - nm_dbus_object_get_path (NM_DBUS_OBJECT (old_config))); - } + + _commit_mtu (self, + IS_IPv4 + ? NM_IP4_CONFIG (new_config) + : priv->ip_config_4); + + if (IS_IPv4) { + success = nm_ip4_config_commit (NM_IP4_CONFIG (new_config), + nm_device_get_platform (self), + nm_device_get_route_table (self, addr_family, FALSE) + ? NM_IP_ROUTE_TABLE_SYNC_MODE_FULL + : NM_IP_ROUTE_TABLE_SYNC_MODE_MAIN); + nm_platform_ip4_dev_route_blacklist_set (nm_device_get_platform (self), + nm_ip_config_get_ifindex (new_config), + ip4_dev_route_blacklist); } else { - has_changes = TRUE; - priv->ip4_config = g_object_ref (new_config); + gs_unref_ptrarray GPtrArray *temporary_not_available = NULL; - if (success && !nm_dbus_object_is_exported (NM_DBUS_OBJECT (new_config))) - nm_dbus_object_export (NM_DBUS_OBJECT (new_config)); + success = nm_ip6_config_commit (NM_IP6_CONFIG (new_config), + nm_device_get_platform (self), + nm_device_get_route_table (self, addr_family, FALSE) + ? NM_IP_ROUTE_TABLE_SYNC_MODE_FULL + : NM_IP_ROUTE_TABLE_SYNC_MODE_MAIN, + &temporary_not_available); - _LOGD (LOGD_IP4, "ip4-config: set IP4Config instance (%s)", - nm_dbus_object_get_path (NM_DBUS_OBJECT (new_config))); + if (!_rt6_temporary_not_available_set (self, temporary_not_available)) + success = FALSE; } - } else if (old_config) { + } + + old_config = priv->ip_config_x[IS_IPv4]; + + if (new_config && old_config) { + /* has_changes is set only on relevant changes, because when the configuration changes, + * this causes a re-read and reset. This should only happen for relevant changes */ + nm_ip_config_replace (old_config, new_config, &has_changes); + if (has_changes) { + _LOGD (LOGD_IP_from_af (addr_family), + "ip%c-config: update IP Config instance (%s)", + nm_utils_addr_family_to_char (addr_family), + nm_dbus_object_get_path (NM_DBUS_OBJECT (old_config))); + } + } else if (new_config /*&& !old_config*/) { + has_changes = TRUE; + priv->ip_config_x[IS_IPv4] = g_object_ref (new_config); + if (!nm_dbus_object_is_exported (NM_DBUS_OBJECT (new_config))) + nm_dbus_object_export (NM_DBUS_OBJECT (new_config)); + + _LOGD (LOGD_IP_from_af (addr_family), + "ip%c-config: set IP Config instance (%s)", + nm_utils_addr_family_to_char (addr_family), + nm_dbus_object_get_path (NM_DBUS_OBJECT (new_config))); + } else if (old_config /*&& !new_config*/) { has_changes = TRUE; - priv->ip4_config = NULL; - _LOGD (LOGD_IP4, "ip4-config: clear IP4Config instance (%s)", + priv->ip_config_x[IS_IPv4] = NULL; + _LOGD (LOGD_IP_from_af (addr_family), + "ip%c-config: clear IP Config instance (%s)", + nm_utils_addr_family_to_char (addr_family), nm_dbus_object_get_path (NM_DBUS_OBJECT (old_config))); - /* Device config is invalid if combined config is invalid */ - applied_config_clear (&priv->dev_ip4_config); + if (IS_IPv4) { + /* Device config is invalid if combined config is invalid */ + applied_config_clear (&priv->dev_ip4_config); + } else + priv->needs_ip6_subnet = FALSE; } - concheck_periodic_update (self); + if (IS_IPv4) { + concheck_periodic_update (self); - if (!nm_device_sys_iface_state_is_external_or_assume (self)) - ip4_rp_filter_update (self); + if (!nm_device_sys_iface_state_is_external_or_assume (self)) + ip4_rp_filter_update (self); + } if (has_changes) { - NMSettingsConnection *settings_connection; - _update_ip4_address (self); + if (IS_IPv4) + _update_ip4_address (self); - if (old_config != priv->ip4_config) - _notify (self, PROP_IP4_CONFIG); - g_signal_emit (self, signals[IP4_CONFIG_CHANGED], 0, priv->ip4_config, old_config); + if (old_config != priv->ip_config_x[IS_IPv4]) + _notify (self, IS_IPv4 ? PROP_IP4_CONFIG : PROP_IP6_CONFIG); - if (old_config != priv->ip4_config) + g_signal_emit (self, + signals[IS_IPv4 ? IP4_CONFIG_CHANGED : IP6_CONFIG_CHANGED], + 0, + priv->ip_config_x[IS_IPv4], + old_config); + + if (old_config != priv->ip_config_x[IS_IPv4]) nm_dbus_object_clear_and_unexport (&old_config); if ( nm_device_sys_iface_state_is_external (self) @@ -10584,20 +10593,24 @@ nm_device_set_ip4_config (NMDevice *self, && NM_FLAGS_HAS (nm_settings_connection_get_flags (settings_connection), NM_SETTINGS_CONNECTION_FLAGS_NM_GENERATED) && nm_active_connection_get_activation_type (NM_ACTIVE_CONNECTION (priv->act_request)) == NM_ACTIVATION_TYPE_EXTERNAL) { - NMSetting *s_ip4; - g_object_freeze_notify (G_OBJECT (settings_connection)); - - nm_connection_remove_setting (NM_CONNECTION (settings_connection), NM_TYPE_SETTING_IP4_CONFIG); - s_ip4 = nm_ip4_config_create_setting (priv->ip4_config); - nm_connection_add_setting (NM_CONNECTION (settings_connection), s_ip4); - + nm_connection_add_setting (NM_CONNECTION (settings_connection), + IS_IPv4 + ? nm_ip4_config_create_setting (priv->ip_config_4) + : nm_ip6_config_create_setting (priv->ip_config_6)); g_object_thaw_notify (G_OBJECT (settings_connection)); } nm_device_queue_recheck_assume (self); + + if (!IS_IPv4) { + if (priv->ndisc) + ndisc_set_router_config (priv->ndisc, self); + } } + nm_assert (!old_config || old_config == priv->ip_config_x[IS_IPv4]); + return success; } @@ -10644,11 +10657,11 @@ nm_device_replace_vpn4_config (NMDevice *self, NMIP4Config *old, NMIP4Config *co nm_assert (!old || nm_ip4_config_get_ifindex (old) == nm_device_get_ip_ifindex (self)); nm_assert (!config || nm_ip4_config_get_ifindex (config) == nm_device_get_ip_ifindex (self)); - if (!_replace_vpn_config_in_list (&priv->vpn4_configs, (GObject *) old, (GObject *) config)) + if (!_replace_vpn_config_in_list (&priv->vpn_configs_4, (GObject *) old, (GObject *) config)) return; /* NULL to use existing configs */ - if (!ip4_config_merge_and_apply (self, TRUE)) + if (!ip_config_merge_and_apply (self, AF_INET, TRUE)) _LOGW (LOGD_IP4, "failed to set VPN routes for device"); } @@ -10657,118 +10670,11 @@ nm_device_set_wwan_ip4_config (NMDevice *self, NMIP4Config *config) { NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); - applied_config_init (&priv->wwan_ip4_config, config); - if (!ip4_config_merge_and_apply (self, TRUE)) + applied_config_init (&priv->wwan_ip_config_4, config); + if (!ip_config_merge_and_apply (self, AF_INET, TRUE)) _LOGW (LOGD_IP4, "failed to set WWAN IPv4 configuration"); } -static gboolean -nm_device_set_ip6_config (NMDevice *self, - NMIP6Config *new_config, - gboolean commit) -{ - NMDevicePrivate *priv; - NMIP6Config *old_config = NULL; - gboolean has_changes = FALSE; - gboolean success = TRUE; - - g_return_val_if_fail (NM_IS_DEVICE (self), FALSE); - - _LOGD (LOGD_IP6, "ip6-config: update (commit=%d, new-config=%p)", - commit, new_config); - - nm_assert ( !new_config - || ( new_config - && ({ - int ip_ifindex = nm_device_get_ip_ifindex (self); - - ( ip_ifindex > 0 - && ip_ifindex == nm_ip6_config_get_ifindex (new_config)); - }))); - - priv = NM_DEVICE_GET_PRIVATE (self); - - old_config = priv->ip6_config; - - /* Always commit to nm-platform to update lifetimes */ - if (commit && new_config) { - gs_unref_ptrarray GPtrArray *temporary_not_available = NULL; - - _commit_mtu (self, priv->ip4_config); - - success = nm_ip6_config_commit (new_config, - nm_device_get_platform (self), - nm_device_get_route_table (self, AF_INET6, FALSE) - ? NM_IP_ROUTE_TABLE_SYNC_MODE_FULL - : NM_IP_ROUTE_TABLE_SYNC_MODE_MAIN, - &temporary_not_available); - - if (!_rt6_temporary_not_available_set (self, temporary_not_available)) - success = FALSE; - } - - if (new_config) { - if (old_config) { - /* has_changes is set only on relevant changes, because when the configuration changes, - * this causes a re-read and reset. This should only happen for relevant changes */ - nm_ip6_config_replace (old_config, new_config, &has_changes); - if (has_changes) { - _LOGD (LOGD_IP6, "ip6-config: update IP6Config instance (%s)", - nm_dbus_object_get_path (NM_DBUS_OBJECT (old_config))); - } - } else { - has_changes = TRUE; - priv->ip6_config = g_object_ref (new_config); - - if (success && !nm_dbus_object_is_exported (NM_DBUS_OBJECT (new_config))) - nm_dbus_object_export (NM_DBUS_OBJECT (new_config)); - - _LOGD (LOGD_IP6, "ip6-config: set IP6Config instance (%s)", - nm_dbus_object_get_path (NM_DBUS_OBJECT (new_config))); - } - } else if (old_config) { - has_changes = TRUE; - priv->ip6_config = NULL; - priv->needs_ip6_subnet = FALSE; - _LOGD (LOGD_IP6, "ip6-config: clear IP6Config instance (%s)", - nm_dbus_object_get_path (NM_DBUS_OBJECT (old_config))); - } - - if (has_changes) { - NMSettingsConnection *settings_connection; - - if (old_config != priv->ip6_config) - _notify (self, PROP_IP6_CONFIG); - g_signal_emit (self, signals[IP6_CONFIG_CHANGED], 0, priv->ip6_config, old_config); - - if (old_config != priv->ip6_config) - nm_dbus_object_clear_and_unexport (&old_config); - - if ( nm_device_sys_iface_state_is_external (self) - && (settings_connection = nm_device_get_settings_connection (self)) - && NM_FLAGS_HAS (nm_settings_connection_get_flags (settings_connection), - NM_SETTINGS_CONNECTION_FLAGS_NM_GENERATED) - && nm_active_connection_get_activation_type (NM_ACTIVE_CONNECTION (priv->act_request)) == NM_ACTIVATION_TYPE_EXTERNAL) { - NMSetting *s_ip6; - - g_object_freeze_notify (G_OBJECT (settings_connection)); - - nm_connection_remove_setting (NM_CONNECTION (settings_connection), NM_TYPE_SETTING_IP6_CONFIG); - s_ip6 = nm_ip6_config_create_setting (priv->ip6_config); - nm_connection_add_setting (NM_CONNECTION (settings_connection), s_ip6); - - g_object_thaw_notify (G_OBJECT (settings_connection)); - } - - nm_device_queue_recheck_assume (self); - - if (priv->ndisc) - ndisc_set_router_config (priv->ndisc, self); - } - - return success; -} - void nm_device_replace_vpn6_config (NMDevice *self, NMIP6Config *old, NMIP6Config *config) { @@ -10779,11 +10685,11 @@ nm_device_replace_vpn6_config (NMDevice *self, NMIP6Config *old, NMIP6Config *co nm_assert (!old || nm_ip6_config_get_ifindex (old) == nm_device_get_ip_ifindex (self)); nm_assert (!config || nm_ip6_config_get_ifindex (config) == nm_device_get_ip_ifindex (self)); - if (!_replace_vpn_config_in_list (&priv->vpn6_configs, (GObject *) old, (GObject *) config)) + if (!_replace_vpn_config_in_list (&priv->vpn_configs_6, (GObject *) old, (GObject *) config)) return; /* NULL to use existing configs */ - if (!ip6_config_merge_and_apply (self, TRUE)) + if (!ip_config_merge_and_apply (self, AF_INET6, TRUE)) _LOGW (LOGD_IP6, "failed to set VPN routes for device"); } @@ -10792,8 +10698,8 @@ nm_device_set_wwan_ip6_config (NMDevice *self, NMIP6Config *config) { NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); - applied_config_init (&priv->wwan_ip6_config, config); - if (!ip6_config_merge_and_apply (self, TRUE)) + applied_config_init (&priv->wwan_ip_config_6, config); + if (!ip_config_merge_and_apply (self, AF_INET6, TRUE)) _LOGW (LOGD_IP6, "failed to set WWAN IPv6 configuration"); } @@ -10810,7 +10716,7 @@ nm_device_get_ip6_config (NMDevice *self) { g_return_val_if_fail (NM_IS_DEVICE (self), NULL); - return NM_DEVICE_GET_PRIVATE (self)->ip6_config; + return NM_DEVICE_GET_PRIVATE (self)->ip_config_6; } /*****************************************************************************/ @@ -11044,15 +10950,15 @@ nm_device_start_ip_check (NMDevice *self) if (timeout) { const NMPObject *gw; - if (priv->ip4_config && priv->ip4_state == IP_DONE) { - gw = nm_ip4_config_best_default_route_get (priv->ip4_config); + if (priv->ip_config_4 && priv->ip4_state == IP_DONE) { + gw = nm_ip4_config_best_default_route_get (priv->ip_config_4); if (gw) { nm_utils_inet4_ntop (NMP_OBJECT_CAST_IP4_ROUTE (gw)->gateway, buf); ping_binary = nm_utils_find_helper ("ping", "/usr/bin/ping", NULL); log_domain = LOGD_IP4; } - } else if (priv->ip6_config && priv->ip6_state == IP_DONE) { - gw = nm_ip6_config_best_default_route_get (priv->ip6_config); + } else if (priv->ip_config_6 && priv->ip6_state == IP_DONE) { + gw = nm_ip6_config_best_default_route_get (priv->ip_config_6); if (gw) { nm_utils_inet6_ntop (&NMP_OBJECT_CAST_IP6_ROUTE (gw)->gateway, buf); ping_binary = nm_utils_find_helper ("ping6", "/usr/bin/ping6", NULL); @@ -11192,11 +11098,11 @@ nm_device_bring_up (NMDevice *self, gboolean block, gboolean *no_firmware) /* when the link comes up, we must restore IP configuration if necessary. */ if (priv->ip4_state == IP_DONE) { - if (!ip4_config_merge_and_apply (self, TRUE)) + if (!ip_config_merge_and_apply (self, AF_INET, TRUE)) _LOGW (LOGD_IP4, "failed applying IP4 config after bringing link up"); } if (priv->ip6_state == IP_DONE) { - if (!ip6_config_merge_and_apply (self, TRUE)) + if (!ip_config_merge_and_apply (self, AF_INET6, TRUE)) _LOGW (LOGD_IP6, "failed applying IP6 config after bringing link up"); } @@ -11261,116 +11167,6 @@ nm_device_get_firmware_missing (NMDevice *self) return NM_DEVICE_GET_PRIVATE (self)->firmware_missing; } -static NMIP4Config * -find_ip4_lease_config (NMDevice *self, - NMConnection *connection, - NMIP4Config *ext_ip4_config) -{ - const char *ip_iface = nm_device_get_ip_iface (self); - int ip_ifindex = nm_device_get_ip_ifindex (self); - GSList *leases, *liter; - NMIP4Config *found = NULL; - - g_return_val_if_fail (NM_IS_IP4_CONFIG (ext_ip4_config), NULL); - g_return_val_if_fail (NM_IS_CONNECTION (connection), NULL); - - leases = nm_dhcp_manager_get_lease_ip_configs (nm_dhcp_manager_get (), - nm_device_get_multi_index (self), - AF_INET, - ip_iface, - ip_ifindex, - nm_connection_get_uuid (connection), - nm_device_get_route_table (self, AF_INET, TRUE), - nm_device_get_route_metric (self, AF_INET)); - for (liter = leases; liter && !found; liter = liter->next) { - NMIP4Config *lease_config = liter->data; - const NMPlatformIP4Address *address = nm_ip4_config_get_first_address (lease_config); - const NMPObject *gw1, *gw2; - - g_assert (address); - if (!nm_ip4_config_address_exists (ext_ip4_config, address)) - continue; - gw1 = nm_ip4_config_best_default_route_get (lease_config); - if (!gw1) - continue; - gw2 = nm_ip4_config_best_default_route_get (ext_ip4_config); - if (!gw2) - continue; - if (NMP_OBJECT_CAST_IP4_ROUTE (gw1)->gateway != NMP_OBJECT_CAST_IP4_ROUTE (gw2)->gateway) - continue; - found = g_object_ref (lease_config); - } - - g_slist_free_full (leases, g_object_unref); - return found; -} - -static void -capture_lease_config (NMDevice *self, - NMIP4Config *ext_ip4_config, - NMIP4Config **out_ip4_config, - NMIP6Config *ext_ip6_config, - NMIP6Config **out_ip6_config) -{ - NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); - NMSettingsConnection *const*connections; - guint i; - gboolean dhcp_used = FALSE; - NMDedupMultiIter ipconf_iter; - - /* Ensure at least one address on the device has a non-infinite lifetime, - * otherwise DHCP cannot possibly be active on the device right now. - */ - if (ext_ip4_config && out_ip4_config) { - const NMPlatformIP4Address *addr; - - nm_ip_config_iter_ip4_address_for_each (&ipconf_iter, ext_ip4_config, &addr) { - if (addr->lifetime != NM_PLATFORM_LIFETIME_PERMANENT) { - dhcp_used = TRUE; - break; - } - } - } else if (ext_ip6_config && out_ip6_config) { - const NMPlatformIP6Address *addr; - - nm_ip_config_iter_ip6_address_for_each (&ipconf_iter, ext_ip6_config, &addr) { - if (addr->lifetime != NM_PLATFORM_LIFETIME_PERMANENT) { - dhcp_used = TRUE; - break; - } - } - } else { - g_return_if_fail ( (ext_ip6_config && out_ip6_config) - || (ext_ip4_config && out_ip4_config)); - } - - if (!dhcp_used) - return; - - connections = nm_settings_get_connections (priv->settings, NULL); - for (i = 0; connections[i]; i++) { - NMConnection *candidate = (NMConnection *) connections[i]; - const char *method; - - if (!nm_device_check_connection_compatible (self, candidate)) - continue; - - /* IPv4 leases */ - method = nm_utils_get_ip_config_method (candidate, NM_TYPE_SETTING_IP4_CONFIG); - if (out_ip4_config && strcmp (method, NM_SETTING_IP4_CONFIG_METHOD_AUTO) == 0) { - *out_ip4_config = find_ip4_lease_config (self, candidate, ext_ip4_config); - if (*out_ip4_config) - return; - } - - /* IPv6 leases */ - method = nm_utils_get_ip_config_method (candidate, NM_TYPE_SETTING_IP6_CONFIG); - if (out_ip6_config && strcmp (method, NM_SETTING_IP6_CONFIG_METHOD_AUTO) == 0) { - /* FIXME: implement find_ip6_lease_config() */ - } - } -} - static void intersect_ext_config (NMDevice *self, AppliedConfig *config) { @@ -11385,8 +11181,8 @@ intersect_ext_config (NMDevice *self, AppliedConfig *config) family = nm_ip_config_get_addr_family (config->orig); penalty = default_route_metric_penalty_get (self, family); ext = family == AF_INET - ? (NMIPConfig *) priv->ext_ip4_config - : (NMIPConfig *) priv->ext_ip6_config; + ? (NMIPConfig *) priv->ext_ip_config_4 + : (NMIPConfig *) priv->ext_ip_config_6; if (config->current) nm_ip_config_intersect (config->current, ext, penalty); @@ -11398,11 +11194,10 @@ intersect_ext_config (NMDevice *self, AppliedConfig *config) } static gboolean -update_ext_ip_config (NMDevice *self, int addr_family, gboolean initial, gboolean intersect_configs) +update_ext_ip_config (NMDevice *self, int addr_family, gboolean intersect_configs) { NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); int ifindex; - gboolean capture_resolv_conf; GSList *iter; nm_assert_addr_family (addr_family); @@ -11411,119 +11206,106 @@ update_ext_ip_config (NMDevice *self, int addr_family, gboolean initial, gboolea if (!ifindex) return FALSE; - capture_resolv_conf = initial - && nm_dns_manager_get_resolv_conf_explicit (nm_dns_manager_get ()); - if (addr_family == AF_INET) { - g_clear_object (&priv->ext_ip4_config); - priv->ext_ip4_config = nm_ip4_config_capture (nm_device_get_multi_index (self), + g_clear_object (&priv->ext_ip_config_4); + priv->ext_ip_config_4 = nm_ip4_config_capture (nm_device_get_multi_index (self), nm_device_get_platform (self), - ifindex, - capture_resolv_conf); - if (priv->ext_ip4_config) { - if (initial) { - applied_config_clear (&priv->dev_ip4_config); - capture_lease_config (self, - priv->ext_ip4_config, - (NMIP4Config **) &priv->dev_ip4_config.orig, - NULL, NULL); - } - + ifindex); + if (priv->ext_ip_config_4) { if (intersect_configs) { /* This function was called upon external changes. Remove the configuration * (addresses,routes) that is no longer present externally from the internal * config. This way, we don't re-add addresses that were manually removed * by the user. */ - if (priv->con_ip4_config) { - nm_ip4_config_intersect (priv->con_ip4_config, priv->ext_ip4_config, + if (priv->con_ip_config_4) { + nm_ip4_config_intersect (priv->con_ip_config_4, priv->ext_ip_config_4, default_route_metric_penalty_get (self, AF_INET)); } intersect_ext_config (self, &priv->dev_ip4_config); - intersect_ext_config (self, &priv->wwan_ip4_config); + intersect_ext_config (self, &priv->wwan_ip_config_4); - for (iter = priv->vpn4_configs; iter; iter = iter->next) - nm_ip4_config_intersect (iter->data, priv->ext_ip4_config, 0); + for (iter = priv->vpn_configs_4; iter; iter = iter->next) + nm_ip4_config_intersect (iter->data, priv->ext_ip_config_4, 0); } - /* Remove parts from ext_ip4_config to only contain the information that + /* Remove parts from ext_ip_config_4 to only contain the information that * was configured externally -- we already have the same configuration from * internal origins. */ - if (priv->con_ip4_config) { - nm_ip4_config_subtract (priv->ext_ip4_config, priv->con_ip4_config, + if (priv->con_ip_config_4) { + nm_ip4_config_subtract (priv->ext_ip_config_4, priv->con_ip_config_4, default_route_metric_penalty_get (self, AF_INET)); } if (applied_config_get_current (&priv->dev_ip4_config)) { - nm_ip_config_subtract ((NMIPConfig *) priv->ext_ip4_config, + nm_ip_config_subtract ((NMIPConfig *) priv->ext_ip_config_4, applied_config_get_current (&priv->dev_ip4_config), default_route_metric_penalty_get (self, AF_INET)); } - if (applied_config_get_current (&priv->wwan_ip4_config)) { - nm_ip_config_subtract ((NMIPConfig *) priv->ext_ip4_config, - applied_config_get_current (&priv->wwan_ip4_config), + if (applied_config_get_current (&priv->wwan_ip_config_4)) { + nm_ip_config_subtract ((NMIPConfig *) priv->ext_ip_config_4, + applied_config_get_current (&priv->wwan_ip_config_4), default_route_metric_penalty_get (self, AF_INET)); } - for (iter = priv->vpn4_configs; iter; iter = iter->next) - nm_ip4_config_subtract (priv->ext_ip4_config, iter->data, 0); + for (iter = priv->vpn_configs_4; iter; iter = iter->next) + nm_ip4_config_subtract (priv->ext_ip_config_4, iter->data, 0); } } else { nm_assert (addr_family == AF_INET6); - g_clear_object (&priv->ext_ip6_config); + g_clear_object (&priv->ext_ip_config_6); g_clear_object (&priv->ext_ip6_config_captured); priv->ext_ip6_config_captured = nm_ip6_config_capture (nm_device_get_multi_index (self), nm_device_get_platform (self), ifindex, - capture_resolv_conf, NM_SETTING_IP6_CONFIG_PRIVACY_UNKNOWN); if (priv->ext_ip6_config_captured) { - priv->ext_ip6_config = nm_ip6_config_new_cloned (priv->ext_ip6_config_captured); + priv->ext_ip_config_6 = nm_ip6_config_new_cloned (priv->ext_ip6_config_captured); if (intersect_configs) { /* This function was called upon external changes. Remove the configuration * (addresses,routes) that is no longer present externally from the internal * config. This way, we don't re-add addresses that were manually removed * by the user. */ - if (priv->con_ip6_config) { - nm_ip6_config_intersect (priv->con_ip6_config, priv->ext_ip6_config, + if (priv->con_ip_config_6) { + nm_ip6_config_intersect (priv->con_ip_config_6, priv->ext_ip_config_6, default_route_metric_penalty_get (self, AF_INET6)); } intersect_ext_config (self, &priv->ac_ip6_config); intersect_ext_config (self, &priv->dhcp6.ip6_config); - intersect_ext_config (self, &priv->wwan_ip6_config); + intersect_ext_config (self, &priv->wwan_ip_config_6); - for (iter = priv->vpn6_configs; iter; iter = iter->next) - nm_ip6_config_intersect (iter->data, priv->ext_ip6_config, 0); + for (iter = priv->vpn_configs_6; iter; iter = iter->next) + nm_ip6_config_intersect (iter->data, priv->ext_ip_config_6, 0); } - /* Remove parts from ext_ip6_config to only contain the information that + /* Remove parts from ext_ip_config_6 to only contain the information that * was configured externally -- we already have the same configuration from * internal origins. */ - if (priv->con_ip6_config) { - nm_ip6_config_subtract (priv->ext_ip6_config, priv->con_ip6_config, + if (priv->con_ip_config_6) { + nm_ip6_config_subtract (priv->ext_ip_config_6, priv->con_ip_config_6, default_route_metric_penalty_get (self, AF_INET6)); } if (applied_config_get_current (&priv->ac_ip6_config)) { - nm_ip_config_subtract ((NMIPConfig *) priv->ext_ip6_config, + nm_ip_config_subtract ((NMIPConfig *) priv->ext_ip_config_6, applied_config_get_current (&priv->ac_ip6_config), default_route_metric_penalty_get (self, AF_INET6)); } if (applied_config_get_current (&priv->dhcp6.ip6_config)) { - nm_ip_config_subtract ((NMIPConfig *) priv->ext_ip6_config, + nm_ip_config_subtract ((NMIPConfig *) priv->ext_ip_config_6, applied_config_get_current (&priv->dhcp6.ip6_config), default_route_metric_penalty_get (self, AF_INET6)); } - if (applied_config_get_current (&priv->wwan_ip6_config)) { - nm_ip_config_subtract ((NMIPConfig *) priv->ext_ip6_config, - applied_config_get_current (&priv->wwan_ip6_config), + if (applied_config_get_current (&priv->wwan_ip_config_6)) { + nm_ip_config_subtract ((NMIPConfig *) priv->ext_ip_config_6, + applied_config_get_current (&priv->wwan_ip_config_6), default_route_metric_penalty_get (self, AF_INET6)); } - for (iter = priv->vpn6_configs; iter; iter = iter->next) - nm_ip6_config_subtract (priv->ext_ip6_config, iter->data, 0); + for (iter = priv->vpn_configs_6; iter; iter = iter->next) + nm_ip6_config_subtract (priv->ext_ip_config_6, iter->data, 0); } } @@ -11531,163 +11313,139 @@ update_ext_ip_config (NMDevice *self, int addr_family, gboolean initial, gboolea } static void -update_ip_config (NMDevice *self, int addr_family, gboolean initial) +update_ip_config (NMDevice *self, int addr_family) { NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); nm_assert_addr_family (addr_family); - if (update_ext_ip_config (self, addr_family, initial, TRUE)) { + if (addr_family == AF_INET) + priv->update_ip_config_completed_v4 = TRUE; + else + priv->update_ip_config_completed_v6 = TRUE; + + if (update_ext_ip_config (self, addr_family, TRUE)) { if (addr_family == AF_INET) { - if (priv->ext_ip4_config) - ip4_config_merge_and_apply (self, FALSE); + if (priv->ext_ip_config_4) + ip_config_merge_and_apply (self, AF_INET, FALSE); } else { if (priv->ext_ip6_config_captured) - ip6_config_merge_and_apply (self, FALSE); + ip_config_merge_and_apply (self, AF_INET6, FALSE); } } - - if ( addr_family == AF_INET6 - && priv->linklocal6_timeout_id - && priv->ext_ip6_config_captured - && nm_ip6_config_get_address_first_nontentative (priv->ext_ip6_config_captured, TRUE)) { - /* linklocal6 is ready now, do the state transition... we are also - * invoked as g_idle_add, so no problems with reentrance doing it now. - */ - linklocal6_complete (self); - } } void nm_device_capture_initial_config (NMDevice *self) { - update_ip_config (self, AF_INET, TRUE); - update_ip_config (self, AF_INET6, TRUE); -} - -static gboolean -queued_ip4_config_change (gpointer user_data) -{ - NMDevice *self = user_data; - NMDevicePrivate *priv; - - g_return_val_if_fail (NM_IS_DEVICE (self), G_SOURCE_REMOVE); - - priv = NM_DEVICE_GET_PRIVATE (self); - - nm_assert (!priv->queued_ip4_config_pending); - - /* Wait for any queued state changes */ - if (priv->queued_state.id) - return TRUE; - - priv->queued_ip4_config_id = 0; - - /* If a commit is scheduled, this function would potentially interfere with - * it changing IP configurations before they are applied. Postpone the - * update in such case. - */ - if (activation_source_is_scheduled (self, - activate_stage5_ip4_config_result, - AF_INET)) { - priv->queued_ip4_config_pending = FALSE; - priv->queued_ip4_config_id = g_idle_add (queued_ip4_config_change, self); - _LOGT (LOGD_DEVICE, "IP4 update was postponed"); - } else - update_ip_config (self, AF_INET, FALSE); - - set_unmanaged_external_down (self, TRUE); - - if (!nm_device_sys_iface_state_is_external_or_assume (self)) { - priv->v4_has_shadowed_routes = _v4_has_shadowed_routes_detect (self);; - ip4_rp_filter_update (self); - } + NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); - return FALSE; + if (!priv->update_ip_config_completed_v4) + update_ip_config (self, AF_INET); + if (!priv->update_ip_config_completed_v6) + update_ip_config (self, AF_INET6); } static gboolean -queued_ip6_config_change (gpointer user_data) +queued_ip_config_change (NMDevice *self, int addr_family) { - NMDevice *self = user_data; NMDevicePrivate *priv; gboolean need_ipv6ll = FALSE; + const gboolean IS_IPv4 = (addr_family == AF_INET); NMPlatform *platform; g_return_val_if_fail (NM_IS_DEVICE (self), G_SOURCE_REMOVE); priv = NM_DEVICE_GET_PRIVATE (self); - nm_assert (!priv->queued_ip4_config_pending); + nm_assert (IS_IPv4 ? !priv->queued_ip4_config_pending : !priv->queued_ip6_config_pending); /* Wait for any queued state changes */ if (priv->queued_state.id) - return TRUE; + return G_SOURCE_CONTINUE; - priv->queued_ip6_config_id = 0; + priv->queued_ip_config_id_x[IS_IPv4] = 0; /* If a commit is scheduled, this function would potentially interfere with * it changing IP configurations before they are applied. Postpone the * update in such case. */ if (activation_source_is_scheduled (self, - activate_stage5_ip6_config_commit, - AF_INET6)) { - priv->queued_ip6_config_pending = FALSE; - priv->queued_ip6_config_id = g_idle_add (queued_ip6_config_change, self); - _LOGT (LOGD_DEVICE, "IP6 update was postponed"); - } else - update_ip_config (self, AF_INET6, FALSE); + IS_IPv4 + ? activate_stage5_ip4_config_result + : activate_stage5_ip6_config_commit, + addr_family)) { + if (IS_IPv4) { + priv->queued_ip4_config_pending = FALSE; + priv->queued_ip_config_id_4 = g_idle_add (queued_ip4_config_change, self); + } else { + priv->queued_ip6_config_pending = FALSE; + priv->queued_ip_config_id_6 = g_idle_add (queued_ip6_config_change, self); + } + _LOGT (LOGD_DEVICE, "IP%c update was postponed", + nm_utils_addr_family_to_char (addr_family)); + } else { + update_ip_config (self, addr_family); - if ( priv->state < NM_DEVICE_STATE_DEACTIVATING - && (platform = nm_device_get_platform (self)) - && nm_platform_link_get (platform, priv->ifindex)) { - /* Handle DAD failures */ - while (priv->dad6_failed_addrs) { - nm_auto_nmpobj const NMPObject *obj = NULL; - const NMPlatformIP6Address *addr; + if (!IS_IPv4) { + /* Check whether we need to complete waiting for link-local. + * We are also called from an idle handler, so no problem doing state transitions + * now. */ + linklocal6_check_complete (self); + } + } - obj = priv->dad6_failed_addrs->data; - priv->dad6_failed_addrs = g_slist_delete_link (priv->dad6_failed_addrs, priv->dad6_failed_addrs); + if (!IS_IPv4) { + if ( priv->state < NM_DEVICE_STATE_DEACTIVATING + && (platform = nm_device_get_platform (self)) + && nm_platform_link_get (platform, priv->ifindex)) { + /* Handle DAD failures */ + while (priv->dad6_failed_addrs) { + nm_auto_nmpobj const NMPObject *obj = NULL; + const NMPlatformIP6Address *addr; - if (!nm_ndisc_dad_addr_is_fail_candidate (platform, obj)) - continue; + obj = priv->dad6_failed_addrs->data; + priv->dad6_failed_addrs = g_slist_delete_link (priv->dad6_failed_addrs, priv->dad6_failed_addrs); - addr = NMP_OBJECT_CAST_IP6_ADDRESS (obj); + if (!nm_ndisc_dad_addr_is_fail_candidate (platform, obj)) + continue; - _LOGI (LOGD_IP6, "ipv6: duplicate address check failed for the %s address", - nm_platform_ip6_address_to_string (addr, NULL, 0)); + addr = NMP_OBJECT_CAST_IP6_ADDRESS (obj); - if (IN6_IS_ADDR_LINKLOCAL (&addr->address)) - need_ipv6ll = TRUE; - else if (priv->ndisc) - nm_ndisc_dad_failed (priv->ndisc, &addr->address); - } + _LOGI (LOGD_IP6, "ipv6: duplicate address check failed for the %s address", + nm_platform_ip6_address_to_string (addr, NULL, 0)); - /* If no IPv6 link-local address exists but other addresses do then we - * must add the LL address to remain conformant with RFC 3513 chapter 2.1 - * ("Addressing Model"): "All interfaces are required to have at least - * one link-local unicast address". - */ - if (priv->ip6_config && nm_ip6_config_get_num_addresses (priv->ip6_config)) - need_ipv6ll = TRUE; + if (IN6_IS_ADDR_LINKLOCAL (&addr->address)) + need_ipv6ll = TRUE; + else if (priv->ndisc) + nm_ndisc_dad_failed (priv->ndisc, &addr->address); + } - if (need_ipv6ll) - check_and_add_ipv6ll_addr (self); - } else { - g_slist_free_full (priv->dad6_failed_addrs, (GDestroyNotify) nmp_object_unref); - priv->dad6_failed_addrs = NULL; - } + /* If no IPv6 link-local address exists but other addresses do then we + * must add the LL address to remain conformant with RFC 3513 chapter 2.1 + * ("Addressing Model"): "All interfaces are required to have at least + * one link-local unicast address". + */ + if ( priv->ip_config_6 + && nm_ip6_config_get_num_addresses (priv->ip_config_6)) + need_ipv6ll = TRUE; + + if (need_ipv6ll) + check_and_add_ipv6ll_addr (self); + } else { + g_slist_free_full (priv->dad6_failed_addrs, (GDestroyNotify) nmp_object_unref); + priv->dad6_failed_addrs = NULL; + } - /* Check if DAD is still pending */ - if ( priv->ip6_state == IP_CONF - && priv->dad6_ip6_config - && priv->ext_ip6_config_captured) { - if (!nm_ip6_config_has_any_dad_pending (priv->ext_ip6_config_captured, - priv->dad6_ip6_config)) { + /* Check if DAD is still pending */ + if ( priv->ip6_state == IP_CONF + && priv->dad6_ip6_config + && priv->ext_ip6_config_captured + && !nm_ip6_config_has_any_dad_pending (priv->ext_ip6_config_captured, + priv->dad6_ip6_config)) { _LOGD (LOGD_DEVICE | LOGD_IP6, "IPv6 DAD terminated"); g_clear_object (&priv->dad6_ip6_config); - _set_ip_state (self, AF_INET6, IP_DONE); + _set_ip_state (self, addr_family, IP_DONE); check_ip_state (self, FALSE, TRUE); if (priv->rt6_temporary_not_available) nm_device_activate_schedule_ip6_config_result (self); @@ -11696,7 +11454,26 @@ queued_ip6_config_change (gpointer user_data) set_unmanaged_external_down (self, TRUE); - return FALSE; + if (IS_IPv4) { + if (!nm_device_sys_iface_state_is_external_or_assume (self)) { + priv->v4_has_shadowed_routes = _v4_has_shadowed_routes_detect (self);; + ip4_rp_filter_update (self); + } + } + + return G_SOURCE_REMOVE; +} + +static gboolean +queued_ip4_config_change (gpointer user_data) +{ + return queued_ip_config_change (user_data, AF_INET); +} + +static gboolean +queued_ip6_config_change (gpointer user_data) +{ + return queued_ip_config_change (user_data, AF_INET6); } static void @@ -11722,10 +11499,10 @@ device_ipx_changed (NMPlatform *platform, case NMP_OBJECT_TYPE_IP4_ROUTE: if (nm_device_get_unmanaged_flags (self, NM_UNMANAGED_PLATFORM_INIT)) { priv->queued_ip4_config_pending = TRUE; - nm_assert_se (!nm_clear_g_source (&priv->queued_ip4_config_id)); - } else if (!priv->queued_ip4_config_id) { + nm_assert_se (!nm_clear_g_source (&priv->queued_ip_config_id_4)); + } else if (!priv->queued_ip_config_id_4) { priv->queued_ip4_config_pending = FALSE; - priv->queued_ip4_config_id = g_idle_add (queued_ip4_config_change, self); + priv->queued_ip_config_id_4 = g_idle_add (queued_ip4_config_change, self); _LOGD (LOGD_DEVICE, "queued IP4 config change"); } break; @@ -11742,10 +11519,10 @@ device_ipx_changed (NMPlatform *platform, case NMP_OBJECT_TYPE_IP6_ROUTE: if (nm_device_get_unmanaged_flags (self, NM_UNMANAGED_PLATFORM_INIT)) { priv->queued_ip6_config_pending = TRUE; - nm_assert_se (!nm_clear_g_source (&priv->queued_ip6_config_id)); - } else if (!priv->queued_ip6_config_id) { + nm_assert_se (!nm_clear_g_source (&priv->queued_ip_config_id_6)); + } else if (!priv->queued_ip_config_id_6) { priv->queued_ip6_config_pending = FALSE; - priv->queued_ip6_config_id = g_idle_add (queued_ip6_config_change, self); + priv->queued_ip_config_id_6 = g_idle_add (queued_ip6_config_change, self); _LOGD (LOGD_DEVICE, "queued IP6 config change"); } break; @@ -12013,14 +11790,14 @@ _set_unmanaged_flags (NMDevice *self, if (priv->queued_ip4_config_pending) { priv->queued_ip4_config_pending = FALSE; - nm_assert_se (!nm_clear_g_source (&priv->queued_ip4_config_id)); - priv->queued_ip4_config_id = g_idle_add (queued_ip4_config_change, self); + nm_assert_se (!nm_clear_g_source (&priv->queued_ip_config_id_4)); + priv->queued_ip_config_id_4 = g_idle_add (queued_ip4_config_change, self); } if (priv->queued_ip6_config_pending) { priv->queued_ip6_config_pending = FALSE; - nm_assert_se (!nm_clear_g_source (&priv->queued_ip6_config_id)); - priv->queued_ip6_config_id = g_idle_add (queued_ip6_config_change, self); + nm_assert_se (!nm_clear_g_source (&priv->queued_ip_config_id_6)); + priv->queued_ip_config_id_6 = g_idle_add (queued_ip6_config_change, self); } if (!priv->pending_actions) { @@ -12354,9 +12131,9 @@ nm_device_update_metered (NMDevice *self) /* Try to guess a value using the metered flag in IP configuration */ if (value == NM_METERED_INVALID) { - if ( priv->ip4_config + if ( priv->ip_config_4 && priv->ip4_state == IP_DONE - && nm_ip4_config_get_metered (priv->ip4_config)) + && nm_ip4_config_get_metered (priv->ip_config_4)) value = NM_METERED_GUESS_YES; } @@ -12851,8 +12628,8 @@ _cleanup_generic_pre (NMDevice *self, CleanupType cleanup_type) queued_state_clear (self); - _cleanup_ip4_pre (self, cleanup_type); - _cleanup_ip6_pre (self, cleanup_type); + _cleanup_ip_pre (self, AF_INET, cleanup_type); + _cleanup_ip_pre (self, AF_INET6, cleanup_type); } static void @@ -12874,31 +12651,31 @@ _cleanup_generic_post (NMDevice *self, CleanupType cleanup_type) /* Clean up IP configs; this does not actually deconfigure the * interface; the caller must flush routes and addresses explicitly. */ - nm_device_set_ip4_config (self, NULL, TRUE, NULL); - nm_device_set_ip6_config (self, NULL, TRUE); + nm_device_set_ip_config (self, AF_INET, NULL, TRUE, NULL); + nm_device_set_ip_config (self, AF_INET6, NULL, TRUE, NULL); g_clear_object (&priv->proxy_config); - g_clear_object (&priv->con_ip4_config); + g_clear_object (&priv->con_ip_config_4); applied_config_clear (&priv->dev_ip4_config); - applied_config_clear (&priv->wwan_ip4_config); - g_clear_object (&priv->ext_ip4_config); - g_clear_object (&priv->ip4_config); - g_clear_object (&priv->con_ip6_config); + applied_config_clear (&priv->wwan_ip_config_4); + g_clear_object (&priv->ext_ip_config_4); + g_clear_object (&priv->ip_config_4); + g_clear_object (&priv->con_ip_config_6); applied_config_clear (&priv->ac_ip6_config); - g_clear_object (&priv->ext_ip6_config); + g_clear_object (&priv->ext_ip_config_6); g_clear_object (&priv->ext_ip6_config_captured); - applied_config_clear (&priv->wwan_ip6_config); - g_clear_object (&priv->ip6_config); + applied_config_clear (&priv->wwan_ip_config_6); + g_clear_object (&priv->ip_config_6); g_clear_object (&priv->dad6_ip6_config); g_clear_pointer (&priv->rt6_temporary_not_available, g_hash_table_unref); nm_clear_g_source (&priv->rt6_temporary_not_available_id); - g_slist_free_full (priv->vpn4_configs, g_object_unref); - priv->vpn4_configs = NULL; - g_slist_free_full (priv->vpn6_configs, g_object_unref); - priv->vpn6_configs = NULL; + g_slist_free_full (priv->vpn_configs_4, g_object_unref); + priv->vpn_configs_4 = NULL; + g_slist_free_full (priv->vpn_configs_6, g_object_unref); + priv->vpn_configs_6 = NULL; - /* We no longer accept the delegations. nm_device_set_ip6_config(NULL) + /* We no longer accept the delegations. nm_device_set_ip_config(NULL) * above disables them. */ nm_assert (priv->needs_ip6_subnet == FALSE); @@ -13048,10 +12825,10 @@ find_dhcp4_address (NMDevice *self) const NMPlatformIP4Address *a; NMDedupMultiIter ipconf_iter; - if (!priv->ip4_config) + if (!priv->ip_config_4) return NULL; - nm_ip_config_iter_ip4_address_for_each (&ipconf_iter, priv->ip4_config, &a) { + nm_ip_config_iter_ip4_address_for_each (&ipconf_iter, priv->ip_config_4, &a) { if (a->addr_source == NM_IP_CONFIG_SOURCE_DHCP) return g_strdup (nm_utils_inet4_ntop (a->address, NULL)); } @@ -13466,8 +13243,8 @@ _set_state_full (NMDevice *self, /* Clean up any half-done IP operations if the device's layer2 * finds out it needs authentication during IP config. */ - _cleanup_ip4_pre (self, CLEANUP_TYPE_DECONFIGURE); - _cleanup_ip6_pre (self, CLEANUP_TYPE_DECONFIGURE); + _cleanup_ip_pre (self, AF_INET, CLEANUP_TYPE_DECONFIGURE); + _cleanup_ip_pre (self, AF_INET6, CLEANUP_TYPE_DECONFIGURE); } break; default: @@ -15001,13 +14778,13 @@ get_property (GObject *object, guint prop_id, g_value_set_uint (value, priv->mtu); break; case PROP_IP4_CONFIG: - nm_dbus_utils_g_value_set_object_path (value, ip_config_valid (priv->state) ? priv->ip4_config : NULL); + nm_dbus_utils_g_value_set_object_path (value, ip_config_valid (priv->state) ? priv->ip_config_4 : NULL); break; case PROP_DHCP4_CONFIG: nm_dbus_utils_g_value_set_object_path (value, ip_config_valid (priv->state) ? priv->dhcp4.config : NULL); break; case PROP_IP6_CONFIG: - nm_dbus_utils_g_value_set_object_path (value, ip_config_valid (priv->state) ? priv->ip6_config : NULL); + nm_dbus_utils_g_value_set_object_path (value, ip_config_valid (priv->state) ? priv->ip_config_6 : NULL); break; case PROP_DHCP6_CONFIG: nm_dbus_utils_g_value_set_object_path (value, ip_config_valid (priv->state) ? priv->dhcp6.config : NULL); diff --git a/src/dhcp/nm-dhcp-client.h b/src/dhcp/nm-dhcp-client.h index f389f534c2..0d92d74304 100644 --- a/src/dhcp/nm-dhcp-client.h +++ b/src/dhcp/nm-dhcp-client.h @@ -194,13 +194,6 @@ typedef struct { GType (*get_type)(void); const char *name; const char *(*get_path) (void); - GSList *(*get_lease_ip_configs) (struct _NMDedupMultiIndex *multi_idx, - int addr_family, - const char *iface, - int ifindex, - const char *uuid, - guint32 route_table, - guint32 route_metric); } NMDhcpClientFactory; extern const NMDhcpClientFactory _nm_dhcp_client_factory_dhcpcanon; diff --git a/src/dhcp/nm-dhcp-dhclient-utils.c b/src/dhcp/nm-dhcp-dhclient-utils.c index 70d70fd60a..52923310b8 100644 --- a/src/dhcp/nm-dhcp-dhclient-utils.c +++ b/src/dhcp/nm-dhcp-dhclient-utils.c @@ -643,259 +643,3 @@ nm_dhcp_dhclient_save_duid (const char *leasefile, g_string_free (s, TRUE); return success; } - -static void -add_lease_option (GHashTable *hash, char *line) -{ - char *spc; - size_t len; - - /* Find the space after "option" */ - spc = strchr (line, ' '); - if (!spc) - return; - - /* Find the option tag's data, which is after the second space */ - if (g_str_has_prefix (line, "option ")) { - while (g_ascii_isspace (*spc)) - spc++; - spc = strchr (spc + 1, ' '); - if (!spc) - return; - } - - /* Split the line at the space */ - *spc = '\0'; - spc++; - - /* Kill the ';' at the end of the line, if any */ - len = strlen (spc); - if (*(spc + len - 1) == ';') - *(spc + len - 1) = '\0'; - - /* Strip leading quote */ - while (g_ascii_isspace (*spc)) - spc++; - if (*spc == '"') - spc++; - - /* Strip trailing quote */ - len = strlen (spc); - if (len > 0 && spc[len - 1] == '"') - spc[len - 1] = '\0'; - - if (spc[0]) - g_hash_table_insert (hash, g_strdup (line), g_strdup (spc)); -} - -#define LEASE_INVALID G_MININT64 -static GTimeSpan -lease_validity_span (const char *str_expire, GDateTime *now) -{ - GDateTime *expire = NULL; - struct tm expire_tm; - GTimeSpan span; - - g_return_val_if_fail (now != NULL, LEASE_INVALID); - g_return_val_if_fail (str_expire != NULL, LEASE_INVALID); - - /* Skip initial number (day of week?) */ - if (!isdigit (*str_expire++)) - return LEASE_INVALID; - if (!isspace (*str_expire++)) - return LEASE_INVALID; - /* Read lease expiration (in UTC) */ - if (!strptime (str_expire, "%t%Y/%m/%d %H:%M:%S", &expire_tm)) - return LEASE_INVALID; - - expire = g_date_time_new_utc (expire_tm.tm_year + 1900, - expire_tm.tm_mon + 1, - expire_tm.tm_mday, - expire_tm.tm_hour, - expire_tm.tm_min, - expire_tm.tm_sec); - if (!expire) - return LEASE_INVALID; - - span = g_date_time_difference (expire, now); - g_date_time_unref (expire); - - /* GDateTime only supports a range of less then 10000 years, so span can - * not overflow or be equal to LEASE_INVALID */ - return span; -} - -/** - * nm_dhcp_dhclient_read_lease_ip_configs: - * @multi_idx: the multi index instance for the ip config object - * @addr_family: whether to read IPv4 or IPv6 leases - * @iface: the interface name to match leases with - * @ifindex: interface index of @iface - * @route_table: the route table for the default route. - * @route_metric: the route metric for the default route. - * @contents: the contents of a dhclient leasefile - * @now: the current UTC date/time; pass %NULL to automatically use current - * UTC time. Testcases may need a different value for 'now' - * - * Reads dhclient leases from @contents and parses them into either - * #NMIP4Config or #NMIP6Config objects depending on the value of @addr_family. - * - * Returns: a #GSList of #NMIP4Config objects (if @addr_family is %AF_INET) or a list of - * #NMIP6Config objects (if @addr_family is %AF_INET6) containing the lease data. - */ -GSList * -nm_dhcp_dhclient_read_lease_ip_configs (NMDedupMultiIndex *multi_idx, - int addr_family, - const char *iface, - int ifindex, - guint32 route_table, - guint32 route_metric, - const char *contents, - GDateTime *now) -{ - GSList *parsed = NULL, *iter, *leases = NULL; - char **line, **split = NULL; - GHashTable *hash = NULL; - gint32 now_monotonic_ts; - - g_return_val_if_fail (contents != NULL, NULL); - nm_assert (NM_IN_SET (addr_family, AF_INET, AF_INET6)); - - split = g_strsplit_set (contents, "\n\r", -1); - if (!split) - return NULL; - - for (line = split; line && *line; line++) { - *line = g_strstrip (*line); - - if (*line[0] == '#') { - /* Comment */ - } else if (!strcmp (*line, "}")) { - /* Lease ends */ - parsed = g_slist_append (parsed, hash); - hash = NULL; - } else if (!strcmp (*line, "lease {")) { - /* Beginning of a new lease */ - if (hash) { - /* Ignore malformed lease that doesn't end before new one starts */ - g_hash_table_destroy (hash); - } - - hash = g_hash_table_new_full (nm_str_hash, g_str_equal, g_free, g_free); - } else if (hash && strlen (*line)) - add_lease_option (hash, *line); - } - g_strfreev (split); - - /* Check if the last lease in the file was properly ended */ - if (hash) { - /* Ignore malformed lease that doesn't end before new one starts */ - g_hash_table_destroy (hash); - hash = NULL; - } - - if (now) - g_date_time_ref (now); - else - now = g_date_time_new_now_utc (); - now_monotonic_ts = nm_utils_get_monotonic_timestamp_s (); - - for (iter = parsed; iter; iter = g_slist_next (iter)) { - NMIP4Config *ip4; - NMPlatformIP4Address address; - const char *value; - GTimeSpan expiry; - guint32 tmp, gw = 0; - - hash = iter->data; - - /* Make sure this lease is for the interface we want */ - value = g_hash_table_lookup (hash, "interface"); - if (!value || strcmp (value, iface)) - continue; - - value = g_hash_table_lookup (hash, "expire"); - if (!value) - continue; - expiry = lease_validity_span (value, now); - if (expiry == LEASE_INVALID) - continue; - - /* scale expiry to seconds (and CLAMP into the range of guint32) */ - expiry = CLAMP (expiry / G_TIME_SPAN_SECOND, 0, NM_PLATFORM_LIFETIME_PERMANENT-1); - if (expiry <= 0) { - /* the address is already expired. Don't even add it. */ - continue; - } - - memset (&address, 0, sizeof (address)); - - /* IP4 address */ - value = g_hash_table_lookup (hash, "fixed-address"); - if (!value) - continue; - if (!inet_pton (AF_INET, value, &address.address)) - continue; - address.peer_address = address.address; - - /* Gateway */ - value = g_hash_table_lookup (hash, "option routers"); - if (!value) - continue; - if (!inet_pton (AF_INET, value, &gw)) - continue; - - /* Netmask */ - value = g_hash_table_lookup (hash, "option subnet-mask"); - if (value && inet_pton (AF_INET, value, &tmp)) - address.plen = nm_utils_ip4_netmask_to_prefix (tmp); - - /* Get default netmask for the IP according to appropriate class. */ - if (!address.plen) - address.plen = _nm_utils_ip4_get_default_prefix (address.address); - - address.timestamp = now_monotonic_ts; - address.lifetime = address.preferred = expiry; - address.addr_source = NM_IP_CONFIG_SOURCE_DHCP; - - ip4 = nm_ip4_config_new (multi_idx, ifindex); - nm_ip4_config_add_address (ip4, &address); - - { - const NMPlatformIP4Route r = { - .rt_source = NM_IP_CONFIG_SOURCE_DHCP, - .gateway = gw, - .table_coerced = nm_platform_route_table_coerce (route_table), - .metric = route_metric, - }; - - nm_ip4_config_add_route (ip4, &r, NULL); - } - - value = g_hash_table_lookup (hash, "option domain-name-servers"); - if (value) { - char **dns, **dns_iter; - - dns = g_strsplit_set (value, ",", -1); - for (dns_iter = dns; dns_iter && *dns_iter; dns_iter++) { - if (inet_pton (AF_INET, *dns_iter, &tmp)) - nm_ip4_config_add_nameserver (ip4, tmp); - } - if (dns) - g_strfreev (dns); - } - - value = g_hash_table_lookup (hash, "option domain-name"); - if (value && value[0]) - nm_ip4_config_add_domain (ip4, value); - - /* FIXME: static routes */ - - leases = g_slist_append (leases, ip4); - } - - g_date_time_unref (now); - g_slist_free_full (parsed, (GDestroyNotify) g_hash_table_destroy); - return leases; -} - diff --git a/src/dhcp/nm-dhcp-dhclient-utils.h b/src/dhcp/nm-dhcp-dhclient-utils.h index d67a4f35d3..fab9196a3b 100644 --- a/src/dhcp/nm-dhcp-dhclient-utils.h +++ b/src/dhcp/nm-dhcp-dhclient-utils.h @@ -43,15 +43,6 @@ gboolean nm_dhcp_dhclient_save_duid (const char *leasefile, const char *escaped_duid, GError **error); -GSList *nm_dhcp_dhclient_read_lease_ip_configs (struct _NMDedupMultiIndex *multi_idx, - int addr_family, - const char *iface, - int ifindex, - guint32 route_table, - guint32 route_metric, - const char *contents, - GDateTime *now); - GBytes *nm_dhcp_dhclient_get_client_id_from_config_file (const char *path); #endif /* __NETWORKMANAGER_DHCP_DHCLIENT_UTILS_H__ */ diff --git a/src/dhcp/nm-dhcp-dhclient.c b/src/dhcp/nm-dhcp-dhclient.c index 56b74d43be..738e9f9184 100644 --- a/src/dhcp/nm-dhcp-dhclient.c +++ b/src/dhcp/nm-dhcp-dhclient.c @@ -158,32 +158,6 @@ get_dhclient_leasefile (int addr_family, return NULL; } -static GSList * -nm_dhcp_dhclient_get_lease_ip_configs (NMDedupMultiIndex *multi_idx, - int addr_family, - const char *iface, - int ifindex, - const char *uuid, - guint32 route_table, - guint32 route_metric) -{ - gs_free char *contents = NULL; - gs_free char *leasefile = NULL; - - leasefile = get_dhclient_leasefile (addr_family, iface, uuid, NULL); - if (!leasefile) - return NULL; - - if ( g_file_test (leasefile, G_FILE_TEST_EXISTS) - && g_file_get_contents (leasefile, &contents, NULL, NULL) - && contents - && contents[0]) { - return nm_dhcp_dhclient_read_lease_ip_configs (multi_idx, addr_family, iface, ifindex, - route_table, route_metric, contents, NULL); - } - return NULL; -} - static gboolean merge_dhclient_config (NMDhcpDhclient *self, int addr_family, @@ -721,7 +695,6 @@ const NMDhcpClientFactory _nm_dhcp_client_factory_dhclient = { .name = "dhclient", .get_type = nm_dhcp_dhclient_get_type, .get_path = nm_dhcp_dhclient_get_path, - .get_lease_ip_configs = nm_dhcp_dhclient_get_lease_ip_configs, }; #endif /* WITH_DHCLIENT */ diff --git a/src/dhcp/nm-dhcp-dhcpcanon.c b/src/dhcp/nm-dhcp-dhcpcanon.c index 66ce45c638..82b3db4fe8 100644 --- a/src/dhcp/nm-dhcp-dhcpcanon.c +++ b/src/dhcp/nm-dhcp-dhcpcanon.c @@ -265,7 +265,6 @@ const NMDhcpClientFactory _nm_dhcp_client_factory_dhcpcanon = { .name = "dhcpcanon", .get_type = nm_dhcp_dhcpcanon_get_type, .get_path = nm_dhcp_dhcpcanon_get_path, - .get_lease_ip_configs = NULL, }; #endif /* WITH_DHCPCANON */ diff --git a/src/dhcp/nm-dhcp-dhcpcd.c b/src/dhcp/nm-dhcp-dhcpcd.c index 8e4ebb1968..c4bcb08437 100644 --- a/src/dhcp/nm-dhcp-dhcpcd.c +++ b/src/dhcp/nm-dhcp-dhcpcd.c @@ -251,7 +251,6 @@ const NMDhcpClientFactory _nm_dhcp_client_factory_dhcpcd = { .name = "dhcpcd", .get_type = nm_dhcp_dhcpcd_get_type, .get_path = nm_dhcp_dhcpcd_get_path, - .get_lease_ip_configs = NULL, }; #endif /* WITH_DHCPCD */ diff --git a/src/dhcp/nm-dhcp-manager.c b/src/dhcp/nm-dhcp-manager.c index 526dbfd796..bf22872d4e 100644 --- a/src/dhcp/nm-dhcp-manager.c +++ b/src/dhcp/nm-dhcp-manager.c @@ -333,31 +333,6 @@ nm_dhcp_manager_set_default_hostname (NMDhcpManager *manager, const char *hostna priv->default_hostname = g_strdup (hostname); } -GSList * -nm_dhcp_manager_get_lease_ip_configs (NMDhcpManager *self, - NMDedupMultiIndex *multi_idx, - int addr_family, - const char *iface, - int ifindex, - const char *uuid, - guint32 route_table, - guint32 route_metric) -{ - NMDhcpManagerPrivate *priv; - - g_return_val_if_fail (NM_IS_DHCP_MANAGER (self), NULL); - g_return_val_if_fail (iface != NULL, NULL); - g_return_val_if_fail (ifindex >= -1, NULL); - g_return_val_if_fail (uuid != NULL, NULL); - g_return_val_if_fail (NM_IN_SET (addr_family, AF_INET, AF_INET6), NULL); - - priv = NM_DHCP_MANAGER_GET_PRIVATE (self); - if ( priv->client_factory - && priv->client_factory->get_lease_ip_configs) - return priv->client_factory->get_lease_ip_configs (multi_idx, addr_family, iface, ifindex, uuid, route_table, route_metric); - return NULL; -} - const char * nm_dhcp_manager_get_config (NMDhcpManager *self) { diff --git a/src/dhcp/nm-dhcp-manager.h b/src/dhcp/nm-dhcp-manager.h index 3cf8cf871b..f8a7e31d2d 100644 --- a/src/dhcp/nm-dhcp-manager.h +++ b/src/dhcp/nm-dhcp-manager.h @@ -78,15 +78,6 @@ NMDhcpClient * nm_dhcp_manager_start_ip6 (NMDhcpManager *manager, NMSettingIP6ConfigPrivacy privacy, guint needed_prefixes); -GSList * nm_dhcp_manager_get_lease_ip_configs (NMDhcpManager *self, - struct _NMDedupMultiIndex *multi_idx, - int addr_family, - const char *iface, - int ifindex, - const char *uuid, - guint32 route_table, - guint32 route_metric); - /* For testing only */ extern const char* nm_dhcp_helper_path; diff --git a/src/dhcp/nm-dhcp-systemd.c b/src/dhcp/nm-dhcp-systemd.c index db392c421b..1305f1a2a4 100644 --- a/src/dhcp/nm-dhcp-systemd.c +++ b/src/dhcp/nm-dhcp-systemd.c @@ -450,36 +450,6 @@ get_leasefile_path (int addr_family, const char *iface, const char *uuid) iface); } -static GSList * -nm_dhcp_systemd_get_lease_ip_configs (NMDedupMultiIndex *multi_idx, - int addr_family, - const char *iface, - int ifindex, - const char *uuid, - guint32 route_table, - guint32 route_metric) -{ - GSList *leases = NULL; - gs_free char *path = NULL; - sd_dhcp_lease *lease = NULL; - NMIP4Config *ip4_config; - int r; - - if (addr_family != AF_INET) - return NULL; - - path = get_leasefile_path (addr_family, iface, uuid); - r = dhcp_lease_load (&lease, path); - if (r == 0 && lease) { - ip4_config = lease_to_ip4_config (multi_idx, iface, ifindex, lease, NULL, route_table, route_metric, FALSE, NULL); - if (ip4_config) - leases = g_slist_append (leases, ip4_config); - sd_dhcp_lease_unref (lease); - } - - return leases; -} - /*****************************************************************************/ static void @@ -1091,5 +1061,4 @@ const NMDhcpClientFactory _nm_dhcp_client_factory_internal = { .name = "internal", .get_type = nm_dhcp_systemd_get_type, .get_path = NULL, - .get_lease_ip_configs = nm_dhcp_systemd_get_lease_ip_configs, }; diff --git a/src/dhcp/tests/leases/basic.leases b/src/dhcp/tests/leases/basic.leases deleted file mode 100644 index 703d92479d..0000000000 --- a/src/dhcp/tests/leases/basic.leases +++ /dev/null @@ -1,31 +0,0 @@ -lease { - interface "wlan0"; - fixed-address 192.168.1.180; - option subnet-mask 255.255.255.0; - option routers 192.168.1.1; - option dhcp-lease-time 600; - option dhcp-message-type 5; - option domain-name-servers 192.168.1.1; - option dhcp-server-identifier 192.168.1.1; - option broadcast-address 192.168.1.255; - renew 5 2013/11/01 19:56:15; - rebind 5 2013/11/01 20:00:44; - expire 5 2013/11/01 20:01:59; -} -lease { - interface "wlan0"; - fixed-address 10.77.52.141; - option subnet-mask 255.0.0.0; - option dhcp-lease-time 1200; - option routers 10.77.52.254; - option dhcp-message-type 5; - option dhcp-server-identifier 10.77.52.254; - option domain-name-servers 8.8.8.8,8.8.4.4; - option dhcp-renewal-time 600; - option dhcp-rebinding-time 1050; - option domain-name "morriesguest.local"; - renew 5 2013/11/01 20:01:08; - rebind 5 2013/11/01 20:05:00; - expire 5 2013/11/01 20:06:15; -} - diff --git a/src/dhcp/tests/leases/malformed1.leases b/src/dhcp/tests/leases/malformed1.leases deleted file mode 100644 index 401d982ad4..0000000000 --- a/src/dhcp/tests/leases/malformed1.leases +++ /dev/null @@ -1,15 +0,0 @@ -# missing fixed-address option -lease { - interface "wlan0"; - option subnet-mask 255.255.255.0; - option routers 192.168.1.1; - option dhcp-lease-time 600; - option dhcp-message-type 5; - option domain-name-servers 192.168.1.1; - option dhcp-server-identifier 192.168.1.1; - option broadcast-address 192.168.1.255; - renew 5 2013/11/01 19:56:15; - rebind 5 2013/11/01 20:00:44; - expire 5 2013/11/01 20:01:59; -} - diff --git a/src/dhcp/tests/leases/malformed2.leases b/src/dhcp/tests/leases/malformed2.leases deleted file mode 100644 index adf5f6decc..0000000000 --- a/src/dhcp/tests/leases/malformed2.leases +++ /dev/null @@ -1,15 +0,0 @@ -# missing routers option -lease { - interface "wlan0"; - fixed-address 192.168.1.180; - option subnet-mask 255.255.255.0; - option dhcp-lease-time 600; - option dhcp-message-type 5; - option domain-name-servers 192.168.1.1; - option dhcp-server-identifier 192.168.1.1; - option broadcast-address 192.168.1.255; - renew 5 2013/11/01 19:56:15; - rebind 5 2013/11/01 20:00:44; - expire 5 2013/11/01 20:01:59; -} - diff --git a/src/dhcp/tests/leases/malformed3.leases b/src/dhcp/tests/leases/malformed3.leases deleted file mode 100644 index a2afc8b6c3..0000000000 --- a/src/dhcp/tests/leases/malformed3.leases +++ /dev/null @@ -1,15 +0,0 @@ -# missing expire time -lease { - interface "wlan0"; - fixed-address 192.168.1.180; - option subnet-mask 255.255.255.0; - option routers 192.168.1.1; - option dhcp-lease-time 600; - option dhcp-message-type 5; - option domain-name-servers 192.168.1.1; - option dhcp-server-identifier 192.168.1.1; - option broadcast-address 192.168.1.255; - renew 5 2013/11/01 19:56:15; - rebind 5 2013/11/01 20:00:44; -} - diff --git a/src/dhcp/tests/test-dhcp-dhclient.c b/src/dhcp/tests/test-dhcp-dhclient.c index f1b0a1a1b1..25af51a135 100644 --- a/src/dhcp/tests/test-dhcp-dhclient.c +++ b/src/dhcp/tests/test-dhcp-dhclient.c @@ -36,12 +36,6 @@ #include "nm-test-utils-core.h" -#define DEBUG 1 - -static const int IFINDEX = 5; -static const guint32 ROUTE_TABLE = RT_TABLE_MAIN; -static const guint32 ROUTE_METRIC = 100; - static void test_config (const char *orig, const char *expected, @@ -993,133 +987,6 @@ test_config_req_intf (void) /*****************************************************************************/ -static void -test_read_lease_ip4_config_basic (void) -{ - nm_auto_unref_dedup_multi_index NMDedupMultiIndex *multi_idx = nm_dedup_multi_index_new (); - GError *error = NULL; - char *contents = NULL; - gboolean success; - const char *path = TESTDIR "/leases/basic.leases"; - GSList *leases; - GDateTime *now; - NMIP4Config *config; - const NMPlatformIP4Address *addr; - guint32 expected_addr; - - success = g_file_get_contents (path, &contents, NULL, &error); - g_assert_no_error (error); - g_assert (success); - - /* Date from before the least expiration */ - now = g_date_time_new_utc (2013, 11, 1, 19, 55, 32); - leases = nm_dhcp_dhclient_read_lease_ip_configs (multi_idx, AF_INET, "wlan0", IFINDEX, ROUTE_TABLE, ROUTE_METRIC, contents, now); - g_assert_cmpint (g_slist_length (leases), ==, 2); - - /* IP4Config #1 */ - config = g_slist_nth_data (leases, 0); - g_assert (NM_IS_IP4_CONFIG (config)); - - /* Address */ - g_assert_cmpint (nm_ip4_config_get_num_addresses (config), ==, 1); - expected_addr = nmtst_inet4_from_string ("192.168.1.180"); - addr = _nmtst_ip4_config_get_address (config, 0); - g_assert_cmpint (addr->address, ==, expected_addr); - g_assert_cmpint (addr->peer_address, ==, expected_addr); - g_assert_cmpint (addr->plen, ==, 24); - - /* Gateway */ - expected_addr = nmtst_inet4_from_string ("192.168.1.1"); - g_assert_cmpint (nmtst_ip4_config_get_gateway (config), ==, expected_addr); - - /* DNS */ - g_assert_cmpint (nm_ip4_config_get_num_nameservers (config), ==, 1); - expected_addr = nmtst_inet4_from_string ("192.168.1.1"); - g_assert_cmpint (nm_ip4_config_get_nameserver (config, 0), ==, expected_addr); - - g_assert_cmpint (nm_ip4_config_get_num_domains (config), ==, 0); - - /* IP4Config #2 */ - config = g_slist_nth_data (leases, 1); - g_assert (NM_IS_IP4_CONFIG (config)); - - /* Address */ - g_assert_cmpint (nm_ip4_config_get_num_addresses (config), ==, 1); - expected_addr = nmtst_inet4_from_string ("10.77.52.141"); - addr = _nmtst_ip4_config_get_address (config, 0); - g_assert_cmpint (addr->address, ==, expected_addr); - g_assert_cmpint (addr->peer_address, ==, expected_addr); - g_assert_cmpint (addr->plen, ==, 8); - - /* Gateway */ - expected_addr = nmtst_inet4_from_string ("10.77.52.254"); - g_assert_cmpint (nmtst_ip4_config_get_gateway (config), ==, expected_addr); - - /* DNS */ - g_assert_cmpint (nm_ip4_config_get_num_nameservers (config), ==, 2); - expected_addr = nmtst_inet4_from_string ("8.8.8.8"); - g_assert_cmpint (nm_ip4_config_get_nameserver (config, 0), ==, expected_addr); - expected_addr = nmtst_inet4_from_string ("8.8.4.4"); - g_assert_cmpint (nm_ip4_config_get_nameserver (config, 1), ==, expected_addr); - - /* Domains */ - g_assert_cmpint (nm_ip4_config_get_num_domains (config), ==, 1); - g_assert_cmpstr (nm_ip4_config_get_domain (config, 0), ==, "morriesguest.local"); - - g_slist_free_full (leases, g_object_unref); - g_date_time_unref (now); - g_free (contents); -} - -static void -test_read_lease_ip4_config_expired (void) -{ - nm_auto_unref_dedup_multi_index NMDedupMultiIndex *multi_idx = nm_dedup_multi_index_new (); - GError *error = NULL; - char *contents = NULL; - gboolean success; - const char *path = TESTDIR "/leases/basic.leases"; - GSList *leases; - GDateTime *now; - - success = g_file_get_contents (path, &contents, NULL, &error); - g_assert_no_error (error); - g_assert (success); - - /* Date from *after* the lease expiration */ - now = g_date_time_new_utc (2013, 12, 1, 19, 55, 32); - leases = nm_dhcp_dhclient_read_lease_ip_configs (multi_idx, AF_INET, "wlan0", IFINDEX, ROUTE_TABLE, ROUTE_METRIC, contents, now); - g_assert (leases == NULL); - - g_date_time_unref (now); - g_free (contents); -} - -static void -test_read_lease_ip4_config_expect_failure (gconstpointer user_data) -{ - nm_auto_unref_dedup_multi_index NMDedupMultiIndex *multi_idx = nm_dedup_multi_index_new (); - GError *error = NULL; - char *contents = NULL; - gboolean success; - GSList *leases; - GDateTime *now; - - success = g_file_get_contents ((const char *) user_data, &contents, NULL, &error); - g_assert_no_error (error); - g_assert (success); - - /* Date from before the least expiration */ - now = g_date_time_new_utc (2013, 11, 1, 1, 1, 1); - leases = nm_dhcp_dhclient_read_lease_ip_configs (multi_idx, AF_INET, "wlan0", IFINDEX, ROUTE_TABLE, ROUTE_METRIC, contents, now); - g_assert (leases == NULL); - - g_date_time_unref (now); - g_free (contents); -} - -/*****************************************************************************/ - NMTST_DEFINE (); int @@ -1157,18 +1024,6 @@ main (int argc, char **argv) g_test_add_func ("/dhcp/dhclient/write_existing_duid", test_write_existing_duid); g_test_add_func ("/dhcp/dhclient/write_existing_commented_duid", test_write_existing_commented_duid); - g_test_add_func ("/dhcp/dhclient/leases/ip4-config/basic", test_read_lease_ip4_config_basic); - g_test_add_func ("/dhcp/dhclient/leases/ip4-config/expired", test_read_lease_ip4_config_expired); - g_test_add_data_func ("/dhcp/dhclient/leases/ip4-config/missing-address", - TESTDIR "/leases/malformed1.leases", - test_read_lease_ip4_config_expect_failure); - g_test_add_data_func ("/dhcp/dhclient/leases/ip4-config/missing-gateway", - TESTDIR "/leases/malformed2.leases", - test_read_lease_ip4_config_expect_failure); - g_test_add_data_func ("/dhcp/dhclient/leases/ip4-config/missing-expire", - TESTDIR "/leases/malformed3.leases", - test_read_lease_ip4_config_expect_failure); - return g_test_run (); } diff --git a/src/dns/nm-dns-manager.c b/src/dns/nm-dns-manager.c index 9b5120e783..56be5aab35 100644 --- a/src/dns/nm-dns-manager.c +++ b/src/dns/nm-dns-manager.c @@ -1474,23 +1474,6 @@ nm_dns_manager_set_hostname (NMDnsManager *self, } } -gboolean -nm_dns_manager_get_resolv_conf_explicit (NMDnsManager *self) -{ - NMDnsManagerPrivate *priv; - - g_return_val_if_fail (NM_IS_DNS_MANAGER (self), FALSE); - - priv = NM_DNS_MANAGER_GET_PRIVATE (self); - - if ( NM_IN_SET (priv->rc_manager, NM_DNS_MANAGER_RESOLV_CONF_MAN_UNMANAGED, - NM_DNS_MANAGER_RESOLV_CONF_MAN_IMMUTABLE) - || priv->plugin) - return FALSE; - - return TRUE; -} - void nm_dns_manager_begin_updates (NMDnsManager *self, const char *func) { diff --git a/src/dns/nm-dns-manager.h b/src/dns/nm-dns-manager.h index 663a3ad258..5688936736 100644 --- a/src/dns/nm-dns-manager.h +++ b/src/dns/nm-dns-manager.h @@ -123,8 +123,6 @@ typedef enum { NM_DNS_MANAGER_RESOLV_CONF_MAN_NETCONFIG, } NMDnsManagerResolvConfManager; -gboolean nm_dns_manager_get_resolv_conf_explicit (NMDnsManager *self); - void nm_dns_manager_stop (NMDnsManager *self); #endif /* __NETWORKMANAGER_DNS_MANAGER_H__ */ diff --git a/src/ndisc/nm-lndp-ndisc.c b/src/ndisc/nm-lndp-ndisc.c index 70200ed34c..9c7d3c4dfa 100644 --- a/src/ndisc/nm-lndp-ndisc.c +++ b/src/ndisc/nm-lndp-ndisc.c @@ -195,6 +195,10 @@ receive_ra (struct ndp *ndp, struct ndp_msg *msg, gpointer user_data) continue; nm_utils_ip6_address_clear_host_address (&r_network, ndp_msg_opt_prefix (msg, offset), r_plen); + if ( IN6_IS_ADDR_UNSPECIFIED (&r_network) + || IN6_IS_ADDR_LINKLOCAL (&r_network)) + continue; + if (ndp_msg_opt_prefix_flag_on_link (msg, offset)) { NMNDiscRoute route = { .network = r_network, diff --git a/src/ndisc/nm-ndisc.c b/src/ndisc/nm-ndisc.c index ede655dd95..ba61cb1125 100644 --- a/src/ndisc/nm-ndisc.c +++ b/src/ndisc/nm-ndisc.c @@ -351,6 +351,8 @@ nm_ndisc_add_address (NMNDisc *ndisc, const NMNDiscAddress *new) nm_assert (new); nm_assert (new->timestamp > 0 && new->timestamp < G_MAXINT32); + nm_assert (!IN6_IS_ADDR_UNSPECIFIED (&new->address)); + nm_assert (!IN6_IS_ADDR_LINKLOCAL (&new->address)); for (i = 0; i < rdata->addresses->len; i++) { NMNDiscAddress *item = &g_array_index (rdata->addresses, NMNDiscAddress, i); diff --git a/src/nm-core-utils.c b/src/nm-core-utils.c index f3e9e5f75e..a9f9255be4 100644 --- a/src/nm-core-utils.c +++ b/src/nm-core-utils.c @@ -1877,110 +1877,6 @@ nm_utils_new_infiniband_name (char *name, const char *parent_name, int p_key) /*****************************************************************************/ -gboolean -nm_utils_resolve_conf_parse (int addr_family, - const char *rc_contents, - GArray *nameservers, - GPtrArray *dns_options) -{ - guint i; - gboolean changed = FALSE; - gs_free const char **lines = NULL; - gsize l; - - g_return_val_if_fail (rc_contents, FALSE); - g_return_val_if_fail (nameservers, FALSE); - g_return_val_if_fail ( ( addr_family == AF_INET - && g_array_get_element_size (nameservers) == sizeof (in_addr_t)) - || ( addr_family == AF_INET6 - && g_array_get_element_size (nameservers) == sizeof (struct in6_addr)), FALSE); - - lines = nm_utils_strsplit_set (rc_contents, "\r\n"); - if (!lines) - return FALSE; - -/* like glibc's MATCH() macro in resolv/res_init.c. */ -#define RC_MATCH(line, option, out_arg) \ - ({ \ - const char *const _line = (line); \ - gboolean _match = FALSE; \ - \ - if ( (strncmp (_line, option, NM_STRLEN (option)) == 0) \ - && (NM_IN_SET (_line[NM_STRLEN (option)], ' ', '\t'))) { \ - _match = TRUE;\ - (out_arg) = &_line[NM_STRLEN (option) + 1]; \ - } \ - _match; \ - }) - - for (l = 0; lines[l]; l++) { - const char *const line = lines[l]; - const char *s = NULL; - - if (RC_MATCH (line, "nameserver", s)) { - gs_free char *s_cpy = NULL; - NMIPAddr ns; - - s = nm_strstrip_avoid_copy (s, &s_cpy); - if (inet_pton (addr_family, s, &ns) != 1) - continue; - - if (addr_family == AF_INET) { - if (!ns.addr4) - continue; - for (i = 0; i < nameservers->len; i++) { - if (g_array_index (nameservers, guint32, i) == ns.addr4) - break; - } - } else { - if (IN6_IS_ADDR_UNSPECIFIED (&ns.addr6)) - continue; - for (i = 0; i < nameservers->len; i++) { - struct in6_addr *t = &g_array_index (nameservers, struct in6_addr, i); - - if (IN6_ARE_ADDR_EQUAL (t, &ns.addr6)) - break; - } - } - - if (i == nameservers->len) { - g_array_append_val (nameservers, ns); - changed = TRUE; - } - continue; - } - - if (RC_MATCH (line, "options", s)) { - if (!dns_options) - continue; - - s = nm_str_skip_leading_spaces (s); - if (s[0]) { - gs_free const char **tokens = NULL; - gsize i_tokens; - - tokens = nm_utils_strsplit_set (s, " \t"); - for (i_tokens = 0; tokens && tokens[i_tokens]; i_tokens++) { - gs_free char *t = g_strstrip (g_strdup (tokens[i_tokens])); - - if ( _nm_utils_dns_option_validate (t, NULL, NULL, - addr_family == AF_INET6, - _nm_utils_dns_option_descs) - && _nm_utils_dns_option_find_idx (dns_options, t) < 0) { - g_ptr_array_add (dns_options, g_steal_pointer (&t)); - changed = TRUE; - } - } - } - continue; - } - } - - return changed; -} - -/*****************************************************************************/ - /** * nm_utils_cmp_connection_by_autoconnect_priority: * @a: diff --git a/src/nm-core-utils.h b/src/nm-core-utils.h index 38f20b0522..d974c8af36 100644 --- a/src/nm-core-utils.h +++ b/src/nm-core-utils.h @@ -229,11 +229,6 @@ gboolean nm_utils_connection_has_default_route (NMConnection *connection, char *nm_utils_new_vlan_name (const char *parent_iface, guint32 vlan_id); const char *nm_utils_new_infiniband_name (char *name, const char *parent_name, int p_key); -gboolean nm_utils_resolve_conf_parse (int addr_family, - const char *rc_contents, - GArray *nameservers, - GPtrArray *dns_options); - int nm_utils_cmp_connection_by_autoconnect_priority (NMConnection *a, NMConnection *b); void nm_utils_log_connection_diff (NMConnection *connection, NMConnection *diff_base, guint32 level, guint64 domain, const char *name, const char *prefix); diff --git a/src/nm-iface-helper.c b/src/nm-iface-helper.c index c85a054ae9..601c72acac 100644 --- a/src/nm-iface-helper.c +++ b/src/nm-iface-helper.c @@ -125,7 +125,7 @@ dhcp4_state_changed (NMDhcpClient *client, g_assert (nm_ip4_config_get_ifindex (ip4_config) == gl.ifindex); existing = nm_ip4_config_capture (nm_platform_get_multi_idx (NM_PLATFORM_GET), - NM_PLATFORM_GET, gl.ifindex, FALSE); + NM_PLATFORM_GET, gl.ifindex); if (last_config) nm_ip4_config_subtract (existing, last_config, 0); @@ -171,7 +171,7 @@ ndisc_config_changed (NMNDisc *ndisc, const NMNDiscData *rdata, guint changed_in NMIP6Config *existing; existing = nm_ip6_config_capture (nm_platform_get_multi_idx (NM_PLATFORM_GET), - NM_PLATFORM_GET, gl.ifindex, FALSE, global_opt.tempaddr); + NM_PLATFORM_GET, gl.ifindex, global_opt.tempaddr); if (ndisc_config) nm_ip6_config_subtract (existing, ndisc_config, 0); else { diff --git a/src/nm-ip4-config.c b/src/nm-ip4-config.c index fa7e78c18a..0a9591d28e 100644 --- a/src/nm-ip4-config.c +++ b/src/nm-ip4-config.c @@ -593,14 +593,13 @@ nm_ip4_config_clone (const NMIP4Config *self) } NMIP4Config * -nm_ip4_config_capture (NMDedupMultiIndex *multi_idx, NMPlatform *platform, int ifindex, gboolean capture_resolv_conf) +nm_ip4_config_capture (NMDedupMultiIndex *multi_idx, NMPlatform *platform, int ifindex) { NMIP4Config *self; NMIP4ConfigPrivate *priv; const NMDedupMultiHeadEntry *head_entry; NMDedupMultiIter iter; const NMPObject *plobj = NULL; - gboolean has_addresses = FALSE; nm_assert (ifindex > 0); @@ -632,7 +631,6 @@ nm_ip4_config_capture (NMDedupMultiIndex *multi_idx, NMPlatform *platform, int i nm_dedup_multi_head_entry_sort (head_entry, sort_captured_addresses, NULL); - has_addresses = TRUE; _notify_addresses (self); } @@ -644,23 +642,6 @@ nm_ip4_config_capture (NMDedupMultiIndex *multi_idx, NMPlatform *platform, int i nmp_cache_iter_for_each (&iter, head_entry, &plobj) _add_route (self, plobj, NULL, NULL); - /* If the interface has the default route, and has IPv4 addresses, capture - * nameservers from /etc/resolv.conf. - */ - if ( has_addresses - && priv->best_default_route - && capture_resolv_conf) { - gs_free char *rc_contents = NULL; - - if (g_file_get_contents (_PATH_RESCONF, &rc_contents, NULL, NULL)) { - if (nm_utils_resolve_conf_parse (AF_INET, - rc_contents, - priv->nameservers, - priv->dns_options)) - _notify (self, PROP_NAMESERVERS); - } - } - return self; } diff --git a/src/nm-ip4-config.h b/src/nm-ip4-config.h index ec525526d2..1c5222df43 100644 --- a/src/nm-ip4-config.h +++ b/src/nm-ip4-config.h @@ -160,7 +160,7 @@ int nm_ip4_config_get_ifindex (const NMIP4Config *self); NMDedupMultiIndex *nm_ip4_config_get_multi_idx (const NMIP4Config *self); -NMIP4Config *nm_ip4_config_capture (NMDedupMultiIndex *multi_idx, NMPlatform *platform, int ifindex, gboolean capture_resolv_conf); +NMIP4Config *nm_ip4_config_capture (NMDedupMultiIndex *multi_idx, NMPlatform *platform, int ifindex); void nm_ip4_config_add_dependent_routes (NMIP4Config *self, guint32 route_table, @@ -397,6 +397,26 @@ nm_ip_config_add_address (NMIPConfig *self, const NMPlatformIPAddress *address) _NM_IP_CONFIG_DISPATCH_VOID (self, nm_ip4_config_add_address, nm_ip6_config_add_address, (gconstpointer) address); } +static inline void +nm_ip_config_reset_addresses (NMIPConfig *self) +{ + _NM_IP_CONFIG_DISPATCH_VOID (self, nm_ip4_config_reset_addresses, nm_ip6_config_reset_addresses); +} + +static inline void +nm_ip_config_add_route (NMIPConfig *self, + const NMPlatformIPRoute *new, + const NMPObject **out_obj_new) +{ + _NM_IP_CONFIG_DISPATCH_VOID (self, nm_ip4_config_add_route, nm_ip6_config_add_route, (gpointer) new, out_obj_new); +} + +static inline void +nm_ip_config_reset_routes (NMIPConfig *self) +{ + _NM_IP_CONFIG_DISPATCH_VOID (self, nm_ip4_config_reset_routes, nm_ip6_config_reset_routes); +} + static inline int nm_ip_config_get_dns_priority (const NMIPConfig *self) { @@ -404,6 +424,12 @@ nm_ip_config_get_dns_priority (const NMIPConfig *self) } static inline void +nm_ip_config_set_dns_priority (NMIPConfig *self, gint priority) +{ + _NM_IP_CONFIG_DISPATCH_VOID (self, nm_ip4_config_set_dns_priority, nm_ip6_config_set_dns_priority, priority); +} + +static inline void nm_ip_config_add_nameserver (NMIPConfig *self, const NMIPAddr *ns) { _NM_IP_CONFIG_DISPATCH_VOID (self, _nm_ip4_config_add_nameserver, nm_ip6_config_add_nameserver, (gconstpointer) ns); @@ -475,18 +501,17 @@ nm_ip_config_get_dns_option (const NMIPConfig *self, guint i) _NM_IP_CONFIG_DISPATCH (self, nm_ip4_config_get_dns_option, nm_ip6_config_get_dns_option, i); } -#define _NM_IP_CONFIG_DISPATCH_SET_OP(dst, src, v4_func, v6_func, ...) \ +#define _NM_IP_CONFIG_DISPATCH_SET_OP(_return, dst, src, v4_func, v6_func, ...) \ G_STMT_START { \ gpointer _dst = (dst); \ gconstpointer _src = (src); \ - int family = nm_ip_config_get_addr_family (_dst); \ \ - nm_assert (family == nm_ip_config_get_addr_family (_src)); \ - if (family == AF_INET) { \ - v4_func ((NMIP4Config *) _dst, (const NMIP4Config *) _src, ##__VA_ARGS__); \ + if (NM_IS_IP4_CONFIG (_dst)) { \ + nm_assert (NM_IS_IP4_CONFIG (_src)); \ + _return v4_func ((NMIP4Config *) _dst, (const NMIP4Config *) _src, ##__VA_ARGS__); \ } else { \ - nm_assert (family == AF_INET6); \ - v6_func ((NMIP6Config *) _dst, (const NMIP6Config *) _src, ##__VA_ARGS__); \ + nm_assert (NM_IS_IP6_CONFIG (_src)); \ + _return v6_func ((NMIP6Config *) _dst, (const NMIP6Config *) _src, ##__VA_ARGS__); \ } \ } G_STMT_END @@ -495,7 +520,7 @@ nm_ip_config_intersect (NMIPConfig *dst, const NMIPConfig *src, guint32 default_route_metric_penalty) { - _NM_IP_CONFIG_DISPATCH_SET_OP (dst, src, + _NM_IP_CONFIG_DISPATCH_SET_OP (, dst, src, nm_ip4_config_intersect, nm_ip6_config_intersect, default_route_metric_penalty); @@ -506,7 +531,7 @@ nm_ip_config_subtract (NMIPConfig *dst, const NMIPConfig *src, guint32 default_route_metric_penalty) { - _NM_IP_CONFIG_DISPATCH_SET_OP (dst, src, + _NM_IP_CONFIG_DISPATCH_SET_OP (, dst, src, nm_ip4_config_subtract, nm_ip6_config_subtract, default_route_metric_penalty); @@ -518,30 +543,41 @@ nm_ip_config_merge (NMIPConfig *dst, NMIPConfigMergeFlags merge_flags, guint32 default_route_metric_penalty) { - _NM_IP_CONFIG_DISPATCH_SET_OP (dst, src, + _NM_IP_CONFIG_DISPATCH_SET_OP (, dst, src, nm_ip4_config_merge, nm_ip6_config_merge, merge_flags, default_route_metric_penalty); } +static inline gboolean +nm_ip_config_replace (NMIPConfig *dst, + const NMIPConfig *src, + gboolean *relevant_changes) +{ + _NM_IP_CONFIG_DISPATCH_SET_OP (return, dst, src, + nm_ip4_config_replace, + nm_ip6_config_replace, + relevant_changes); +} + static inline NMIPConfig * nm_ip_config_intersect_alloc (const NMIPConfig *a, const NMIPConfig *b, guint32 default_route_metric_penalty) { - int family; - - family = nm_ip_config_get_addr_family (a); - nm_assert (family == nm_ip_config_get_addr_family (b)); - - if (family == AF_INET) + if (NM_IS_IP4_CONFIG (a)) { + nm_assert (NM_IS_IP4_CONFIG (b)); return (NMIPConfig *) nm_ip4_config_intersect_alloc ((const NMIP4Config *) a, (const NMIP4Config *) b, default_route_metric_penalty); - else + } else { + nm_assert (NM_IS_IP6_CONFIG (a)); + nm_assert (NM_IS_IP6_CONFIG (b)); return (NMIPConfig *) nm_ip6_config_intersect_alloc ((const NMIP6Config *) a, (const NMIP6Config *) b, default_route_metric_penalty); + } } + #endif /* __NETWORKMANAGER_IP4_CONFIG_H__ */ diff --git a/src/nm-ip6-config.c b/src/nm-ip6-config.c index 883e8e00fa..c76da9951e 100644 --- a/src/nm-ip6-config.c +++ b/src/nm-ip6-config.c @@ -376,14 +376,13 @@ nm_ip6_config_clone (const NMIP6Config *self) } NMIP6Config * -nm_ip6_config_capture (NMDedupMultiIndex *multi_idx, NMPlatform *platform, int ifindex, gboolean capture_resolv_conf, NMSettingIP6ConfigPrivacy use_temporary) +nm_ip6_config_capture (NMDedupMultiIndex *multi_idx, NMPlatform *platform, int ifindex, NMSettingIP6ConfigPrivacy use_temporary) { NMIP6Config *self; NMIP6ConfigPrivate *priv; const NMDedupMultiHeadEntry *head_entry; NMDedupMultiIter iter; const NMPObject *plobj = NULL; - gboolean has_addresses = FALSE; nm_assert (ifindex > 0); @@ -409,7 +408,6 @@ nm_ip6_config_capture (NMDedupMultiIndex *multi_idx, NMPlatform *platform, int i NULL, NULL)) nm_assert_not_reached (); - has_addresses = TRUE; } head_entry = nm_ip6_config_lookup_addresses (self); nm_assert (head_entry); @@ -426,23 +424,6 @@ nm_ip6_config_capture (NMDedupMultiIndex *multi_idx, NMPlatform *platform, int i nmp_cache_iter_for_each (&iter, head_entry, &plobj) _add_route (self, plobj, NULL, NULL); - /* If the interface has the default route, and has IPv6 addresses, capture - * nameservers from /etc/resolv.conf. - */ - if ( has_addresses - && priv->best_default_route - && capture_resolv_conf) { - gs_free char *rc_contents = NULL; - - if (g_file_get_contents (_PATH_RESCONF, &rc_contents, NULL, NULL)) { - if (nm_utils_resolve_conf_parse (AF_INET6, - rc_contents, - priv->nameservers, - priv->dns_options)) - _notify (self, PROP_NAMESERVERS); - } - } - return self; } @@ -1691,19 +1672,43 @@ nm_ip6_config_lookup_address (const NMIP6Config *self, } const NMPlatformIP6Address * -nm_ip6_config_get_address_first_nontentative (const NMIP6Config *self, gboolean linklocal) +nm_ip6_config_find_first_address (const NMIP6Config *self, + NMPlatformMatchFlags match_flag) { const NMPlatformIP6Address *addr; NMDedupMultiIter iter; g_return_val_if_fail (NM_IS_IP6_CONFIG (self), NULL); - linklocal = !!linklocal; + nm_assert (!NM_FLAGS_ANY (match_flag, ~( NM_PLATFORM_MATCH_WITH_ADDRTYPE__ANY + | NM_PLATFORM_MATCH_WITH_ADDRSTATE__ANY))); + + nm_assert (NM_FLAGS_ANY (match_flag, NM_PLATFORM_MATCH_WITH_ADDRTYPE__ANY)); + nm_assert (NM_FLAGS_ANY (match_flag, NM_PLATFORM_MATCH_WITH_ADDRSTATE__ANY)); nm_ip_config_iter_ip6_address_for_each (&iter, self, &addr) { - if ( ((!!IN6_IS_ADDR_LINKLOCAL (&addr->address)) == linklocal) - && !(addr->n_ifa_flags & IFA_F_TENTATIVE)) - return addr; + + if (IN6_IS_ADDR_LINKLOCAL (&addr->address)) { + if (!NM_FLAGS_HAS (match_flag, NM_PLATFORM_MATCH_WITH_ADDRTYPE_LINKLOCAL)) + continue; + } else { + if (!NM_FLAGS_HAS (match_flag, NM_PLATFORM_MATCH_WITH_ADDRTYPE_NORMAL)) + continue; + } + + if (NM_FLAGS_HAS (addr->n_ifa_flags, IFA_F_DADFAILED)) { + if (!NM_FLAGS_HAS (match_flag, NM_PLATFORM_MATCH_WITH_ADDRSTATE_DADFAILED)) + continue; + } else if ( NM_FLAGS_HAS (addr->n_ifa_flags, IFA_F_TENTATIVE) + && !NM_FLAGS_HAS (addr->n_ifa_flags, IFA_F_OPTIMISTIC)) { + if (!NM_FLAGS_HAS (match_flag, NM_PLATFORM_MATCH_WITH_ADDRSTATE_TENTATIVE)) + continue; + } else { + if (!NM_FLAGS_HAS (match_flag, NM_PLATFORM_MATCH_WITH_ADDRSTATE_NORMAL)) + continue; + } + + return addr; } return NULL; diff --git a/src/nm-ip6-config.h b/src/nm-ip6-config.h index 882047d1c1..cd01ed021b 100644 --- a/src/nm-ip6-config.h +++ b/src/nm-ip6-config.h @@ -106,7 +106,7 @@ int nm_ip6_config_get_ifindex (const NMIP6Config *self); struct _NMDedupMultiIndex *nm_ip6_config_get_multi_idx (const NMIP6Config *self); NMIP6Config *nm_ip6_config_capture (struct _NMDedupMultiIndex *multi_idx, NMPlatform *platform, int ifindex, - gboolean capture_resolv_conf, NMSettingIP6ConfigPrivacy use_temporary); + NMSettingIP6ConfigPrivacy use_temporary); void nm_ip6_config_add_dependent_routes (NMIP6Config *self, guint32 route_table, @@ -149,7 +149,8 @@ void _nmtst_ip6_config_del_address (NMIP6Config *self, guint i); guint nm_ip6_config_get_num_addresses (const NMIP6Config *self); const NMPlatformIP6Address *nm_ip6_config_get_first_address (const NMIP6Config *self); const NMPlatformIP6Address *_nmtst_ip6_config_get_address (const NMIP6Config *self, guint i); -const NMPlatformIP6Address *nm_ip6_config_get_address_first_nontentative (const NMIP6Config *self, gboolean linklocal); +const NMPlatformIP6Address *nm_ip6_config_find_first_address (const NMIP6Config *self, + NMPlatformMatchFlags match_flag); gboolean nm_ip6_config_address_exists (const NMIP6Config *self, const NMPlatformIP6Address *address); const NMPlatformIP6Address *nm_ip6_config_lookup_address (const NMIP6Config *self, const struct in6_addr *addr); diff --git a/src/nm-logging.h b/src/nm-logging.h index 8fcbc8cc41..29acb09f65 100644 --- a/src/nm-logging.h +++ b/src/nm-logging.h @@ -83,6 +83,16 @@ typedef enum { /*< skip >*/ LOGD_IP = LOGD_IP4 | LOGD_IP6, } NMLogDomain; +static inline NMLogDomain +LOGD_IP_from_af (int addr_family) +{ + switch (addr_family) { + case AF_INET: return LOGD_IP4; + case AF_INET6: return LOGD_IP6; + } + g_return_val_if_reached (LOGD_NONE); +} + /* Log levels */ typedef enum { /*< skip >*/ LOGL_TRACE, diff --git a/src/platform/nm-platform.h b/src/platform/nm-platform.h index 0afdb3b060..824735083a 100644 --- a/src/platform/nm-platform.h +++ b/src/platform/nm-platform.h @@ -171,6 +171,34 @@ typedef enum { /*< skip >*/ NM_PLATFORM_ERROR_CANT_SET_MTU, } NMPlatformError; +typedef enum { + + /* match-flags are strictly inclusive. That means, + * by default nothing is matched, but if you enable a particular + * flag, a candidate that matches passes the check. + * + * In other words: adding more flags can only extend the result + * set of matching objects. + * + * Also, the flags form partitions. Like, an address can be either of + * ADDRTYPE_NORMAL or ADDRTYPE_LINKLOCAL, but never both. Same for + * the ADDRSTATE match types. + */ + NM_PLATFORM_MATCH_WITH_NONE = 0, + + NM_PLATFORM_MATCH_WITH_ADDRTYPE_NORMAL = (1LL << 0), + NM_PLATFORM_MATCH_WITH_ADDRTYPE_LINKLOCAL = (1LL << 1), + NM_PLATFORM_MATCH_WITH_ADDRTYPE__ANY = NM_PLATFORM_MATCH_WITH_ADDRTYPE_NORMAL + | NM_PLATFORM_MATCH_WITH_ADDRTYPE_LINKLOCAL, + + NM_PLATFORM_MATCH_WITH_ADDRSTATE_NORMAL = (1LL << 2), + NM_PLATFORM_MATCH_WITH_ADDRSTATE_TENTATIVE = (1LL << 3), + NM_PLATFORM_MATCH_WITH_ADDRSTATE_DADFAILED = (1LL << 4), + NM_PLATFORM_MATCH_WITH_ADDRSTATE__ANY = NM_PLATFORM_MATCH_WITH_ADDRSTATE_NORMAL + | NM_PLATFORM_MATCH_WITH_ADDRSTATE_TENTATIVE + | NM_PLATFORM_MATCH_WITH_ADDRSTATE_DADFAILED, +} NMPlatformMatchFlags; + #define NM_PLATFORM_LINK_OTHER_NETNS (-1) #define __NMPlatformObject_COMMON \ diff --git a/src/tests/meson.build b/src/tests/meson.build index 9e32a92965..b87da713da 100644 --- a/src/tests/meson.build +++ b/src/tests/meson.build @@ -6,7 +6,6 @@ test_units = [ 'test-ip4-config', 'test-ip6-config', 'test-dcb', - 'test-resolvconf-capture', 'test-wired-defname', 'test-utils' ] diff --git a/src/tests/test-resolvconf-capture.c b/src/tests/test-resolvconf-capture.c deleted file mode 100644 index 2c34ff74d9..0000000000 --- a/src/tests/test-resolvconf-capture.c +++ /dev/null @@ -1,298 +0,0 @@ -/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ -/* - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2, or (at your option) - * any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Copyright (C) 2013 Red Hat, Inc. - * - */ - -#include "nm-default.h" - -#include <string.h> -#include <arpa/inet.h> - -#include "NetworkManagerUtils.h" -#include "nm-ip4-config.h" -#include "nm-ip6-config.h" -#include "platform/nm-platform.h" - -#include "nm-test-utils-core.h" - -static void -test_capture_empty (void) -{ - GArray *ns4 = g_array_new (FALSE, FALSE, sizeof (guint32)); - GArray *ns6 = g_array_new (FALSE, FALSE, sizeof (struct in6_addr)); - - g_assert (!nm_utils_resolve_conf_parse (AF_INET, "", ns4, NULL)); - g_assert_cmpint (ns4->len, ==, 0); - - g_assert (!nm_utils_resolve_conf_parse (AF_INET6, "", ns6, NULL)); - g_assert_cmpint (ns6->len, ==, 0); - - g_array_free (ns4, TRUE); - g_array_free (ns6, TRUE); -} - -#define assert_dns4_entry(a, i, s) \ - g_assert_cmpint ((g_array_index ((a), guint32, (i))), ==, nmtst_inet4_from_string (s)); - -#define assert_dns6_entry(a, i, s) \ - g_assert (IN6_ARE_ADDR_EQUAL (&g_array_index ((a), struct in6_addr, (i)), nmtst_inet6_from_string (s))) - -#define assert_dns_option(a, i, s) \ - g_assert_cmpstr ((a)->pdata[(i)], ==, (s)); - -static void -test_capture_basic4 (void) -{ - GArray *ns4 = g_array_new (FALSE, FALSE, sizeof (guint32)); - const char *rc = -"# neato resolv.conf\r\n" -"domain foobar.com\r\n" -"search foobar.com\r\n" -"nameserver 4.2.2.1\r\n" -"nameserver 4.2.2.2\r\n"; - - g_assert (nm_utils_resolve_conf_parse (AF_INET, rc, ns4, NULL)); - g_assert_cmpint (ns4->len, ==, 2); - assert_dns4_entry (ns4, 0, "4.2.2.1"); - assert_dns4_entry (ns4, 1, "4.2.2.2"); - - g_array_free (ns4, TRUE); -} - -static void -test_capture_dup4 (void) -{ - GArray *ns4 = g_array_new (FALSE, FALSE, sizeof (guint32)); - const char *rc = -"# neato resolv.conf\r\n" -"domain foobar.com\r\n" -"search foobar.com\r\n" -"nameserver 4.2.2.1\r\n" -"nameserver 4.2.2.1\r\n" -"nameserver 4.2.2.2\r\n"; - - /* Check that duplicates are ignored */ - g_assert (nm_utils_resolve_conf_parse (AF_INET, rc, ns4, NULL)); - g_assert_cmpint (ns4->len, ==, 2); - assert_dns4_entry (ns4, 0, "4.2.2.1"); - assert_dns4_entry (ns4, 1, "4.2.2.2"); - - g_array_free (ns4, TRUE); -} - -static void -test_capture_basic6 (void) -{ - GArray *ns6 = g_array_new (FALSE, FALSE, sizeof (struct in6_addr)); - const char *rc = -"# neato resolv.conf\r\n" -"domain foobar.com\r\n" -"search foobar.com\r\n" -"nameserver 2001:4860:4860::8888\r\n" -"nameserver 2001:4860:4860::8844\r\n"; - - g_assert (nm_utils_resolve_conf_parse (AF_INET6, rc, ns6, NULL)); - g_assert_cmpint (ns6->len, ==, 2); - assert_dns6_entry (ns6, 0, "2001:4860:4860::8888"); - assert_dns6_entry (ns6, 1, "2001:4860:4860::8844"); - - g_array_free (ns6, TRUE); -} - -static void -test_capture_dup6 (void) -{ - GArray *ns6 = g_array_new (FALSE, FALSE, sizeof (struct in6_addr)); - const char *rc = -"# neato resolv.conf\r\n" -"domain foobar.com\r\n" -"search foobar.com\r\n" -"nameserver 2001:4860:4860::8888\r\n" -"nameserver 2001:4860:4860::8888\r\n" -"nameserver 2001:4860:4860::8844\r\n"; - - /* Check that duplicates are ignored */ - g_assert (nm_utils_resolve_conf_parse (AF_INET6, rc, ns6, NULL)); - g_assert_cmpint (ns6->len, ==, 2); - assert_dns6_entry (ns6, 0, "2001:4860:4860::8888"); - assert_dns6_entry (ns6, 1, "2001:4860:4860::8844"); - - g_array_free (ns6, TRUE); -} - -static void -test_capture_addr4_with_6 (void) -{ - GArray *ns4 = g_array_new (FALSE, FALSE, sizeof (guint32)); - const char *rc = -"# neato resolv.conf\r\n" -"domain foobar.com\r\n" -"search foobar.com\r\n" -"nameserver 4.2.2.1\r\n" -"nameserver 4.2.2.2\r\n" -"nameserver 2001:4860:4860::8888\r\n"; - - g_assert (nm_utils_resolve_conf_parse (AF_INET, rc, ns4, NULL)); - g_assert_cmpint (ns4->len, ==, 2); - assert_dns4_entry (ns4, 0, "4.2.2.1"); - assert_dns4_entry (ns4, 1, "4.2.2.2"); - - g_array_free (ns4, TRUE); -} - -static void -test_capture_addr6_with_4 (void) -{ - GArray *ns6 = g_array_new (FALSE, FALSE, sizeof (struct in6_addr)); - const char *rc = -"# neato resolv.conf\r\n" -"domain foobar.com\r\n" -"search foobar.com\r\n" -"nameserver 4.2.2.1\r\n" -"nameserver 2001:4860:4860::8888\r\n" -"nameserver 2001:4860:4860::8844\r\n"; - - g_assert (nm_utils_resolve_conf_parse (AF_INET6, rc, ns6, NULL)); - g_assert_cmpint (ns6->len, ==, 2); - assert_dns6_entry (ns6, 0, "2001:4860:4860::8888"); - assert_dns6_entry (ns6, 1, "2001:4860:4860::8844"); - - g_array_free (ns6, TRUE); -} - -static void -test_capture_format (void) -{ - GArray *ns4 = g_array_new (FALSE, FALSE, sizeof (guint32)); - const char *rc = -" nameserver 4.2.2.1\r\n" /* bad */ -"nameserver4.2.2.1\r\n" /* bad */ -"nameserver 4.2.2.3\r" /* good */ -"nameserver\t\t4.2.2.4\r\n" /* good */ -"nameserver 4.2.2.5\t\t\r\n" /* good */ -"nameserver 4.2.2.6 \r\n"; /* good */ - - g_assert (nm_utils_resolve_conf_parse (AF_INET, rc, ns4, NULL)); - g_assert_cmpint (ns4->len, ==, 4); - assert_dns4_entry (ns4, 0, "4.2.2.3"); - assert_dns4_entry (ns4, 1, "4.2.2.4"); - assert_dns4_entry (ns4, 2, "4.2.2.5"); - assert_dns4_entry (ns4, 3, "4.2.2.6"); - - g_array_free (ns4, TRUE); -} - -static void -test_capture_dns_options (void) -{ - GArray *ns4 = g_array_new (FALSE, FALSE, sizeof (guint32)); - GPtrArray *dns_options = g_ptr_array_new_with_free_func (g_free); - const char *rc = -"nameserver 4.2.2.1\r\n" -"options debug rotate timeout:5 \r\n" -"options edns0\r\n"; - - g_assert (nm_utils_resolve_conf_parse (AF_INET, rc, ns4, dns_options)); - g_assert_cmpint (dns_options->len, ==, 4); - assert_dns_option (dns_options, 0, "debug"); - assert_dns_option (dns_options, 1, "rotate"); - assert_dns_option (dns_options, 2, "timeout:5"); - assert_dns_option (dns_options, 3, "edns0"); - - g_array_free (ns4, TRUE); - g_ptr_array_free (dns_options, TRUE); -} - -static void -test_capture_dns_options_dup (void) -{ - GArray *ns4 = g_array_new (FALSE, FALSE, sizeof (guint32)); - GPtrArray *dns_options = g_ptr_array_new_with_free_func (g_free); - const char *rc = -"options debug rotate timeout:3\r\n" -"options edns0 debug\r\n" -"options timeout:5\r\n"; - - g_assert (nm_utils_resolve_conf_parse (AF_INET, rc, ns4, dns_options)); - g_assert_cmpint (dns_options->len, ==, 4); - assert_dns_option (dns_options, 0, "debug"); - assert_dns_option (dns_options, 1, "rotate"); - assert_dns_option (dns_options, 2, "timeout:3"); - assert_dns_option (dns_options, 3, "edns0"); - - g_array_free (ns4, TRUE); - g_ptr_array_free (dns_options, TRUE); -} - -static void -test_capture_dns_options_valid4 (void) -{ - GArray *ns4 = g_array_new (FALSE, FALSE, sizeof (guint32)); - GPtrArray *dns_options = g_ptr_array_new_with_free_func (g_free); - const char *rc = -"options debug: rotate:yes edns0 foobar : inet6\r\n"; - - g_assert (nm_utils_resolve_conf_parse (AF_INET, rc, ns4, dns_options)); - g_assert_cmpint (dns_options->len, ==, 1); - assert_dns_option (dns_options, 0, "edns0"); - - g_array_free (ns4, TRUE); - g_ptr_array_free (dns_options, TRUE); -} - -static void -test_capture_dns_options_valid6 (void) -{ - GArray *ns6 = g_array_new (FALSE, FALSE, sizeof (struct in6_addr)); - GPtrArray *dns_options = g_ptr_array_new_with_free_func (g_free); - const char *rc = -"options inet6 debug foobar rotate:\r\n"; - - g_assert (nm_utils_resolve_conf_parse (AF_INET6, rc, ns6, dns_options)); - g_assert_cmpint (dns_options->len, ==, 2); - assert_dns_option (dns_options, 0, "inet6"); - assert_dns_option (dns_options, 1, "debug"); - - g_array_free (ns6, TRUE); - g_ptr_array_free (dns_options, TRUE); -} -/*****************************************************************************/ - -NMTST_DEFINE (); - -int -main (int argc, char **argv) -{ - nmtst_init_assert_logging (&argc, &argv, "INFO", "DEFAULT"); - - g_test_add_func ("/resolvconf-capture/empty", test_capture_empty); - g_test_add_func ("/resolvconf-capture/basic4", test_capture_basic4); - g_test_add_func ("/resolvconf-capture/dup4", test_capture_dup4); - g_test_add_func ("/resolvconf-capture/basic6", test_capture_basic6); - g_test_add_func ("/resolvconf-capture/dup6", test_capture_dup6); - g_test_add_func ("/resolvconf-capture/addr4-with-6", test_capture_addr4_with_6); - g_test_add_func ("/resolvconf-capture/addr6-with-4", test_capture_addr6_with_4); - g_test_add_func ("/resolvconf-capture/format", test_capture_format); - g_test_add_func ("/resolvconf-capture/dns-options", test_capture_dns_options); - g_test_add_func ("/resolvconf-capture/dns-options-dup", test_capture_dns_options_dup); - g_test_add_func ("/resolvconf-capture/dns-options-valid4", test_capture_dns_options_valid4); - g_test_add_func ("/resolvconf-capture/dns-options-valid6", test_capture_dns_options_valid6); - - return g_test_run (); -} - |