TTY: serial, remove dead code from 68328
[linux-2.6/linux-acpi-2.6/ibm-acpi-2.6.git] / net / netfilter / ipvs / ip_vs_proto_sctp.c
blobd12ed53ec95ff6a67950ce39b902e6816d40b249
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>
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)
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;
21 ip_vs_fill_iphdr(af, skb_network_header(skb), &iph);
23 sh = skb_header_pointer(skb, iph.len, sizeof(_sctph), &_sctph);
24 if (sh == NULL)
25 return 0;
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;
37 if (ip_vs_todrop(net_ipvs(net))) {
39 * It seems that we are very loaded.
40 * We have to drop this packet :(
42 ip_vs_service_put(svc);
43 *verdict = NF_DROP;
44 return 0;
47 * Let the virtual server select a real server for the
48 * incoming connection, and create a connection entry.
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;
58 return 0;
60 ip_vs_service_put(svc);
62 /* NF_ACCEPT */
63 return 1;
66 static int
67 sctp_snat_handler(struct sk_buff *skb,
68 struct ip_vs_protocol *pp, struct ip_vs_conn *cp)
70 sctp_sctphdr_t *sctph;
71 unsigned int sctphoff;
72 struct sk_buff *iter;
73 __be32 crc32;
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);
82 /* csum_check requires unshared skb */
83 if (!skb_make_writable(skb, sctphoff + sizeof(*sctph)))
84 return 0;
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;
91 /* Call application helper if needed */
92 if (!ip_vs_app_pkt_out(cp, skb))
93 return 0;
96 sctph = (void *) skb_network_header(skb) + sctphoff;
97 sctph->source = cp->vport;
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;
107 return 1;
110 static int
111 sctp_dnat_handler(struct sk_buff *skb,
112 struct ip_vs_protocol *pp, struct ip_vs_conn *cp)
114 sctp_sctphdr_t *sctph;
115 unsigned int sctphoff;
116 struct sk_buff *iter;
117 __be32 crc32;
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);
126 /* csum_check requires unshared skb */
127 if (!skb_make_writable(skb, sctphoff + sizeof(*sctph)))
128 return 0;
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;
135 /* Call application helper if needed */
136 if (!ip_vs_app_pkt_in(cp, skb))
137 return 0;
140 sctph = (void *) skb_network_header(skb) + sctphoff;
141 sctph->dest = cp->dport;
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;
151 return 1;
154 static int
155 sctp_csum_check(int af, struct sk_buff *skb, struct ip_vs_protocol *pp)
157 unsigned int sctphoff;
158 struct sctphdr *sh, _sctph;
159 struct sk_buff *iter;
160 __le32 cmp;
161 __le32 val;
162 __u32 tmp;
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);
171 sh = skb_header_pointer(skb, sctphoff, sizeof(_sctph), &_sctph);
172 if (sh == NULL)
173 return 0;
175 cmp = sh->checksum;
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);
182 val = sctp_end_cksum(tmp);
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;
190 return 1;
193 struct ipvs_sctp_nextstate {
194 int next_state;
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
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,
236 static struct ipvs_sctp_nextstate
237 sctp_states_table[IP_VS_SCTP_S_LAST][IP_VS_SCTP_EVE_LAST] = {
239 * STATE : IP_VS_SCTP_S_NONE
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 */ },
262 * STATE : IP_VS_SCTP_S_INIT_CLI
263 * Cient sent INIT and is waiting for reply from server(In ECHO_WAIT)
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 */ }
285 * State : IP_VS_SCTP_S_INIT_SER
286 * Server sent INIT and waiting for INIT ACK from the client
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 */ }
308 * State : IP_VS_SCTP_S_INIT_ACK_CLI
309 * Client sent INIT ACK and waiting for ECHO from the server
311 {{IP_VS_SCTP_S_CLOSED /* IP_VS_SCTP_EVE_DATA_CLI */ },
312 {IP_VS_SCTP_S_CLOSED /* IP_VS_SCTP_EVE_DATA_SER */ },
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”).
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 */ },
322 * INIT_ACK has been resent by the client, let us stay is in
323 * the same state
325 {IP_VS_SCTP_S_INIT_ACK_CLI /* IP_VS_SCTP_EVE_INIT_ACK_CLI */ },
327 * INIT_ACK sent by the server, close the connection
329 {IP_VS_SCTP_S_CLOSED /* IP_VS_SCTP_EVE_INIT_ACK_SER */ },
331 * ECHO by client, it should not happen, close the connection
333 {IP_VS_SCTP_S_CLOSED /* IP_VS_SCTP_EVE_COOKIE_ECHO_CLI */ },
335 * ECHO by server, this is what we are expecting, move to ECHO_SER
337 {IP_VS_SCTP_S_ECHO_SER /* IP_VS_SCTP_EVE_COOKIE_ECHO_SER */ },
339 * COOKIE ACK from client, it should not happen, close the connection
341 {IP_VS_SCTP_S_CLOSED /* IP_VS_SCTP_EVE_COOKIE_ACK_CLI */ },
343 * Unexpected COOKIE ACK from server, staty in the same state
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 */ }
356 * State : IP_VS_SCTP_S_INIT_ACK_SER
357 * Server sent INIT ACK and waiting for ECHO from the client
359 {{IP_VS_SCTP_S_CLOSED /* IP_VS_SCTP_EVE_DATA_CLI */ },
360 {IP_VS_SCTP_S_CLOSED /* IP_VS_SCTP_EVE_DATA_SER */ },
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”).
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 */ },
370 * Unexpected INIT_ACK by the client, let us close the connection
372 {IP_VS_SCTP_S_CLOSED /* IP_VS_SCTP_EVE_INIT_ACK_CLI */ },
374 * INIT_ACK resent by the server, let us move to same state
376 {IP_VS_SCTP_S_INIT_ACK_SER /* IP_VS_SCTP_EVE_INIT_ACK_SER */ },
378 * Client send the ECHO, this is what we are expecting,
379 * move to ECHO_CLI
381 {IP_VS_SCTP_S_ECHO_CLI /* IP_VS_SCTP_EVE_COOKIE_ECHO_CLI */ },
383 * ECHO received from the server, Not sure what to do,
384 * let us close it
386 {IP_VS_SCTP_S_CLOSED /* IP_VS_SCTP_EVE_COOKIE_ECHO_SER */ },
388 * COOKIE ACK from client, let us stay in the same state
390 {IP_VS_SCTP_S_INIT_ACK_SER /* IP_VS_SCTP_EVE_COOKIE_ACK_CLI */ },
392 * COOKIE ACK from server, hmm... this should not happen, lets close
393 * the connection.
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 */ }
406 * State : IP_VS_SCTP_S_ECHO_CLI
407 * Cient sent ECHO and waiting COOKEI ACK from the Server
409 {{IP_VS_SCTP_S_CLOSED /* IP_VS_SCTP_EVE_DATA_CLI */ },
410 {IP_VS_SCTP_S_CLOSED /* IP_VS_SCTP_EVE_DATA_SER */ },
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”).
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 */ },
420 * INIT_ACK has been by the client, let us close the connection
422 {IP_VS_SCTP_S_CLOSED /* IP_VS_SCTP_EVE_INIT_ACK_CLI */ },
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
429 {IP_VS_SCTP_S_ECHO_CLI /* IP_VS_SCTP_EVE_INIT_ACK_SER */ },
431 * Client resent the ECHO, let us stay in the same state
433 {IP_VS_SCTP_S_ECHO_CLI /* IP_VS_SCTP_EVE_COOKIE_ECHO_CLI */ },
435 * ECHO received from the server, Not sure what to do,
436 * let us close it
438 {IP_VS_SCTP_S_CLOSED /* IP_VS_SCTP_EVE_COOKIE_ECHO_SER */ },
440 * COOKIE ACK from client, this shoud not happen, let's close the
441 * connection
443 {IP_VS_SCTP_S_CLOSED /* IP_VS_SCTP_EVE_COOKIE_ACK_CLI */ },
445 * COOKIE ACK from server, this is what we are awaiting,lets move to
446 * ESTABLISHED.
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 */ }
459 * State : IP_VS_SCTP_S_ECHO_SER
460 * Server sent ECHO and waiting COOKEI ACK from the client
462 {{IP_VS_SCTP_S_CLOSED /* IP_VS_SCTP_EVE_DATA_CLI */ },
463 {IP_VS_SCTP_S_CLOSED /* IP_VS_SCTP_EVE_DATA_SER */ },
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”).
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 */ },
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
478 {IP_VS_SCTP_S_ECHO_SER /* IP_VS_SCTP_EVE_INIT_ACK_CLI */ },
480 * INIT_ACK has been by the server, let us close the connection
482 {IP_VS_SCTP_S_CLOSED /* IP_VS_SCTP_EVE_INIT_ACK_SER */ },
484 * Client sent the ECHO, not sure what to do, let's close the
485 * connection.
487 {IP_VS_SCTP_S_CLOSED /* IP_VS_SCTP_EVE_COOKIE_ECHO_CLI */ },
489 * ECHO resent by the server, stay in the same state
491 {IP_VS_SCTP_S_ECHO_SER /* IP_VS_SCTP_EVE_COOKIE_ECHO_SER */ },
493 * COOKIE ACK from client, this is what we are expecting, let's move
494 * to ESTABLISHED.
496 {IP_VS_SCTP_S_ESTABLISHED /* IP_VS_SCTP_EVE_COOKIE_ACK_CLI */ },
498 * COOKIE ACK from server, this should not happen, lets close the
499 * connection.
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 */ }
512 * State : IP_VS_SCTP_S_ESTABLISHED
513 * Association established
515 {{IP_VS_SCTP_S_ESTABLISHED /* IP_VS_SCTP_EVE_DATA_CLI */ },
516 {IP_VS_SCTP_S_ESTABLISHED /* IP_VS_SCTP_EVE_DATA_SER */ },
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”).
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 */ },
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
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 */ },
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
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 */ },
541 * COOKIE ACK from client, not sure what to do stay in the same state
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 */ },
548 * SHUTDOWN from the client, move to SHUDDOWN_CLI
550 {IP_VS_SCTP_S_SHUT_CLI /* IP_VS_SCTP_EVE_SHUT_CLI */ },
552 * SHUTDOWN from the server, move to SHUTDOWN_SER
554 {IP_VS_SCTP_S_SHUT_SER /* IP_VS_SCTP_EVE_SHUT_SER */ },
556 * client sent SHUDTDOWN_ACK, this should not happen, let's close
557 * the connection
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 */ }
565 * State : IP_VS_SCTP_S_SHUT_CLI
566 * SHUTDOWN sent from the client, waitinf for SHUT ACK from the server
569 * We received 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
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 */ },
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”).
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 */ },
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
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 */ },
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
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 */ },
600 * COOKIE ACK from client, not sure what to do stay in the same state
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 */ },
607 * SHUTDOWN resent from the client, move to SHUDDOWN_CLI
609 {IP_VS_SCTP_S_SHUT_CLI /* IP_VS_SCTP_EVE_SHUT_CLI */ },
611 * SHUTDOWN from the server, move to SHUTDOWN_SER
613 {IP_VS_SCTP_S_SHUT_SER /* IP_VS_SCTP_EVE_SHUT_SER */ },
615 * client sent SHUDTDOWN_ACK, this should not happen, let's close
616 * the connection
618 {IP_VS_SCTP_S_CLOSED /* IP_VS_SCTP_EVE_SHUT_ACK_CLI */ },
620 * Server sent SHUTDOWN ACK, this is what we are expecting, let's move
621 * to SHUDOWN_ACK_SER
623 {IP_VS_SCTP_S_SHUT_ACK_SER /* IP_VS_SCTP_EVE_SHUT_ACK_SER */ },
625 * SHUTDOWN COM from client, this should not happen, let's close the
626 * connection
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 */ }
632 * State : IP_VS_SCTP_S_SHUT_SER
633 * SHUTDOWN sent from the server, waitinf for SHUTDOWN ACK from client
636 * We received 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
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 */ },
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”).
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 */ },
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
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 */ },
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
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 */ },
667 * COOKIE ACK from client, not sure what to do stay in the same state
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 */ },
674 * SHUTDOWN resent from the client, move to SHUDDOWN_CLI
676 {IP_VS_SCTP_S_SHUT_CLI /* IP_VS_SCTP_EVE_SHUT_CLI */ },
678 * SHUTDOWN resent from the server, move to SHUTDOWN_SER
680 {IP_VS_SCTP_S_SHUT_SER /* IP_VS_SCTP_EVE_SHUT_SER */ },
682 * client sent SHUDTDOWN_ACK, this is what we are expecting, let's
683 * move to SHUT_ACK_CLI
685 {IP_VS_SCTP_S_SHUT_ACK_CLI /* IP_VS_SCTP_EVE_SHUT_ACK_CLI */ },
687 * Server sent SHUTDOWN ACK, this should not happen, let's close the
688 * connection
690 {IP_VS_SCTP_S_CLOSED /* IP_VS_SCTP_EVE_SHUT_ACK_SER */ },
692 * SHUTDOWN COM from client, this should not happen, let's close the
693 * connection
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 */ }
700 * State : IP_VS_SCTP_S_SHUT_ACK_CLI
701 * SHUTDOWN ACK from the client, awaiting for SHUTDOWN COM from server
704 * We received 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
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 */ },
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”).
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 */ },
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
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 */ },
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
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 */ },
735 * COOKIE ACK from client, not sure what to do stay in the same state
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 */ },
742 * SHUTDOWN sent from the client, move to SHUDDOWN_CLI
744 {IP_VS_SCTP_S_SHUT_CLI /* IP_VS_SCTP_EVE_SHUT_CLI */ },
746 * SHUTDOWN sent from the server, move to SHUTDOWN_SER
748 {IP_VS_SCTP_S_SHUT_SER /* IP_VS_SCTP_EVE_SHUT_SER */ },
750 * client resent SHUDTDOWN_ACK, let's stay in the same state
752 {IP_VS_SCTP_S_SHUT_ACK_CLI /* IP_VS_SCTP_EVE_SHUT_ACK_CLI */ },
754 * Server sent SHUTDOWN ACK, this should not happen, let's close the
755 * connection
757 {IP_VS_SCTP_S_CLOSED /* IP_VS_SCTP_EVE_SHUT_ACK_SER */ },
759 * SHUTDOWN COM from client, this should not happen, let's close the
760 * connection
762 {IP_VS_SCTP_S_CLOSED /* IP_VS_SCTP_EVE_SHUT_COM_CLI */ },
764 * SHUTDOWN COMPLETE from server this is what we are expecting.
766 {IP_VS_SCTP_S_CLOSED /* IP_VS_SCTP_EVE_SHUT_COM_SER */ }
770 * State : IP_VS_SCTP_S_SHUT_ACK_SER
771 * SHUTDOWN ACK from the server, awaiting for SHUTDOWN COM from client
774 * We received 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
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 */ },
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”).
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 */ },
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
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 */ },
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
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 */ },
805 * COOKIE ACK from client, not sure what to do stay in the same state
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 */ },
812 * SHUTDOWN sent from the client, move to SHUDDOWN_CLI
814 {IP_VS_SCTP_S_SHUT_CLI /* IP_VS_SCTP_EVE_SHUT_CLI */ },
816 * SHUTDOWN sent from the server, move to SHUTDOWN_SER
818 {IP_VS_SCTP_S_SHUT_SER /* IP_VS_SCTP_EVE_SHUT_SER */ },
820 * client sent SHUDTDOWN_ACK, this should not happen let's close
821 * the connection.
823 {IP_VS_SCTP_S_CLOSED /* IP_VS_SCTP_EVE_SHUT_ACK_CLI */ },
825 * Server resent SHUTDOWN ACK, stay in the same state
827 {IP_VS_SCTP_S_SHUT_ACK_SER /* IP_VS_SCTP_EVE_SHUT_ACK_SER */ },
829 * SHUTDOWN COM from client, this what we are expecting, let's close
830 * the connection
832 {IP_VS_SCTP_S_CLOSED /* IP_VS_SCTP_EVE_SHUT_COM_CLI */ },
834 * SHUTDOWN COMPLETE from server this should not happen.
836 {IP_VS_SCTP_S_CLOSED /* IP_VS_SCTP_EVE_SHUT_COM_SER */ }
839 * State : IP_VS_SCTP_S_CLOSED
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 */ }
863 * Timeout table[state]
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,
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!"
900 static const char *sctp_state_name(int state)
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 "?";
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)
913 sctp_chunkhdr_t _sctpch, *sch;
914 unsigned char chunk_type;
915 int event, next_state;
916 int ihl;
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
924 sch = skb_header_pointer(skb, ihl + sizeof(sctp_sctphdr_t),
925 sizeof(_sctpch), &_sctpch);
926 if (sch == NULL)
927 return 0;
929 chunk_type = sch->type;
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.
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.
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;
951 event = sctp_events[chunk_type];
954 * If the direction is IP_VS_DIR_OUTPUT, this event is from server
956 if (direction == IP_VS_DIR_OUTPUT)
957 event++;
959 * get next state
961 next_state = sctp_states_table[cp->state][event].next_state;
963 if (next_state != cp->state) {
964 struct ip_vs_dest *dest = cp->dest;
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;
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];
997 return 1;
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)
1004 int ret = 0;
1006 spin_lock(&cp->lock);
1007 ret = set_sctp_state(pd, cp, direction, skb);
1008 spin_unlock(&cp->lock);
1010 return ret;
1013 static inline __u16 sctp_app_hashkey(__be16 port)
1015 return (((__force u16)port >> SCTP_APP_TAB_BITS) ^ (__force u16)port)
1016 & SCTP_APP_TAB_MASK;
1019 static int sctp_register_app(struct net *net, struct ip_vs_app *inc)
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);
1028 hash = sctp_app_hashkey(port);
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;
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);
1042 return ret;
1045 static void sctp_unregister_app(struct net *net, struct ip_vs_app *inc)
1047 struct netns_ipvs *ipvs = net_ipvs(net);
1048 struct ip_vs_proto_data *pd = ip_vs_proto_data_get(net, IPPROTO_SCTP);
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);
1056 static int sctp_app_conn_bind(struct ip_vs_conn *cp)
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;
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);
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);
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;
1090 spin_unlock(&ipvs->sctp_app_lock);
1091 out:
1092 return result;
1095 /* ---------------------------------------------
1096 * timeouts is netns related now.
1097 * ---------------------------------------------
1099 static void __ip_vs_sctp_init(struct net *net, struct ip_vs_proto_data *pd)
1101 struct netns_ipvs *ipvs = net_ipvs(net);
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));
1109 static void __ip_vs_sctp_exit(struct net *net, struct ip_vs_proto_data *pd)
1111 kfree(pd->timeout_table);
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,