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

Configure Feed

Select the types of activity you want to include in your feed.

tools/net/ynl: Add extack policy attribute decoding

The NLMSGERR_ATTR_POLICY extack attribute has been ignored by ynl up to
now. Extend extack decoding to include _POLICY and the nested
NL_POLICY_TYPE_ATTR_* attributes.

For example:

./tools/net/ynl/cli.py \
--spec Documentation/netlink/specs/rt_link.yaml \
--create --do newlink --json '{
"ifname": "12345678901234567890",
"linkinfo": {"kind": "bridge"}
}'
Netlink error: Numerical result out of range
nl_len = 104 (88) nl_flags = 0x300 nl_type = 2
error: -34 extack: {'msg': 'Attribute failed policy validation',
'policy': {'max-length': 15, 'type': 'string'}, 'bad-attr': '.ifname'}

Signed-off-by: Donald Hunter <donald.hunter@gmail.com>
Link: https://lore.kernel.org/r/20240328155636.64688-1-donald.hunter@gmail.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>

authored by

Donald Hunter and committed by
Jakub Kicinski
bd3ce405 730fffce

+46
+46
tools/net/ynl/lib/ynl.py
··· 1 1 # SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause 2 2 3 3 from collections import namedtuple 4 + from enum import Enum 4 5 import functools 5 6 import os 6 7 import random ··· 77 76 NLMSGERR_ATTR_MISS_TYPE = 5 78 77 NLMSGERR_ATTR_MISS_NEST = 6 79 78 79 + # Policy types 80 + NL_POLICY_TYPE_ATTR_TYPE = 1 81 + NL_POLICY_TYPE_ATTR_MIN_VALUE_S = 2 82 + NL_POLICY_TYPE_ATTR_MAX_VALUE_S = 3 83 + NL_POLICY_TYPE_ATTR_MIN_VALUE_U = 4 84 + NL_POLICY_TYPE_ATTR_MAX_VALUE_U = 5 85 + NL_POLICY_TYPE_ATTR_MIN_LENGTH = 6 86 + NL_POLICY_TYPE_ATTR_MAX_LENGTH = 7 87 + NL_POLICY_TYPE_ATTR_POLICY_IDX = 8 88 + NL_POLICY_TYPE_ATTR_POLICY_MAXTYPE = 9 89 + NL_POLICY_TYPE_ATTR_BITFIELD32_MASK = 10 90 + NL_POLICY_TYPE_ATTR_PAD = 11 91 + NL_POLICY_TYPE_ATTR_MASK = 12 92 + 93 + AttrType = Enum('AttrType', ['flag', 'u8', 'u16', 'u32', 'u64', 94 + 's8', 's16', 's32', 's64', 95 + 'binary', 'string', 'nul-string', 96 + 'nested', 'nested-array', 97 + 'bitfield32', 'sint', 'uint']) 80 98 81 99 class NlError(Exception): 82 100 def __init__(self, nl_msg): ··· 218 198 self.extack['miss-nest'] = extack.as_scalar('u32') 219 199 elif extack.type == Netlink.NLMSGERR_ATTR_OFFS: 220 200 self.extack['bad-attr-offs'] = extack.as_scalar('u32') 201 + elif extack.type == Netlink.NLMSGERR_ATTR_POLICY: 202 + self.extack['policy'] = self._decode_policy(extack.raw) 221 203 else: 222 204 if 'unknown' not in self.extack: 223 205 self.extack['unknown'] = [] ··· 235 213 if 'doc' in spec: 236 214 desc += f" ({spec['doc']})" 237 215 self.extack['miss-type'] = desc 216 + 217 + def _decode_policy(self, raw): 218 + policy = {} 219 + for attr in NlAttrs(raw): 220 + if attr.type == Netlink.NL_POLICY_TYPE_ATTR_TYPE: 221 + type = attr.as_scalar('u32') 222 + policy['type'] = Netlink.AttrType(type).name 223 + elif attr.type == Netlink.NL_POLICY_TYPE_ATTR_MIN_VALUE_S: 224 + policy['min-value'] = attr.as_scalar('s64') 225 + elif attr.type == Netlink.NL_POLICY_TYPE_ATTR_MAX_VALUE_S: 226 + policy['max-value'] = attr.as_scalar('s64') 227 + elif attr.type == Netlink.NL_POLICY_TYPE_ATTR_MIN_VALUE_U: 228 + policy['min-value'] = attr.as_scalar('u64') 229 + elif attr.type == Netlink.NL_POLICY_TYPE_ATTR_MAX_VALUE_U: 230 + policy['max-value'] = attr.as_scalar('u64') 231 + elif attr.type == Netlink.NL_POLICY_TYPE_ATTR_MIN_LENGTH: 232 + policy['min-length'] = attr.as_scalar('u32') 233 + elif attr.type == Netlink.NL_POLICY_TYPE_ATTR_MAX_LENGTH: 234 + policy['max-length'] = attr.as_scalar('u32') 235 + elif attr.type == Netlink.NL_POLICY_TYPE_ATTR_BITFIELD32_MASK: 236 + policy['bitfield32-mask'] = attr.as_scalar('u32') 237 + elif attr.type == Netlink.NL_POLICY_TYPE_ATTR_MASK: 238 + policy['mask'] = attr.as_scalar('u64') 239 + return policy 238 240 239 241 def cmd(self): 240 242 return self.nl_type