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 | ||
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! */ | |
d6a9b650 | 27 | union nf_conntrack_address { |
9fb9cbb1 | 28 | u_int32_t all[NF_CT_TUPLE_L3SIZE]; |
bff9a89b PM |
29 | __be32 ip; |
30 | __be32 ip6[4]; | |
9fb9cbb1 YK |
31 | }; |
32 | ||
33 | /* The protocol-specific manipulable parts of the tuple: always in | |
34 | network order! */ | |
35 | union nf_conntrack_man_proto | |
36 | { | |
37 | /* Add other protocols here. */ | |
a34c4589 | 38 | __be16 all; |
9fb9cbb1 YK |
39 | |
40 | struct { | |
bff9a89b | 41 | __be16 port; |
9fb9cbb1 YK |
42 | } tcp; |
43 | struct { | |
bff9a89b | 44 | __be16 port; |
9fb9cbb1 YK |
45 | } udp; |
46 | struct { | |
bff9a89b | 47 | __be16 id; |
9fb9cbb1 YK |
48 | } icmp; |
49 | struct { | |
bff9a89b | 50 | __be16 port; |
9fb9cbb1 | 51 | } sctp; |
f09943fe PM |
52 | struct { |
53 | __be16 key; /* GRE key is 32bit, PPtP only uses 16bit */ | |
54 | } gre; | |
9fb9cbb1 YK |
55 | }; |
56 | ||
57 | /* The manipulable part of the tuple. */ | |
58 | struct nf_conntrack_man | |
59 | { | |
d6a9b650 | 60 | union nf_conntrack_address u3; |
9fb9cbb1 YK |
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. */ | |
67 | struct nf_conntrack_tuple | |
68 | { | |
69 | struct nf_conntrack_man src; | |
70 | ||
71 | /* These are the parts of the tuple which are fixed. */ | |
72 | struct { | |
d6a9b650 | 73 | union nf_conntrack_address u3; |
9fb9cbb1 YK |
74 | union { |
75 | /* Add other protocols here. */ | |
a34c4589 | 76 | __be16 all; |
9fb9cbb1 YK |
77 | |
78 | struct { | |
bff9a89b | 79 | __be16 port; |
9fb9cbb1 YK |
80 | } tcp; |
81 | struct { | |
bff9a89b | 82 | __be16 port; |
9fb9cbb1 YK |
83 | } udp; |
84 | struct { | |
85 | u_int8_t type, code; | |
86 | } icmp; | |
87 | struct { | |
bff9a89b | 88 | __be16 port; |
9fb9cbb1 | 89 | } sctp; |
f09943fe PM |
90 | struct { |
91 | __be16 key; | |
92 | } gre; | |
9fb9cbb1 YK |
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 | ||
d4156e8c PM |
103 | struct nf_conntrack_tuple_mask |
104 | { | |
105 | struct { | |
106 | union nf_conntrack_address u3; | |
107 | union nf_conntrack_man_proto u; | |
108 | } src; | |
109 | }; | |
110 | ||
9fb9cbb1 YK |
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 | ||
0d53778e PM |
123 | #define NF_CT_DUMP_TUPLE(tp) \ |
124 | pr_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)) | |
9fb9cbb1 YK |
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 */ | |
134 | struct nf_conntrack_tuple_hash | |
135 | { | |
f205c5e0 | 136 | struct hlist_node hnode; |
9fb9cbb1 YK |
137 | struct nf_conntrack_tuple tuple; |
138 | }; | |
139 | ||
140 | #endif /* __KERNEL__ */ | |
141 | ||
142 | static 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 | ||
154 | static 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 | ||
166 | static 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 | ||
d4156e8c PM |
172 | static 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 | ||
182 | static 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 | ||
9fb9cbb1 YK |
204 | static inline int nf_ct_tuple_mask_cmp(const struct nf_conntrack_tuple *t, |
205 | const struct nf_conntrack_tuple *tuple, | |
d4156e8c | 206 | const struct nf_conntrack_tuple_mask *mask) |
9fb9cbb1 | 207 | { |
d4156e8c PM |
208 | return nf_ct_tuple_src_mask_cmp(t, tuple, mask) && |
209 | nf_ct_tuple_dst_equal(t, tuple); | |
9fb9cbb1 YK |
210 | } |
211 | ||
212 | #endif /* _NF_CONNTRACK_TUPLE_H */ |