diff options
author | Beniamino Galvani <bgalvani@redhat.com> | 2023-02-16 16:37:54 +0100 |
---|---|---|
committer | Beniamino Galvani <bgalvani@redhat.com> | 2023-03-02 16:51:16 +0100 |
commit | e02fd76d9fcee5f2313be5e73d3a1e560760b8e0 (patch) | |
tree | 14858abd6350efa184a317bbf7627b315eb5e64d | |
parent | 39bfcf7aab973424433c8dcd0e175c75cc325c28 (diff) | |
download | NetworkManager-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.c | 31 | ||||
-rw-r--r-- | src/libnm-platform/nm-linux-platform.c | 44 | ||||
-rw-r--r-- | src/libnm-platform/nm-platform.c | 50 | ||||
-rw-r--r-- | src/libnm-platform/nm-platform.h | 26 |
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, |