- patches.apparmor/remove_suid_new_case_in_2.6.22.diff: Merge fix.
[linux-flexiantxendom0-3.2.10.git] / net / netfilter / nf_conntrack_netlink.c
index 48f0531..d6d39e2 100644 (file)
@@ -6,9 +6,6 @@
  * (C) 2003 by Patrick Mchardy <kaber@trash.net>
  * (C) 2005-2006 by Pablo Neira Ayuso <pablo@eurodev.net>
  *
- * I've reworked this stuff to use attributes instead of conntrack
- * structures. 5.44 am. I need more tea. --pablo 05/07/11.
- *
  * Initial connection tracking via netlink development funded and
  * generally made possible by Network Robots, Inc. (www.networkrobots.com)
  *
@@ -16,8 +13,6 @@
  *
  * This software may be used and distributed according to the terms
  * of the GNU General Public License, incorporated herein by reference.
- *
- * Derived from ip_conntrack_netlink.c: Port by Pablo Neira Ayuso (05/11/14)
  */
 
 #include <linux/init.h>
@@ -33,6 +28,7 @@
 #include <linux/notifier.h>
 
 #include <linux/netfilter.h>
+#include <net/netlink.h>
 #include <net/netfilter/nf_conntrack.h>
 #include <net/netfilter/nf_conntrack_core.h>
 #include <net/netfilter/nf_conntrack_expect.h>
@@ -268,9 +264,7 @@ ctnetlink_fill_info(struct sk_buff *skb, u32 pid, u32 seq,
        struct nlmsghdr *nlh;
        struct nfgenmsg *nfmsg;
        struct nfattr *nest_parms;
-       unsigned char *b;
-
-       b = skb->tail;
+       unsigned char *b = skb_tail_pointer(skb);
 
        event |= NFNL_SUBSYS_CTNETLINK << 8;
        nlh    = NLMSG_PUT(skb, pid, seq, event, sizeof(struct nfgenmsg));
@@ -303,12 +297,12 @@ ctnetlink_fill_info(struct sk_buff *skb, u32 pid, u32 seq,
            ctnetlink_dump_use(skb, ct) < 0)
                goto nfattr_failure;
 
-       nlh->nlmsg_len = skb->tail - b;
+       nlh->nlmsg_len = skb_tail_pointer(skb) - b;
        return skb->len;
 
 nlmsg_failure:
 nfattr_failure:
-       skb_trim(skb, b - skb->data);
+       nlmsg_trim(skb, b);
        return -1;
 }
 
