drivers/block/floppy.c: comment neatening and remove naked ;
[safe/jmp/linux-2.6] / net / netfilter / xt_conntrack.c
index 5cd58d7..ae66305 100644 (file)
 
 MODULE_LICENSE("GPL");
 MODULE_AUTHOR("Marc Boucher <marc@mbsi.ca>");
-MODULE_AUTHOR("Jan Engelhardt <jengelh@computergmbh.de>");
+MODULE_AUTHOR("Jan Engelhardt <jengelh@medozas.de>");
 MODULE_DESCRIPTION("Xtables: connection tracking state match");
 MODULE_ALIAS("ipt_conntrack");
 MODULE_ALIAS("ip6t_conntrack");
 
 static bool
-conntrack_mt_v0(const struct sk_buff *skb, const struct xt_match_param *par)
-{
-       const struct xt_conntrack_info *sinfo = par->matchinfo;
-       const struct nf_conn *ct;
-       enum ip_conntrack_info ctinfo;
-       unsigned int statebit;
-
-       ct = nf_ct_get(skb, &ctinfo);
-
-#define FWINV(bool, invflg) ((bool) ^ !!(sinfo->invflags & (invflg)))
-
-       if (ct == &nf_conntrack_untracked)
-               statebit = XT_CONNTRACK_STATE_UNTRACKED;
-       else if (ct)
-               statebit = XT_CONNTRACK_STATE_BIT(ctinfo);
-       else
-               statebit = XT_CONNTRACK_STATE_INVALID;
-
-       if (sinfo->flags & XT_CONNTRACK_STATE) {
-               if (ct) {
-                       if (test_bit(IPS_SRC_NAT_BIT, &ct->status))
-                               statebit |= XT_CONNTRACK_STATE_SNAT;
-                       if (test_bit(IPS_DST_NAT_BIT, &ct->status))
-                               statebit |= XT_CONNTRACK_STATE_DNAT;
-               }
-               if (FWINV((statebit & sinfo->statemask) == 0,
-                         XT_CONNTRACK_STATE))
-                       return false;
-       }
-
-       if (ct == NULL) {
-               if (sinfo->flags & ~XT_CONNTRACK_STATE)
-                       return false;
-               return true;
-       }
-
-       if (sinfo->flags & XT_CONNTRACK_PROTO &&
-           FWINV(nf_ct_protonum(ct) !=
-                 sinfo->tuple[IP_CT_DIR_ORIGINAL].dst.protonum,
-                 XT_CONNTRACK_PROTO))
-               return false;
-
-       if (sinfo->flags & XT_CONNTRACK_ORIGSRC &&
-           FWINV((ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.src.u3.ip &
-                  sinfo->sipmsk[IP_CT_DIR_ORIGINAL].s_addr) !=
-                 sinfo->tuple[IP_CT_DIR_ORIGINAL].src.ip,
-                 XT_CONNTRACK_ORIGSRC))
-               return false;
-
-       if (sinfo->flags & XT_CONNTRACK_ORIGDST &&
-           FWINV((ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.dst.u3.ip &
-                  sinfo->dipmsk[IP_CT_DIR_ORIGINAL].s_addr) !=
-                 sinfo->tuple[IP_CT_DIR_ORIGINAL].dst.ip,
-                 XT_CONNTRACK_ORIGDST))
-               return false;
-
-       if (sinfo->flags & XT_CONNTRACK_REPLSRC &&
-           FWINV((ct->tuplehash[IP_CT_DIR_REPLY].tuple.src.u3.ip &
-                  sinfo->sipmsk[IP_CT_DIR_REPLY].s_addr) !=
-                 sinfo->tuple[IP_CT_DIR_REPLY].src.ip,
-                 XT_CONNTRACK_REPLSRC))
-               return false;
-
-       if (sinfo->flags & XT_CONNTRACK_REPLDST &&
-           FWINV((ct->tuplehash[IP_CT_DIR_REPLY].tuple.dst.u3.ip &
-                  sinfo->dipmsk[IP_CT_DIR_REPLY].s_addr) !=
-                 sinfo->tuple[IP_CT_DIR_REPLY].dst.ip,
-                 XT_CONNTRACK_REPLDST))
-               return false;
-
-       if (sinfo->flags & XT_CONNTRACK_STATUS &&
-           FWINV((ct->status & sinfo->statusmask) == 0,
-                 XT_CONNTRACK_STATUS))
-               return false;
-
-       if(sinfo->flags & XT_CONNTRACK_EXPIRES) {
-               unsigned long expires = timer_pending(&ct->timeout) ?
-                                       (ct->timeout.expires - jiffies)/HZ : 0;
-
-               if (FWINV(!(expires >= sinfo->expires_min &&
-                           expires <= sinfo->expires_max),
-                         XT_CONNTRACK_EXPIRES))
-                       return false;
-       }
-       return true;
-#undef FWINV
-}
-
-static bool
 conntrack_addrcmp(const union nf_inet_addr *kaddr,
                   const union nf_inet_addr *uaddr,
                   const union nf_inet_addr *umask, unsigned int l3proto)
