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