summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBeniamino Galvani <bgalvani@redhat.com>2023-02-16 16:37:54 +0100
committerBeniamino Galvani <bgalvani@redhat.com>2023-03-02 16:51:16 +0100
commite02fd76d9fcee5f2313be5e73d3a1e560760b8e0 (patch)
tree14858abd6350efa184a317bbf7627b315eb5e64d
parent39bfcf7aab973424433c8dcd0e175c75cc325c28 (diff)
downloadNetworkManager-e02fd76d9fcee5f2313be5e73d3a1e560760b8e0.tar.gz
platform: support changing link properties
Add support in platform for changing the newly introduced link properties.
-rw-r--r--src/core/platform/tests/test-link.c31
-rw-r--r--src/libnm-platform/nm-linux-platform.c44
-rw-r--r--src/libnm-platform/nm-platform.c50
-rw-r--r--src/libnm-platform/nm-platform.h26
4 files changed, 150 insertions, 1 deletions
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-platform/nm-linux-platform.c b/src/libnm-platform/nm-linux-platform.c
index 7833c2c5f2..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]);
@@ -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);
@@ -11170,6 +11210,8 @@ nm_linux_platform_class_init(NMLinuxPlatformClass *klass)
platform_class->link_change_extra = link_change_extra;
platform_class->link_delete = link_delete;
+ platform_class->link_change = link_change;
+
platform_class->link_refresh = link_refresh;
platform_class->link_set_netns = link_set_netns;
diff --git a/src/libnm-platform/nm-platform.c b/src/libnm-platform/nm-platform.c
index d36d5b9f4c..06c1f4a741 100644
--- a/src/libnm-platform/nm-platform.c
+++ b/src/libnm-platform/nm-platform.c
@@ -2133,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
@@ -6018,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,
@@ -6050,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,
@@ -7882,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,
@@ -7929,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 33571cfc50..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;
@@ -1097,6 +1114,10 @@ typedef struct {
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);
@@ -1930,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,