linux/include/net/netfilter/nf_conntrack_tuple.h
<<
>>
Prefs
   1/*
   2 * Definitions and Declarations for tuple.
   3 *
   4 * 16 Dec 2003: Yasuyuki Kozakai @USAGI <yasuyuki.kozakai@toshiba.co.jp>
   5 *      - generalize L3 protocol dependent part.
   6 *
   7 * Derived from include/linux/netfiter_ipv4/ip_conntrack_tuple.h
   8 */
   9
  10#ifndef _NF_CONNTRACK_TUPLE_H
  11#define _NF_CONNTRACK_TUPLE_H
  12
  13#include <linux/netfilter/nf_conntrack_tuple_common.h>
  14
  15/* A `tuple' is a structure containing the information to uniquely
  16  identify a connection.  ie. if two packets have the same tuple, they
  17  are in the same connection; if not, they are not.
  18
  19  We divide the structure along "manipulatable" and
  20  "non-manipulatable" lines, for the benefit of the NAT code.
  21*/
  22
  23#define NF_CT_TUPLE_L3SIZE      4
  24
  25/* The l3 protocol-specific manipulable parts of the tuple: always in
  26   network order! */
  27union nf_conntrack_address {
  28        u_int32_t all[NF_CT_TUPLE_L3SIZE];
  29        __be32 ip;
  30        __be32 ip6[4];
  31};
  32
  33/* The protocol-specific manipulable parts of the tuple: always in
  34   network order! */
  35union nf_conntrack_man_proto
  36{
  37        /* Add other protocols here. */
  38        __be16 all;
  39
  40        struct {
  41                __be16 port;
  42        } tcp;
  43        struct {
  44                __be16 port;
  45        } udp;
  46        struct {
  47                __be16 id;
  48        } icmp;
  49        struct {
  50                __be16 port;
  51        } sctp;
  52        struct {
  53                __be16 key;     /* GRE key is 32bit, PPtP only uses 16bit */
  54        } gre;
  55};
  56
  57/* The manipulable part of the tuple. */
  58struct nf_conntrack_man
  59{
  60        union nf_conntrack_address u3;
  61        union nf_conntrack_man_proto u;
  62        /* Layer 3 protocol */
  63        u_int16_t l3num;
  64};
  65
  66/* This contains the information to distinguish a connection. */
  67struct nf_conntrack_tuple
  68{
  69        struct nf_conntrack_man src;
  70
  71        /* These are the parts of the tuple which are fixed. */
  72        struct {
  73                union nf_conntrack_address u3;
  74                union {
  75                        /* Add other protocols here. */
  76                        __be16 all;
  77
  78                        struct {
  79                                __be16 port;
  80                        } tcp;
  81                        struct {
  82                                __be16 port;
  83                        } udp;
  84                        struct {
  85                                u_int8_t type, code;
  86                        } icmp;
  87                        struct {
  88                                __be16 port;
  89                        } sctp;
  90                        struct {
  91                                __be16 key;
  92                        } gre;
  93                } u;
  94
  95                /* The protocol. */
  96                u_int8_t protonum;
  97
  98                /* The direction (for tuplehash) */
  99                u_int8_t dir;
 100        } dst;
 101};
 102
 103struct nf_conntrack_tuple_mask
 104{
 105        struct {
 106                union nf_conntrack_address u3;
 107                union nf_conntrack_man_proto u;
 108        } src;
 109};
 110
 111/* This is optimized opposed to a memset of the whole structure.  Everything we
 112 * really care about is the  source/destination unions */
 113#define NF_CT_TUPLE_U_BLANK(tuple)                                      \
 114        do {                                                            \
 115                (tuple)->src.u.all = 0;                                 \
 116                (tuple)->dst.u.all = 0;                                 \
 117                memset(&(tuple)->src.u3, 0, sizeof((tuple)->src.u3));   \
 118                memset(&(tuple)->dst.u3, 0, sizeof((tuple)->dst.u3));   \
 119        } while (0)
 120
 121#ifdef __KERNEL__
 122
 123#define NF_CT_DUMP_TUPLE(tp)                                                 \
 124pr_debug("tuple %p: %u %u " NIP6_FMT " %hu -> " NIP6_FMT " %hu\n",           \
 125         (tp), (tp)->src.l3num, (tp)->dst.protonum,                          \
 126         NIP6(*(struct in6_addr *)(tp)->src.u3.all), ntohs((tp)->src.u.all), \
 127         NIP6(*(struct in6_addr *)(tp)->dst.u3.all), ntohs((tp)->dst.u.all))
 128
 129/* If we're the first tuple, it's the original dir. */
 130#define NF_CT_DIRECTION(h)                                              \
 131        ((enum ip_conntrack_dir)(h)->tuple.dst.dir)
 132
 133/* Connections have two entries in the hash table: one for each way */
 134struct nf_conntrack_tuple_hash
 135{
 136        struct hlist_node hnode;
 137        struct nf_conntrack_tuple tuple;
 138};
 139
 140#endif /* __KERNEL__ */
 141
 142static inline int nf_ct_tuple_src_equal(const struct nf_conntrack_tuple *t1,
 143                                        const struct nf_conntrack_tuple *t2)
 144{ 
 145        return (t1->src.u3.all[0] == t2->src.u3.all[0] &&
 146                t1->src.u3.all[1] == t2->src.u3.all[1] &&
 147                t1->src.u3.all[2] == t2->src.u3.all[2] &&
 148                t1->src.u3.all[3] == t2->src.u3.all[3] &&
 149                t1->src.u.all == t2->src.u.all &&
 150                t1->src.l3num == t2->src.l3num &&
 151                t1->dst.protonum == t2->dst.protonum);
 152}
 153
 154static inline int nf_ct_tuple_dst_equal(const struct nf_conntrack_tuple *t1,
 155                                        const struct nf_conntrack_tuple *t2)
 156{
 157        return (t1->dst.u3.all[0] == t2->dst.u3.all[0] &&
 158                t1->dst.u3.all[1] == t2->dst.u3.all[1] &&
 159                t1->dst.u3.all[2] == t2->dst.u3.all[2] &&
 160                t1->dst.u3.all[3] == t2->dst.u3.all[3] &&
 161                t1->dst.u.all == t2->dst.u.all &&
 162                t1->src.l3num == t2->src.l3num &&
 163                t1->dst.protonum == t2->dst.protonum);
 164}
 165
 166static inline int nf_ct_tuple_equal(const struct nf_conntrack_tuple *t1,
 167                                    const struct nf_conntrack_tuple *t2)
 168{
 169        return nf_ct_tuple_src_equal(t1, t2) && nf_ct_tuple_dst_equal(t1, t2);
 170}
 171
 172static inline int nf_ct_tuple_mask_equal(const struct nf_conntrack_tuple_mask *m1,
 173                                         const struct nf_conntrack_tuple_mask *m2)
 174{
 175        return (m1->src.u3.all[0] == m2->src.u3.all[0] &&
 176                m1->src.u3.all[1] == m2->src.u3.all[1] &&
 177                m1->src.u3.all[2] == m2->src.u3.all[2] &&
 178                m1->src.u3.all[3] == m2->src.u3.all[3] &&
 179                m1->src.u.all == m2->src.u.all);
 180}
 181
 182static inline int nf_ct_tuple_src_mask_cmp(const struct nf_conntrack_tuple *t1,
 183                                           const struct nf_conntrack_tuple *t2,
 184                                           const struct nf_conntrack_tuple_mask *mask)
 185{
 186        int count;
 187
 188        for (count = 0; count < NF_CT_TUPLE_L3SIZE; count++) {
 189                if ((t1->src.u3.all[count] ^ t2->src.u3.all[count]) &
 190                    mask->src.u3.all[count])
 191                        return 0;
 192        }
 193
 194        if ((t1->src.u.all ^ t2->src.u.all) & mask->src.u.all)
 195                return 0;
 196
 197        if (t1->src.l3num != t2->src.l3num ||
 198            t1->dst.protonum != t2->dst.protonum)
 199                return 0;
 200
 201        return 1;
 202}
 203
 204static inline int nf_ct_tuple_mask_cmp(const struct nf_conntrack_tuple *t,
 205                                       const struct nf_conntrack_tuple *tuple,
 206                                       const struct nf_conntrack_tuple_mask *mask)
 207{
 208        return nf_ct_tuple_src_mask_cmp(t, tuple, mask) &&
 209               nf_ct_tuple_dst_equal(t, tuple);
 210}
 211
 212#endif /* _NF_CONNTRACK_TUPLE_H */
 213