|
@@ -2171,6 +2171,7 @@ EXPORT_SYMBOL(__nlmsg_put);
|
|
|
static int netlink_dump(struct sock *sk)
|
|
|
{
|
|
|
struct netlink_sock *nlk = nlk_sk(sk);
|
|
|
+ struct netlink_ext_ack extack = {};
|
|
|
struct netlink_callback *cb;
|
|
|
struct sk_buff *skb = NULL;
|
|
|
struct nlmsghdr *nlh;
|
|
@@ -2222,8 +2223,11 @@ static int netlink_dump(struct sock *sk)
|
|
|
skb_reserve(skb, skb_tailroom(skb) - alloc_size);
|
|
|
netlink_skb_set_owner_r(skb, sk);
|
|
|
|
|
|
- if (nlk->dump_done_errno > 0)
|
|
|
+ if (nlk->dump_done_errno > 0) {
|
|
|
+ cb->extack = &extack;
|
|
|
nlk->dump_done_errno = cb->dump(skb, cb);
|
|
|
+ cb->extack = NULL;
|
|
|
+ }
|
|
|
|
|
|
if (nlk->dump_done_errno > 0 ||
|
|
|
skb_tailroom(skb) < nlmsg_total_size(sizeof(nlk->dump_done_errno))) {
|
|
@@ -2246,6 +2250,12 @@ static int netlink_dump(struct sock *sk)
|
|
|
memcpy(nlmsg_data(nlh), &nlk->dump_done_errno,
|
|
|
sizeof(nlk->dump_done_errno));
|
|
|
|
|
|
+ if (extack._msg && nlk->flags & NETLINK_F_EXT_ACK) {
|
|
|
+ nlh->nlmsg_flags |= NLM_F_ACK_TLVS;
|
|
|
+ if (!nla_put_string(skb, NLMSGERR_ATTR_MSG, extack._msg))
|
|
|
+ nlmsg_end(skb, nlh);
|
|
|
+ }
|
|
|
+
|
|
|
if (sk_filter(sk, skb))
|
|
|
kfree_skb(skb);
|
|
|
else
|