all: add NMMptcpFlags and connection.mptcp-flags property

This commit is contained in:
Thomas Haller 2022-07-18 21:24:09 +02:00
parent 5374c403d2
commit eb083eece5
No known key found for this signature in database
GPG key ID: 29C2366E4DFC5728
22 changed files with 1424 additions and 548 deletions

View file

@ -854,6 +854,10 @@ ipv6.ip6-privacy=0
<term><varname>connection.mdns</varname></term>
<listitem><para>If unspecified, the ultimate default values depends on the DNS plugin. With systemd-resolved the default currently is "no" (0) and for all other plugins also "no" (0).</para></listitem>
</varlistentry>
<varlistentry>
<term><varname>connection.mptcp-flags</varname></term>
<listitem><para>If unspecified, the fallback is either 0 (<literal>"disabled"</literal>) or 0x22 (<literal>"enabled-on-global-iface,subflow"</literal>), depending on <literal>/proc/sys/net/mptcp/enabled</literal>.</para></listitem>
</varlistentry>
<varlistentry>
<term><varname>connection.dns-over-tls</varname></term>
<listitem><para>If unspecified, the ultimate default values depends on the DNS plugin. With systemd-resolved the default currently is global setting and for all other plugins "no" (0).</para></listitem>

View file

@ -1398,6 +1398,56 @@ _prop_get_connection_dns_over_tls(NMDevice *self)
NM_SETTING_CONNECTION_DNS_OVER_TLS_DEFAULT);
}
static NMMptcpFlags
_prop_get_connection_mptcp_flags(NMDevice *self)
{
NMConnection *connection;
NMMptcpFlags mptcp_flags = NM_MPTCP_FLAGS_NONE;
g_return_val_if_fail(NM_IS_DEVICE(self), NM_MPTCP_FLAGS_DISABLED);
connection = nm_device_get_applied_connection(self);
if (connection) {
mptcp_flags =
nm_setting_connection_get_mptcp_flags(nm_connection_get_setting_connection(connection));
if (mptcp_flags != NM_MPTCP_FLAGS_NONE)
mptcp_flags = nm_mptcp_flags_normalize(mptcp_flags);
}
if (mptcp_flags == NM_MPTCP_FLAGS_NONE) {
guint64 v;
v = nm_config_data_get_connection_default_int64(NM_CONFIG_GET_DATA,
NM_CON_DEFAULT("connection.mptcp-flags"),
self,
0,
G_MAXINT64,
NM_MPTCP_FLAGS_NONE);
/* We filter out all invalid settings and accept it. Somewhat intentionally, we don't do a
* strict parsing of the value to support forward compatibility. */
if (v != NM_MPTCP_FLAGS_NONE)
mptcp_flags = nm_mptcp_flags_normalize(v);
}
if (mptcp_flags == NM_MPTCP_FLAGS_NONE) {
gint32 v;
v = nm_platform_sysctl_get_int32(nm_device_get_platform(self),
NMP_SYSCTL_PATHID_ABSOLUTE("/proc/sys/net/mptcp/enabled"),
-1);
if (v > 0) {
/* if MPTCP is enabled via the sysctl, we use the default. */
mptcp_flags = _NM_MPTCP_FLAGS_DEFAULT;
} else
mptcp_flags = NM_MPTCP_FLAGS_DISABLED;
}
nm_assert(mptcp_flags != NM_MPTCP_FLAGS_NONE
&& mptcp_flags == nm_mptcp_flags_normalize(mptcp_flags));
return mptcp_flags;
}
static guint32
_prop_get_ipvx_route_table(NMDevice *self, int addr_family)
{
@ -2773,6 +2823,7 @@ nm_device_create_l3_config_data_from_connection(NMDevice *self, NMConnection *co
nm_l3_config_data_set_llmnr(l3cd, _prop_get_connection_llmnr(self));
nm_l3_config_data_set_dns_over_tls(l3cd, _prop_get_connection_dns_over_tls(self));
nm_l3_config_data_set_ip6_privacy(l3cd, _prop_get_ipv6_ip6_privacy(self));
nm_l3_config_data_set_mptcp_flags(l3cd, _prop_get_connection_mptcp_flags(self));
return l3cd;
}
@ -12662,6 +12713,7 @@ can_reapply_change(NMDevice *self,
NM_SETTING_CONNECTION_MDNS,
NM_SETTING_CONNECTION_LLMNR,
NM_SETTING_CONNECTION_DNS_OVER_TLS,
NM_SETTING_CONNECTION_MPTCP_FLAGS,
NM_SETTING_CONNECTION_WAIT_ACTIVATION_DELAY);
}
@ -12878,7 +12930,8 @@ check_and_reapply_connection(NMDevice *self,
NM_SETTING_CONNECTION_LLDP,
NM_SETTING_CONNECTION_MDNS,
NM_SETTING_CONNECTION_LLMNR,
NM_SETTING_CONNECTION_DNS_OVER_TLS)) {
NM_SETTING_CONNECTION_DNS_OVER_TLS,
NM_SETTING_CONNECTION_MPTCP_FLAGS)) {
priv->ip_data_4.do_reapply = TRUE;
priv->ip_data_6.do_reapply = TRUE;
}

View file

