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