[NETFILTER]: nf_conntrack: reduce masks to a subset of tuples
[powerpc.git] / net / netfilter / nf_conntrack_netlink.c
index c64f029..2064914 100644 (file)
@@ -6,18 +6,13 @@
  * (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 
+ * Initial connection tracking via netlink development funded and
  * generally made possible by Network Robots, Inc. (www.networkrobots.com)
  *
  * Further development of this code funded by Astaro AG (http://www.astaro.com)
  *
  * 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>
@@ -53,7 +49,7 @@ MODULE_LICENSE("GPL");
 static char __initdata version[] = "0.93";
 
 static inline int
-ctnetlink_dump_tuples_proto(struct sk_buff *skb, 
+ctnetlink_dump_tuples_proto(struct sk_buff *skb,
                            const struct nf_conntrack_tuple *tuple,
                            struct nf_conntrack_l4proto *l4proto)
 {
@@ -64,7 +60,7 @@ ctnetlink_dump_tuples_proto(struct sk_buff *skb,
 
        if (likely(l4proto->tuple_to_nfattr))
                ret = l4proto->tuple_to_nfattr(skb, tuple);
-       
+
        NFA_NEST_END(skb, nest_parms);
 
        return ret;
@@ -135,7 +131,7 @@ ctnetlink_dump_timeout(struct sk_buff *skb, const struct nf_conn *ct)
                timeout = 0;
        else
                timeout = htonl(timeout_l / HZ);
-       
+
        NFA_PUT(skb, CTA_TIMEOUT, sizeof(timeout), &timeout);
        return 0;
 
@@ -154,7 +150,7 @@ ctnetlink_dump_protoinfo(struct sk_buff *skb, const struct nf_conn *ct)
                nf_ct_l4proto_put(l4proto);
                return 0;
        }
-       
+
        nest_proto = NFA_NEST(skb, CTA_PROTOINFO);
 
        ret = l4proto->to_nfattr(skb, nest_proto, ct);
@@ -175,21 +171,29 @@ ctnetlink_dump_helpinfo(struct sk_buff *skb, const struct nf_conn *ct)
 {
        struct nfattr *nest_helper;
        const struct nf_conn_help *help = nfct_help(ct);
+       struct nf_conntrack_helper *helper;
 
-       if (!help || !help->helper)
+       if (!help)
                return 0;
-               
+
+       rcu_read_lock();
+       helper = rcu_dereference(help->helper);
+       if (!helper)
+               goto out;
+
        nest_helper = NFA_NEST(skb, CTA_HELP);
-       NFA_PUT(skb, CTA_HELP_NAME, strlen(help->helper->name), help->helper->name);
+       NFA_PUT(skb, CTA_HELP_NAME, strlen(helper->name), helper->name);
 
-       if (help->helper->to_nfattr)
-               help->helper->to_nfattr(skb, ct);
+       if (helper->to_nfattr)
+               helper->to_nfattr(skb, ct);
 
        NFA_NEST_END(skb, nest_helper);
-
+out:
+       rcu_read_unlock();
        return 0;
 
 nfattr_failure:
+       rcu_read_unlock();
        return -1;
 }
 
@@ -250,7 +254,7 @@ static inline int
 ctnetlink_dump_use(struct sk_buff *skb, const struct nf_conn *ct)
 {
        __be32 use = htonl(atomic_read(&ct->ct_general.use));
-       
+
        NFA_PUT(skb, CTA_USE, sizeof(u_int32_t), &use);
        return 0;
 
@@ -262,22 +266,20 @@ nfattr_failure:
 
 static int
 ctnetlink_fill_info(struct sk_buff *skb, u32 pid, u32 seq,
-                   int event, int nowait, 
+                   int event, int nowait,
                    const struct nf_conn *ct)
 {
        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));
        nfmsg  = NLMSG_DATA(nlh);
 
        nlh->nlmsg_flags    = (nowait && pid) ? NLM_F_MULTI : 0;
-       nfmsg->nfgen_family = 
+       nfmsg->nfgen_family =
                ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.src.l3num;
        nfmsg->version      = NFNETLINK_V0;
        nfmsg->res_id       = 0;
@@ -286,7 +288,7 @@ ctnetlink_fill_info(struct sk_buff *skb, u32 pid, u32 seq,
        if (ctnetlink_dump_tuples(skb, tuple(ct, IP_CT_DIR_ORIGINAL)) < 0)
                goto nfattr_failure;
        NFA_NEST_END(skb, nest_parms);
-       
+
        nest_parms = NFA_NEST(skb, CTA_TUPLE_REPLY);
        if (ctnetlink_dump_tuples(skb, tuple(ct, IP_CT_DIR_REPLY)) < 0)
                goto nfattr_failure;
@@ -303,18 +305,18 @@ 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;
 }
 
 #ifdef CONFIG_NF_CONNTRACK_EVENTS
 static int ctnetlink_conntrack_event(struct notifier_block *this,
-                                     unsigned long events, void *ptr)
+                                    unsigned long events, void *ptr)
 {
        struct nlmsghdr *nlh;
        struct nfgenmsg *nfmsg;
@@ -322,7 +324,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 */
@@ -364,7 +366,7 @@ static int ctnetlink_conntrack_event(struct notifier_block *this,
        if (ctnetlink_dump_tuples(skb, tuple(ct, IP_CT_DIR_ORIGINAL)) < 0)
                goto nfattr_failure;
        NFA_NEST_END(skb, nest_parms);
-       
+
        nest_parms = NFA_NEST(skb, CTA_TUPLE_REPLY);
        if (ctnetlink_dump_tuples(skb, tuple(ct, IP_CT_DIR_REPLY)) < 0)
                goto nfattr_failure;
@@ -383,16 +385,16 @@ static int ctnetlink_conntrack_event(struct notifier_block *this,
 
                if (events & IPCT_PROTOINFO
                    && ctnetlink_dump_protoinfo(skb, ct) < 0)
-                       goto nfattr_failure;
+                       goto nfattr_failure;
 
                if ((events & IPCT_HELPER || nfct_help(ct))
                    && ctnetlink_dump_helpinfo(skb, ct) < 0)
-                       goto nfattr_failure;
+                       goto nfattr_failure;
 
 #ifdef CONFIG_NF_CONNTRACK_MARK
                if ((events & IPCT_MARK || ct->mark)
                    && ctnetlink_dump_mark(skb, ct) < 0)
-                       goto nfattr_failure;
+                       goto nfattr_failure;
 #endif
 
                if (events & IPCT_COUNTER_FILLING &&
@@ -426,7 +428,7 @@ ctnetlink_dump_table(struct sk_buff *skb, struct netlink_callback *cb)
 {
        struct nf_conn *ct, *last;
        struct nf_conntrack_tuple_hash *h;
-       struct list_head *i;
+       struct hlist_node *n;
        struct nfgenmsg *nfmsg = NLMSG_DATA(cb->nlh);
        u_int8_t l3proto = nfmsg->nfgen_family;
 
@@ -434,8 +436,8 @@ ctnetlink_dump_table(struct sk_buff *skb, struct netlink_callback *cb)
        last = (struct nf_conn *)cb->args[1];
        for (; cb->args[0] < nf_conntrack_htable_size; cb->args[0]++) {
 restart:
-               list_for_each_prev(i, &nf_conntrack_hash[cb->args[0]]) {
-                       h = (struct nf_conntrack_tuple_hash *) i;
+               hlist_for_each_entry(h, n, &nf_conntrack_hash[cb->args[0]],
+                                    hnode) {
                        if (NF_CT_DIRECTION(h) != IP_CT_DIR_ORIGINAL)
                                continue;
                        ct = nf_ct_tuplehash_to_ctrack(h);
@@ -450,7 +452,7 @@ restart:
                                cb->args[1] = 0;
                        }
                        if (ctnetlink_fill_info(skb, NETLINK_CB(cb->skb).pid,
-                                               cb->nlh->nlmsg_seq,
+                                               cb->nlh->nlmsg_seq,
                                                IPCTNL_MSG_CT_NEW,
                                                1, ct) < 0) {
                                nf_conntrack_get(&ct->ct_general);
@@ -500,7 +502,7 @@ static const size_t cta_min_proto[CTA_PROTO_MAX] = {
 };
 
 static inline int
-ctnetlink_parse_tuple_proto(struct nfattr *attr, 
+ctnetlink_parse_tuple_proto(struct nfattr *attr,
                            struct nf_conntrack_tuple *tuple)
 {
        struct nfattr *tb[CTA_PROTO_MAX];
@@ -522,7 +524,7 @@ ctnetlink_parse_tuple_proto(struct nfattr *attr,
                ret = l4proto->nfattr_to_tuple(tb, tuple);
 
        nf_ct_l4proto_put(l4proto);
-       
+
        return ret;
 }
 
@@ -609,7 +611,7 @@ nfnetlink_parse_nat(struct nfattr *nat,
        int err;
 
        memset(range, 0, sizeof(*range));
-       
+
        nfattr_parse_nested(tb, CTA_NAT_MAX, nat);
 
        if (nfattr_bad_size(tb, CTA_NAT_MAX, cta_min_nat))
@@ -661,8 +663,8 @@ 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)
+ctnetlink_del_conntrack(struct sock *ctnl, struct sk_buff *skb,
+                       struct nlmsghdr *nlh, struct nfattr *cda[])
 {
        struct nf_conntrack_tuple_hash *h;
        struct nf_conntrack_tuple tuple;
@@ -687,19 +689,19 @@ ctnetlink_del_conntrack(struct sock *ctnl, struct sk_buff *skb,
        if (err < 0)
                return err;
 
-       h = nf_conntrack_find_get(&tuple, NULL);
+       h = nf_conntrack_find_get(&tuple);
        if (!h)
                return -ENOENT;
 
        ct = nf_ct_tuplehash_to_ctrack(h);
-       
+
        if (cda[CTA_ID-1]) {
                u_int32_t id = ntohl(*(__be32 *)NFA_DATA(cda[CTA_ID-1]));
                if (ct->id != id) {
                        nf_ct_put(ct);
                        return -ENOENT;
                }
-       }       
+       }
        if (del_timer(&ct->timeout))
                ct->timeout.function((unsigned long)ct);
 
@@ -709,8 +711,8 @@ 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)
+ctnetlink_get_conntrack(struct sock *ctnl, struct sk_buff *skb,
+                       struct nlmsghdr *nlh, struct nfattr *cda[])
 {
        struct nf_conntrack_tuple_hash *h;
        struct nf_conntrack_tuple tuple;
@@ -721,22 +723,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))
@@ -752,7 +744,7 @@ ctnetlink_get_conntrack(struct sock *ctnl, struct sk_buff *skb,
        if (err < 0)
                return err;
 
-       h = nf_conntrack_find_get(&tuple, NULL);
+       h = nf_conntrack_find_get(&tuple);
        if (!h)
                return -ENOENT;
 
@@ -765,7 +757,7 @@ ctnetlink_get_conntrack(struct sock *ctnl, struct sk_buff *skb,
                return -ENOMEM;
        }
 
-       err = ctnetlink_fill_info(skb2, NETLINK_CB(skb).pid, nlh->nlmsg_seq, 
+       err = ctnetlink_fill_info(skb2, NETLINK_CB(skb).pid, nlh->nlmsg_seq,
                                  IPCTNL_MSG_CT_NEW, 1, ct);
        nf_ct_put(ct);
        if (err <= 0)
@@ -793,12 +785,12 @@ ctnetlink_change_status(struct nf_conn *ct, struct nfattr *cda[])
        if (d & (IPS_EXPECTED|IPS_CONFIRMED|IPS_DYING))
                /* unchangeable */
                return -EINVAL;
-       
+
        if (d & IPS_SEEN_REPLY && !(status & IPS_SEEN_REPLY))
                /* SEEN_REPLY bit can only be set */
                return -EINVAL;
 
-       
+
        if (d & IPS_ASSURED && !(status & IPS_ASSURED))
                /* ASSURED bit can only be set */
                return -EINVAL;
@@ -846,11 +838,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,26 +846,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));
+                       rcu_assign_pointer(help->helper, NULL);
                }
+
+               return 0;
+       }
+
+       helper = __nf_conntrack_helper_find_byname(helpname);
+       if (helper == NULL)
+               return -EINVAL;
+
+       if (help) {
+               if (help->helper == helper)
+                       return 0;
+               if (help->helper)
+                       return -EBUSY;
+               /* need to zero data of old helper */
+               memset(&help->help, 0, sizeof(help->help));
+       } else {
+               help = nf_ct_ext_add(ct, NF_CT_EXT_HELPER, GFP_KERNEL);
+               if (help == NULL)
+                       return -ENOMEM;
        }
-       
-       help->helper = helper;
+
+       rcu_assign_pointer(help->helper, helper);
 
        return 0;
 }
@@ -887,7 +882,7 @@ static inline int
 ctnetlink_change_timeout(struct nf_conn *ct, struct nfattr *cda[])
 {
        u_int32_t timeout = ntohl(*(__be32 *)NFA_DATA(cda[CTA_TIMEOUT-1]));
-       
+
        if (!del_timer(&ct->timeout))
                return -ETIME;
 
@@ -955,17 +950,18 @@ ctnetlink_change_conntrack(struct nf_conn *ct, struct nfattr *cda[])
 }
 
 static int
-ctnetlink_create_conntrack(struct nfattr *cda[], 
+ctnetlink_create_conntrack(struct nfattr *cda[],
                           struct nf_conntrack_tuple *otuple,
                           struct nf_conntrack_tuple *rtuple)
 {
        struct nf_conn *ct;
        int err = -EINVAL;
        struct nf_conn_help *help;
+       struct nf_conntrack_helper *helper;
 
        ct = nf_conntrack_alloc(otuple, rtuple);
        if (ct == NULL || IS_ERR(ct))
-               return -ENOMEM; 
+               return -ENOMEM;
 
        if (!cda[CTA_TIMEOUT-1])
                goto err;
@@ -991,26 +987,34 @@ ctnetlink_create_conntrack(struct nfattr *cda[],
                ct->mark = ntohl(*(__be32 *)NFA_DATA(cda[CTA_MARK-1]));
 #endif
 
-       help = nfct_help(ct);
-       if (help)
-               help->helper = nf_ct_helper_find_get(rtuple);
+       helper = nf_ct_helper_find_get(rtuple);
+       if (helper) {
+               help = nf_ct_ext_add(ct, NF_CT_EXT_HELPER, GFP_KERNEL);
+               if (help == NULL) {
+                       nf_ct_helper_put(helper);
+                       err = -ENOMEM;
+                       goto err;
+               }
+               /* not in hash table yet so not strictly necessary */
+               rcu_assign_pointer(help->helper, helper);
+       }
 
        add_timer(&ct->timeout);
        nf_conntrack_hash_insert(ct);
 
-       if (help && help->helper)
-               nf_ct_helper_put(help->helper);
+       if (helper)
+               nf_ct_helper_put(helper);
 
        return 0;
 
-err:   
+err:
        nf_conntrack_free(ct);
        return err;
 }
 
-static int 
-ctnetlink_new_conntrack(struct sock *ctnl, struct sk_buff *skb, 
-                       struct nlmsghdr *nlh, struct nfattr *cda[], int *errp)
+static int
+ctnetlink_new_conntrack(struct sock *ctnl, struct sk_buff *skb,
+                       struct nlmsghdr *nlh, struct nfattr *cda[])
 {
        struct nf_conntrack_tuple otuple, rtuple;
        struct nf_conntrack_tuple_hash *h = NULL;
@@ -1065,9 +1069,9 @@ out_unlock:
        return err;
 }
 
-/*********************************************************************** 
- * EXPECT 
- ***********************************************************************/ 
+/***********************************************************************
+ * EXPECT
+ ***********************************************************************/
 
 static inline int
 ctnetlink_exp_dump_tuple(struct sk_buff *skb,
@@ -1075,7 +1079,7 @@ ctnetlink_exp_dump_tuple(struct sk_buff *skb,
                         enum ctattr_expect type)
 {
        struct nfattr *nest_parms = NFA_NEST(skb, type);
-       
+
        if (ctnetlink_dump_tuples(skb, tuple) < 0)
                goto nfattr_failure;
 
@@ -1085,27 +1089,34 @@ ctnetlink_exp_dump_tuple(struct sk_buff *skb,
 
 nfattr_failure:
        return -1;
-}                      
+}
 
 static inline int
 ctnetlink_exp_dump_mask(struct sk_buff *skb,
                        const struct nf_conntrack_tuple *tuple,
-                       const struct nf_conntrack_tuple *mask)
+                       const struct nf_conntrack_tuple_mask *mask)
 {
        int ret;
        struct nf_conntrack_l3proto *l3proto;
        struct nf_conntrack_l4proto *l4proto;
-       struct nfattr *nest_parms = NFA_NEST(skb, CTA_EXPECT_MASK);
+       struct nf_conntrack_tuple m;
+       struct nfattr *nest_parms;
+
+       memset(&m, 0xFF, sizeof(m));
+       m.src.u.all = mask->src.u.all;
+       memcpy(&m.src.u3, &mask->src.u3, sizeof(m.src.u3));
+
+       nest_parms = NFA_NEST(skb, CTA_EXPECT_MASK);
 
        l3proto = nf_ct_l3proto_find_get(tuple->src.l3num);
-       ret = ctnetlink_dump_tuples_ip(skb, mask, l3proto);
+       ret = ctnetlink_dump_tuples_ip(skb, &m, l3proto);
        nf_ct_l3proto_put(l3proto);
 
        if (unlikely(ret < 0))
                goto nfattr_failure;
 
        l4proto = nf_ct_l4proto_find_get(tuple->src.l3num, tuple->dst.protonum);
-       ret = ctnetlink_dump_tuples_proto(skb, mask, l4proto);
+       ret = ctnetlink_dump_tuples_proto(skb, &m, l4proto);
        nf_ct_l4proto_put(l4proto);
        if (unlikely(ret < 0))
                goto nfattr_failure;
@@ -1120,7 +1131,7 @@ nfattr_failure:
 
 static inline int
 ctnetlink_exp_dump_expect(struct sk_buff *skb,
-                          const struct nf_conntrack_expect *exp)
+                         const struct nf_conntrack_expect *exp)
 {
        struct nf_conn *master = exp->master;
        __be32 timeout = htonl((exp->timeout.expires - jiffies) / HZ);
@@ -1134,27 +1145,25 @@ ctnetlink_exp_dump_expect(struct sk_buff *skb,
                                 &master->tuplehash[IP_CT_DIR_ORIGINAL].tuple,
                                 CTA_EXPECT_MASTER) < 0)
                goto nfattr_failure;
-       
+
        NFA_PUT(skb, CTA_EXPECT_TIMEOUT, sizeof(timeout), &timeout);
        NFA_PUT(skb, CTA_EXPECT_ID, sizeof(u_int32_t), &id);
 
        return 0;
-       
+
 nfattr_failure:
        return -1;
 }
 
 static int
 ctnetlink_exp_fill_info(struct sk_buff *skb, u32 pid, u32 seq,
-                   int event, 
-                   int nowait, 
+                   int event,
+                   int nowait,
                    const struct nf_conntrack_expect *exp)
 {
        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 +1177,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 +1195,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) {
@@ -1237,7 +1246,7 @@ ctnetlink_exp_dump_table(struct sk_buff *skb, struct netlink_callback *cb)
        u_int8_t l3proto = nfmsg->nfgen_family;
 
        read_lock_bh(&nf_conntrack_lock);
-       list_for_each_prev(i, &nf_conntrack_expect_list) {
+       list_for_each_prev(i, &nf_ct_expect_list) {
                exp = (struct nf_conntrack_expect *) i;
                if (l3proto && exp->tuple.src.l3num != l3proto)
                        continue;
@@ -1250,7 +1259,7 @@ ctnetlink_exp_dump_table(struct sk_buff *skb, struct netlink_callback *cb)
                        goto out;
                *id = exp->id;
        }
-out:   
+out:
        read_unlock_bh(&nf_conntrack_lock);
 
        return skb->len;
@@ -1262,8 +1271,8 @@ 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)
+ctnetlink_get_expect(struct sock *ctnl, struct sk_buff *skb,
+                    struct nlmsghdr *nlh, struct nfattr *cda[])
 {
        struct nf_conntrack_tuple tuple;
        struct nf_conntrack_expect *exp;
@@ -1276,17 +1285,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])
@@ -1297,43 +1298,43 @@ ctnetlink_get_expect(struct sock *ctnl, struct sk_buff *skb,
        if (err < 0)
                return err;
 
-       exp = nf_conntrack_expect_find_get(&tuple);
+       exp = nf_ct_expect_find_get(&tuple);
        if (!exp)
                return -ENOENT;
 
        if (cda[CTA_EXPECT_ID-1]) {
                __be32 id = *(__be32 *)NFA_DATA(cda[CTA_EXPECT_ID-1]);
                if (exp->id != ntohl(id)) {
-                       nf_conntrack_expect_put(exp);
+                       nf_ct_expect_put(exp);
                        return -ENOENT;
                }
-       }       
+       }
 
        err = -ENOMEM;
        skb2 = alloc_skb(NLMSG_GOODSIZE, GFP_KERNEL);
        if (!skb2)
                goto out;
 
-       err = ctnetlink_exp_fill_info(skb2, NETLINK_CB(skb).pid, 
+       err = ctnetlink_exp_fill_info(skb2, NETLINK_CB(skb).pid,
                                      nlh->nlmsg_seq, IPCTNL_MSG_EXP_NEW,
                                      1, exp);
        if (err <= 0)
                goto free;
 
-       nf_conntrack_expect_put(exp);
+       nf_ct_expect_put(exp);
 
        return netlink_unicast(ctnl, skb2, NETLINK_CB(skb).pid, MSG_DONTWAIT);
 
 free:
        kfree_skb(skb2);
 out:
-       nf_conntrack_expect_put(exp);
+       nf_ct_expect_put(exp);
        return err;
 }
 
 static int
-ctnetlink_del_expect(struct sock *ctnl, struct sk_buff *skb, 
-                    struct nlmsghdr *nlh, struct nfattr *cda[], int *errp)
+ctnetlink_del_expect(struct sock *ctnl, struct sk_buff *skb,
+                    struct nlmsghdr *nlh, struct nfattr *cda[])
 {
        struct nf_conntrack_expect *exp, *tmp;
        struct nf_conntrack_tuple tuple;
@@ -1352,23 +1353,23 @@ ctnetlink_del_expect(struct sock *ctnl, struct sk_buff *skb,
                        return err;
 
                /* bump usage count to 2 */
-               exp = nf_conntrack_expect_find_get(&tuple);
+               exp = nf_ct_expect_find_get(&tuple);
                if (!exp)
                        return -ENOENT;
 
                if (cda[CTA_EXPECT_ID-1]) {
                        __be32 id = *(__be32 *)NFA_DATA(cda[CTA_EXPECT_ID-1]);
                        if (exp->id != ntohl(id)) {
-                               nf_conntrack_expect_put(exp);
+                               nf_ct_expect_put(exp);
                                return -ENOENT;
                        }
                }
 
                /* after list removal, usage count == 1 */
-               nf_conntrack_unexpect_related(exp);
-               /* have to put what we 'get' above. 
+               nf_ct_unexpect_related(exp);
+               /* have to put what we 'get' above.
                 * after this line usage count == 0 */
-               nf_conntrack_expect_put(exp);
+               nf_ct_expect_put(exp);
        } else if (cda[CTA_EXPECT_HELP_NAME-1]) {
                char *name = NFA_DATA(cda[CTA_EXPECT_HELP_NAME-1]);
 
@@ -1379,24 +1380,22 @@ ctnetlink_del_expect(struct sock *ctnl, struct sk_buff *skb,
                        write_unlock_bh(&nf_conntrack_lock);
                        return -EINVAL;
                }
-               list_for_each_entry_safe(exp, tmp, &nf_conntrack_expect_list,
-                                        list) {
+               list_for_each_entry_safe(exp, tmp, &nf_ct_expect_list, list) {
                        struct nf_conn_help *m_help = nfct_help(exp->master);
                        if (m_help->helper == h
                            && del_timer(&exp->timeout)) {
                                nf_ct_unlink_expect(exp);
-                               nf_conntrack_expect_put(exp);
+                               nf_ct_expect_put(exp);
                        }
                }
                write_unlock_bh(&nf_conntrack_lock);
        } else {
                /* This basically means we have to flush everything*/
                write_lock_bh(&nf_conntrack_lock);
-               list_for_each_entry_safe(exp, tmp, &nf_conntrack_expect_list,
-                                        list) {
+               list_for_each_entry_safe(exp, tmp, &nf_ct_expect_list, list) {
                        if (del_timer(&exp->timeout)) {
                                nf_ct_unlink_expect(exp);
-                               nf_conntrack_expect_put(exp);
+                               nf_ct_expect_put(exp);
                        }
                }
                write_unlock_bh(&nf_conntrack_lock);
@@ -1432,7 +1431,7 @@ ctnetlink_create_expect(struct nfattr *cda[], u_int8_t u3)
                return err;
 
        /* Look for master conntrack of this expectation */
-       h = nf_conntrack_find_get(&master_tuple, NULL);
+       h = nf_conntrack_find_get(&master_tuple);
        if (!h)
                return -ENOENT;
        ct = nf_ct_tuplehash_to_ctrack(h);
@@ -1444,30 +1443,31 @@ ctnetlink_create_expect(struct nfattr *cda[], u_int8_t u3)
                goto out;
        }
 
-       exp = nf_conntrack_expect_alloc(ct);
+       exp = nf_ct_expect_alloc(ct);
        if (!exp) {
                err = -ENOMEM;
                goto out;
        }
-       
+
        exp->expectfn = NULL;
        exp->flags = 0;
        exp->master = ct;
        exp->helper = NULL;
        memcpy(&exp->tuple, &tuple, sizeof(struct nf_conntrack_tuple));
-       memcpy(&exp->mask, &mask, sizeof(struct nf_conntrack_tuple));
+       memcpy(&exp->mask.src.u3, &mask.src.u3, sizeof(exp->mask.src.u3));
+       exp->mask.src.u.all = mask.src.u.all;
 
-       err = nf_conntrack_expect_related(exp);
-       nf_conntrack_expect_put(exp);
+       err = nf_ct_expect_related(exp);
+       nf_ct_expect_put(exp);
 
-out:   
+out:
        nf_ct_put(nf_ct_tuplehash_to_ctrack(h));
        return err;
 }
 
 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;
@@ -1488,7 +1488,7 @@ ctnetlink_new_expect(struct sock *ctnl, struct sk_buff *skb,
                return err;
 
        write_lock_bh(&nf_conntrack_lock);
-       exp = __nf_conntrack_expect_find(&tuple);
+       exp = __nf_ct_expect_find(&tuple);
 
        if (!exp) {
                write_unlock_bh(&nf_conntrack_lock);
@@ -1578,7 +1578,7 @@ static int __init ctnetlink_init(void)
                goto err_unreg_exp_subsys;
        }
 
-       ret = nf_conntrack_expect_register_notifier(&ctnl_notifier_exp);
+       ret = nf_ct_expect_register_notifier(&ctnl_notifier_exp);
        if (ret < 0) {
                printk("ctnetlink_init: cannot expect register notifier.\n");
                goto err_unreg_notifier;
@@ -1604,7 +1604,7 @@ static void __exit ctnetlink_exit(void)
        printk("ctnetlink: unregistering from nfnetlink.\n");
 
 #ifdef CONFIG_NF_CONNTRACK_EVENTS
-       nf_conntrack_expect_unregister_notifier(&ctnl_notifier_exp);
+       nf_ct_expect_unregister_notifier(&ctnl_notifier_exp);
        nf_conntrack_unregister_notifier(&ctnl_notifier);
 #endif