All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH net-next v2] netlink: policy: report the big endian attributes
@ 2026-09-12 20:24 Jakub Kicinski
  0 siblings, 0 replies; only message in thread
From: Jakub Kicinski @ 2026-09-12 20:24 UTC (permalink / raw)
  To: davem
  Cc: netdev, edumazet, pabeni, andrew+netdev, horms, Jakub Kicinski,
	donald.hunter, johannes, fw, pablo

Paolo pointed out an issue flagged at low priority by Sashiko -
we're currently not handling BE{16,32} attributes in policy dumps.

Commit 3f4285d741b4 ("netlink: specs: fou: local-v4 and peer-v4 are big
endian") flipped two fou attributes from NLA_U32 to NLA_BE32.
This made them vanish from the policy dump.

Follow the YAML spec format and treat byte order as a property of
a u16 / u32 rather than a type of its own. I don't have a strong
preference either way. The YNL format "feels cleaner" but the
kernel's separate type is easier when handling decoding.
I don't think that the policy type is actually usable for decoding
(since it only contains input types) so I went with YNL and added
the separate attr.

A missing byte order means host order, again like in the YAML specs.

Link: https://lore.kernel.org/ab90f970-0ebb-4c07-b7b1-db3f91395116@redhat.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
---
v2:
 - add netlink.h to Makefile.deps of nlctrl (fix tools build)
v1: https://lore.kernel.org/20260908235500.1642031-1-kuba@kernel.org

CC: donald.hunter@gmail.com
CC: johannes@sipsolutions.net
CC: fw@strlen.de
CC: pablo@netfilter.org
---
 Documentation/netlink/specs/nlctrl.yaml | 15 +++++++++++++++
 tools/net/ynl/Makefile.deps             |  3 ++-
 include/uapi/linux/netlink.h            | 14 ++++++++++++++
 net/netlink/policy.c                    | 16 ++++++++++++++--
 tools/net/ynl/pyynl/lib/ynl.py          |  8 +++++++-
 5 files changed, 52 insertions(+), 4 deletions(-)

diff --git a/Documentation/netlink/specs/nlctrl.yaml b/Documentation/netlink/specs/nlctrl.yaml
index 8b4472a6aa36..7e7c158e3e73 100644
--- a/Documentation/netlink/specs/nlctrl.yaml
+++ b/Documentation/netlink/specs/nlctrl.yaml
@@ -42,6 +42,16 @@ doc: |
       - bitfield32
       - sint
       - uint
+  -
+    name: policy-byte-order
+    doc: |
+      Byte order of an integer attribute. Zero is left unused so that it
+      can be taken to mean host byte order.
+    enum-name: netlink-policy-byte-order
+    type: enum
+    value-start: 1
+    entries:
+      - big-endian
 
 attribute-sets:
   -
@@ -152,6 +162,11 @@ doc: |
       -
         name: pad
         type: pad
+      -
+        name: byte-order
+        doc: Byte order of the attribute, absent means host byte order.
+        type: u32
+        enum: policy-byte-order
   -
     name: op-policy-attrs
     name-prefix: ctrl-attr-policy-
diff --git a/tools/net/ynl/Makefile.deps b/tools/net/ynl/Makefile.deps
index 2771375339d9..1e746e25e2bc 100644
--- a/tools/net/ynl/Makefile.deps
+++ b/tools/net/ynl/Makefile.deps
@@ -30,7 +30,8 @@ CFLAGS_mptcp_pm:=$(call get_hdr_inc,_LINUX_MPTCP_PM_H,mptcp_pm.h)
 CFLAGS_net_shaper:=$(call get_hdr_inc,_LINUX_NET_SHAPER_H,net_shaper.h)
 CFLAGS_netdev:=$(call get_hdr_inc,_LINUX_NETDEV_H,netdev.h)
 CFLAGS_nl80211:=$(call get_hdr_inc,__LINUX_NL802121_H,nl80211.h)
-CFLAGS_nlctrl:=$(call get_hdr_inc,__LINUX_GENERIC_NETLINK_H,genetlink.h)
+CFLAGS_nlctrl:=$(call get_hdr_inc,__LINUX_GENERIC_NETLINK_H,genetlink.h) \
+	$(call get_hdr_inc,__LINUX_NETLINK_H,netlink.h)
 CFLAGS_nfsd:=$(call get_hdr_inc,_LINUX_NFSD_NETLINK_H,nfsd_netlink.h)
 CFLAGS_ovpn:=$(call get_hdr_inc,_LINUX_OVPN_H,ovpn.h)
 CFLAGS_ovs_datapath:=$(call get_hdr_inc,__LINUX_OPENVSWITCH_H,openvswitch.h)
diff --git a/include/uapi/linux/netlink.h b/include/uapi/linux/netlink.h
index f87aaf28a649..82c41aeb4357 100644
--- a/include/uapi/linux/netlink.h
+++ b/include/uapi/linux/netlink.h
@@ -329,6 +329,17 @@ enum netlink_attribute_type {
 	NL_ATTR_TYPE_UINT,
 };
 
+/**
+ * enum netlink_policy_byte_order - byte order of an integer attribute
+ * @NL_POLICY_BYTE_ORDER_BIG_ENDIAN: big endian (network byte order)
+ *
+ * Zero is left unassigned so that it keeps meaning host byte order,
+ * which is also what a missing byte order means.
+ */
+enum netlink_policy_byte_order {
+	NL_POLICY_BYTE_ORDER_BIG_ENDIAN = 1,
+};
+
 /**
  * enum netlink_policy_type_attr - policy type attributes
  * @NL_POLICY_TYPE_ATTR_UNSPEC: unused
@@ -356,6 +367,8 @@ enum netlink_attribute_type {
  *	bitfield32 type (U32)
  * @NL_POLICY_TYPE_ATTR_MASK: mask of valid bits for unsigned integers (U64)
  * @NL_POLICY_TYPE_ATTR_PAD: pad attribute for 64-bit alignment
+ * @NL_POLICY_TYPE_ATTR_BYTE_ORDER: byte order of an integer attribute,
+ *	&enum netlink_policy_byte_order, absent if host byte order (U32)
  *
  * @__NL_POLICY_TYPE_ATTR_MAX: number of attributes
  * @NL_POLICY_TYPE_ATTR_MAX: highest attribute number
@@ -374,6 +387,7 @@ enum netlink_policy_type_attr {
 	NL_POLICY_TYPE_ATTR_BITFIELD32_MASK,
 	NL_POLICY_TYPE_ATTR_PAD,
 	NL_POLICY_TYPE_ATTR_MASK,
+	NL_POLICY_TYPE_ATTR_BYTE_ORDER,
 
 	/* keep last */
 	__NL_POLICY_TYPE_ATTR_MAX,
diff --git a/net/netlink/policy.c b/net/netlink/policy.c
index 08b006c48f06..574d44b7d518 100644
--- a/net/netlink/policy.c
+++ b/net/netlink/policy.c
@@ -234,6 +234,11 @@ int netlink_policy_dump_attr_size_estimate(const struct nla_policy *pt)
 		/* maximum is common, u64 min/max with padding */
 		return common +
 		       2 * (nla_attr_size(0) + nla_attr_size(sizeof(u64)));
+	case NLA_BE16:
+	case NLA_BE32:
+		/* same as the unsigned types, plus the byte order */
+		return common + nla_attr_size(sizeof(u32)) +
+		       2 * (nla_attr_size(0) + nla_attr_size(sizeof(u64)));
 	case NLA_BITFIELD32:
 		return common + nla_attr_size(sizeof(u32));
 	case NLA_STRING:
@@ -289,21 +294,28 @@ __netlink_policy_dump_write_attr(struct netlink_policy_dump_state *state,
 	case NLA_U16:
 	case NLA_U32:
 	case NLA_U64:
+	case NLA_BE16:
+	case NLA_BE32:
 	case NLA_UINT:
 	case NLA_MSECS: {
 		struct netlink_range_validation range;
 
 		if (pt->type == NLA_U8)
 			type = NL_ATTR_TYPE_U8;
-		else if (pt->type == NLA_U16)
+		else if (pt->type == NLA_U16 || pt->type == NLA_BE16)
 			type = NL_ATTR_TYPE_U16;
-		else if (pt->type == NLA_U32)
+		else if (pt->type == NLA_U32 || pt->type == NLA_BE32)
 			type = NL_ATTR_TYPE_U32;
 		else if (pt->type == NLA_U64)
 			type = NL_ATTR_TYPE_U64;
 		else
 			type = NL_ATTR_TYPE_UINT;
 
+		if ((pt->type == NLA_BE16 || pt->type == NLA_BE32) &&
+		    nla_put_u32(skb, NL_POLICY_TYPE_ATTR_BYTE_ORDER,
+				NL_POLICY_BYTE_ORDER_BIG_ENDIAN))
+			goto nla_put_failure;
+
 		if (pt->validation_type == NLA_VALIDATE_MASK) {
 			if (nla_put_u64_64bit(skb, NL_POLICY_TYPE_ATTR_MASK,
 					      pt->mask,
diff --git a/tools/net/ynl/pyynl/lib/ynl.py b/tools/net/ynl/pyynl/lib/ynl.py
index 8682bf588e1f..fb5acb8acded 100644
--- a/tools/net/ynl/pyynl/lib/ynl.py
+++ b/tools/net/ynl/pyynl/lib/ynl.py
@@ -115,6 +115,7 @@ from .nlspec import SpecFamily
     NL_POLICY_TYPE_ATTR_BITFIELD32_MASK = 10
     NL_POLICY_TYPE_ATTR_PAD = 11
     NL_POLICY_TYPE_ATTR_MASK = 12
+    NL_POLICY_TYPE_ATTR_BYTE_ORDER = 13
 
     AttrType = Enum('AttrType', ['flag', 'u8', 'u16', 'u32', 'u64',
                                   's8', 's16', 's32', 's64',
@@ -122,6 +123,8 @@ from .nlspec import SpecFamily
                                   'nested', 'nested-array',
                                   'bitfield32', 'sint', 'uint'])
 
+    ByteOrder = Enum('ByteOrder', ['big-endian'], start=1)
+
 class NlError(Exception):
     def __init__(self, nl_msg):
         self.nl_msg = nl_msg
@@ -158,7 +161,7 @@ from .nlspec import SpecFamily
 
     Each policy entry always has a 'type' attribute (e.g. u32, string,
     nested). Optional attributes depending on the 'type': min-value,
-    max-value, min-length, max-length, mask.
+    max-value, min-length, max-length, mask, byte-order.
 
     Policies can form infinite nesting loops. These loops are trimmed
     when policy is converted to a dict with pol.to_dict().
@@ -454,6 +457,9 @@ from .nlspec import SpecFamily
             policy['bitfield32-mask'] = attr.as_scalar('u32')
         elif attr.type == Netlink.NL_POLICY_TYPE_ATTR_MASK:
             policy['mask'] = attr.as_scalar('u64')
+        elif attr.type == Netlink.NL_POLICY_TYPE_ATTR_BYTE_ORDER:
+            byte_order = attr.as_scalar('u32')
+            policy['byte-order'] = Netlink.ByteOrder(byte_order).name
     return policy
 
 
-- 
2.55.0


^ permalink raw reply related	[flat|nested] only message in thread

only message in thread, other threads:[~2026-09-12 20:24 UTC | newest]

Thread overview: (only message) (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-09-12 20:24 [PATCH net-next v2] netlink: policy: report the big endian attributes Jakub Kicinski

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.