@@ -129,7 +40,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 +49,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 +58,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 +67,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 +75,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;
@@ -202,9 +113,10 @@ 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)
+conntrack_mt(const struct sk_buff *skb, const struct xt_match_param *par,
+             u16 state_mask, u16 status_mask)
 {
-       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;
@@ -225,7 +137,7 @@ conntrack_mt(const struct sk_buff *skb, const struct xt_match_param *par)
                        if (test_bit(IPS_DST_NAT_BIT, &ct->status))
                                statebit |= XT_CONNTRACK_STATE_DNAT;
                }
-               if (!!(info->state_mask & statebit) ^
+               if (!!(state_mask & statebit) ^
                    !(info->invert_flags & XT_CONNTRACK_STATE))
                        return false;
        }
@@ -238,22 +150,22 @@ conntrack_mt(const struct sk_buff *skb, const struct xt_match_param *par)
                return false;
 
        if (info->match_flags & XT_CONNTRACK_ORIGSRC)
-               if (conntrack_mt_origsrc(ct, info, par->match->family) ^
+               if (conntrack_mt_origsrc(ct, info, par->family) ^
                    !(info->invert_flags & XT_CONNTRACK_ORIGSRC))
                        return false;
 
        if (info->match_flags & XT_CONNTRACK_ORIGDST)
-               if (conntrack_mt_origdst(ct, info, par->match->family) ^
+               if (conntrack_mt_origdst(ct, info, par->family) ^
                    !(info->invert_flags & XT_CONNTRACK_ORIGDST))
                        return false;
 
        if (info->match_flags & XT_CONNTRACK_REPLSRC)
-               if (conntrack_mt_replsrc(ct, info, par->match->family) ^
+               if (conntrack_mt_replsrc(ct, info, par->family) ^
                    !(info->invert_flags & XT_CONNTRACK_REPLSRC))
                        return false;
 
        if (info->match_flags & XT_CONNTRACK_REPLDST)
-               if (conntrack_mt_repldst(ct, info, par->match->family) ^
+               if (conntrack_mt_repldst(ct, info, par->family) ^
                    !(info->invert_flags & XT_CONNTRACK_REPLDST))
                        return false;
 
@@ -261,7 +173,7 @@ conntrack_mt(const struct sk_buff *skb, const struct xt_match_param *par)
                return false;
 
        if ((info->match_flags & XT_CONNTRACK_STATUS) &&
-           (!!(info->status_mask & ct->status) ^
+           (!!(status_mask & ct->status) ^
            !(info->invert_flags & XT_CONNTRACK_STATUS)))
                return false;
 
@@ -278,102 +190,54 @@ conntrack_mt(const struct sk_buff *skb, const struct xt_match_param *par)
        return true;
 }
 
-static bool conntrack_mt_check(const struct xt_mtchk_param *par)
+static bool
+conntrack_mt_v1(const struct sk_buff *skb, const struct xt_match_param *par)
 {
-       if (nf_ct_l3proto_try_module_get(par->match->family) < 0) {
-               printk(KERN_WARNING "can't load conntrack support for "
-                                   "proto=%u\n", par->match->family);
-               return false;
-       }
-       return true;
-}
+       const struct xt_conntrack_mtinfo1 *info = par->matchinfo;
 
-static void conntrack_mt_destroy(const struct xt_mtdtor_param *par)
-{
-       nf_ct_l3proto_module_put(par->match->family);
+       return conntrack_mt(skb, par, info->state_mask, info->status_mask);
 }
 
-#ifdef CONFIG_COMPAT
-struct compat_xt_conntrack_info
+static bool
+conntrack_mt_v2(const struct sk_buff *skb, const struct xt_match_param *par)
 {
-       compat_uint_t                   statemask;
-       compat_uint_t                   statusmask;
-       struct ip_conntrack_old_tuple   tuple[IP_CT_DIR_MAX];
-       struct in_addr                  sipmsk[IP_CT_DIR_MAX];
-       struct in_addr                  dipmsk[IP_CT_DIR_MAX];
-       compat_ulong_t                  expires_min;
-       compat_ulong_t                  expires_max;
-       u_int8_t                        flags;
-       u_int8_t                        invflags;
-};
+       const struct xt_conntrack_mtinfo2 *info = par->matchinfo;
 
-static void conntrack_mt_compat_from_user_v0(void *dst, void *src)
+       return conntrack_mt(skb, par, info->state_mask, info->status_mask);
+}
+
+static bool conntrack_mt_check(const struct xt_mtchk_param *par)
 {
-       const struct compat_xt_conntrack_info *cm = src;
-       struct xt_conntrack_info m = {
-               .statemask      = cm->statemask,
-               .statusmask     = cm->statusmask,
-               .expires_min    = cm->expires_min,
-               .expires_max    = cm->expires_max,
-               .flags          = cm->flags,
-               .invflags       = cm->invflags,
-       };
-       memcpy(m.tuple, cm->tuple, sizeof(m.tuple));
-       memcpy(m.sipmsk, cm->sipmsk, sizeof(m.sipmsk));
-       memcpy(m.dipmsk, cm->dipmsk, sizeof(m.dipmsk));
-       memcpy(dst, &m, sizeof(m));
+       if (nf_ct_l3proto_try_module_get(par->family) < 0) {
+               printk(KERN_WARNING "can't load conntrack support for "
+                                   "proto=%u\n", par->family);
+               return false;
+       }
+       return true;
 }
 
-static int conntrack_mt_compat_to_user_v0(void __user *dst, void *src)
+static void conntrack_mt_destroy(const struct xt_mtdtor_param *par)
 {
-       const struct xt_conntrack_info *m = src;
-       struct compat_xt_conntrack_info cm = {
-               .statemask      = m->statemask,
-               .statusmask     = m->statusmask,
-               .expires_min    = m->expires_min,
-               .expires_max    = m->expires_max,
-               .flags          = m->flags,
-               .invflags       = m->invflags,
-       };
-       memcpy(cm.tuple, m->tuple, sizeof(cm.tuple));
-       memcpy(cm.sipmsk, m->sipmsk, sizeof(cm.sipmsk));
-       memcpy(cm.dipmsk, m->dipmsk, sizeof(cm.dipmsk));
-       return copy_to_user(dst, &cm, sizeof(cm)) ? -EFAULT : 0;
+       nf_ct_l3proto_module_put(par->family);
 }
-#endif
 
 static struct xt_match conntrack_mt_reg[] __read_mostly = {
        {
                .name       = "conntrack",
-               .revision   = 0,
-               .family     = NFPROTO_IPV4,
-               .match      = conntrack_mt_v0,
-               .checkentry = conntrack_mt_check,
-               .destroy    = conntrack_mt_destroy,
-               .matchsize  = sizeof(struct xt_conntrack_info),
-               .me         = THIS_MODULE,
-#ifdef CONFIG_COMPAT
-               .compatsize       = sizeof(struct compat_xt_conntrack_info),
-               .compat_from_user = conntrack_mt_compat_from_user_v0,
-               .compat_to_user   = conntrack_mt_compat_to_user_v0,
-#endif
-       },
-       {
-               .name       = "conntrack",
                .revision   = 1,
-               .family     = NFPROTO_IPV4,
+               .family     = NFPROTO_UNSPEC,
                .matchsize  = sizeof(struct xt_conntrack_mtinfo1),
-               .match      = conntrack_mt,
+               .match      = conntrack_mt_v1,
                .checkentry = conntrack_mt_check,
                .destroy    = conntrack_mt_destroy,
                .me         = THIS_MODULE,
        },
        {
                .name       = "conntrack",
-               .revision   = 1,
-               .family     = NFPROTO_IPV6,
-               .matchsize  = sizeof(struct xt_conntrack_mtinfo1),
-               .match      = conntrack_mt,
+               .revision   = 2,
+               .family     = NFPROTO_UNSPEC,
+               .matchsize  = sizeof(struct xt_conntrack_mtinfo2),
+               .match      = conntrack_mt_v2,
                .checkentry = conntrack_mt_check,
                .destroy    = conntrack_mt_destroy,
                .me         = THIS_MODULE,