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