Skip to content

Commit ba0dc5f

Browse files
jmberg-inteldavem330
authored andcommitted
netlink: allow sending extended ACK with cookie on success
Now that we have extended error reporting and a new message format for netlink ACK messages, also extend this to be able to return arbitrary cookie data on success. This will allow, for example, nl80211 to not send an extra message for cookies identifying newly created objects, but return those directly in the ACK message. The cookie data size is currently limited to 20 bytes (since Jamal talked about using SHA1 for identifiers.) Thanks to Jamal Hadi Salim for bringing up this idea during the discussions. Signed-off-by: Johannes Berg <[email protected]> Reviewed-by: Jiri Pirko <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent 7ab606d commit ba0dc5f

File tree

3 files changed

+33
-11
lines changed

3 files changed

+33
-11
lines changed

include/linux/netlink.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,15 +62,22 @@ netlink_kernel_create(struct net *net, int unit, struct netlink_kernel_cfg *cfg)
6262
return __netlink_kernel_create(net, unit, THIS_MODULE, cfg);
6363
}
6464

65+
/* this can be increased when necessary - don't expose to userland */
66+
#define NETLINK_MAX_COOKIE_LEN 20
67+
6568
/**
6669
* struct netlink_ext_ack - netlink extended ACK report struct
6770
* @_msg: message string to report - don't access directly, use
6871
* %NL_SET_ERR_MSG
6972
* @bad_attr: attribute with error
73+
* @cookie: cookie data to return to userspace (for success)
74+
* @cookie_len: actual cookie data length
7075
*/
7176
struct netlink_ext_ack {
7277
const char *_msg;
7378
const struct nlattr *bad_attr;
79+
u8 cookie[NETLINK_MAX_COOKIE_LEN];
80+
u8 cookie_len;
7481
};
7582

7683
/* Always use this macro, this allows later putting the

include/uapi/linux/netlink.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -122,13 +122,17 @@ struct nlmsgerr {
122122
* @NLMSGERR_ATTR_MSG: error message string (string)
123123
* @NLMSGERR_ATTR_OFFS: offset of the invalid attribute in the original
124124
* message, counting from the beginning of the header (u32)
125+
* @NLMSGERR_ATTR_COOKIE: arbitrary subsystem specific cookie to
126+
* be used - in the success case - to identify a created
127+
* object or operation or similar (binary)
125128
* @__NLMSGERR_ATTR_MAX: number of attributes
126129
* @NLMSGERR_ATTR_MAX: highest attribute number
127130
*/
128131
enum nlmsgerr_attrs {
129132
NLMSGERR_ATTR_UNUSED,
130133
NLMSGERR_ATTR_MSG,
131134
NLMSGERR_ATTR_OFFS,
135+
NLMSGERR_ATTR_COOKIE,
132136

133137
__NLMSGERR_ATTR_MAX,
134138
NLMSGERR_ATTR_MAX = __NLMSGERR_ATTR_MAX - 1

net/netlink/af_netlink.c

Lines changed: 22 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -2311,6 +2311,10 @@ void netlink_ack(struct sk_buff *in_skb, struct nlmsghdr *nlh, int err,
23112311
}
23122312
} else {
23132313
flags |= NLM_F_CAPPED;
2314+
2315+
if (nlk->flags & NETLINK_F_EXT_ACK &&
2316+
extack && extack->cookie_len)
2317+
tlvlen += nla_total_size(extack->cookie_len);
23142318
}
23152319

23162320
if (tlvlen)
@@ -2337,17 +2341,24 @@ void netlink_ack(struct sk_buff *in_skb, struct nlmsghdr *nlh, int err,
23372341
errmsg->error = err;
23382342
memcpy(&errmsg->msg, nlh, payload > sizeof(*errmsg) ? nlh->nlmsg_len : sizeof(*nlh));
23392343

2340-
if (err && nlk->flags & NETLINK_F_EXT_ACK && extack) {
2341-
if (extack->_msg)
2342-
WARN_ON(nla_put_string(skb, NLMSGERR_ATTR_MSG,
2343-
extack->_msg));
2344-
if (extack->bad_attr &&
2345-
!WARN_ON((u8 *)extack->bad_attr < in_skb->data ||
2346-
(u8 *)extack->bad_attr >= in_skb->data +
2347-
in_skb->len))
2348-
WARN_ON(nla_put_u32(skb, NLMSGERR_ATTR_OFFS,
2349-
(u8 *)extack->bad_attr -
2350-
in_skb->data));
2344+
if (nlk->flags & NETLINK_F_EXT_ACK && extack) {
2345+
if (err) {
2346+
if (extack->_msg)
2347+
WARN_ON(nla_put_string(skb, NLMSGERR_ATTR_MSG,
2348+
extack->_msg));
2349+
if (extack->bad_attr &&
2350+
!WARN_ON((u8 *)extack->bad_attr < in_skb->data ||
2351+
(u8 *)extack->bad_attr >= in_skb->data +
2352+
in_skb->len))
2353+
WARN_ON(nla_put_u32(skb, NLMSGERR_ATTR_OFFS,
2354+
(u8 *)extack->bad_attr -
2355+
in_skb->data));
2356+
} else {
2357+
if (extack->cookie_len)
2358+
WARN_ON(nla_put(skb, NLMSGERR_ATTR_COOKIE,
2359+
extack->cookie_len,
2360+
extack->cookie));
2361+
}
23512362
}
23522363

23532364
nlmsg_end(skb, rep);

0 commit comments

Comments
 (0)