]> git.kernelconcepts.de Git - karo-tx-linux.git/blobdiff - net/netfilter/nfnetlink.c
Merge tag 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/dledford/rdma
[karo-tx-linux.git] / net / netfilter / nfnetlink.c
index 80f5ecf2c3d7096f579361663da5d2e651eebd3e..92b05e188fd1f8adac7e363f59998ce8310ed9ed 100644 (file)
@@ -201,7 +201,8 @@ replay:
 
                if (nc->call_rcu) {
                        err = nc->call_rcu(net, net->nfnl, skb, nlh,
-                                          (const struct nlattr **)cda);
+                                          (const struct nlattr **)cda,
+                                          extack);
                        rcu_read_unlock();
                } else {
                        rcu_read_unlock();
@@ -211,7 +212,8 @@ replay:
                                err = -EAGAIN;
                        else if (nc->call)
                                err = nc->call(net, net->nfnl, skb, nlh,
-                                              (const struct nlattr **)cda);
+                                              (const struct nlattr **)cda,
+                                              extack);
                        else
                                err = -EINVAL;
                        nfnl_unlock(subsys_id);
@@ -226,9 +228,11 @@ struct nfnl_err {
        struct list_head        head;
        struct nlmsghdr         *nlh;
        int                     err;
+       struct netlink_ext_ack  extack;
 };
 
-static int nfnl_err_add(struct list_head *list, struct nlmsghdr *nlh, int err)
+static int nfnl_err_add(struct list_head *list, struct nlmsghdr *nlh, int err,
+                       const struct netlink_ext_ack *extack)
 {
        struct nfnl_err *nfnl_err;
 
@@ -238,6 +242,7 @@ static int nfnl_err_add(struct list_head *list, struct nlmsghdr *nlh, int err)
 
        nfnl_err->nlh = nlh;
        nfnl_err->err = err;
+       nfnl_err->extack = *extack;
        list_add_tail(&nfnl_err->head, list);
 
        return 0;
@@ -262,7 +267,8 @@ static void nfnl_err_deliver(struct list_head *err_list, struct sk_buff *skb)
        struct nfnl_err *nfnl_err, *next;
 
        list_for_each_entry_safe(nfnl_err, next, err_list, head) {
-               netlink_ack(skb, nfnl_err->nlh, nfnl_err->err, NULL);
+               netlink_ack(skb, nfnl_err->nlh, nfnl_err->err,
+                           &nfnl_err->extack);
                nfnl_err_del(nfnl_err);
        }
 }
@@ -280,6 +286,7 @@ static void nfnetlink_rcv_batch(struct sk_buff *skb, struct nlmsghdr *nlh,
        struct net *net = sock_net(skb->sk);
        const struct nfnetlink_subsystem *ss;
        const struct nfnl_callback *nc;
+       struct netlink_ext_ack extack;
        LIST_HEAD(err_list);
        u32 status;
        int err;
@@ -325,6 +332,7 @@ replay:
        while (skb->len >= nlmsg_total_size(0)) {
                int msglen, type;
 
+               memset(&extack, 0, sizeof(extack));
                nlh = nlmsg_hdr(skb);
                err = 0;
 
@@ -384,7 +392,8 @@ replay:
 
                        if (nc->call_batch) {
                                err = nc->call_batch(net, net->nfnl, skb, nlh,
-                                                    (const struct nlattr **)cda);
+                                                    (const struct nlattr **)cda,
+                                                    &extack);
                        }
 
                        /* The lock was released to autoload some module, we
@@ -402,7 +411,7 @@ ack:
                         * processed, this avoids that the same error is
                         * reported several times when replaying the batch.
                         */
-                       if (nfnl_err_add(&err_list, nlh, err) < 0) {
+                       if (nfnl_err_add(&err_list, nlh, err, &extack) < 0) {
                                /* We failed to enqueue an error, reset the
                                 * list of errors and send OOM to userspace
                                 * pointing to the batch header.