diff options
author | Beniamino Galvani <bgalvani@redhat.com> | 2023-03-03 11:52:24 +0100 |
---|---|---|
committer | Beniamino Galvani <bgalvani@redhat.com> | 2023-03-03 11:52:24 +0100 |
commit | 992e39e048f28cd83004ec5232f009c3cd16d292 (patch) | |
tree | f261cc8f0b2929d0d9e3e488499d12f8f3b04af5 | |
parent | 86b922695f18566132980bd23516038b6ca4c0f4 (diff) | |
parent | 220189b9e67199f75d55d648a5d86bfaa07d79ae (diff) |
merge: branch 'bg/link-setting'
https://bugzilla.redhat.com/show_bug.cgi?id=2158328
https://gitlab.freedesktop.org/NetworkManager/NetworkManager/-/merge_requests/1541
29 files changed, 761 insertions, 21 deletions
diff --git a/Makefile.am b/Makefile.am index 9109af4c6a..6fc3d035b6 100644 --- a/Makefile.am +++ b/Makefile.am @@ -1265,6 +1265,7 @@ src_libnm_core_impl_lib_h_pub_real = \ src/libnm-core-public/nm-setting-ip-tunnel.h \ src/libnm-core-public/nm-setting-ip4-config.h \ src/libnm-core-public/nm-setting-ip6-config.h \ + src/libnm-core-public/nm-setting-link.h \ src/libnm-core-public/nm-setting-loopback.h \ src/libnm-core-public/nm-setting-macsec.h \ src/libnm-core-public/nm-setting-macvlan.h \ @@ -1346,6 +1347,7 @@ src_libnm_core_impl_lib_c_settings_real = \ src/libnm-core-impl/nm-setting-ip-tunnel.c \ src/libnm-core-impl/nm-setting-ip4-config.c \ src/libnm-core-impl/nm-setting-ip6-config.c \ + src/libnm-core-impl/nm-setting-link.c \ src/libnm-core-impl/nm-setting-loopback.c \ src/libnm-core-impl/nm-setting-macsec.c \ src/libnm-core-impl/nm-setting-macvlan.c \ diff --git a/docs/libnm/libnm-docs.xml b/docs/libnm/libnm-docs.xml index df668e4ee9..09468a5cdb 100644 --- a/docs/libnm/libnm-docs.xml +++ b/docs/libnm/libnm-docs.xml @@ -332,6 +332,7 @@ print ("NetworkManager version " + client.get_version())]]></programlisting></in <xi:include href="xml/nm-setting-ip-tunnel.xml"/> <xi:include href="xml/nm-setting-ip4-config.xml"/> <xi:include href="xml/nm-setting-ip6-config.xml"/> + <xi:include href="xml/nm-setting-link.xml"/> <xi:include href="xml/nm-setting-loopback.xml"/> <xi:include href="xml/nm-setting-macsec.xml"/> <xi:include href="xml/nm-setting-macvlan.xml"/> diff --git a/src/core/devices/nm-device-private.h b/src/core/devices/nm-device-private.h index 6f3a1c3e42..013bc7fd86 100644 --- a/src/core/devices/nm-device-private.h +++ b/src/core/devices/nm-device-private.h @@ -176,4 +176,6 @@ void nm_device_auth_request(NMDevice *self, NMManagerDeviceAuthRequestFunc callback, gpointer user_data); +void nm_device_link_properties_set(NMDevice *self, gboolean reapply); + #endif /* NM_DEVICE_PRIVATE_H */ diff --git a/src/core/devices/nm-device.c b/src/core/devices/nm-device.c index c0cdd733d9..300c958743 100644 --- a/src/core/devices/nm-device.c +++ b/src/core/devices/nm-device.c @@ -599,6 +599,8 @@ typedef struct _NMDevicePrivate { bool tc_committed : 1; + bool link_props_set : 1; + NMDeviceStageState stage1_sriov_state : 3; char *current_stable_id; @@ -702,6 +704,10 @@ typedef struct _NMDevicePrivate { GHashTable *ip6_saved_properties; EthtoolState *ethtool_state; + struct { + NMPlatformLinkProps props; + NMPlatformLinkChangeFlags flags; + } link_props_state; /* master interface for bridge/bond/team slave */ NMDevice *master; @@ -2750,6 +2756,151 @@ _ethtool_state_set(NMDevice *self) priv->ethtool_state = g_steal_pointer(ðtool_state); } +static NMPlatformLinkChangeFlags +link_properties_fill_from_setting(NMDevice *self, NMPlatformLinkProps *props) +{ + NMPlatformLinkChangeFlags flags = NM_PLATFORM_LINK_CHANGE_NONE; + NMSettingLink *s_link; + gint64 v; + + *props = (NMPlatformLinkProps){}; + + s_link = nm_device_get_applied_setting(self, NM_TYPE_SETTING_LINK); + if (!s_link) + return 0; + + v = nm_setting_link_get_tx_queue_length(s_link); + if (v != -1) { + props->tx_queue_length = (guint32) v; + flags |= NM_PLATFORM_LINK_CHANGE_TX_QUEUE_LENGTH; + } + + v = nm_setting_link_get_gso_max_size(s_link); + if (v != -1) { + props->gso_max_size = (guint32) v; + flags |= NM_PLATFORM_LINK_CHANGE_GSO_MAX_SIZE; + } + + v = nm_setting_link_get_gso_max_segments(s_link); + if (v != -1) { + props->gso_max_segments = (guint32) v; + flags |= NM_PLATFORM_LINK_CHANGE_GSO_MAX_SEGMENTS; + } + + v = nm_setting_link_get_gro_max_size(s_link); + if (v != -1) { + props->gro_max_size = (guint32) v; + flags |= NM_PLATFORM_LINK_CHANGE_GRO_MAX_SIZE; + } + + return flags; +} + +void +nm_device_link_properties_set(NMDevice *self, gboolean reapply) +{ + NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE(self); + NMPlatformLinkProps props; + NMPlatformLinkChangeFlags flags; + NMPlatform *platform; + const NMPlatformLink *plink; + int ifindex; + + ifindex = nm_device_get_ip_ifindex(self); + if (ifindex <= 0) + return; + + if (priv->link_props_set && !reapply) + return; + + priv->link_props_set = TRUE; + + flags = link_properties_fill_from_setting(self, &props); + + if (flags == NM_PLATFORM_LINK_CHANGE_NONE + && priv->link_props_state.flags == NM_PLATFORM_LINK_CHANGE_NONE) { + /* Nothing to set now, and nothing was set previously. */ + return; + } + + platform = nm_device_get_platform(self); + + if (priv->link_props_state.flags == NM_PLATFORM_LINK_CHANGE_NONE) { + /* It's the first time we reach here. Try to fetch the current + * link settings (reset them later). */ + plink = nm_platform_link_get(platform, ifindex); + if (plink) { + priv->link_props_state.props = plink->link_props; + priv->link_props_state.flags = flags; + } else { + /* Unknown properties. The "priv->link_props_state.flags" stays unset. + * It indicates that "priv->link_props_state.props" is unknown. */ + } + + } else { + /* From a previous call we have some "priv->link_props_state.flags" + * flags, which indicates that all link props are cached. Also add + * "flags" which are are going to set, to indicate that those flags + * will need to be reset later. */ + priv->link_props_state.flags |= flags; + } + +#define _RESET(_f, _field) \ + if (!NM_FLAGS_HAS(flags, (_f)) && NM_FLAGS_HAS(priv->link_props_state.flags, (_f))) { \ + props._field = priv->link_props_state.props._field; \ + priv->link_props_state.flags &= ~(_f); \ + flags |= (_f); \ + } + + /* During reapply, if we previously set some "priv->link_props_state.flags" + * but now not anymore (according to "flags"), then we reset the value now. + * + * We do this by copying the props field from "priv->link_props_state" to + * "props", reset the flag in "priv->link_props_state.flags" and set the + * flag in "flags" (for changing it). */ + _RESET(NM_PLATFORM_LINK_CHANGE_TX_QUEUE_LENGTH, tx_queue_length); + _RESET(NM_PLATFORM_LINK_CHANGE_GSO_MAX_SIZE, gso_max_size); + _RESET(NM_PLATFORM_LINK_CHANGE_GSO_MAX_SEGMENTS, gso_max_segments); + _RESET(NM_PLATFORM_LINK_CHANGE_GRO_MAX_SIZE, gro_max_size); + + if (nm_platform_link_change(platform, ifindex, &props, flags)) { + _LOGD(LOGD_DEVICE, "link properties successfully set"); + } else { + _LOGW(LOGD_DEVICE, "failure setting link properties"); + } +} + +static void +link_properties_reset(NMDevice *self) +{ + NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE(self); + NMPlatform *platform; + int ifindex; + + if (priv->link_props_state.flags == 0) + goto out; + + ifindex = nm_device_get_ip_ifindex(self); + if (ifindex <= 0) + goto out; + + platform = nm_device_get_platform(self); + nm_assert(platform); + + if (nm_platform_link_change(platform, + ifindex, + &priv->link_props_state.props, + priv->link_props_state.flags)) { + _LOGD(LOGD_DEVICE, "link properties successfully reset"); + } else { + _LOGW(LOGD_DEVICE, "failure resetting link properties"); + } + +out: + priv->link_props_set = FALSE; + priv->link_props_state.flags = 0; +} + /*****************************************************************************/ gboolean @@ -9760,10 +9911,12 @@ activate_stage2_device_config(NMDevice *self) nm_device_state_changed(self, NM_DEVICE_STATE_CONFIG, NM_DEVICE_STATE_REASON_NONE); - if (!nm_device_sys_iface_state_is_external_or_assume(self)) + if (!nm_device_sys_iface_state_is_external(self)) { _ethtool_state_set(self); + nm_device_link_properties_set(self, FALSE); + } - if (!nm_device_sys_iface_state_is_external_or_assume(self)) { + if (!nm_device_sys_iface_state_is_external(self)) { if (!priv->tc_committed && !tc_commit(self)) { _LOGW(LOGD_DEVICE, "failed applying traffic control rules"); nm_device_state_changed(self, @@ -12828,7 +12981,8 @@ can_reapply_change(NMDevice *self, NM_SETTING_USER_SETTING_NAME, NM_SETTING_PROXY_SETTING_NAME, NM_SETTING_IP4_CONFIG_SETTING_NAME, - NM_SETTING_IP6_CONFIG_SETTING_NAME)) + NM_SETTING_IP6_CONFIG_SETTING_NAME, + NM_SETTING_LINK_SETTING_NAME)) return TRUE; if (nm_streq(setting_name, NM_SETTING_WIRED_SETTING_NAME)) { @@ -13024,6 +13178,8 @@ check_and_reapply_connection(NMDevice *self, *************************************************************************/ klass->reapply_connection(self, con_old, con_new); + nm_device_link_properties_set(self, TRUE); + if (priv->state >= NM_DEVICE_STATE_CONFIG) lldp_setup(self, NM_TERNARY_DEFAULT); @@ -15622,6 +15778,7 @@ nm_device_cleanup(NMDevice *self, NMDeviceStateReason reason, CleanupType cleanu } _ethtool_state_reset(self); + link_properties_reset(self); if (priv->promisc_reset != NM_OPTION_BOOL_DEFAULT && ifindex > 0) { nm_platform_link_change_flags(nm_device_get_platform(self), diff --git a/src/core/devices/ovs/nm-device-ovs-interface.c b/src/core/devices/ovs/nm-device-ovs-interface.c index 711f65cb5b..3ff52c4645 100644 --- a/src/core/devices/ovs/nm-device-ovs-interface.c +++ b/src/core/devices/ovs/nm-device-ovs-interface.c @@ -132,6 +132,8 @@ link_changed(NMDevice *device, const NMPlatformLink *pllink) nm_device_devip_set_failed(device, AF_INET6, NM_DEVICE_STATE_REASON_CONFIG_FAILED); return; } + + nm_device_link_properties_set(device, FALSE); nm_device_bring_up(device); nm_device_devip_set_state(device, AF_INET, NM_DEVICE_IP_STATE_PENDING, NULL); @@ -214,6 +216,7 @@ _set_ip_ifindex_tun(gpointer user_data) priv->wait_link_is_waiting = FALSE; nm_device_set_ip_ifindex(device, priv->wait_link_ifindex); + nm_device_link_properties_set(device, FALSE); nm_device_devip_set_state(device, AF_INET, NM_DEVICE_IP_STATE_PENDING, NULL); nm_device_devip_set_state(device, AF_INET6, NM_DEVICE_IP_STATE_PENDING, NULL); @@ -303,6 +306,7 @@ act_stage3_ip_config(NMDevice *device, int addr_family) return; } + nm_device_link_properties_set(device, FALSE); nm_device_devip_set_state(device, addr_family, NM_DEVICE_IP_STATE_READY, NULL); } diff --git a/src/core/platform/tests/test-link.c b/src/core/platform/tests/test-link.c index fd341b4c8b..eb351eaa7d 100644 --- a/src/core/platform/tests/test-link.c +++ b/src/core/platform/tests/test-link.c @@ -2583,6 +2583,35 @@ test_vlan_set_xgress(void) /*****************************************************************************/ static void +test_link_set_properties(void) +{ + const NMPlatformLink *link; + NMPlatformLinkProps props; + NMPlatformLinkChangeFlags flags; + + props = (NMPlatformLinkProps){ + .tx_queue_length = 599, + .gso_max_size = 10001, + .gso_max_segments = 512, + }; + flags = NM_PLATFORM_LINK_CHANGE_TX_QUEUE_LENGTH | NM_PLATFORM_LINK_CHANGE_GSO_MAX_SIZE + | NM_PLATFORM_LINK_CHANGE_GSO_MAX_SEGMENTS; + + link = nmtstp_link_dummy_add(NM_PLATFORM_GET, FALSE, "dummy1"); + g_assert(nm_platform_link_change(NM_PLATFORM_GET, link->ifindex, &props, flags)); + + link = nmtstp_link_get(NM_PLATFORM_GET, link->ifindex, "dummy1"); + g_assert(link); + g_assert_cmpint(link->link_props.tx_queue_length, ==, 599); + g_assert_cmpint(link->link_props.gso_max_size, ==, 10001); + g_assert_cmpint(link->link_props.gso_max_segments, ==, 512); + + nmtstp_link_delete(NULL, -1, link->ifindex, "dummy1", TRUE); +} + +/*****************************************************************************/ + +static void test_create_many_links_do(guint n_devices) { gint64 time, start_time = nm_utils_get_monotonic_timestamp_nsec(); @@ -3948,6 +3977,8 @@ _nmtstp_setup_tests(void) g_test_add_func("/link/software/vlan/set-xgress", test_vlan_set_xgress); + g_test_add_func("/link/set-properties", test_link_set_properties); + g_test_add_data_func("/link/create-many-links/20", GUINT_TO_POINTER(20), test_create_many_links); diff --git a/src/libnm-client-impl/libnm.ver b/src/libnm-client-impl/libnm.ver index fbaebb13ec..5a89536ab3 100644 --- a/src/libnm-client-impl/libnm.ver +++ b/src/libnm-client-impl/libnm.ver @@ -1930,4 +1930,10 @@ libnm_1_44_0 { global: nm_setting_gsm_get_initial_eps_apn; nm_setting_gsm_get_initial_eps_config; + nm_setting_link_get_gro_max_size; + nm_setting_link_get_gso_max_segments; + nm_setting_link_get_gso_max_size; + nm_setting_link_get_tx_queue_length; + nm_setting_link_get_type; + nm_setting_link_new; } libnm_1_42_0; diff --git a/src/libnm-client-public/NetworkManager.h b/src/libnm-client-public/NetworkManager.h index da661db93b..cb5c319f77 100644 --- a/src/libnm-client-public/NetworkManager.h +++ b/src/libnm-client-public/NetworkManager.h @@ -44,6 +44,7 @@ #include "nm-setting-ip6-config.h" #include "nm-setting-ip-config.h" #include "nm-setting-ip-tunnel.h" +#include "nm-setting-link.h" #include "nm-setting-loopback.h" #include "nm-setting-macsec.h" #include "nm-setting-macvlan.h" diff --git a/src/libnm-client-public/nm-autoptr.h b/src/libnm-client-public/nm-autoptr.h index 9020af1481..fde6cccf32 100644 --- a/src/libnm-client-public/nm-autoptr.h +++ b/src/libnm-client-public/nm-autoptr.h @@ -85,6 +85,7 @@ G_DEFINE_AUTOPTR_CLEANUP_FUNC(NMSettingIP6Config, g_object_unref) G_DEFINE_AUTOPTR_CLEANUP_FUNC(NMSettingIPConfig, g_object_unref) G_DEFINE_AUTOPTR_CLEANUP_FUNC(NMSettingIPTunnel, g_object_unref) G_DEFINE_AUTOPTR_CLEANUP_FUNC(NMSettingInfiniband, g_object_unref) +G_DEFINE_AUTOPTR_CLEANUP_FUNC(NMSettingLink, g_object_unref) G_DEFINE_AUTOPTR_CLEANUP_FUNC(NMSettingLoopback, g_object_unref) G_DEFINE_AUTOPTR_CLEANUP_FUNC(NMSettingMacsec, g_object_unref) G_DEFINE_AUTOPTR_CLEANUP_FUNC(NMSettingMacvlan, g_object_unref) diff --git a/src/libnm-core-impl/gen-metadata-nm-settings-libnm-core.xml.in b/src/libnm-core-impl/gen-metadata-nm-settings-libnm-core.xml.in index 0559c2572f..c4133243ff 100644 --- a/src/libnm-core-impl/gen-metadata-nm-settings-libnm-core.xml.in +++ b/src/libnm-core-impl/gen-metadata-nm-settings-libnm-core.xml.in @@ -1749,6 +1749,26 @@ gprop-type="gchararray" /> </setting> + <setting name="link" + gtype="NMSettingLink" + > + <property name="gro-max-size" + dbus-type="x" + gprop-type="gint64" + /> + <property name="gso-max-segments" + dbus-type="x" + gprop-type="gint64" + /> + <property name="gso-max-size" + dbus-type="x" + gprop-type="gint64" + /> + <property name="tx-queue-length" + dbus-type="x" + gprop-type="gint64" + /> + </setting> <setting name="loopback" gtype="NMSettingLoopback" > diff --git a/src/libnm-core-impl/meson.build b/src/libnm-core-impl/meson.build index 6408ae178a..635b417b7e 100644 --- a/src/libnm-core-impl/meson.build +++ b/src/libnm-core-impl/meson.build @@ -24,6 +24,7 @@ libnm_core_settings_sources = files( 'nm-setting-ip-tunnel.c', 'nm-setting-ip4-config.c', 'nm-setting-ip6-config.c', + 'nm-setting-link.c', 'nm-setting-loopback.c', 'nm-setting-macsec.c', 'nm-setting-macvlan.c', diff --git a/src/libnm-core-impl/nm-meta-setting-base-impl.c b/src/libnm-core-impl/nm-meta-setting-base-impl.c index 190826718a..b531ae85a3 100644 --- a/src/libnm-core-impl/nm-meta-setting-base-impl.c +++ b/src/libnm-core-impl/nm-meta-setting-base-impl.c @@ -34,6 +34,7 @@ #include "nm-setting-ip-tunnel.h" #include "nm-setting-ip4-config.h" #include "nm-setting-ip6-config.h" +#include "nm-setting-link.h" #include "nm-setting-loopback.h" #include "nm-setting-macsec.h" #include "nm-setting-macvlan.h" @@ -362,6 +363,13 @@ const NMMetaSettingInfo nm_meta_setting_infos[] = { .setting_name = NM_SETTING_IP_TUNNEL_SETTING_NAME, .get_setting_gtype = nm_setting_ip_tunnel_get_type, }, + [NM_META_SETTING_TYPE_LINK] = + { + .meta_type = NM_META_SETTING_TYPE_LINK, + .setting_priority = NM_SETTING_PRIORITY_AUX, + .setting_name = NM_SETTING_LINK_SETTING_NAME, + .get_setting_gtype = nm_setting_link_get_type, + }, [NM_META_SETTING_TYPE_LOOPBACK] = { .meta_type = NM_META_SETTING_TYPE_LOOPBACK, @@ -660,6 +668,7 @@ const NMMetaSettingType nm_meta_setting_types_by_priority[] = { NM_META_SETTING_TYPE_BOND_PORT, NM_META_SETTING_TYPE_BRIDGE_PORT, NM_META_SETTING_TYPE_ETHTOOL, + NM_META_SETTING_TYPE_LINK, NM_META_SETTING_TYPE_MATCH, NM_META_SETTING_TYPE_OVS_EXTERNAL_IDS, NM_META_SETTING_TYPE_OVS_OTHER_CONFIG, diff --git a/src/libnm-core-impl/nm-setting-link.c b/src/libnm-core-impl/nm-setting-link.c new file mode 100644 index 0000000000..29d56d67eb --- /dev/null +++ b/src/libnm-core-impl/nm-setting-link.c @@ -0,0 +1,241 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2023 Red Hat, Inc. + */ + +#include "libnm-core-impl/nm-default-libnm-core.h" + +#include "nm-setting-link.h" + +#include "nm-setting-private.h" +#include "nm-utils-private.h" + +/** + * SECTION:nm-setting-link + * @short_description: Contains properties related to the link + * @include: nm-setting-link.h + **/ + +/*****************************************************************************/ + +NM_GOBJECT_PROPERTIES_DEFINE(NMSettingLink, + PROP_TX_QUEUE_LENGTH, + PROP_GSO_MAX_SIZE, + PROP_GSO_MAX_SEGMENTS, + PROP_GRO_MAX_SIZE, ); + +/** + * NMSettingLink: + * + * Link settings + * + * Since: 1.44 + */ +struct _NMSettingLink { + NMSetting parent; + gint64 tx_queue_length; + gint64 gso_max_size; + gint64 gso_max_segments; + gint64 gro_max_size; +}; + +struct _NMSettingLinkClass { + NMSettingClass parent; +}; + +G_DEFINE_TYPE(NMSettingLink, nm_setting_link, NM_TYPE_SETTING) + +/** + * nm_setting_link_get_tx_queue_length: + * @setting: the #NMSettingLink + * + * Returns the value contained in the #NMSettingLink:tx-queue-length + * property. + * + * Returns: the 'tx-queue-length' property value + * + * Since: 1.44 + **/ +gint64 +nm_setting_link_get_tx_queue_length(NMSettingLink *setting) +{ + g_return_val_if_fail(NM_IS_SETTING_LINK(setting), 0); + + return setting->tx_queue_length; +} + +/** + * nm_setting_link_get_gso_max_size: + * @setting: the #NMSettingLink + * + * Returns the value contained in the #NMSettingLink:gso-max-size + * property. + * + * Returns: the 'gso-max-size' property value + * + * Since: 1.44 + **/ +gint64 +nm_setting_link_get_gso_max_size(NMSettingLink *setting) +{ + g_return_val_if_fail(NM_IS_SETTING_LINK(setting), 0); + + return setting->gso_max_size; +} + +/** + * nm_setting_link_get_gso_max_segments: + * @setting: the #NMSettingLink + * + * Returns the value contained in the #NMSettingLink:gso-max-segments + * property. + * + * Returns: the 'gso-max-segments' property value + * + * Since: 1.44 + **/ +gint64 +nm_setting_link_get_gso_max_segments(NMSettingLink *setting) +{ + g_return_val_if_fail(NM_IS_SETTING_LINK(setting), 0); + + return setting->gso_max_segments; +} + +/** + * nm_setting_link_get_gro_max_size: + * @setting: the #NMSettingLink + * + * Returns the value contained in the #NMSettingLink:gro-max-size + * property. + * + * Returns: the 'gro-max-size' property value + * + * Since: 1.44 + **/ +gint64 +nm_setting_link_get_gro_max_size(NMSettingLink *setting) +{ + g_return_val_if_fail(NM_IS_SETTING_LINK(setting), 0); + + return setting->gro_max_size; +} + +/*****************************************************************************/ + +static void +nm_setting_link_init(NMSettingLink *setting) +{} + +/** + * nm_setting_link_new: + * + * Creates a new #NMSettingLink object with default values. + * + * Returns: (transfer full): the new empty #NMSettingLink object + * + * Since: 1.44 + **/ +NMSetting * +nm_setting_link_new(void) +{ + return g_object_new(NM_TYPE_SETTING_LINK, NULL); +} + +static void +nm_setting_link_class_init(NMSettingLinkClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS(klass); + NMSettingClass *setting_class = NM_SETTING_CLASS(klass); + GArray *properties_override = _nm_sett_info_property_override_create_array(); + + object_class->get_property = _nm_setting_property_get_property_direct; + object_class->set_property = _nm_setting_property_set_property_direct; + + /** + * NMSettingLink:tx-queue-length + * + * The size of the transmit queue for the device, in number of packets. The value + * must be between 0 and 4294967295. When set to -1, the existing value is preserved. + * + * Since: 1.44 + **/ + _nm_setting_property_define_direct_int64(properties_override, + obj_properties, + NM_SETTING_LINK_TX_QUEUE_LENGTH, + PROP_TX_QUEUE_LENGTH, + -1, + G_MAXUINT32, + -1, + NM_SETTING_PARAM_NONE, + NMSettingLink, + tx_queue_length); + + /** + * NMSettingLink:gso-max-size + * + * The maximum size of a Generic Segment Offload packet the device should accept. + * The value must be between 0 and 4294967295. When set to -1, the existing value + * is preserved. + * + * Since: 1.44 + **/ + _nm_setting_property_define_direct_int64(properties_override, + obj_properties, + NM_SETTING_LINK_GSO_MAX_SIZE, + PROP_GSO_MAX_SIZE, + -1, + G_MAXUINT32, + -1, + NM_SETTING_PARAM_NONE, + NMSettingLink, + gso_max_size); + + /** + * NMSettingLink:gso-max-segments + * + * The maximum segments of a Generic Segment Offload packet the device should accept. + * The value must be between 0 and 4294967295. When set to -1, the existing value + * is preserved. + * + * Since: 1.44 + **/ + _nm_setting_property_define_direct_int64(properties_override, + obj_properties, + NM_SETTING_LINK_GSO_MAX_SEGMENTS, + PROP_GSO_MAX_SEGMENTS, + -1, + G_MAXUINT32, + -1, + NM_SETTING_PARAM_NONE, + NMSettingLink, + gso_max_segments); + + /** + * NMSettingLink:gro-max-size + * + * The maximum size of a packet built by the Generic Receive Offload stack for + * this device. The value must be between 0 and 4294967295. When set to -1, the + * existing value is preserved. + * + * Since: 1.44 + **/ + _nm_setting_property_define_direct_int64(properties_override, + obj_properties, + NM_SETTING_LINK_GRO_MAX_SIZE, + PROP_GRO_MAX_SIZE, + -1, + G_MAXUINT32, + -1, + NM_SETTING_PARAM_NONE, + NMSettingLink, + gro_max_size); + + g_object_class_install_properties(object_class, _PROPERTY_ENUMS_LAST, obj_properties); + + _nm_setting_class_commit(setting_class, + NM_META_SETTING_TYPE_LINK, + NULL, + properties_override, + 0); +} diff --git a/src/libnm-core-impl/tests/test-setting.c b/src/libnm-core-impl/tests/test-setting.c index 09e0fc70ee..46e6818125 100644 --- a/src/libnm-core-impl/tests/test-setting.c +++ b/src/libnm-core-impl/tests/test-setting.c @@ -121,8 +121,6 @@ test_nm_meta_setting_types_by_priority(void) G_STATIC_ASSERT_EXPR(_NM_META_SETTING_TYPE_NUM == G_N_ELEMENTS(nm_meta_setting_types_by_priority)); - G_STATIC_ASSERT_EXPR(_NM_META_SETTING_TYPE_NUM == 54); - arr = g_ptr_array_new_with_free_func(g_object_unref); for (i = 0; i < _NM_META_SETTING_TYPE_NUM; i++) { diff --git a/src/libnm-core-intern/nm-core-internal.h b/src/libnm-core-intern/nm-core-internal.h index 71bbb0d499..3a56012323 100644 --- a/src/libnm-core-intern/nm-core-internal.h +++ b/src/libnm-core-intern/nm-core-internal.h @@ -43,6 +43,7 @@ #include "nm-setting-ip-tunnel.h" #include "nm-setting-ip4-config.h" #include "nm-setting-ip6-config.h" +#include "nm-setting-link.h" #include "nm-setting-loopback.h" #include "nm-setting-macsec.h" #include "nm-setting-macvlan.h" diff --git a/src/libnm-core-intern/nm-meta-setting-base-impl.h b/src/libnm-core-intern/nm-meta-setting-base-impl.h index 0c2def90cd..c6d1c2fcb6 100644 --- a/src/libnm-core-intern/nm-meta-setting-base-impl.h +++ b/src/libnm-core-intern/nm-meta-setting-base-impl.h @@ -127,6 +127,7 @@ typedef enum _nm_packed { NM_META_SETTING_TYPE_IP_TUNNEL, NM_META_SETTING_TYPE_IP4_CONFIG, NM_META_SETTING_TYPE_IP6_CONFIG, + NM_META_SETTING_TYPE_LINK, NM_META_SETTING_TYPE_LOOPBACK, NM_META_SETTING_TYPE_MACSEC, NM_META_SETTING_TYPE_MACVLAN, diff --git a/src/libnm-core-public/meson.build b/src/libnm-core-public/meson.build index c54071303c..d135dbff94 100644 --- a/src/libnm-core-public/meson.build +++ b/src/libnm-core-public/meson.build @@ -29,6 +29,7 @@ libnm_core_headers = files( 'nm-setting-ip-tunnel.h', 'nm-setting-ip4-config.h', 'nm-setting-ip6-config.h', + 'nm-setting-link.h', 'nm-setting-loopback.h', 'nm-setting-macsec.h', 'nm-setting-macvlan.h', diff --git a/src/libnm-core-public/nm-core-types.h b/src/libnm-core-public/nm-core-types.h index f285a0f6f1..758733a1cc 100644 --- a/src/libnm-core-public/nm-core-types.h +++ b/src/libnm-core-public/nm-core-types.h @@ -35,6 +35,7 @@ typedef struct _NMSettingIP6Config NMSettingIP6Config; typedef struct _NMSettingIPConfig NMSettingIPConfig; typedef struct _NMSettingIPTunnel NMSettingIPTunnel; typedef struct _NMSettingInfiniband NMSettingInfiniband; +typedef struct _NMSettingLink NMSettingLink; typedef struct _NMSettingLoopback NMSettingLoopback; typedef struct _NMSettingMacsec NMSettingMacsec; typedef struct _NMSettingMacvlan NMSettingMacvlan; diff --git a/src/libnm-core-public/nm-setting-link.h b/src/libnm-core-public/nm-setting-link.h new file mode 100644 index 0000000000..98973ff568 --- /dev/null +++ b/src/libnm-core-public/nm-setting-link.h @@ -0,0 +1,52 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2020 Red Hat, Inc. + */ + +#ifndef __NM_SETTING_LINK_H__ +#define __NM_SETTING_LINK_H__ + +#if !defined(__NETWORKMANAGER_H_INSIDE__) && !defined(NETWORKMANAGER_COMPILATION) +#error "Only <NetworkManager.h> can be included directly." +#endif + +#include "nm-setting.h" + +G_BEGIN_DECLS + +#define NM_TYPE_SETTING_LINK (nm_setting_link_get_type()) +#define NM_SETTING_LINK(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST((obj), NM_TYPE_SETTING_LINK, NMSettingLink)) +#define NM_SETTING_LINK_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_CAST((klass), NM_TYPE_SETTING_LINK, NMSettingLinkClass)) +#define NM_IS_SETTING_LINK(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), NM_TYPE_SETTING_LINK)) +#define NM_IS_SETTING_LINK_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), NM_TYPE_SETTING_LINK)) +#define NM_SETTING_LINK_GET_CLASS(obj) \ + (G_TYPE_INSTANCE_GET_CLASS((obj), NM_TYPE_SETTING_LINK, NMSettingLinkClass)) + +#define NM_SETTING_LINK_SETTING_NAME "link" + +#define NM_SETTING_LINK_TX_QUEUE_LENGTH "tx-queue-length" +#define NM_SETTING_LINK_GSO_MAX_SIZE "gso-max-size" +#define NM_SETTING_LINK_GSO_MAX_SEGMENTS "gso-max-segments" +#define NM_SETTING_LINK_GRO_MAX_SIZE "gro-max-size" + +typedef struct _NMSettingLinkClass NMSettingLinkClass; + +NM_AVAILABLE_IN_1_44 +GType nm_setting_link_get_type(void); +NM_AVAILABLE_IN_1_44 +NMSetting *nm_setting_link_new(void); + +NM_AVAILABLE_IN_1_44 +gint64 nm_setting_link_get_tx_queue_length(NMSettingLink *setting); +NM_AVAILABLE_IN_1_44 +gint64 nm_setting_link_get_gso_max_size(NMSettingLink *setting); +NM_AVAILABLE_IN_1_44 +gint64 nm_setting_link_get_gso_max_segments(NMSettingLink *setting); +NM_AVAILABLE_IN_1_44 +gint64 nm_setting_link_get_gro_max_size(NMSettingLink *setting); + +G_END_DECLS + +#endif /* __NM_SETTING_LINK_H__ */ diff --git a/src/libnm-platform/nm-linux-platform.c b/src/libnm-platform/nm-linux-platform.c index 78d6e704bb..94e92a9bec 100644 --- a/src/libnm-platform/nm-linux-platform.c +++ b/src/libnm-platform/nm-linux-platform.c @@ -115,7 +115,9 @@ typedef enum _nm_packed { #define IFLA_CARRIER 33 #define IFLA_PHYS_PORT_ID 34 #define IFLA_LINK_NETNSID 37 -#define __IFLA_MAX 39 +#define IFLA_GSO_MAX_SEGS 40 +#define IFLA_GSO_MAX_SIZE 41 +#define IFLA_GRO_MAX_SIZE 58 #define IFLA_INET6_TOKEN 7 #define IFLA_INET6_ADDR_GEN_MODE 8 @@ -3260,6 +3262,9 @@ _new_from_nl_link(NMPlatform *platform, [IFLA_IFNAME] = {.type = NLA_STRING, .maxlen = IFNAMSIZ}, [IFLA_MTU] = {.type = NLA_U32}, [IFLA_TXQLEN] = {.type = NLA_U32}, + [IFLA_GSO_MAX_SIZE] = {.type = NLA_U32}, + [IFLA_GSO_MAX_SEGS] = {.type = NLA_U32}, + [IFLA_GRO_MAX_SIZE] = {.type = NLA_U32}, [IFLA_LINK] = {.type = NLA_U32}, [IFLA_WEIGHT] = {.type = NLA_U32}, [IFLA_MASTER] = {.type = NLA_U32}, @@ -3359,6 +3364,15 @@ _new_from_nl_link(NMPlatform *platform, nl_info_data = li[IFLA_INFO_DATA]; } + if (tb[IFLA_TXQLEN]) + obj->link.link_props.tx_queue_length = nla_get_u32(tb[IFLA_TXQLEN]); + if (tb[IFLA_GSO_MAX_SIZE]) + obj->link.link_props.gso_max_size = nla_get_u32(tb[IFLA_GSO_MAX_SIZE]); + if (tb[IFLA_GSO_MAX_SEGS]) + obj->link.link_props.gso_max_segments = nla_get_u32(tb[IFLA_GSO_MAX_SEGS]); + if (tb[IFLA_GRO_MAX_SIZE]) + obj->link.link_props.gro_max_size = nla_get_u32(tb[IFLA_GRO_MAX_SIZE]); + if (tb[IFLA_STATS64]) { const char *stats = nla_data(tb[IFLA_STATS64]); @@ -8270,7 +8284,7 @@ out: } static int -link_change(NMPlatform *platform, NMLinkType type, int ifindex, gconstpointer extra_data) +link_change_extra(NMPlatform *platform, NMLinkType type, int ifindex, gconstpointer extra_data) { nm_auto_nlmsg struct nl_msg *nlmsg = NULL; @@ -8348,6 +8362,32 @@ link_delete(NMPlatform *platform, int ifindex) } static gboolean +link_change(NMPlatform *platform, + int ifindex, + NMPlatformLinkProps *props, + NMPlatformLinkChangeFlags flags) +{ + nm_auto_nlmsg struct nl_msg *nlmsg = NULL; + + nlmsg = _nl_msg_new_link(RTM_NEWLINK, 0, ifindex, NULL); + if (!nlmsg) + return FALSE; + + if (flags & NM_PLATFORM_LINK_CHANGE_TX_QUEUE_LENGTH) + NLA_PUT_U32(nlmsg, IFLA_TXQLEN, props->tx_queue_length); + if (flags & NM_PLATFORM_LINK_CHANGE_GSO_MAX_SIZE) + NLA_PUT_U32(nlmsg, IFLA_GSO_MAX_SIZE, props->gso_max_size); + if (flags & NM_PLATFORM_LINK_CHANGE_GSO_MAX_SEGMENTS) + NLA_PUT_U32(nlmsg, IFLA_GSO_MAX_SEGS, props->gso_max_segments); + if (flags & NM_PLATFORM_LINK_CHANGE_GRO_MAX_SIZE) + NLA_PUT_U32(nlmsg, IFLA_GRO_MAX_SIZE, props->gro_max_size); + + return do_change_link(platform, CHANGE_LINK_TYPE_UNSPEC, ifindex, nlmsg, NULL) == 0; +nla_put_failure: + g_return_val_if_reached(FALSE); +} + +static gboolean link_refresh(NMPlatform *platform, int ifindex) { do_request_link(platform, ifindex, NULL); @@ -11166,9 +11206,11 @@ nm_linux_platform_class_init(NMLinuxPlatformClass *klass) platform_class->sysctl_set_async = sysctl_set_async; platform_class->sysctl_get = sysctl_get; - platform_class->link_add = link_add; + platform_class->link_add = link_add; + platform_class->link_change_extra = link_change_extra; + platform_class->link_delete = link_delete; + platform_class->link_change = link_change; - platform_class->link_delete = link_delete; platform_class->link_refresh = link_refresh; diff --git a/src/libnm-platform/nm-platform.c b/src/libnm-platform/nm-platform.c index 64d0fd8efd..06c1f4a741 100644 --- a/src/libnm-platform/nm-platform.c +++ b/src/libnm-platform/nm-platform.c @@ -1406,7 +1406,10 @@ nm_platform_link_add(NMPlatform *self, } int -nm_platform_link_change(NMPlatform *self, NMLinkType type, int ifindex, gconstpointer extra_data) +nm_platform_link_change_extra(NMPlatform *self, + NMLinkType type, + int ifindex, + gconstpointer extra_data) { char buf[512]; const char *name = nm_platform_link_get_name(self, ifindex); @@ -1447,7 +1450,7 @@ nm_platform_link_change(NMPlatform *self, NMLinkType type, int ifindex, gconstpo buf; })); - return klass->link_change(self, type, ifindex, extra_data); + return klass->link_change_extra(self, type, ifindex, extra_data); } /** @@ -2130,6 +2133,40 @@ nm_platform_link_set_name(NMPlatform *self, int ifindex, const char *name) return klass->link_set_name(self, ifindex, name); } +gboolean +nm_platform_link_change(NMPlatform *self, + int ifindex, + NMPlatformLinkProps *props, + NMPlatformLinkChangeFlags flags) +{ + _CHECK_SELF(self, klass, FALSE); + + g_return_val_if_fail(ifindex >= 0, FALSE); + + if (flags == 0) + return TRUE; + + if (_LOGD_ENABLED()) { + nm_auto_free_gstring GString *str = g_string_new(""); + + if (flags & NM_PLATFORM_LINK_CHANGE_TX_QUEUE_LENGTH) + g_string_append_printf(str, "tx-queue-length %u ", props->tx_queue_length); + if (flags & NM_PLATFORM_LINK_CHANGE_GSO_MAX_SIZE) + g_string_append_printf(str, "gso_max_size %u ", props->gso_max_size); + if (flags & NM_PLATFORM_LINK_CHANGE_GSO_MAX_SEGMENTS) + g_string_append_printf(str, "gso_max_segments %u ", props->gso_max_segments); + if (flags & NM_PLATFORM_LINK_CHANGE_GRO_MAX_SIZE) + g_string_append_printf(str, "gro_max_size %u ", props->gro_max_size); + + if (str->len > 0 && str->str[str->len - 1] == ' ') + g_string_truncate(str, str->len - 1); + + _LOG3D("link: change: %s", str->str); + } + + return klass->link_change(self, ifindex, props, flags); +} + /** * nm_platform_link_get_physical_port_id: * @self: platform instance @@ -6015,6 +6052,10 @@ nm_platform_link_to_string(const NMPlatformLink *link, char *buf, gsize len) "%s%s" /* l_broadcast */ "%s%s" /* inet6_token */ "%s%s" /* driver */ + " tx-queue-len %u" + " gso-max-size %u" + " gso-max-segs %u" + " gro-max-size %u" " rx:%" G_GUINT64_FORMAT ",%" G_GUINT64_FORMAT " tx:%" G_GUINT64_FORMAT ",%" G_GUINT64_FORMAT, link->ifindex, @@ -6047,6 +6088,10 @@ nm_platform_link_to_string(const NMPlatformLink *link, char *buf, gsize len) : "", link->driver ? " driver " : "", link->driver ?: "", + link->link_props.tx_queue_length, + link->link_props.gso_max_size, + link->link_props.gso_max_segments, + link->link_props.gro_max_size, link->rx_packets, link->rx_bytes, link->tx_packets, @@ -7879,6 +7924,10 @@ nm_platform_link_hash_update(const NMPlatformLink *obj, NMHashState *h) obj->arptype, obj->inet6_addr_gen_mode_inv, obj->inet6_token, + obj->link_props.tx_queue_length, + obj->link_props.gso_max_size, + obj->link_props.gso_max_segments, + obj->link_props.gro_max_size, obj->rx_packets, obj->rx_bytes, obj->tx_packets, @@ -7926,6 +7975,10 @@ nm_platform_link_cmp(const NMPlatformLink *a, const NMPlatformLink *b) if (a->l_broadcast.len) NM_CMP_FIELD_MEMCMP_LEN(a, b, l_broadcast.data, a->l_broadcast.len); NM_CMP_FIELD_MEMCMP(a, b, inet6_token); + NM_CMP_FIELD(a, b, link_props.tx_queue_length); + NM_CMP_FIELD(a, b, link_props.gso_max_size); + NM_CMP_FIELD(a, b, link_props.gso_max_segments); + NM_CMP_FIELD(a, b, link_props.gro_max_size); NM_CMP_FIELD(a, b, rx_packets); NM_CMP_FIELD(a, b, rx_bytes); NM_CMP_FIELD(a, b, tx_packets); diff --git a/src/libnm-platform/nm-platform.h b/src/libnm-platform/nm-platform.h index 447ef3aa8f..d816513cd0 100644 --- a/src/libnm-platform/nm-platform.h +++ b/src/libnm-platform/nm-platform.h @@ -150,6 +150,21 @@ GBytes *nmp_link_address_get_as_bytes(const NMPLinkAddress *addr); #define NM_PLATFORM_LINK_OTHER_NETNS (-1) +typedef struct { + guint32 tx_queue_length; + guint32 gso_max_size; + guint32 gso_max_segments; + guint32 gro_max_size; +} NMPlatformLinkProps; + +typedef enum { + NM_PLATFORM_LINK_CHANGE_NONE = 0, + NM_PLATFORM_LINK_CHANGE_TX_QUEUE_LENGTH = (1 << 0), + NM_PLATFORM_LINK_CHANGE_GSO_MAX_SIZE = (1 << 1), + NM_PLATFORM_LINK_CHANGE_GSO_MAX_SEGMENTS = (1 << 2), + NM_PLATFORM_LINK_CHANGE_GRO_MAX_SIZE = (1 << 3), +} NMPlatformLinkChangeFlags; + struct _NMPlatformObjWithIfindex { __NMPlatformObjWithIfindex_COMMON; } _nm_alignas(NMPlatformObject); @@ -204,6 +219,8 @@ struct _NMPlatformLink { guint64 tx_packets; guint64 tx_bytes; + NMPlatformLinkProps link_props; + /* @connected is mostly identical to (@n_ifi_flags & IFF_UP). Except for bridge/bond masters, * where we coerce the link as disconnect if it has no slaves. */ bool connected : 1; @@ -1093,9 +1110,14 @@ typedef struct { guint32 mtu, gconstpointer extra_data, const NMPlatformLink **out_link); - - int (*link_change)(NMPlatform *self, NMLinkType type, int ifindex, gconstpointer extra_data); - + int (*link_change_extra)(NMPlatform *self, + NMLinkType type, + int ifindex, + gconstpointer extra_data); + gboolean (*link_change)(NMPlatform *self, + int ifindex, + NMPlatformLinkProps *props, + NMPlatformLinkChangeFlags flags); gboolean (*link_delete)(NMPlatform *self, int ifindex); gboolean (*link_refresh)(NMPlatform *self, int ifindex); gboolean (*link_set_netns)(NMPlatform *self, int ifindex, int netns_fd); @@ -1603,8 +1625,10 @@ int nm_platform_link_add(NMPlatform *self, gconstpointer extra_data, const NMPlatformLink **out_link); -int -nm_platform_link_change(NMPlatform *self, NMLinkType type, int ifindex, gconstpointer extra_data); +int nm_platform_link_change_extra(NMPlatform *self, + NMLinkType type, + int ifindex, + gconstpointer extra_data); static inline int nm_platform_link_veth_add(NMPlatform *self, @@ -1644,13 +1668,13 @@ nm_platform_link_bridge_add(NMPlatform *self, static inline int nm_platform_link_bridge_change(NMPlatform *self, int ifindex, const NMPlatformLnkBridge *props) { - return nm_platform_link_change(self, NM_LINK_TYPE_BRIDGE, ifindex, props); + return nm_platform_link_change_extra(self, NM_LINK_TYPE_BRIDGE, ifindex, props); } static inline int nm_platform_link_bond_change(NMPlatform *self, int ifindex, const NMPlatformLnkBond *props) { - return nm_platform_link_change(self, NM_LINK_TYPE_BOND, ifindex, props); + return nm_platform_link_change_extra(self, NM_LINK_TYPE_BOND, ifindex, props); } static inline int @@ -1927,6 +1951,11 @@ nm_platform_link_change_flags(NMPlatform *self, int ifindex, unsigned value, gbo return nm_platform_link_change_flags_full(self, ifindex, value, set ? value : 0u); } +gboolean nm_platform_link_change(NMPlatform *self, + int ifindex, + NMPlatformLinkProps *props, + NMPlatformLinkChangeFlags flags); + gboolean nm_platform_link_get_udev_property(NMPlatform *self, int ifindex, const char *name, diff --git a/src/libnmc-setting/nm-meta-setting-base-impl.c b/src/libnmc-setting/nm-meta-setting-base-impl.c index 190826718a..b531ae85a3 100644 --- a/src/libnmc-setting/nm-meta-setting-base-impl.c +++ b/src/libnmc-setting/nm-meta-setting-base-impl.c @@ -34,6 +34,7 @@ #include "nm-setting-ip-tunnel.h" #include "nm-setting-ip4-config.h" #include "nm-setting-ip6-config.h" +#include "nm-setting-link.h" #include "nm-setting-loopback.h" #include "nm-setting-macsec.h" #include "nm-setting-macvlan.h" @@ -362,6 +363,13 @@ const NMMetaSettingInfo nm_meta_setting_infos[] = { .setting_name = NM_SETTING_IP_TUNNEL_SETTING_NAME, .get_setting_gtype = nm_setting_ip_tunnel_get_type, }, + [NM_META_SETTING_TYPE_LINK] = + { + .meta_type = NM_META_SETTING_TYPE_LINK, + .setting_priority = NM_SETTING_PRIORITY_AUX, + .setting_name = NM_SETTING_LINK_SETTING_NAME, + .get_setting_gtype = nm_setting_link_get_type, + }, [NM_META_SETTING_TYPE_LOOPBACK] = { .meta_type = NM_META_SETTING_TYPE_LOOPBACK, @@ -660,6 +668,7 @@ const NMMetaSettingType nm_meta_setting_types_by_priority[] = { NM_META_SETTING_TYPE_BOND_PORT, NM_META_SETTING_TYPE_BRIDGE_PORT, NM_META_SETTING_TYPE_ETHTOOL, + NM_META_SETTING_TYPE_LINK, NM_META_SETTING_TYPE_MATCH, NM_META_SETTING_TYPE_OVS_EXTERNAL_IDS, NM_META_SETTING_TYPE_OVS_OTHER_CONFIG, diff --git a/src/libnmc-setting/nm-meta-setting-base-impl.h b/src/libnmc-setting/nm-meta-setting-base-impl.h index 0c2def90cd..c6d1c2fcb6 100644 --- a/src/libnmc-setting/nm-meta-setting-base-impl.h +++ b/src/libnmc-setting/nm-meta-setting-base-impl.h @@ -127,6 +127,7 @@ typedef enum _nm_packed { NM_META_SETTING_TYPE_IP_TUNNEL, NM_META_SETTING_TYPE_IP4_CONFIG, NM_META_SETTING_TYPE_IP6_CONFIG, + NM_META_SETTING_TYPE_LINK, NM_META_SETTING_TYPE_LOOPBACK, NM_META_SETTING_TYPE_MACSEC, NM_META_SETTING_TYPE_MACVLAN, diff --git a/src/libnmc-setting/nm-meta-setting-desc.c b/src/libnmc-setting/nm-meta-setting-desc.c index 46bc818fa5..60a2cfd402 100644 --- a/src/libnmc-setting/nm-meta-setting-desc.c +++ b/src/libnmc-setting/nm-meta-setting-desc.c @@ -6649,6 +6649,56 @@ static const NMMetaPropertyInfo *const property_infos_LOOPBACK[] = { }; #undef _CURRENT_NM_META_SETTING_TYPE +#define _CURRENT_NM_META_SETTING_TYPE NM_META_SETTING_TYPE_LINK +static const NMMetaPropertyInfo *const property_infos_LINK[] = { + PROPERTY_INFO_WITH_DESC (NM_SETTING_LINK_GSO_MAX_SEGMENTS, + .property_type = &_pt_gobject_int, + .property_typ_data = DEFINE_PROPERTY_TYP_DATA_SUBTYPE (gobject_int, + .value_infos = INT_VALUE_INFOS ( + { + .value.i64 = -1, + .nick = "default", + }, + ), + ), + ), + PROPERTY_INFO_WITH_DESC (NM_SETTING_LINK_GSO_MAX_SIZE, + .property_type = &_pt_gobject_int, + .property_typ_data = DEFINE_PROPERTY_TYP_DATA_SUBTYPE (gobject_int, + .value_infos = INT_VALUE_INFOS ( + { + .value.i64 = -1, + .nick = "default", + }, + ), + ), + ), + PROPERTY_INFO_WITH_DESC (NM_SETTING_LINK_GRO_MAX_SIZE, + .property_type = &_pt_gobject_int, + .property_typ_data = DEFINE_PROPERTY_TYP_DATA_SUBTYPE (gobject_int, + .value_infos = INT_VALUE_INFOS ( + { + .value.i64 = -1, + .nick = "default", + }, + ), + ), + ), + PROPERTY_INFO_WITH_DESC (NM_SETTING_LINK_TX_QUEUE_LENGTH, + .property_type = &_pt_gobject_int, + .property_typ_data = DEFINE_PROPERTY_TYP_DATA_SUBTYPE (gobject_int, + .value_infos = INT_VALUE_INFOS ( + { + .value.i64 = -1, + .nick = "default", + }, + ), + ), + ), + NULL +}; + +#undef _CURRENT_NM_META_SETTING_TYPE #define _CURRENT_NM_META_SETTING_TYPE NM_META_SETTING_TYPE_MACSEC static const NMMetaPropertyInfo *const property_infos_MACSEC[] = { PROPERTY_INFO_WITH_DESC (NM_SETTING_MACSEC_PARENT, @@ -8427,6 +8477,7 @@ _setting_init_fcn_wireless (ARGS_SETTING_INIT_FCN) #define SETTING_PRETTY_NAME_IP4_CONFIG N_("IPv4 protocol") #define SETTING_PRETTY_NAME_IP6_CONFIG N_("IPv6 protocol") #define SETTING_PRETTY_NAME_IP_TUNNEL N_("IP-tunnel settings") +#define SETTING_PRETTY_NAME_LINK N_("Link settings") #define SETTING_PRETTY_NAME_LOOPBACK N_("Loopback settings") #define SETTING_PRETTY_NAME_MACSEC N_("MACsec connection") #define SETTING_PRETTY_NAME_MACVLAN N_("macvlan connection") @@ -8588,6 +8639,7 @@ const NMMetaSettingInfoEditor nm_meta_setting_infos_editor[] = { NM_META_SETTING_VALID_PART_ITEM (ETHTOOL, FALSE), ), ), + SETTING_INFO (LINK), SETTING_INFO (LOOPBACK, .valid_parts = NM_META_SETTING_VALID_PARTS ( NM_META_SETTING_VALID_PART_ITEM (CONNECTION, TRUE), @@ -8802,6 +8854,7 @@ static const NMMetaSettingValidPartItem *const valid_settings_noslave[] = { NM_META_SETTING_VALID_PART_ITEM(IP4_CONFIG, FALSE), NM_META_SETTING_VALID_PART_ITEM(IP6_CONFIG, FALSE), NM_META_SETTING_VALID_PART_ITEM(HOSTNAME, FALSE), + NM_META_SETTING_VALID_PART_ITEM(LINK, FALSE), NM_META_SETTING_VALID_PART_ITEM(TC_CONFIG, FALSE), NM_META_SETTING_VALID_PART_ITEM(PROXY, FALSE), NULL, @@ -8809,11 +8862,15 @@ static const NMMetaSettingValidPartItem *const valid_settings_noslave[] = { static const NMMetaSettingValidPartItem *const valid_settings_slave_bond[] = { NM_META_SETTING_VALID_PART_ITEM(BOND_PORT, TRUE), + NM_META_SETTING_VALID_PART_ITEM(LINK, FALSE), + NM_META_SETTING_VALID_PART_ITEM(MATCH, FALSE), NULL, }; static const NMMetaSettingValidPartItem *const valid_settings_slave_bridge[] = { NM_META_SETTING_VALID_PART_ITEM(BRIDGE_PORT, TRUE), + NM_META_SETTING_VALID_PART_ITEM(LINK, FALSE), + NM_META_SETTING_VALID_PART_ITEM(MATCH, FALSE), NULL, }; @@ -8823,11 +8880,15 @@ static const NMMetaSettingValidPartItem *const valid_settings_slave_ovs_bridge[] }; static const NMMetaSettingValidPartItem *const valid_settings_slave_ovs_port[] = { + NM_META_SETTING_VALID_PART_ITEM(LINK, FALSE), + NM_META_SETTING_VALID_PART_ITEM(MATCH, FALSE), NM_META_SETTING_VALID_PART_ITEM(OVS_INTERFACE, FALSE), NULL, }; static const NMMetaSettingValidPartItem *const valid_settings_slave_team[] = { + NM_META_SETTING_VALID_PART_ITEM(LINK, FALSE), + NM_META_SETTING_VALID_PART_ITEM(MATCH, FALSE), NM_META_SETTING_VALID_PART_ITEM(TEAM_PORT, TRUE), NULL, }; diff --git a/src/libnmc-setting/settings-docs.h.in b/src/libnmc-setting/settings-docs.h.in index ece3cfc831..8c8741d166 100644 --- a/src/libnmc-setting/settings-docs.h.in +++ b/src/libnmc-setting/settings-docs.h.in @@ -443,6 +443,10 @@ #define DESCRIBE_DOC_NM_SETTING_HOSTNAME_FROM_DNS_LOOKUP N_("Whether the system hostname can be determined from reverse DNS lookup of addresses on this device. When set to NM_TERNARY_DEFAULT (-1), the value from global configuration is used. If the property doesn't have a value in the global configuration, NetworkManager assumes the value to be NM_TERNARY_TRUE (1).") #define DESCRIBE_DOC_NM_SETTING_HOSTNAME_ONLY_FROM_DEFAULT N_("If set to NM_TERNARY_TRUE (1), NetworkManager attempts to get the hostname via DHCPv4/DHCPv6 or reverse DNS lookup on this device only when the device has the default route for the given address family (IPv4/IPv6). If set to NM_TERNARY_FALSE (0), the hostname can be set from this device even if it doesn't have the default route. When set to NM_TERNARY_DEFAULT (-1), the value from global configuration is used. If the property doesn't have a value in the global configuration, NetworkManager assumes the value to be NM_TERNARY_FALSE (0).") #define DESCRIBE_DOC_NM_SETTING_HOSTNAME_PRIORITY N_("The relative priority of this connection to determine the system hostname. A lower numerical value is better (higher priority). A connection with higher priority is considered before connections with lower priority. If the value is zero, it can be overridden by a global value from NetworkManager configuration. If the property doesn't have a value in the global configuration, the value is assumed to be 100. Negative values have the special effect of excluding other connections with a greater numerical priority value; so in presence of at least one negative priority, only connections with the lowest priority value will be used to determine the hostname.") +#define DESCRIBE_DOC_NM_SETTING_LINK_GRO_MAX_SIZE N_("The maximum size of a packet built by the Generic Receive Offload stack for this device. The value must be between 0 and 4294967295. When set to -1, the existing value is preserved.") +#define DESCRIBE_DOC_NM_SETTING_LINK_GSO_MAX_SEGMENTS N_("The maximum segments of a Generic Segment Offload packet the device should accept. The value must be between 0 and 4294967295. When set to -1, the existing value is preserved.") +#define DESCRIBE_DOC_NM_SETTING_LINK_GSO_MAX_SIZE N_("The maximum size of a Generic Segment Offload packet the device should accept. The value must be between 0 and 4294967295. When set to -1, the existing value is preserved.") +#define DESCRIBE_DOC_NM_SETTING_LINK_TX_QUEUE_LENGTH N_("The size of the transmit queue for the device, in number of packets. The value must be between 0 and 4294967295. When set to -1, the existing value is preserved.") #define DESCRIBE_DOC_NM_SETTING_LOOPBACK_MTU N_("If non-zero, only transmit packets of the specified size or smaller, breaking larger packets up into multiple Ethernet frames.") #define DESCRIBE_DOC_NM_SETTING_OVS_EXTERNAL_IDS_DATA N_("A dictionary of key/value pairs with external-ids for OVS.") #define DESCRIBE_DOC_NM_SETTING_OVS_OTHER_CONFIG_DATA N_("A dictionary of key/value pairs with other_config settings for OVS. See also \"other_config\" in the \"ovs-vswitchd.conf.db\" manual for the keys that OVS supports.") diff --git a/src/nmcli/connections.c b/src/nmcli/connections.c index 36de6373e9..5de64727b3 100644 --- a/src/nmcli/connections.c +++ b/src/nmcli/connections.c @@ -1046,9 +1046,9 @@ const NmcMetaGenericInfo "," NM_SETTING_MACVLAN_SETTING_NAME "," NM_SETTING_VXLAN_SETTING_NAME \ "," NM_SETTING_VRF_SETTING_NAME "," NM_SETTING_WPAN_SETTING_NAME \ "," NM_SETTING_6LOWPAN_SETTING_NAME "," NM_SETTING_WIREGUARD_SETTING_NAME \ - "," NM_SETTING_PROXY_SETTING_NAME "," NM_SETTING_TC_CONFIG_SETTING_NAME \ - "," NM_SETTING_SRIOV_SETTING_NAME "," NM_SETTING_ETHTOOL_SETTING_NAME \ - "," NM_SETTING_OVS_DPDK_SETTING_NAME \ + "," NM_SETTING_LINK_SETTING_NAME "," NM_SETTING_PROXY_SETTING_NAME \ + "," NM_SETTING_TC_CONFIG_SETTING_NAME "," NM_SETTING_SRIOV_SETTING_NAME \ + "," NM_SETTING_ETHTOOL_SETTING_NAME "," NM_SETTING_OVS_DPDK_SETTING_NAME \ "," NM_SETTING_HOSTNAME_SETTING_NAME /* NM_SETTING_DUMMY_SETTING_NAME NM_SETTING_WIMAX_SETTING_NAME */ const NmcMetaGenericInfo *const nmc_fields_con_active_details_groups[] = { diff --git a/src/nmcli/gen-metadata-nm-settings-nmcli.xml.in b/src/nmcli/gen-metadata-nm-settings-nmcli.xml.in index 66815d2697..41d6c2bd13 100644 --- a/src/nmcli/gen-metadata-nm-settings-nmcli.xml.in +++ b/src/nmcli/gen-metadata-nm-settings-nmcli.xml.in @@ -776,6 +776,16 @@ <property name="token" description="Configure the token for draft-chown-6man-tokenised-ipv6-identifiers-02 IPv6 tokenized interface identifiers. Useful with eui64 addr-gen-mode." /> </setting> + <setting name="link" > + <property name="gso-max-segments" + description="The maximum segments of a Generic Segment Offload packet the device should accept. The value must be between 0 and 4294967295. When set to -1, the existing value is preserved." /> + <property name="gso-max-size" + description="The maximum size of a Generic Segment Offload packet the device should accept. The value must be between 0 and 4294967295. When set to -1, the existing value is preserved." /> + <property name="gro-max-size" + description="The maximum size of a packet built by the Generic Receive Offload stack for this device. The value must be between 0 and 4294967295. When set to -1, the existing value is preserved." /> + <property name="tx-queue-length" + description="The size of the transmit queue for the device, in number of packets. The value must be between 0 and 4294967295. When set to -1, the existing value is preserved." /> + </setting> <setting name="loopback" > <property name="mtu" alias="mtu" diff --git a/vapi/NM-1.0.metadata b/vapi/NM-1.0.metadata index 48df877b51..44e2674e70 100644 --- a/vapi/NM-1.0.metadata +++ b/vapi/NM-1.0.metadata @@ -36,6 +36,7 @@ SETTING_IP4_CONFIG_* parent="NM.SettingIP4Config" name="SETTIN SETTING_IP6_CONFIG_* parent="NM.SettingIP6Config" name="SETTING_IP6_CONFIG_(.+)" SETTING_IP_CONFIG_* parent="NM.SettingIPConfig" name="SETTING_IP_CONFIG_(.+)" SETTING_IP_TUNNEL_* parent="NM.SettingIPTunnel" name="SETTING_IP_TUNNEL_(.+)" +SETTING_LINK_* parent="NM.SettingLink" name="SETTING_LINK_(.+)" SETTING_LOOPBACK_* parent="NM.SettingLoopback" name="SETTING_LOOPBACK_(.+)" SETTING_MACSEC_* parent="NM.SettingMacsec" name="SETTING_MACSEC_(.+)" SETTING_MACVLAN_* parent="NM.SettingMacvlan" name="SETTING_MACVLAN_(.+)" |