diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2011-05-20 16:43:21 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2011-05-20 16:43:21 -0400 |
commit | 06f4e926d256d902dd9a53dcb400fd74974ce087 (patch) | |
tree | 0b438b67f5f0eff6fd617bc497a9dace6164a488 /net/sctp | |
parent | 8e7bfcbab3825d1b404d615cb1b54f44ff81f981 (diff) | |
parent | d93515611bbc70c2fe4db232e5feb448ed8e4cc9 (diff) |
Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-next-2.6
* git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-next-2.6: (1446 commits)
macvlan: fix panic if lowerdev in a bond
tg3: Add braces around 5906 workaround.
tg3: Fix NETIF_F_LOOPBACK error
macvlan: remove one synchronize_rcu() call
networking: NET_CLS_ROUTE4 depends on INET
irda: Fix error propagation in ircomm_lmp_connect_response()
irda: Kill set but unused variable 'bytes' in irlan_check_command_param()
irda: Kill set but unused variable 'clen' in ircomm_connect_indication()
rxrpc: Fix set but unused variable 'usage' in rxrpc_get_transport()
be2net: Kill set but unused variable 'req' in lancer_fw_download()
irda: Kill set but unused vars 'saddr' and 'daddr' in irlan_provider_connect_indication()
atl1c: atl1c_resume() is only used when CONFIG_PM_SLEEP is defined.
rxrpc: Fix set but unused variable 'usage' in rxrpc_get_peer().
rxrpc: Kill set but unused variable 'local' in rxrpc_UDP_error_handler()
rxrpc: Kill set but unused variable 'sp' in rxrpc_process_connection()
rxrpc: Kill set but unused variable 'sp' in rxrpc_rotate_tx_window()
pkt_sched: Kill set but unused variable 'protocol' in tc_classify()
isdn: capi: Use pr_debug() instead of ifdefs.
tg3: Update version to 3.119
tg3: Apply rx_discards fix to 5719/5720
...
Fix up trivial conflicts in arch/x86/Kconfig and net/mac80211/agg-tx.c
as per Davem.
Diffstat (limited to 'net/sctp')
-rw-r--r-- | net/sctp/bind_addr.c | 10 | ||||
-rw-r--r-- | net/sctp/debug.c | 1 | ||||
-rw-r--r-- | net/sctp/endpointola.c | 20 | ||||
-rw-r--r-- | net/sctp/input.c | 19 | ||||
-rw-r--r-- | net/sctp/ipv6.c | 185 | ||||
-rw-r--r-- | net/sctp/outqueue.c | 19 | ||||
-rw-r--r-- | net/sctp/protocol.c | 71 | ||||
-rw-r--r-- | net/sctp/sm_make_chunk.c | 62 | ||||
-rw-r--r-- | net/sctp/sm_sideeffect.c | 9 | ||||
-rw-r--r-- | net/sctp/sm_statefuns.c | 89 | ||||
-rw-r--r-- | net/sctp/sm_statetable.c | 78 | ||||
-rw-r--r-- | net/sctp/socket.c | 95 | ||||
-rw-r--r-- | net/sctp/transport.c | 27 | ||||
-rw-r--r-- | net/sctp/ulpevent.c | 30 |
14 files changed, 396 insertions, 319 deletions
diff --git a/net/sctp/bind_addr.c b/net/sctp/bind_addr.c index 3c06c87cd280..6338413376c8 100644 --- a/net/sctp/bind_addr.c +++ b/net/sctp/bind_addr.c | |||
@@ -140,14 +140,12 @@ void sctp_bind_addr_init(struct sctp_bind_addr *bp, __u16 port) | |||
140 | /* Dispose of the address list. */ | 140 | /* Dispose of the address list. */ |
141 | static void sctp_bind_addr_clean(struct sctp_bind_addr *bp) | 141 | static void sctp_bind_addr_clean(struct sctp_bind_addr *bp) |
142 | { | 142 | { |
143 | struct sctp_sockaddr_entry *addr; | 143 | struct sctp_sockaddr_entry *addr, *temp; |
144 | struct list_head *pos, *temp; | ||
145 | 144 | ||
146 | /* Empty the bind address list. */ | 145 | /* Empty the bind address list. */ |
147 | list_for_each_safe(pos, temp, &bp->address_list) { | 146 | list_for_each_entry_safe(addr, temp, &bp->address_list, list) { |
148 | addr = list_entry(pos, struct sctp_sockaddr_entry, list); | 147 | list_del_rcu(&addr->list); |
149 | list_del(pos); | 148 | call_rcu(&addr->rcu, sctp_local_addr_free); |
150 | kfree(addr); | ||
151 | SCTP_DBG_OBJCNT_DEC(addr); | 149 | SCTP_DBG_OBJCNT_DEC(addr); |
152 | } | 150 | } |
153 | } | 151 | } |
diff --git a/net/sctp/debug.c b/net/sctp/debug.c index bf24fa697de2..ec997cfe0a7e 100644 --- a/net/sctp/debug.c +++ b/net/sctp/debug.c | |||
@@ -98,7 +98,6 @@ const char *sctp_cname(const sctp_subtype_t cid) | |||
98 | 98 | ||
99 | /* These are printable forms of the states. */ | 99 | /* These are printable forms of the states. */ |
100 | const char *const sctp_state_tbl[SCTP_STATE_NUM_STATES] = { | 100 | const char *const sctp_state_tbl[SCTP_STATE_NUM_STATES] = { |
101 | "STATE_EMPTY", | ||
102 | "STATE_CLOSED", | 101 | "STATE_CLOSED", |
103 | "STATE_COOKIE_WAIT", | 102 | "STATE_COOKIE_WAIT", |
104 | "STATE_COOKIE_ECHOED", | 103 | "STATE_COOKIE_ECHOED", |
diff --git a/net/sctp/endpointola.c b/net/sctp/endpointola.c index e10acc01c75f..c8cc24e282c3 100644 --- a/net/sctp/endpointola.c +++ b/net/sctp/endpointola.c | |||
@@ -325,6 +325,7 @@ static struct sctp_association *__sctp_endpoint_lookup_assoc( | |||
325 | struct sctp_transport **transport) | 325 | struct sctp_transport **transport) |
326 | { | 326 | { |
327 | struct sctp_association *asoc = NULL; | 327 | struct sctp_association *asoc = NULL; |
328 | struct sctp_association *tmp; | ||
328 | struct sctp_transport *t = NULL; | 329 | struct sctp_transport *t = NULL; |
329 | struct sctp_hashbucket *head; | 330 | struct sctp_hashbucket *head; |
330 | struct sctp_ep_common *epb; | 331 | struct sctp_ep_common *epb; |
@@ -333,25 +334,32 @@ static struct sctp_association *__sctp_endpoint_lookup_assoc( | |||
333 | int rport; | 334 | int rport; |
334 | 335 | ||
335 | *transport = NULL; | 336 | *transport = NULL; |
337 | |||
338 | /* If the local port is not set, there can't be any associations | ||
339 | * on this endpoint. | ||
340 | */ | ||
341 | if (!ep->base.bind_addr.port) | ||
342 | goto out; | ||
343 | |||
336 | rport = ntohs(paddr->v4.sin_port); | 344 | rport = ntohs(paddr->v4.sin_port); |
337 | 345 | ||
338 | hash = sctp_assoc_hashfn(ep->base.bind_addr.port, rport); | 346 | hash = sctp_assoc_hashfn(ep->base.bind_addr.port, rport); |
339 | head = &sctp_assoc_hashtable[hash]; | 347 | head = &sctp_assoc_hashtable[hash]; |
340 | read_lock(&head->lock); | 348 | read_lock(&head->lock); |
341 | sctp_for_each_hentry(epb, node, &head->chain) { | 349 | sctp_for_each_hentry(epb, node, &head->chain) { |
342 | asoc = sctp_assoc(epb); | 350 | tmp = sctp_assoc(epb); |
343 | if (asoc->ep != ep || rport != asoc->peer.port) | 351 | if (tmp->ep != ep || rport != tmp->peer.port) |
344 | goto next; | 352 | continue; |
345 | 353 | ||
346 | t = sctp_assoc_lookup_paddr(asoc, paddr); | 354 | t = sctp_assoc_lookup_paddr(tmp, paddr); |
347 | if (t) { | 355 | if (t) { |
356 | asoc = tmp; | ||
348 | *transport = t; | 357 | *transport = t; |
349 | break; | 358 | break; |
350 | } | 359 | } |
351 | next: | ||
352 | asoc = NULL; | ||
353 | } | 360 | } |
354 | read_unlock(&head->lock); | 361 | read_unlock(&head->lock); |
362 | out: | ||
355 | return asoc; | 363 | return asoc; |
356 | } | 364 | } |
357 | 365 | ||
diff --git a/net/sctp/input.c b/net/sctp/input.c index 5436c6921167..741ed1648838 100644 --- a/net/sctp/input.c +++ b/net/sctp/input.c | |||
@@ -565,7 +565,7 @@ void sctp_err_finish(struct sock *sk, struct sctp_association *asoc) | |||
565 | */ | 565 | */ |
566 | void sctp_v4_err(struct sk_buff *skb, __u32 info) | 566 | void sctp_v4_err(struct sk_buff *skb, __u32 info) |
567 | { | 567 | { |
568 | struct iphdr *iph = (struct iphdr *)skb->data; | 568 | const struct iphdr *iph = (const struct iphdr *)skb->data; |
569 | const int ihlen = iph->ihl * 4; | 569 | const int ihlen = iph->ihl * 4; |
570 | const int type = icmp_hdr(skb)->type; | 570 | const int type = icmp_hdr(skb)->type; |
571 | const int code = icmp_hdr(skb)->code; | 571 | const int code = icmp_hdr(skb)->code; |
@@ -661,7 +661,6 @@ static int sctp_rcv_ootb(struct sk_buff *skb) | |||
661 | { | 661 | { |
662 | sctp_chunkhdr_t *ch; | 662 | sctp_chunkhdr_t *ch; |
663 | __u8 *ch_end; | 663 | __u8 *ch_end; |
664 | sctp_errhdr_t *err; | ||
665 | 664 | ||
666 | ch = (sctp_chunkhdr_t *) skb->data; | 665 | ch = (sctp_chunkhdr_t *) skb->data; |
667 | 666 | ||
@@ -697,20 +696,6 @@ static int sctp_rcv_ootb(struct sk_buff *skb) | |||
697 | if (SCTP_CID_INIT == ch->type && (void *)ch != skb->data) | 696 | if (SCTP_CID_INIT == ch->type && (void *)ch != skb->data) |
698 | goto discard; | 697 | goto discard; |
699 | 698 | ||
700 | /* RFC 8.4, 7) If the packet contains a "Stale cookie" ERROR | ||
701 | * or a COOKIE ACK the SCTP Packet should be silently | ||
702 | * discarded. | ||
703 | */ | ||
704 | if (SCTP_CID_COOKIE_ACK == ch->type) | ||
705 | goto discard; | ||
706 | |||
707 | if (SCTP_CID_ERROR == ch->type) { | ||
708 | sctp_walk_errors(err, ch) { | ||
709 | if (SCTP_ERROR_STALE_COOKIE == err->cause) | ||
710 | goto discard; | ||
711 | } | ||
712 | } | ||
713 | |||
714 | ch = (sctp_chunkhdr_t *) ch_end; | 699 | ch = (sctp_chunkhdr_t *) ch_end; |
715 | } while (ch_end < skb_tail_pointer(skb)); | 700 | } while (ch_end < skb_tail_pointer(skb)); |
716 | 701 | ||
@@ -1017,7 +1002,7 @@ static struct sctp_association *__sctp_rcv_asconf_lookup( | |||
1017 | /* Skip over the ADDIP header and find the Address parameter */ | 1002 | /* Skip over the ADDIP header and find the Address parameter */ |
1018 | param = (union sctp_addr_param *)(asconf + 1); | 1003 | param = (union sctp_addr_param *)(asconf + 1); |
1019 | 1004 | ||
1020 | af = sctp_get_af_specific(param_type2af(param->v4.param_hdr.type)); | 1005 | af = sctp_get_af_specific(param_type2af(param->p.type)); |
1021 | if (unlikely(!af)) | 1006 | if (unlikely(!af)) |
1022 | return NULL; | 1007 | return NULL; |
1023 | 1008 | ||
diff --git a/net/sctp/ipv6.c b/net/sctp/ipv6.c index 185fe058db11..0bb0d7cb9f10 100644 --- a/net/sctp/ipv6.c +++ b/net/sctp/ipv6.c | |||
@@ -80,6 +80,13 @@ | |||
80 | 80 | ||
81 | #include <asm/uaccess.h> | 81 | #include <asm/uaccess.h> |
82 | 82 | ||
83 | static inline int sctp_v6_addr_match_len(union sctp_addr *s1, | ||
84 | union sctp_addr *s2); | ||
85 | static void sctp_v6_to_addr(union sctp_addr *addr, struct in6_addr *saddr, | ||
86 | __be16 port); | ||
87 | static int sctp_v6_cmp_addr(const union sctp_addr *addr1, | ||
88 | const union sctp_addr *addr2); | ||
89 | |||
83 | /* Event handler for inet6 address addition/deletion events. | 90 | /* Event handler for inet6 address addition/deletion events. |
84 | * The sctp_local_addr_list needs to be protocted by a spin lock since | 91 | * The sctp_local_addr_list needs to be protocted by a spin lock since |
85 | * multiple notifiers (say IPv4 and IPv6) may be running at the same | 92 | * multiple notifiers (say IPv4 and IPv6) may be running at the same |
@@ -240,37 +247,107 @@ static int sctp_v6_xmit(struct sk_buff *skb, struct sctp_transport *transport) | |||
240 | /* Returns the dst cache entry for the given source and destination ip | 247 | /* Returns the dst cache entry for the given source and destination ip |
241 | * addresses. | 248 | * addresses. |
242 | */ | 249 | */ |
243 | static struct dst_entry *sctp_v6_get_dst(struct sctp_association *asoc, | 250 | static void sctp_v6_get_dst(struct sctp_transport *t, union sctp_addr *saddr, |
244 | union sctp_addr *daddr, | 251 | struct flowi *fl, struct sock *sk) |
245 | union sctp_addr *saddr) | ||
246 | { | 252 | { |
247 | struct dst_entry *dst; | 253 | struct sctp_association *asoc = t->asoc; |
248 | struct flowi6 fl6; | 254 | struct dst_entry *dst = NULL; |
255 | struct flowi6 *fl6 = &fl->u.ip6; | ||
256 | struct sctp_bind_addr *bp; | ||
257 | struct sctp_sockaddr_entry *laddr; | ||
258 | union sctp_addr *baddr = NULL; | ||
259 | union sctp_addr *daddr = &t->ipaddr; | ||
260 | union sctp_addr dst_saddr; | ||
261 | __u8 matchlen = 0; | ||
262 | __u8 bmatchlen; | ||
263 | sctp_scope_t scope; | ||
249 | 264 | ||
250 | memset(&fl6, 0, sizeof(fl6)); | 265 | memset(fl6, 0, sizeof(struct flowi6)); |
251 | ipv6_addr_copy(&fl6.daddr, &daddr->v6.sin6_addr); | 266 | ipv6_addr_copy(&fl6->daddr, &daddr->v6.sin6_addr); |
267 | fl6->fl6_dport = daddr->v6.sin6_port; | ||
268 | fl6->flowi6_proto = IPPROTO_SCTP; | ||
252 | if (ipv6_addr_type(&daddr->v6.sin6_addr) & IPV6_ADDR_LINKLOCAL) | 269 | if (ipv6_addr_type(&daddr->v6.sin6_addr) & IPV6_ADDR_LINKLOCAL) |
253 | fl6.flowi6_oif = daddr->v6.sin6_scope_id; | 270 | fl6->flowi6_oif = daddr->v6.sin6_scope_id; |
254 | 271 | ||
272 | SCTP_DEBUG_PRINTK("%s: DST=%pI6 ", __func__, &fl6->daddr); | ||
255 | 273 | ||
256 | SCTP_DEBUG_PRINTK("%s: DST=%pI6 ", __func__, &fl6.daddr); | 274 | if (asoc) |
275 | fl6->fl6_sport = htons(asoc->base.bind_addr.port); | ||
257 | 276 | ||
258 | if (saddr) { | 277 | if (saddr) { |
259 | ipv6_addr_copy(&fl6.saddr, &saddr->v6.sin6_addr); | 278 | ipv6_addr_copy(&fl6->saddr, &saddr->v6.sin6_addr); |
260 | SCTP_DEBUG_PRINTK("SRC=%pI6 - ", &fl6.saddr); | 279 | fl6->fl6_sport = saddr->v6.sin6_port; |
280 | SCTP_DEBUG_PRINTK("SRC=%pI6 - ", &fl6->saddr); | ||
281 | } | ||
282 | |||
283 | dst = ip6_dst_lookup_flow(sk, fl6, NULL, false); | ||
284 | if (!asoc || saddr) | ||
285 | goto out; | ||
286 | |||
287 | bp = &asoc->base.bind_addr; | ||
288 | scope = sctp_scope(daddr); | ||
289 | /* ip6_dst_lookup has filled in the fl6->saddr for us. Check | ||
290 | * to see if we can use it. | ||
291 | */ | ||
292 | if (!IS_ERR(dst)) { | ||
293 | /* Walk through the bind address list and look for a bind | ||
294 | * address that matches the source address of the returned dst. | ||
295 | */ | ||
296 | sctp_v6_to_addr(&dst_saddr, &fl6->saddr, htons(bp->port)); | ||
297 | rcu_read_lock(); | ||
298 | list_for_each_entry_rcu(laddr, &bp->address_list, list) { | ||
299 | if (!laddr->valid || (laddr->state != SCTP_ADDR_SRC)) | ||
300 | continue; | ||
301 | |||
302 | /* Do not compare against v4 addrs */ | ||
303 | if ((laddr->a.sa.sa_family == AF_INET6) && | ||
304 | (sctp_v6_cmp_addr(&dst_saddr, &laddr->a))) { | ||
305 | rcu_read_unlock(); | ||
306 | goto out; | ||
307 | } | ||
308 | } | ||
309 | rcu_read_unlock(); | ||
310 | /* None of the bound addresses match the source address of the | ||
311 | * dst. So release it. | ||
312 | */ | ||
313 | dst_release(dst); | ||
314 | dst = NULL; | ||
261 | } | 315 | } |
262 | 316 | ||
263 | dst = ip6_route_output(&init_net, NULL, &fl6); | 317 | /* Walk through the bind address list and try to get the |
264 | if (!dst->error) { | 318 | * best source address for a given destination. |
319 | */ | ||
320 | rcu_read_lock(); | ||
321 | list_for_each_entry_rcu(laddr, &bp->address_list, list) { | ||
322 | if (!laddr->valid && laddr->state != SCTP_ADDR_SRC) | ||
323 | continue; | ||
324 | if ((laddr->a.sa.sa_family == AF_INET6) && | ||
325 | (scope <= sctp_scope(&laddr->a))) { | ||
326 | bmatchlen = sctp_v6_addr_match_len(daddr, &laddr->a); | ||
327 | if (!baddr || (matchlen < bmatchlen)) { | ||
328 | baddr = &laddr->a; | ||
329 | matchlen = bmatchlen; | ||
330 | } | ||
331 | } | ||
332 | } | ||
333 | rcu_read_unlock(); | ||
334 | if (baddr) { | ||
335 | ipv6_addr_copy(&fl6->saddr, &baddr->v6.sin6_addr); | ||
336 | fl6->fl6_sport = baddr->v6.sin6_port; | ||
337 | dst = ip6_dst_lookup_flow(sk, fl6, NULL, false); | ||
338 | } | ||
339 | |||
340 | out: | ||
341 | if (!IS_ERR(dst)) { | ||
265 | struct rt6_info *rt; | 342 | struct rt6_info *rt; |
266 | rt = (struct rt6_info *)dst; | 343 | rt = (struct rt6_info *)dst; |
344 | t->dst = dst; | ||
267 | SCTP_DEBUG_PRINTK("rt6_dst:%pI6 rt6_src:%pI6\n", | 345 | SCTP_DEBUG_PRINTK("rt6_dst:%pI6 rt6_src:%pI6\n", |
268 | &rt->rt6i_dst.addr, &rt->rt6i_src.addr); | 346 | &rt->rt6i_dst.addr, &fl6->saddr); |
269 | return dst; | 347 | } else { |
348 | t->dst = NULL; | ||
349 | SCTP_DEBUG_PRINTK("NO ROUTE\n"); | ||
270 | } | 350 | } |
271 | SCTP_DEBUG_PRINTK("NO ROUTE\n"); | ||
272 | dst_release(dst); | ||
273 | return NULL; | ||
274 | } | 351 | } |
275 | 352 | ||
276 | /* Returns the number of consecutive initial bits that match in the 2 ipv6 | 353 | /* Returns the number of consecutive initial bits that match in the 2 ipv6 |
@@ -286,64 +363,18 @@ static inline int sctp_v6_addr_match_len(union sctp_addr *s1, | |||
286 | * and asoc's bind address list. | 363 | * and asoc's bind address list. |
287 | */ | 364 | */ |
288 | static void sctp_v6_get_saddr(struct sctp_sock *sk, | 365 | static void sctp_v6_get_saddr(struct sctp_sock *sk, |
289 | struct sctp_association *asoc, | 366 | struct sctp_transport *t, |
290 | struct dst_entry *dst, | 367 | struct flowi *fl) |
291 | union sctp_addr *daddr, | ||
292 | union sctp_addr *saddr) | ||
293 | { | 368 | { |
294 | struct sctp_bind_addr *bp; | 369 | struct flowi6 *fl6 = &fl->u.ip6; |
295 | struct sctp_sockaddr_entry *laddr; | 370 | union sctp_addr *saddr = &t->saddr; |
296 | sctp_scope_t scope; | ||
297 | union sctp_addr *baddr = NULL; | ||
298 | __u8 matchlen = 0; | ||
299 | __u8 bmatchlen; | ||
300 | 371 | ||
301 | SCTP_DEBUG_PRINTK("%s: asoc:%p dst:%p daddr:%pI6 ", | 372 | SCTP_DEBUG_PRINTK("%s: asoc:%p dst:%p\n", __func__, t->asoc, t->dst); |
302 | __func__, asoc, dst, &daddr->v6.sin6_addr); | ||
303 | |||
304 | if (!asoc) { | ||
305 | ipv6_dev_get_saddr(sock_net(sctp_opt2sk(sk)), | ||
306 | dst ? ip6_dst_idev(dst)->dev : NULL, | ||
307 | &daddr->v6.sin6_addr, | ||
308 | inet6_sk(&sk->inet.sk)->srcprefs, | ||
309 | &saddr->v6.sin6_addr); | ||
310 | SCTP_DEBUG_PRINTK("saddr from ipv6_get_saddr: %pI6\n", | ||
311 | &saddr->v6.sin6_addr); | ||
312 | return; | ||
313 | } | ||
314 | |||
315 | scope = sctp_scope(daddr); | ||
316 | |||
317 | bp = &asoc->base.bind_addr; | ||
318 | 373 | ||
319 | /* Go through the bind address list and find the best source address | 374 | if (t->dst) { |
320 | * that matches the scope of the destination address. | 375 | saddr->v6.sin6_family = AF_INET6; |
321 | */ | 376 | ipv6_addr_copy(&saddr->v6.sin6_addr, &fl6->saddr); |
322 | rcu_read_lock(); | ||
323 | list_for_each_entry_rcu(laddr, &bp->address_list, list) { | ||
324 | if (!laddr->valid) | ||
325 | continue; | ||
326 | if ((laddr->state == SCTP_ADDR_SRC) && | ||
327 | (laddr->a.sa.sa_family == AF_INET6) && | ||
328 | (scope <= sctp_scope(&laddr->a))) { | ||
329 | bmatchlen = sctp_v6_addr_match_len(daddr, &laddr->a); | ||
330 | if (!baddr || (matchlen < bmatchlen)) { | ||
331 | baddr = &laddr->a; | ||
332 | matchlen = bmatchlen; | ||
333 | } | ||
334 | } | ||
335 | } | ||
336 | |||
337 | if (baddr) { | ||
338 | memcpy(saddr, baddr, sizeof(union sctp_addr)); | ||
339 | SCTP_DEBUG_PRINTK("saddr: %pI6\n", &saddr->v6.sin6_addr); | ||
340 | } else { | ||
341 | pr_err("%s: asoc:%p Could not find a valid source " | ||
342 | "address for the dest:%pI6\n", | ||
343 | __func__, asoc, &daddr->v6.sin6_addr); | ||
344 | } | 377 | } |
345 | |||
346 | rcu_read_unlock(); | ||
347 | } | 378 | } |
348 | 379 | ||
349 | /* Make a copy of all potential local addresses. */ | 380 | /* Make a copy of all potential local addresses. */ |
@@ -465,14 +496,13 @@ static int sctp_v6_to_addr_param(const union sctp_addr *addr, | |||
465 | return length; | 496 | return length; |
466 | } | 497 | } |
467 | 498 | ||
468 | /* Initialize a sctp_addr from a dst_entry. */ | 499 | /* Initialize a sctp_addr from struct in6_addr. */ |
469 | static void sctp_v6_dst_saddr(union sctp_addr *addr, struct dst_entry *dst, | 500 | static void sctp_v6_to_addr(union sctp_addr *addr, struct in6_addr *saddr, |
470 | __be16 port) | 501 | __be16 port) |
471 | { | 502 | { |
472 | struct rt6_info *rt = (struct rt6_info *)dst; | ||
473 | addr->sa.sa_family = AF_INET6; | 503 | addr->sa.sa_family = AF_INET6; |
474 | addr->v6.sin6_port = port; | 504 | addr->v6.sin6_port = port; |
475 | ipv6_addr_copy(&addr->v6.sin6_addr, &rt->rt6i_src.addr); | 505 | ipv6_addr_copy(&addr->v6.sin6_addr, saddr); |
476 | } | 506 | } |
477 | 507 | ||
478 | /* Compare addresses exactly. | 508 | /* Compare addresses exactly. |
@@ -531,7 +561,7 @@ static int sctp_v6_is_any(const union sctp_addr *addr) | |||
531 | static int sctp_v6_available(union sctp_addr *addr, struct sctp_sock *sp) | 561 | static int sctp_v6_available(union sctp_addr *addr, struct sctp_sock *sp) |
532 | { | 562 | { |
533 | int type; | 563 | int type; |
534 | struct in6_addr *in6 = (struct in6_addr *)&addr->v6.sin6_addr; | 564 | const struct in6_addr *in6 = (const struct in6_addr *)&addr->v6.sin6_addr; |
535 | 565 | ||
536 | type = ipv6_addr_type(in6); | 566 | type = ipv6_addr_type(in6); |
537 | if (IPV6_ADDR_ANY == type) | 567 | if (IPV6_ADDR_ANY == type) |
@@ -959,7 +989,6 @@ static struct sctp_af sctp_af_inet6 = { | |||
959 | .to_sk_daddr = sctp_v6_to_sk_daddr, | 989 | .to_sk_daddr = sctp_v6_to_sk_daddr, |
960 | .from_addr_param = sctp_v6_from_addr_param, | 990 | .from_addr_param = sctp_v6_from_addr_param, |
961 | .to_addr_param = sctp_v6_to_addr_param, | 991 | .to_addr_param = sctp_v6_to_addr_param, |
962 | .dst_saddr = sctp_v6_dst_saddr, | ||
963 | .cmp_addr = sctp_v6_cmp_addr, | 992 | .cmp_addr = sctp_v6_cmp_addr, |
964 | .scope = sctp_v6_scope, | 993 | .scope = sctp_v6_scope, |
965 | .addr_valid = sctp_v6_addr_valid, | 994 | .addr_valid = sctp_v6_addr_valid, |
diff --git a/net/sctp/outqueue.c b/net/sctp/outqueue.c index bf92a5b68f8b..1c88c8911dc5 100644 --- a/net/sctp/outqueue.c +++ b/net/sctp/outqueue.c | |||
@@ -131,7 +131,8 @@ static inline int sctp_cacc_skip_3_1_d(struct sctp_transport *primary, | |||
131 | static inline int sctp_cacc_skip_3_1_f(struct sctp_transport *transport, | 131 | static inline int sctp_cacc_skip_3_1_f(struct sctp_transport *transport, |
132 | int count_of_newacks) | 132 | int count_of_newacks) |
133 | { | 133 | { |
134 | if (count_of_newacks < 2 && !transport->cacc.cacc_saw_newack) | 134 | if (count_of_newacks < 2 && |
135 | (transport && !transport->cacc.cacc_saw_newack)) | ||
135 | return 1; | 136 | return 1; |
136 | return 0; | 137 | return 0; |
137 | } | 138 | } |
@@ -319,7 +320,6 @@ int sctp_outq_tail(struct sctp_outq *q, struct sctp_chunk *chunk) | |||
319 | * chunk. | 320 | * chunk. |
320 | */ | 321 | */ |
321 | switch (q->asoc->state) { | 322 | switch (q->asoc->state) { |
322 | case SCTP_STATE_EMPTY: | ||
323 | case SCTP_STATE_CLOSED: | 323 | case SCTP_STATE_CLOSED: |
324 | case SCTP_STATE_SHUTDOWN_PENDING: | 324 | case SCTP_STATE_SHUTDOWN_PENDING: |
325 | case SCTP_STATE_SHUTDOWN_SENT: | 325 | case SCTP_STATE_SHUTDOWN_SENT: |
@@ -577,6 +577,13 @@ static int sctp_outq_flush_rtx(struct sctp_outq *q, struct sctp_packet *pkt, | |||
577 | * try to send as much as possible. | 577 | * try to send as much as possible. |
578 | */ | 578 | */ |
579 | list_for_each_entry_safe(chunk, chunk1, lqueue, transmitted_list) { | 579 | list_for_each_entry_safe(chunk, chunk1, lqueue, transmitted_list) { |
580 | /* If the chunk is abandoned, move it to abandoned list. */ | ||
581 | if (sctp_chunk_abandoned(chunk)) { | ||
582 | list_del_init(&chunk->transmitted_list); | ||
583 | sctp_insert_list(&q->abandoned, | ||
584 | &chunk->transmitted_list); | ||
585 | continue; | ||
586 | } | ||
580 | 587 | ||
581 | /* Make sure that Gap Acked TSNs are not retransmitted. A | 588 | /* Make sure that Gap Acked TSNs are not retransmitted. A |
582 | * simple approach is just to move such TSNs out of the | 589 | * simple approach is just to move such TSNs out of the |
@@ -618,9 +625,12 @@ redo: | |||
618 | 625 | ||
619 | /* If we are retransmitting, we should only | 626 | /* If we are retransmitting, we should only |
620 | * send a single packet. | 627 | * send a single packet. |
628 | * Otherwise, try appending this chunk again. | ||
621 | */ | 629 | */ |
622 | if (rtx_timeout || fast_rtx) | 630 | if (rtx_timeout || fast_rtx) |
623 | done = 1; | 631 | done = 1; |
632 | else | ||
633 | goto redo; | ||
624 | 634 | ||
625 | /* Bundle next chunk in the next round. */ | 635 | /* Bundle next chunk in the next round. */ |
626 | break; | 636 | break; |
@@ -1683,8 +1693,9 @@ static void sctp_mark_missing(struct sctp_outq *q, | |||
1683 | /* SFR-CACC may require us to skip marking | 1693 | /* SFR-CACC may require us to skip marking |
1684 | * this chunk as missing. | 1694 | * this chunk as missing. |
1685 | */ | 1695 | */ |
1686 | if (!transport || !sctp_cacc_skip(primary, transport, | 1696 | if (!transport || !sctp_cacc_skip(primary, |
1687 | count_of_newacks, tsn)) { | 1697 | chunk->transport, |
1698 | count_of_newacks, tsn)) { | ||
1688 | chunk->tsn_missing_report++; | 1699 | chunk->tsn_missing_report++; |
1689 | 1700 | ||
1690 | SCTP_DEBUG_PRINTK( | 1701 | SCTP_DEBUG_PRINTK( |
diff --git a/net/sctp/protocol.c b/net/sctp/protocol.c index 065d99958ced..67380a29e2e9 100644 --- a/net/sctp/protocol.c +++ b/net/sctp/protocol.c | |||
@@ -332,13 +332,12 @@ static int sctp_v4_to_addr_param(const union sctp_addr *addr, | |||
332 | } | 332 | } |
333 | 333 | ||
334 | /* Initialize a sctp_addr from a dst_entry. */ | 334 | /* Initialize a sctp_addr from a dst_entry. */ |
335 | static void sctp_v4_dst_saddr(union sctp_addr *saddr, struct dst_entry *dst, | 335 | static void sctp_v4_dst_saddr(union sctp_addr *saddr, struct flowi4 *fl4, |
336 | __be16 port) | 336 | __be16 port) |
337 | { | 337 | { |
338 | struct rtable *rt = (struct rtable *)dst; | ||
339 | saddr->v4.sin_family = AF_INET; | 338 | saddr->v4.sin_family = AF_INET; |
340 | saddr->v4.sin_port = port; | 339 | saddr->v4.sin_port = port; |
341 | saddr->v4.sin_addr.s_addr = rt->rt_src; | 340 | saddr->v4.sin_addr.s_addr = fl4->saddr; |
342 | } | 341 | } |
343 | 342 | ||
344 | /* Compare two addresses exactly. */ | 343 | /* Compare two addresses exactly. */ |
@@ -456,35 +455,36 @@ static sctp_scope_t sctp_v4_scope(union sctp_addr *addr) | |||
456 | * addresses. If an association is passed, trys to get a dst entry with a | 455 | * addresses. If an association is passed, trys to get a dst entry with a |
457 | * source address that matches an address in the bind address list. | 456 | * source address that matches an address in the bind address list. |
458 | */ | 457 | */ |
459 | static struct dst_entry *sctp_v4_get_dst(struct sctp_association *asoc, | 458 | static void sctp_v4_get_dst(struct sctp_transport *t, union sctp_addr *saddr, |
460 | union sctp_addr *daddr, | 459 | struct flowi *fl, struct sock *sk) |
461 | union sctp_addr *saddr) | ||
462 | { | 460 | { |
461 | struct sctp_association *asoc = t->asoc; | ||
463 | struct rtable *rt; | 462 | struct rtable *rt; |
464 | struct flowi4 fl4; | 463 | struct flowi4 *fl4 = &fl->u.ip4; |
465 | struct sctp_bind_addr *bp; | 464 | struct sctp_bind_addr *bp; |
466 | struct sctp_sockaddr_entry *laddr; | 465 | struct sctp_sockaddr_entry *laddr; |
467 | struct dst_entry *dst = NULL; | 466 | struct dst_entry *dst = NULL; |
467 | union sctp_addr *daddr = &t->ipaddr; | ||
468 | union sctp_addr dst_saddr; | 468 | union sctp_addr dst_saddr; |
469 | 469 | ||
470 | memset(&fl4, 0x0, sizeof(struct flowi4)); | 470 | memset(fl4, 0x0, sizeof(struct flowi4)); |
471 | fl4.daddr = daddr->v4.sin_addr.s_addr; | 471 | fl4->daddr = daddr->v4.sin_addr.s_addr; |
472 | fl4.fl4_dport = daddr->v4.sin_port; | 472 | fl4->fl4_dport = daddr->v4.sin_port; |
473 | fl4.flowi4_proto = IPPROTO_SCTP; | 473 | fl4->flowi4_proto = IPPROTO_SCTP; |
474 | if (asoc) { | 474 | if (asoc) { |
475 | fl4.flowi4_tos = RT_CONN_FLAGS(asoc->base.sk); | 475 | fl4->flowi4_tos = RT_CONN_FLAGS(asoc->base.sk); |
476 | fl4.flowi4_oif = asoc->base.sk->sk_bound_dev_if; | 476 | fl4->flowi4_oif = asoc->base.sk->sk_bound_dev_if; |
477 | fl4.fl4_sport = htons(asoc->base.bind_addr.port); | 477 | fl4->fl4_sport = htons(asoc->base.bind_addr.port); |
478 | } | 478 | } |
479 | if (saddr) { | 479 | if (saddr) { |
480 | fl4.saddr = saddr->v4.sin_addr.s_addr; | 480 | fl4->saddr = saddr->v4.sin_addr.s_addr; |
481 | fl4.fl4_sport = saddr->v4.sin_port; | 481 | fl4->fl4_sport = saddr->v4.sin_port; |
482 | } | 482 | } |
483 | 483 | ||
484 | SCTP_DEBUG_PRINTK("%s: DST:%pI4, SRC:%pI4 - ", | 484 | SCTP_DEBUG_PRINTK("%s: DST:%pI4, SRC:%pI4 - ", |
485 | __func__, &fl4.daddr, &fl4.saddr); | 485 | __func__, &fl4->daddr, &fl4->saddr); |
486 | 486 | ||
487 | rt = ip_route_output_key(&init_net, &fl4); | 487 | rt = ip_route_output_key(&init_net, fl4); |
488 | if (!IS_ERR(rt)) | 488 | if (!IS_ERR(rt)) |
489 | dst = &rt->dst; | 489 | dst = &rt->dst; |
490 | 490 | ||
@@ -500,7 +500,7 @@ static struct dst_entry *sctp_v4_get_dst(struct sctp_association *asoc, | |||
500 | /* Walk through the bind address list and look for a bind | 500 | /* Walk through the bind address list and look for a bind |
501 | * address that matches the source address of the returned dst. | 501 | * address that matches the source address of the returned dst. |
502 | */ | 502 | */ |
503 | sctp_v4_dst_saddr(&dst_saddr, dst, htons(bp->port)); | 503 | sctp_v4_dst_saddr(&dst_saddr, fl4, htons(bp->port)); |
504 | rcu_read_lock(); | 504 | rcu_read_lock(); |
505 | list_for_each_entry_rcu(laddr, &bp->address_list, list) { | 505 | list_for_each_entry_rcu(laddr, &bp->address_list, list) { |
506 | if (!laddr->valid || (laddr->state != SCTP_ADDR_SRC)) | 506 | if (!laddr->valid || (laddr->state != SCTP_ADDR_SRC)) |
@@ -526,9 +526,9 @@ static struct dst_entry *sctp_v4_get_dst(struct sctp_association *asoc, | |||
526 | continue; | 526 | continue; |
527 | if ((laddr->state == SCTP_ADDR_SRC) && | 527 | if ((laddr->state == SCTP_ADDR_SRC) && |
528 | (AF_INET == laddr->a.sa.sa_family)) { | 528 | (AF_INET == laddr->a.sa.sa_family)) { |
529 | fl4.saddr = laddr->a.v4.sin_addr.s_addr; | 529 | fl4->saddr = laddr->a.v4.sin_addr.s_addr; |
530 | fl4.fl4_sport = laddr->a.v4.sin_port; | 530 | fl4->fl4_sport = laddr->a.v4.sin_port; |
531 | rt = ip_route_output_key(&init_net, &fl4); | 531 | rt = ip_route_output_key(&init_net, fl4); |
532 | if (!IS_ERR(rt)) { | 532 | if (!IS_ERR(rt)) { |
533 | dst = &rt->dst; | 533 | dst = &rt->dst; |
534 | goto out_unlock; | 534 | goto out_unlock; |
@@ -539,33 +539,27 @@ static struct dst_entry *sctp_v4_get_dst(struct sctp_association *asoc, | |||
539 | out_unlock: | 539 | out_unlock: |
540 | rcu_read_unlock(); | 540 | rcu_read_unlock(); |
541 | out: | 541 | out: |
542 | t->dst = dst; | ||
542 | if (dst) | 543 | if (dst) |
543 | SCTP_DEBUG_PRINTK("rt_dst:%pI4, rt_src:%pI4\n", | 544 | SCTP_DEBUG_PRINTK("rt_dst:%pI4, rt_src:%pI4\n", |
544 | &rt->rt_dst, &rt->rt_src); | 545 | &fl4->daddr, &fl4->saddr); |
545 | else | 546 | else |
546 | SCTP_DEBUG_PRINTK("NO ROUTE\n"); | 547 | SCTP_DEBUG_PRINTK("NO ROUTE\n"); |
547 | |||
548 | return dst; | ||
549 | } | 548 | } |
550 | 549 | ||
551 | /* For v4, the source address is cached in the route entry(dst). So no need | 550 | /* For v4, the source address is cached in the route entry(dst). So no need |
552 | * to cache it separately and hence this is an empty routine. | 551 | * to cache it separately and hence this is an empty routine. |
553 | */ | 552 | */ |
554 | static void sctp_v4_get_saddr(struct sctp_sock *sk, | 553 | static void sctp_v4_get_saddr(struct sctp_sock *sk, |
555 | struct sctp_association *asoc, | 554 | struct sctp_transport *t, |
556 | struct dst_entry *dst, | 555 | struct flowi *fl) |
557 | union sctp_addr *daddr, | ||
558 | union sctp_addr *saddr) | ||
559 | { | 556 | { |
560 | struct rtable *rt = (struct rtable *)dst; | 557 | union sctp_addr *saddr = &t->saddr; |
561 | 558 | struct rtable *rt = (struct rtable *)t->dst; | |
562 | if (!asoc) | ||
563 | return; | ||
564 | 559 | ||
565 | if (rt) { | 560 | if (rt) { |
566 | saddr->v4.sin_family = AF_INET; | 561 | saddr->v4.sin_family = AF_INET; |
567 | saddr->v4.sin_port = htons(asoc->base.bind_addr.port); | 562 | saddr->v4.sin_addr.s_addr = fl->u.ip4.saddr; |
568 | saddr->v4.sin_addr.s_addr = rt->rt_src; | ||
569 | } | 563 | } |
570 | } | 564 | } |
571 | 565 | ||
@@ -847,14 +841,14 @@ static inline int sctp_v4_xmit(struct sk_buff *skb, | |||
847 | 841 | ||
848 | SCTP_DEBUG_PRINTK("%s: skb:%p, len:%d, src:%pI4, dst:%pI4\n", | 842 | SCTP_DEBUG_PRINTK("%s: skb:%p, len:%d, src:%pI4, dst:%pI4\n", |
849 | __func__, skb, skb->len, | 843 | __func__, skb, skb->len, |
850 | &skb_rtable(skb)->rt_src, | 844 | &transport->fl.u.ip4.saddr, |
851 | &skb_rtable(skb)->rt_dst); | 845 | &transport->fl.u.ip4.daddr); |
852 | 846 | ||
853 | inet->pmtudisc = transport->param_flags & SPP_PMTUD_ENABLE ? | 847 | inet->pmtudisc = transport->param_flags & SPP_PMTUD_ENABLE ? |
854 | IP_PMTUDISC_DO : IP_PMTUDISC_DONT; | 848 | IP_PMTUDISC_DO : IP_PMTUDISC_DONT; |
855 | 849 | ||
856 | SCTP_INC_STATS(SCTP_MIB_OUTSCTPPACKS); | 850 | SCTP_INC_STATS(SCTP_MIB_OUTSCTPPACKS); |
857 | return ip_queue_xmit(skb); | 851 | return ip_queue_xmit(skb, &transport->fl); |
858 | } | 852 | } |
859 | 853 | ||
860 | static struct sctp_af sctp_af_inet; | 854 | static struct sctp_af sctp_af_inet; |
@@ -943,7 +937,6 @@ static struct sctp_af sctp_af_inet = { | |||
943 | .to_sk_daddr = sctp_v4_to_sk_daddr, | 937 | .to_sk_daddr = sctp_v4_to_sk_daddr, |
944 | .from_addr_param = sctp_v4_from_addr_param, | 938 | .from_addr_param = sctp_v4_from_addr_param, |
945 | .to_addr_param = sctp_v4_to_addr_param, | 939 | .to_addr_param = sctp_v4_to_addr_param, |
946 | .dst_saddr = sctp_v4_dst_saddr, | ||
947 | .cmp_addr = sctp_v4_cmp_addr, | 940 | .cmp_addr = sctp_v4_cmp_addr, |
948 | .addr_valid = sctp_v4_addr_valid, | 941 | .addr_valid = sctp_v4_addr_valid, |
949 | .inaddr_any = sctp_v4_inaddr_any, | 942 | .inaddr_any = sctp_v4_inaddr_any, |
diff --git a/net/sctp/sm_make_chunk.c b/net/sctp/sm_make_chunk.c index b3434cc7d0cf..58eb27fed4b4 100644 --- a/net/sctp/sm_make_chunk.c +++ b/net/sctp/sm_make_chunk.c | |||
@@ -1075,20 +1075,28 @@ nodata: | |||
1075 | 1075 | ||
1076 | /* Make a HEARTBEAT chunk. */ | 1076 | /* Make a HEARTBEAT chunk. */ |
1077 | struct sctp_chunk *sctp_make_heartbeat(const struct sctp_association *asoc, | 1077 | struct sctp_chunk *sctp_make_heartbeat(const struct sctp_association *asoc, |
1078 | const struct sctp_transport *transport, | 1078 | const struct sctp_transport *transport) |
1079 | const void *payload, const size_t paylen) | ||
1080 | { | 1079 | { |
1081 | struct sctp_chunk *retval = sctp_make_chunk(asoc, SCTP_CID_HEARTBEAT, | 1080 | struct sctp_chunk *retval; |
1082 | 0, paylen); | 1081 | sctp_sender_hb_info_t hbinfo; |
1082 | |||
1083 | retval = sctp_make_chunk(asoc, SCTP_CID_HEARTBEAT, 0, sizeof(hbinfo)); | ||
1083 | 1084 | ||
1084 | if (!retval) | 1085 | if (!retval) |
1085 | goto nodata; | 1086 | goto nodata; |
1086 | 1087 | ||
1088 | hbinfo.param_hdr.type = SCTP_PARAM_HEARTBEAT_INFO; | ||
1089 | hbinfo.param_hdr.length = htons(sizeof(sctp_sender_hb_info_t)); | ||
1090 | hbinfo.daddr = transport->ipaddr; | ||
1091 | hbinfo.sent_at = jiffies; | ||
1092 | hbinfo.hb_nonce = transport->hb_nonce; | ||
1093 | |||
1087 | /* Cast away the 'const', as this is just telling the chunk | 1094 | /* Cast away the 'const', as this is just telling the chunk |
1088 | * what transport it belongs to. | 1095 | * what transport it belongs to. |
1089 | */ | 1096 | */ |
1090 | retval->transport = (struct sctp_transport *) transport; | 1097 | retval->transport = (struct sctp_transport *) transport; |
1091 | retval->subh.hbs_hdr = sctp_addto_chunk(retval, paylen, payload); | 1098 | retval->subh.hbs_hdr = sctp_addto_chunk(retval, sizeof(hbinfo), |
1099 | &hbinfo); | ||
1092 | 1100 | ||
1093 | nodata: | 1101 | nodata: |
1094 | return retval; | 1102 | return retval; |
@@ -2242,14 +2250,17 @@ int sctp_verify_init(const struct sctp_association *asoc, | |||
2242 | * Returns 0 on failure, else success. | 2250 | * Returns 0 on failure, else success. |
2243 | * FIXME: This is an association method. | 2251 | * FIXME: This is an association method. |
2244 | */ | 2252 | */ |
2245 | int sctp_process_init(struct sctp_association *asoc, sctp_cid_t cid, | 2253 | int sctp_process_init(struct sctp_association *asoc, struct sctp_chunk *chunk, |
2246 | const union sctp_addr *peer_addr, | 2254 | const union sctp_addr *peer_addr, |
2247 | sctp_init_chunk_t *peer_init, gfp_t gfp) | 2255 | sctp_init_chunk_t *peer_init, gfp_t gfp) |
2248 | { | 2256 | { |
2249 | union sctp_params param; | 2257 | union sctp_params param; |
2250 | struct sctp_transport *transport; | 2258 | struct sctp_transport *transport; |
2251 | struct list_head *pos, *temp; | 2259 | struct list_head *pos, *temp; |
2260 | struct sctp_af *af; | ||
2261 | union sctp_addr addr; | ||
2252 | char *cookie; | 2262 | char *cookie; |
2263 | int src_match = 0; | ||
2253 | 2264 | ||
2254 | /* We must include the address that the INIT packet came from. | 2265 | /* We must include the address that the INIT packet came from. |
2255 | * This is the only address that matters for an INIT packet. | 2266 | * This is the only address that matters for an INIT packet. |
@@ -2261,18 +2272,31 @@ int sctp_process_init(struct sctp_association *asoc, sctp_cid_t cid, | |||
2261 | * added as the primary transport. The source address seems to | 2272 | * added as the primary transport. The source address seems to |
2262 | * be a a better choice than any of the embedded addresses. | 2273 | * be a a better choice than any of the embedded addresses. |
2263 | */ | 2274 | */ |
2264 | if (peer_addr) { | 2275 | if(!sctp_assoc_add_peer(asoc, peer_addr, gfp, SCTP_ACTIVE)) |
2265 | if(!sctp_assoc_add_peer(asoc, peer_addr, gfp, SCTP_ACTIVE)) | 2276 | goto nomem; |
2266 | goto nomem; | 2277 | |
2267 | } | 2278 | if (sctp_cmp_addr_exact(sctp_source(chunk), peer_addr)) |
2279 | src_match = 1; | ||
2268 | 2280 | ||
2269 | /* Process the initialization parameters. */ | 2281 | /* Process the initialization parameters. */ |
2270 | sctp_walk_params(param, peer_init, init_hdr.params) { | 2282 | sctp_walk_params(param, peer_init, init_hdr.params) { |
2283 | if (!src_match && (param.p->type == SCTP_PARAM_IPV4_ADDRESS || | ||
2284 | param.p->type == SCTP_PARAM_IPV6_ADDRESS)) { | ||
2285 | af = sctp_get_af_specific(param_type2af(param.p->type)); | ||
2286 | af->from_addr_param(&addr, param.addr, | ||
2287 | chunk->sctp_hdr->source, 0); | ||
2288 | if (sctp_cmp_addr_exact(sctp_source(chunk), &addr)) | ||
2289 | src_match = 1; | ||
2290 | } | ||
2271 | 2291 | ||
2272 | if (!sctp_process_param(asoc, param, peer_addr, gfp)) | 2292 | if (!sctp_process_param(asoc, param, peer_addr, gfp)) |
2273 | goto clean_up; | 2293 | goto clean_up; |
2274 | } | 2294 | } |
2275 | 2295 | ||
2296 | /* source address of chunk may not match any valid address */ | ||
2297 | if (!src_match) | ||
2298 | goto clean_up; | ||
2299 | |||
2276 | /* AUTH: After processing the parameters, make sure that we | 2300 | /* AUTH: After processing the parameters, make sure that we |
2277 | * have all the required info to potentially do authentications. | 2301 | * have all the required info to potentially do authentications. |
2278 | */ | 2302 | */ |
@@ -2923,7 +2947,7 @@ static __be16 sctp_process_asconf_param(struct sctp_association *asoc, | |||
2923 | asconf_param->param_hdr.type != SCTP_PARAM_SET_PRIMARY) | 2947 | asconf_param->param_hdr.type != SCTP_PARAM_SET_PRIMARY) |
2924 | return SCTP_ERROR_UNKNOWN_PARAM; | 2948 | return SCTP_ERROR_UNKNOWN_PARAM; |
2925 | 2949 | ||
2926 | switch (addr_param->v4.param_hdr.type) { | 2950 | switch (addr_param->p.type) { |
2927 | case SCTP_PARAM_IPV6_ADDRESS: | 2951 | case SCTP_PARAM_IPV6_ADDRESS: |
2928 | if (!asoc->peer.ipv6_address) | 2952 | if (!asoc->peer.ipv6_address) |
2929 | return SCTP_ERROR_DNS_FAILED; | 2953 | return SCTP_ERROR_DNS_FAILED; |
@@ -2936,7 +2960,7 @@ static __be16 sctp_process_asconf_param(struct sctp_association *asoc, | |||
2936 | return SCTP_ERROR_DNS_FAILED; | 2960 | return SCTP_ERROR_DNS_FAILED; |
2937 | } | 2961 | } |
2938 | 2962 | ||
2939 | af = sctp_get_af_specific(param_type2af(addr_param->v4.param_hdr.type)); | 2963 | af = sctp_get_af_specific(param_type2af(addr_param->p.type)); |
2940 | if (unlikely(!af)) | 2964 | if (unlikely(!af)) |
2941 | return SCTP_ERROR_DNS_FAILED; | 2965 | return SCTP_ERROR_DNS_FAILED; |
2942 | 2966 | ||
@@ -3100,7 +3124,7 @@ struct sctp_chunk *sctp_process_asconf(struct sctp_association *asoc, | |||
3100 | /* Skip the address parameter and store a pointer to the first | 3124 | /* Skip the address parameter and store a pointer to the first |
3101 | * asconf parameter. | 3125 | * asconf parameter. |
3102 | */ | 3126 | */ |
3103 | length = ntohs(addr_param->v4.param_hdr.length); | 3127 | length = ntohs(addr_param->p.length); |
3104 | asconf_param = (sctp_addip_param_t *)((void *)addr_param + length); | 3128 | asconf_param = (sctp_addip_param_t *)((void *)addr_param + length); |
3105 | chunk_len -= length; | 3129 | chunk_len -= length; |
3106 | 3130 | ||
@@ -3177,7 +3201,7 @@ static void sctp_asconf_param_success(struct sctp_association *asoc, | |||
3177 | ((void *)asconf_param + sizeof(sctp_addip_param_t)); | 3201 | ((void *)asconf_param + sizeof(sctp_addip_param_t)); |
3178 | 3202 | ||
3179 | /* We have checked the packet before, so we do not check again. */ | 3203 | /* We have checked the packet before, so we do not check again. */ |
3180 | af = sctp_get_af_specific(param_type2af(addr_param->v4.param_hdr.type)); | 3204 | af = sctp_get_af_specific(param_type2af(addr_param->p.type)); |
3181 | af->from_addr_param(&addr, addr_param, htons(bp->port), 0); | 3205 | af->from_addr_param(&addr, addr_param, htons(bp->port), 0); |
3182 | 3206 | ||
3183 | switch (asconf_param->param_hdr.type) { | 3207 | switch (asconf_param->param_hdr.type) { |
@@ -3193,11 +3217,8 @@ static void sctp_asconf_param_success(struct sctp_association *asoc, | |||
3193 | local_bh_enable(); | 3217 | local_bh_enable(); |
3194 | list_for_each_entry(transport, &asoc->peer.transport_addr_list, | 3218 | list_for_each_entry(transport, &asoc->peer.transport_addr_list, |
3195 | transports) { | 3219 | transports) { |
3196 | if (transport->state == SCTP_ACTIVE) | ||
3197 | continue; | ||
3198 | dst_release(transport->dst); | 3220 | dst_release(transport->dst); |
3199 | sctp_transport_route(transport, NULL, | 3221 | transport->dst = NULL; |
3200 | sctp_sk(asoc->base.sk)); | ||
3201 | } | 3222 | } |
3202 | break; | 3223 | break; |
3203 | case SCTP_PARAM_DEL_IP: | 3224 | case SCTP_PARAM_DEL_IP: |
@@ -3207,8 +3228,7 @@ static void sctp_asconf_param_success(struct sctp_association *asoc, | |||
3207 | list_for_each_entry(transport, &asoc->peer.transport_addr_list, | 3228 | list_for_each_entry(transport, &asoc->peer.transport_addr_list, |
3208 | transports) { | 3229 | transports) { |
3209 | dst_release(transport->dst); | 3230 | dst_release(transport->dst); |
3210 | sctp_transport_route(transport, NULL, | 3231 | transport->dst = NULL; |
3211 | sctp_sk(asoc->base.sk)); | ||
3212 | } | 3232 | } |
3213 | break; | 3233 | break; |
3214 | default: | 3234 | default: |
@@ -3304,7 +3324,7 @@ int sctp_process_asconf_ack(struct sctp_association *asoc, | |||
3304 | /* Skip the address parameter in the last asconf sent and store a | 3324 | /* Skip the address parameter in the last asconf sent and store a |
3305 | * pointer to the first asconf parameter. | 3325 | * pointer to the first asconf parameter. |
3306 | */ | 3326 | */ |
3307 | length = ntohs(addr_param->v4.param_hdr.length); | 3327 | length = ntohs(addr_param->p.length); |
3308 | asconf_param = (sctp_addip_param_t *)((void *)addr_param + length); | 3328 | asconf_param = (sctp_addip_param_t *)((void *)addr_param + length); |
3309 | asconf_len -= length; | 3329 | asconf_len -= length; |
3310 | 3330 | ||
diff --git a/net/sctp/sm_sideeffect.c b/net/sctp/sm_sideeffect.c index 5f86ee4b54c1..d612ca1ca6c0 100644 --- a/net/sctp/sm_sideeffect.c +++ b/net/sctp/sm_sideeffect.c | |||
@@ -595,8 +595,7 @@ static int sctp_cmd_process_init(sctp_cmd_seq_t *commands, | |||
595 | * fail during INIT processing (due to malloc problems), | 595 | * fail during INIT processing (due to malloc problems), |
596 | * just return the error and stop processing the stack. | 596 | * just return the error and stop processing the stack. |
597 | */ | 597 | */ |
598 | if (!sctp_process_init(asoc, chunk->chunk_hdr->type, | 598 | if (!sctp_process_init(asoc, chunk, sctp_source(chunk), peer_init, gfp)) |
599 | sctp_source(chunk), peer_init, gfp)) | ||
600 | error = -ENOMEM; | 599 | error = -ENOMEM; |
601 | else | 600 | else |
602 | error = 0; | 601 | error = 0; |
@@ -1415,12 +1414,6 @@ static int sctp_cmd_interpreter(sctp_event_t event_type, | |||
1415 | SCTP_RTXR_T3_RTX); | 1414 | SCTP_RTXR_T3_RTX); |
1416 | break; | 1415 | break; |
1417 | 1416 | ||
1418 | case SCTP_CMD_TRANSMIT: | ||
1419 | /* Kick start transmission. */ | ||
1420 | error = sctp_outq_uncork(&asoc->outqueue); | ||
1421 | local_cork = 0; | ||
1422 | break; | ||
1423 | |||
1424 | case SCTP_CMD_ECN_CE: | 1417 | case SCTP_CMD_ECN_CE: |
1425 | /* Do delayed CE processing. */ | 1418 | /* Do delayed CE processing. */ |
1426 | sctp_do_ecn_ce_work(asoc, cmd->obj.u32); | 1419 | sctp_do_ecn_ce_work(asoc, cmd->obj.u32); |
diff --git a/net/sctp/sm_statefuns.c b/net/sctp/sm_statefuns.c index 76792083c379..7f4a4f8368ee 100644 --- a/net/sctp/sm_statefuns.c +++ b/net/sctp/sm_statefuns.c | |||
@@ -393,8 +393,7 @@ sctp_disposition_t sctp_sf_do_5_1B_init(const struct sctp_endpoint *ep, | |||
393 | goto nomem_init; | 393 | goto nomem_init; |
394 | 394 | ||
395 | /* The call, sctp_process_init(), can fail on memory allocation. */ | 395 | /* The call, sctp_process_init(), can fail on memory allocation. */ |
396 | if (!sctp_process_init(new_asoc, chunk->chunk_hdr->type, | 396 | if (!sctp_process_init(new_asoc, chunk, sctp_source(chunk), |
397 | sctp_source(chunk), | ||
398 | (sctp_init_chunk_t *)chunk->chunk_hdr, | 397 | (sctp_init_chunk_t *)chunk->chunk_hdr, |
399 | GFP_ATOMIC)) | 398 | GFP_ATOMIC)) |
400 | goto nomem_init; | 399 | goto nomem_init; |
@@ -725,7 +724,7 @@ sctp_disposition_t sctp_sf_do_5_1D_ce(const struct sctp_endpoint *ep, | |||
725 | */ | 724 | */ |
726 | peer_init = &chunk->subh.cookie_hdr->c.peer_init[0]; | 725 | peer_init = &chunk->subh.cookie_hdr->c.peer_init[0]; |
727 | 726 | ||
728 | if (!sctp_process_init(new_asoc, chunk->chunk_hdr->type, | 727 | if (!sctp_process_init(new_asoc, chunk, |
729 | &chunk->subh.cookie_hdr->c.peer_addr, | 728 | &chunk->subh.cookie_hdr->c.peer_addr, |
730 | peer_init, GFP_ATOMIC)) | 729 | peer_init, GFP_ATOMIC)) |
731 | goto nomem_init; | 730 | goto nomem_init; |
@@ -942,18 +941,9 @@ static sctp_disposition_t sctp_sf_heartbeat(const struct sctp_endpoint *ep, | |||
942 | { | 941 | { |
943 | struct sctp_transport *transport = (struct sctp_transport *) arg; | 942 | struct sctp_transport *transport = (struct sctp_transport *) arg; |
944 | struct sctp_chunk *reply; | 943 | struct sctp_chunk *reply; |
945 | sctp_sender_hb_info_t hbinfo; | ||
946 | size_t paylen = 0; | ||
947 | |||
948 | hbinfo.param_hdr.type = SCTP_PARAM_HEARTBEAT_INFO; | ||
949 | hbinfo.param_hdr.length = htons(sizeof(sctp_sender_hb_info_t)); | ||
950 | hbinfo.daddr = transport->ipaddr; | ||
951 | hbinfo.sent_at = jiffies; | ||
952 | hbinfo.hb_nonce = transport->hb_nonce; | ||
953 | 944 | ||
954 | /* Send a heartbeat to our peer. */ | 945 | /* Send a heartbeat to our peer. */ |
955 | paylen = sizeof(sctp_sender_hb_info_t); | 946 | reply = sctp_make_heartbeat(asoc, transport); |
956 | reply = sctp_make_heartbeat(asoc, transport, &hbinfo, paylen); | ||
957 | if (!reply) | 947 | if (!reply) |
958 | return SCTP_DISPOSITION_NOMEM; | 948 | return SCTP_DISPOSITION_NOMEM; |
959 | 949 | ||
@@ -1464,8 +1454,7 @@ static sctp_disposition_t sctp_sf_do_unexpected_init( | |||
1464 | * Verification Tag and Peers Verification tag into a reserved | 1454 | * Verification Tag and Peers Verification tag into a reserved |
1465 | * place (local tie-tag and per tie-tag) within the state cookie. | 1455 | * place (local tie-tag and per tie-tag) within the state cookie. |
1466 | */ | 1456 | */ |
1467 | if (!sctp_process_init(new_asoc, chunk->chunk_hdr->type, | 1457 | if (!sctp_process_init(new_asoc, chunk, sctp_source(chunk), |
1468 | sctp_source(chunk), | ||
1469 | (sctp_init_chunk_t *)chunk->chunk_hdr, | 1458 | (sctp_init_chunk_t *)chunk->chunk_hdr, |
1470 | GFP_ATOMIC)) | 1459 | GFP_ATOMIC)) |
1471 | goto nomem; | 1460 | goto nomem; |
@@ -1694,8 +1683,7 @@ static sctp_disposition_t sctp_sf_do_dupcook_a(const struct sctp_endpoint *ep, | |||
1694 | */ | 1683 | */ |
1695 | peer_init = &chunk->subh.cookie_hdr->c.peer_init[0]; | 1684 | peer_init = &chunk->subh.cookie_hdr->c.peer_init[0]; |
1696 | 1685 | ||
1697 | if (!sctp_process_init(new_asoc, chunk->chunk_hdr->type, | 1686 | if (!sctp_process_init(new_asoc, chunk, sctp_source(chunk), peer_init, |
1698 | sctp_source(chunk), peer_init, | ||
1699 | GFP_ATOMIC)) | 1687 | GFP_ATOMIC)) |
1700 | goto nomem; | 1688 | goto nomem; |
1701 | 1689 | ||
@@ -1780,8 +1768,7 @@ static sctp_disposition_t sctp_sf_do_dupcook_b(const struct sctp_endpoint *ep, | |||
1780 | * side effects--it is safe to run them here. | 1768 | * side effects--it is safe to run them here. |
1781 | */ | 1769 | */ |
1782 | peer_init = &chunk->subh.cookie_hdr->c.peer_init[0]; | 1770 | peer_init = &chunk->subh.cookie_hdr->c.peer_init[0]; |
1783 | if (!sctp_process_init(new_asoc, chunk->chunk_hdr->type, | 1771 | if (!sctp_process_init(new_asoc, chunk, sctp_source(chunk), peer_init, |
1784 | sctp_source(chunk), peer_init, | ||
1785 | GFP_ATOMIC)) | 1772 | GFP_ATOMIC)) |
1786 | goto nomem; | 1773 | goto nomem; |
1787 | 1774 | ||
@@ -2412,8 +2399,15 @@ static sctp_disposition_t __sctp_sf_do_9_1_abort(const struct sctp_endpoint *ep, | |||
2412 | 2399 | ||
2413 | /* See if we have an error cause code in the chunk. */ | 2400 | /* See if we have an error cause code in the chunk. */ |
2414 | len = ntohs(chunk->chunk_hdr->length); | 2401 | len = ntohs(chunk->chunk_hdr->length); |
2415 | if (len >= sizeof(struct sctp_chunkhdr) + sizeof(struct sctp_errhdr)) | 2402 | if (len >= sizeof(struct sctp_chunkhdr) + sizeof(struct sctp_errhdr)) { |
2403 | |||
2404 | sctp_errhdr_t *err; | ||
2405 | sctp_walk_errors(err, chunk->chunk_hdr); | ||
2406 | if ((void *)err != (void *)chunk->chunk_end) | ||
2407 | return sctp_sf_pdiscard(ep, asoc, type, arg, commands); | ||
2408 | |||
2416 | error = ((sctp_errhdr_t *)chunk->skb->data)->cause; | 2409 | error = ((sctp_errhdr_t *)chunk->skb->data)->cause; |
2410 | } | ||
2417 | 2411 | ||
2418 | sctp_add_cmd_sf(commands, SCTP_CMD_SET_SK_ERR, SCTP_ERROR(ECONNRESET)); | 2412 | sctp_add_cmd_sf(commands, SCTP_CMD_SET_SK_ERR, SCTP_ERROR(ECONNRESET)); |
2419 | /* ASSOC_FAILED will DELETE_TCB. */ | 2413 | /* ASSOC_FAILED will DELETE_TCB. */ |
@@ -3204,6 +3198,7 @@ sctp_disposition_t sctp_sf_operr_notify(const struct sctp_endpoint *ep, | |||
3204 | sctp_cmd_seq_t *commands) | 3198 | sctp_cmd_seq_t *commands) |
3205 | { | 3199 | { |
3206 | struct sctp_chunk *chunk = arg; | 3200 | struct sctp_chunk *chunk = arg; |
3201 | sctp_errhdr_t *err; | ||
3207 | 3202 | ||
3208 | if (!sctp_vtag_verify(chunk, asoc)) | 3203 | if (!sctp_vtag_verify(chunk, asoc)) |
3209 | return sctp_sf_pdiscard(ep, asoc, type, arg, commands); | 3204 | return sctp_sf_pdiscard(ep, asoc, type, arg, commands); |
@@ -3212,6 +3207,10 @@ sctp_disposition_t sctp_sf_operr_notify(const struct sctp_endpoint *ep, | |||
3212 | if (!sctp_chunk_length_valid(chunk, sizeof(sctp_operr_chunk_t))) | 3207 | if (!sctp_chunk_length_valid(chunk, sizeof(sctp_operr_chunk_t))) |
3213 | return sctp_sf_violation_chunklen(ep, asoc, type, arg, | 3208 | return sctp_sf_violation_chunklen(ep, asoc, type, arg, |
3214 | commands); | 3209 | commands); |
3210 | sctp_walk_errors(err, chunk->chunk_hdr); | ||
3211 | if ((void *)err != (void *)chunk->chunk_end) | ||
3212 | return sctp_sf_violation_paramlen(ep, asoc, type, arg, | ||
3213 | (void *)err, commands); | ||
3215 | 3214 | ||
3216 | sctp_add_cmd_sf(commands, SCTP_CMD_PROCESS_OPERR, | 3215 | sctp_add_cmd_sf(commands, SCTP_CMD_PROCESS_OPERR, |
3217 | SCTP_CHUNK(chunk)); | 3216 | SCTP_CHUNK(chunk)); |
@@ -3320,8 +3319,10 @@ sctp_disposition_t sctp_sf_ootb(const struct sctp_endpoint *ep, | |||
3320 | struct sctp_chunk *chunk = arg; | 3319 | struct sctp_chunk *chunk = arg; |
3321 | struct sk_buff *skb = chunk->skb; | 3320 | struct sk_buff *skb = chunk->skb; |
3322 | sctp_chunkhdr_t *ch; | 3321 | sctp_chunkhdr_t *ch; |
3322 | sctp_errhdr_t *err; | ||
3323 | __u8 *ch_end; | 3323 | __u8 *ch_end; |
3324 | int ootb_shut_ack = 0; | 3324 | int ootb_shut_ack = 0; |
3325 | int ootb_cookie_ack = 0; | ||
3325 | 3326 | ||
3326 | SCTP_INC_STATS(SCTP_MIB_OUTOFBLUES); | 3327 | SCTP_INC_STATS(SCTP_MIB_OUTOFBLUES); |
3327 | 3328 | ||
@@ -3346,6 +3347,23 @@ sctp_disposition_t sctp_sf_ootb(const struct sctp_endpoint *ep, | |||
3346 | if (SCTP_CID_ABORT == ch->type) | 3347 | if (SCTP_CID_ABORT == ch->type) |
3347 | return sctp_sf_pdiscard(ep, asoc, type, arg, commands); | 3348 | return sctp_sf_pdiscard(ep, asoc, type, arg, commands); |
3348 | 3349 | ||
3350 | /* RFC 8.4, 7) If the packet contains a "Stale cookie" ERROR | ||
3351 | * or a COOKIE ACK the SCTP Packet should be silently | ||
3352 | * discarded. | ||
3353 | */ | ||
3354 | |||
3355 | if (SCTP_CID_COOKIE_ACK == ch->type) | ||
3356 | ootb_cookie_ack = 1; | ||
3357 | |||
3358 | if (SCTP_CID_ERROR == ch->type) { | ||
3359 | sctp_walk_errors(err, ch) { | ||
3360 | if (SCTP_ERROR_STALE_COOKIE == err->cause) { | ||
3361 | ootb_cookie_ack = 1; | ||
3362 | break; | ||
3363 | } | ||
3364 | } | ||
3365 | } | ||
3366 | |||
3349 | /* Report violation if chunk len overflows */ | 3367 | /* Report violation if chunk len overflows */ |
3350 | ch_end = ((__u8 *)ch) + WORD_ROUND(ntohs(ch->length)); | 3368 | ch_end = ((__u8 *)ch) + WORD_ROUND(ntohs(ch->length)); |
3351 | if (ch_end > skb_tail_pointer(skb)) | 3369 | if (ch_end > skb_tail_pointer(skb)) |
@@ -3357,6 +3375,8 @@ sctp_disposition_t sctp_sf_ootb(const struct sctp_endpoint *ep, | |||
3357 | 3375 | ||
3358 | if (ootb_shut_ack) | 3376 | if (ootb_shut_ack) |
3359 | return sctp_sf_shut_8_4_5(ep, asoc, type, arg, commands); | 3377 | return sctp_sf_shut_8_4_5(ep, asoc, type, arg, commands); |
3378 | else if (ootb_cookie_ack) | ||
3379 | return sctp_sf_pdiscard(ep, asoc, type, arg, commands); | ||
3360 | else | 3380 | else |
3361 | return sctp_sf_tabort_8_4_8(ep, asoc, type, arg, commands); | 3381 | return sctp_sf_tabort_8_4_8(ep, asoc, type, arg, commands); |
3362 | } | 3382 | } |
@@ -4343,8 +4363,9 @@ static sctp_disposition_t sctp_sf_violation_chunklen( | |||
4343 | 4363 | ||
4344 | /* | 4364 | /* |
4345 | * Handle a protocol violation when the parameter length is invalid. | 4365 | * Handle a protocol violation when the parameter length is invalid. |
4346 | * "Invalid" length is identified as smaller than the minimal length a | 4366 | * If the length is smaller than the minimum length of a given parameter, |
4347 | * given parameter can be. | 4367 | * or accumulated length in multi parameters exceeds the end of the chunk, |
4368 | * the length is considered as invalid. | ||
4348 | */ | 4369 | */ |
4349 | static sctp_disposition_t sctp_sf_violation_paramlen( | 4370 | static sctp_disposition_t sctp_sf_violation_paramlen( |
4350 | const struct sctp_endpoint *ep, | 4371 | const struct sctp_endpoint *ep, |
@@ -5056,6 +5077,30 @@ sctp_disposition_t sctp_sf_ignore_primitive( | |||
5056 | ***************************************************************************/ | 5077 | ***************************************************************************/ |
5057 | 5078 | ||
5058 | /* | 5079 | /* |
5080 | * When the SCTP stack has no more user data to send or retransmit, this | ||
5081 | * notification is given to the user. Also, at the time when a user app | ||
5082 | * subscribes to this event, if there is no data to be sent or | ||
5083 | * retransmit, the stack will immediately send up this notification. | ||
5084 | */ | ||
5085 | sctp_disposition_t sctp_sf_do_no_pending_tsn( | ||
5086 | const struct sctp_endpoint *ep, | ||
5087 | const struct sctp_association *asoc, | ||
5088 | const sctp_subtype_t type, | ||
5089 | void *arg, | ||
5090 | sctp_cmd_seq_t *commands) | ||
5091 | { | ||
5092 | struct sctp_ulpevent *event; | ||
5093 | |||
5094 | event = sctp_ulpevent_make_sender_dry_event(asoc, GFP_ATOMIC); | ||
5095 | if (!event) | ||
5096 | return SCTP_DISPOSITION_NOMEM; | ||
5097 | |||
5098 | sctp_add_cmd_sf(commands, SCTP_CMD_EVENT_ULP, SCTP_ULPEVENT(event)); | ||
5099 | |||
5100 | return SCTP_DISPOSITION_CONSUME; | ||
5101 | } | ||
5102 | |||
5103 | /* | ||
5059 | * Start the shutdown negotiation. | 5104 | * Start the shutdown negotiation. |
5060 | * | 5105 | * |
5061 | * From Section 9.2: | 5106 | * From Section 9.2: |
diff --git a/net/sctp/sm_statetable.c b/net/sctp/sm_statetable.c index 546d4387fb3c..0338dc6fdc9d 100644 --- a/net/sctp/sm_statetable.c +++ b/net/sctp/sm_statetable.c | |||
@@ -107,8 +107,6 @@ const sctp_sm_table_entry_t *sctp_sm_lookup_event(sctp_event_t event_type, | |||
107 | #define TYPE_SCTP_FUNC(func) {.fn = func, .name = #func} | 107 | #define TYPE_SCTP_FUNC(func) {.fn = func, .name = #func} |
108 | 108 | ||
109 | #define TYPE_SCTP_DATA { \ | 109 | #define TYPE_SCTP_DATA { \ |
110 | /* SCTP_STATE_EMPTY */ \ | ||
111 | TYPE_SCTP_FUNC(sctp_sf_ootb), \ | ||
112 | /* SCTP_STATE_CLOSED */ \ | 110 | /* SCTP_STATE_CLOSED */ \ |
113 | TYPE_SCTP_FUNC(sctp_sf_ootb), \ | 111 | TYPE_SCTP_FUNC(sctp_sf_ootb), \ |
114 | /* SCTP_STATE_COOKIE_WAIT */ \ | 112 | /* SCTP_STATE_COOKIE_WAIT */ \ |
@@ -128,8 +126,6 @@ const sctp_sm_table_entry_t *sctp_sm_lookup_event(sctp_event_t event_type, | |||
128 | } /* TYPE_SCTP_DATA */ | 126 | } /* TYPE_SCTP_DATA */ |
129 | 127 | ||
130 | #define TYPE_SCTP_INIT { \ | 128 | #define TYPE_SCTP_INIT { \ |
131 | /* SCTP_STATE_EMPTY */ \ | ||
132 | TYPE_SCTP_FUNC(sctp_sf_bug), \ | ||
133 | /* SCTP_STATE_CLOSED */ \ | 129 | /* SCTP_STATE_CLOSED */ \ |
134 | TYPE_SCTP_FUNC(sctp_sf_do_5_1B_init), \ | 130 | TYPE_SCTP_FUNC(sctp_sf_do_5_1B_init), \ |
135 | /* SCTP_STATE_COOKIE_WAIT */ \ | 131 | /* SCTP_STATE_COOKIE_WAIT */ \ |
@@ -149,8 +145,6 @@ const sctp_sm_table_entry_t *sctp_sm_lookup_event(sctp_event_t event_type, | |||
149 | } /* TYPE_SCTP_INIT */ | 145 | } /* TYPE_SCTP_INIT */ |
150 | 146 | ||
151 | #define TYPE_SCTP_INIT_ACK { \ | 147 | #define TYPE_SCTP_INIT_ACK { \ |
152 | /* SCTP_STATE_EMPTY */ \ | ||
153 | TYPE_SCTP_FUNC(sctp_sf_ootb), \ | ||
154 | /* SCTP_STATE_CLOSED */ \ | 148 | /* SCTP_STATE_CLOSED */ \ |
155 | TYPE_SCTP_FUNC(sctp_sf_do_5_2_3_initack), \ | 149 | TYPE_SCTP_FUNC(sctp_sf_do_5_2_3_initack), \ |
156 | /* SCTP_STATE_COOKIE_WAIT */ \ | 150 | /* SCTP_STATE_COOKIE_WAIT */ \ |
@@ -170,8 +164,6 @@ const sctp_sm_table_entry_t *sctp_sm_lookup_event(sctp_event_t event_type, | |||
170 | } /* TYPE_SCTP_INIT_ACK */ | 164 | } /* TYPE_SCTP_INIT_ACK */ |
171 | 165 | ||
172 | #define TYPE_SCTP_SACK { \ | 166 | #define TYPE_SCTP_SACK { \ |
173 | /* SCTP_STATE_EMPTY */ \ | ||
174 | TYPE_SCTP_FUNC(sctp_sf_ootb), \ | ||
175 | /* SCTP_STATE_CLOSED */ \ | 167 | /* SCTP_STATE_CLOSED */ \ |
176 | TYPE_SCTP_FUNC(sctp_sf_ootb), \ | 168 | TYPE_SCTP_FUNC(sctp_sf_ootb), \ |
177 | /* SCTP_STATE_COOKIE_WAIT */ \ | 169 | /* SCTP_STATE_COOKIE_WAIT */ \ |
@@ -191,8 +183,6 @@ const sctp_sm_table_entry_t *sctp_sm_lookup_event(sctp_event_t event_type, | |||
191 | } /* TYPE_SCTP_SACK */ | 183 | } /* TYPE_SCTP_SACK */ |
192 | 184 | ||
193 | #define TYPE_SCTP_HEARTBEAT { \ | 185 | #define TYPE_SCTP_HEARTBEAT { \ |
194 | /* SCTP_STATE_EMPTY */ \ | ||
195 | TYPE_SCTP_FUNC(sctp_sf_ootb), \ | ||
196 | /* SCTP_STATE_CLOSED */ \ | 186 | /* SCTP_STATE_CLOSED */ \ |
197 | TYPE_SCTP_FUNC(sctp_sf_ootb), \ | 187 | TYPE_SCTP_FUNC(sctp_sf_ootb), \ |
198 | /* SCTP_STATE_COOKIE_WAIT */ \ | 188 | /* SCTP_STATE_COOKIE_WAIT */ \ |
@@ -213,8 +203,6 @@ const sctp_sm_table_entry_t *sctp_sm_lookup_event(sctp_event_t event_type, | |||
213 | } /* TYPE_SCTP_HEARTBEAT */ | 203 | } /* TYPE_SCTP_HEARTBEAT */ |
214 | 204 | ||
215 | #define TYPE_SCTP_HEARTBEAT_ACK { \ | 205 | #define TYPE_SCTP_HEARTBEAT_ACK { \ |
216 | /* SCTP_STATE_EMPTY */ \ | ||
217 | TYPE_SCTP_FUNC(sctp_sf_ootb), \ | ||
218 | /* SCTP_STATE_CLOSED */ \ | 206 | /* SCTP_STATE_CLOSED */ \ |
219 | TYPE_SCTP_FUNC(sctp_sf_ootb), \ | 207 | TYPE_SCTP_FUNC(sctp_sf_ootb), \ |
220 | /* SCTP_STATE_COOKIE_WAIT */ \ | 208 | /* SCTP_STATE_COOKIE_WAIT */ \ |
@@ -234,8 +222,6 @@ const sctp_sm_table_entry_t *sctp_sm_lookup_event(sctp_event_t event_type, | |||
234 | } /* TYPE_SCTP_HEARTBEAT_ACK */ | 222 | } /* TYPE_SCTP_HEARTBEAT_ACK */ |
235 | 223 | ||
236 | #define TYPE_SCTP_ABORT { \ | 224 | #define TYPE_SCTP_ABORT { \ |
237 | /* SCTP_STATE_EMPTY */ \ | ||
238 | TYPE_SCTP_FUNC(sctp_sf_ootb), \ | ||
239 | /* SCTP_STATE_CLOSED */ \ | 225 | /* SCTP_STATE_CLOSED */ \ |
240 | TYPE_SCTP_FUNC(sctp_sf_pdiscard), \ | 226 | TYPE_SCTP_FUNC(sctp_sf_pdiscard), \ |
241 | /* SCTP_STATE_COOKIE_WAIT */ \ | 227 | /* SCTP_STATE_COOKIE_WAIT */ \ |
@@ -255,8 +241,6 @@ const sctp_sm_table_entry_t *sctp_sm_lookup_event(sctp_event_t event_type, | |||
255 | } /* TYPE_SCTP_ABORT */ | 241 | } /* TYPE_SCTP_ABORT */ |
256 | 242 | ||
257 | #define TYPE_SCTP_SHUTDOWN { \ | 243 | #define TYPE_SCTP_SHUTDOWN { \ |
258 | /* SCTP_STATE_EMPTY */ \ | ||
259 | TYPE_SCTP_FUNC(sctp_sf_ootb), \ | ||
260 | /* SCTP_STATE_CLOSED */ \ | 244 | /* SCTP_STATE_CLOSED */ \ |
261 | TYPE_SCTP_FUNC(sctp_sf_ootb), \ | 245 | TYPE_SCTP_FUNC(sctp_sf_ootb), \ |
262 | /* SCTP_STATE_COOKIE_WAIT */ \ | 246 | /* SCTP_STATE_COOKIE_WAIT */ \ |
@@ -276,8 +260,6 @@ const sctp_sm_table_entry_t *sctp_sm_lookup_event(sctp_event_t event_type, | |||
276 | } /* TYPE_SCTP_SHUTDOWN */ | 260 | } /* TYPE_SCTP_SHUTDOWN */ |
277 | 261 | ||
278 | #define TYPE_SCTP_SHUTDOWN_ACK { \ | 262 | #define TYPE_SCTP_SHUTDOWN_ACK { \ |
279 | /* SCTP_STATE_EMPTY */ \ | ||
280 | TYPE_SCTP_FUNC(sctp_sf_ootb), \ | ||
281 | /* SCTP_STATE_CLOSED */ \ | 263 | /* SCTP_STATE_CLOSED */ \ |
282 | TYPE_SCTP_FUNC(sctp_sf_ootb), \ | 264 | TYPE_SCTP_FUNC(sctp_sf_ootb), \ |
283 | /* SCTP_STATE_COOKIE_WAIT */ \ | 265 | /* SCTP_STATE_COOKIE_WAIT */ \ |
@@ -297,8 +279,6 @@ const sctp_sm_table_entry_t *sctp_sm_lookup_event(sctp_event_t event_type, | |||
297 | } /* TYPE_SCTP_SHUTDOWN_ACK */ | 279 | } /* TYPE_SCTP_SHUTDOWN_ACK */ |
298 | 280 | ||
299 | #define TYPE_SCTP_ERROR { \ | 281 | #define TYPE_SCTP_ERROR { \ |
300 | /* SCTP_STATE_EMPTY */ \ | ||
301 | TYPE_SCTP_FUNC(sctp_sf_ootb), \ | ||
302 | /* SCTP_STATE_CLOSED */ \ | 282 | /* SCTP_STATE_CLOSED */ \ |
303 | TYPE_SCTP_FUNC(sctp_sf_ootb), \ | 283 | TYPE_SCTP_FUNC(sctp_sf_ootb), \ |
304 | /* SCTP_STATE_COOKIE_WAIT */ \ | 284 | /* SCTP_STATE_COOKIE_WAIT */ \ |
@@ -318,8 +298,6 @@ const sctp_sm_table_entry_t *sctp_sm_lookup_event(sctp_event_t event_type, | |||
318 | } /* TYPE_SCTP_ERROR */ | 298 | } /* TYPE_SCTP_ERROR */ |
319 | 299 | ||
320 | #define TYPE_SCTP_COOKIE_ECHO { \ | 300 | #define TYPE_SCTP_COOKIE_ECHO { \ |
321 | /* SCTP_STATE_EMPTY */ \ | ||
322 | TYPE_SCTP_FUNC(sctp_sf_bug), \ | ||
323 | /* SCTP_STATE_CLOSED */ \ | 301 | /* SCTP_STATE_CLOSED */ \ |
324 | TYPE_SCTP_FUNC(sctp_sf_do_5_1D_ce), \ | 302 | TYPE_SCTP_FUNC(sctp_sf_do_5_1D_ce), \ |
325 | /* SCTP_STATE_COOKIE_WAIT */ \ | 303 | /* SCTP_STATE_COOKIE_WAIT */ \ |
@@ -339,8 +317,6 @@ const sctp_sm_table_entry_t *sctp_sm_lookup_event(sctp_event_t event_type, | |||
339 | } /* TYPE_SCTP_COOKIE_ECHO */ | 317 | } /* TYPE_SCTP_COOKIE_ECHO */ |
340 | 318 | ||
341 | #define TYPE_SCTP_COOKIE_ACK { \ | 319 | #define TYPE_SCTP_COOKIE_ACK { \ |
342 | /* SCTP_STATE_EMPTY */ \ | ||
343 | TYPE_SCTP_FUNC(sctp_sf_ootb), \ | ||
344 | /* SCTP_STATE_CLOSED */ \ | 320 | /* SCTP_STATE_CLOSED */ \ |
345 | TYPE_SCTP_FUNC(sctp_sf_discard_chunk), \ | 321 | TYPE_SCTP_FUNC(sctp_sf_discard_chunk), \ |
346 | /* SCTP_STATE_COOKIE_WAIT */ \ | 322 | /* SCTP_STATE_COOKIE_WAIT */ \ |
@@ -360,8 +336,6 @@ const sctp_sm_table_entry_t *sctp_sm_lookup_event(sctp_event_t event_type, | |||
360 | } /* TYPE_SCTP_COOKIE_ACK */ | 336 | } /* TYPE_SCTP_COOKIE_ACK */ |
361 | 337 | ||
362 | #define TYPE_SCTP_ECN_ECNE { \ | 338 | #define TYPE_SCTP_ECN_ECNE { \ |
363 | /* SCTP_STATE_EMPTY */ \ | ||
364 | TYPE_SCTP_FUNC(sctp_sf_ootb), \ | ||
365 | /* SCTP_STATE_CLOSED */ \ | 339 | /* SCTP_STATE_CLOSED */ \ |
366 | TYPE_SCTP_FUNC(sctp_sf_discard_chunk), \ | 340 | TYPE_SCTP_FUNC(sctp_sf_discard_chunk), \ |
367 | /* SCTP_STATE_COOKIE_WAIT */ \ | 341 | /* SCTP_STATE_COOKIE_WAIT */ \ |
@@ -381,8 +355,6 @@ const sctp_sm_table_entry_t *sctp_sm_lookup_event(sctp_event_t event_type, | |||
381 | } /* TYPE_SCTP_ECN_ECNE */ | 355 | } /* TYPE_SCTP_ECN_ECNE */ |
382 | 356 | ||
383 | #define TYPE_SCTP_ECN_CWR { \ | 357 | #define TYPE_SCTP_ECN_CWR { \ |
384 | /* SCTP_STATE_EMPTY */ \ | ||
385 | TYPE_SCTP_FUNC(sctp_sf_ootb), \ | ||
386 | /* SCTP_STATE_CLOSED */ \ | 358 | /* SCTP_STATE_CLOSED */ \ |
387 | TYPE_SCTP_FUNC(sctp_sf_discard_chunk), \ | 359 | TYPE_SCTP_FUNC(sctp_sf_discard_chunk), \ |
388 | /* SCTP_STATE_COOKIE_WAIT */ \ | 360 | /* SCTP_STATE_COOKIE_WAIT */ \ |
@@ -402,8 +374,6 @@ const sctp_sm_table_entry_t *sctp_sm_lookup_event(sctp_event_t event_type, | |||
402 | } /* TYPE_SCTP_ECN_CWR */ | 374 | } /* TYPE_SCTP_ECN_CWR */ |
403 | 375 | ||
404 | #define TYPE_SCTP_SHUTDOWN_COMPLETE { \ | 376 | #define TYPE_SCTP_SHUTDOWN_COMPLETE { \ |
405 | /* SCTP_STATE_EMPTY */ \ | ||
406 | TYPE_SCTP_FUNC(sctp_sf_ootb), \ | ||
407 | /* SCTP_STATE_CLOSED */ \ | 377 | /* SCTP_STATE_CLOSED */ \ |
408 | TYPE_SCTP_FUNC(sctp_sf_discard_chunk), \ | 378 | TYPE_SCTP_FUNC(sctp_sf_discard_chunk), \ |
409 | /* SCTP_STATE_COOKIE_WAIT */ \ | 379 | /* SCTP_STATE_COOKIE_WAIT */ \ |
@@ -446,8 +416,6 @@ static const sctp_sm_table_entry_t chunk_event_table[SCTP_NUM_BASE_CHUNK_TYPES][ | |||
446 | }; /* state_fn_t chunk_event_table[][] */ | 416 | }; /* state_fn_t chunk_event_table[][] */ |
447 | 417 | ||
448 | #define TYPE_SCTP_ASCONF { \ | 418 | #define TYPE_SCTP_ASCONF { \ |
449 | /* SCTP_STATE_EMPTY */ \ | ||
450 | TYPE_SCTP_FUNC(sctp_sf_ootb), \ | ||
451 | /* SCTP_STATE_CLOSED */ \ | 419 | /* SCTP_STATE_CLOSED */ \ |
452 | TYPE_SCTP_FUNC(sctp_sf_discard_chunk), \ | 420 | TYPE_SCTP_FUNC(sctp_sf_discard_chunk), \ |
453 | /* SCTP_STATE_COOKIE_WAIT */ \ | 421 | /* SCTP_STATE_COOKIE_WAIT */ \ |
@@ -467,8 +435,6 @@ static const sctp_sm_table_entry_t chunk_event_table[SCTP_NUM_BASE_CHUNK_TYPES][ | |||
467 | } /* TYPE_SCTP_ASCONF */ | 435 | } /* TYPE_SCTP_ASCONF */ |
468 | 436 | ||
469 | #define TYPE_SCTP_ASCONF_ACK { \ | 437 | #define TYPE_SCTP_ASCONF_ACK { \ |
470 | /* SCTP_STATE_EMPTY */ \ | ||
471 | TYPE_SCTP_FUNC(sctp_sf_ootb), \ | ||
472 | /* SCTP_STATE_CLOSED */ \ | 438 | /* SCTP_STATE_CLOSED */ \ |
473 | TYPE_SCTP_FUNC(sctp_sf_discard_chunk), \ | 439 | TYPE_SCTP_FUNC(sctp_sf_discard_chunk), \ |
474 | /* SCTP_STATE_COOKIE_WAIT */ \ | 440 | /* SCTP_STATE_COOKIE_WAIT */ \ |
@@ -496,8 +462,6 @@ static const sctp_sm_table_entry_t addip_chunk_event_table[SCTP_NUM_ADDIP_CHUNK_ | |||
496 | }; /*state_fn_t addip_chunk_event_table[][] */ | 462 | }; /*state_fn_t addip_chunk_event_table[][] */ |
497 | 463 | ||
498 | #define TYPE_SCTP_FWD_TSN { \ | 464 | #define TYPE_SCTP_FWD_TSN { \ |
499 | /* SCTP_STATE_EMPTY */ \ | ||
500 | TYPE_SCTP_FUNC(sctp_sf_ootb), \ | ||
501 | /* SCTP_STATE_CLOSED */ \ | 465 | /* SCTP_STATE_CLOSED */ \ |
502 | TYPE_SCTP_FUNC(sctp_sf_ootb), \ | 466 | TYPE_SCTP_FUNC(sctp_sf_ootb), \ |
503 | /* SCTP_STATE_COOKIE_WAIT */ \ | 467 | /* SCTP_STATE_COOKIE_WAIT */ \ |
@@ -524,8 +488,6 @@ static const sctp_sm_table_entry_t prsctp_chunk_event_table[SCTP_NUM_PRSCTP_CHUN | |||
524 | }; /*state_fn_t prsctp_chunk_event_table[][] */ | 488 | }; /*state_fn_t prsctp_chunk_event_table[][] */ |
525 | 489 | ||
526 | #define TYPE_SCTP_AUTH { \ | 490 | #define TYPE_SCTP_AUTH { \ |
527 | /* SCTP_STATE_EMPTY */ \ | ||
528 | TYPE_SCTP_FUNC(sctp_sf_ootb), \ | ||
529 | /* SCTP_STATE_CLOSED */ \ | 491 | /* SCTP_STATE_CLOSED */ \ |
530 | TYPE_SCTP_FUNC(sctp_sf_ootb), \ | 492 | TYPE_SCTP_FUNC(sctp_sf_ootb), \ |
531 | /* SCTP_STATE_COOKIE_WAIT */ \ | 493 | /* SCTP_STATE_COOKIE_WAIT */ \ |
@@ -553,8 +515,6 @@ static const sctp_sm_table_entry_t auth_chunk_event_table[SCTP_NUM_AUTH_CHUNK_TY | |||
553 | 515 | ||
554 | static const sctp_sm_table_entry_t | 516 | static const sctp_sm_table_entry_t |
555 | chunk_event_table_unknown[SCTP_STATE_NUM_STATES] = { | 517 | chunk_event_table_unknown[SCTP_STATE_NUM_STATES] = { |
556 | /* SCTP_STATE_EMPTY */ | ||
557 | TYPE_SCTP_FUNC(sctp_sf_ootb), | ||
558 | /* SCTP_STATE_CLOSED */ | 518 | /* SCTP_STATE_CLOSED */ |
559 | TYPE_SCTP_FUNC(sctp_sf_ootb), | 519 | TYPE_SCTP_FUNC(sctp_sf_ootb), |
560 | /* SCTP_STATE_COOKIE_WAIT */ | 520 | /* SCTP_STATE_COOKIE_WAIT */ |
@@ -575,8 +535,6 @@ chunk_event_table_unknown[SCTP_STATE_NUM_STATES] = { | |||
575 | 535 | ||
576 | 536 | ||
577 | #define TYPE_SCTP_PRIMITIVE_ASSOCIATE { \ | 537 | #define TYPE_SCTP_PRIMITIVE_ASSOCIATE { \ |
578 | /* SCTP_STATE_EMPTY */ \ | ||
579 | TYPE_SCTP_FUNC(sctp_sf_bug), \ | ||
580 | /* SCTP_STATE_CLOSED */ \ | 538 | /* SCTP_STATE_CLOSED */ \ |
581 | TYPE_SCTP_FUNC(sctp_sf_do_prm_asoc), \ | 539 | TYPE_SCTP_FUNC(sctp_sf_do_prm_asoc), \ |
582 | /* SCTP_STATE_COOKIE_WAIT */ \ | 540 | /* SCTP_STATE_COOKIE_WAIT */ \ |
@@ -596,8 +554,6 @@ chunk_event_table_unknown[SCTP_STATE_NUM_STATES] = { | |||
596 | } /* TYPE_SCTP_PRIMITIVE_ASSOCIATE */ | 554 | } /* TYPE_SCTP_PRIMITIVE_ASSOCIATE */ |
597 | 555 | ||
598 | #define TYPE_SCTP_PRIMITIVE_SHUTDOWN { \ | 556 | #define TYPE_SCTP_PRIMITIVE_SHUTDOWN { \ |
599 | /* SCTP_STATE_EMPTY */ \ | ||
600 | TYPE_SCTP_FUNC(sctp_sf_bug), \ | ||
601 | /* SCTP_STATE_CLOSED */ \ | 557 | /* SCTP_STATE_CLOSED */ \ |
602 | TYPE_SCTP_FUNC(sctp_sf_error_closed), \ | 558 | TYPE_SCTP_FUNC(sctp_sf_error_closed), \ |
603 | /* SCTP_STATE_COOKIE_WAIT */ \ | 559 | /* SCTP_STATE_COOKIE_WAIT */ \ |
@@ -617,8 +573,6 @@ chunk_event_table_unknown[SCTP_STATE_NUM_STATES] = { | |||
617 | } /* TYPE_SCTP_PRIMITIVE_SHUTDOWN */ | 573 | } /* TYPE_SCTP_PRIMITIVE_SHUTDOWN */ |
618 | 574 | ||
619 | #define TYPE_SCTP_PRIMITIVE_ABORT { \ | 575 | #define TYPE_SCTP_PRIMITIVE_ABORT { \ |
620 | /* SCTP_STATE_EMPTY */ \ | ||
621 | TYPE_SCTP_FUNC(sctp_sf_bug), \ | ||
622 | /* SCTP_STATE_CLOSED */ \ | 576 | /* SCTP_STATE_CLOSED */ \ |
623 | TYPE_SCTP_FUNC(sctp_sf_error_closed), \ | 577 | TYPE_SCTP_FUNC(sctp_sf_error_closed), \ |
624 | /* SCTP_STATE_COOKIE_WAIT */ \ | 578 | /* SCTP_STATE_COOKIE_WAIT */ \ |
@@ -638,8 +592,6 @@ chunk_event_table_unknown[SCTP_STATE_NUM_STATES] = { | |||
638 | } /* TYPE_SCTP_PRIMITIVE_ABORT */ | 592 | } /* TYPE_SCTP_PRIMITIVE_ABORT */ |
639 | 593 | ||
640 | #define TYPE_SCTP_PRIMITIVE_SEND { \ | 594 | #define TYPE_SCTP_PRIMITIVE_SEND { \ |
641 | /* SCTP_STATE_EMPTY */ \ | ||
642 | TYPE_SCTP_FUNC(sctp_sf_bug), \ | ||
643 | /* SCTP_STATE_CLOSED */ \ | 595 | /* SCTP_STATE_CLOSED */ \ |
644 | TYPE_SCTP_FUNC(sctp_sf_error_closed), \ | 596 | TYPE_SCTP_FUNC(sctp_sf_error_closed), \ |
645 | /* SCTP_STATE_COOKIE_WAIT */ \ | 597 | /* SCTP_STATE_COOKIE_WAIT */ \ |
@@ -659,8 +611,6 @@ chunk_event_table_unknown[SCTP_STATE_NUM_STATES] = { | |||
659 | } /* TYPE_SCTP_PRIMITIVE_SEND */ | 611 | } /* TYPE_SCTP_PRIMITIVE_SEND */ |
660 | 612 | ||
661 | #define TYPE_SCTP_PRIMITIVE_REQUESTHEARTBEAT { \ | 613 | #define TYPE_SCTP_PRIMITIVE_REQUESTHEARTBEAT { \ |
662 | /* SCTP_STATE_EMPTY */ \ | ||
663 | TYPE_SCTP_FUNC(sctp_sf_bug), \ | ||
664 | /* SCTP_STATE_CLOSED */ \ | 614 | /* SCTP_STATE_CLOSED */ \ |
665 | TYPE_SCTP_FUNC(sctp_sf_error_closed), \ | 615 | TYPE_SCTP_FUNC(sctp_sf_error_closed), \ |
666 | /* SCTP_STATE_COOKIE_WAIT */ \ | 616 | /* SCTP_STATE_COOKIE_WAIT */ \ |
@@ -680,8 +630,6 @@ chunk_event_table_unknown[SCTP_STATE_NUM_STATES] = { | |||
680 | } /* TYPE_SCTP_PRIMITIVE_REQUESTHEARTBEAT */ | 630 | } /* TYPE_SCTP_PRIMITIVE_REQUESTHEARTBEAT */ |
681 | 631 | ||
682 | #define TYPE_SCTP_PRIMITIVE_ASCONF { \ | 632 | #define TYPE_SCTP_PRIMITIVE_ASCONF { \ |
683 | /* SCTP_STATE_EMPTY */ \ | ||
684 | TYPE_SCTP_FUNC(sctp_sf_bug), \ | ||
685 | /* SCTP_STATE_CLOSED */ \ | 633 | /* SCTP_STATE_CLOSED */ \ |
686 | TYPE_SCTP_FUNC(sctp_sf_error_closed), \ | 634 | TYPE_SCTP_FUNC(sctp_sf_error_closed), \ |
687 | /* SCTP_STATE_COOKIE_WAIT */ \ | 635 | /* SCTP_STATE_COOKIE_WAIT */ \ |
@@ -713,8 +661,6 @@ static const sctp_sm_table_entry_t primitive_event_table[SCTP_NUM_PRIMITIVE_TYPE | |||
713 | }; | 661 | }; |
714 | 662 | ||
715 | #define TYPE_SCTP_OTHER_NO_PENDING_TSN { \ | 663 | #define TYPE_SCTP_OTHER_NO_PENDING_TSN { \ |
716 | /* SCTP_STATE_EMPTY */ \ | ||
717 | TYPE_SCTP_FUNC(sctp_sf_bug), \ | ||
718 | /* SCTP_STATE_CLOSED */ \ | 664 | /* SCTP_STATE_CLOSED */ \ |
719 | TYPE_SCTP_FUNC(sctp_sf_ignore_other), \ | 665 | TYPE_SCTP_FUNC(sctp_sf_ignore_other), \ |
720 | /* SCTP_STATE_COOKIE_WAIT */ \ | 666 | /* SCTP_STATE_COOKIE_WAIT */ \ |
@@ -722,7 +668,7 @@ static const sctp_sm_table_entry_t primitive_event_table[SCTP_NUM_PRIMITIVE_TYPE | |||
722 | /* SCTP_STATE_COOKIE_ECHOED */ \ | 668 | /* SCTP_STATE_COOKIE_ECHOED */ \ |
723 | TYPE_SCTP_FUNC(sctp_sf_ignore_other), \ | 669 | TYPE_SCTP_FUNC(sctp_sf_ignore_other), \ |
724 | /* SCTP_STATE_ESTABLISHED */ \ | 670 | /* SCTP_STATE_ESTABLISHED */ \ |
725 | TYPE_SCTP_FUNC(sctp_sf_ignore_other), \ | 671 | TYPE_SCTP_FUNC(sctp_sf_do_no_pending_tsn), \ |
726 | /* SCTP_STATE_SHUTDOWN_PENDING */ \ | 672 | /* SCTP_STATE_SHUTDOWN_PENDING */ \ |
727 | TYPE_SCTP_FUNC(sctp_sf_do_9_2_start_shutdown), \ | 673 | TYPE_SCTP_FUNC(sctp_sf_do_9_2_start_shutdown), \ |
728 | /* SCTP_STATE_SHUTDOWN_SENT */ \ | 674 | /* SCTP_STATE_SHUTDOWN_SENT */ \ |
@@ -734,8 +680,6 @@ static const sctp_sm_table_entry_t primitive_event_table[SCTP_NUM_PRIMITIVE_TYPE | |||
734 | } | 680 | } |
735 | 681 | ||
736 | #define TYPE_SCTP_OTHER_ICMP_PROTO_UNREACH { \ | 682 | #define TYPE_SCTP_OTHER_ICMP_PROTO_UNREACH { \ |
737 | /* SCTP_STATE_EMPTY */ \ | ||
738 | TYPE_SCTP_FUNC(sctp_sf_bug), \ | ||
739 | /* SCTP_STATE_CLOSED */ \ | 683 | /* SCTP_STATE_CLOSED */ \ |
740 | TYPE_SCTP_FUNC(sctp_sf_ignore_other), \ | 684 | TYPE_SCTP_FUNC(sctp_sf_ignore_other), \ |
741 | /* SCTP_STATE_COOKIE_WAIT */ \ | 685 | /* SCTP_STATE_COOKIE_WAIT */ \ |
@@ -760,8 +704,6 @@ static const sctp_sm_table_entry_t other_event_table[SCTP_NUM_OTHER_TYPES][SCTP_ | |||
760 | }; | 704 | }; |
761 | 705 | ||
762 | #define TYPE_SCTP_EVENT_TIMEOUT_NONE { \ | 706 | #define TYPE_SCTP_EVENT_TIMEOUT_NONE { \ |
763 | /* SCTP_STATE_EMPTY */ \ | ||
764 | TYPE_SCTP_FUNC(sctp_sf_bug), \ | ||
765 | /* SCTP_STATE_CLOSED */ \ | 707 | /* SCTP_STATE_CLOSED */ \ |
766 | TYPE_SCTP_FUNC(sctp_sf_bug), \ | 708 | TYPE_SCTP_FUNC(sctp_sf_bug), \ |
767 | /* SCTP_STATE_COOKIE_WAIT */ \ | 709 | /* SCTP_STATE_COOKIE_WAIT */ \ |
@@ -781,8 +723,6 @@ static const sctp_sm_table_entry_t other_event_table[SCTP_NUM_OTHER_TYPES][SCTP_ | |||
781 | } | 723 | } |
782 | 724 | ||
783 | #define TYPE_SCTP_EVENT_TIMEOUT_T1_COOKIE { \ | 725 | #define TYPE_SCTP_EVENT_TIMEOUT_T1_COOKIE { \ |
784 | /* SCTP_STATE_EMPTY */ \ | ||
785 | TYPE_SCTP_FUNC(sctp_sf_bug), \ | ||
786 | /* SCTP_STATE_CLOSED */ \ | 726 | /* SCTP_STATE_CLOSED */ \ |
787 | TYPE_SCTP_FUNC(sctp_sf_timer_ignore), \ | 727 | TYPE_SCTP_FUNC(sctp_sf_timer_ignore), \ |
788 | /* SCTP_STATE_COOKIE_WAIT */ \ | 728 | /* SCTP_STATE_COOKIE_WAIT */ \ |
@@ -802,8 +742,6 @@ static const sctp_sm_table_entry_t other_event_table[SCTP_NUM_OTHER_TYPES][SCTP_ | |||
802 | } | 742 | } |
803 | 743 | ||
804 | #define TYPE_SCTP_EVENT_TIMEOUT_T1_INIT { \ | 744 | #define TYPE_SCTP_EVENT_TIMEOUT_T1_INIT { \ |
805 | /* SCTP_STATE_EMPTY */ \ | ||
806 | TYPE_SCTP_FUNC(sctp_sf_bug), \ | ||
807 | /* SCTP_STATE_CLOSED */ \ | 745 | /* SCTP_STATE_CLOSED */ \ |
808 | TYPE_SCTP_FUNC(sctp_sf_timer_ignore), \ | 746 | TYPE_SCTP_FUNC(sctp_sf_timer_ignore), \ |
809 | /* SCTP_STATE_COOKIE_WAIT */ \ | 747 | /* SCTP_STATE_COOKIE_WAIT */ \ |
@@ -823,8 +761,6 @@ static const sctp_sm_table_entry_t other_event_table[SCTP_NUM_OTHER_TYPES][SCTP_ | |||
823 | } | 761 | } |
824 | 762 | ||
825 | #define TYPE_SCTP_EVENT_TIMEOUT_T2_SHUTDOWN { \ | 763 | #define TYPE_SCTP_EVENT_TIMEOUT_T2_SHUTDOWN { \ |
826 | /* SCTP_STATE_EMPTY */ \ | ||
827 | TYPE_SCTP_FUNC(sctp_sf_bug), \ | ||
828 | /* SCTP_STATE_CLOSED */ \ | 764 | /* SCTP_STATE_CLOSED */ \ |
829 | TYPE_SCTP_FUNC(sctp_sf_timer_ignore), \ | 765 | TYPE_SCTP_FUNC(sctp_sf_timer_ignore), \ |
830 | /* SCTP_STATE_COOKIE_WAIT */ \ | 766 | /* SCTP_STATE_COOKIE_WAIT */ \ |
@@ -844,8 +780,6 @@ static const sctp_sm_table_entry_t other_event_table[SCTP_NUM_OTHER_TYPES][SCTP_ | |||
844 | } | 780 | } |
845 | 781 | ||
846 | #define TYPE_SCTP_EVENT_TIMEOUT_T3_RTX { \ | 782 | #define TYPE_SCTP_EVENT_TIMEOUT_T3_RTX { \ |
847 | /* SCTP_STATE_EMPTY */ \ | ||
848 | TYPE_SCTP_FUNC(sctp_sf_bug), \ | ||
849 | /* SCTP_STATE_CLOSED */ \ | 783 | /* SCTP_STATE_CLOSED */ \ |
850 | TYPE_SCTP_FUNC(sctp_sf_timer_ignore), \ | 784 | TYPE_SCTP_FUNC(sctp_sf_timer_ignore), \ |
851 | /* SCTP_STATE_COOKIE_WAIT */ \ | 785 | /* SCTP_STATE_COOKIE_WAIT */ \ |
@@ -865,8 +799,6 @@ static const sctp_sm_table_entry_t other_event_table[SCTP_NUM_OTHER_TYPES][SCTP_ | |||
865 | } | 799 | } |
866 | 800 | ||
867 | #define TYPE_SCTP_EVENT_TIMEOUT_T4_RTO { \ | 801 | #define TYPE_SCTP_EVENT_TIMEOUT_T4_RTO { \ |
868 | /* SCTP_STATE_EMPTY */ \ | ||
869 | TYPE_SCTP_FUNC(sctp_sf_bug), \ | ||
870 | /* SCTP_STATE_CLOSED */ \ | 802 | /* SCTP_STATE_CLOSED */ \ |
871 | TYPE_SCTP_FUNC(sctp_sf_timer_ignore), \ | 803 | TYPE_SCTP_FUNC(sctp_sf_timer_ignore), \ |
872 | /* SCTP_STATE_COOKIE_WAIT */ \ | 804 | /* SCTP_STATE_COOKIE_WAIT */ \ |
@@ -886,8 +818,6 @@ static const sctp_sm_table_entry_t other_event_table[SCTP_NUM_OTHER_TYPES][SCTP_ | |||
886 | } | 818 | } |
887 | 819 | ||
888 | #define TYPE_SCTP_EVENT_TIMEOUT_T5_SHUTDOWN_GUARD { \ | 820 | #define TYPE_SCTP_EVENT_TIMEOUT_T5_SHUTDOWN_GUARD { \ |
889 | /* SCTP_STATE_EMPTY */ \ | ||
890 | TYPE_SCTP_FUNC(sctp_sf_bug), \ | ||
891 | /* SCTP_STATE_CLOSED */ \ | 821 | /* SCTP_STATE_CLOSED */ \ |
892 | TYPE_SCTP_FUNC(sctp_sf_timer_ignore), \ | 822 | TYPE_SCTP_FUNC(sctp_sf_timer_ignore), \ |
893 | /* SCTP_STATE_COOKIE_WAIT */ \ | 823 | /* SCTP_STATE_COOKIE_WAIT */ \ |
@@ -907,8 +837,6 @@ static const sctp_sm_table_entry_t other_event_table[SCTP_NUM_OTHER_TYPES][SCTP_ | |||
907 | } | 837 | } |
908 | 838 | ||
909 | #define TYPE_SCTP_EVENT_TIMEOUT_HEARTBEAT { \ | 839 | #define TYPE_SCTP_EVENT_TIMEOUT_HEARTBEAT { \ |
910 | /* SCTP_STATE_EMPTY */ \ | ||
911 | TYPE_SCTP_FUNC(sctp_sf_bug), \ | ||
912 | /* SCTP_STATE_CLOSED */ \ | 840 | /* SCTP_STATE_CLOSED */ \ |
913 | TYPE_SCTP_FUNC(sctp_sf_timer_ignore), \ | 841 | TYPE_SCTP_FUNC(sctp_sf_timer_ignore), \ |
914 | /* SCTP_STATE_COOKIE_WAIT */ \ | 842 | /* SCTP_STATE_COOKIE_WAIT */ \ |
@@ -928,8 +856,6 @@ static const sctp_sm_table_entry_t other_event_table[SCTP_NUM_OTHER_TYPES][SCTP_ | |||
928 | } | 856 | } |
929 | 857 | ||
930 | #define TYPE_SCTP_EVENT_TIMEOUT_SACK { \ | 858 | #define TYPE_SCTP_EVENT_TIMEOUT_SACK { \ |
931 | /* SCTP_STATE_EMPTY */ \ | ||
932 | TYPE_SCTP_FUNC(sctp_sf_bug), \ | ||
933 | /* SCTP_STATE_CLOSED */ \ | 859 | /* SCTP_STATE_CLOSED */ \ |
934 | TYPE_SCTP_FUNC(sctp_sf_timer_ignore), \ | 860 | TYPE_SCTP_FUNC(sctp_sf_timer_ignore), \ |
935 | /* SCTP_STATE_COOKIE_WAIT */ \ | 861 | /* SCTP_STATE_COOKIE_WAIT */ \ |
@@ -949,8 +875,6 @@ static const sctp_sm_table_entry_t other_event_table[SCTP_NUM_OTHER_TYPES][SCTP_ | |||
949 | } | 875 | } |
950 | 876 | ||
951 | #define TYPE_SCTP_EVENT_TIMEOUT_AUTOCLOSE { \ | 877 | #define TYPE_SCTP_EVENT_TIMEOUT_AUTOCLOSE { \ |
952 | /* SCTP_STATE_EMPTY */ \ | ||
953 | TYPE_SCTP_FUNC(sctp_sf_timer_ignore), \ | ||
954 | /* SCTP_STATE_CLOSED */ \ | 878 | /* SCTP_STATE_CLOSED */ \ |
955 | TYPE_SCTP_FUNC(sctp_sf_timer_ignore), \ | 879 | TYPE_SCTP_FUNC(sctp_sf_timer_ignore), \ |
956 | /* SCTP_STATE_COOKIE_WAIT */ \ | 880 | /* SCTP_STATE_COOKIE_WAIT */ \ |
diff --git a/net/sctp/socket.c b/net/sctp/socket.c index deb82e35a107..6766913a53e6 100644 --- a/net/sctp/socket.c +++ b/net/sctp/socket.c | |||
@@ -658,11 +658,15 @@ static int sctp_bindx_rem(struct sock *sk, struct sockaddr *addrs, int addrcnt) | |||
658 | goto err_bindx_rem; | 658 | goto err_bindx_rem; |
659 | } | 659 | } |
660 | 660 | ||
661 | if (sa_addr->v4.sin_port != htons(bp->port)) { | 661 | if (sa_addr->v4.sin_port && |
662 | sa_addr->v4.sin_port != htons(bp->port)) { | ||
662 | retval = -EINVAL; | 663 | retval = -EINVAL; |
663 | goto err_bindx_rem; | 664 | goto err_bindx_rem; |
664 | } | 665 | } |
665 | 666 | ||
667 | if (!sa_addr->v4.sin_port) | ||
668 | sa_addr->v4.sin_port = htons(bp->port); | ||
669 | |||
666 | /* FIXME - There is probably a need to check if sk->sk_saddr and | 670 | /* FIXME - There is probably a need to check if sk->sk_saddr and |
667 | * sk->sk_rcv_addr are currently set to one of the addresses to | 671 | * sk->sk_rcv_addr are currently set to one of the addresses to |
668 | * be removed. This is something which needs to be looked into | 672 | * be removed. This is something which needs to be looked into |
@@ -1492,7 +1496,7 @@ SCTP_STATIC int sctp_sendmsg(struct kiocb *iocb, struct sock *sk, | |||
1492 | struct sctp_chunk *chunk; | 1496 | struct sctp_chunk *chunk; |
1493 | union sctp_addr to; | 1497 | union sctp_addr to; |
1494 | struct sockaddr *msg_name = NULL; | 1498 | struct sockaddr *msg_name = NULL; |
1495 | struct sctp_sndrcvinfo default_sinfo = { 0 }; | 1499 | struct sctp_sndrcvinfo default_sinfo; |
1496 | struct sctp_sndrcvinfo *sinfo; | 1500 | struct sctp_sndrcvinfo *sinfo; |
1497 | struct sctp_initmsg *sinit; | 1501 | struct sctp_initmsg *sinit; |
1498 | sctp_assoc_t associd = 0; | 1502 | sctp_assoc_t associd = 0; |
@@ -1756,6 +1760,7 @@ SCTP_STATIC int sctp_sendmsg(struct kiocb *iocb, struct sock *sk, | |||
1756 | /* If the user didn't specify SNDRCVINFO, make up one with | 1760 | /* If the user didn't specify SNDRCVINFO, make up one with |
1757 | * some defaults. | 1761 | * some defaults. |
1758 | */ | 1762 | */ |
1763 | memset(&default_sinfo, 0, sizeof(default_sinfo)); | ||
1759 | default_sinfo.sinfo_stream = asoc->default_stream; | 1764 | default_sinfo.sinfo_stream = asoc->default_stream; |
1760 | default_sinfo.sinfo_flags = asoc->default_flags; | 1765 | default_sinfo.sinfo_flags = asoc->default_flags; |
1761 | default_sinfo.sinfo_ppid = asoc->default_ppid; | 1766 | default_sinfo.sinfo_ppid = asoc->default_ppid; |
@@ -1786,12 +1791,10 @@ SCTP_STATIC int sctp_sendmsg(struct kiocb *iocb, struct sock *sk, | |||
1786 | goto out_free; | 1791 | goto out_free; |
1787 | } | 1792 | } |
1788 | 1793 | ||
1789 | if (sinfo) { | 1794 | /* Check for invalid stream. */ |
1790 | /* Check for invalid stream. */ | 1795 | if (sinfo->sinfo_stream >= asoc->c.sinit_num_ostreams) { |
1791 | if (sinfo->sinfo_stream >= asoc->c.sinit_num_ostreams) { | 1796 | err = -EINVAL; |
1792 | err = -EINVAL; | 1797 | goto out_free; |
1793 | goto out_free; | ||
1794 | } | ||
1795 | } | 1798 | } |
1796 | 1799 | ||
1797 | timeo = sock_sndtimeo(sk, msg->msg_flags & MSG_DONTWAIT); | 1800 | timeo = sock_sndtimeo(sk, msg->msg_flags & MSG_DONTWAIT); |
@@ -2283,7 +2286,7 @@ static int sctp_apply_peer_addr_params(struct sctp_paddrparams *params, | |||
2283 | trans->param_flags = | 2286 | trans->param_flags = |
2284 | (trans->param_flags & ~SPP_PMTUD) | pmtud_change; | 2287 | (trans->param_flags & ~SPP_PMTUD) | pmtud_change; |
2285 | if (update) { | 2288 | if (update) { |
2286 | sctp_transport_pmtu(trans); | 2289 | sctp_transport_pmtu(trans, sctp_opt2sk(sp)); |
2287 | sctp_assoc_sync_pmtu(asoc); | 2290 | sctp_assoc_sync_pmtu(asoc); |
2288 | } | 2291 | } |
2289 | } else if (asoc) { | 2292 | } else if (asoc) { |
@@ -3215,14 +3218,9 @@ static int sctp_setsockopt_hmac_ident(struct sock *sk, | |||
3215 | if (optlen < sizeof(struct sctp_hmacalgo)) | 3218 | if (optlen < sizeof(struct sctp_hmacalgo)) |
3216 | return -EINVAL; | 3219 | return -EINVAL; |
3217 | 3220 | ||
3218 | hmacs = kmalloc(optlen, GFP_KERNEL); | 3221 | hmacs= memdup_user(optval, optlen); |
3219 | if (!hmacs) | 3222 | if (IS_ERR(hmacs)) |
3220 | return -ENOMEM; | 3223 | return PTR_ERR(hmacs); |
3221 | |||
3222 | if (copy_from_user(hmacs, optval, optlen)) { | ||
3223 | err = -EFAULT; | ||
3224 | goto out; | ||
3225 | } | ||
3226 | 3224 | ||
3227 | idents = hmacs->shmac_num_idents; | 3225 | idents = hmacs->shmac_num_idents; |
3228 | if (idents == 0 || idents > SCTP_AUTH_NUM_HMACS || | 3226 | if (idents == 0 || idents > SCTP_AUTH_NUM_HMACS || |
@@ -3257,14 +3255,9 @@ static int sctp_setsockopt_auth_key(struct sock *sk, | |||
3257 | if (optlen <= sizeof(struct sctp_authkey)) | 3255 | if (optlen <= sizeof(struct sctp_authkey)) |
3258 | return -EINVAL; | 3256 | return -EINVAL; |
3259 | 3257 | ||
3260 | authkey = kmalloc(optlen, GFP_KERNEL); | 3258 | authkey= memdup_user(optval, optlen); |
3261 | if (!authkey) | 3259 | if (IS_ERR(authkey)) |
3262 | return -ENOMEM; | 3260 | return PTR_ERR(authkey); |
3263 | |||
3264 | if (copy_from_user(authkey, optval, optlen)) { | ||
3265 | ret = -EFAULT; | ||
3266 | goto out; | ||
3267 | } | ||
3268 | 3261 | ||
3269 | if (authkey->sca_keylength > optlen - sizeof(struct sctp_authkey)) { | 3262 | if (authkey->sca_keylength > optlen - sizeof(struct sctp_authkey)) { |
3270 | ret = -EINVAL; | 3263 | ret = -EINVAL; |
@@ -5283,6 +5276,55 @@ static int sctp_getsockopt_assoc_number(struct sock *sk, int len, | |||
5283 | return 0; | 5276 | return 0; |
5284 | } | 5277 | } |
5285 | 5278 | ||
5279 | /* | ||
5280 | * 8.2.6. Get the Current Identifiers of Associations | ||
5281 | * (SCTP_GET_ASSOC_ID_LIST) | ||
5282 | * | ||
5283 | * This option gets the current list of SCTP association identifiers of | ||
5284 | * the SCTP associations handled by a one-to-many style socket. | ||
5285 | */ | ||
5286 | static int sctp_getsockopt_assoc_ids(struct sock *sk, int len, | ||
5287 | char __user *optval, int __user *optlen) | ||
5288 | { | ||
5289 | struct sctp_sock *sp = sctp_sk(sk); | ||
5290 | struct sctp_association *asoc; | ||
5291 | struct sctp_assoc_ids *ids; | ||
5292 | u32 num = 0; | ||
5293 | |||
5294 | if (sctp_style(sk, TCP)) | ||
5295 | return -EOPNOTSUPP; | ||
5296 | |||
5297 | if (len < sizeof(struct sctp_assoc_ids)) | ||
5298 | return -EINVAL; | ||
5299 | |||
5300 | list_for_each_entry(asoc, &(sp->ep->asocs), asocs) { | ||
5301 | num++; | ||
5302 | } | ||
5303 | |||
5304 | if (len < sizeof(struct sctp_assoc_ids) + sizeof(sctp_assoc_t) * num) | ||
5305 | return -EINVAL; | ||
5306 | |||
5307 | len = sizeof(struct sctp_assoc_ids) + sizeof(sctp_assoc_t) * num; | ||
5308 | |||
5309 | ids = kmalloc(len, GFP_KERNEL); | ||
5310 | if (unlikely(!ids)) | ||
5311 | return -ENOMEM; | ||
5312 | |||
5313 | ids->gaids_number_of_ids = num; | ||
5314 | num = 0; | ||
5315 | list_for_each_entry(asoc, &(sp->ep->asocs), asocs) { | ||
5316 | ids->gaids_assoc_id[num++] = asoc->assoc_id; | ||
5317 | } | ||
5318 | |||
5319 | if (put_user(len, optlen) || copy_to_user(optval, ids, len)) { | ||
5320 | kfree(ids); | ||
5321 | return -EFAULT; | ||
5322 | } | ||
5323 | |||
5324 | kfree(ids); | ||
5325 | return 0; | ||
5326 | } | ||
5327 | |||
5286 | SCTP_STATIC int sctp_getsockopt(struct sock *sk, int level, int optname, | 5328 | SCTP_STATIC int sctp_getsockopt(struct sock *sk, int level, int optname, |
5287 | char __user *optval, int __user *optlen) | 5329 | char __user *optval, int __user *optlen) |
5288 | { | 5330 | { |
@@ -5415,6 +5457,9 @@ SCTP_STATIC int sctp_getsockopt(struct sock *sk, int level, int optname, | |||
5415 | case SCTP_GET_ASSOC_NUMBER: | 5457 | case SCTP_GET_ASSOC_NUMBER: |
5416 | retval = sctp_getsockopt_assoc_number(sk, len, optval, optlen); | 5458 | retval = sctp_getsockopt_assoc_number(sk, len, optval, optlen); |
5417 | break; | 5459 | break; |
5460 | case SCTP_GET_ASSOC_ID_LIST: | ||
5461 | retval = sctp_getsockopt_assoc_ids(sk, len, optval, optlen); | ||
5462 | break; | ||
5418 | default: | 5463 | default: |
5419 | retval = -ENOPROTOOPT; | 5464 | retval = -ENOPROTOOPT; |
5420 | break; | 5465 | break; |
diff --git a/net/sctp/transport.c b/net/sctp/transport.c index d3ae493d234a..394c57ca2f54 100644 --- a/net/sctp/transport.c +++ b/net/sctp/transport.c | |||
@@ -211,15 +211,17 @@ void sctp_transport_set_owner(struct sctp_transport *transport, | |||
211 | } | 211 | } |
212 | 212 | ||
213 | /* Initialize the pmtu of a transport. */ | 213 | /* Initialize the pmtu of a transport. */ |
214 | void sctp_transport_pmtu(struct sctp_transport *transport) | 214 | void sctp_transport_pmtu(struct sctp_transport *transport, struct sock *sk) |
215 | { | 215 | { |
216 | struct dst_entry *dst; | 216 | /* If we don't have a fresh route, look one up */ |
217 | 217 | if (!transport->dst || transport->dst->obsolete > 1) { | |
218 | dst = transport->af_specific->get_dst(NULL, &transport->ipaddr, NULL); | 218 | dst_release(transport->dst); |
219 | transport->af_specific->get_dst(transport, &transport->saddr, | ||
220 | &transport->fl, sk); | ||
221 | } | ||
219 | 222 | ||
220 | if (dst) { | 223 | if (transport->dst) { |
221 | transport->pathmtu = dst_mtu(dst); | 224 | transport->pathmtu = dst_mtu(transport->dst); |
222 | dst_release(dst); | ||
223 | } else | 225 | } else |
224 | transport->pathmtu = SCTP_DEFAULT_MAXSEGMENT; | 226 | transport->pathmtu = SCTP_DEFAULT_MAXSEGMENT; |
225 | } | 227 | } |
@@ -270,22 +272,19 @@ void sctp_transport_route(struct sctp_transport *transport, | |||
270 | { | 272 | { |
271 | struct sctp_association *asoc = transport->asoc; | 273 | struct sctp_association *asoc = transport->asoc; |
272 | struct sctp_af *af = transport->af_specific; | 274 | struct sctp_af *af = transport->af_specific; |
273 | union sctp_addr *daddr = &transport->ipaddr; | ||
274 | struct dst_entry *dst; | ||
275 | 275 | ||
276 | dst = af->get_dst(asoc, daddr, saddr); | 276 | af->get_dst(transport, saddr, &transport->fl, sctp_opt2sk(opt)); |
277 | 277 | ||
278 | if (saddr) | 278 | if (saddr) |
279 | memcpy(&transport->saddr, saddr, sizeof(union sctp_addr)); | 279 | memcpy(&transport->saddr, saddr, sizeof(union sctp_addr)); |
280 | else | 280 | else |
281 | af->get_saddr(opt, asoc, dst, daddr, &transport->saddr); | 281 | af->get_saddr(opt, transport, &transport->fl); |
282 | 282 | ||
283 | transport->dst = dst; | ||
284 | if ((transport->param_flags & SPP_PMTUD_DISABLE) && transport->pathmtu) { | 283 | if ((transport->param_flags & SPP_PMTUD_DISABLE) && transport->pathmtu) { |
285 | return; | 284 | return; |
286 | } | 285 | } |
287 | if (dst) { | 286 | if (transport->dst) { |
288 | transport->pathmtu = dst_mtu(dst); | 287 | transport->pathmtu = dst_mtu(transport->dst); |
289 | 288 | ||
290 | /* Initialize sk->sk_rcv_saddr, if the transport is the | 289 | /* Initialize sk->sk_rcv_saddr, if the transport is the |
291 | * association's active path for getsockname(). | 290 | * association's active path for getsockname(). |
diff --git a/net/sctp/ulpevent.c b/net/sctp/ulpevent.c index 61b1f5ada96a..e70e5fc87890 100644 --- a/net/sctp/ulpevent.c +++ b/net/sctp/ulpevent.c | |||
@@ -843,7 +843,7 @@ struct sctp_ulpevent *sctp_ulpevent_make_authkey( | |||
843 | ak = (struct sctp_authkey_event *) | 843 | ak = (struct sctp_authkey_event *) |
844 | skb_put(skb, sizeof(struct sctp_authkey_event)); | 844 | skb_put(skb, sizeof(struct sctp_authkey_event)); |
845 | 845 | ||
846 | ak->auth_type = SCTP_AUTHENTICATION_INDICATION; | 846 | ak->auth_type = SCTP_AUTHENTICATION_EVENT; |
847 | ak->auth_flags = 0; | 847 | ak->auth_flags = 0; |
848 | ak->auth_length = sizeof(struct sctp_authkey_event); | 848 | ak->auth_length = sizeof(struct sctp_authkey_event); |
849 | 849 | ||
@@ -862,6 +862,34 @@ fail: | |||
862 | return NULL; | 862 | return NULL; |
863 | } | 863 | } |
864 | 864 | ||
865 | /* | ||
866 | * Socket Extensions for SCTP | ||
867 | * 6.3.10. SCTP_SENDER_DRY_EVENT | ||
868 | */ | ||
869 | struct sctp_ulpevent *sctp_ulpevent_make_sender_dry_event( | ||
870 | const struct sctp_association *asoc, gfp_t gfp) | ||
871 | { | ||
872 | struct sctp_ulpevent *event; | ||
873 | struct sctp_sender_dry_event *sdry; | ||
874 | struct sk_buff *skb; | ||
875 | |||
876 | event = sctp_ulpevent_new(sizeof(struct sctp_sender_dry_event), | ||
877 | MSG_NOTIFICATION, gfp); | ||
878 | if (!event) | ||
879 | return NULL; | ||
880 | |||
881 | skb = sctp_event2skb(event); | ||
882 | sdry = (struct sctp_sender_dry_event *) | ||
883 | skb_put(skb, sizeof(struct sctp_sender_dry_event)); | ||
884 | |||
885 | sdry->sender_dry_type = SCTP_SENDER_DRY_EVENT; | ||
886 | sdry->sender_dry_flags = 0; | ||
887 | sdry->sender_dry_length = sizeof(struct sctp_sender_dry_event); | ||
888 | sctp_ulpevent_set_owner(event, asoc); | ||
889 | sdry->sender_dry_assoc_id = sctp_assoc2id(asoc); | ||
890 | |||
891 | return event; | ||
892 | } | ||
865 | 893 | ||
866 | /* Return the notification type, assuming this is a notification | 894 | /* Return the notification type, assuming this is a notification |
867 | * event. | 895 | * event. |