diff options
Diffstat (limited to 'src/core')
| -rw-r--r-- | src/core/devices/nm-device.c | 127 | ||||
| -rw-r--r-- | src/core/devices/nm-device.h | 2 | ||||
| -rw-r--r-- | src/core/devices/wwan/nm-modem-ofono.c | 5 | ||||
| -rw-r--r-- | src/core/dhcp/nm-dhcp-client.c | 35 | ||||
| -rw-r--r-- | src/core/dhcp/nm-dhcp-nettools.c | 62 | ||||
| -rw-r--r-- | src/core/dhcp/nm-dhcp-options.c | 36 | ||||
| -rw-r--r-- | src/core/dhcp/nm-dhcp-options.h | 28 | ||||
| -rw-r--r-- | src/core/dhcp/nm-dhcp-systemd.c | 33 | ||||
| -rw-r--r-- | src/core/nm-active-connection.c | 16 | ||||
| -rw-r--r-- | src/core/nm-active-connection.h | 1 | ||||
| -rw-r--r-- | src/core/nm-core-utils.c | 48 | ||||
| -rw-r--r-- | src/core/nm-dispatcher.c | 2 | ||||
| -rw-r--r-- | src/core/nm-policy.c | 2 | ||||
| -rw-r--r-- | src/core/settings/plugins/ifcfg-rh/nms-ifcfg-rh-reader.c | 4 | ||||
| -rw-r--r-- | src/core/settings/plugins/ifcfg-rh/nms-ifcfg-rh-utils.c | 2 | ||||
| -rw-r--r-- | src/core/settings/plugins/ifcfg-rh/nms-ifcfg-rh-utils.h | 2 | ||||
| -rw-r--r-- | src/core/settings/plugins/ifcfg-rh/nms-ifcfg-rh-writer.c | 8 | ||||
| -rw-r--r-- | src/core/vpn/nm-vpn-connection.c | 5 |
18 files changed, 299 insertions, 119 deletions
diff --git a/src/core/devices/nm-device.c b/src/core/devices/nm-device.c index 04478614..3565c04d 100644 --- a/src/core/devices/nm-device.c +++ b/src/core/devices/nm-device.c @@ -312,7 +312,7 @@ typedef struct { typedef enum { RESOLVER_WAIT_ADDRESS = 0, - RESOLVER_IN_PROGRESS, + RESOLVER_STARTED, RESOLVER_DONE, } ResolverState; @@ -1810,6 +1810,7 @@ _prop_get_ipvx_dhcp_iaid(NMDevice *self, const char *iface; const char *fail_reason; gboolean is_explicit = TRUE; + gint64 i64; s_ip = nm_connection_get_setting_ip_config(connection, addr_family); iaid_str = nm_setting_ip_config_get_dhcp_iaid(s_ip); @@ -1868,7 +1869,7 @@ _prop_get_ipvx_dhcp_iaid(NMDevice *self, iaid = unaligned_read_be32(&hwaddr_buf[hwaddr_len - 4]); goto out_good; - } else if (nm_streq(iaid_str, "stable")) { + } else if (nm_streq(iaid_str, NM_IAID_STABLE)) { nm_auto_free_checksum GChecksum *sum = NULL; guint8 digest[NM_UTILS_CHECKSUM_LENGTH_SHA1]; NMUtilsStableType stable_type; @@ -1891,14 +1892,21 @@ _prop_get_ipvx_dhcp_iaid(NMDevice *self, iaid = unaligned_read_be32(digest); goto out_good; - } else if ((iaid = _nm_utils_ascii_str_to_int64(iaid_str, 10, 0, G_MAXUINT32, -1)) != -1) { - goto out_good; - } else { + } else if (nm_streq(iaid_str, NM_IAID_IFNAME)) { iface = nm_device_get_ip_iface(self); iaid = nm_utils_create_dhcp_iaid(TRUE, (const guint8 *) iface, strlen(iface)); goto out_good; + } else if (_nm_utils_iaid_verify(iaid_str, &i64)) { + if (i64 < 0) { + fail_reason = nm_assert_unreachable_val("bug handling iaid value"); + goto out_fail; + } + nm_assert(i64 <= G_MAXUINT32); + iaid = (guint32) i64; + goto out_good; } + fail_reason = nm_assert_unreachable_val("bug handling iaid code"); out_fail: nm_assert(fail_reason); if (!log_silent) { @@ -1912,11 +1920,13 @@ out_fail: iaid = nm_utils_create_dhcp_iaid(TRUE, (const guint8 *) iface, strlen(iface)); out_good: if (!log_silent) { + char buf[NM_DHCP_IAID_TO_HEXSTR_BUF_LEN]; + _LOGD(LOGD_DEVICE | LOGD_DHCPX(IS_IPv4) | LOGD_IPX(IS_IPv4), - "ipv%c.dhcp-iaid: using %u (0x%08x) IAID (str: '%s', explicit %d)", + "ipv%c.dhcp-iaid: using %u (%s) IAID (str: '%s', explicit %d)", nm_utils_addr_family_to_char(addr_family), iaid, - iaid, + nm_dhcp_iaid_to_hexstr(iaid, buf), iaid_str, is_explicit); } @@ -7168,6 +7178,9 @@ nm_device_update_from_platform_link(NMDevice *self, const NMPlatformLink *plink) ifindex_changed = _set_ifindex(self, plink ? plink->ifindex : 0, FALSE); + nm_device_update_hw_address(self); + nm_device_update_permanent_hw_address(self, FALSE); + if (ifindex_changed) NM_DEVICE_GET_CLASS(self)->link_changed(self, plink); @@ -8581,6 +8594,7 @@ nm_device_generate_connection(NMDevice *self, nm_device_get_iface(master), local->message); g_error_free(local); + NM_SET_OUT(out_maybe_later, TRUE); return NULL; } } else { @@ -9641,6 +9655,18 @@ _routing_rules_sync(NMDevice *self, NMTernary set_mode) user_tag_1, NMP_GLOBAL_TRACKER_EXTERN_WEAKLY_TRACKED_USER_TAG); } + + if (nm_setting_ip_config_get_replace_local_rule(s_ip) == NM_TERNARY_TRUE) { + /* The user specified that the local rule should be replaced. + * In order to do that, we track the local rule with negative + * priority. */ + nmp_global_tracker_track_local_rule( + global_tracker, + addr_family, + -5, + user_tag_1, + NMP_GLOBAL_TRACKER_EXTERN_WEAKLY_TRACKED_USER_TAG); + } } if (klass->get_extra_rules) { @@ -17093,6 +17119,21 @@ nm_device_auth_retries_try_next(NMDevice *self) return TRUE; } +static const char * +_resolver_state_to_string(ResolverState state) +{ + switch (state) { + case RESOLVER_WAIT_ADDRESS: + return "WAIT-ADDRESS"; + case RESOLVER_STARTED: + return "STARTED"; + case RESOLVER_DONE: + return "DONE"; + } + nm_assert_not_reached(); + return "UNKNOWN"; +} + static void hostname_dns_lookup_callback(GObject *source, GAsyncResult *result, gpointer user_data) { @@ -17112,7 +17153,9 @@ hostname_dns_lookup_callback(GObject *source, GAsyncResult *result, gpointer use if (error) { _LOGD(LOGD_DNS, - "hostname-from-dns: lookup error for %s: %s", + "hostname-from-dns: ipv%c resolver %s: lookup error for %s: %s", + nm_utils_addr_family_to_char(resolver->addr_family), + _resolver_state_to_string(RESOLVER_DONE), (addr_str = g_inet_address_to_string(resolver->address)), error->message); } else { @@ -17122,7 +17165,9 @@ hostname_dns_lookup_callback(GObject *source, GAsyncResult *result, gpointer use valid = nm_utils_validate_hostname(resolver->hostname); _LOGD(LOGD_DNS, - "hostname-from-dns: lookup done for %s, result %s%s%s%s", + "hostname-from-dns: ipv%c resolver %s: lookup successful for %s, result %s%s%s%s", + nm_utils_addr_family_to_char(resolver->addr_family), + _resolver_state_to_string(RESOLVER_DONE), (addr_str = g_inet_address_to_string(resolver->address)), NM_PRINT_FMT_QUOTE_STRING(resolver->hostname), valid ? "" : " (invalid)"); @@ -17148,8 +17193,9 @@ hostname_dns_address_timeout(gpointer user_data) nm_assert(!resolver->cancellable); _LOGT(LOGD_DNS, - "hostname-from-dns: timed out while waiting IPv%c address", - nm_utils_addr_family_to_char(resolver->addr_family)); + "hostname-from-dns: ipv%c state %s: timed out while waiting for address", + nm_utils_addr_family_to_char(resolver->addr_family), + _resolver_state_to_string(RESOLVER_DONE)); resolver->timeout_id = 0; resolver->state = RESOLVER_DONE; @@ -17158,30 +17204,16 @@ hostname_dns_address_timeout(gpointer user_data) return G_SOURCE_REMOVE; } -static const char * -_resolver_state_to_string(ResolverState state) -{ - switch (state) { - case RESOLVER_WAIT_ADDRESS: - return "wait-address"; - case RESOLVER_IN_PROGRESS: - return "in-progress"; - case RESOLVER_DONE: - return "done"; - default: - nm_assert_not_reached(); - return "unknown"; - } -} - void -nm_device_clear_dns_lookup_data(NMDevice *self) +nm_device_clear_dns_lookup_data(NMDevice *self, const char *reason) { NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE(self); - guint i; - for (i = 0; i < 2; i++) - nm_clear_pointer(&priv->hostname_resolver_x[i], _hostname_resolver_free); + if (priv->hostname_resolver_4 || priv->hostname_resolver_6) { + _LOGT(LOGD_DNS, "hostname-from-dns: resetting (%s)", reason); + nm_clear_pointer(&priv->hostname_resolver_4, _hostname_resolver_free); + nm_clear_pointer(&priv->hostname_resolver_6, _hostname_resolver_free); + } } gboolean @@ -17222,6 +17254,9 @@ get_address_for_hostname_dns_lookup(NMDevice *self, int addr_family) return g_inet_address_new_from_bytes(addr->ax.address_ptr, G_SOCKET_FAMILY_IPV4); } + if (addr->ax.n_ifa_flags & IFA_F_TENTATIVE) + continue; + /* For IPv6 prefer, in order: * - !link-local, !deprecated * - !link-local, deprecated @@ -17315,29 +17350,35 @@ nm_device_get_hostname_from_dns_lookup(NMDevice *self, int addr_family, gboolean } else if (new_address != resolver->address) address_changed = TRUE; + if (address_changed) { + /* set new state before logging */ + if (new_address) + resolver->state = RESOLVER_STARTED; + else + resolver->state = RESOLVER_WAIT_ADDRESS; + } + { gs_free char *old_str = NULL; gs_free char *new_str = NULL; - _LOGT(LOGD_DNS, - "hostname-from-dns: ipv%c resolver state %s, old address %s, new address %s", - nm_utils_addr_family_to_char(resolver->addr_family), - _resolver_state_to_string(resolver->state), - resolver->address ? (old_str = g_inet_address_to_string(resolver->address)) - : "(null)", - new_address ? (new_str = g_inet_address_to_string(new_address)) : "(null)"); + if (address_changed) { + _LOGT(LOGD_DNS, + "hostname-from-dns: ipv%c resolver %s, address changed from %s to %s", + nm_utils_addr_family_to_char(resolver->addr_family), + _resolver_state_to_string(resolver->state), + resolver->address ? (old_str = g_inet_address_to_string(resolver->address)) + : "(null)", + new_address ? (new_str = g_inet_address_to_string(new_address)) : "(null)"); + } } - /* In every state, if the address changed, we restart - * the resolution with the new address */ if (address_changed) { nm_clear_g_cancellable(&resolver->cancellable); g_clear_object(&resolver->address); - resolver->state = RESOLVER_WAIT_ADDRESS; } if (address_changed && new_address) { - resolver->state = RESOLVER_IN_PROGRESS; resolver->cancellable = g_cancellable_new(); resolver->address = g_steal_pointer(&new_address); @@ -17355,7 +17396,7 @@ nm_device_get_hostname_from_dns_lookup(NMDevice *self, int addr_family, gboolean resolver->timeout_id = g_timeout_add(30000, hostname_dns_address_timeout, resolver); NM_SET_OUT(out_wait, TRUE); return NULL; - case RESOLVER_IN_PROGRESS: + case RESOLVER_STARTED: NM_SET_OUT(out_wait, TRUE); return NULL; case RESOLVER_DONE: diff --git a/src/core/devices/nm-device.h b/src/core/devices/nm-device.h index f54457d1..bcf4d7b9 100644 --- a/src/core/devices/nm-device.h +++ b/src/core/devices/nm-device.h @@ -817,7 +817,7 @@ gboolean nm_device_is_vpn(NMDevice *self); const char * nm_device_get_hostname_from_dns_lookup(NMDevice *self, int addr_family, gboolean *out_pending); -void nm_device_clear_dns_lookup_data(NMDevice *self); +void nm_device_clear_dns_lookup_data(NMDevice *self, const char *reason); gboolean nm_device_get_allow_autoconnect_on_external(NMDevice *self); diff --git a/src/core/devices/wwan/nm-modem-ofono.c b/src/core/devices/wwan/nm-modem-ofono.c index b3745621..33a19e93 100644 --- a/src/core/devices/wwan/nm-modem-ofono.c +++ b/src/core/devices/wwan/nm-modem-ofono.c @@ -734,7 +734,7 @@ update_connection_list(NMModemOfono *self) g_hash_table_iter_init(&iter, priv->contexts); while (g_hash_table_iter_next(&iter, (gpointer *) &uuid, (gpointer *) &octx)) { - if (octx->preferred) { + if (octx->preferred && nm_streq(octx->type, "internet")) { octx_preferred = octx; break; } @@ -743,8 +743,7 @@ update_connection_list(NMModemOfono *self) g_hash_table_iter_init(&iter, priv->contexts); while (g_hash_table_iter_next(&iter, (gpointer *) &uuid, (gpointer *) &octx)) { gboolean connection_should_exist = - (!octx_preferred || octx_preferred == octx) - && (nm_streq(octx->type, "internet") || nm_streq(octx->type, "internet+mms")); + octx_preferred == octx || (!octx_preferred && nm_streq(octx->type, "internet")); gboolean connection_exists = g_hash_table_contains(priv->connections, uuid); if (connection_should_exist && !connection_exists) { diff --git a/src/core/dhcp/nm-dhcp-client.c b/src/core/dhcp/nm-dhcp-client.c index 600cb930..1fc2d944 100644 --- a/src/core/dhcp/nm-dhcp-client.c +++ b/src/core/dhcp/nm-dhcp-client.c @@ -241,7 +241,8 @@ nm_dhcp_client_create_l3cd(NMDhcpClient *self) GHashTable * nm_dhcp_client_create_options_dict(NMDhcpClient *self, gboolean static_keys) { - NMDhcpClientPrivate *priv = NM_DHCP_CLIENT_GET_PRIVATE(self); + NMDhcpClientPrivate *priv = NM_DHCP_CLIENT_GET_PRIVATE(self); + const int IS_IPv4 = NM_IS_IPv4(priv->config.addr_family); GHashTable *options; GBytes *effective_client_id; @@ -249,22 +250,18 @@ nm_dhcp_client_create_options_dict(NMDhcpClient *self, gboolean static_keys) effective_client_id = nm_dhcp_client_get_effective_client_id(self); if (effective_client_id) { - guint option = NM_IS_IPv4(priv->config.addr_family) ? NM_DHCP_OPTION_DHCP4_CLIENT_ID - : NM_DHCP_OPTION_DHCP6_CLIENT_ID; - gs_free char *str = nm_dhcp_utils_duid_to_string(effective_client_id); + guint option = IS_IPv4 ? NM_DHCP_OPTION_DHCP4_CLIENT_ID : NM_DHCP_OPTION_DHCP6_CLIENT_ID; + gs_free char *str = nm_dhcp_utils_duid_to_string(effective_client_id); /* Note that for the nm-dhcp-helper based plugins (dhclient), the plugin * may send the used client-id/DUID via the environment variables and * overwrite them yet again. */ - if (static_keys) { - nm_dhcp_option_add_option(options, priv->config.addr_family, option, str); - } else { - g_hash_table_insert( - options, - g_strdup(nm_dhcp_option_request_string(priv->config.addr_family, option)), - g_steal_pointer(&str)); - } + nm_dhcp_option_take_option(options, + static_keys, + priv->config.addr_family, + option, + g_steal_pointer(&str)); } return options; @@ -1591,6 +1588,20 @@ maybe_add_option(NMDhcpClient *self, GHashTable *hash, const char *key, GVariant str_value = nm_dhcp_utils_duid_to_string(bytes); } + if (!IS_IPv4 && nm_streq(key, "iaid")) { + gs_free char *str = g_steal_pointer(&str_value); + guint32 iaid; + + /* Validate and normalize the iaid. */ + + if (!nm_dhcp_iaid_from_hexstr(str, &iaid)) { + /* Seems invalid. Ignore */ + return; + } + + str_value = nm_dhcp_iaid_to_hexstr(iaid, g_malloc(NM_DHCP_IAID_TO_HEXSTR_BUF_LEN)); + } + g_hash_table_insert(hash, g_strdup(key), str_value); /* dhclient has no special labels for private dhcp options: it uses "unknown_xyz" diff --git a/src/core/dhcp/nm-dhcp-nettools.c b/src/core/dhcp/nm-dhcp-nettools.c index 9cdfd9aa..f36dfb4d 100644 --- a/src/core/dhcp/nm-dhcp-nettools.c +++ b/src/core/dhcp/nm-dhcp-nettools.c @@ -84,6 +84,11 @@ static void dhcp4_event_pop_all_events_on_idle(NMDhcpNettools *self); /*****************************************************************************/ +#define _add_option(options, option, str) \ + nm_dhcp_option_add_option((options), TRUE, AF_INET, (option), (str)) + +/*****************************************************************************/ + static void set_error_nettools(GError **error, int r, const char *message) { @@ -266,26 +271,34 @@ lease_parse_address(NMDhcpNettools *self /* for logging context only */, } nm_dhcp_option_add_option_in_addr(options, + TRUE, AF_INET, NM_DHCP_OPTION_DHCP4_NM_IP_ADDRESS, a_address.s_addr); nm_dhcp_option_add_option_in_addr(options, + TRUE, AF_INET, NM_DHCP_OPTION_DHCP4_SUBNET_MASK, a_netmask); nm_dhcp_option_add_option_u64(options, + TRUE, AF_INET, NM_DHCP_OPTION_DHCP4_IP_ADDRESS_LEASE_TIME, (guint64) a_lifetime); if (a_expiry != G_MAXUINT64) { - nm_dhcp_option_add_option_u64(options, AF_INET, NM_DHCP_OPTION_DHCP4_NM_EXPIRY, a_expiry); + nm_dhcp_option_add_option_u64(options, + TRUE, + AF_INET, + NM_DHCP_OPTION_DHCP4_NM_EXPIRY, + a_expiry); } n_dhcp4_client_lease_get_siaddr(lease, &a_next_server); if (a_next_server.s_addr != INADDR_ANY) { nm_dhcp_option_add_option_in_addr(options, + TRUE, AF_INET, NM_DHCP_OPTION_DHCP4_NM_NEXT_SERVER, a_next_server.s_addr); @@ -368,7 +381,7 @@ lease_parse_address_list(NDhcp4ClientLease *lease, } } - nm_dhcp_option_add_option(options, AF_INET, option, nm_str_buf_get_str(sbuf)); + _add_option(options, option, nm_str_buf_get_str(sbuf)); } static void @@ -446,7 +459,7 @@ lease_parse_routes(NDhcp4ClientLease *lease, } has_classless = TRUE; - nm_dhcp_option_add_option(options, AF_INET, option_code, nm_str_buf_get_str(sbuf)); + _add_option(options, option_code, nm_str_buf_get_str(sbuf)); } r = _client_lease_query(lease, NM_DHCP_OPTION_DHCP4_STATIC_ROUTE, &l_data, &l_data_len); @@ -489,10 +502,7 @@ lease_parse_routes(NDhcp4ClientLease *lease, })); } - nm_dhcp_option_add_option(options, - AF_INET, - NM_DHCP_OPTION_DHCP4_STATIC_ROUTE, - nm_str_buf_get_str(sbuf)); + _add_option(options, NM_DHCP_OPTION_DHCP4_STATIC_ROUTE, nm_str_buf_get_str(sbuf)); } r = _client_lease_query(lease, NM_DHCP_OPTION_DHCP4_ROUTER, &l_data, &l_data_len); @@ -534,10 +544,7 @@ lease_parse_routes(NDhcp4ClientLease *lease, })); } - nm_dhcp_option_add_option(options, - AF_INET, - NM_DHCP_OPTION_DHCP4_ROUTER, - nm_str_buf_get_str(sbuf)); + _add_option(options, NM_DHCP_OPTION_DHCP4_ROUTER, nm_str_buf_get_str(sbuf)); } } @@ -570,6 +577,7 @@ lease_parse_search_domains(NDhcp4ClientLease *lease, nm_l3_config_data_add_search(l3cd, AF_INET, domains[i]); nm_dhcp_option_take_option(options, + TRUE, AF_INET, NM_DHCP_OPTION_DHCP4_DOMAIN_SEARCH_LIST, g_strjoinv(" ", domains)); @@ -598,7 +606,7 @@ lease_parse_private_options(NDhcp4ClientLease *lease, GHashTable *options) continue; option_string = nm_utils_bin2hexstr_full(l_data, l_data_len, ':', FALSE, NULL); - nm_dhcp_option_take_option(options, AF_INET, i, g_steal_pointer(&option_string)); + nm_dhcp_option_take_option(options, TRUE, AF_INET, i, g_steal_pointer(&option_string)); } } @@ -632,6 +640,7 @@ lease_to_ip4_config(NMDhcpNettools *self, NDhcp4ClientLease *lease, GError **err r = n_dhcp4_client_lease_get_server_identifier(lease, &v_inaddr_s); if (r == 0) { nm_dhcp_option_add_option_in_addr(options, + TRUE, AF_INET, NM_DHCP_OPTION_DHCP4_SERVER_ID, v_inaddr_s.s_addr); @@ -645,6 +654,7 @@ lease_to_ip4_config(NMDhcpNettools *self, NDhcp4ClientLease *lease, GError **err iface, NM_DHCP_OPTION_DHCP4_BROADCAST)) { nm_dhcp_option_add_option_in_addr(options, + TRUE, AF_INET, NM_DHCP_OPTION_DHCP4_BROADCAST, v_inaddr); @@ -696,10 +706,7 @@ lease_to_ip4_config(NMDhcpNettools *self, NDhcp4ClientLease *lease, GError **err } if (sbuf.len > 0) { - nm_dhcp_option_add_option(options, - AF_INET, - NM_DHCP_OPTION_DHCP4_DOMAIN_NAME, - nm_str_buf_get_str(&sbuf)); + _add_option(options, NM_DHCP_OPTION_DHCP4_DOMAIN_NAME, nm_str_buf_get_str(&sbuf)); } } @@ -713,7 +720,11 @@ lease_to_ip4_config(NMDhcpNettools *self, NDhcp4ClientLease *lease, GError **err iface, AF_INET, NM_DHCP_OPTION_DHCP4_INTERFACE_MTU)) { - nm_dhcp_option_add_option_u64(options, AF_INET, NM_DHCP_OPTION_DHCP4_INTERFACE_MTU, v_u16); + nm_dhcp_option_add_option_u64(options, + TRUE, + AF_INET, + NM_DHCP_OPTION_DHCP4_INTERFACE_MTU, + v_u16); nm_l3_config_data_set_mtu(l3cd, v_u16); } @@ -731,7 +742,7 @@ lease_to_ip4_config(NMDhcpNettools *self, NDhcp4ClientLease *lease, GError **err iface, AF_INET, NM_DHCP_OPTION_DHCP4_HOST_NAME)) { - nm_dhcp_option_add_option(options, AF_INET, NM_DHCP_OPTION_DHCP4_HOST_NAME, s); + _add_option(options, NM_DHCP_OPTION_DHCP4_HOST_NAME, s); } } @@ -755,6 +766,7 @@ lease_to_ip4_config(NMDhcpNettools *self, NDhcp4ClientLease *lease, GError **err /* "Its minimum length is 1." */ } else { nm_dhcp_option_add_option_utf8safe_escape(options, + TRUE, AF_INET, NM_DHCP_OPTION_DHCP4_ROOT_PATH, l_data, @@ -782,10 +794,7 @@ lease_to_ip4_config(NMDhcpNettools *self, NDhcp4ClientLease *lease, GError **err const char *escaped; escaped = nm_utils_buf_utf8safe_escape((char *) l_data, l_data_len, 0, &to_free); - nm_dhcp_option_add_option(options, - AF_INET, - NM_DHCP_OPTION_DHCP4_PRIVATE_PROXY_AUTODISCOVERY, - escaped ?: ""); + _add_option(options, NM_DHCP_OPTION_DHCP4_PRIVATE_PROXY_AUTODISCOVERY, escaped ?: ""); nm_l3_config_data_set_proxy_method(l3cd, NM_PROXY_CONFIG_METHOD_AUTO); nm_l3_config_data_set_proxy_pac_url(l3cd, escaped ?: ""); @@ -808,7 +817,7 @@ lease_to_ip4_config(NMDhcpNettools *self, NDhcp4ClientLease *lease, GError **err NM_UTILS_STR_UTF8_SAFE_FLAG_ESCAPE_CTRL, &to_free); - nm_dhcp_option_add_option(options, AF_INET, NM_DHCP_OPTION_DHCP4_NIS_DOMAIN, v_str ?: ""); + _add_option(options, NM_DHCP_OPTION_DHCP4_NIS_DOMAIN, v_str ?: ""); nm_l3_config_data_set_nis_domain(l3cd, v_str ?: ""); } @@ -820,7 +829,7 @@ lease_to_ip4_config(NMDhcpNettools *self, NDhcp4ClientLease *lease, GError **err -1, NM_UTILS_STR_UTF8_SAFE_FLAG_ESCAPE_CTRL, &to_free); - nm_dhcp_option_add_option(options, AF_INET, NM_DHCP_OPTION_DHCP4_NM_FILENAME, v_str ?: ""); + _add_option(options, NM_DHCP_OPTION_DHCP4_NM_FILENAME, v_str ?: ""); } r = _client_lease_query(lease, NM_DHCP_OPTION_DHCP4_BOOTFILE_NAME, &l_data, &l_data_len); @@ -837,10 +846,7 @@ lease_to_ip4_config(NMDhcpNettools *self, NDhcp4ClientLease *lease, GError **err l_data_len, NM_UTILS_STR_UTF8_SAFE_FLAG_ESCAPE_CTRL, &to_free); - nm_dhcp_option_add_option(options, - AF_INET, - NM_DHCP_OPTION_DHCP4_BOOTFILE_NAME, - v_str ?: ""); + _add_option(options, NM_DHCP_OPTION_DHCP4_BOOTFILE_NAME, v_str ?: ""); } lease_parse_address_list(lease, l3cd, iface, NM_DHCP_OPTION_DHCP4_NIS_SERVERS, options, &sbuf); diff --git a/src/core/dhcp/nm-dhcp-options.c b/src/core/dhcp/nm-dhcp-options.c index d95fe016..33a9f4ed 100644 --- a/src/core/dhcp/nm-dhcp-options.c +++ b/src/core/dhcp/nm-dhcp-options.c @@ -383,8 +383,14 @@ nm_dhcp_option_find(int addr_family, guint option) /*****************************************************************************/ void -nm_dhcp_option_take_option(GHashTable *options, int addr_family, guint option, char *value) +nm_dhcp_option_take_option(GHashTable *options, + gboolean static_keys, + int addr_family, + guint option, + char *value) { + const char *key; + nm_assert_addr_family(addr_family); nm_assert(value); nm_assert(g_utf8_validate(value, -1, NULL)); @@ -395,19 +401,13 @@ nm_dhcp_option_take_option(GHashTable *options, int addr_family, guint option, c return; } - g_hash_table_insert(options, - (gpointer) nm_dhcp_option_request_string(addr_family, option), - value); -} - -void -nm_dhcp_option_add_option(GHashTable *options, int addr_family, guint option, const char *value) -{ - nm_dhcp_option_take_option(options, addr_family, option, g_strdup(value)); + key = nm_dhcp_option_request_string(addr_family, option), + g_hash_table_insert(options, static_keys ? (gpointer) key : g_strdup(key), value); } void nm_dhcp_option_add_option_utf8safe_escape(GHashTable *options, + gboolean static_keys, int addr_family, guint option, const guint8 *data, @@ -420,13 +420,18 @@ nm_dhcp_option_add_option_utf8safe_escape(GHashTable *options, n_data, NM_UTILS_STR_UTF8_SAFE_FLAG_ESCAPE_CTRL, &to_free); - nm_dhcp_option_add_option(options, addr_family, option, escaped ?: ""); + nm_dhcp_option_add_option(options, static_keys, addr_family, option, escaped ?: ""); } void -nm_dhcp_option_add_option_u64(GHashTable *options, int addr_family, guint option, guint64 value) +nm_dhcp_option_add_option_u64(GHashTable *options, + gboolean static_keys, + int addr_family, + guint option, + guint64 value) { nm_dhcp_option_take_option(options, + static_keys, addr_family, option, g_strdup_printf("%" G_GUINT64_FORMAT, value)); @@ -434,13 +439,18 @@ nm_dhcp_option_add_option_u64(GHashTable *options, int addr_family, guint option void nm_dhcp_option_add_option_in_addr(GHashTable *options, + gboolean static_keys, int addr_family, guint option, in_addr_t value) { char sbuf[NM_INET_ADDRSTRLEN]; - nm_dhcp_option_add_option(options, addr_family, option, nm_inet4_ntop(value, sbuf)); + nm_dhcp_option_add_option(options, + static_keys, + addr_family, + option, + nm_inet4_ntop(value, sbuf)); } void diff --git a/src/core/dhcp/nm-dhcp-options.h b/src/core/dhcp/nm-dhcp-options.h index fcc6f9cd..050080d9 100644 --- a/src/core/dhcp/nm-dhcp-options.h +++ b/src/core/dhcp/nm-dhcp-options.h @@ -208,20 +208,38 @@ nm_dhcp_option_request_string(int addr_family, guint option) return nm_dhcp_option_get_name(nm_dhcp_option_find(addr_family, option)); } -void nm_dhcp_option_take_option(GHashTable *options, int addr_family, guint option, char *value); -void -nm_dhcp_option_add_option(GHashTable *options, int addr_family, guint option, const char *value); +void nm_dhcp_option_take_option(GHashTable *options, + gboolean static_keys, + int addr_family, + guint option, + char *value); + +static inline void +nm_dhcp_option_add_option(GHashTable *options, + gboolean static_keys, + int addr_family, + guint option, + const char *value) +{ + nm_dhcp_option_take_option(options, static_keys, addr_family, option, g_strdup(value)); +} + void nm_dhcp_option_add_option_utf8safe_escape(GHashTable *options, + gboolean static_keys, int addr_family, guint option, const guint8 *data, gsize n_data); void nm_dhcp_option_add_option_in_addr(GHashTable *options, + gboolean static_keys, int addr_family, guint option, in_addr_t value); -void -nm_dhcp_option_add_option_u64(GHashTable *options, int addr_family, guint option, guint64 value); +void nm_dhcp_option_add_option_u64(GHashTable *options, + gboolean static_keys, + int addr_family, + guint option, + guint64 value); void nm_dhcp_option_add_requests_to_options(GHashTable *options, int addr_family); GHashTable *nm_dhcp_option_create_options_dict(gboolean static_keys); diff --git a/src/core/dhcp/nm-dhcp-systemd.c b/src/core/dhcp/nm-dhcp-systemd.c index 10990822..6f9312da 100644 --- a/src/core/dhcp/nm-dhcp-systemd.c +++ b/src/core/dhcp/nm-dhcp-systemd.c @@ -70,11 +70,13 @@ G_DEFINE_TYPE(NMDhcpSystemd, nm_dhcp_systemd, NM_TYPE_DHCP_CLIENT) static NML3ConfigData * lease_to_ip6_config(NMDhcpSystemd *self, sd_dhcp6_lease *lease, gint32 ts, GError **error) { + const NMDhcpClientConfig *config; nm_auto_unref_l3cd_init NML3ConfigData *l3cd = NULL; gs_unref_hashtable GHashTable *options = NULL; struct in6_addr tmp_addr; const struct in6_addr *dns; char addr_str[NM_INET_ADDRSTRLEN]; + char iaid_buf[NM_DHCP_IAID_TO_HEXSTR_BUF_LEN]; char **domains; char **ntp_fqdns; const struct in6_addr *ntp_addrs; @@ -84,11 +86,19 @@ lease_to_ip6_config(NMDhcpSystemd *self, sd_dhcp6_lease *lease, gint32 ts, GErro nm_assert(lease); + config = nm_dhcp_client_get_config(NM_DHCP_CLIENT(self)); + l3cd = nm_dhcp_client_create_l3cd(NM_DHCP_CLIENT(self)); options = nm_dhcp_client_create_options_dict(NM_DHCP_CLIENT(self), TRUE); - if (!nm_dhcp_client_get_config(NM_DHCP_CLIENT(self))->v6.info_only) { + nm_dhcp_option_add_option(options, + TRUE, + AF_INET6, + NM_DHCP_OPTION_DHCP6_NM_IAID, + nm_dhcp_iaid_to_hexstr(config->v6.iaid, iaid_buf)); + + if (!config->v6.info_only) { gboolean has_any_addresses = FALSE; uint32_t lft_pref; uint32_t lft_valid; @@ -115,6 +125,7 @@ lease_to_ip6_config(NMDhcpSystemd *self, sd_dhcp6_lease *lease, gint32 ts, GErro if (str->len) { nm_dhcp_option_add_option(options, + TRUE, AF_INET6, NM_DHCP_OPTION_DHCP6_NM_IP_ADDRESS, str->str); @@ -137,7 +148,11 @@ lease_to_ip6_config(NMDhcpSystemd *self, sd_dhcp6_lease *lease, gint32 ts, GErro g_string_append(nm_gstring_add_space_delimiter(str), addr_str); nm_l3_config_data_add_nameserver_detail(l3cd, AF_INET6, &dns[i], NULL); } - nm_dhcp_option_add_option(options, AF_INET6, NM_DHCP_OPTION_DHCP6_DNS_SERVERS, str->str); + nm_dhcp_option_add_option(options, + TRUE, + AF_INET6, + NM_DHCP_OPTION_DHCP6_DNS_SERVERS, + str->str); } num = sd_dhcp6_lease_get_domains(lease, &domains); @@ -147,11 +162,15 @@ lease_to_ip6_config(NMDhcpSystemd *self, sd_dhcp6_lease *lease, gint32 ts, GErro g_string_append(nm_gstring_add_space_delimiter(str), domains[i]); nm_l3_config_data_add_search(l3cd, AF_INET6, domains[i]); } - nm_dhcp_option_add_option(options, AF_INET6, NM_DHCP_OPTION_DHCP6_DOMAIN_LIST, str->str); + nm_dhcp_option_add_option(options, + TRUE, + AF_INET6, + NM_DHCP_OPTION_DHCP6_DOMAIN_LIST, + str->str); } if (sd_dhcp6_lease_get_fqdn(lease, &s) >= 0) { - nm_dhcp_option_add_option(options, AF_INET6, NM_DHCP_OPTION_DHCP6_FQDN, s); + nm_dhcp_option_add_option(options, TRUE, AF_INET6, NM_DHCP_OPTION_DHCP6_FQDN, s); } /* RFC 5908, section 4 states: "This option MUST include one, and only @@ -175,7 +194,11 @@ lease_to_ip6_config(NMDhcpSystemd *self, sd_dhcp6_lease *lease, gint32 ts, GErro } } if (str->len) { - nm_dhcp_option_add_option(options, AF_INET6, NM_DHCP_OPTION_DHCP6_NTP_SERVER, str->str); + nm_dhcp_option_add_option(options, + TRUE, + AF_INET6, + NM_DHCP_OPTION_DHCP6_NTP_SERVER, + str->str); } nm_l3_config_data_set_dhcp_lease_from_options(l3cd, AF_INET6, g_steal_pointer(&options)); diff --git a/src/core/nm-active-connection.c b/src/core/nm-active-connection.c index 4488d909..6f62a601 100644 --- a/src/core/nm-active-connection.c +++ b/src/core/nm-active-connection.c @@ -81,6 +81,7 @@ NM_GOBJECT_PROPERTIES_DEFINE(NMActiveConnection, PROP_DHCP6_CONFIG, PROP_VPN, PROP_MASTER, + PROP_CONTROLLER, PROP_INT_SETTINGS_CONNECTION, PROP_INT_APPLIED_CONNECTION, @@ -803,7 +804,7 @@ check_master_ready(NMActiveConnection *self) * ensure that if the master connection was created without a device * that we notify clients when the master device is known. */ - _notify(self, PROP_MASTER); + nm_gobject_notify_together(self, PROP_MASTER, PROP_CONTROLLER); } } @@ -1343,6 +1344,7 @@ get_property(GObject *object, guint prop_id, GValue *value, GParamSpec *pspec) case PROP_VPN: g_value_set_boolean(value, priv->vpn); break; + case PROP_CONTROLLER: case PROP_MASTER: if (priv->master) master_device = nm_active_connection_get_device(priv->master); @@ -1440,8 +1442,6 @@ set_property(GObject *object, guint prop_id, const GValue *value, GParamSpec *ps /* construct-only */ priv->vpn = g_value_get_boolean(value); break; - case PROP_MASTER: - break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); break; @@ -1601,6 +1601,9 @@ static const NMDBusInterfaceInfoExtended interface_info_active_connection = { "o", NM_ACTIVE_CONNECTION_DHCP6_CONFIG), NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE("Vpn", "b", NM_ACTIVE_CONNECTION_VPN), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE("Controller", + "o", + NM_ACTIVE_CONNECTION_CONTROLLER), NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE("Master", "o", NM_ACTIVE_CONNECTION_MASTER), ), ), @@ -1732,6 +1735,13 @@ nm_active_connection_class_init(NMActiveConnectionClass *ac_class) NULL, G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); + obj_properties[PROP_CONTROLLER] = + g_param_spec_string(NM_ACTIVE_CONNECTION_CONTROLLER, + "", + "", + NULL, + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); + /* Internal properties */ obj_properties[PROP_INT_SETTINGS_CONNECTION] = g_param_spec_object(NM_ACTIVE_CONNECTION_INT_SETTINGS_CONNECTION, diff --git a/src/core/nm-active-connection.h b/src/core/nm-active-connection.h index a2353a65..15db68c3 100644 --- a/src/core/nm-active-connection.h +++ b/src/core/nm-active-connection.h @@ -38,6 +38,7 @@ #define NM_ACTIVE_CONNECTION_DHCP6_CONFIG "dhcp6-config" #define NM_ACTIVE_CONNECTION_VPN "vpn" #define NM_ACTIVE_CONNECTION_MASTER "master" +#define NM_ACTIVE_CONNECTION_CONTROLLER "controller" /* Internal non-exported properties */ #define NM_ACTIVE_CONNECTION_INT_SETTINGS_CONNECTION "int-settings-connection" diff --git a/src/core/nm-core-utils.c b/src/core/nm-core-utils.c index 9448ba7b..500bffb9 100644 --- a/src/core/nm-core-utils.c +++ b/src/core/nm-core-utils.c @@ -4868,11 +4868,14 @@ typedef struct { int child_stdin; int child_stdout; + int child_stderr; GSource *input_source; GSource *output_source; + GSource *error_source; NMStrBuf in_buffer; NMStrBuf out_buffer; + NMStrBuf err_buffer; gsize out_buffer_offset; } HelperInfo; @@ -4908,13 +4911,17 @@ helper_info_free(gpointer data) nm_str_buf_destroy(&info->in_buffer); nm_str_buf_destroy(&info->out_buffer); + nm_str_buf_destroy(&info->err_buffer); nm_clear_g_source_inst(&info->input_source); nm_clear_g_source_inst(&info->output_source); + nm_clear_g_source_inst(&info->error_source); if (info->child_stdout != -1) nm_close(info->child_stdout); if (info->child_stdin != -1) nm_close(info->child_stdin); + if (info->child_stderr != -1) + nm_close(info->child_stderr); if (info->pid != -1) { nm_assert(info->pid > 1); @@ -4928,6 +4935,10 @@ static void helper_complete(HelperInfo *info, GError *error) { if (error) { + if (info->err_buffer.len > 0) { + _LOG2T(info, "stderr: %s", nm_str_buf_get_str(&info->err_buffer)); + } + nm_clear_g_cancellable_disconnect(g_task_get_cancellable(info->task), &info->cancellable_id); g_task_return_error(info->task, error); @@ -5023,6 +5034,24 @@ helper_have_data(int fd, GIOCondition condition, gpointer user_data) return G_SOURCE_CONTINUE; } +static gboolean +helper_have_err_data(int fd, GIOCondition condition, gpointer user_data) +{ + HelperInfo *info = user_data; + gssize n_read; + + n_read = nm_utils_fd_read(fd, &info->err_buffer); + + if (n_read > 0) + return G_SOURCE_CONTINUE; + + nm_clear_g_source_inst(&info->error_source); + nm_close(info->child_stderr); + info->child_stderr = -1; + + return G_SOURCE_CONTINUE; +} + static void helper_child_terminated(GPid pid, int status, gpointer user_data) { @@ -5098,10 +5127,11 @@ nm_utils_spawn_helper(const char *const *args, &info->pid, &info->child_stdin, &info->child_stdout, - NULL, + &info->child_stderr, &error)) { info->child_stdin = -1; info->child_stdout = -1; + info->child_stderr = -1; info->pid = -1; g_task_return_error(info->task, g_error_new(NM_UTILS_ERROR, @@ -5130,9 +5160,11 @@ nm_utils_spawn_helper(const char *const *args, fcntl(info->child_stdin, F_SETFL, fd_flags | O_NONBLOCK); fd_flags = fcntl(info->child_stdout, F_GETFD, 0); fcntl(info->child_stdout, F_SETFL, fd_flags | O_NONBLOCK); + fd_flags = fcntl(info->child_stderr, F_GETFD, 0); + fcntl(info->child_stderr, F_SETFL, fd_flags | O_NONBLOCK); /* Watch process stdin */ - info->out_buffer = NM_STR_BUF_INIT(32, TRUE); + info->out_buffer = NM_STR_BUF_INIT(NM_UTILS_GET_NEXT_REALLOC_SIZE_40, TRUE); for (arg = args; *arg; arg++) { nm_str_buf_append(&info->out_buffer, *arg); nm_str_buf_append_c(&info->out_buffer, '\0'); @@ -5146,7 +5178,7 @@ nm_utils_spawn_helper(const char *const *args, g_source_attach(info->output_source, g_main_context_get_thread_default()); /* Watch process stdout */ - info->in_buffer = NM_STR_BUF_INIT(NM_UTILS_GET_NEXT_REALLOC_SIZE_1000, FALSE); + info->in_buffer = NM_STR_BUF_INIT(0, FALSE); info->input_source = nm_g_unix_fd_source_new(info->child_stdout, G_IO_IN | G_IO_ERR | G_IO_HUP, G_PRIORITY_DEFAULT, @@ -5155,6 +5187,16 @@ nm_utils_spawn_helper(const char *const *args, NULL); g_source_attach(info->input_source, g_main_context_get_thread_default()); + /* Watch process stderr */ + info->err_buffer = NM_STR_BUF_INIT(0, FALSE); + info->error_source = nm_g_unix_fd_source_new(info->child_stderr, + G_IO_IN | G_IO_ERR | G_IO_HUP, + G_PRIORITY_DEFAULT, + helper_have_err_data, + info, + NULL); + g_source_attach(info->error_source, g_main_context_get_thread_default()); + if (cancellable) { gulong signal_id; diff --git a/src/core/nm-dispatcher.c b/src/core/nm-dispatcher.c index 01a63826..cdc07dd6 100644 --- a/src/core/nm-dispatcher.c +++ b/src/core/nm-dispatcher.c @@ -231,7 +231,7 @@ dump_ip_to_props(const NML3ConfigData *l3cd, int addr_family, GVariantBuilder *b continue; if (IS_IPv4) - g_variant_builder_add(&int_builder, "u", &a); + g_variant_builder_add(&int_builder, "u", a.addr4); else g_variant_builder_add(&int_builder, "@ay", nm_g_variant_new_ay_in6addr(&a.addr6)); } diff --git a/src/core/nm-policy.c b/src/core/nm-policy.c index 4192808a..d7e05b7b 100644 --- a/src/core/nm-policy.c +++ b/src/core/nm-policy.c @@ -2581,7 +2581,7 @@ dns_config_changed(NMDnsManager *dns_manager, gpointer user_data) return; nm_manager_for_each_device (priv->manager, device, tmp_lst) { - nm_device_clear_dns_lookup_data(device); + nm_device_clear_dns_lookup_data(device, "DNS configuration changed"); } update_system_hostname(self, "DNS configuration changed"); diff --git a/src/core/settings/plugins/ifcfg-rh/nms-ifcfg-rh-reader.c b/src/core/settings/plugins/ifcfg-rh/nms-ifcfg-rh-reader.c index 0eeead8a..aa593331 100644 --- a/src/core/settings/plugins/ifcfg-rh/nms-ifcfg-rh-reader.c +++ b/src/core/settings/plugins/ifcfg-rh/nms-ifcfg-rh-reader.c @@ -1944,6 +1944,8 @@ make_ip4_setting(shvarFile *ifcfg, ipv4_link_local, NM_SETTING_IP_CONFIG_AUTO_ROUTE_EXT_GW, svGetValueTernary(ifcfg, "IPV4_AUTO_ROUTE_EXT_GW"), + NM_SETTING_IP_CONFIG_REPLACE_LOCAL_RULE, + svGetValueTernary(ifcfg, "IPV4_REPLACE_LOCAL_RULE"), NULL); if (nm_streq(method, NM_SETTING_IP4_CONFIG_METHOD_DISABLED)) @@ -2459,6 +2461,8 @@ make_ip6_setting(shvarFile *ifcfg, shvarFile *network_ifcfg, gboolean routes_rea ip6_privacy_val, NM_SETTING_IP_CONFIG_AUTO_ROUTE_EXT_GW, svGetValueTernary(ifcfg, "IPV6_AUTO_ROUTE_EXT_GW"), + NM_SETTING_IP_CONFIG_REPLACE_LOCAL_RULE, + svGetValueTernary(ifcfg, "IPV6_REPLACE_LOCAL_RULE"), NULL); /* Don't bother to read IP, DNS and routes when IPv6 is disabled */ diff --git a/src/core/settings/plugins/ifcfg-rh/nms-ifcfg-rh-utils.c b/src/core/settings/plugins/ifcfg-rh/nms-ifcfg-rh-utils.c index 85a0eb26..552310dd 100644 --- a/src/core/settings/plugins/ifcfg-rh/nms-ifcfg-rh-utils.c +++ b/src/core/settings/plugins/ifcfg-rh/nms-ifcfg-rh-utils.c @@ -962,6 +962,7 @@ const NMSIfcfgKeyTypeInfo nms_ifcfg_well_known_keys[] = { _KEY_TYPE("IPV4_DNS_PRIORITY", NMS_IFCFG_KEY_TYPE_IS_PLAIN), _KEY_TYPE("IPV4_FAILURE_FATAL", NMS_IFCFG_KEY_TYPE_IS_PLAIN), _KEY_TYPE("IPV4_LINK_LOCAL", NMS_IFCFG_KEY_TYPE_IS_PLAIN), + _KEY_TYPE("IPV4_REPLACE_LOCAL_RULE", NMS_IFCFG_KEY_TYPE_IS_PLAIN), _KEY_TYPE("IPV4_REQUIRED_TIMEOUT", NMS_IFCFG_KEY_TYPE_IS_PLAIN), _KEY_TYPE("IPV4_ROUTE_METRIC", NMS_IFCFG_KEY_TYPE_IS_PLAIN), _KEY_TYPE("IPV4_ROUTE_TABLE", NMS_IFCFG_KEY_TYPE_IS_PLAIN), @@ -986,6 +987,7 @@ const NMSIfcfgKeyTypeInfo nms_ifcfg_well_known_keys[] = { _KEY_TYPE("IPV6_PRIVACY", NMS_IFCFG_KEY_TYPE_IS_PLAIN), _KEY_TYPE("IPV6_PRIVACY_PREFER_PUBLIC_IP", NMS_IFCFG_KEY_TYPE_IS_PLAIN), _KEY_TYPE("IPV6_RA_TIMEOUT", NMS_IFCFG_KEY_TYPE_IS_PLAIN), + _KEY_TYPE("IPV6_REPLACE_LOCAL_RULE", NMS_IFCFG_KEY_TYPE_IS_PLAIN), _KEY_TYPE("IPV6_REQUIRED_TIMEOUT", NMS_IFCFG_KEY_TYPE_IS_PLAIN), _KEY_TYPE("IPV6_RES_OPTIONS", NMS_IFCFG_KEY_TYPE_IS_PLAIN), _KEY_TYPE("IPV6_ROUTE_METRIC", NMS_IFCFG_KEY_TYPE_IS_PLAIN), diff --git a/src/core/settings/plugins/ifcfg-rh/nms-ifcfg-rh-utils.h b/src/core/settings/plugins/ifcfg-rh/nms-ifcfg-rh-utils.h index 31064274..4fa9f18c 100644 --- a/src/core/settings/plugins/ifcfg-rh/nms-ifcfg-rh-utils.h +++ b/src/core/settings/plugins/ifcfg-rh/nms-ifcfg-rh-utils.h @@ -33,7 +33,7 @@ typedef struct { NMSIfcfgKeyTypeFlags key_flags; } NMSIfcfgKeyTypeInfo; -extern const NMSIfcfgKeyTypeInfo nms_ifcfg_well_known_keys[259]; +extern const NMSIfcfgKeyTypeInfo nms_ifcfg_well_known_keys[261]; const NMSIfcfgKeyTypeInfo *nms_ifcfg_well_known_key_find_info(const char *key, gssize *out_idx); diff --git a/src/core/settings/plugins/ifcfg-rh/nms-ifcfg-rh-writer.c b/src/core/settings/plugins/ifcfg-rh/nms-ifcfg-rh-writer.c index 2ea097fd..41260020 100644 --- a/src/core/settings/plugins/ifcfg-rh/nms-ifcfg-rh-writer.c +++ b/src/core/settings/plugins/ifcfg-rh/nms-ifcfg-rh-writer.c @@ -2941,6 +2941,10 @@ write_ip4_setting(NMConnection *connection, svSetValueTernary(ifcfg, "IPV4_AUTO_ROUTE_EXT_GW", nm_setting_ip_config_get_auto_route_ext_gw(s_ip4)); + + svSetValueTernary(ifcfg, + "IPV4_REPLACE_LOCAL_RULE", + nm_setting_ip_config_get_replace_local_rule(s_ip4)); } static void @@ -3205,6 +3209,10 @@ write_ip6_setting(NMConnection *connection, shvarFile *ifcfg, GString **out_rout svSetValueTernary(ifcfg, "IPV6_AUTO_ROUTE_EXT_GW", nm_setting_ip_config_get_auto_route_ext_gw(s_ip6)); + + svSetValueTernary(ifcfg, + "IPV6_REPLACE_LOCAL_RULE", + nm_setting_ip_config_get_replace_local_rule(s_ip6)); } static void diff --git a/src/core/vpn/nm-vpn-connection.c b/src/core/vpn/nm-vpn-connection.c index 4fb926a5..d7102a12 100644 --- a/src/core/vpn/nm-vpn-connection.c +++ b/src/core/vpn/nm-vpn-connection.c @@ -99,6 +99,7 @@ NM_GOBJECT_PROPERTIES_DEFINE(NMVpnConnection, PROP_VPN_STATE, PROP_BANNER, #define PROP_IP4_CONFIG 2000 #define PROP_IP6_CONFIG 2001 #define PROP_MASTER 2002 +#define PROP_CONTROLLER 2003 ); typedef struct { @@ -2899,6 +2900,7 @@ get_property(GObject *object, guint prop_id, GValue *value, GParamSpec *pspec) case PROP_IP6_CONFIG: nm_dbus_utils_g_value_set_object_path(value, priv->ip_data_6.ip_config); break; + case PROP_CONTROLLER: case PROP_MASTER: nm_dbus_utils_g_value_set_object_path( value, @@ -3065,6 +3067,9 @@ nm_vpn_connection_class_init(NMVpnConnectionClass *klass) g_object_class_install_properties(object_class, _PROPERTY_ENUMS_LAST, obj_properties); + g_object_class_override_property(object_class, + PROP_CONTROLLER, + NM_ACTIVE_CONNECTION_CONTROLLER); g_object_class_override_property(object_class, PROP_MASTER, NM_ACTIVE_CONNECTION_MASTER); g_object_class_override_property(object_class, PROP_IP4_CONFIG, |