@@ -322,7 +316,7 @@ static int ctnetlink_conntrack_event(struct notifier_block *this,
        struct nf_conn *ct = (struct nf_conn *)ptr;
        struct sk_buff *skb;
        unsigned int type;
-       unsigned char *b;
+       sk_buff_data_t b;
        unsigned int flags = 0, group;
 
        /* ignore our fake conntrack entry */
@@ -662,7 +656,7 @@ static const size_t cta_min[CTA_MAX] = {
 
 static int
 ctnetlink_del_conntrack(struct sock *ctnl, struct sk_buff *skb,
-                       struct nlmsghdr *nlh, struct nfattr *cda[], int *errp)
+                       struct nlmsghdr *nlh, struct nfattr *cda[])
 {
        struct nf_conntrack_tuple_hash *h;
        struct nf_conntrack_tuple tuple;
@@ -710,7 +704,7 @@ ctnetlink_del_conntrack(struct sock *ctnl, struct sk_buff *skb,
 
 static int
 ctnetlink_get_conntrack(struct sock *ctnl, struct sk_buff *skb,
-                       struct nlmsghdr *nlh, struct nfattr *cda[], int *errp)
+                       struct nlmsghdr *nlh, struct nfattr *cda[])
 {
        struct nf_conntrack_tuple_hash *h;
        struct nf_conntrack_tuple tuple;
@@ -721,22 +715,12 @@ ctnetlink_get_conntrack(struct sock *ctnl, struct sk_buff *skb,
        int err = 0;
 
        if (nlh->nlmsg_flags & NLM_F_DUMP) {
-               u32 rlen;
-
 #ifndef CONFIG_NF_CT_ACCT
                if (NFNL_MSG_TYPE(nlh->nlmsg_type) == IPCTNL_MSG_CT_GET_CTRZERO)
                        return -ENOTSUPP;
 #endif
-               if ((*errp = netlink_dump_start(ctnl, skb, nlh,
-                                               ctnetlink_dump_table,
-                                               ctnetlink_done)) != 0)
-                       return -EINVAL;
-
-               rlen = NLMSG_ALIGN(nlh->nlmsg_len);
-               if (rlen > skb->len)
-                       rlen = skb->len;
-               skb_pull(skb, rlen);
-               return 0;
+               return netlink_dump_start(ctnl, skb, nlh, ctnetlink_dump_table,
+                                         ctnetlink_done);
        }
 
        if (nfattr_bad_size(cda, CTA_MAX, cta_min))
@@ -846,11 +830,6 @@ ctnetlink_change_helper(struct nf_conn *ct, struct nfattr *cda[])
        char *helpname;
        int err;
 
-       if (!help) {
-               /* FIXME: we need to reallocate and rehash */
-               return -EBUSY;
-       }
-
        /* don't change helper of sibling connections */
        if (ct->master)
                return -EINVAL;
@@ -859,25 +838,34 @@ ctnetlink_change_helper(struct nf_conn *ct, struct nfattr *cda[])
        if (err < 0)
                return err;
 
-       helper = __nf_conntrack_helper_find_byname(helpname);
-       if (!helper) {
-               if (!strcmp(helpname, ""))
-                       helper = NULL;
-               else
-                       return -EINVAL;
-       }
-
-       if (help->helper) {
-               if (!helper) {
+       if (!strcmp(helpname, "")) {
+               if (help && help->helper) {
                        /* we had a helper before ... */
                        nf_ct_remove_expectations(ct);
                        help->helper = NULL;
-               } else {
-                       /* need to zero data of old helper */
-                       memset(&help->help, 0, sizeof(help->help));
                }
+
+               return 0;
        }
 
+       if (!help) {
+               /* FIXME: we need to reallocate and rehash */
+               return -EBUSY;
+       }
+
+       helper = __nf_conntrack_helper_find_byname(helpname);
+       if (helper == NULL)
+               return -EINVAL;
+
+       if (help->helper == helper)
+               return 0;
+
+       if (help->helper)
+               /* we had a helper before ... */
+               nf_ct_remove_expectations(ct);
+
+       /* need to zero data of old helper */
+       memset(&help->help, 0, sizeof(help->help));
        help->helper = helper;
 
        return 0;
@@ -1010,7 +998,7 @@ err:
 
 static int
 ctnetlink_new_conntrack(struct sock *ctnl, struct sk_buff *skb,
-                       struct nlmsghdr *nlh, struct nfattr *cda[], int *errp)
+                       struct nlmsghdr *nlh, struct nfattr *cda[])
 {
        struct nf_conntrack_tuple otuple, rtuple;
        struct nf_conntrack_tuple_hash *h = NULL;
@@ -1152,9 +1140,7 @@ ctnetlink_exp_fill_info(struct sk_buff *skb, u32 pid, u32 seq,
 {
        struct nlmsghdr *nlh;
        struct nfgenmsg *nfmsg;
-       unsigned char *b;
-
-       b = skb->tail;
+       unsigned char *b = skb_tail_pointer(skb);
 
        event |= NFNL_SUBSYS_CTNETLINK_EXP << 8;
        nlh    = NLMSG_PUT(skb, pid, seq, event, sizeof(struct nfgenmsg));
@@ -1168,12 +1154,12 @@ ctnetlink_exp_fill_info(struct sk_buff *skb, u32 pid, u32 seq,
        if (ctnetlink_exp_dump_expect(skb, exp) < 0)
                goto nfattr_failure;
 
-       nlh->nlmsg_len = skb->tail - b;
+       nlh->nlmsg_len = skb_tail_pointer(skb) - b;
        return skb->len;
 
 nlmsg_failure:
 nfattr_failure:
-       skb_trim(skb, b - skb->data);
+       nlmsg_trim(skb, b);
        return -1;
 }
 
@@ -1186,7 +1172,7 @@ static int ctnetlink_expect_event(struct notifier_block *this,
        struct nf_conntrack_expect *exp = (struct nf_conntrack_expect *)ptr;
        struct sk_buff *skb;
        unsigned int type;
-       unsigned char *b;
+       sk_buff_data_t b;
        int flags = 0;
 
        if (events & IPEXP_NEW) {
@@ -1263,7 +1249,7 @@ static const size_t cta_min_exp[CTA_EXPECT_MAX] = {
 
 static int
 ctnetlink_get_expect(struct sock *ctnl, struct sk_buff *skb,
-                    struct nlmsghdr *nlh, struct nfattr *cda[], int *errp)
+                    struct nlmsghdr *nlh, struct nfattr *cda[])
 {
        struct nf_conntrack_tuple tuple;
        struct nf_conntrack_expect *exp;
@@ -1276,17 +1262,9 @@ ctnetlink_get_expect(struct sock *ctnl, struct sk_buff *skb,
                return -EINVAL;
 
        if (nlh->nlmsg_flags & NLM_F_DUMP) {
-               u32 rlen;
-
-               if ((*errp = netlink_dump_start(ctnl, skb, nlh,
-                                               ctnetlink_exp_dump_table,
-                                               ctnetlink_done)) != 0)
-                       return -EINVAL;
-               rlen = NLMSG_ALIGN(nlh->nlmsg_len);
-               if (rlen > skb->len)
-                       rlen = skb->len;
-               skb_pull(skb, rlen);
-               return 0;
+               return netlink_dump_start(ctnl, skb, nlh,
+                                         ctnetlink_exp_dump_table,
+                                         ctnetlink_done);
        }
 
        if (cda[CTA_EXPECT_MASTER-1])
@@ -1333,7 +1311,7 @@ out:
 
 static int
 ctnetlink_del_expect(struct sock *ctnl, struct sk_buff *skb,
-                    struct nlmsghdr *nlh, struct nfattr *cda[], int *errp)
+                    struct nlmsghdr *nlh, struct nfattr *cda[])
 {
        struct nf_conntrack_expect *exp, *tmp;
        struct nf_conntrack_tuple tuple;
@@ -1467,7 +1445,7 @@ out:
 
 static int
 ctnetlink_new_expect(struct sock *ctnl, struct sk_buff *skb,
-                    struct nlmsghdr *nlh, struct nfattr *cda[], int *errp)
+                    struct nlmsghdr *nlh, struct nfattr *cda[])
 {
        struct nf_conntrack_tuple tuple;
        struct nf_conntrack_expect *exp;