1 #include <linux/kernel.h>
3 #include <linux/sctp.h>
5 #include <net/ip6_checksum.h>
6 #include <linux/netfilter.h>
7 #include <linux/netfilter_ipv4.h>
8 #include <net/sctp/checksum.h>
12 sctp_conn_schedule(int af, struct sk_buff *skb, struct ip_vs_proto_data *pd,
13 int *verdict, struct ip_vs_conn **cpp,
14 struct ip_vs_iphdr *iph)
17 struct ip_vs_service *svc;
18 struct netns_ipvs *ipvs;
19 sctp_chunkhdr_t _schunkh, *sch;
20 sctp_sctphdr_t *sh, _sctph;
22 sh = skb_header_pointer(skb, iph->len, sizeof(_sctph), &_sctph);
26 sch = skb_header_pointer(skb, iph->len + sizeof(sctp_sctphdr_t),
27 sizeof(_schunkh), &_schunkh);
33 if ((sch->type == SCTP_CID_INIT || sysctl_sloppy_sctp(ipvs)) &&
34 (svc = ip_vs_service_find(net, af, skb->mark, iph->protocol,
35 &iph->daddr, sh->dest))) {
38 if (ip_vs_todrop(ipvs)) {
40 * It seems that we are very loaded.
41 * We have to drop this packet :(
48 * Let the virtual server select a real server for the
49 * incoming connection, and create a connection entry.
51 *cpp = ip_vs_schedule(svc, skb, pd, &ignored, iph);
52 if (!*cpp && ignored <= 0) {
54 *verdict = ip_vs_leave(svc, skb, pd, iph);
66 static void sctp_nat_csum(struct sk_buff *skb, sctp_sctphdr_t *sctph,
67 unsigned int sctphoff)
69 sctph->checksum = sctp_compute_cksum(skb, sctphoff);
70 skb->ip_summed = CHECKSUM_UNNECESSARY;
74 sctp_snat_handler(struct sk_buff *skb, struct ip_vs_protocol *pp,
75 struct ip_vs_conn *cp, struct ip_vs_iphdr *iph)
77 sctp_sctphdr_t *sctph;
78 unsigned int sctphoff = iph->len;
80 #ifdef CONFIG_IP_VS_IPV6
81 if (cp->af == AF_INET6 && iph->fragoffs)
85 /* csum_check requires unshared skb */
86 if (!skb_make_writable(skb, sctphoff + sizeof(*sctph)))
89 if (unlikely(cp->app != NULL)) {
90 /* Some checks before mangling */
91 if (pp->csum_check && !pp->csum_check(cp->af, skb, pp))
94 /* Call application helper if needed */
95 if (!ip_vs_app_pkt_out(cp, skb))
99 sctph = (void *) skb_network_header(skb) + sctphoff;
100 sctph->source = cp->vport;
102 sctp_nat_csum(skb, sctph, sctphoff);
108 sctp_dnat_handler(struct sk_buff *skb, struct ip_vs_protocol *pp,
109 struct ip_vs_conn *cp, struct ip_vs_iphdr *iph)
111 sctp_sctphdr_t *sctph;
112 unsigned int sctphoff = iph->len;
114 #ifdef CONFIG_IP_VS_IPV6
115 if (cp->af == AF_INET6 && iph->fragoffs)
119 /* csum_check requires unshared skb */
120 if (!skb_make_writable(skb, sctphoff + sizeof(*sctph)))
123 if (unlikely(cp->app != NULL)) {
124 /* Some checks before mangling */
125 if (pp->csum_check && !pp->csum_check(cp->af, skb, pp))
128 /* Call application helper if needed */
129 if (!ip_vs_app_pkt_in(cp, skb))
133 sctph = (void *) skb_network_header(skb) + sctphoff;
134 sctph->dest = cp->dport;
136 sctp_nat_csum(skb, sctph, sctphoff);
142 sctp_csum_check(int af, struct sk_buff *skb, struct ip_vs_protocol *pp)
144 unsigned int sctphoff;
145 struct sctphdr *sh, _sctph;
148 #ifdef CONFIG_IP_VS_IPV6
150 sctphoff = sizeof(struct ipv6hdr);
153 sctphoff = ip_hdrlen(skb);
155 sh = skb_header_pointer(skb, sctphoff, sizeof(_sctph), &_sctph);
160 val = sctp_compute_cksum(skb, sctphoff);
163 /* CRC failure, dump it. */
164 IP_VS_DBG_RL_PKT(0, af, pp, skb, 0,
165 "Failed checksum for");
171 enum ipvs_sctp_event_t {
172 IP_VS_SCTP_DATA = 0, /* DATA, SACK, HEARTBEATs */
175 IP_VS_SCTP_COOKIE_ECHO,
176 IP_VS_SCTP_COOKIE_ACK,
178 IP_VS_SCTP_SHUTDOWN_ACK,
179 IP_VS_SCTP_SHUTDOWN_COMPLETE,
182 IP_VS_SCTP_EVENT_LAST
185 /* RFC 2960, 3.2 Chunk Field Descriptions */
186 static __u8 sctp_events[] = {
187 [SCTP_CID_DATA] = IP_VS_SCTP_DATA,
188 [SCTP_CID_INIT] = IP_VS_SCTP_INIT,
189 [SCTP_CID_INIT_ACK] = IP_VS_SCTP_INIT_ACK,
190 [SCTP_CID_SACK] = IP_VS_SCTP_DATA,
191 [SCTP_CID_HEARTBEAT] = IP_VS_SCTP_DATA,
192 [SCTP_CID_HEARTBEAT_ACK] = IP_VS_SCTP_DATA,
193 [SCTP_CID_ABORT] = IP_VS_SCTP_ABORT,
194 [SCTP_CID_SHUTDOWN] = IP_VS_SCTP_SHUTDOWN,
195 [SCTP_CID_SHUTDOWN_ACK] = IP_VS_SCTP_SHUTDOWN_ACK,
196 [SCTP_CID_ERROR] = IP_VS_SCTP_ERROR,
197 [SCTP_CID_COOKIE_ECHO] = IP_VS_SCTP_COOKIE_ECHO,
198 [SCTP_CID_COOKIE_ACK] = IP_VS_SCTP_COOKIE_ACK,
199 [SCTP_CID_ECN_ECNE] = IP_VS_SCTP_DATA,
200 [SCTP_CID_ECN_CWR] = IP_VS_SCTP_DATA,
201 [SCTP_CID_SHUTDOWN_COMPLETE] = IP_VS_SCTP_SHUTDOWN_COMPLETE,
205 * See RFC 2960, 4. SCTP Association State Diagram
207 * New states (not in diagram):
208 * - INIT1 state: use shorter timeout for dropped INIT packets
209 * - REJECTED state: use shorter timeout if INIT is rejected with ABORT
210 * - INIT, COOKIE_SENT, COOKIE_REPLIED, COOKIE states: for better debugging
212 * The states are as seen in real server. In the diagram, INIT1, INIT,
213 * COOKIE_SENT and COOKIE_REPLIED processing happens in CLOSED state.
215 * States as per packets from client (C) and server (S):
217 * Setup of client connection:
218 * IP_VS_SCTP_S_INIT1: First C:INIT sent, wait for S:INIT-ACK
219 * IP_VS_SCTP_S_INIT: Next C:INIT sent, wait for S:INIT-ACK
220 * IP_VS_SCTP_S_COOKIE_SENT: S:INIT-ACK sent, wait for C:COOKIE-ECHO
221 * IP_VS_SCTP_S_COOKIE_REPLIED: C:COOKIE-ECHO sent, wait for S:COOKIE-ACK
223 * Setup of server connection:
224 * IP_VS_SCTP_S_COOKIE_WAIT: S:INIT sent, wait for C:INIT-ACK
225 * IP_VS_SCTP_S_COOKIE: C:INIT-ACK sent, wait for S:COOKIE-ECHO
226 * IP_VS_SCTP_S_COOKIE_ECHOED: S:COOKIE-ECHO sent, wait for C:COOKIE-ACK
229 #define sNO IP_VS_SCTP_S_NONE
230 #define sI1 IP_VS_SCTP_S_INIT1
231 #define sIN IP_VS_SCTP_S_INIT
232 #define sCS IP_VS_SCTP_S_COOKIE_SENT
233 #define sCR IP_VS_SCTP_S_COOKIE_REPLIED
234 #define sCW IP_VS_SCTP_S_COOKIE_WAIT
235 #define sCO IP_VS_SCTP_S_COOKIE
236 #define sCE IP_VS_SCTP_S_COOKIE_ECHOED
237 #define sES IP_VS_SCTP_S_ESTABLISHED
238 #define sSS IP_VS_SCTP_S_SHUTDOWN_SENT
239 #define sSR IP_VS_SCTP_S_SHUTDOWN_RECEIVED
240 #define sSA IP_VS_SCTP_S_SHUTDOWN_ACK_SENT
241 #define sRJ IP_VS_SCTP_S_REJECTED
242 #define sCL IP_VS_SCTP_S_CLOSED
244 static const __u8 sctp_states
245 [IP_VS_DIR_LAST][IP_VS_SCTP_EVENT_LAST][IP_VS_SCTP_S_LAST] = {
247 /* sNO, sI1, sIN, sCS, sCR, sCW, sCO, sCE, sES, sSS, sSR, sSA, sRJ, sCL*/
248 /* d */{sES, sI1, sIN, sCS, sCR, sCW, sCO, sCE, sES, sSS, sSR, sSA, sRJ, sCL},
249 /* i */{sI1, sIN, sIN, sCS, sCR, sCW, sCO, sCE, sES, sSS, sSR, sSA, sIN, sIN},
250 /* i_a */{sCW, sCW, sCW, sCS, sCR, sCO, sCO, sCE, sES, sSS, sSR, sSA, sRJ, sCL},
251 /* c_e */{sCR, sIN, sIN, sCR, sCR, sCW, sCO, sCE, sES, sSS, sSR, sSA, sRJ, sCL},
252 /* c_a */{sES, sI1, sIN, sCS, sCR, sCW, sCO, sES, sES, sSS, sSR, sSA, sRJ, sCL},
253 /* s */{sSR, sI1, sIN, sCS, sCR, sCW, sCO, sCE, sSR, sSS, sSR, sSA, sRJ, sCL},
254 /* s_a */{sCL, sIN, sIN, sCS, sCR, sCW, sCO, sCE, sES, sCL, sSR, sCL, sRJ, sCL},
255 /* s_c */{sCL, sCL, sCL, sCS, sCR, sCW, sCO, sCE, sES, sSS, sSR, sCL, sRJ, sCL},
256 /* err */{sCL, sI1, sIN, sCS, sCR, sCW, sCO, sCL, sES, sSS, sSR, sSA, sRJ, sCL},
257 /* ab */{sCL, sCL, sCL, sCL, sCL, sRJ, sCL, sCL, sCL, sCL, sCL, sCL, sCL, sCL},
260 /* sNO, sI1, sIN, sCS, sCR, sCW, sCO, sCE, sES, sSS, sSR, sSA, sRJ, sCL*/
261 /* d */{sES, sI1, sIN, sCS, sCR, sCW, sCO, sCE, sES, sSS, sSR, sSA, sRJ, sCL},
262 /* i */{sCW, sCW, sCW, sCW, sCW, sCW, sCW, sCW, sES, sCW, sCW, sCW, sCW, sCW},
263 /* i_a */{sCS, sCS, sCS, sCS, sCR, sCW, sCO, sCE, sES, sSS, sSR, sSA, sRJ, sCL},
264 /* c_e */{sCE, sCE, sCE, sCE, sCE, sCE, sCE, sCE, sES, sSS, sSR, sSA, sRJ, sCL},
265 /* c_a */{sES, sES, sES, sES, sES, sES, sES, sES, sES, sSS, sSR, sSA, sRJ, sCL},
266 /* s */{sSS, sSS, sSS, sSS, sSS, sSS, sSS, sSS, sSS, sSS, sSR, sSA, sRJ, sCL},
267 /* s_a */{sSA, sSA, sSA, sSA, sSA, sCW, sCO, sCE, sES, sSA, sSA, sSA, sRJ, sCL},
268 /* s_c */{sCL, sI1, sIN, sCS, sCR, sCW, sCO, sCE, sES, sSS, sSR, sSA, sRJ, sCL},
269 /* err */{sCL, sCL, sCL, sCL, sCL, sCW, sCO, sCE, sES, sSS, sSR, sSA, sRJ, sCL},
270 /* ab */{sCL, sRJ, sCL, sCL, sCL, sCL, sCL, sCL, sCL, sCL, sCL, sCL, sCL, sCL},
273 /* sNO, sI1, sIN, sCS, sCR, sCW, sCO, sCE, sES, sSS, sSR, sSA, sRJ, sCL*/
274 /* d */{sES, sI1, sIN, sCS, sCR, sES, sCO, sCE, sES, sSS, sSR, sSA, sRJ, sCL},
275 /* i */{sI1, sIN, sIN, sIN, sIN, sIN, sCO, sCE, sES, sSS, sSR, sSA, sIN, sIN},
276 /* i_a */{sCE, sCE, sCE, sCE, sCE, sCE, sCO, sCE, sES, sSS, sSR, sSA, sRJ, sCL},
277 /* c_e */{sES, sES, sES, sES, sES, sES, sCO, sCE, sES, sSS, sSR, sSA, sRJ, sCL},
278 /* c_a */{sES, sI1, sIN, sES, sES, sCW, sES, sES, sES, sSS, sSR, sSA, sRJ, sCL},
279 /* s */{sSR, sI1, sIN, sCS, sCR, sCW, sCO, sCE, sSR, sSS, sSR, sSA, sRJ, sCL},
280 /* s_a */{sCL, sIN, sIN, sCS, sCR, sCW, sCO, sCE, sCL, sCL, sSR, sCL, sRJ, sCL},
281 /* s_c */{sCL, sCL, sCL, sCL, sCL, sCW, sCO, sCE, sES, sSS, sCL, sCL, sRJ, sCL},
282 /* err */{sCL, sI1, sIN, sCS, sCR, sCW, sCO, sCE, sES, sSS, sSR, sSA, sRJ, sCL},
283 /* ab */{sCL, sCL, sCL, sCL, sCL, sRJ, sCL, sCL, sCL, sCL, sCL, sCL, sCL, sCL},
287 #define IP_VS_SCTP_MAX_RTO ((60 + 1) * HZ)
289 /* Timeout table[state] */
290 static const int sctp_timeouts[IP_VS_SCTP_S_LAST + 1] = {
291 [IP_VS_SCTP_S_NONE] = 2 * HZ,
292 [IP_VS_SCTP_S_INIT1] = (0 + 3 + 1) * HZ,
293 [IP_VS_SCTP_S_INIT] = IP_VS_SCTP_MAX_RTO,
294 [IP_VS_SCTP_S_COOKIE_SENT] = IP_VS_SCTP_MAX_RTO,
295 [IP_VS_SCTP_S_COOKIE_REPLIED] = IP_VS_SCTP_MAX_RTO,
296 [IP_VS_SCTP_S_COOKIE_WAIT] = IP_VS_SCTP_MAX_RTO,
297 [IP_VS_SCTP_S_COOKIE] = IP_VS_SCTP_MAX_RTO,
298 [IP_VS_SCTP_S_COOKIE_ECHOED] = IP_VS_SCTP_MAX_RTO,
299 [IP_VS_SCTP_S_ESTABLISHED] = 15 * 60 * HZ,
300 [IP_VS_SCTP_S_SHUTDOWN_SENT] = IP_VS_SCTP_MAX_RTO,
301 [IP_VS_SCTP_S_SHUTDOWN_RECEIVED] = IP_VS_SCTP_MAX_RTO,
302 [IP_VS_SCTP_S_SHUTDOWN_ACK_SENT] = IP_VS_SCTP_MAX_RTO,
303 [IP_VS_SCTP_S_REJECTED] = (0 + 3 + 1) * HZ,
304 [IP_VS_SCTP_S_CLOSED] = IP_VS_SCTP_MAX_RTO,
305 [IP_VS_SCTP_S_LAST] = 2 * HZ,
308 static const char *sctp_state_name_table[IP_VS_SCTP_S_LAST + 1] = {
309 [IP_VS_SCTP_S_NONE] = "NONE",
310 [IP_VS_SCTP_S_INIT1] = "INIT1",
311 [IP_VS_SCTP_S_INIT] = "INIT",
312 [IP_VS_SCTP_S_COOKIE_SENT] = "C-SENT",
313 [IP_VS_SCTP_S_COOKIE_REPLIED] = "C-REPLIED",
314 [IP_VS_SCTP_S_COOKIE_WAIT] = "C-WAIT",
315 [IP_VS_SCTP_S_COOKIE] = "COOKIE",
316 [IP_VS_SCTP_S_COOKIE_ECHOED] = "C-ECHOED",
317 [IP_VS_SCTP_S_ESTABLISHED] = "ESTABLISHED",
318 [IP_VS_SCTP_S_SHUTDOWN_SENT] = "S-SENT",
319 [IP_VS_SCTP_S_SHUTDOWN_RECEIVED] = "S-RECEIVED",
320 [IP_VS_SCTP_S_SHUTDOWN_ACK_SENT] = "S-ACK-SENT",
321 [IP_VS_SCTP_S_REJECTED] = "REJECTED",
322 [IP_VS_SCTP_S_CLOSED] = "CLOSED",
323 [IP_VS_SCTP_S_LAST] = "BUG!",
327 static const char *sctp_state_name(int state)
329 if (state >= IP_VS_SCTP_S_LAST)
331 if (sctp_state_name_table[state])
332 return sctp_state_name_table[state];
337 set_sctp_state(struct ip_vs_proto_data *pd, struct ip_vs_conn *cp,
338 int direction, const struct sk_buff *skb)
340 sctp_chunkhdr_t _sctpch, *sch;
341 unsigned char chunk_type;
342 int event, next_state;
345 #ifdef CONFIG_IP_VS_IPV6
346 ihl = cp->af == AF_INET ? ip_hdrlen(skb) : sizeof(struct ipv6hdr);
348 ihl = ip_hdrlen(skb);
351 cofs = ihl + sizeof(sctp_sctphdr_t);
352 sch = skb_header_pointer(skb, cofs, sizeof(_sctpch), &_sctpch);
356 chunk_type = sch->type;
358 * Section 3: Multiple chunks can be bundled into one SCTP packet
359 * up to the MTU size, except for the INIT, INIT ACK, and
360 * SHUTDOWN COMPLETE chunks. These chunks MUST NOT be bundled with
361 * any other chunk in a packet.
363 * Section 3.3.7: DATA chunks MUST NOT be bundled with ABORT. Control
364 * chunks (except for INIT, INIT ACK, and SHUTDOWN COMPLETE) MAY be
365 * bundled with an ABORT, but they MUST be placed before the ABORT
366 * in the SCTP packet or they will be ignored by the receiver.
368 if ((sch->type == SCTP_CID_COOKIE_ECHO) ||
369 (sch->type == SCTP_CID_COOKIE_ACK)) {
370 int clen = ntohs(sch->length);
372 if (clen >= sizeof(sctp_chunkhdr_t)) {
373 sch = skb_header_pointer(skb, cofs + ALIGN(clen, 4),
374 sizeof(_sctpch), &_sctpch);
375 if (sch && sch->type == SCTP_CID_ABORT)
376 chunk_type = sch->type;
380 event = (chunk_type < sizeof(sctp_events)) ?
381 sctp_events[chunk_type] : IP_VS_SCTP_DATA;
383 /* Update direction to INPUT_ONLY if necessary
384 * or delete NO_OUTPUT flag if output packet detected
386 if (cp->flags & IP_VS_CONN_F_NOOUTPUT) {
387 if (direction == IP_VS_DIR_OUTPUT)
388 cp->flags &= ~IP_VS_CONN_F_NOOUTPUT;
390 direction = IP_VS_DIR_INPUT_ONLY;
393 next_state = sctp_states[direction][event][cp->state];
395 if (next_state != cp->state) {
396 struct ip_vs_dest *dest = cp->dest;
398 IP_VS_DBG_BUF(8, "%s %s %s:%d->"
399 "%s:%d state: %s->%s conn->refcnt:%d\n",
401 ((direction == IP_VS_DIR_OUTPUT) ?
402 "output " : "input "),
403 IP_VS_DBG_ADDR(cp->af, &cp->daddr),
405 IP_VS_DBG_ADDR(cp->af, &cp->caddr),
407 sctp_state_name(cp->state),
408 sctp_state_name(next_state),
409 atomic_read(&cp->refcnt));
411 if (!(cp->flags & IP_VS_CONN_F_INACTIVE) &&
412 (next_state != IP_VS_SCTP_S_ESTABLISHED)) {
413 atomic_dec(&dest->activeconns);
414 atomic_inc(&dest->inactconns);
415 cp->flags |= IP_VS_CONN_F_INACTIVE;
416 } else if ((cp->flags & IP_VS_CONN_F_INACTIVE) &&
417 (next_state == IP_VS_SCTP_S_ESTABLISHED)) {
418 atomic_inc(&dest->activeconns);
419 atomic_dec(&dest->inactconns);
420 cp->flags &= ~IP_VS_CONN_F_INACTIVE;
425 cp->timeout = pd->timeout_table[cp->state = next_state];
426 else /* What to do ? */
427 cp->timeout = sctp_timeouts[cp->state = next_state];
431 sctp_state_transition(struct ip_vs_conn *cp, int direction,
432 const struct sk_buff *skb, struct ip_vs_proto_data *pd)
434 spin_lock_bh(&cp->lock);
435 set_sctp_state(pd, cp, direction, skb);
436 spin_unlock_bh(&cp->lock);
439 static inline __u16 sctp_app_hashkey(__be16 port)
441 return (((__force u16)port >> SCTP_APP_TAB_BITS) ^ (__force u16)port)
445 static int sctp_register_app(struct net *net, struct ip_vs_app *inc)
449 __be16 port = inc->port;
451 struct netns_ipvs *ipvs = net_ipvs(net);
452 struct ip_vs_proto_data *pd = ip_vs_proto_data_get(net, IPPROTO_SCTP);
454 hash = sctp_app_hashkey(port);
456 list_for_each_entry(i, &ipvs->sctp_apps[hash], p_list) {
457 if (i->port == port) {
462 list_add_rcu(&inc->p_list, &ipvs->sctp_apps[hash]);
463 atomic_inc(&pd->appcnt);
469 static void sctp_unregister_app(struct net *net, struct ip_vs_app *inc)
471 struct ip_vs_proto_data *pd = ip_vs_proto_data_get(net, IPPROTO_SCTP);
473 atomic_dec(&pd->appcnt);
474 list_del_rcu(&inc->p_list);
477 static int sctp_app_conn_bind(struct ip_vs_conn *cp)
479 struct netns_ipvs *ipvs = net_ipvs(ip_vs_conn_net(cp));
481 struct ip_vs_app *inc;
484 /* Default binding: bind app only for NAT */
485 if (IP_VS_FWD_METHOD(cp) != IP_VS_CONN_F_MASQ)
487 /* Lookup application incarnations and bind the right one */
488 hash = sctp_app_hashkey(cp->vport);
491 list_for_each_entry_rcu(inc, &ipvs->sctp_apps[hash], p_list) {
492 if (inc->port == cp->vport) {
493 if (unlikely(!ip_vs_app_inc_get(inc)))
497 IP_VS_DBG_BUF(9, "%s: Binding conn %s:%u->"
498 "%s:%u to app %s on port %u\n",
500 IP_VS_DBG_ADDR(cp->af, &cp->caddr),
502 IP_VS_DBG_ADDR(cp->af, &cp->vaddr),
504 inc->name, ntohs(inc->port));
507 result = inc->init_conn(inc, cp);
516 /* ---------------------------------------------
517 * timeouts is netns related now.
518 * ---------------------------------------------
520 static int __ip_vs_sctp_init(struct net *net, struct ip_vs_proto_data *pd)
522 struct netns_ipvs *ipvs = net_ipvs(net);
524 ip_vs_init_hash_table(ipvs->sctp_apps, SCTP_APP_TAB_SIZE);
525 pd->timeout_table = ip_vs_create_timeout_table((int *)sctp_timeouts,
526 sizeof(sctp_timeouts));
527 if (!pd->timeout_table)
532 static void __ip_vs_sctp_exit(struct net *net, struct ip_vs_proto_data *pd)
534 kfree(pd->timeout_table);
537 struct ip_vs_protocol ip_vs_protocol_sctp = {
539 .protocol = IPPROTO_SCTP,
540 .num_states = IP_VS_SCTP_S_LAST,
544 .init_netns = __ip_vs_sctp_init,
545 .exit_netns = __ip_vs_sctp_exit,
546 .register_app = sctp_register_app,
547 .unregister_app = sctp_unregister_app,
548 .conn_schedule = sctp_conn_schedule,
549 .conn_in_get = ip_vs_conn_in_get_proto,
550 .conn_out_get = ip_vs_conn_out_get_proto,
551 .snat_handler = sctp_snat_handler,
552 .dnat_handler = sctp_dnat_handler,
553 .csum_check = sctp_csum_check,
554 .state_name = sctp_state_name,
555 .state_transition = sctp_state_transition,
556 .app_conn_bind = sctp_app_conn_bind,
557 .debug_packet = ip_vs_tcpudp_debug_packet,
558 .timeout_change = NULL,