Merge branch 'master' of master.kernel.org:/pub/scm/linux/kernel/git/davem/net-2.6
[deliverable/linux.git] / net / netfilter / ipvs / ip_vs_proto_sctp.c
1 #include <linux/kernel.h>
2 #include <linux/ip.h>
3 #include <linux/sctp.h>
4 #include <net/ip.h>
5 #include <net/ip6_checksum.h>
6 #include <linux/netfilter.h>
7 #include <linux/netfilter_ipv4.h>
8 #include <net/sctp/checksum.h>
9 #include <net/ip_vs.h>
10
11 static int
12 sctp_conn_schedule(int af, struct sk_buff *skb, struct ip_vs_proto_data *pd,
13 int *verdict, struct ip_vs_conn **cpp)
14 {
15 struct net *net;
16 struct ip_vs_service *svc;
17 sctp_chunkhdr_t _schunkh, *sch;
18 sctp_sctphdr_t *sh, _sctph;
19 struct ip_vs_iphdr iph;
20
21 ip_vs_fill_iphdr(af, skb_network_header(skb), &iph);
22
23 sh = skb_header_pointer(skb, iph.len, sizeof(_sctph), &_sctph);
24 if (sh == NULL)
25 return 0;
26
27 sch = skb_header_pointer(skb, iph.len + sizeof(sctp_sctphdr_t),
28 sizeof(_schunkh), &_schunkh);
29 if (sch == NULL)
30 return 0;
31 net = skb_net(skb);
32 if ((sch->type == SCTP_CID_INIT) &&
33 (svc = ip_vs_service_get(net, af, skb->mark, iph.protocol,
34 &iph.daddr, sh->dest))) {
35 int ignored;
36
37 if (ip_vs_todrop(net_ipvs(net))) {
38 /*
39 * It seems that we are very loaded.
40 * We have to drop this packet :(
41 */
42 ip_vs_service_put(svc);
43 *verdict = NF_DROP;
44 return 0;
45 }
46 /*
47 * Let the virtual server select a real server for the
48 * incoming connection, and create a connection entry.
49 */
50 *cpp = ip_vs_schedule(svc, skb, pd, &ignored);
51 if (!*cpp && ignored <= 0) {
52 if (!ignored)
53 *verdict = ip_vs_leave(svc, skb, pd);
54 else {
55 ip_vs_service_put(svc);
56 *verdict = NF_DROP;
57 }
58 return 0;
59 }
60 ip_vs_service_put(svc);
61 }
62 /* NF_ACCEPT */
63 return 1;
64 }
65
66 static int
67 sctp_snat_handler(struct sk_buff *skb,
68 struct ip_vs_protocol *pp, struct ip_vs_conn *cp)
69 {
70 sctp_sctphdr_t *sctph;
71 unsigned int sctphoff;
72 struct sk_buff *iter;
73 __be32 crc32;
74
75 #ifdef CONFIG_IP_VS_IPV6
76 if (cp->af == AF_INET6)
77 sctphoff = sizeof(struct ipv6hdr);
78 else
79 #endif
80 sctphoff = ip_hdrlen(skb);
81
82 /* csum_check requires unshared skb */
83 if (!skb_make_writable(skb, sctphoff + sizeof(*sctph)))
84 return 0;
85
86 if (unlikely(cp->app != NULL)) {
87 /* Some checks before mangling */
88 if (pp->csum_check && !pp->csum_check(cp->af, skb, pp))
89 return 0;
90
91 /* Call application helper if needed */
92 if (!ip_vs_app_pkt_out(cp, skb))
93 return 0;
94 }
95
96 sctph = (void *) skb_network_header(skb) + sctphoff;
97 sctph->source = cp->vport;
98
99 /* Calculate the checksum */
100 crc32 = sctp_start_cksum((u8 *) sctph, skb_headlen(skb) - sctphoff);
101 skb_walk_frags(skb, iter)
102 crc32 = sctp_update_cksum((u8 *) iter->data, skb_headlen(iter),
103 crc32);
104 crc32 = sctp_end_cksum(crc32);
105 sctph->checksum = crc32;
106
107 return 1;
108 }
109
110 static int
111 sctp_dnat_handler(struct sk_buff *skb,
112 struct ip_vs_protocol *pp, struct ip_vs_conn *cp)
113 {
114 sctp_sctphdr_t *sctph;
115 unsigned int sctphoff;
116 struct sk_buff *iter;
117 __be32 crc32;
118
119 #ifdef CONFIG_IP_VS_IPV6
120 if (cp->af == AF_INET6)
121 sctphoff = sizeof(struct ipv6hdr);
122 else
123 #endif
124 sctphoff = ip_hdrlen(skb);
125
126 /* csum_check requires unshared skb */
127 if (!skb_make_writable(skb, sctphoff + sizeof(*sctph)))
128 return 0;
129
130 if (unlikely(cp->app != NULL)) {
131 /* Some checks before mangling */
132 if (pp->csum_check && !pp->csum_check(cp->af, skb, pp))
133 return 0;
134
135 /* Call application helper if needed */
136 if (!ip_vs_app_pkt_in(cp, skb))
137 return 0;
138 }
139
140 sctph = (void *) skb_network_header(skb) + sctphoff;
141 sctph->dest = cp->dport;
142
143 /* Calculate the checksum */
144 crc32 = sctp_start_cksum((u8 *) sctph, skb_headlen(skb) - sctphoff);
145 skb_walk_frags(skb, iter)
146 crc32 = sctp_update_cksum((u8 *) iter->data, skb_headlen(iter),
147 crc32);
148 crc32 = sctp_end_cksum(crc32);
149 sctph->checksum = crc32;
150
151 return 1;
152 }
153
154 static int
155 sctp_csum_check(int af, struct sk_buff *skb, struct ip_vs_protocol *pp)
156 {
157 unsigned int sctphoff;
158 struct sctphdr *sh, _sctph;
159 struct sk_buff *iter;
160 __le32 cmp;
161 __le32 val;
162 __u32 tmp;
163
164 #ifdef CONFIG_IP_VS_IPV6
165 if (af == AF_INET6)
166 sctphoff = sizeof(struct ipv6hdr);
167 else
168 #endif
169 sctphoff = ip_hdrlen(skb);
170
171 sh = skb_header_pointer(skb, sctphoff, sizeof(_sctph), &_sctph);
172 if (sh == NULL)
173 return 0;
174
175 cmp = sh->checksum;
176
177 tmp = sctp_start_cksum((__u8 *) sh, skb_headlen(skb));
178 skb_walk_frags(skb, iter)
179 tmp = sctp_update_cksum((__u8 *) iter->data,
180 skb_headlen(iter), tmp);
181
182 val = sctp_end_cksum(tmp);
183
184 if (val != cmp) {
185 /* CRC failure, dump it. */
186 IP_VS_DBG_RL_PKT(0, af, pp, skb, 0,
187 "Failed checksum for");
188 return 0;
189 }
190 return 1;
191 }
192
193 struct ipvs_sctp_nextstate {
194 int next_state;
195 };
196 enum ipvs_sctp_event_t {
197 IP_VS_SCTP_EVE_DATA_CLI,
198 IP_VS_SCTP_EVE_DATA_SER,
199 IP_VS_SCTP_EVE_INIT_CLI,
200 IP_VS_SCTP_EVE_INIT_SER,
201 IP_VS_SCTP_EVE_INIT_ACK_CLI,
202 IP_VS_SCTP_EVE_INIT_ACK_SER,
203 IP_VS_SCTP_EVE_COOKIE_ECHO_CLI,
204 IP_VS_SCTP_EVE_COOKIE_ECHO_SER,
205 IP_VS_SCTP_EVE_COOKIE_ACK_CLI,
206 IP_VS_SCTP_EVE_COOKIE_ACK_SER,
207 IP_VS_SCTP_EVE_ABORT_CLI,
208 IP_VS_SCTP_EVE__ABORT_SER,
209 IP_VS_SCTP_EVE_SHUT_CLI,
210 IP_VS_SCTP_EVE_SHUT_SER,
211 IP_VS_SCTP_EVE_SHUT_ACK_CLI,
212 IP_VS_SCTP_EVE_SHUT_ACK_SER,
213 IP_VS_SCTP_EVE_SHUT_COM_CLI,
214 IP_VS_SCTP_EVE_SHUT_COM_SER,
215 IP_VS_SCTP_EVE_LAST
216 };
217
218 static enum ipvs_sctp_event_t sctp_events[255] = {
219 IP_VS_SCTP_EVE_DATA_CLI,
220 IP_VS_SCTP_EVE_INIT_CLI,
221 IP_VS_SCTP_EVE_INIT_ACK_CLI,
222 IP_VS_SCTP_EVE_DATA_CLI,
223 IP_VS_SCTP_EVE_DATA_CLI,
224 IP_VS_SCTP_EVE_DATA_CLI,
225 IP_VS_SCTP_EVE_ABORT_CLI,
226 IP_VS_SCTP_EVE_SHUT_CLI,
227 IP_VS_SCTP_EVE_SHUT_ACK_CLI,
228 IP_VS_SCTP_EVE_DATA_CLI,
229 IP_VS_SCTP_EVE_COOKIE_ECHO_CLI,
230 IP_VS_SCTP_EVE_COOKIE_ACK_CLI,
231 IP_VS_SCTP_EVE_DATA_CLI,
232 IP_VS_SCTP_EVE_DATA_CLI,
233 IP_VS_SCTP_EVE_SHUT_COM_CLI,
234 };
235
236 static struct ipvs_sctp_nextstate
237 sctp_states_table[IP_VS_SCTP_S_LAST][IP_VS_SCTP_EVE_LAST] = {
238 /*
239 * STATE : IP_VS_SCTP_S_NONE
240 */
241 /*next state *//*event */
242 {{IP_VS_SCTP_S_CLOSED /* IP_VS_SCTP_EVE_DATA_CLI */ },
243 {IP_VS_SCTP_S_CLOSED /* IP_VS_SCTP_EVE_DATA_SER */ },
244 {IP_VS_SCTP_S_INIT_CLI /* IP_VS_SCTP_EVE_INIT_CLI */ },
245 {IP_VS_SCTP_S_INIT_SER /* IP_VS_SCTP_EVE_INIT_SER */ },
246 {IP_VS_SCTP_S_CLOSED /* IP_VS_SCTP_EVE_INIT_ACK_CLI */ },
247 {IP_VS_SCTP_S_CLOSED /* IP_VS_SCTP_EVE_INIT_ACK_SER */ },
248 {IP_VS_SCTP_S_CLOSED /* IP_VS_SCTP_EVE_COOKIE_ECHO_CLI */ },
249 {IP_VS_SCTP_S_CLOSED /* IP_VS_SCTP_EVE_COOKIE_ECHO_SER */ },
250 {IP_VS_SCTP_S_CLOSED /* IP_VS_SCTP_EVE_COOKIE_ACK_CLI */ },
251 {IP_VS_SCTP_S_CLOSED /* IP_VS_SCTP_EVE_COOKIE_ACK_SER */ },
252 {IP_VS_SCTP_S_CLOSED /* IP_VS_SCTP_EVE_ABORT_CLI */ },
253 {IP_VS_SCTP_S_CLOSED /* IP_VS_SCTP_EVE_ABORT_SER */ },
254 {IP_VS_SCTP_S_CLOSED /* IP_VS_SCTP_EVE_SHUT_CLI */ },
255 {IP_VS_SCTP_S_CLOSED /* IP_VS_SCTP_EVE_SHUT_SER */ },
256 {IP_VS_SCTP_S_CLOSED /* IP_VS_SCTP_EVE_SHUT_ACK_CLI */ },
257 {IP_VS_SCTP_S_CLOSED /* IP_VS_SCTP_EVE_SHUT_ACK_SER */ },
258 {IP_VS_SCTP_S_CLOSED /* IP_VS_SCTP_EVE_SHUT_COM_CLI */ },
259 {IP_VS_SCTP_S_CLOSED /* IP_VS_SCTP_EVE_SHUT_COM_SER */ },
260 },
261 /*
262 * STATE : IP_VS_SCTP_S_INIT_CLI
263 * Cient sent INIT and is waiting for reply from server(In ECHO_WAIT)
264 */
265 {{IP_VS_SCTP_S_CLOSED /* IP_VS_SCTP_EVE_DATA_CLI */ },
266 {IP_VS_SCTP_S_CLOSED /* IP_VS_SCTP_EVE_DATA_SER */ },
267 {IP_VS_SCTP_S_INIT_CLI /* IP_VS_SCTP_EVE_INIT_CLI */ },
268 {IP_VS_SCTP_S_INIT_SER /* IP_VS_SCTP_EVE_INIT_SER */ },
269 {IP_VS_SCTP_S_CLOSED /* IP_VS_SCTP_EVE_INIT_ACK_CLI */ },
270 {IP_VS_SCTP_S_INIT_ACK_SER /* IP_VS_SCTP_EVE_INIT_ACK_SER */ },
271 {IP_VS_SCTP_S_CLOSED /* IP_VS_SCTP_EVE_ECHO_CLI */ },
272 {IP_VS_SCTP_S_INIT_CLI /* IP_VS_SCTP_EVE_ECHO_SER */ },
273 {IP_VS_SCTP_S_CLOSED /* IP_VS_SCTP_EVE_COOKIE_ACK_CLI */ },
274 {IP_VS_SCTP_S_INIT_CLI /* IP_VS_SCTP_EVE_COOKIE_ACK_SER */ },
275 {IP_VS_SCTP_S_CLOSED /* IP_VS_SCTP_EVE_ABORT_CLI */ },
276 {IP_VS_SCTP_S_CLOSED /* IP_VS_SCTP_EVE_ABORT_SER */ },
277 {IP_VS_SCTP_S_CLOSED /* IP_VS_SCTP_EVE_SHUT_CLI */ },
278 {IP_VS_SCTP_S_CLOSED /* IP_VS_SCTP_EVE_SHUT_SER */ },
279 {IP_VS_SCTP_S_CLOSED /* IP_VS_SCTP_EVE_SHUT_ACK_CLI */ },
280 {IP_VS_SCTP_S_CLOSED /* IP_VS_SCTP_EVE_SHUT_ACK_SER */ },
281 {IP_VS_SCTP_S_CLOSED /* IP_VS_SCTP_EVE_SHUT_COM_CLI */ },
282 {IP_VS_SCTP_S_CLOSED /* IP_VS_SCTP_EVE_SHUT_COM_SER */ }
283 },
284 /*
285 * State : IP_VS_SCTP_S_INIT_SER
286 * Server sent INIT and waiting for INIT ACK from the client
287 */
288 {{IP_VS_SCTP_S_CLOSED /* IP_VS_SCTP_EVE_DATA_CLI */ },
289 {IP_VS_SCTP_S_CLOSED /* IP_VS_SCTP_EVE_DATA_SER */ },
290 {IP_VS_SCTP_S_INIT_CLI /* IP_VS_SCTP_EVE_INIT_CLI */ },
291 {IP_VS_SCTP_S_INIT_SER /* IP_VS_SCTP_EVE_INIT_SER */ },
292 {IP_VS_SCTP_S_INIT_ACK_CLI /* IP_VS_SCTP_EVE_INIT_ACK_CLI */ },
293 {IP_VS_SCTP_S_CLOSED /* IP_VS_SCTP_EVE_INIT_ACK_SER */ },
294 {IP_VS_SCTP_S_INIT_SER /* IP_VS_SCTP_EVE_COOKIE_ECHO_CLI */ },
295 {IP_VS_SCTP_S_CLOSED /* IP_VS_SCTP_EVE_COOKIE_ECHO_SER */ },
296 {IP_VS_SCTP_S_INIT_SER /* IP_VS_SCTP_EVE_COOKIE_ACK_CLI */ },
297 {IP_VS_SCTP_S_CLOSED /* IP_VS_SCTP_EVE_COOKIE_ACK_SER */ },
298 {IP_VS_SCTP_S_CLOSED /* IP_VS_SCTP_EVE_ABORT_CLI */ },
299 {IP_VS_SCTP_S_CLOSED /* IP_VS_SCTP_EVE_ABORT_SER */ },
300 {IP_VS_SCTP_S_CLOSED /* IP_VS_SCTP_EVE_SHUT_CLI */ },
301 {IP_VS_SCTP_S_CLOSED /* IP_VS_SCTP_EVE_SHUT_SER */ },
302 {IP_VS_SCTP_S_CLOSED /* IP_VS_SCTP_EVE_SHUT_ACK_CLI */ },
303 {IP_VS_SCTP_S_CLOSED /* IP_VS_SCTP_EVE_SHUT_ACK_SER */ },
304 {IP_VS_SCTP_S_CLOSED /* IP_VS_SCTP_EVE_SHUT_COM_CLI */ },
305 {IP_VS_SCTP_S_CLOSED /* IP_VS_SCTP_EVE_SHUT_COM_SER */ }
306 },
307 /*
308 * State : IP_VS_SCTP_S_INIT_ACK_CLI
309 * Client sent INIT ACK and waiting for ECHO from the server
310 */
311 {{IP_VS_SCTP_S_CLOSED /* IP_VS_SCTP_EVE_DATA_CLI */ },
312 {IP_VS_SCTP_S_CLOSED /* IP_VS_SCTP_EVE_DATA_SER */ },
313 /*
314 * We have got an INIT from client. From the spec.“Upon receipt of
315 * an INIT in the COOKIE-WAIT state, an endpoint MUST respond with
316 * an INIT ACK using the same parameters it sent in its original
317 * INIT chunk (including its Initiate Tag, unchanged”).
318 */
319 {IP_VS_SCTP_S_INIT_CLI /* IP_VS_SCTP_EVE_INIT_CLI */ },
320 {IP_VS_SCTP_S_INIT_SER /* IP_VS_SCTP_EVE_INIT_SER */ },
321 /*
322 * INIT_ACK has been resent by the client, let us stay is in
323 * the same state
324 */
325 {IP_VS_SCTP_S_INIT_ACK_CLI /* IP_VS_SCTP_EVE_INIT_ACK_CLI */ },
326 /*
327 * INIT_ACK sent by the server, close the connection
328 */
329 {IP_VS_SCTP_S_CLOSED /* IP_VS_SCTP_EVE_INIT_ACK_SER */ },
330 /*
331 * ECHO by client, it should not happen, close the connection
332 */
333 {IP_VS_SCTP_S_CLOSED /* IP_VS_SCTP_EVE_COOKIE_ECHO_CLI */ },
334 /*
335 * ECHO by server, this is what we are expecting, move to ECHO_SER
336 */
337 {IP_VS_SCTP_S_ECHO_SER /* IP_VS_SCTP_EVE_COOKIE_ECHO_SER */ },
338 /*
339 * COOKIE ACK from client, it should not happen, close the connection
340 */
341 {IP_VS_SCTP_S_CLOSED /* IP_VS_SCTP_EVE_COOKIE_ACK_CLI */ },
342 /*
343 * Unexpected COOKIE ACK from server, staty in the same state
344 */
345 {IP_VS_SCTP_S_INIT_ACK_CLI /* IP_VS_SCTP_EVE_COOKIE_ACK_SER */ },
346 {IP_VS_SCTP_S_CLOSED /* IP_VS_SCTP_EVE_ABORT_CLI */ },
347 {IP_VS_SCTP_S_CLOSED /* IP_VS_SCTP_EVE_ABORT_SER */ },
348 {IP_VS_SCTP_S_CLOSED /* IP_VS_SCTP_EVE_SHUT_CLI */ },
349 {IP_VS_SCTP_S_CLOSED /* IP_VS_SCTP_EVE_SHUT_SER */ },
350 {IP_VS_SCTP_S_CLOSED /* IP_VS_SCTP_EVE_SHUT_ACK_CLI */ },
351 {IP_VS_SCTP_S_CLOSED /* IP_VS_SCTP_EVE_SHUT_ACK_SER */ },
352 {IP_VS_SCTP_S_CLOSED /* IP_VS_SCTP_EVE_SHUT_COM_CLI */ },
353 {IP_VS_SCTP_S_CLOSED /* IP_VS_SCTP_EVE_SHUT_COM_SER */ }
354 },
355 /*
356 * State : IP_VS_SCTP_S_INIT_ACK_SER
357 * Server sent INIT ACK and waiting for ECHO from the client
358 */
359 {{IP_VS_SCTP_S_CLOSED /* IP_VS_SCTP_EVE_DATA_CLI */ },
360 {IP_VS_SCTP_S_CLOSED /* IP_VS_SCTP_EVE_DATA_SER */ },
361 /*
362 * We have got an INIT from client. From the spec.“Upon receipt of
363 * an INIT in the COOKIE-WAIT state, an endpoint MUST respond with
364 * an INIT ACK using the same parameters it sent in its original
365 * INIT chunk (including its Initiate Tag, unchanged”).
366 */
367 {IP_VS_SCTP_S_INIT_CLI /* IP_VS_SCTP_EVE_INIT_CLI */ },
368 {IP_VS_SCTP_S_INIT_SER /* IP_VS_SCTP_EVE_INIT_SER */ },
369 /*
370 * Unexpected INIT_ACK by the client, let us close the connection
371 */
372 {IP_VS_SCTP_S_CLOSED /* IP_VS_SCTP_EVE_INIT_ACK_CLI */ },
373 /*
374 * INIT_ACK resent by the server, let us move to same state
375 */
376 {IP_VS_SCTP_S_INIT_ACK_SER /* IP_VS_SCTP_EVE_INIT_ACK_SER */ },
377 /*
378 * Client send the ECHO, this is what we are expecting,
379 * move to ECHO_CLI
380 */
381 {IP_VS_SCTP_S_ECHO_CLI /* IP_VS_SCTP_EVE_COOKIE_ECHO_CLI */ },
382 /*
383 * ECHO received from the server, Not sure what to do,
384 * let us close it
385 */
386 {IP_VS_SCTP_S_CLOSED /* IP_VS_SCTP_EVE_COOKIE_ECHO_SER */ },
387 /*
388 * COOKIE ACK from client, let us stay in the same state
389 */
390 {IP_VS_SCTP_S_INIT_ACK_SER /* IP_VS_SCTP_EVE_COOKIE_ACK_CLI */ },
391 /*
392 * COOKIE ACK from server, hmm... this should not happen, lets close
393 * the connection.
394 */
395 {IP_VS_SCTP_S_CLOSED /* IP_VS_SCTP_EVE_COOKIE_ACK_SER */ },
396 {IP_VS_SCTP_S_CLOSED /* IP_VS_SCTP_EVE_ABORT_CLI */ },
397 {IP_VS_SCTP_S_CLOSED /* IP_VS_SCTP_EVE_ABORT_SER */ },
398 {IP_VS_SCTP_S_CLOSED /* IP_VS_SCTP_EVE_SHUT_CLI */ },
399 {IP_VS_SCTP_S_CLOSED /* IP_VS_SCTP_EVE_SHUT_SER */ },
400 {IP_VS_SCTP_S_CLOSED /* IP_VS_SCTP_EVE_SHUT_ACK_CLI */ },
401 {IP_VS_SCTP_S_CLOSED /* IP_VS_SCTP_EVE_SHUT_ACK_SER */ },
402 {IP_VS_SCTP_S_CLOSED /* IP_VS_SCTP_EVE_SHUT_COM_CLI */ },
403 {IP_VS_SCTP_S_CLOSED /* IP_VS_SCTP_EVE_SHUT_COM_SER */ }
404 },
405 /*
406 * State : IP_VS_SCTP_S_ECHO_CLI
407 * Cient sent ECHO and waiting COOKEI ACK from the Server
408 */
409 {{IP_VS_SCTP_S_CLOSED /* IP_VS_SCTP_EVE_DATA_CLI */ },
410 {IP_VS_SCTP_S_CLOSED /* IP_VS_SCTP_EVE_DATA_SER */ },
411 /*
412 * We have got an INIT from client. From the spec.“Upon receipt of
413 * an INIT in the COOKIE-WAIT state, an endpoint MUST respond with
414 * an INIT ACK using the same parameters it sent in its original
415 * INIT chunk (including its Initiate Tag, unchanged”).
416 */
417 {IP_VS_SCTP_S_INIT_CLI /* IP_VS_SCTP_EVE_INIT_CLI */ },
418 {IP_VS_SCTP_S_INIT_SER /* IP_VS_SCTP_EVE_INIT_SER */ },
419 /*
420 * INIT_ACK has been by the client, let us close the connection
421 */
422 {IP_VS_SCTP_S_CLOSED /* IP_VS_SCTP_EVE_INIT_ACK_CLI */ },
423 /*
424 * INIT_ACK sent by the server, Unexpected INIT ACK, spec says,
425 * “If an INIT ACK is received by an endpoint in any state other
426 * than the COOKIE-WAIT state, the endpoint should discard the
427 * INIT ACK chunk”. Stay in the same state
428 */
429 {IP_VS_SCTP_S_ECHO_CLI /* IP_VS_SCTP_EVE_INIT_ACK_SER */ },
430 /*
431 * Client resent the ECHO, let us stay in the same state
432 */
433 {IP_VS_SCTP_S_ECHO_CLI /* IP_VS_SCTP_EVE_COOKIE_ECHO_CLI */ },
434 /*
435 * ECHO received from the server, Not sure what to do,
436 * let us close it
437 */
438 {IP_VS_SCTP_S_CLOSED /* IP_VS_SCTP_EVE_COOKIE_ECHO_SER */ },
439 /*
440 * COOKIE ACK from client, this shoud not happen, let's close the
441 * connection
442 */
443 {IP_VS_SCTP_S_CLOSED /* IP_VS_SCTP_EVE_COOKIE_ACK_CLI */ },
444 /*
445 * COOKIE ACK from server, this is what we are awaiting,lets move to
446 * ESTABLISHED.
447 */
448 {IP_VS_SCTP_S_ESTABLISHED /* IP_VS_SCTP_EVE_COOKIE_ACK_SER */ },
449 {IP_VS_SCTP_S_CLOSED /* IP_VS_SCTP_EVE_ABORT_CLI */ },
450 {IP_VS_SCTP_S_CLOSED /* IP_VS_SCTP_EVE_ABORT_SER */ },
451 {IP_VS_SCTP_S_CLOSED /* IP_VS_SCTP_EVE_SHUT_CLI */ },
452 {IP_VS_SCTP_S_CLOSED /* IP_VS_SCTP_EVE_SHUT_SER */ },
453 {IP_VS_SCTP_S_CLOSED /* IP_VS_SCTP_EVE_SHUT_ACK_CLI */ },
454 {IP_VS_SCTP_S_CLOSED /* IP_VS_SCTP_EVE_SHUT_ACK_SER */ },
455 {IP_VS_SCTP_S_CLOSED /* IP_VS_SCTP_EVE_SHUT_COM_CLI */ },
456 {IP_VS_SCTP_S_CLOSED /* IP_VS_SCTP_EVE_SHUT_COM_SER */ }
457 },
458 /*
459 * State : IP_VS_SCTP_S_ECHO_SER
460 * Server sent ECHO and waiting COOKEI ACK from the client
461 */
462 {{IP_VS_SCTP_S_CLOSED /* IP_VS_SCTP_EVE_DATA_CLI */ },
463 {IP_VS_SCTP_S_CLOSED /* IP_VS_SCTP_EVE_DATA_SER */ },
464 /*
465 * We have got an INIT from client. From the spec.“Upon receipt of
466 * an INIT in the COOKIE-WAIT state, an endpoint MUST respond with
467 * an INIT ACK using the same parameters it sent in its original
468 * INIT chunk (including its Initiate Tag, unchanged”).
469 */
470 {IP_VS_SCTP_S_INIT_CLI /* IP_VS_SCTP_EVE_INIT_CLI */ },
471 {IP_VS_SCTP_S_INIT_SER /* IP_VS_SCTP_EVE_INIT_SER */ },
472 /*
473 * INIT_ACK sent by the server, Unexpected INIT ACK, spec says,
474 * “If an INIT ACK is received by an endpoint in any state other
475 * than the COOKIE-WAIT state, the endpoint should discard the
476 * INIT ACK chunk”. Stay in the same state
477 */
478 {IP_VS_SCTP_S_ECHO_SER /* IP_VS_SCTP_EVE_INIT_ACK_CLI */ },
479 /*
480 * INIT_ACK has been by the server, let us close the connection
481 */
482 {IP_VS_SCTP_S_CLOSED /* IP_VS_SCTP_EVE_INIT_ACK_SER */ },
483 /*
484 * Client sent the ECHO, not sure what to do, let's close the
485 * connection.
486 */
487 {IP_VS_SCTP_S_CLOSED /* IP_VS_SCTP_EVE_COOKIE_ECHO_CLI */ },
488 /*
489 * ECHO resent by the server, stay in the same state
490 */
491 {IP_VS_SCTP_S_ECHO_SER /* IP_VS_SCTP_EVE_COOKIE_ECHO_SER */ },
492 /*
493 * COOKIE ACK from client, this is what we are expecting, let's move
494 * to ESTABLISHED.
495 */
496 {IP_VS_SCTP_S_ESTABLISHED /* IP_VS_SCTP_EVE_COOKIE_ACK_CLI */ },
497 /*
498 * COOKIE ACK from server, this should not happen, lets close the
499 * connection.
500 */
501 {IP_VS_SCTP_S_CLOSED /* IP_VS_SCTP_EVE_COOKIE_ACK_SER */ },
502 {IP_VS_SCTP_S_CLOSED /* IP_VS_SCTP_EVE_ABORT_CLI */ },
503 {IP_VS_SCTP_S_CLOSED /* IP_VS_SCTP_EVE_ABORT_SER */ },
504 {IP_VS_SCTP_S_CLOSED /* IP_VS_SCTP_EVE_SHUT_CLI */ },
505 {IP_VS_SCTP_S_CLOSED /* IP_VS_SCTP_EVE_SHUT_SER */ },
506 {IP_VS_SCTP_S_CLOSED /* IP_VS_SCTP_EVE_SHUT_ACK_CLI */ },
507 {IP_VS_SCTP_S_CLOSED /* IP_VS_SCTP_EVE_SHUT_ACK_SER */ },
508 {IP_VS_SCTP_S_CLOSED /* IP_VS_SCTP_EVE_SHUT_COM_CLI */ },
509 {IP_VS_SCTP_S_CLOSED /* IP_VS_SCTP_EVE_SHUT_COM_SER */ }
510 },
511 /*
512 * State : IP_VS_SCTP_S_ESTABLISHED
513 * Association established
514 */
515 {{IP_VS_SCTP_S_ESTABLISHED /* IP_VS_SCTP_EVE_DATA_CLI */ },
516 {IP_VS_SCTP_S_ESTABLISHED /* IP_VS_SCTP_EVE_DATA_SER */ },
517 /*
518 * We have got an INIT from client. From the spec.“Upon receipt of
519 * an INIT in the COOKIE-WAIT state, an endpoint MUST respond with
520 * an INIT ACK using the same parameters it sent in its original
521 * INIT chunk (including its Initiate Tag, unchanged”).
522 */
523 {IP_VS_SCTP_S_INIT_CLI /* IP_VS_SCTP_EVE_INIT_CLI */ },
524 {IP_VS_SCTP_S_INIT_SER /* IP_VS_SCTP_EVE_INIT_SER */ },
525 /*
526 * INIT_ACK sent by the server, Unexpected INIT ACK, spec says,
527 * “If an INIT ACK is received by an endpoint in any state other
528 * than the COOKIE-WAIT state, the endpoint should discard the
529 * INIT ACK chunk”. Stay in the same state
530 */
531 {IP_VS_SCTP_S_ESTABLISHED /* IP_VS_SCTP_EVE_INIT_ACK_CLI */ },
532 {IP_VS_SCTP_S_ESTABLISHED /* IP_VS_SCTP_EVE_INIT_ACK_SER */ },
533 /*
534 * Client sent ECHO, Spec(sec 5.2.4) says it may be handled by the
535 * peer and peer shall move to the ESTABISHED. if it doesn't handle
536 * it will send ERROR chunk. So, stay in the same state
537 */
538 {IP_VS_SCTP_S_ESTABLISHED /* IP_VS_SCTP_EVE_COOKIE_ECHO_CLI */ },
539 {IP_VS_SCTP_S_ESTABLISHED /* IP_VS_SCTP_EVE_COOKIE_ECHO_SER */ },
540 /*
541 * COOKIE ACK from client, not sure what to do stay in the same state
542 */
543 {IP_VS_SCTP_S_ESTABLISHED /* IP_VS_SCTP_EVE_COOKIE_ACK_CLI */ },
544 {IP_VS_SCTP_S_ESTABLISHED /* IP_VS_SCTP_EVE_COOKIE_ACK_SER */ },
545 {IP_VS_SCTP_S_CLOSED /* IP_VS_SCTP_EVE_ABORT_CLI */ },
546 {IP_VS_SCTP_S_CLOSED /* IP_VS_SCTP_EVE_ABORT_SER */ },
547 /*
548 * SHUTDOWN from the client, move to SHUDDOWN_CLI
549 */
550 {IP_VS_SCTP_S_SHUT_CLI /* IP_VS_SCTP_EVE_SHUT_CLI */ },
551 /*
552 * SHUTDOWN from the server, move to SHUTDOWN_SER
553 */
554 {IP_VS_SCTP_S_SHUT_SER /* IP_VS_SCTP_EVE_SHUT_SER */ },
555 /*
556 * client sent SHUDTDOWN_ACK, this should not happen, let's close
557 * the connection
558 */
559 {IP_VS_SCTP_S_CLOSED /* IP_VS_SCTP_EVE_SHUT_ACK_CLI */ },
560 {IP_VS_SCTP_S_CLOSED /* IP_VS_SCTP_EVE_SHUT_ACK_SER */ },
561 {IP_VS_SCTP_S_CLOSED /* IP_VS_SCTP_EVE_SHUT_COM_CLI */ },
562 {IP_VS_SCTP_S_CLOSED /* IP_VS_SCTP_EVE_SHUT_COM_SER */ }
563 },
564 /*
565 * State : IP_VS_SCTP_S_SHUT_CLI
566 * SHUTDOWN sent from the client, waitinf for SHUT ACK from the server
567 */
568 /*
569 * We recieved the data chuck, keep the state unchanged. I assume
570 * that still data chuncks can be received by both the peers in
571 * SHUDOWN state
572 */
573
574 {{IP_VS_SCTP_S_SHUT_CLI /* IP_VS_SCTP_EVE_DATA_CLI */ },
575 {IP_VS_SCTP_S_SHUT_CLI /* IP_VS_SCTP_EVE_DATA_SER */ },
576 /*
577 * We have got an INIT from client. From the spec.“Upon receipt of
578 * an INIT in the COOKIE-WAIT state, an endpoint MUST respond with
579 * an INIT ACK using the same parameters it sent in its original
580 * INIT chunk (including its Initiate Tag, unchanged”).
581 */
582 {IP_VS_SCTP_S_INIT_CLI /* IP_VS_SCTP_EVE_INIT_CLI */ },
583 {IP_VS_SCTP_S_INIT_SER /* IP_VS_SCTP_EVE_INIT_SER */ },
584 /*
585 * INIT_ACK sent by the server, Unexpected INIT ACK, spec says,
586 * “If an INIT ACK is received by an endpoint in any state other
587 * than the COOKIE-WAIT state, the endpoint should discard the
588 * INIT ACK chunk”. Stay in the same state
589 */
590 {IP_VS_SCTP_S_SHUT_CLI /* IP_VS_SCTP_EVE_INIT_ACK_CLI */ },
591 {IP_VS_SCTP_S_SHUT_CLI /* IP_VS_SCTP_EVE_INIT_ACK_SER */ },
592 /*
593 * Client sent ECHO, Spec(sec 5.2.4) says it may be handled by the
594 * peer and peer shall move to the ESTABISHED. if it doesn't handle
595 * it will send ERROR chunk. So, stay in the same state
596 */
597 {IP_VS_SCTP_S_ESTABLISHED /* IP_VS_SCTP_EVE_COOKIE_ECHO_CLI */ },
598 {IP_VS_SCTP_S_ESTABLISHED /* IP_VS_SCTP_EVE_COOKIE_ECHO_SER */ },
599 /*
600 * COOKIE ACK from client, not sure what to do stay in the same state
601 */
602 {IP_VS_SCTP_S_SHUT_CLI /* IP_VS_SCTP_EVE_COOKIE_ACK_CLI */ },
603 {IP_VS_SCTP_S_SHUT_CLI /* IP_VS_SCTP_EVE_COOKIE_ACK_SER */ },
604 {IP_VS_SCTP_S_CLOSED /* IP_VS_SCTP_EVE_ABORT_CLI */ },
605 {IP_VS_SCTP_S_CLOSED /* IP_VS_SCTP_EVE_ABORT_SER */ },
606 /*
607 * SHUTDOWN resent from the client, move to SHUDDOWN_CLI
608 */
609 {IP_VS_SCTP_S_SHUT_CLI /* IP_VS_SCTP_EVE_SHUT_CLI */ },
610 /*
611 * SHUTDOWN from the server, move to SHUTDOWN_SER
612 */
613 {IP_VS_SCTP_S_SHUT_SER /* IP_VS_SCTP_EVE_SHUT_SER */ },
614 /*
615 * client sent SHUDTDOWN_ACK, this should not happen, let's close
616 * the connection
617 */
618 {IP_VS_SCTP_S_CLOSED /* IP_VS_SCTP_EVE_SHUT_ACK_CLI */ },
619 /*
620 * Server sent SHUTDOWN ACK, this is what we are expecting, let's move
621 * to SHUDOWN_ACK_SER
622 */
623 {IP_VS_SCTP_S_SHUT_ACK_SER /* IP_VS_SCTP_EVE_SHUT_ACK_SER */ },
624 /*
625 * SHUTDOWN COM from client, this should not happen, let's close the
626 * connection
627 */
628 {IP_VS_SCTP_S_CLOSED /* IP_VS_SCTP_EVE_SHUT_COM_CLI */ },
629 {IP_VS_SCTP_S_CLOSED /* IP_VS_SCTP_EVE_SHUT_COM_SER */ }
630 },
631 /*
632 * State : IP_VS_SCTP_S_SHUT_SER
633 * SHUTDOWN sent from the server, waitinf for SHUTDOWN ACK from client
634 */
635 /*
636 * We recieved the data chuck, keep the state unchanged. I assume
637 * that still data chuncks can be received by both the peers in
638 * SHUDOWN state
639 */
640
641 {{IP_VS_SCTP_S_SHUT_SER /* IP_VS_SCTP_EVE_DATA_CLI */ },
642 {IP_VS_SCTP_S_SHUT_SER /* IP_VS_SCTP_EVE_DATA_SER */ },
643 /*
644 * We have got an INIT from client. From the spec.“Upon receipt of
645 * an INIT in the COOKIE-WAIT state, an endpoint MUST respond with
646 * an INIT ACK using the same parameters it sent in its original
647 * INIT chunk (including its Initiate Tag, unchanged”).
648 */
649 {IP_VS_SCTP_S_INIT_CLI /* IP_VS_SCTP_EVE_INIT_CLI */ },
650 {IP_VS_SCTP_S_INIT_SER /* IP_VS_SCTP_EVE_INIT_SER */ },
651 /*
652 * INIT_ACK sent by the server, Unexpected INIT ACK, spec says,
653 * “If an INIT ACK is received by an endpoint in any state other
654 * than the COOKIE-WAIT state, the endpoint should discard the
655 * INIT ACK chunk”. Stay in the same state
656 */
657 {IP_VS_SCTP_S_SHUT_SER /* IP_VS_SCTP_EVE_INIT_ACK_CLI */ },
658 {IP_VS_SCTP_S_SHUT_SER /* IP_VS_SCTP_EVE_INIT_ACK_SER */ },
659 /*
660 * Client sent ECHO, Spec(sec 5.2.4) says it may be handled by the
661 * peer and peer shall move to the ESTABISHED. if it doesn't handle
662 * it will send ERROR chunk. So, stay in the same state
663 */
664 {IP_VS_SCTP_S_ESTABLISHED /* IP_VS_SCTP_EVE_COOKIE_ECHO_CLI */ },
665 {IP_VS_SCTP_S_ESTABLISHED /* IP_VS_SCTP_EVE_COOKIE_ECHO_SER */ },
666 /*
667 * COOKIE ACK from client, not sure what to do stay in the same state
668 */
669 {IP_VS_SCTP_S_SHUT_SER /* IP_VS_SCTP_EVE_COOKIE_ACK_CLI */ },
670 {IP_VS_SCTP_S_SHUT_SER /* IP_VS_SCTP_EVE_COOKIE_ACK_SER */ },
671 {IP_VS_SCTP_S_CLOSED /* IP_VS_SCTP_EVE_ABORT_CLI */ },
672 {IP_VS_SCTP_S_CLOSED /* IP_VS_SCTP_EVE_ABORT_SER */ },
673 /*
674 * SHUTDOWN resent from the client, move to SHUDDOWN_CLI
675 */
676 {IP_VS_SCTP_S_SHUT_CLI /* IP_VS_SCTP_EVE_SHUT_CLI */ },
677 /*
678 * SHUTDOWN resent from the server, move to SHUTDOWN_SER
679 */
680 {IP_VS_SCTP_S_SHUT_SER /* IP_VS_SCTP_EVE_SHUT_SER */ },
681 /*
682 * client sent SHUDTDOWN_ACK, this is what we are expecting, let's
683 * move to SHUT_ACK_CLI
684 */
685 {IP_VS_SCTP_S_SHUT_ACK_CLI /* IP_VS_SCTP_EVE_SHUT_ACK_CLI */ },
686 /*
687 * Server sent SHUTDOWN ACK, this should not happen, let's close the
688 * connection
689 */
690 {IP_VS_SCTP_S_CLOSED /* IP_VS_SCTP_EVE_SHUT_ACK_SER */ },
691 /*
692 * SHUTDOWN COM from client, this should not happen, let's close the
693 * connection
694 */
695 {IP_VS_SCTP_S_CLOSED /* IP_VS_SCTP_EVE_SHUT_COM_CLI */ },
696 {IP_VS_SCTP_S_CLOSED /* IP_VS_SCTP_EVE_SHUT_COM_SER */ }
697 },
698
699 /*
700 * State : IP_VS_SCTP_S_SHUT_ACK_CLI
701 * SHUTDOWN ACK from the client, awaiting for SHUTDOWN COM from server
702 */
703 /*
704 * We recieved the data chuck, keep the state unchanged. I assume
705 * that still data chuncks can be received by both the peers in
706 * SHUDOWN state
707 */
708
709 {{IP_VS_SCTP_S_SHUT_ACK_CLI /* IP_VS_SCTP_EVE_DATA_CLI */ },
710 {IP_VS_SCTP_S_SHUT_ACK_CLI /* IP_VS_SCTP_EVE_DATA_SER */ },
711 /*
712 * We have got an INIT from client. From the spec.“Upon receipt of
713 * an INIT in the COOKIE-WAIT state, an endpoint MUST respond with
714 * an INIT ACK using the same parameters it sent in its original
715 * INIT chunk (including its Initiate Tag, unchanged”).
716 */
717 {IP_VS_SCTP_S_INIT_CLI /* IP_VS_SCTP_EVE_INIT_CLI */ },
718 {IP_VS_SCTP_S_INIT_SER /* IP_VS_SCTP_EVE_INIT_SER */ },
719 /*
720 * INIT_ACK sent by the server, Unexpected INIT ACK, spec says,
721 * “If an INIT ACK is received by an endpoint in any state other
722 * than the COOKIE-WAIT state, the endpoint should discard the
723 * INIT ACK chunk”. Stay in the same state
724 */
725 {IP_VS_SCTP_S_SHUT_ACK_CLI /* IP_VS_SCTP_EVE_INIT_ACK_CLI */ },
726 {IP_VS_SCTP_S_SHUT_ACK_CLI /* IP_VS_SCTP_EVE_INIT_ACK_SER */ },
727 /*
728 * Client sent ECHO, Spec(sec 5.2.4) says it may be handled by the
729 * peer and peer shall move to the ESTABISHED. if it doesn't handle
730 * it will send ERROR chunk. So, stay in the same state
731 */
732 {IP_VS_SCTP_S_ESTABLISHED /* IP_VS_SCTP_EVE_COOKIE_ECHO_CLI */ },
733 {IP_VS_SCTP_S_ESTABLISHED /* IP_VS_SCTP_EVE_COOKIE_ECHO_SER */ },
734 /*
735 * COOKIE ACK from client, not sure what to do stay in the same state
736 */
737 {IP_VS_SCTP_S_SHUT_ACK_CLI /* IP_VS_SCTP_EVE_COOKIE_ACK_CLI */ },
738 {IP_VS_SCTP_S_SHUT_ACK_CLI /* IP_VS_SCTP_EVE_COOKIE_ACK_SER */ },
739 {IP_VS_SCTP_S_CLOSED /* IP_VS_SCTP_EVE_ABORT_CLI */ },
740 {IP_VS_SCTP_S_CLOSED /* IP_VS_SCTP_EVE_ABORT_SER */ },
741 /*
742 * SHUTDOWN sent from the client, move to SHUDDOWN_CLI
743 */
744 {IP_VS_SCTP_S_SHUT_CLI /* IP_VS_SCTP_EVE_SHUT_CLI */ },
745 /*
746 * SHUTDOWN sent from the server, move to SHUTDOWN_SER
747 */
748 {IP_VS_SCTP_S_SHUT_SER /* IP_VS_SCTP_EVE_SHUT_SER */ },
749 /*
750 * client resent SHUDTDOWN_ACK, let's stay in the same state
751 */
752 {IP_VS_SCTP_S_SHUT_ACK_CLI /* IP_VS_SCTP_EVE_SHUT_ACK_CLI */ },
753 /*
754 * Server sent SHUTDOWN ACK, this should not happen, let's close the
755 * connection
756 */
757 {IP_VS_SCTP_S_CLOSED /* IP_VS_SCTP_EVE_SHUT_ACK_SER */ },
758 /*
759 * SHUTDOWN COM from client, this should not happen, let's close the
760 * connection
761 */
762 {IP_VS_SCTP_S_CLOSED /* IP_VS_SCTP_EVE_SHUT_COM_CLI */ },
763 /*
764 * SHUTDOWN COMPLETE from server this is what we are expecting.
765 */
766 {IP_VS_SCTP_S_CLOSED /* IP_VS_SCTP_EVE_SHUT_COM_SER */ }
767 },
768
769 /*
770 * State : IP_VS_SCTP_S_SHUT_ACK_SER
771 * SHUTDOWN ACK from the server, awaiting for SHUTDOWN COM from client
772 */
773 /*
774 * We recieved the data chuck, keep the state unchanged. I assume
775 * that still data chuncks can be received by both the peers in
776 * SHUDOWN state
777 */
778
779 {{IP_VS_SCTP_S_SHUT_ACK_SER /* IP_VS_SCTP_EVE_DATA_CLI */ },
780 {IP_VS_SCTP_S_SHUT_ACK_SER /* IP_VS_SCTP_EVE_DATA_SER */ },
781 /*
782 * We have got an INIT from client. From the spec.“Upon receipt of
783 * an INIT in the COOKIE-WAIT state, an endpoint MUST respond with
784 * an INIT ACK using the same parameters it sent in its original
785 * INIT chunk (including its Initiate Tag, unchanged”).
786 */
787 {IP_VS_SCTP_S_INIT_CLI /* IP_VS_SCTP_EVE_INIT_CLI */ },
788 {IP_VS_SCTP_S_INIT_SER /* IP_VS_SCTP_EVE_INIT_SER */ },
789 /*
790 * INIT_ACK sent by the server, Unexpected INIT ACK, spec says,
791 * “If an INIT ACK is received by an endpoint in any state other
792 * than the COOKIE-WAIT state, the endpoint should discard the
793 * INIT ACK chunk”. Stay in the same state
794 */
795 {IP_VS_SCTP_S_SHUT_ACK_SER /* IP_VS_SCTP_EVE_INIT_ACK_CLI */ },
796 {IP_VS_SCTP_S_SHUT_ACK_SER /* IP_VS_SCTP_EVE_INIT_ACK_SER */ },
797 /*
798 * Client sent ECHO, Spec(sec 5.2.4) says it may be handled by the
799 * peer and peer shall move to the ESTABISHED. if it doesn't handle
800 * it will send ERROR chunk. So, stay in the same state
801 */
802 {IP_VS_SCTP_S_ESTABLISHED /* IP_VS_SCTP_EVE_COOKIE_ECHO_CLI */ },
803 {IP_VS_SCTP_S_ESTABLISHED /* IP_VS_SCTP_EVE_COOKIE_ECHO_SER */ },
804 /*
805 * COOKIE ACK from client, not sure what to do stay in the same state
806 */
807 {IP_VS_SCTP_S_SHUT_ACK_SER /* IP_VS_SCTP_EVE_COOKIE_ACK_CLI */ },
808 {IP_VS_SCTP_S_SHUT_ACK_SER /* IP_VS_SCTP_EVE_COOKIE_ACK_SER */ },
809 {IP_VS_SCTP_S_CLOSED /* IP_VS_SCTP_EVE_ABORT_CLI */ },
810 {IP_VS_SCTP_S_CLOSED /* IP_VS_SCTP_EVE_ABORT_SER */ },
811 /*
812 * SHUTDOWN sent from the client, move to SHUDDOWN_CLI
813 */
814 {IP_VS_SCTP_S_SHUT_CLI /* IP_VS_SCTP_EVE_SHUT_CLI */ },
815 /*
816 * SHUTDOWN sent from the server, move to SHUTDOWN_SER
817 */
818 {IP_VS_SCTP_S_SHUT_SER /* IP_VS_SCTP_EVE_SHUT_SER */ },
819 /*
820 * client sent SHUDTDOWN_ACK, this should not happen let's close
821 * the connection.
822 */
823 {IP_VS_SCTP_S_CLOSED /* IP_VS_SCTP_EVE_SHUT_ACK_CLI */ },
824 /*
825 * Server resent SHUTDOWN ACK, stay in the same state
826 */
827 {IP_VS_SCTP_S_SHUT_ACK_SER /* IP_VS_SCTP_EVE_SHUT_ACK_SER */ },
828 /*
829 * SHUTDOWN COM from client, this what we are expecting, let's close
830 * the connection
831 */
832 {IP_VS_SCTP_S_CLOSED /* IP_VS_SCTP_EVE_SHUT_COM_CLI */ },
833 /*
834 * SHUTDOWN COMPLETE from server this should not happen.
835 */
836 {IP_VS_SCTP_S_CLOSED /* IP_VS_SCTP_EVE_SHUT_COM_SER */ }
837 },
838 /*
839 * State : IP_VS_SCTP_S_CLOSED
840 */
841 {{IP_VS_SCTP_S_CLOSED /* IP_VS_SCTP_EVE_DATA_CLI */ },
842 {IP_VS_SCTP_S_CLOSED /* IP_VS_SCTP_EVE_DATA_SER */ },
843 {IP_VS_SCTP_S_INIT_CLI /* IP_VS_SCTP_EVE_INIT_CLI */ },
844 {IP_VS_SCTP_S_INIT_SER /* IP_VS_SCTP_EVE_INIT_SER */ },
845 {IP_VS_SCTP_S_CLOSED /* IP_VS_SCTP_EVE_INIT_ACK_CLI */ },
846 {IP_VS_SCTP_S_CLOSED /* IP_VS_SCTP_EVE_INIT_ACK_SER */ },
847 {IP_VS_SCTP_S_CLOSED /* IP_VS_SCTP_EVE_COOKIE_ECHO_CLI */ },
848 {IP_VS_SCTP_S_CLOSED /* IP_VS_SCTP_EVE_COOKIE_ECHO_SER */ },
849 {IP_VS_SCTP_S_CLOSED /* IP_VS_SCTP_EVE_COOKIE_ACK_CLI */ },
850 {IP_VS_SCTP_S_CLOSED /* IP_VS_SCTP_EVE_COOKIE_ACK_SER */ },
851 {IP_VS_SCTP_S_CLOSED /* IP_VS_SCTP_EVE_ABORT_CLI */ },
852 {IP_VS_SCTP_S_CLOSED /* IP_VS_SCTP_EVE_ABORT_SER */ },
853 {IP_VS_SCTP_S_CLOSED /* IP_VS_SCTP_EVE_SHUT_CLI */ },
854 {IP_VS_SCTP_S_CLOSED /* IP_VS_SCTP_EVE_SHUT_SER */ },
855 {IP_VS_SCTP_S_CLOSED /* IP_VS_SCTP_EVE_SHUT_ACK_CLI */ },
856 {IP_VS_SCTP_S_CLOSED /* IP_VS_SCTP_EVE_SHUT_ACK_SER */ },
857 {IP_VS_SCTP_S_CLOSED /* IP_VS_SCTP_EVE_SHUT_COM_CLI */ },
858 {IP_VS_SCTP_S_CLOSED /* IP_VS_SCTP_EVE_SHUT_COM_SER */ }
859 }
860 };
861
862 /*
863 * Timeout table[state]
864 */
865 static const int sctp_timeouts[IP_VS_SCTP_S_LAST + 1] = {
866 [IP_VS_SCTP_S_NONE] = 2 * HZ,
867 [IP_VS_SCTP_S_INIT_CLI] = 1 * 60 * HZ,
868 [IP_VS_SCTP_S_INIT_SER] = 1 * 60 * HZ,
869 [IP_VS_SCTP_S_INIT_ACK_CLI] = 1 * 60 * HZ,
870 [IP_VS_SCTP_S_INIT_ACK_SER] = 1 * 60 * HZ,
871 [IP_VS_SCTP_S_ECHO_CLI] = 1 * 60 * HZ,
872 [IP_VS_SCTP_S_ECHO_SER] = 1 * 60 * HZ,
873 [IP_VS_SCTP_S_ESTABLISHED] = 15 * 60 * HZ,
874 [IP_VS_SCTP_S_SHUT_CLI] = 1 * 60 * HZ,
875 [IP_VS_SCTP_S_SHUT_SER] = 1 * 60 * HZ,
876 [IP_VS_SCTP_S_SHUT_ACK_CLI] = 1 * 60 * HZ,
877 [IP_VS_SCTP_S_SHUT_ACK_SER] = 1 * 60 * HZ,
878 [IP_VS_SCTP_S_CLOSED] = 10 * HZ,
879 [IP_VS_SCTP_S_LAST] = 2 * HZ,
880 };
881
882 static const char *sctp_state_name_table[IP_VS_SCTP_S_LAST + 1] = {
883 [IP_VS_SCTP_S_NONE] = "NONE",
884 [IP_VS_SCTP_S_INIT_CLI] = "INIT_CLI",
885 [IP_VS_SCTP_S_INIT_SER] = "INIT_SER",
886 [IP_VS_SCTP_S_INIT_ACK_CLI] = "INIT_ACK_CLI",
887 [IP_VS_SCTP_S_INIT_ACK_SER] = "INIT_ACK_SER",
888 [IP_VS_SCTP_S_ECHO_CLI] = "COOKIE_ECHO_CLI",
889 [IP_VS_SCTP_S_ECHO_SER] = "COOKIE_ECHO_SER",
890 [IP_VS_SCTP_S_ESTABLISHED] = "ESTABISHED",
891 [IP_VS_SCTP_S_SHUT_CLI] = "SHUTDOWN_CLI",
892 [IP_VS_SCTP_S_SHUT_SER] = "SHUTDOWN_SER",
893 [IP_VS_SCTP_S_SHUT_ACK_CLI] = "SHUTDOWN_ACK_CLI",
894 [IP_VS_SCTP_S_SHUT_ACK_SER] = "SHUTDOWN_ACK_SER",
895 [IP_VS_SCTP_S_CLOSED] = "CLOSED",
896 [IP_VS_SCTP_S_LAST] = "BUG!"
897 };
898
899
900 static const char *sctp_state_name(int state)
901 {
902 if (state >= IP_VS_SCTP_S_LAST)
903 return "ERR!";
904 if (sctp_state_name_table[state])
905 return sctp_state_name_table[state];
906 return "?";
907 }
908
909 static inline int
910 set_sctp_state(struct ip_vs_proto_data *pd, struct ip_vs_conn *cp,
911 int direction, const struct sk_buff *skb)
912 {
913 sctp_chunkhdr_t _sctpch, *sch;
914 unsigned char chunk_type;
915 int event, next_state;
916 int ihl;
917
918 #ifdef CONFIG_IP_VS_IPV6
919 ihl = cp->af == AF_INET ? ip_hdrlen(skb) : sizeof(struct ipv6hdr);
920 #else
921 ihl = ip_hdrlen(skb);
922 #endif
923
924 sch = skb_header_pointer(skb, ihl + sizeof(sctp_sctphdr_t),
925 sizeof(_sctpch), &_sctpch);
926 if (sch == NULL)
927 return 0;
928
929 chunk_type = sch->type;
930 /*
931 * Section 3: Multiple chunks can be bundled into one SCTP packet
932 * up to the MTU size, except for the INIT, INIT ACK, and
933 * SHUTDOWN COMPLETE chunks. These chunks MUST NOT be bundled with
934 * any other chunk in a packet.
935 *
936 * Section 3.3.7: DATA chunks MUST NOT be bundled with ABORT. Control
937 * chunks (except for INIT, INIT ACK, and SHUTDOWN COMPLETE) MAY be
938 * bundled with an ABORT, but they MUST be placed before the ABORT
939 * in the SCTP packet or they will be ignored by the receiver.
940 */
941 if ((sch->type == SCTP_CID_COOKIE_ECHO) ||
942 (sch->type == SCTP_CID_COOKIE_ACK)) {
943 sch = skb_header_pointer(skb, (ihl + sizeof(sctp_sctphdr_t) +
944 sch->length), sizeof(_sctpch), &_sctpch);
945 if (sch) {
946 if (sch->type == SCTP_CID_ABORT)
947 chunk_type = sch->type;
948 }
949 }
950
951 event = sctp_events[chunk_type];
952
953 /*
954 * If the direction is IP_VS_DIR_OUTPUT, this event is from server
955 */
956 if (direction == IP_VS_DIR_OUTPUT)
957 event++;
958 /*
959 * get next state
960 */
961 next_state = sctp_states_table[cp->state][event].next_state;
962
963 if (next_state != cp->state) {
964 struct ip_vs_dest *dest = cp->dest;
965
966 IP_VS_DBG_BUF(8, "%s %s %s:%d->"
967 "%s:%d state: %s->%s conn->refcnt:%d\n",
968 pd->pp->name,
969 ((direction == IP_VS_DIR_OUTPUT) ?
970 "output " : "input "),
971 IP_VS_DBG_ADDR(cp->af, &cp->daddr),
972 ntohs(cp->dport),
973 IP_VS_DBG_ADDR(cp->af, &cp->caddr),
974 ntohs(cp->cport),
975 sctp_state_name(cp->state),
976 sctp_state_name(next_state),
977 atomic_read(&cp->refcnt));
978 if (dest) {
979 if (!(cp->flags & IP_VS_CONN_F_INACTIVE) &&
980 (next_state != IP_VS_SCTP_S_ESTABLISHED)) {
981 atomic_dec(&dest->activeconns);
982 atomic_inc(&dest->inactconns);
983 cp->flags |= IP_VS_CONN_F_INACTIVE;
984 } else if ((cp->flags & IP_VS_CONN_F_INACTIVE) &&
985 (next_state == IP_VS_SCTP_S_ESTABLISHED)) {
986 atomic_inc(&dest->activeconns);
987 atomic_dec(&dest->inactconns);
988 cp->flags &= ~IP_VS_CONN_F_INACTIVE;
989 }
990 }
991 }
992 if (likely(pd))
993 cp->timeout = pd->timeout_table[cp->state = next_state];
994 else /* What to do ? */
995 cp->timeout = sctp_timeouts[cp->state = next_state];
996
997 return 1;
998 }
999
1000 static int
1001 sctp_state_transition(struct ip_vs_conn *cp, int direction,
1002 const struct sk_buff *skb, struct ip_vs_proto_data *pd)
1003 {
1004 int ret = 0;
1005
1006 spin_lock(&cp->lock);
1007 ret = set_sctp_state(pd, cp, direction, skb);
1008 spin_unlock(&cp->lock);
1009
1010 return ret;
1011 }
1012
1013 static inline __u16 sctp_app_hashkey(__be16 port)
1014 {
1015 return (((__force u16)port >> SCTP_APP_TAB_BITS) ^ (__force u16)port)
1016 & SCTP_APP_TAB_MASK;
1017 }
1018
1019 static int sctp_register_app(struct net *net, struct ip_vs_app *inc)
1020 {
1021 struct ip_vs_app *i;
1022 __u16 hash;
1023 __be16 port = inc->port;
1024 int ret = 0;
1025 struct netns_ipvs *ipvs = net_ipvs(net);
1026 struct ip_vs_proto_data *pd = ip_vs_proto_data_get(net, IPPROTO_SCTP);
1027
1028 hash = sctp_app_hashkey(port);
1029
1030 spin_lock_bh(&ipvs->sctp_app_lock);
1031 list_for_each_entry(i, &ipvs->sctp_apps[hash], p_list) {
1032 if (i->port == port) {
1033 ret = -EEXIST;
1034 goto out;
1035 }
1036 }
1037 list_add(&inc->p_list, &ipvs->sctp_apps[hash]);
1038 atomic_inc(&pd->appcnt);
1039 out:
1040 spin_unlock_bh(&ipvs->sctp_app_lock);
1041
1042 return ret;
1043 }
1044
1045 static void sctp_unregister_app(struct net *net, struct ip_vs_app *inc)
1046 {
1047 struct netns_ipvs *ipvs = net_ipvs(net);
1048 struct ip_vs_proto_data *pd = ip_vs_proto_data_get(net, IPPROTO_SCTP);
1049
1050 spin_lock_bh(&ipvs->sctp_app_lock);
1051 atomic_dec(&pd->appcnt);
1052 list_del(&inc->p_list);
1053 spin_unlock_bh(&ipvs->sctp_app_lock);
1054 }
1055
1056 static int sctp_app_conn_bind(struct ip_vs_conn *cp)
1057 {
1058 struct netns_ipvs *ipvs = net_ipvs(ip_vs_conn_net(cp));
1059 int hash;
1060 struct ip_vs_app *inc;
1061 int result = 0;
1062
1063 /* Default binding: bind app only for NAT */
1064 if (IP_VS_FWD_METHOD(cp) != IP_VS_CONN_F_MASQ)
1065 return 0;
1066 /* Lookup application incarnations and bind the right one */
1067 hash = sctp_app_hashkey(cp->vport);
1068
1069 spin_lock(&ipvs->sctp_app_lock);
1070 list_for_each_entry(inc, &ipvs->sctp_apps[hash], p_list) {
1071 if (inc->port == cp->vport) {
1072 if (unlikely(!ip_vs_app_inc_get(inc)))
1073 break;
1074 spin_unlock(&ipvs->sctp_app_lock);
1075
1076 IP_VS_DBG_BUF(9, "%s: Binding conn %s:%u->"
1077 "%s:%u to app %s on port %u\n",
1078 __func__,
1079 IP_VS_DBG_ADDR(cp->af, &cp->caddr),
1080 ntohs(cp->cport),
1081 IP_VS_DBG_ADDR(cp->af, &cp->vaddr),
1082 ntohs(cp->vport),
1083 inc->name, ntohs(inc->port));
1084 cp->app = inc;
1085 if (inc->init_conn)
1086 result = inc->init_conn(inc, cp);
1087 goto out;
1088 }
1089 }
1090 spin_unlock(&ipvs->sctp_app_lock);
1091 out:
1092 return result;
1093 }
1094
1095 /* ---------------------------------------------
1096 * timeouts is netns related now.
1097 * ---------------------------------------------
1098 */
1099 static void __ip_vs_sctp_init(struct net *net, struct ip_vs_proto_data *pd)
1100 {
1101 struct netns_ipvs *ipvs = net_ipvs(net);
1102
1103 ip_vs_init_hash_table(ipvs->sctp_apps, SCTP_APP_TAB_SIZE);
1104 spin_lock_init(&ipvs->sctp_app_lock);
1105 pd->timeout_table = ip_vs_create_timeout_table((int *)sctp_timeouts,
1106 sizeof(sctp_timeouts));
1107 }
1108
1109 static void __ip_vs_sctp_exit(struct net *net, struct ip_vs_proto_data *pd)
1110 {
1111 kfree(pd->timeout_table);
1112 }
1113
1114 struct ip_vs_protocol ip_vs_protocol_sctp = {
1115 .name = "SCTP",
1116 .protocol = IPPROTO_SCTP,
1117 .num_states = IP_VS_SCTP_S_LAST,
1118 .dont_defrag = 0,
1119 .init = NULL,
1120 .exit = NULL,
1121 .init_netns = __ip_vs_sctp_init,
1122 .exit_netns = __ip_vs_sctp_exit,
1123 .register_app = sctp_register_app,
1124 .unregister_app = sctp_unregister_app,
1125 .conn_schedule = sctp_conn_schedule,
1126 .conn_in_get = ip_vs_conn_in_get_proto,
1127 .conn_out_get = ip_vs_conn_out_get_proto,
1128 .snat_handler = sctp_snat_handler,
1129 .dnat_handler = sctp_dnat_handler,
1130 .csum_check = sctp_csum_check,
1131 .state_name = sctp_state_name,
1132 .state_transition = sctp_state_transition,
1133 .app_conn_bind = sctp_app_conn_bind,
1134 .debug_packet = ip_vs_tcpudp_debug_packet,
1135 .timeout_change = NULL,
1136 };
This page took 0.053319 seconds and 5 git commands to generate.