platform: support changing link properties
Add support in platform for changing the newly introduced link properties.
This commit is contained in:
@@ -2582,6 +2582,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)
|
||||
{
|
||||
@@ -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);
|
||||
|
@@ -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]);
|
||||
|
||||
@@ -8347,6 +8361,32 @@ link_delete(NMPlatform *platform, int ifindex)
|
||||
return do_delete_object(platform, &obj_id, nlmsg);
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
@@ -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;
|
||||
|
@@ -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);
|
||||
|
@@ -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,
|
||||
|
Reference in New Issue
Block a user