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