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