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