Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

docs: netlink: clarify the historical baggage of Netlink flags

nlmsg_flags are full of historical baggage, inconsistencies and
strangeness. Try to document it more thoroughly. Explain the meaning
of the ECHO flag (and while at it clarify the comment in the uAPI).
Handwave a little about the NEW request flags and how they make
sense on the surface but cater to really old paradigm before commands
were a thing.

I will add more notes on how to make use of ECHO and discouragement
for reuse of flags to the kernel-side documentation.

Link: https://lore.kernel.org/r/20220927212306.823862-1-kuba@kernel.org
Signed-off-by: Jakub Kicinski <kuba@kernel.org>

+49 -14
+48 -13
Documentation/userspace-api/netlink/intro.rst
··· 623 623 the same verbs in their message names (``GET``, ``SET``) the concept 624 624 of request types did not find wider adoption. 625 625 626 - Message flags 627 - ------------- 626 + Notification echo 627 + ----------------- 628 628 629 - The earlier section has already covered the basic request flags 630 - (``NLM_F_REQUEST``, ``NLM_F_ACK``, ``NLM_F_DUMP``) and the ``NLMSG_ERROR`` / 631 - ``NLMSG_DONE`` flags (``NLM_F_CAPPED``, ``NLM_F_ACK_TLVS``). 632 - Dump flags were also mentioned (``NLM_F_MULTI``, ``NLM_F_DUMP_INTR``). 629 + ``NLM_F_ECHO`` requests for notifications resulting from the request 630 + to be queued onto the requesting socket. This is useful to discover 631 + the impact of the request. 633 632 634 - Those are the main flags of note, with a small exception (of ``ieee802154``) 635 - Generic Netlink does not make use of other flags. If the protocol needs 636 - to communicate special constraints for a request it should use 637 - an attribute, not the flags in struct nlmsghdr. 633 + Note that this feature is not universally implemented. 638 634 639 - Classic Netlink, however, defined various flags for its ``GET``, ``NEW`` 640 - and ``DEL`` requests. Since request types have not been generalized 641 - the request type specific flags should not be used either. 635 + Other request-type-specific flags 636 + --------------------------------- 637 + 638 + Classic Netlink defined various flags for its ``GET``, ``NEW`` 639 + and ``DEL`` requests in the upper byte of nlmsg_flags in struct nlmsghdr. 640 + Since request types have not been generalized the request type specific 641 + flags are rarely used (and considered deprecated for new families). 642 + 643 + For ``GET`` - ``NLM_F_ROOT`` and ``NLM_F_MATCH`` are combined into 644 + ``NLM_F_DUMP``, and not used separately. ``NLM_F_ATOMIC`` is never used. 645 + 646 + For ``DEL`` - ``NLM_F_NONREC`` is only used by nftables and ``NLM_F_BULK`` 647 + only by FDB some operations. 648 + 649 + The flags for ``NEW`` are used most commonly in classic Netlink. Unfortunately, 650 + the meaning is not crystal clear. The following description is based on the 651 + best guess of the intention of the authors, and in practice all families 652 + stray from it in one way or another. ``NLM_F_REPLACE`` asks to replace 653 + an existing object, if no matching object exists the operation should fail. 654 + ``NLM_F_EXCL`` has the opposite semantics and only succeeds if object already 655 + existed. 656 + ``NLM_F_CREATE`` asks for the object to be created if it does not 657 + exist, it can be combined with ``NLM_F_REPLACE`` and ``NLM_F_EXCL``. 658 + 659 + A comment in the main Netlink uAPI header states:: 660 + 661 + 4.4BSD ADD NLM_F_CREATE|NLM_F_EXCL 662 + 4.4BSD CHANGE NLM_F_REPLACE 663 + 664 + True CHANGE NLM_F_CREATE|NLM_F_REPLACE 665 + Append NLM_F_CREATE 666 + Check NLM_F_EXCL 667 + 668 + which seems to indicate that those flags predate request types. 669 + ``NLM_F_REPLACE`` without ``NLM_F_CREATE`` was initially used instead 670 + of ``SET`` commands. 671 + ``NLM_F_EXCL`` without ``NLM_F_CREATE`` was used to check if object exists 672 + without creating it, presumably predating ``GET`` commands. 673 + 674 + ``NLM_F_APPEND`` indicates that if one key can have multiple objects associated 675 + with it (e.g. multiple next-hop objects for a route) the new object should be 676 + added to the list rather than replacing the entire list. 642 677 643 678 uAPI reference 644 679 ==============
+1 -1
include/uapi/linux/netlink.h
··· 62 62 #define NLM_F_REQUEST 0x01 /* It is request message. */ 63 63 #define NLM_F_MULTI 0x02 /* Multipart message, terminated by NLMSG_DONE */ 64 64 #define NLM_F_ACK 0x04 /* Reply with ack, with zero or error code */ 65 - #define NLM_F_ECHO 0x08 /* Echo this request */ 65 + #define NLM_F_ECHO 0x08 /* Receive resulting notifications */ 66 66 #define NLM_F_DUMP_INTR 0x10 /* Dump was inconsistent due to sequence change */ 67 67 #define NLM_F_DUMP_FILTERED 0x20 /* Dump was filtered as requested */ 68 68