diff options
author | Jakub Kicinski <kuba@kernel.org> | 2022-08-25 20:09:31 -0700 |
---|---|---|
committer | Paolo Abeni <pabeni@redhat.com> | 2022-08-30 12:20:43 +0200 |
commit | 690252f19f0e486abb8590b3a7a03d4e065d93d4 (patch) | |
tree | a656cf7a2cec54ed3ff0ff28df4c9176c0228763 /net/netlink/af_netlink.c | |
parent | 0c95cea24f30eb28d464c593d8fbd64cd305791b (diff) | |
download | lwn-690252f19f0e486abb8590b3a7a03d4e065d93d4.tar.gz lwn-690252f19f0e486abb8590b3a7a03d4e065d93d4.zip |
netlink: add support for ext_ack missing attributes
There is currently no way to report via extack in a structured way
that an attribute is missing. This leads to families resorting to
string messages.
Add a pair of attributes - @offset and @type for machine-readable
way of reporting missing attributes. The @offset points to the
nest which should have contained the attribute, @type is the
expected nla_type. The offset will be skipped if the attribute
is missing at the message level rather than inside a nest.
User space should be able to figure out which attribute enum
(AKA attribute space AKA attribute set) the nest pointed to by
@offset is using.
Reviewed-by: Johannes Berg <johannes@sipsolutions.net>
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
Diffstat (limited to 'net/netlink/af_netlink.c')
-rw-r--r-- | net/netlink/af_netlink.c | 12 |
1 files changed, 12 insertions, 0 deletions
diff --git a/net/netlink/af_netlink.c b/net/netlink/af_netlink.c index 7eae157c1625..f89ba302ac6e 100644 --- a/net/netlink/af_netlink.c +++ b/net/netlink/af_netlink.c @@ -2423,6 +2423,10 @@ netlink_ack_tlv_len(struct netlink_sock *nlk, int err, tlvlen += nla_total_size(sizeof(u32)); if (extack->policy) tlvlen += netlink_policy_dump_attr_size_estimate(extack->policy); + if (extack->miss_type) + tlvlen += nla_total_size(sizeof(u32)); + if (extack->miss_nest) + tlvlen += nla_total_size(sizeof(u32)); return tlvlen; } @@ -2449,6 +2453,14 @@ netlink_ack_tlv_fill(struct sk_buff *in_skb, struct sk_buff *skb, if (extack->policy) netlink_policy_dump_write_attr(skb, extack->policy, NLMSGERR_ATTR_POLICY); + if (extack->miss_type) + WARN_ON(nla_put_u32(skb, NLMSGERR_ATTR_MISS_TYPE, + extack->miss_type)); + if (extack->miss_nest && + !WARN_ON((u8 *)extack->miss_nest < in_skb->data || + (u8 *)extack->miss_nest > in_skb->data + in_skb->len)) + WARN_ON(nla_put_u32(skb, NLMSGERR_ATTR_MISS_NEST, + (u8 *)extack->miss_nest - (u8 *)nlh)); } void netlink_ack(struct sk_buff *in_skb, struct nlmsghdr *nlh, int err, |