1// SPDX-License-Identifier: GPL-2.0
2#include <linux/kernel.h>
3#include <linux/ip.h>
4#include <linux/sctp.h>
5#include <net/ip.h>
6#include <net/ip6_checksum.h>
7#include <linux/netfilter.h>
8#include <linux/netfilter_ipv4.h>
9#include <net/sctp/checksum.h>
10#include <net/ip_vs.h>
11
12static int
13sctp_csum_check(int af, struct sk_buff *skb, struct ip_vs_protocol *pp);
14
15static int
16sctp_conn_schedule(struct netns_ipvs *ipvs, int af, struct sk_buff *skb,
17		   struct ip_vs_proto_data *pd,
18		   int *verdict, struct ip_vs_conn **cpp,
19		   struct ip_vs_iphdr *iph)
20{
21	struct ip_vs_service *svc;
22	struct sctp_chunkhdr _schunkh, *sch;
23	struct sctphdr *sh, _sctph;
24	__be16 _ports[2], *ports = NULL;
25
26	if (likely(!ip_vs_iph_icmp(iph))) {
27		sh = skb_header_pointer(skb, iph->len, sizeof(_sctph), &_sctph);
28		if (sh) {
29			sch = skb_header_pointer(skb, iph->len + sizeof(_sctph),
30						 sizeof(_schunkh), &_schunkh);
31			if (sch) {
32				if (sch->type == SCTP_CID_ABORT ||
33				    !(sysctl_sloppy_sctp(ipvs) ||
34				      sch->type == SCTP_CID_INIT))
35					return 1;
36				ports = &sh->source;
37			}
38		}
39	} else {
40		ports = skb_header_pointer(
41			skb, iph->len, sizeof(_ports), &_ports);
42	}
43
44	if (!ports) {
45		*verdict = NF_DROP;
46		return 0;
47	}
48
49	if (likely(!ip_vs_iph_inverse(iph)))
50		svc = ip_vs_service_find(ipvs, af, skb->mark, iph->protocol,
51					 &iph->daddr, ports[1]);
52	else
53		svc = ip_vs_service_find(ipvs, af, skb->mark, iph->protocol,
54					 &iph->saddr, ports[0]);
55	if (svc) {
56		int ignored;
57
58		if (ip_vs_todrop(ipvs)) {
59			/*
60			 * It seems that we are very loaded.
61			 * We have to drop this packet :(
62			 */
63			*verdict = NF_DROP;
64			return 0;
65		}
66		/*
67		 * Let the virtual server select a real server for the
68		 * incoming connection, and create a connection entry.
69		 */
70		*cpp = ip_vs_schedule(svc, skb, pd, &ignored, iph);
71		if (!*cpp && ignored <= 0) {
72			if (!ignored)
73				*verdict = ip_vs_leave(svc, skb, pd, iph);
74			else
75				*verdict = NF_DROP;
76			return 0;
77		}
78	}
79	/* NF_ACCEPT */
80	return 1;
81}
82
83static void sctp_nat_csum(struct sk_buff *skb, struct sctphdr *sctph,
84			  unsigned int sctphoff)
85{
86	sctph->checksum = sctp_compute_cksum(skb, sctphoff);
87	skb->ip_summed = CHECKSUM_UNNECESSARY;
88}
89
90static int
91sctp_snat_handler(struct sk_buff *skb, struct ip_vs_protocol *pp,
92		  struct ip_vs_conn *cp, struct ip_vs_iphdr *iph)
93{
94	struct sctphdr *sctph;
95	unsigned int sctphoff = iph->len;
96	bool payload_csum = false;
97
98#ifdef CONFIG_IP_VS_IPV6
99	if (cp->af == AF_INET6 && iph->fragoffs)
100		return 1;
101#endif
102
103	/* csum_check requires unshared skb */
104	if (skb_ensure_writable(skb, sctphoff + sizeof(*sctph)))
105		return 0;
106
107	if (unlikely(cp->app != NULL)) {
108		int ret;
109
110		/* Some checks before mangling */
111		if (!sctp_csum_check(cp->af, skb, pp))
112			return 0;
113
114		/* Call application helper if needed */
115		ret = ip_vs_app_pkt_out(cp, skb, iph);
116		if (ret == 0)
117			return 0;
118		/* ret=2: csum update is needed after payload mangling */
119		if (ret == 2)
120			payload_csum = true;
121	}
122
123	sctph = (void *) skb_network_header(skb) + sctphoff;
124
125	/* Only update csum if we really have to */
126	if (sctph->source != cp->vport || payload_csum ||
127	    skb->ip_summed == CHECKSUM_PARTIAL) {
128		sctph->source = cp->vport;
129		sctp_nat_csum(skb, sctph, sctphoff);
130	} else {
131		skb->ip_summed = CHECKSUM_UNNECESSARY;
132	}
133
134	return 1;
135}
136
137static int
138sctp_dnat_handler(struct sk_buff *skb, struct ip_vs_protocol *pp,
139		  struct ip_vs_conn *cp, struct ip_vs_iphdr *iph)
140{
141	struct sctphdr *sctph;
142	unsigned int sctphoff = iph->len;
143	bool payload_csum = false;
144
145#ifdef CONFIG_IP_VS_IPV6
146	if (cp->af == AF_INET6 && iph->fragoffs)
147		return 1;
148#endif
149
150	/* csum_check requires unshared skb */
151	if (skb_ensure_writable(skb, sctphoff + sizeof(*sctph)))
152		return 0;
153
154	if (unlikely(cp->app != NULL)) {
155		int ret;
156
157		/* Some checks before mangling */
158		if (!sctp_csum_check(cp->af, skb, pp))
159			return 0;
160
161		/* Call application helper if needed */
162		ret = ip_vs_app_pkt_in(cp, skb, iph);
163		if (ret == 0)
164			return 0;
165		/* ret=2: csum update is needed after payload mangling */
166		if (ret == 2)
167			payload_csum = true;
168	}
169
170	sctph = (void *) skb_network_header(skb) + sctphoff;
171
172	/* Only update csum if we really have to */
173	if (sctph->dest != cp->dport || payload_csum ||
174	    (skb->ip_summed == CHECKSUM_PARTIAL &&
175	     !(skb_dst(skb)->dev->features & NETIF_F_SCTP_CRC))) {
176		sctph->dest = cp->dport;
177		sctp_nat_csum(skb, sctph, sctphoff);
178	} else if (skb->ip_summed != CHECKSUM_PARTIAL) {
179		skb->ip_summed = CHECKSUM_UNNECESSARY;
180	}
181
182	return 1;
183}
184
185static int
186sctp_csum_check(int af, struct sk_buff *skb, struct ip_vs_protocol *pp)
187{
188	unsigned int sctphoff;
189	struct sctphdr *sh;
190	__le32 cmp, val;
191
192#ifdef CONFIG_IP_VS_IPV6
193	if (af == AF_INET6)
194		sctphoff = sizeof(struct ipv6hdr);
195	else
196#endif
197		sctphoff = ip_hdrlen(skb);
198
199	sh = (struct sctphdr *)(skb->data + sctphoff);
200	cmp = sh->checksum;
201	val = sctp_compute_cksum(skb, sctphoff);
202
203	if (val != cmp) {
204		/* CRC failure, dump it. */
205		IP_VS_DBG_RL_PKT(0, af, pp, skb, 0,
206				"Failed checksum for");
207		return 0;
208	}
209	return 1;
210}
211
212enum ipvs_sctp_event_t {
213	IP_VS_SCTP_DATA = 0,		/* DATA, SACK, HEARTBEATs */
214	IP_VS_SCTP_INIT,
215	IP_VS_SCTP_INIT_ACK,
216	IP_VS_SCTP_COOKIE_ECHO,
217	IP_VS_SCTP_COOKIE_ACK,
218	IP_VS_SCTP_SHUTDOWN,
219	IP_VS_SCTP_SHUTDOWN_ACK,
220	IP_VS_SCTP_SHUTDOWN_COMPLETE,
221	IP_VS_SCTP_ERROR,
222	IP_VS_SCTP_ABORT,
223	IP_VS_SCTP_EVENT_LAST
224};
225
226/* RFC 2960, 3.2 Chunk Field Descriptions */
227static __u8 sctp_events[] = {
228	[SCTP_CID_DATA]			= IP_VS_SCTP_DATA,
229	[SCTP_CID_INIT]			= IP_VS_SCTP_INIT,
230	[SCTP_CID_INIT_ACK]		= IP_VS_SCTP_INIT_ACK,
231	[SCTP_CID_SACK]			= IP_VS_SCTP_DATA,
232	[SCTP_CID_HEARTBEAT]		= IP_VS_SCTP_DATA,
233	[SCTP_CID_HEARTBEAT_ACK]	= IP_VS_SCTP_DATA,
234	[SCTP_CID_ABORT]		= IP_VS_SCTP_ABORT,
235	[SCTP_CID_SHUTDOWN]		= IP_VS_SCTP_SHUTDOWN,
236	[SCTP_CID_SHUTDOWN_ACK]		= IP_VS_SCTP_SHUTDOWN_ACK,
237	[SCTP_CID_ERROR]		= IP_VS_SCTP_ERROR,
238	[SCTP_CID_COOKIE_ECHO]		= IP_VS_SCTP_COOKIE_ECHO,
239	[SCTP_CID_COOKIE_ACK]		= IP_VS_SCTP_COOKIE_ACK,
240	[SCTP_CID_ECN_ECNE]		= IP_VS_SCTP_DATA,
241	[SCTP_CID_ECN_CWR]		= IP_VS_SCTP_DATA,
242	[SCTP_CID_SHUTDOWN_COMPLETE]	= IP_VS_SCTP_SHUTDOWN_COMPLETE,
243};
244
245/* SCTP States:
246 * See RFC 2960, 4. SCTP Association State Diagram
247 *
248 * New states (not in diagram):
249 * - INIT1 state: use shorter timeout for dropped INIT packets
250 * - REJECTED state: use shorter timeout if INIT is rejected with ABORT
251 * - INIT, COOKIE_SENT, COOKIE_REPLIED, COOKIE states: for better debugging
252 *
253 * The states are as seen in real server. In the diagram, INIT1, INIT,
254 * COOKIE_SENT and COOKIE_REPLIED processing happens in CLOSED state.
255 *
256 * States as per packets from client (C) and server (S):
257 *
258 * Setup of client connection:
259 * IP_VS_SCTP_S_INIT1: First C:INIT sent, wait for S:INIT-ACK
260 * IP_VS_SCTP_S_INIT: Next C:INIT sent, wait for S:INIT-ACK
261 * IP_VS_SCTP_S_COOKIE_SENT: S:INIT-ACK sent, wait for C:COOKIE-ECHO
262 * IP_VS_SCTP_S_COOKIE_REPLIED: C:COOKIE-ECHO sent, wait for S:COOKIE-ACK
263 *
264 * Setup of server connection:
265 * IP_VS_SCTP_S_COOKIE_WAIT: S:INIT sent, wait for C:INIT-ACK
266 * IP_VS_SCTP_S_COOKIE: C:INIT-ACK sent, wait for S:COOKIE-ECHO
267 * IP_VS_SCTP_S_COOKIE_ECHOED: S:COOKIE-ECHO sent, wait for C:COOKIE-ACK
268 */
269
270#define sNO IP_VS_SCTP_S_NONE
271#define sI1 IP_VS_SCTP_S_INIT1
272#define sIN IP_VS_SCTP_S_INIT
273#define sCS IP_VS_SCTP_S_COOKIE_SENT
274#define sCR IP_VS_SCTP_S_COOKIE_REPLIED
275#define sCW IP_VS_SCTP_S_COOKIE_WAIT
276#define sCO IP_VS_SCTP_S_COOKIE
277#define sCE IP_VS_SCTP_S_COOKIE_ECHOED
278#define sES IP_VS_SCTP_S_ESTABLISHED
279#define sSS IP_VS_SCTP_S_SHUTDOWN_SENT
280#define sSR IP_VS_SCTP_S_SHUTDOWN_RECEIVED
281#define sSA IP_VS_SCTP_S_SHUTDOWN_ACK_SENT
282#define sRJ IP_VS_SCTP_S_REJECTED
283#define sCL IP_VS_SCTP_S_CLOSED
284
285static const __u8 sctp_states
286	[IP_VS_DIR_LAST][IP_VS_SCTP_EVENT_LAST][IP_VS_SCTP_S_LAST] = {
287	{ /* INPUT */
288/*        sNO, sI1, sIN, sCS, sCR, sCW, sCO, sCE, sES, sSS, sSR, sSA, sRJ, sCL*/
289/* d   */{sES, sI1, sIN, sCS, sCR, sCW, sCO, sCE, sES, sSS, sSR, sSA, sRJ, sCL},
290/* i   */{sI1, sIN, sIN, sCS, sCR, sCW, sCO, sCE, sES, sSS, sSR, sSA, sIN, sIN},
291/* i_a */{sCW, sCW, sCW, sCS, sCR, sCO, sCO, sCE, sES, sSS, sSR, sSA, sRJ, sCL},
292/* c_e */{sCR, sIN, sIN, sCR, sCR, sCW, sCO, sCE, sES, sSS, sSR, sSA, sRJ, sCL},
293/* c_a */{sES, sI1, sIN, sCS, sCR, sCW, sCO, sES, sES, sSS, sSR, sSA, sRJ, sCL},
294/* s   */{sSR, sI1, sIN, sCS, sCR, sCW, sCO, sCE, sSR, sSS, sSR, sSA, sRJ, sCL},
295/* s_a */{sCL, sIN, sIN, sCS, sCR, sCW, sCO, sCE, sES, sCL, sSR, sCL, sRJ, sCL},
296/* s_c */{sCL, sCL, sCL, sCS, sCR, sCW, sCO, sCE, sES, sSS, sSR, sCL, sRJ, sCL},
297/* err */{sCL, sI1, sIN, sCS, sCR, sCW, sCO, sCL, sES, sSS, sSR, sSA, sRJ, sCL},
298/* ab  */{sCL, sCL, sCL, sCL, sCL, sRJ, sCL, sCL, sCL, sCL, sCL, sCL, sCL, sCL},
299	},
300	{ /* OUTPUT */
301/*        sNO, sI1, sIN, sCS, sCR, sCW, sCO, sCE, sES, sSS, sSR, sSA, sRJ, sCL*/
302/* d   */{sES, sI1, sIN, sCS, sCR, sCW, sCO, sCE, sES, sSS, sSR, sSA, sRJ, sCL},
303/* i   */{sCW, sCW, sCW, sCW, sCW, sCW, sCW, sCW, sES, sCW, sCW, sCW, sCW, sCW},
304/* i_a */{sCS, sCS, sCS, sCS, sCR, sCW, sCO, sCE, sES, sSS, sSR, sSA, sRJ, sCL},
305/* c_e */{sCE, sCE, sCE, sCE, sCE, sCE, sCE, sCE, sES, sSS, sSR, sSA, sRJ, sCL},
306/* c_a */{sES, sES, sES, sES, sES, sES, sES, sES, sES, sSS, sSR, sSA, sRJ, sCL},
307/* s   */{sSS, sSS, sSS, sSS, sSS, sSS, sSS, sSS, sSS, sSS, sSR, sSA, sRJ, sCL},
308/* s_a */{sSA, sSA, sSA, sSA, sSA, sCW, sCO, sCE, sES, sSA, sSA, sSA, sRJ, sCL},
309/* s_c */{sCL, sI1, sIN, sCS, sCR, sCW, sCO, sCE, sES, sSS, sSR, sSA, sRJ, sCL},
310/* err */{sCL, sCL, sCL, sCL, sCL, sCW, sCO, sCE, sES, sSS, sSR, sSA, sRJ, sCL},
311/* ab  */{sCL, sRJ, sCL, sCL, sCL, sCL, sCL, sCL, sCL, sCL, sCL, sCL, sCL, sCL},
312	},
313	{ /* INPUT-ONLY */
314/*        sNO, sI1, sIN, sCS, sCR, sCW, sCO, sCE, sES, sSS, sSR, sSA, sRJ, sCL*/
315/* d   */{sES, sI1, sIN, sCS, sCR, sES, sCO, sCE, sES, sSS, sSR, sSA, sRJ, sCL},
316/* i   */{sI1, sIN, sIN, sIN, sIN, sIN, sCO, sCE, sES, sSS, sSR, sSA, sIN, sIN},
317/* i_a */{sCE, sCE, sCE, sCE, sCE, sCE, sCO, sCE, sES, sSS, sSR, sSA, sRJ, sCL},
318/* c_e */{sES, sES, sES, sES, sES, sES, sCO, sCE, sES, sSS, sSR, sSA, sRJ, sCL},
319/* c_a */{sES, sI1, sIN, sES, sES, sCW, sES, sES, sES, sSS, sSR, sSA, sRJ, sCL},
320/* s   */{sSR, sI1, sIN, sCS, sCR, sCW, sCO, sCE, sSR, sSS, sSR, sSA, sRJ, sCL},
321/* s_a */{sCL, sIN, sIN, sCS, sCR, sCW, sCO, sCE, sCL, sCL, sSR, sCL, sRJ, sCL},
322/* s_c */{sCL, sCL, sCL, sCL, sCL, sCW, sCO, sCE, sES, sSS, sCL, sCL, sRJ, sCL},
323/* err */{sCL, sI1, sIN, sCS, sCR, sCW, sCO, sCE, sES, sSS, sSR, sSA, sRJ, sCL},
324/* ab  */{sCL, sCL, sCL, sCL, sCL, sRJ, sCL, sCL, sCL, sCL, sCL, sCL, sCL, sCL},
325	},
326};
327
328#define IP_VS_SCTP_MAX_RTO	((60 + 1) * HZ)
329
330/* Timeout table[state] */
331static const int sctp_timeouts[IP_VS_SCTP_S_LAST + 1] = {
332	[IP_VS_SCTP_S_NONE]			= 2 * HZ,
333	[IP_VS_SCTP_S_INIT1]			= (0 + 3 + 1) * HZ,
334	[IP_VS_SCTP_S_INIT]			= IP_VS_SCTP_MAX_RTO,
335	[IP_VS_SCTP_S_COOKIE_SENT]		= IP_VS_SCTP_MAX_RTO,
336	[IP_VS_SCTP_S_COOKIE_REPLIED]		= IP_VS_SCTP_MAX_RTO,
337	[IP_VS_SCTP_S_COOKIE_WAIT]		= IP_VS_SCTP_MAX_RTO,
338	[IP_VS_SCTP_S_COOKIE]			= IP_VS_SCTP_MAX_RTO,
339	[IP_VS_SCTP_S_COOKIE_ECHOED]		= IP_VS_SCTP_MAX_RTO,
340	[IP_VS_SCTP_S_ESTABLISHED]		= 15 * 60 * HZ,
341	[IP_VS_SCTP_S_SHUTDOWN_SENT]		= IP_VS_SCTP_MAX_RTO,
342	[IP_VS_SCTP_S_SHUTDOWN_RECEIVED]	= IP_VS_SCTP_MAX_RTO,
343	[IP_VS_SCTP_S_SHUTDOWN_ACK_SENT]	= IP_VS_SCTP_MAX_RTO,
344	[IP_VS_SCTP_S_REJECTED]			= (0 + 3 + 1) * HZ,
345	[IP_VS_SCTP_S_CLOSED]			= IP_VS_SCTP_MAX_RTO,
346	[IP_VS_SCTP_S_LAST]			= 2 * HZ,
347};
348
349static const char *sctp_state_name_table[IP_VS_SCTP_S_LAST + 1] = {
350	[IP_VS_SCTP_S_NONE]			= "NONE",
351	[IP_VS_SCTP_S_INIT1]			= "INIT1",
352	[IP_VS_SCTP_S_INIT]			= "INIT",
353	[IP_VS_SCTP_S_COOKIE_SENT]		= "C-SENT",
354	[IP_VS_SCTP_S_COOKIE_REPLIED]		= "C-REPLIED",
355	[IP_VS_SCTP_S_COOKIE_WAIT]		= "C-WAIT",
356	[IP_VS_SCTP_S_COOKIE]			= "COOKIE",
357	[IP_VS_SCTP_S_COOKIE_ECHOED]		= "C-ECHOED",
358	[IP_VS_SCTP_S_ESTABLISHED]		= "ESTABLISHED",
359	[IP_VS_SCTP_S_SHUTDOWN_SENT]		= "S-SENT",
360	[IP_VS_SCTP_S_SHUTDOWN_RECEIVED]	= "S-RECEIVED",
361	[IP_VS_SCTP_S_SHUTDOWN_ACK_SENT]	= "S-ACK-SENT",
362	[IP_VS_SCTP_S_REJECTED]			= "REJECTED",
363	[IP_VS_SCTP_S_CLOSED]			= "CLOSED",
364	[IP_VS_SCTP_S_LAST]			= "BUG!",
365};
366
367
368static const char *sctp_state_name(int state)
369{
370	if (state >= IP_VS_SCTP_S_LAST)
371		return "ERR!";
372	if (sctp_state_name_table[state])
373		return sctp_state_name_table[state];
374	return "?";
375}
376
377static inline void
378set_sctp_state(struct ip_vs_proto_data *pd, struct ip_vs_conn *cp,
379		int direction, const struct sk_buff *skb)
380{
381	struct sctp_chunkhdr _sctpch, *sch;
382	unsigned char chunk_type;
383	int event, next_state;
384	int ihl, cofs;
385
386#ifdef CONFIG_IP_VS_IPV6
387	ihl = cp->af == AF_INET ? ip_hdrlen(skb) : sizeof(struct ipv6hdr);
388#else
389	ihl = ip_hdrlen(skb);
390#endif
391
392	cofs = ihl + sizeof(struct sctphdr);
393	sch = skb_header_pointer(skb, cofs, sizeof(_sctpch), &_sctpch);
394	if (sch == NULL)
395		return;
396
397	chunk_type = sch->type;
398	/*
399	 * Section 3: Multiple chunks can be bundled into one SCTP packet
400	 * up to the MTU size, except for the INIT, INIT ACK, and
401	 * SHUTDOWN COMPLETE chunks. These chunks MUST NOT be bundled with
402	 * any other chunk in a packet.
403	 *
404	 * Section 3.3.7: DATA chunks MUST NOT be bundled with ABORT. Control
405	 * chunks (except for INIT, INIT ACK, and SHUTDOWN COMPLETE) MAY be
406	 * bundled with an ABORT, but they MUST be placed before the ABORT
407	 * in the SCTP packet or they will be ignored by the receiver.
408	 */
409	if ((sch->type == SCTP_CID_COOKIE_ECHO) ||
410	    (sch->type == SCTP_CID_COOKIE_ACK)) {
411		int clen = ntohs(sch->length);
412
413		if (clen >= sizeof(_sctpch)) {
414			sch = skb_header_pointer(skb, cofs + ALIGN(clen, 4),
415						 sizeof(_sctpch), &_sctpch);
416			if (sch && sch->type == SCTP_CID_ABORT)
417				chunk_type = sch->type;
418		}
419	}
420
421	event = (chunk_type < sizeof(sctp_events)) ?
422		sctp_events[chunk_type] : IP_VS_SCTP_DATA;
423
424	/* Update direction to INPUT_ONLY if necessary
425	 * or delete NO_OUTPUT flag if output packet detected
426	 */
427	if (cp->flags & IP_VS_CONN_F_NOOUTPUT) {
428		if (direction == IP_VS_DIR_OUTPUT)
429			cp->flags &= ~IP_VS_CONN_F_NOOUTPUT;
430		else
431			direction = IP_VS_DIR_INPUT_ONLY;
432	}
433
434	next_state = sctp_states[direction][event][cp->state];
435
436	if (next_state != cp->state) {
437		struct ip_vs_dest *dest = cp->dest;
438
439		IP_VS_DBG_BUF(8, "%s %s  %s:%d->"
440				"%s:%d state: %s->%s conn->refcnt:%d\n",
441				pd->pp->name,
442				((direction == IP_VS_DIR_OUTPUT) ?
443				 "output " : "input "),
444				IP_VS_DBG_ADDR(cp->daf, &cp->daddr),
445				ntohs(cp->dport),
446				IP_VS_DBG_ADDR(cp->af, &cp->caddr),
447				ntohs(cp->cport),
448				sctp_state_name(cp->state),
449				sctp_state_name(next_state),
450				refcount_read(&cp->refcnt));
451		if (dest) {
452			if (!(cp->flags & IP_VS_CONN_F_INACTIVE) &&
453				(next_state != IP_VS_SCTP_S_ESTABLISHED)) {
454				atomic_dec(&dest->activeconns);
455				atomic_inc(&dest->inactconns);
456				cp->flags |= IP_VS_CONN_F_INACTIVE;
457			} else if ((cp->flags & IP_VS_CONN_F_INACTIVE) &&
458				   (next_state == IP_VS_SCTP_S_ESTABLISHED)) {
459				atomic_inc(&dest->activeconns);
460				atomic_dec(&dest->inactconns);
461				cp->flags &= ~IP_VS_CONN_F_INACTIVE;
462			}
463		}
464		if (next_state == IP_VS_SCTP_S_ESTABLISHED)
465			ip_vs_control_assure_ct(cp);
466	}
467	if (likely(pd))
468		cp->timeout = pd->timeout_table[cp->state = next_state];
469	else	/* What to do ? */
470		cp->timeout = sctp_timeouts[cp->state = next_state];
471}
472
473static void
474sctp_state_transition(struct ip_vs_conn *cp, int direction,
475		const struct sk_buff *skb, struct ip_vs_proto_data *pd)
476{
477	spin_lock_bh(&cp->lock);
478	set_sctp_state(pd, cp, direction, skb);
479	spin_unlock_bh(&cp->lock);
480}
481
482static inline __u16 sctp_app_hashkey(__be16 port)
483{
484	return (((__force u16)port >> SCTP_APP_TAB_BITS) ^ (__force u16)port)
485		& SCTP_APP_TAB_MASK;
486}
487
488static int sctp_register_app(struct netns_ipvs *ipvs, struct ip_vs_app *inc)
489{
490	struct ip_vs_app *i;
491	__u16 hash;
492	__be16 port = inc->port;
493	int ret = 0;
494	struct ip_vs_proto_data *pd = ip_vs_proto_data_get(ipvs, IPPROTO_SCTP);
495
496	hash = sctp_app_hashkey(port);
497
498	list_for_each_entry(i, &ipvs->sctp_apps[hash], p_list) {
499		if (i->port == port) {
500			ret = -EEXIST;
501			goto out;
502		}
503	}
504	list_add_rcu(&inc->p_list, &ipvs->sctp_apps[hash]);
505	atomic_inc(&pd->appcnt);
506out:
507
508	return ret;
509}
510
511static void sctp_unregister_app(struct netns_ipvs *ipvs, struct ip_vs_app *inc)
512{
513	struct ip_vs_proto_data *pd = ip_vs_proto_data_get(ipvs, IPPROTO_SCTP);
514
515	atomic_dec(&pd->appcnt);
516	list_del_rcu(&inc->p_list);
517}
518
519static int sctp_app_conn_bind(struct ip_vs_conn *cp)
520{
521	struct netns_ipvs *ipvs = cp->ipvs;
522	int hash;
523	struct ip_vs_app *inc;
524	int result = 0;
525
526	/* Default binding: bind app only for NAT */
527	if (IP_VS_FWD_METHOD(cp) != IP_VS_CONN_F_MASQ)
528		return 0;
529	/* Lookup application incarnations and bind the right one */
530	hash = sctp_app_hashkey(cp->vport);
531
532	list_for_each_entry_rcu(inc, &ipvs->sctp_apps[hash], p_list) {
533		if (inc->port == cp->vport) {
534			if (unlikely(!ip_vs_app_inc_get(inc)))
535				break;
536
537			IP_VS_DBG_BUF(9, "%s: Binding conn %s:%u->"
538					"%s:%u to app %s on port %u\n",
539					__func__,
540					IP_VS_DBG_ADDR(cp->af, &cp->caddr),
541					ntohs(cp->cport),
542					IP_VS_DBG_ADDR(cp->af, &cp->vaddr),
543					ntohs(cp->vport),
544					inc->name, ntohs(inc->port));
545			cp->app = inc;
546			if (inc->init_conn)
547				result = inc->init_conn(inc, cp);
548			break;
549		}
550	}
551
552	return result;
553}
554
555/* ---------------------------------------------
556 *   timeouts is netns related now.
557 * ---------------------------------------------
558 */
559static int __ip_vs_sctp_init(struct netns_ipvs *ipvs, struct ip_vs_proto_data *pd)
560{
561	ip_vs_init_hash_table(ipvs->sctp_apps, SCTP_APP_TAB_SIZE);
562	pd->timeout_table = ip_vs_create_timeout_table((int *)sctp_timeouts,
563							sizeof(sctp_timeouts));
564	if (!pd->timeout_table)
565		return -ENOMEM;
566	return 0;
567}
568
569static void __ip_vs_sctp_exit(struct netns_ipvs *ipvs, struct ip_vs_proto_data *pd)
570{
571	kfree(pd->timeout_table);
572}
573
574struct ip_vs_protocol ip_vs_protocol_sctp = {
575	.name		= "SCTP",
576	.protocol	= IPPROTO_SCTP,
577	.num_states	= IP_VS_SCTP_S_LAST,
578	.dont_defrag	= 0,
579	.init		= NULL,
580	.exit		= NULL,
581	.init_netns	= __ip_vs_sctp_init,
582	.exit_netns	= __ip_vs_sctp_exit,
583	.register_app	= sctp_register_app,
584	.unregister_app = sctp_unregister_app,
585	.conn_schedule	= sctp_conn_schedule,
586	.conn_in_get	= ip_vs_conn_in_get_proto,
587	.conn_out_get	= ip_vs_conn_out_get_proto,
588	.snat_handler	= sctp_snat_handler,
589	.dnat_handler	= sctp_dnat_handler,
590	.state_name	= sctp_state_name,
591	.state_transition = sctp_state_transition,
592	.app_conn_bind	= sctp_app_conn_bind,
593	.debug_packet	= ip_vs_tcpudp_debug_packet,
594	.timeout_change	= NULL,
595};
596