Messages in this thread | | | From | Alexander Lobakin <> | Subject | [PATCH net-next 0/4] netlink: add 'bitmap' attribute type and API | Date | Thu, 21 Jul 2022 17:59:46 +0200 |
| |
Add a new type of Netlink attribute -- bitmap.
Lots of different bitfields in the kernel grow through time, sometimes significantly. They can consume a u8 at fist, then require 16 bits, 32... To support such bitfields without rewriting code each time, kernel have bitmaps. For now, that is purely in-kernel type and API, and to communicate with userspace, they need to be converted to some primitive at first (e.g. __u32 etc.), dealing with that sometimes bitfields will run out of the size set for the corresponding Netlink attribute. Those can be netdev features, linkmodes and so on. Internally, in-kernel bitmaps are represented as arrays of unsigned longs. This provides optimal performance and memory usage; however, bitness dependent types can't be used to communicate between kernel and userspace -- for example, userapp can be 32-bit on a 64-bit system. So, to provide reliable communication data type, 64-bit arrays are now used. Netlink core takes care of converting them from/to unsigned longs when sending or receiving Netlink messages; although, on LE and 64-bit systems conversion is a no-op. They also can have explicit byteorder -- core code also handles this (both kernel and userspace must know in advance the byteorder of a particular attribute), as well as cases when the userspace and the kernel assume different number of bits (-> different number of u64s) for an attribute.
Basic consumer functions/macros are: * nla_put_bitmap and nla_get_bitmap families -- to easily put a bitmap to an skb or get it from a received message (only pointer to an unsigned long bitmap and the number of bits in it are needed), with optional explicit byteorder; * nla_total_size_bitmap() -- to provide estimate size in bytes to Netlink needed to store a bitmap; * {,__}NLA_POLICY_BITMAP() -- to declare a Netlink policy for a bitmap attribute.
Netlink policy for a bitmap can have an optional bitmap mask of bits supported by the code -- for example, to filter out obsolete bits removed some time ago. Without it, Netlink will make sure no bits past the passed number are set. Both variants can be requested from the userspace and the kernel will put a mask into a new policy attribute (%NL_POLICY_TYPE_ATTR_BITMAP_MASK). BTW, Ethtool bitsets provide similar functionality, but it operates with u32s (u64 is more convenient and optimal on most platforms) and Netlink bitmaps is a generic interface providing policies and data verification (Ethtool bitsets are declared simply as %NLA_BINARY), generic getters/setters etc.
An example of using this API can be found in my IP tunnel tree[0] (planned for submission later), the actual average number of locs to start both sending and receiving bitmaps in one subsys is ~10[1]. And it looks like that some of the already existing APIs could be later converted to Netlink bitmaps or expanded as well.
[0] https://github.com/alobakin/linux/commits/ip_tunnel [1] https://github.com/alobakin/linux/commit/26d2f2cf13fd
Alexander Lobakin (4): bitmap: add converting from/to 64-bit arrays of explicit byteorder bitmap: add a couple more helpers to work with arrays of u64s lib/test_bitmap: cover explicitly byteordered arr64s netlink: add 'bitmap' attribute type (%NL_ATTR_TYPE_BITMAP / %NLA_BITMAP)
include/linux/bitmap.h | 80 ++++++++++++++++-- include/net/netlink.h | 159 ++++++++++++++++++++++++++++++++++- include/uapi/linux/netlink.h | 5 ++ lib/bitmap.c | 143 +++++++++++++++++++++++++++---- lib/nlattr.c | 43 +++++++++- lib/test_bitmap.c | 22 +++-- net/netlink/policy.c | 44 ++++++++++ 7 files changed, 461 insertions(+), 35 deletions(-)
base-commit: 3a2ba42cbd0b669ce3837ba400905f93dd06c79f --- Targeted for net-next, but uses base-commit from the bitmap tree (a merge will be needed) and the API is for kernel-wide/generic usage rather than networking-specific. -- 2.36.1
| |