@ -149,6 +149,8 @@ struct _NML3ConfigData {
NMSettingIP6ConfigPrivacy ip6_privacy : 4;
NMMptcpFlags mptcp_flags : 18;
bool is_sealed : 1;
bool has_routes_with_type_local_4_set : 1;
@ -582,6 +584,16 @@ nm_l3_config_data_log(const NML3ConfigData *self,
NULL)));
}
if (self->mptcp_flags != NM_MPTCP_FLAGS_NONE) {
gs_free char *s = NULL;
_L("mptcp-flags: %s",
(s = _nm_utils_enum_to_str_full(nm_mptcp_flags_get_type(),
self->mptcp_flags,
" ",
NULL)));
}
if (self->ip6_token.id != 0) {
_L("ipv6-token: %s",
nm_utils_inet6_interface_identifier_to_token(&self->ip6_token, sbuf_addr));
@ -694,6 +706,7 @@ nm_l3_config_data_new(NMDedupMultiIndex *multi_idx, int ifindex, NMIPConfigSourc
.never_default_4 = NM_OPTION_BOOL_DEFAULT,
.source = source,
.ip6_privacy = NM_SETTING_IP6_CONFIG_PRIVACY_UNKNOWN,
.mptcp_flags = NM_MPTCP_FLAGS_NONE,
.ndisc_hop_limit_set = FALSE,
.ndisc_reachable_time_msec_set = FALSE,
.ndisc_retrans_timer_msec_set = FALSE,
@ -1875,6 +1888,30 @@ nm_l3_config_data_set_ip6_token(NML3ConfigData *self, NMUtilsIPv6IfaceId ipv6_to
return TRUE;
}
NMMptcpFlags
nm_l3_config_data_get_mptcp_flags(const NML3ConfigData *self)
{
nm_assert(!self || _NM_IS_L3_CONFIG_DATA(self, TRUE));
if (!self)
return NM_MPTCP_FLAGS_NONE;
return self->mptcp_flags;
}
gboolean
nm_l3_config_data_set_mptcp_flags(NML3ConfigData *self, NMMptcpFlags mptcp_flags)
{
nm_assert(_NM_IS_L3_CONFIG_DATA(self, FALSE));
nm_assert(!NM_FLAGS_ANY(mptcp_flags, ~_NM_MPTCP_FLAGS_ALL));
if (self->mptcp_flags == mptcp_flags)
return FALSE;
self->mptcp_flags = mptcp_flags;
nm_assert(self->mptcp_flags == mptcp_flags);
return TRUE;
}
NMProxyConfigMethod
nm_l3_config_data_get_proxy_method(const NML3ConfigData *self)
{
@ -2324,6 +2361,7 @@ nm_l3_config_data_cmp_full(const NML3ConfigData *a,
NM_CMP_DIRECT_REF_STRING(a->proxy_pac_url, b->proxy_pac_url);
NM_CMP_DIRECT_REF_STRING(a->proxy_pac_script, b->proxy_pac_script);
NM_CMP_DIRECT_UNSAFE(a->ip6_privacy, b->ip6_privacy);
NM_CMP_DIRECT_UNSAFE(a->mptcp_flags, b->mptcp_flags);
NM_CMP_DIRECT_UNSAFE(a->ndisc_hop_limit_set, b->ndisc_hop_limit_set);
if (a->ndisc_hop_limit_set)
@ -3242,6 +3280,9 @@ nm_l3_config_data_merge(NML3ConfigData *self,
if (self->ip6_privacy == NM_SETTING_IP6_CONFIG_PRIVACY_UNKNOWN)
self->ip6_privacy = src->ip6_privacy;
if (self->mptcp_flags == NM_MPTCP_FLAGS_NONE)
self->mptcp_flags = src->mptcp_flags;
if (!self->ndisc_hop_limit_set && src->ndisc_hop_limit_set) {
self->ndisc_hop_limit_set = TRUE;
self->ndisc_hop_limit_val = src->ndisc_hop_limit_val;

View file

@ -487,6 +487,10 @@ NMUtilsIPv6IfaceId nm_l3_config_data_get_ip6_token(const NML3ConfigData *self);
gboolean nm_l3_config_data_set_ip6_token(NML3ConfigData *self, NMUtilsIPv6IfaceId ipv6_token);
NMMptcpFlags nm_l3_config_data_get_mptcp_flags(const NML3ConfigData *self);
gboolean nm_l3_config_data_set_mptcp_flags(NML3ConfigData *self, NMMptcpFlags mptcp_flags);
const in_addr_t *nm_l3_config_data_get_wins(const NML3ConfigData *self, guint *out_len);
gboolean nm_l3_config_data_add_wins(NML3ConfigData *self, in_addr_t wins);

View file

@ -4,6 +4,8 @@
#include "nm-l3cfg.h"
#include "libnm-std-aux/nm-linux-compat.h"
#include <net/if.h>
#include <linux/if_addr.h>
#include <linux/if_ether.h>
@ -270,6 +272,15 @@ typedef struct _NML3CfgPrivate {
NMIPConfig *ipconfig_x[2];
};
/* Whether we earlier configured MPTCP endpoints for the interface. */
union {
struct {
bool mptcp_set_6;
bool mptcp_set_4;
};
bool mptcp_set_x[2];
};
/* This is for rate-limiting the creation of nacd instance. */
GSource *nacd_instance_ensure_retry;
@ -311,6 +322,9 @@ typedef struct _NML3CfgPrivate {
bool changed_configs_configs : 1;
bool changed_configs_acd_state : 1;
bool rp_filter_handled : 1;
bool rp_filter_set : 1;
} NML3CfgPrivate;
struct _NML3CfgClass {
@ -321,6 +335,13 @@ G_DEFINE_TYPE(NML3Cfg, nm_l3cfg, G_TYPE_OBJECT)
/*****************************************************************************/
#define _NODEV_ROUTES_TAG(self, IS_IPv4) \
((gconstpointer) (&(((const char *) (self))[0 + (!(IS_IPv4))])))
#define _MPTCP_TAG(self, IS_IPv4) ((gconstpointer) (&(((const char *) (self))[2 + (!(IS_IPv4))])))
/*****************************************************************************/
#define _NMLOG_DOMAIN LOGD_CORE
#define _NMLOG_PREFIX_NAME "l3cfg"
#define _NMLOG(level, ...) \
@ -3450,9 +3471,6 @@ nm_l3cfg_remove_config_all_dirty(NML3Cfg *self, gconstpointer tag)
/*****************************************************************************/
#define _NODEV_ROUTES_TAG(self, IS_IPv4) \
((gconstpointer) (&(&(self)->priv.global_tracker)[IS_IPv4]))
static gboolean
_nodev_routes_untrack(NML3Cfg *self, int addr_family)
{
@ -3492,10 +3510,11 @@ out_clear:
if (_nodev_routes_untrack(self, addr_family))
changed = TRUE;
if (changed || commit_type >= NM_L3_CFG_COMMIT_TYPE_REAPPLY)
if (changed || commit_type >= NM_L3_CFG_COMMIT_TYPE_REAPPLY) {
nmp_global_tracker_sync(self->priv.global_tracker,
NMP_OBJECT_TYPE_IP_ROUTE(IS_IPv4),
FALSE);
}
}
/*****************************************************************************/
@ -4184,6 +4203,277 @@ _l3_commit_ip6_token(NML3Cfg *self, NML3CfgCommitType commit_type)
}
}
/*****************************************************************************/
static void
_rp_filter_update(NML3Cfg *self, gboolean reapply)
{
gboolean rp_filter_relax = FALSE;
const char *ifname;
int rf_val;
/* The rp_filter sysctl is only an IPv4 thing. We only enable the rp-filter
* handling, if we did anything to MPTCP about IPv4 addresses.
*
* While we only have one "connection.mptcp-flags=enabled" property, whether
* we handle MPTCP is still tracked per AF. In particular, with "enabled-on-global-iface"
* flag, which honors the AF-specific default route. */
if (self->priv.p->mptcp_set_4 && self->priv.p->combined_l3cd_commited
&& !NM_FLAGS_HAS(nm_l3_config_data_get_mptcp_flags(self->priv.p->combined_l3cd_commited),
NM_MPTCP_FLAGS_NO_RELAX_RP_FILTER)) {
rp_filter_relax = TRUE;
}
if (!rp_filter_relax) {
if (self->priv.p->rp_filter_handled) {
self->priv.p->rp_filter_handled = FALSE;
if (self->priv.p->rp_filter_set) {
self->priv.p->rp_filter_set = FALSE;
ifname = nm_l3cfg_get_ifname(self, TRUE);
rf_val = nm_platform_sysctl_ip_conf_get_rp_filter_ipv4(self->priv.platform,
ifname,
FALSE,
NULL);
if (rf_val == 2) {
/* We only relaxed from 1 to 2. Only if that is still the case, reset. */
nm_platform_sysctl_ip_conf_set(self->priv.platform,
AF_INET,
ifname,
"rp_filter",
"1");
}
}
}
return;
}
if (self->priv.p->rp_filter_handled && !reapply) {
/* We only set rp_filter once (except reapply). */
return;
}
/* No matter whether we actually reset the value below, we set the "handled" flag
* so that we only do this once (except during reapply). */
self->priv.p->rp_filter_handled = TRUE;
ifname = nm_l3cfg_get_ifname(self, TRUE);
rf_val =
nm_platform_sysctl_ip_conf_get_rp_filter_ipv4(self->priv.platform, ifname, FALSE, NULL);
if (rf_val != 1) {
/* We only relax from strict (1) to loose (2). No other transition. Nothing to do. */
return;
}
/* We actually loosen the flag. We need to remember to reset it. */
self->priv.p->rp_filter_set = TRUE;
nm_platform_sysctl_ip_conf_set(self->priv.platform, AF_INET, ifname, "rp_filter", "2");
}
/*****************************************************************************/
static gboolean
_global_tracker_mptcp_untrack(NML3Cfg *self, int addr_family)
{
return nmp_global_tracker_untrack_all(self->priv.global_tracker,
_MPTCP_TAG(self, NM_IS_IPv4(addr_family)),
FALSE,
TRUE);
}
static gboolean
_l3_commit_mptcp_af(NML3Cfg *self,
NML3CfgCommitType commit_type,
int addr_family,
gboolean *out_reapply)
{
const int IS_IPv4 = NM_IS_IPv4(addr_family);
NMMptcpFlags mptcp_flags;
gboolean reapply = FALSE;
gboolean changed = FALSE;
nm_assert(NM_IS_L3CFG(self));
nm_assert(NM_IN_SET(commit_type,
NM_L3_CFG_COMMIT_TYPE_NONE,
NM_L3_CFG_COMMIT_TYPE_REAPPLY,
NM_L3_CFG_COMMIT_TYPE_UPDATE));
if (commit_type >= NM_L3_CFG_COMMIT_TYPE_REAPPLY)
reapply = TRUE;
if (commit_type != NM_L3_CFG_COMMIT_TYPE_NONE && self->priv.p->combined_l3cd_commited)
mptcp_flags = nm_l3_config_data_get_mptcp_flags(self->priv.p->combined_l3cd_commited);
else
mptcp_flags = NM_MPTCP_FLAGS_DISABLED;
if (mptcp_flags == NM_MPTCP_FLAGS_NONE || NM_FLAGS_HAS(mptcp_flags, NM_MPTCP_FLAGS_DISABLED))
mptcp_flags = NM_MPTCP_FLAGS_DISABLED;
else if (NM_FLAGS_HAS(mptcp_flags, NM_MPTCP_FLAGS_ENABLED_ON_GLOBAL_IFACE)) {
/* Whether MPTCP is enabled/disabled, depends on whether we have a unicast default
* route (in the main routing table). */
if (self->priv.p->combined_l3cd_commited
&& nm_l3_config_data_get_best_default_route(self->priv.p->combined_l3cd_commited,
addr_family))
mptcp_flags = NM_FLAGS_UNSET(mptcp_flags, NM_MPTCP_FLAGS_ENABLED_ON_GLOBAL_IFACE)
| NM_MPTCP_FLAGS_ENABLED;
else
mptcp_flags = NM_MPTCP_FLAGS_DISABLED;
} else
mptcp_flags |= NM_MPTCP_FLAGS_ENABLED;
if (NM_FLAGS_HAS(mptcp_flags, NM_MPTCP_FLAGS_DISABLED)) {
if (!self->priv.p->mptcp_set_x[IS_IPv4] && !reapply) {
/* Nothing to configure, and we did not earlier configure MPTCP. Nothing to do. */
NM_SET_OUT(out_reapply, FALSE);
return FALSE;
}
self->priv.p->mptcp_set_x[IS_IPv4] = FALSE;
reapply = TRUE;
} else {
const NMPlatformIPXAddress *addr;
NMDedupMultiIter iter;
const guint32 FLAGS =
(NM_FLAGS_HAS(mptcp_flags, NM_MPTCP_FLAGS_SIGNAL) ? MPTCP_PM_ADDR_FLAG_SIGNAL : 0)
| (NM_FLAGS_HAS(mptcp_flags, NM_MPTCP_FLAGS_SUBFLOW) ? MPTCP_PM_ADDR_FLAG_SUBFLOW : 0)
| (NM_FLAGS_HAS(mptcp_flags, NM_MPTCP_FLAGS_BACKUP) ? MPTCP_PM_ADDR_FLAG_BACKUP : 0)
| (NM_FLAGS_HAS(mptcp_flags, NM_MPTCP_FLAGS_FULLMESH) ? MPTCP_PM_ADDR_FLAG_FULLMESH
: 0);
NMPlatformMptcpAddr a = {
.ifindex = self->priv.ifindex,
.id = 0,
.flags = FLAGS,
.addr_family = addr_family,
.port = 0,
};
gboolean any_tracked = FALSE;
self->priv.p->mptcp_set_x[IS_IPv4] = TRUE;
if (self->priv.p->combined_l3cd_commited) {
gint32 addr_prio;
addr_prio = 100;
nm_l3_config_data_iter_ip_address_for_each (&iter,
self->priv.p->combined_l3cd_commited,
addr_family,
(const NMPlatformIPAddress **) &addr) {
/* We want to evaluate the with-{loopback,link_local}-{4,6} flags based on the actual
* ifa_scope that the address will have once we configure it.
* "addr" is an address we want to configure, we expect that it will
* later have the scope nm_platform_ip_address_get_scope() based on
* the address. */
switch (nm_platform_ip_address_get_scope(addr_family, addr->ax.address_ptr)) {
case RT_SCOPE_HOST:
if (!NM_FLAGS_ANY(mptcp_flags,
IS_IPv4 ? NM_MPTCP_FLAGS_WITH_LOOPBACK_4
: NM_MPTCP_FLAGS_WITH_LOOPBACK_6))
goto skip_addr;
break;
case RT_SCOPE_LINK:
if (!NM_FLAGS_ANY(mptcp_flags,
IS_IPv4 ? NM_MPTCP_FLAGS_WITH_LINK_LOCAL_4
: NM_MPTCP_FLAGS_WITH_LINK_LOCAL_6))
goto skip_addr;
break;
default:
if (IS_IPv4) {
if (nm_utils_ip_is_site_local(AF_INET, &addr->a4.address)) {
/* By default we take rfc1918 private addresses, unless there
* is a flag to opt-out. */
if (NM_FLAGS_HAS(mptcp_flags, NM_MPTCP_FLAGS_SKIP_SITE_LOCAL_4))
goto skip_addr;
} else {
/* other addresses we take. */
}
} else {
if (nm_utils_ip6_is_ula(&addr->a6.address)) {
/* Special treatment for unique local IPv6 addresses fc00::/7. */
if (!NM_FLAGS_HAS(mptcp_flags, NM_MPTCP_FLAGS_WITH_SITE_LOCAL_6))
goto skip_addr;
} else {
/* We take all other addresses, including deprecated IN6_IS_ADDR_SITELOCAL()
* (fec0::/10). */
}
}
break;
}
a.addr = nm_ip_addr_init(addr_family, addr->ax.address_ptr);
/* We track the address with different priorities, that depends
* on the order in which they are listed here. NMPGlobalTracker
* will sort all tracked addresses by priority. That means, if we
* have multiple interfaces then we will prefer the first address
* of those interfaces, then the second, etc.
*
* That is relevant, because the overall number of addresses we
* can configure in kernel is strongly limited (MPTCP_PM_ADDR_MAX). */
if (addr_prio > 10)
addr_prio--;
if (nmp_global_tracker_track(self->priv.global_tracker,
NMP_OBJECT_TYPE_MPTCP_ADDR,
&a,
addr_prio,
_MPTCP_TAG(self, IS_IPv4),
NULL))
changed = TRUE;
any_tracked = TRUE;
skip_addr:
(void) 0;
}
}
if (!any_tracked) {
/* We need to make it known that this ifindex is used. Track a dummy object. */
if (nmp_global_tracker_track(
self->priv.global_tracker,
NMP_OBJECT_TYPE_MPTCP_ADDR,
nmp_global_tracker_mptcp_addr_init_for_ifindex(&a, self->priv.ifindex),
1,
_MPTCP_TAG(self, IS_IPv4),
NULL))
changed = TRUE;
}
}
if (_global_tracker_mptcp_untrack(self, addr_family))
changed = TRUE;
NM_SET_OUT(out_reapply, reapply);
return changed || reapply;
}
static void
_l3_commit_mptcp(NML3Cfg *self, NML3CfgCommitType commit_type)
{
gboolean changed = FALSE;
gboolean reapply = FALSE;
gboolean i_reapply = FALSE;
if (_l3_commit_mptcp_af(self, commit_type, AF_INET, &i_reapply))
changed = TRUE;
reapply |= i_reapply;
if (_l3_commit_mptcp_af(self, commit_type, AF_INET6, &i_reapply))
changed = TRUE;
reapply |= i_reapply;
nm_assert(commit_type < NM_L3_CFG_COMMIT_TYPE_REAPPLY || reapply);
if (changed)
nmp_global_tracker_sync_mptcp_addrs(self->priv.global_tracker, reapply, FALSE);
else
nm_assert(!reapply);
_rp_filter_update(self, reapply);
}
static gboolean
_l3_commit_one(NML3Cfg *self,
int addr_family,
@ -4382,6 +4672,8 @@ _l3_commit(NML3Cfg *self, NML3CfgCommitType commit_type, gboolean is_idle)
_l3_commit_one(self, AF_INET, commit_type, changed_combined_l3cd, l3cd_old);
_l3_commit_one(self, AF_INET6, commit_type, changed_combined_l3cd, l3cd_old);
_l3_commit_mptcp(self, commit_type);
_l3_acd_data_process_changes(self);
if (self->priv.p->l3_config_datas) {
@ -4790,6 +5082,7 @@ static void
finalize(GObject *object)
{
NML3Cfg *self = NM_L3CFG(object);
gboolean changed;
nm_assert(!self->priv.p->ipconfig_4);
nm_assert(!self->priv.p->ipconfig_6);
@ -4827,6 +5120,14 @@ finalize(GObject *object)
if (_nodev_routes_untrack(self, AF_INET6))
nmp_global_tracker_sync(self->priv.global_tracker, NMP_OBJECT_TYPE_IP6_ROUTE, FALSE);
changed = FALSE;
if (_global_tracker_mptcp_untrack(self, AF_INET))
changed = TRUE;
if (_global_tracker_mptcp_untrack(self, AF_INET6))
changed = TRUE;
if (changed)
nmp_global_tracker_sync_mptcp_addrs(self->priv.global_tracker, FALSE, FALSE);
g_clear_object(&self->priv.netns);
g_clear_object(&self->priv.platform);
nm_clear_pointer(&self->priv.global_tracker, nmp_global_tracker_unref);

View file

@ -645,6 +645,11 @@ make_connection_setting(const char *file,
PARSE_WARNING("invalid DNS_OVER_TLS setting");
g_object_set(s_con, NM_SETTING_CONNECTION_DNS_OVER_TLS, i_val, NULL);
i_val = NM_MPTCP_FLAGS_NONE;
if (!svGetValueEnum(ifcfg, "MPTCP_FLAGS", nm_mptcp_flags_get_type(), &i_val, NULL))
PARSE_WARNING("invalid MPTCP_FLAGS setting");
g_object_set(s_con, NM_SETTING_CONNECTION_MPTCP_FLAGS, (guint) i_val, NULL);
vint32 = svGetValueInt64(ifcfg, "WAIT_ACTIVATION_DELAY", 10, -1, G_MAXINT32, -1);
g_object_set(s_con, NM_SETTING_CONNECTION_WAIT_ACTIVATION_DELAY, (int) vint32, NULL);

View file

@ -1006,6 +1006,7 @@ const NMSIfcfgKeyTypeInfo nms_ifcfg_well_known_keys[] = {
_KEY_TYPE("MDNS", NMS_IFCFG_KEY_TYPE_IS_PLAIN),
_KEY_TYPE("METRIC", NMS_IFCFG_KEY_TYPE_IS_NUMBERED),
_KEY_TYPE("MODE", NMS_IFCFG_KEY_TYPE_IS_PLAIN),
_KEY_TYPE("MPTCP_FLAGS", NMS_IFCFG_KEY_TYPE_IS_PLAIN),
_KEY_TYPE("MTU", NMS_IFCFG_KEY_TYPE_IS_PLAIN),
_KEY_TYPE("MUD_URL", NMS_IFCFG_KEY_TYPE_IS_PLAIN),
_KEY_TYPE("MULTI_CONNECT", NMS_IFCFG_KEY_TYPE_IS_PLAIN),

View file

@ -33,7 +33,7 @@ typedef struct {
NMSIfcfgKeyTypeFlags key_flags;
} NMSIfcfgKeyTypeInfo;
extern const NMSIfcfgKeyTypeInfo nms_ifcfg_well_known_keys[255];
extern const NMSIfcfgKeyTypeInfo nms_ifcfg_well_known_keys[256];
const NMSIfcfgKeyTypeInfo *nms_ifcfg_well_known_key_find_info(const char *key, gssize *out_idx);

View file

@ -2095,6 +2095,7 @@ write_connection_setting(NMSettingConnection *s_con, shvarFile *ifcfg)
NMSettingConnectionMdns mdns;
NMSettingConnectionLlmnr llmnr;
NMSettingConnectionDnsOverTls dns_over_tls;
NMMptcpFlags mptcp_flags;
guint32 vuint32;
const char *tmp, *mud_url;
@ -2289,6 +2290,10 @@ write_connection_setting(NMSettingConnection *s_con, shvarFile *ifcfg)
nm_setting_connection_dns_over_tls_get_type(),
dns_over_tls);
}
mptcp_flags = nm_setting_connection_get_mptcp_flags(s_con);
if (mptcp_flags != NM_MPTCP_FLAGS_NONE)
svSetValueEnum(ifcfg, "MPTCP_FLAGS", nm_mptcp_flags_get_type(), mptcp_flags);
}
static char *

View file

@ -1839,6 +1839,7 @@ global:
libnm_1_40_0 {
global:
nm_conn_wireguard_import;
nm_mptcp_flags_get_type;
nm_setting_connection_get_wait_activation_delay;
nm_setting_ip4_link_local_get_type;
nm_setting_ip6_config_get_mtu;

View file

@ -493,3 +493,36 @@ _nm_connection_new_setting(NMConnection *connection, GType gtype)
nm_connection_add_setting(connection, setting);
return setting;
}
/*****************************************************************************/
NMMptcpFlags
nm_mptcp_flags_normalize(NMMptcpFlags flags)
{
/* Certain combinations of flags are incompatible. Normalize them.
*
* This function never returns 0x0 (NONE). If the flags are neither
* disabled,enabled-on-global-iface,enabled, then we default to "enabled". */
if (NM_FLAGS_HAS(flags, NM_MPTCP_FLAGS_DISABLED)) {
/* If the disabled flag is set, then that's the end of it. */
return NM_MPTCP_FLAGS_DISABLED;
}
/* Clear all unknown flags. */
flags &= _NM_MPTCP_FLAGS_ALL;
/* We must either set "enabled-on-global-iface" or "enabled". The
* former takes precedence, if they are both set.
*
* If neither is set, we default to "enabled". */
if (NM_FLAGS_HAS(flags, NM_MPTCP_FLAGS_ENABLED_ON_GLOBAL_IFACE))
flags = NM_FLAGS_UNSET(flags, NM_MPTCP_FLAGS_ENABLED);
else
flags = NM_FLAGS_SET(flags, NM_MPTCP_FLAGS_ENABLED);
if (NM_FLAGS_ALL(flags, NM_MPTCP_FLAGS_SIGNAL | NM_MPTCP_FLAGS_FULLMESH))
flags = NM_FLAGS_UNSET(flags, NM_MPTCP_FLAGS_FULLMESH);
return flags;
}

View file

@ -267,4 +267,20 @@ gboolean nm_settings_connection_validate_permission_user(const char *item, gssiz
gpointer _nm_connection_ensure_setting(NMConnection *connection, GType gtype);
gpointer _nm_connection_new_setting(NMConnection *connection, GType gtype);
/*****************************************************************************/
#define _NM_MPTCP_FLAGS_ALL \
((NMMptcpFlags) (NM_MPTCP_FLAGS_DISABLED | NM_MPTCP_FLAGS_ENABLED_ON_GLOBAL_IFACE \
| NM_MPTCP_FLAGS_ENABLED | NM_MPTCP_FLAGS_SIGNAL | NM_MPTCP_FLAGS_SUBFLOW \
| NM_MPTCP_FLAGS_BACKUP | NM_MPTCP_FLAGS_FULLMESH \
| NM_MPTCP_FLAGS_WITH_LOOPBACK_4 | NM_MPTCP_FLAGS_WITH_LINK_LOCAL_4 \
| NM_MPTCP_FLAGS_SKIP_SITE_LOCAL_4 | NM_MPTCP_FLAGS_WITH_LOOPBACK_6 \
| NM_MPTCP_FLAGS_WITH_LINK_LOCAL_6 | NM_MPTCP_FLAGS_WITH_SITE_LOCAL_6 \
| NM_MPTCP_FLAGS_NO_RELAX_RP_FILTER))
#define _NM_MPTCP_FLAGS_DEFAULT \
((NMMptcpFlags) (NM_MPTCP_FLAGS_ENABLED_ON_GLOBAL_IFACE | NM_MPTCP_FLAGS_SUBFLOW))
NMMptcpFlags nm_mptcp_flags_normalize(NMMptcpFlags flags);
#endif /* __NM_LIBNM_SHARED_UTILS_H__ */

View file

@ -65,6 +65,7 @@ NM_GOBJECT_PROPERTIES_DEFINE(NMSettingConnection,
PROP_MDNS,
PROP_LLMNR,
PROP_DNS_OVER_TLS,
PROP_MPTCP_FLAGS,
PROP_STABLE_ID,
PROP_AUTH_RETRIES,
PROP_WAIT_DEVICE_TIMEOUT,
@ -96,6 +97,7 @@ typedef struct {
gint32 wait_device_timeout;
gint32 lldp;
gint32 wait_activation_delay;
guint32 mptcp_flags;
guint32 gateway_ping_timeout;
bool autoconnect;
bool read_only;
@ -1015,6 +1017,22 @@ nm_setting_connection_get_dns_over_tls(NMSettingConnection *setting)
return NM_SETTING_CONNECTION_GET_PRIVATE(setting)->dns_over_tls;
}
/**
* nm_setting_connection_get_mptcp_flags:
* @setting: the #NMSettingConnection
*
* Returns: the #NMSettingConnection:mptcp-flags property of the setting.
*
* Since: 1.40
**/
NMMptcpFlags
nm_setting_connection_get_mptcp_flags(NMSettingConnection *setting)
{
g_return_val_if_fail(NM_IS_SETTING_CONNECTION(setting), NM_MPTCP_FLAGS_NONE);
return NM_SETTING_CONNECTION_GET_PRIVATE(setting)->mptcp_flags;
}
static void
_set_error_missing_base_setting(GError **error, const char *type)
{
@ -1367,6 +1385,64 @@ after_interface_name:
return FALSE;
}
if (priv->mptcp_flags != 0) {
if (NM_FLAGS_HAS(priv->mptcp_flags, NM_MPTCP_FLAGS_DISABLED)) {
if (priv->mptcp_flags != NM_MPTCP_FLAGS_DISABLED) {
g_set_error_literal(
error,
NM_CONNECTION_ERROR,
NM_CONNECTION_ERROR_INVALID_PROPERTY,
_("\"disabled\" flag cannot be combined with other MPTCP flags"));
g_prefix_error(error,
"%s.%s: ",
NM_SETTING_CONNECTION_SETTING_NAME,
NM_SETTING_CONNECTION_MPTCP_FLAGS);
return FALSE;
}
} else {
guint32 f;
if (NM_FLAGS_ALL(priv->mptcp_flags,
NM_MPTCP_FLAGS_ENABLED_ON_GLOBAL_IFACE | NM_MPTCP_FLAGS_ENABLED)) {
g_set_error_literal(
error,
NM_CONNECTION_ERROR,
NM_CONNECTION_ERROR_INVALID_PROPERTY,
_("\"enabled\" and \"enabled-on-global-iface\" flag cannot be set together"));
g_prefix_error(error,
"%s.%s: ",
NM_SETTING_CONNECTION_SETTING_NAME,
NM_SETTING_CONNECTION_MPTCP_FLAGS);
return FALSE;
}
if (NM_FLAGS_ALL(priv->mptcp_flags, NM_MPTCP_FLAGS_SIGNAL | NM_MPTCP_FLAGS_FULLMESH)) {
g_set_error_literal(error,
NM_CONNECTION_ERROR,
NM_CONNECTION_ERROR_INVALID_PROPERTY,
_("cannot set both \"signal\" and \"fullmesh\" MPTCP flags"));
g_prefix_error(error,
"%s.%s: ",
NM_SETTING_CONNECTION_SETTING_NAME,
NM_SETTING_CONNECTION_MPTCP_FLAGS);
return FALSE;
}
f = NM_FLAGS_UNSET(priv->mptcp_flags, NM_MPTCP_FLAGS_ENABLED_ON_GLOBAL_IFACE)
| ((guint32) NM_MPTCP_FLAGS_ENABLED);
if (f != nm_mptcp_flags_normalize(f)) {
g_set_error(error,
NM_CONNECTION_ERROR,
NM_CONNECTION_ERROR_INVALID_PROPERTY,
_("value %u is not a valid combination of MPTCP flags"),
priv->mptcp_flags);
g_prefix_error(error,
"%s.%s: ",
NM_SETTING_CONNECTION_SETTING_NAME,
NM_SETTING_CONNECTION_MPTCP_FLAGS);
return FALSE;
}
}
}
if (!NM_IN_SET(priv->multi_connect,
(int) NM_CONNECTION_MULTI_CONNECT_DEFAULT,
(int) NM_CONNECTION_MULTI_CONNECT_SINGLE,
@ -2483,6 +2559,115 @@ nm_setting_connection_class_init(NMSettingConnectionClass *klass)
NMSettingConnectionPrivate,
dns_over_tls);
/* Notes about "mptcp-flags":
*
* It is a bit odd that NMMptcpFlags mixes flags with different purposes:
*
* - "disabled", "disabled-on-local-iface", "enable": whether MPTCP handling
* is enabled. The flag "disabled-on-local-iface" enables it based on whether
* the interface has a default route.
* - "signal", "subflow", "backup", "fullmesh": the endpoint flags
* that are used.
* - "with-loopback-4", "with-*", ..., "skip-site-local-4": to include/exclude addresses,
* which should be configured as endpoints.
* - "no-relax-rp-filter": controls whether to (not) change rp_filter.
*
* The reason is, that it is useful to have one "connection.mptcp-flags"
* property, that can express various aspects at once. The alternatives
* would be multiple properties like "connection.mptcp-enabled",
* "connection.mptcp-addr-flags" and "connection.mptcp-notify-flags".
* More properties does not necessarily make the API simpler. In particular
* for something like MPTCP, which should just work by default and only
* in special cases require special configuration.
*
* The entire idea is to only have one "connection.mptcp-flags" property (for now).
* That one can encode multiple aspects about MPTCP, whether it's enabled at all,
* which address flags to use when configuring endpoints, and opt-in addresses
* that otherwise would not be configured as endpoints.
*
* "connection.mptcp-flags" applies to all addresses on the interface (minus the ones
* that are not included via "with-*" and "skip-*" flags). The idea is that in the future we could have
* more properties like "ipv4.dhcp-mptcp-flags=subflow", "ipv6.link-local-mptcp-flags=disabled",
* "ipv4.addresses='192.168.1.5/24 mptcp-flags=signal,backup'", which can overwrite the
* flags on a per-address basis.
*
* But for that future extension, we now need a global "connection.mptcp-flags" property
* in the API that is the basis and applies to all addresses.
*/
/**
* NMSettingConnection:mptcp-flags:
*
* Whether to configure MPTCP endpoints and the address flags.
* If MPTCP is enabled in NetworkManager, it will configure the
* addresses of the interface as MPTCP endpoints. The supported
* flags are as follows.
*
* If "disabled" (0x1), MPTCP handling for the interface is disabled and
* no endpoints are registered.
*
* The flag "enabled-on-global-iface" (0x2) means that MPTCP handling is enabled
* if the interface configures a default route in the main routing table.
* This choice is per-address family, for example if there is an IPv4 default route
* 0.0.0.0/0, IPv4 endpoints are configured.
*
* The "enabled" (0x4) flag means that MPTCP handling is explicitly enabled.
* This flag can also be implied from the presence of other flags.
*
* If MPTCP handling is enabled, then endpoints will be configured
* with the specified address flags "signal" (0x10), "subflow" (0x20), "backup" (0x40),
* "fullmesh" (0x80). See ip-mptcp(8) manual for additional information about the flags.
*
* The flag "with-loopback-4" (0x100) indicates that NetworkManager will
* also configure MPTCP endpoints for IPv4 loopback addresses 127.0.0.0/8.
* Likewise, the flag "with-link-local-4" (0x200) includes IPv4 link local
* addresses 169.254.0.0/16.
*
* The "skip-site-local-4" (0x400) flag indicates to exclude rfc1918 private addresses
* (10.0.0.0/8, 172.16.0.0/12, 192.168.0.0/16).
*
* The flags "with-loopback-6" (0x1000), "with-link-local-6" (0x2000)
* and "with-site-local-6" (0x4000) apply to the IPv6 loopback address (::1),
* IPv6 link local addresses (fe80::/10) and IPv6 unique local addresses (ULA, fc00::/7),
* respectively. IPv6 privacy addresses (rfc3041, ipv6.ip6-privacy) are excluded
* from MPTCP configuration.
*
* The flag "no-relax-rp-filter" (0x10000) causes NetworkManager to not touch
* IPv4 rp_filter. Strict reverse path filtering (rp_filter) breaks many MPTCP
* use cases, so when MPTCP handling on the interface is enabled, NetworkManager would
* loosen the strict reverse path filtering (1) to the loose setting (2).
* This flag prevents that.
*
* If the flags are zero, the global connection default from NetworkManager.conf is
* honored. If still unspecified, the fallback is either "disabled" or
* "enabled-on-global-iface,subflow" depending on "/proc/sys/net/mptcp/enabled".
*
* NetworkManager does not change the MPTCP limits nor enable MPTCP via
* "/proc/sys/net/mptcp/enabled". That is a host configuration which the
* admin can change via sysctl and ip-mptcp.
*
* Since: 1.40
**/
/* ---ifcfg-rh---
* property: mptcp-flags
* variable: MPTCP_FLAGS(+)
* default: missing variable means global default
* description: The MPTCP flags that indicate whether MPTCP is enabled
* and which flags to use for the address endpoints.
* example: MPTCP_FLAGS="signal,subflow"
* ---end---
*/
_nm_setting_property_define_direct_uint32(properties_override,
obj_properties,
NM_SETTING_CONNECTION_MPTCP_FLAGS,
PROP_MPTCP_FLAGS,
0,
G_MAXUINT32,
NM_MPTCP_FLAGS_NONE,
NM_SETTING_PARAM_NONE,
NMSettingConnectionPrivate,
mptcp_flags);
/**
* NMSettingConnection:wait-device-timeout:
*

View file

@ -3954,6 +3954,7 @@ test_connection_diff_a_only(void)
{NM_SETTING_CONNECTION_MDNS, NM_SETTING_DIFF_RESULT_IN_A},
{NM_SETTING_CONNECTION_LLMNR, NM_SETTING_DIFF_RESULT_IN_A},
{NM_SETTING_CONNECTION_DNS_OVER_TLS, NM_SETTING_DIFF_RESULT_IN_A},
{NM_SETTING_CONNECTION_MPTCP_FLAGS, NM_SETTING_DIFF_RESULT_IN_A},
{NM_SETTING_CONNECTION_MUD_URL, NM_SETTING_DIFF_RESULT_IN_A},
{NM_SETTING_CONNECTION_WAIT_DEVICE_TIMEOUT, NM_SETTING_DIFF_RESULT_IN_A},
{NM_SETTING_CONNECTION_WAIT_ACTIVATION_DELAY, NM_SETTING_DIFF_RESULT_IN_A},

View file

@ -1315,4 +1315,66 @@ typedef enum /*< flags >*/ {
NM_RADIO_FLAG_WWAN_AVAILABLE = 0x2,
} NMRadioFlags;
/**
* NMMptcpFlags:
* @NM_MPTCP_FLAGS_NONE: The default, meaning that no MPTCP flags are set.
* @NM_MPTCP_FLAGS_DISABLED: don't configure MPTCP endpoints on the device.
* @NM_MPTCP_FLAGS_ENABLED_ON_GLOBAL_IFACE: MPTCP handling is enabled
* or disabled depending on whether a /0 default route (either IPv4 or IPv6) is
* configured in the main routing table.
* @NM_MPTCP_FLAGS_ENABLED: MPTCP is enabled and endpoints will be configured.
* This flag is implied if any of the other flags indicate that
* MPTCP is enabled and therefore in most cases unnecessary.
* @NM_MPTCP_FLAGS_SIGNAL: Flag for the MPTCP endpoint. The endpoint will be
* announced/signaled to each peer via an MPTCP ADD_ADDR sub-option.
* @NM_MPTCP_FLAGS_SUBFLOW: Flag for the MPTCP endpoint. If additional subflow creation
* is allowed by the MPTCP limits, the MPTCP path manager will try to create an
* additional subflow using this endpoint as the source address after the MPTCP connection
* is established.
* @NM_MPTCP_FLAGS_BACKUP: Flag for the MPTCP endpoint. If this is a subflow endpoint, the
* subflows created using this endpoint will have the backup flag set during the connection
* process. This flag instructs the peer to only send data on a given subflow when all
* non-backup subflows are unavailable. This does not affect outgoing data,
* where subflow priority is determined by the backup/non-backup flag received
* from the peer
* @NM_MPTCP_FLAGS_FULLMESH: Flag for the MPTCP endpoint. If this is a subflow endpoint and additional
* subflow creation is allowed by the MPTCP limits, the MPTCP path manager will try to create an
* additional subflow for each known peer address, using this endpoint as the source address.
* This will occur after the MPTCP connection is established. If the peer did not announce
* any additional addresses using the MPTCP ADD_ADDR sub-option, this will behave the same
* as a plain subflow endpoint. When the peer does announce addresses, each received ADD_ADDR
* sub-option will trigger creation of an additional subflow to generate a full mesh topology.
* @NM_MPTCP_FLAGS_WITH_LOOPBACK_4: Also configure MPTCP endpoints for IPv4 addresses 127.0.0.0/8 with scope "host".
* @NM_MPTCP_FLAGS_WITH_LOOPBACK_6: Also configure MPTCP endpoints for the IPv6 address ::1 with scope "host".
* @NM_MPTCP_FLAGS_WITH_LINK_LOCAL_4: Also configure MPTCP endpoints for IPv4 addresses 169.254.0.0/16 with scope "link".
* @NM_MPTCP_FLAGS_WITH_LINK_LOCAL_6: Also configure MPTCP endpoints for IPv6 addresses fe80::/10 with scope "link".
* @NM_MPTCP_FLAGS_SKIP_SITE_LOCAL_4: Don't configure MPTCP endpoints for site local IPv4 addresses (RFC1918, 10.0.0.0/8, 172.16.0.0/12, 192.168.0.0/16).
* @NM_MPTCP_FLAGS_WITH_SITE_LOCAL_6: Also configure MPTCP endpoints for unique local IPv6 addresses (ULA, fc00::/7).
* @NM_MPTCP_FLAGS_NO_RELAX_RP_FILTER: When configure MPTCP on an interface, NetworkManager will
* loosen a strict rp_filter source validation. This flag prevents changing rp_filter.
*
* Since: 1.40
*/
typedef enum /*< flags >*/ {
NM_MPTCP_FLAGS_NONE = 0,
NM_MPTCP_FLAGS_DISABLED = 0x1,
NM_MPTCP_FLAGS_ENABLED_ON_GLOBAL_IFACE = 0x2,
NM_MPTCP_FLAGS_ENABLED = 0x4,
NM_MPTCP_FLAGS_SIGNAL = 0x10,
NM_MPTCP_FLAGS_SUBFLOW = 0x20,
NM_MPTCP_FLAGS_BACKUP = 0x40,
NM_MPTCP_FLAGS_FULLMESH = 0x80,
NM_MPTCP_FLAGS_WITH_LOOPBACK_4 = 0x0100,
NM_MPTCP_FLAGS_WITH_LINK_LOCAL_4 = 0x0200,
NM_MPTCP_FLAGS_SKIP_SITE_LOCAL_4 = 0x0400,
NM_MPTCP_FLAGS_WITH_LOOPBACK_6 = 0x1000,
NM_MPTCP_FLAGS_WITH_LINK_LOCAL_6 = 0x2000,
NM_MPTCP_FLAGS_WITH_SITE_LOCAL_6 = 0x4000,
NM_MPTCP_FLAGS_NO_RELAX_RP_FILTER = 0x10000,
} NMMptcpFlags;
#endif /* __NM_DBUS_INTERFACE_H__ */

View file

@ -57,6 +57,7 @@ G_BEGIN_DECLS
#define NM_SETTING_CONNECTION_MDNS "mdns"
#define NM_SETTING_CONNECTION_LLMNR "llmnr"
#define NM_SETTING_CONNECTION_DNS_OVER_TLS "dns-over-tls"
#define NM_SETTING_CONNECTION_MPTCP_FLAGS "mptcp-flags"
#define NM_SETTING_CONNECTION_WAIT_DEVICE_TIMEOUT "wait-device-timeout"
#define NM_SETTING_CONNECTION_MUD_URL "mud-url"
#define NM_SETTING_CONNECTION_WAIT_ACTIVATION_DELAY "wait-activation-delay"
@ -216,6 +217,9 @@ NMSettingConnectionLlmnr nm_setting_connection_get_llmnr(NMSettingConnection *se
NM_AVAILABLE_IN_1_34
NMSettingConnectionDnsOverTls nm_setting_connection_get_dns_over_tls(NMSettingConnection *setting);
NM_AVAILABLE_IN_1_40
NMMptcpFlags nm_setting_connection_get_mptcp_flags(NMSettingConnection *setting);
NM_AVAILABLE_IN_1_20
gint32 nm_setting_connection_get_wait_device_timeout(NMSettingConnection *setting);

View file

@ -5578,6 +5578,21 @@ static const NMMetaPropertyInfo *const property_infos_CONNECTION[] = {
),
),
),
PROPERTY_INFO_WITH_DESC (NM_SETTING_CONNECTION_MPTCP_FLAGS,
.property_type = &_pt_gobject_enum,
.property_typ_data = DEFINE_PROPERTY_TYP_DATA (
PROPERTY_TYP_DATA_SUBTYPE (gobject_enum,
.get_gtype = nm_mptcp_flags_get_type,
.value_infos_get = GOBJECT_ENUM_VALUE_INFOS_GET_FROM_SETTER,
.value_infos = ENUM_VALUE_INFOS (
{
.value = NM_MPTCP_FLAGS_NONE,
.nick = "default",
},
),
),
),
),
PROPERTY_INFO_WITH_DESC (NM_SETTING_CONNECTION_MUD_URL,
.property_type = &_pt_gobject_string,
.hide_if_default = TRUE,

View file

@ -14,6 +14,7 @@
#define DESCRIBE_DOC_NM_SETTING_CONNECTION_MASTER N_("Interface name of the master device or UUID of the master connection.")
#define DESCRIBE_DOC_NM_SETTING_CONNECTION_MDNS N_("Whether mDNS is enabled for the connection. The permitted values are: \"yes\" (2) register hostname and resolving for the connection, \"no\" (0) disable mDNS for the interface, \"resolve\" (1) do not register hostname but allow resolving of mDNS host names and \"default\" (-1) to allow lookup of a global default in NetworkManager.conf. If unspecified, \"default\" ultimately depends on the DNS plugin (which for systemd-resolved currently means \"no\"). This feature requires a plugin which supports mDNS. Otherwise, the setting has no effect. One such plugin is dns-systemd-resolved.")
#define DESCRIBE_DOC_NM_SETTING_CONNECTION_METERED N_("Whether the connection is metered. When updating this property on a currently activated connection, the change takes effect immediately.")
#define DESCRIBE_DOC_NM_SETTING_CONNECTION_MPTCP_FLAGS N_("Whether to configure MPTCP endpoints and the address flags. If MPTCP is enabled in NetworkManager, it will configure the addresses of the interface as MPTCP endpoints. The supported flags are as follows. If \"disabled\" (0x1), MPTCP handling for the interface is disabled and no endpoints are registered. The flag \"enabled-on-global-iface\" (0x2) means that MPTCP handling is enabled if the interface configures a default route in the main routing table. This choice is per-address family, for example if there is an IPv4 default route 0.0.0.0/0, IPv4 endpoints are configured. The \"enabled\" (0x4) flag means that MPTCP handling is explicitly enabled. This flag can also be implied from the presence of other flags. If MPTCP handling is enabled, then endpoints will be configured with the specified address flags \"signal\" (0x10), \"subflow\" (0x20), \"backup\" (0x40), \"fullmesh\" (0x80). See ip-mptcp(8) manual for additional information about the flags. The flag \"with-loopback-4\" (0x100) indicates that NetworkManager will also configure MPTCP endpoints for IPv4 loopback addresses 127.0.0.0/8. Likewise, the flag \"with-link-local-4\" (0x200) includes IPv4 link local addresses 169.254.0.0/16. The \"skip-site-local-4\" (0x400) flag indicates to exclude rfc1918 private addresses (10.0.0.0/8, 172.16.0.0/12, 192.168.0.0/16). The flags \"with-loopback-6\" (0x1000), \"with-link-local-6\" (0x2000) and \"with-site-local-6\" (0x4000) apply to the IPv6 loopback address (::1), IPv6 link local addresses (fe80::/10) and IPv6 unique local addresses (ULA, fc00::/7), respectively. IPv6 privacy addresses (rfc3041, ipv6.ip6-privacy) are excluded from MPTCP configuration. The flag \"no-relax-rp-filter\" (0x10000) causes NetworkManager to not touch IPv4 rp_filter. Strict reverse path filtering (rp_filter) breaks many MPTCP use cases, so when MPTCP handling on the interface is enabled, NetworkManager would loosen the strict reverse path filtering (1) to the loose setting (2). This flag prevents that. If the flags are zero, the global connection default from NetworkManager.conf is honored. If still unspecified, the fallback is either \"disabled\" or \"enabled-on-global-iface,subflow\" depending on \"/proc/sys/net/mptcp/enabled\". NetworkManager does not change the MPTCP limits nor enable MPTCP via \"/proc/sys/net/mptcp/enabled\". That is a host configuration which the admin can change via sysctl and ip-mptcp.")
#define DESCRIBE_DOC_NM_SETTING_CONNECTION_MUD_URL N_("If configured, set to a Manufacturer Usage Description (MUD) URL that points to manufacturer-recommended network policies for IoT devices. It is transmitted as a DHCPv4 or DHCPv6 option. The value must be a valid URL starting with \"https://\". The special value \"none\" is allowed to indicate that no MUD URL is used. If the per-profile value is unspecified (the default), a global connection default gets consulted. If still unspecified, the ultimate default is \"none\".")
#define DESCRIBE_DOC_NM_SETTING_CONNECTION_MULTI_CONNECT N_("Specifies whether the profile can be active multiple times at a particular moment. The value is of type NMConnectionMultiConnect.")
#define DESCRIBE_DOC_NM_SETTING_CONNECTION_PERMISSIONS N_("An array of strings defining what access a given user has to this connection. If this is NULL or empty, all users are allowed to access this connection; otherwise users are allowed if and only if they are in this list. When this is not empty, the connection can be active only when one of the specified users is logged into an active session. Each entry is of the form \"[type]:[id]:[reserved]\"; for example, \"user:dcbw:blah\". At this time only the \"user\" [type] is allowed. Any other values are ignored and reserved for future use. [id] is the username that this permission refers to, which may not contain the \":\" character. Any [reserved] information present must be ignored and is reserved for future use. All of [type], [id], and [reserved] must be valid UTF-8.")

View file

@ -419,6 +419,8 @@
description="Whether Link-Local Multicast Name Resolution (LLMNR) is enabled for the connection. LLMNR is a protocol based on the Domain Name System (DNS) packet format that allows both IPv4 and IPv6 hosts to perform name resolution for hosts on the same local link. The permitted values are: &quot;yes&quot; (2) register hostname and resolving for the connection, &quot;no&quot; (0) disable LLMNR for the interface, &quot;resolve&quot; (1) do not register hostname but allow resolving of LLMNR host names If unspecified, &quot;default&quot; ultimately depends on the DNS plugin (which for systemd-resolved currently means &quot;yes&quot;). This feature requires a plugin which supports LLMNR. Otherwise, the setting has no effect. One such plugin is dns-systemd-resolved." />
<property name="dns-over-tls"
description="Whether DNSOverTls (dns-over-tls) is enabled for the connection. DNSOverTls is a technology which uses TLS to encrypt dns traffic. The permitted values are: &quot;yes&quot; (2) use DNSOverTls and disabled fallback, &quot;opportunistic&quot; (1) use DNSOverTls but allow fallback to unencrypted resolution, &quot;no&quot; (0) don&apos;t ever use DNSOverTls. If unspecified &quot;default&quot; depends on the plugin used. Systemd-resolved uses global setting. This feature requires a plugin which supports DNSOverTls. Otherwise, the setting has no effect. One such plugin is dns-systemd-resolved." />
<property name="mptcp-flags"
description="Whether to configure MPTCP endpoints and the address flags. If MPTCP is enabled in NetworkManager, it will configure the addresses of the interface as MPTCP endpoints. The supported flags are as follows. If &quot;disabled&quot; (0x1), MPTCP handling for the interface is disabled and no endpoints are registered. The flag &quot;enabled-on-global-iface&quot; (0x2) means that MPTCP handling is enabled if the interface configures a default route in the main routing table. This choice is per-address family, for example if there is an IPv4 default route 0.0.0.0/0, IPv4 endpoints are configured. The &quot;enabled&quot; (0x4) flag means that MPTCP handling is explicitly enabled. This flag can also be implied from the presence of other flags. If MPTCP handling is enabled, then endpoints will be configured with the specified address flags &quot;signal&quot; (0x10), &quot;subflow&quot; (0x20), &quot;backup&quot; (0x40), &quot;fullmesh&quot; (0x80). See ip-mptcp(8) manual for additional information about the flags. The flag &quot;with-loopback-4&quot; (0x100) indicates that NetworkManager will also configure MPTCP endpoints for IPv4 loopback addresses 127.0.0.0/8. Likewise, the flag &quot;with-link-local-4&quot; (0x200) includes IPv4 link local addresses 169.254.0.0/16. The &quot;skip-site-local-4&quot; (0x400) flag indicates to exclude rfc1918 private addresses (10.0.0.0/8, 172.16.0.0/12, 192.168.0.0/16). The flags &quot;with-loopback-6&quot; (0x1000), &quot;with-link-local-6&quot; (0x2000) and &quot;with-site-local-6&quot; (0x4000) apply to the IPv6 loopback address (::1), IPv6 link local addresses (fe80::/10) and IPv6 unique local addresses (ULA, fc00::/7), respectively. IPv6 privacy addresses (rfc3041, ipv6.ip6-privacy) are excluded from MPTCP configuration. The flag &quot;no-relax-rp-filter&quot; (0x10000) causes NetworkManager to not touch IPv4 rp_filter. Strict reverse path filtering (rp_filter) breaks many MPTCP use cases, so when MPTCP handling on the interface is enabled, NetworkManager would loosen the strict reverse path filtering (1) to the loose setting (2). This flag prevents that. If the flags are zero, the global connection default from NetworkManager.conf is honored. If still unspecified, the fallback is either &quot;disabled&quot; or &quot;enabled-on-global-iface,subflow&quot; depending on &quot;/proc/sys/net/mptcp/enabled&quot;. NetworkManager does not change the MPTCP limits nor enable MPTCP via &quot;/proc/sys/net/mptcp/enabled&quot;. That is a host configuration which the admin can change via sysctl and ip-mptcp." />
<property name="mud-url"
description="If configured, set to a Manufacturer Usage Description (MUD) URL that points to manufacturer-recommended network policies for IoT devices. It is transmitted as a DHCPv4 or DHCPv6 option. The value must be a valid URL starting with &quot;https://&quot;. The special value &quot;none&quot; is allowed to indicate that no MUD URL is used. If the per-profile value is unspecified (the default), a global connection default gets consulted. If still unspecified, the ultimate default is &quot;none&quot;." />
<property name="wait-device-timeout"

View file

@ -502,12 +502,12 @@ NAME UUID TYPE DEVICE
con-1 5fcfd6d7-1e63-3332-8826-a7eda103792d ethernet --
<<<
size: 1362
size: 1416
location: src/tests/client/test-client.py:test_002()/23
cmd: $NMCLI c s con-1
lang: C
returncode: 0
stdout: 1234 bytes
stdout: 1288 bytes
>>>
connection.id: con-1
connection.uuid: 5fcfd6d7-1e63-3332-8826-a7eda103792d
@ -533,16 +533,17 @@ connection.lldp: default
connection.mdns: -1 (default)
connection.llmnr: -1 (default)
connection.dns-over-tls: -1 (default)
connection.mptcp-flags: 0x0 (default)
connection.wait-device-timeout: -1
connection.wait-activation-delay: -1
<<<
size: 1374
size: 1428
location: src/tests/client/test-client.py:test_002()/24
cmd: $NMCLI c s con-1
lang: pl_PL.UTF-8
returncode: 0
stdout: 1236 bytes
stdout: 1290 bytes
>>>
connection.id: con-1
connection.uuid: 5fcfd6d7-1e63-3332-8826-a7eda103792d
@ -568,6 +569,7 @@ connection.lldp: default
connection.mdns: -1 (default)
connection.llmnr: -1 (default)
connection.dns-over-tls: -1 (default)
connection.mptcp-flags: 0x0 (default)
connection.wait-device-timeout: -1
connection.wait-activation-delay: -1

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff