]> git.karo-electronics.de Git - karo-tx-linux.git/blobdiff - net/netfilter/xt_conntrack.c
Merge branch 'master' of ssh+git://oss.sgi.com/oss/git/xfs/xfs
[karo-tx-linux.git] / net / netfilter / xt_conntrack.c
index 0b7139f3dd786b3b4fa9ac416ca20fb9fbfe47c4..fc581800698e6885ee9c6ccb71ccc4be6eb9f594 100644 (file)
@@ -129,7 +129,7 @@ conntrack_addrcmp(const union nf_inet_addr *kaddr,
 
 static inline bool
 conntrack_mt_origsrc(const struct nf_conn *ct,
-                     const struct xt_conntrack_mtinfo1 *info,
+                     const struct xt_conntrack_mtinfo2 *info,
                     u_int8_t family)
 {
        return conntrack_addrcmp(&ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.src.u3,
@@ -138,7 +138,7 @@ conntrack_mt_origsrc(const struct nf_conn *ct,
 
 static inline bool
 conntrack_mt_origdst(const struct nf_conn *ct,
-                     const struct xt_conntrack_mtinfo1 *info,
+                     const struct xt_conntrack_mtinfo2 *info,
                     u_int8_t family)
 {
        return conntrack_addrcmp(&ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.dst.u3,
@@ -147,7 +147,7 @@ conntrack_mt_origdst(const struct nf_conn *ct,
 
 static inline bool
 conntrack_mt_replsrc(const struct nf_conn *ct,
-                     const struct xt_conntrack_mtinfo1 *info,
+                     const struct xt_conntrack_mtinfo2 *info,
                     u_int8_t family)
 {
        return conntrack_addrcmp(&ct->tuplehash[IP_CT_DIR_REPLY].tuple.src.u3,
@@ -156,7 +156,7 @@ conntrack_mt_replsrc(const struct nf_conn *ct,
 
 static inline bool
 conntrack_mt_repldst(const struct nf_conn *ct,
-                     const struct xt_conntrack_mtinfo1 *info,
+                     const struct xt_conntrack_mtinfo2 *info,
                     u_int8_t family)
 {
        return conntrack_addrcmp(&ct->tuplehash[IP_CT_DIR_REPLY].tuple.dst.u3,
@@ -164,7 +164,7 @@ conntrack_mt_repldst(const struct nf_conn *ct,
 }
 
 static inline bool
-ct_proto_port_check(const struct xt_conntrack_mtinfo1 *info,
+ct_proto_port_check(const struct xt_conntrack_mtinfo2 *info,
                     const struct nf_conn *ct)
 {
        const struct nf_conntrack_tuple *tuple;
@@ -204,7 +204,7 @@ ct_proto_port_check(const struct xt_conntrack_mtinfo1 *info,
 static bool
 conntrack_mt(const struct sk_buff *skb, const struct xt_match_param *par)
 {
-       const struct xt_conntrack_mtinfo1 *info = par->matchinfo;
+       const struct xt_conntrack_mtinfo2 *info = par->matchinfo;
        enum ip_conntrack_info ctinfo;
        const struct nf_conn *ct;
        unsigned int statebit;
@@ -278,6 +278,16 @@ conntrack_mt(const struct sk_buff *skb, const struct xt_match_param *par)
        return true;
 }
 
+static bool
+conntrack_mt_v1(const struct sk_buff *skb, const struct xt_match_param *par)
+{
+       const struct xt_conntrack_mtinfo2 *const *info = par->matchinfo;
+       struct xt_match_param newpar = *par;
+
+       newpar.matchinfo = *info;
+       return conntrack_mt(skb, &newpar);
+}
+
 static bool conntrack_mt_check(const struct xt_mtchk_param *par)
 {
        if (nf_ct_l3proto_try_module_get(par->family) < 0) {
@@ -288,11 +298,45 @@ static bool conntrack_mt_check(const struct xt_mtchk_param *par)
        return true;
 }
 
+static bool conntrack_mt_check_v1(const struct xt_mtchk_param *par)
+{
+       struct xt_conntrack_mtinfo1 *info = par->matchinfo;
+       struct xt_conntrack_mtinfo2 *up;
+       int ret = conntrack_mt_check(par);
+
+       if (ret < 0)
+               return ret;
+
+       up = kmalloc(sizeof(*up), GFP_KERNEL);
+       if (up == NULL) {
+               nf_ct_l3proto_module_put(par->family);
+               return -ENOMEM;
+       }
+
+       /*
+        * The strategy here is to minimize the overhead of v1 matching,
+        * by prebuilding a v2 struct and putting the pointer into the
+        * v1 dataspace.
+        */
+       memcpy(up, info, offsetof(typeof(*info), state_mask));
+       up->state_mask  = info->state_mask;
+       up->status_mask = info->status_mask;
+       *(void **)info  = up;
+       return true;
+}
+
 static void conntrack_mt_destroy(const struct xt_mtdtor_param *par)
 {
        nf_ct_l3proto_module_put(par->family);
 }
 
+static void conntrack_mt_destroy_v1(const struct xt_mtdtor_param *par)
+{
+       struct xt_conntrack_mtinfo2 **info = par->matchinfo;
+       kfree(*info);
+       conntrack_mt_destroy(par);
+}
+
 #ifdef CONFIG_COMPAT
 struct compat_xt_conntrack_info
 {
@@ -363,6 +407,16 @@ static struct xt_match conntrack_mt_reg[] __read_mostly = {
                .revision   = 1,
                .family     = NFPROTO_UNSPEC,
                .matchsize  = sizeof(struct xt_conntrack_mtinfo1),
+               .match      = conntrack_mt_v1,
+               .checkentry = conntrack_mt_check_v1,
+               .destroy    = conntrack_mt_destroy_v1,
+               .me         = THIS_MODULE,
+       },
+       {
+               .name       = "conntrack",
+               .revision   = 2,
+               .family     = NFPROTO_UNSPEC,
+               .matchsize  = sizeof(struct xt_conntrack_mtinfo2),
                .match      = conntrack_mt,
                .checkentry = conntrack_mt_check,
                .destroy    = conntrack_mt_destroy,