From 9adafeddacb42e649e355b05c6f4e43e6c8507f0 Mon Sep 17 00:00:00 2001 From: Susant Sahani Date: Tue, 20 Feb 2024 18:42:20 +0530 Subject: [PATCH] netdev/macvlan: allow to set the broadcast queueing threshold Allow to set the broadcast queueing threshold on macvlan devices. This controls which multicast packets will be processed in a workqueue instead of inline. --- man/systemd.netdev.xml | 13 ++++ .../sd-netlink/netlink-types-rtnl.c | 1 + src/network/netdev/macvlan.c | 59 +++++++++++++++++++ src/network/netdev/macvlan.h | 2 + src/network/netdev/netdev-gperf.gperf | 1 + 5 files changed, 76 insertions(+) diff --git a/man/systemd.netdev.xml b/man/systemd.netdev.xml index 08da75f06fc..e941a39eb89 100644 --- a/man/systemd.netdev.xml +++ b/man/systemd.netdev.xml @@ -571,6 +571,19 @@ + + + BroadcastQueueThreshold= + + Controls the threshold for broadcast queueing of the macvlan device. Takes the special value + no, or an integer in the range 0…2147483647. When no is + specified, the broadcast queueing is disabled altogether. When an integer is specified, a multicast + address will be queued as broadcast if the number of devices using it is greater than the given + value. Defaults to unset, and the kernel default will be used. + + + + diff --git a/src/libsystemd/sd-netlink/netlink-types-rtnl.c b/src/libsystemd/sd-netlink/netlink-types-rtnl.c index 1fa88b1ca58..e39a75cfe47 100644 --- a/src/libsystemd/sd-netlink/netlink-types-rtnl.c +++ b/src/libsystemd/sd-netlink/netlink-types-rtnl.c @@ -308,6 +308,7 @@ static const NLAPolicy rtnl_link_info_data_macvlan_policies[] = { [IFLA_MACVLAN_MACADDR_COUNT] = BUILD_POLICY(U32), [IFLA_MACVLAN_BC_QUEUE_LEN] = BUILD_POLICY(U32), [IFLA_MACVLAN_BC_QUEUE_LEN_USED] = BUILD_POLICY(U32), + [IFLA_MACVLAN_BC_CUTOFF] = BUILD_POLICY(S32), }; static const NLAPolicy rtnl_link_info_data_tun_policies[] = { diff --git a/src/network/netdev/macvlan.c b/src/network/netdev/macvlan.c index 203807e3a56..85011e11de4 100644 --- a/src/network/netdev/macvlan.c +++ b/src/network/netdev/macvlan.c @@ -10,6 +10,11 @@ #include "networkd-network.h" #include "parse-util.h" +typedef enum BCQueueThreshold { + BC_QUEUE_THRESHOLD_UNDEF = INT32_MIN, + BC_QUEUE_THRESHOLD_DISABLE = -1, +} BCQueueThreshold; + DEFINE_CONFIG_PARSE_ENUM(config_parse_macvlan_mode, macvlan_mode, MacVlanMode, "Failed to parse macvlan mode"); static int netdev_macvlan_fill_message_create(NetDev *netdev, Link *link, sd_netlink_message *req) { @@ -62,6 +67,12 @@ static int netdev_macvlan_fill_message_create(NetDev *netdev, Link *link, sd_net return r; } + if (m->bc_queue_threshold != BC_QUEUE_THRESHOLD_UNDEF) { + r = sd_netlink_message_append_s32(req, IFLA_MACVLAN_BC_CUTOFF, m->bc_queue_threshold); + if (r < 0) + return r; + } + return 0; } @@ -96,6 +107,53 @@ int config_parse_macvlan_broadcast_queue_size( &m->bc_queue_length); } +int config_parse_macvlan_broadcast_queue_threshold( + const char *unit, + const char *filename, + unsigned line, + const char *section, + unsigned section_line, + const char *lvalue, + int ltype, + const char *rvalue, + void *data, + void *userdata) { + + assert(filename); + assert(lvalue); + assert(rvalue); + + int32_t v, *threshold = ASSERT_PTR(data); + int r; + + if (isempty(rvalue)) { + *threshold = BC_QUEUE_THRESHOLD_UNDEF; + return 0; + } + + if (streq(rvalue, "no")) { + *threshold = BC_QUEUE_THRESHOLD_DISABLE; + return 0; + } + + r = safe_atoi32(rvalue, &v); + if (r < 0) { + log_syntax(unit, LOG_WARNING, filename, line, r, + "Failed to parse %s=, ignoring assignment: %s", + lvalue, rvalue); + return 0; + } + if (v < 0) { + log_syntax(unit, LOG_WARNING, filename, line, 0, + "Invalid %s= value specified, ignoring assignment: %s", + lvalue, rvalue); + return 0; + } + + *threshold = v; + return 0; +} + static void macvlan_done(NetDev *netdev) { MacVlan *m = ASSERT_PTR(netdev)->kind == NETDEV_KIND_MACVLAN ? MACVLAN(netdev) : MACVTAP(netdev); @@ -107,6 +165,7 @@ static void macvlan_init(NetDev *netdev) { m->mode = _NETDEV_MACVLAN_MODE_INVALID; m->bc_queue_length = UINT32_MAX; + m->bc_queue_threshold = BC_QUEUE_THRESHOLD_UNDEF; } const NetDevVTable macvtap_vtable = { diff --git a/src/network/netdev/macvlan.h b/src/network/netdev/macvlan.h index c45fc4fd339..76b53a62eae 100644 --- a/src/network/netdev/macvlan.h +++ b/src/network/netdev/macvlan.h @@ -14,6 +14,7 @@ struct MacVlan { Set *match_source_mac; uint32_t bc_queue_length; + int32_t bc_queue_threshold; }; DEFINE_NETDEV_CAST(MACVLAN, MacVlan); @@ -23,3 +24,4 @@ extern const NetDevVTable macvtap_vtable; CONFIG_PARSER_PROTOTYPE(config_parse_macvlan_mode); CONFIG_PARSER_PROTOTYPE(config_parse_macvlan_broadcast_queue_size); +CONFIG_PARSER_PROTOTYPE(config_parse_macvlan_broadcast_queue_threshold); diff --git a/src/network/netdev/netdev-gperf.gperf b/src/network/netdev/netdev-gperf.gperf index eb28b9be540..1bac0c227d0 100644 --- a/src/network/netdev/netdev-gperf.gperf +++ b/src/network/netdev/netdev-gperf.gperf @@ -64,6 +64,7 @@ VLAN.IngressQOSMaps, config_parse_vlan_qos_maps, MACVLAN.Mode, config_parse_macvlan_mode, 0, offsetof(MacVlan, mode) MACVLAN.SourceMACAddress, config_parse_ether_addrs, 0, offsetof(MacVlan, match_source_mac) MACVLAN.BroadcastMulticastQueueLength, config_parse_macvlan_broadcast_queue_size, 0, offsetof(MacVlan, bc_queue_length) +MACVLAN.BroadcastQueueThreshold, config_parse_macvlan_broadcast_queue_threshold, 0, offsetof(MacVlan, bc_queue_threshold) MACVTAP.Mode, config_parse_macvlan_mode, 0, offsetof(MacVlan, mode) MACVTAP.SourceMACAddress, config_parse_ether_addrs, 0, offsetof(MacVlan, match_source_mac) IPVLAN.Mode, config_parse_ipvlan_mode, 0, offsetof(IPVlan, mode)