mirror of
https://github.com/torvalds/linux.git
synced 2026-11-07 06:17:02 +01:00
netlink: policy: report the big endian attributes
Paolo pointed out an issue flagged at low priority by Sashiko -
we're currently not handling BE{16,32} attributes in policy dumps.
Commit 3f4285d741 ("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
Link: https://patch.msgid.link/20260912202401.141336-1-kuba@kernel.org
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
This commit is contained in:
parent
032ef43b9d
commit
b785f5c56f
|
|
@ -42,6 +42,16 @@ definitions:
|
|||
- 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 @@ attribute-sets:
|
|||
-
|
||||
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-
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -115,6 +115,7 @@ class Netlink:
|
|||
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 @@ class Netlink:
|
|||
'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 @@ class NlPolicy:
|
|||
|
||||
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 @@ def _genl_decode_policy(raw):
|
|||
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
|
||||
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user