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