diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2008-07-20 20:43:29 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2008-07-20 20:43:29 -0400 |
commit | db6d8c7a4027b48d797b369a53f8470aaeed7063 (patch) | |
tree | e140c104a89abc2154e1f41a7db8ebecbb6fa0b4 /net/sctp | |
parent | 3a533374283aea50eab3976d8a6d30532175f009 (diff) | |
parent | fb65a7c091529bfffb1262515252c0d0f6241c5c (diff) |
Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-2.6
* git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-2.6: (1232 commits)
iucv: Fix bad merging.
net_sched: Add size table for qdiscs
net_sched: Add accessor function for packet length for qdiscs
net_sched: Add qdisc_enqueue wrapper
highmem: Export totalhigh_pages.
ipv6 mcast: Omit redundant address family checks in ip6_mc_source().
net: Use standard structures for generic socket address structures.
ipv6 netns: Make several "global" sysctl variables namespace aware.
netns: Use net_eq() to compare net-namespaces for optimization.
ipv6: remove unused macros from net/ipv6.h
ipv6: remove unused parameter from ip6_ra_control
tcp: fix kernel panic with listening_get_next
tcp: Remove redundant checks when setting eff_sacks
tcp: options clean up
tcp: Fix MD5 signatures for non-linear skbs
sctp: Update sctp global memory limit allocations.
sctp: remove unnecessary byteshifting, calculate directly in big-endian
sctp: Allow only 1 listening socket with SO_REUSEADDR
sctp: Do not leak memory on multiple listen() calls
sctp: Support ipv6only AF_INET6 sockets.
...
Diffstat (limited to 'net/sctp')
-rw-r--r-- | net/sctp/Kconfig | 4 | ||||
-rw-r--r-- | net/sctp/Makefile | 4 | ||||
-rw-r--r-- | net/sctp/associola.c | 4 | ||||
-rw-r--r-- | net/sctp/bind_addr.c | 37 | ||||
-rw-r--r-- | net/sctp/input.c | 38 | ||||
-rw-r--r-- | net/sctp/ipv6.c | 20 | ||||
-rw-r--r-- | net/sctp/output.c | 14 | ||||
-rw-r--r-- | net/sctp/outqueue.c | 34 | ||||
-rw-r--r-- | net/sctp/proc.c | 141 | ||||
-rw-r--r-- | net/sctp/protocol.c | 35 | ||||
-rw-r--r-- | net/sctp/sm_make_chunk.c | 7 | ||||
-rw-r--r-- | net/sctp/sm_sideeffect.c | 44 | ||||
-rw-r--r-- | net/sctp/sm_statefuns.c | 16 | ||||
-rw-r--r-- | net/sctp/socket.c | 383 | ||||
-rw-r--r-- | net/sctp/transport.c | 3 |
15 files changed, 608 insertions, 176 deletions
diff --git a/net/sctp/Kconfig b/net/sctp/Kconfig index 0b79f869c4ea..58b3e882a187 100644 --- a/net/sctp/Kconfig +++ b/net/sctp/Kconfig | |||
@@ -47,11 +47,11 @@ config SCTP_DBG_MSG | |||
47 | 47 | ||
48 | config SCTP_DBG_OBJCNT | 48 | config SCTP_DBG_OBJCNT |
49 | bool "SCTP: Debug object counts" | 49 | bool "SCTP: Debug object counts" |
50 | depends on PROC_FS | ||
50 | help | 51 | help |
51 | If you say Y, this will enable debugging support for counting the | 52 | If you say Y, this will enable debugging support for counting the |
52 | type of objects that are currently allocated. This is useful for | 53 | type of objects that are currently allocated. This is useful for |
53 | identifying memory leaks. If the /proc filesystem is enabled this | 54 | identifying memory leaks. This debug information can be viewed by |
54 | debug information can be viewed by | ||
55 | 'cat /proc/net/sctp/sctp_dbg_objcnt' | 55 | 'cat /proc/net/sctp/sctp_dbg_objcnt' |
56 | 56 | ||
57 | If unsure, say N | 57 | If unsure, say N |
diff --git a/net/sctp/Makefile b/net/sctp/Makefile index f5356b9d5ee3..6b794734380a 100644 --- a/net/sctp/Makefile +++ b/net/sctp/Makefile | |||
@@ -9,10 +9,10 @@ sctp-y := sm_statetable.o sm_statefuns.o sm_sideeffect.o \ | |||
9 | transport.o chunk.o sm_make_chunk.o ulpevent.o \ | 9 | transport.o chunk.o sm_make_chunk.o ulpevent.o \ |
10 | inqueue.o outqueue.o ulpqueue.o command.o \ | 10 | inqueue.o outqueue.o ulpqueue.o command.o \ |
11 | tsnmap.o bind_addr.o socket.o primitive.o \ | 11 | tsnmap.o bind_addr.o socket.o primitive.o \ |
12 | output.o input.o debug.o ssnmap.o proc.o \ | 12 | output.o input.o debug.o ssnmap.o auth.o |
13 | auth.o | ||
14 | 13 | ||
15 | sctp-$(CONFIG_SCTP_DBG_OBJCNT) += objcnt.o | 14 | sctp-$(CONFIG_SCTP_DBG_OBJCNT) += objcnt.o |
15 | sctp-$(CONFIG_PROC_FS) += proc.o | ||
16 | sctp-$(CONFIG_SYSCTL) += sysctl.o | 16 | sctp-$(CONFIG_SYSCTL) += sysctl.o |
17 | 17 | ||
18 | sctp-$(subst m,y,$(CONFIG_IPV6)) += ipv6.o | 18 | sctp-$(subst m,y,$(CONFIG_IPV6)) += ipv6.o |
diff --git a/net/sctp/associola.c b/net/sctp/associola.c index 024c3ebd9661..ec2a0a33fd78 100644 --- a/net/sctp/associola.c +++ b/net/sctp/associola.c | |||
@@ -136,6 +136,7 @@ static struct sctp_association *sctp_association_init(struct sctp_association *a | |||
136 | 136 | ||
137 | /* Set association default SACK delay */ | 137 | /* Set association default SACK delay */ |
138 | asoc->sackdelay = msecs_to_jiffies(sp->sackdelay); | 138 | asoc->sackdelay = msecs_to_jiffies(sp->sackdelay); |
139 | asoc->sackfreq = sp->sackfreq; | ||
139 | 140 | ||
140 | /* Set the association default flags controlling | 141 | /* Set the association default flags controlling |
141 | * Heartbeat, SACK delay, and Path MTU Discovery. | 142 | * Heartbeat, SACK delay, and Path MTU Discovery. |
@@ -261,6 +262,7 @@ static struct sctp_association *sctp_association_init(struct sctp_association *a | |||
261 | * already received one packet.] | 262 | * already received one packet.] |
262 | */ | 263 | */ |
263 | asoc->peer.sack_needed = 1; | 264 | asoc->peer.sack_needed = 1; |
265 | asoc->peer.sack_cnt = 0; | ||
264 | 266 | ||
265 | /* Assume that the peer will tell us if he recognizes ASCONF | 267 | /* Assume that the peer will tell us if he recognizes ASCONF |
266 | * as part of INIT exchange. | 268 | * as part of INIT exchange. |
@@ -624,6 +626,7 @@ struct sctp_transport *sctp_assoc_add_peer(struct sctp_association *asoc, | |||
624 | * association configured value. | 626 | * association configured value. |
625 | */ | 627 | */ |
626 | peer->sackdelay = asoc->sackdelay; | 628 | peer->sackdelay = asoc->sackdelay; |
629 | peer->sackfreq = asoc->sackfreq; | ||
627 | 630 | ||
628 | /* Enable/disable heartbeat, SACK delay, and path MTU discovery | 631 | /* Enable/disable heartbeat, SACK delay, and path MTU discovery |
629 | * based on association setting. | 632 | * based on association setting. |
@@ -650,6 +653,7 @@ struct sctp_transport *sctp_assoc_add_peer(struct sctp_association *asoc, | |||
650 | 653 | ||
651 | SCTP_DEBUG_PRINTK("sctp_assoc_add_peer:association %p PMTU set to " | 654 | SCTP_DEBUG_PRINTK("sctp_assoc_add_peer:association %p PMTU set to " |
652 | "%d\n", asoc, asoc->pathmtu); | 655 | "%d\n", asoc, asoc->pathmtu); |
656 | peer->pmtu_pending = 0; | ||
653 | 657 | ||
654 | asoc->frag_point = sctp_frag_point(sp, asoc->pathmtu); | 658 | asoc->frag_point = sctp_frag_point(sp, asoc->pathmtu); |
655 | 659 | ||
diff --git a/net/sctp/bind_addr.c b/net/sctp/bind_addr.c index 80e6df06967a..f62bc2468935 100644 --- a/net/sctp/bind_addr.c +++ b/net/sctp/bind_addr.c | |||
@@ -348,6 +348,43 @@ int sctp_bind_addr_match(struct sctp_bind_addr *bp, | |||
348 | return match; | 348 | return match; |
349 | } | 349 | } |
350 | 350 | ||
351 | /* Does the address 'addr' conflict with any addresses in | ||
352 | * the bp. | ||
353 | */ | ||
354 | int sctp_bind_addr_conflict(struct sctp_bind_addr *bp, | ||
355 | const union sctp_addr *addr, | ||
356 | struct sctp_sock *bp_sp, | ||
357 | struct sctp_sock *addr_sp) | ||
358 | { | ||
359 | struct sctp_sockaddr_entry *laddr; | ||
360 | int conflict = 0; | ||
361 | struct sctp_sock *sp; | ||
362 | |||
363 | /* Pick the IPv6 socket as the basis of comparison | ||
364 | * since it's usually a superset of the IPv4. | ||
365 | * If there is no IPv6 socket, then default to bind_addr. | ||
366 | */ | ||
367 | if (sctp_opt2sk(bp_sp)->sk_family == AF_INET6) | ||
368 | sp = bp_sp; | ||
369 | else if (sctp_opt2sk(addr_sp)->sk_family == AF_INET6) | ||
370 | sp = addr_sp; | ||
371 | else | ||
372 | sp = bp_sp; | ||
373 | |||
374 | rcu_read_lock(); | ||
375 | list_for_each_entry_rcu(laddr, &bp->address_list, list) { | ||
376 | if (!laddr->valid) | ||
377 | continue; | ||
378 | |||
379 | conflict = sp->pf->cmp_addr(&laddr->a, addr, sp); | ||
380 | if (conflict) | ||
381 | break; | ||
382 | } | ||
383 | rcu_read_unlock(); | ||
384 | |||
385 | return conflict; | ||
386 | } | ||
387 | |||
351 | /* Get the state of the entry in the bind_addr_list */ | 388 | /* Get the state of the entry in the bind_addr_list */ |
352 | int sctp_bind_addr_state(const struct sctp_bind_addr *bp, | 389 | int sctp_bind_addr_state(const struct sctp_bind_addr *bp, |
353 | const union sctp_addr *addr) | 390 | const union sctp_addr *addr) |
diff --git a/net/sctp/input.c b/net/sctp/input.c index ca6b022b1df2..a49fa80b57b9 100644 --- a/net/sctp/input.c +++ b/net/sctp/input.c | |||
@@ -61,6 +61,7 @@ | |||
61 | #include <net/sctp/sctp.h> | 61 | #include <net/sctp/sctp.h> |
62 | #include <net/sctp/sm.h> | 62 | #include <net/sctp/sm.h> |
63 | #include <net/sctp/checksum.h> | 63 | #include <net/sctp/checksum.h> |
64 | #include <net/net_namespace.h> | ||
64 | 65 | ||
65 | /* Forward declarations for internal helpers. */ | 66 | /* Forward declarations for internal helpers. */ |
66 | static int sctp_rcv_ootb(struct sk_buff *); | 67 | static int sctp_rcv_ootb(struct sk_buff *); |
@@ -82,8 +83,8 @@ static inline int sctp_rcv_checksum(struct sk_buff *skb) | |||
82 | { | 83 | { |
83 | struct sk_buff *list = skb_shinfo(skb)->frag_list; | 84 | struct sk_buff *list = skb_shinfo(skb)->frag_list; |
84 | struct sctphdr *sh = sctp_hdr(skb); | 85 | struct sctphdr *sh = sctp_hdr(skb); |
85 | __u32 cmp = ntohl(sh->checksum); | 86 | __be32 cmp = sh->checksum; |
86 | __u32 val = sctp_start_cksum((__u8 *)sh, skb_headlen(skb)); | 87 | __be32 val = sctp_start_cksum((__u8 *)sh, skb_headlen(skb)); |
87 | 88 | ||
88 | for (; list; list = list->next) | 89 | for (; list; list = list->next) |
89 | val = sctp_update_cksum((__u8 *)list->data, skb_headlen(list), | 90 | val = sctp_update_cksum((__u8 *)list->data, skb_headlen(list), |
@@ -430,6 +431,9 @@ struct sock *sctp_err_lookup(int family, struct sk_buff *skb, | |||
430 | struct sock *sk = NULL; | 431 | struct sock *sk = NULL; |
431 | struct sctp_association *asoc; | 432 | struct sctp_association *asoc; |
432 | struct sctp_transport *transport = NULL; | 433 | struct sctp_transport *transport = NULL; |
434 | struct sctp_init_chunk *chunkhdr; | ||
435 | __u32 vtag = ntohl(sctphdr->vtag); | ||
436 | int len = skb->len - ((void *)sctphdr - (void *)skb->data); | ||
433 | 437 | ||
434 | *app = NULL; *tpp = NULL; | 438 | *app = NULL; *tpp = NULL; |
435 | 439 | ||
@@ -451,8 +455,28 @@ struct sock *sctp_err_lookup(int family, struct sk_buff *skb, | |||
451 | 455 | ||
452 | sk = asoc->base.sk; | 456 | sk = asoc->base.sk; |
453 | 457 | ||
454 | if (ntohl(sctphdr->vtag) != asoc->c.peer_vtag) { | 458 | /* RFC 4960, Appendix C. ICMP Handling |
455 | ICMP_INC_STATS_BH(ICMP_MIB_INERRORS); | 459 | * |
460 | * ICMP6) An implementation MUST validate that the Verification Tag | ||
461 | * contained in the ICMP message matches the Verification Tag of | ||
462 | * the peer. If the Verification Tag is not 0 and does NOT | ||
463 | * match, discard the ICMP message. If it is 0 and the ICMP | ||
464 | * message contains enough bytes to verify that the chunk type is | ||
465 | * an INIT chunk and that the Initiate Tag matches the tag of the | ||
466 | * peer, continue with ICMP7. If the ICMP message is too short | ||
467 | * or the chunk type or the Initiate Tag does not match, silently | ||
468 | * discard the packet. | ||
469 | */ | ||
470 | if (vtag == 0) { | ||
471 | chunkhdr = (struct sctp_init_chunk *)((void *)sctphdr | ||
472 | + sizeof(struct sctphdr)); | ||
473 | if (len < sizeof(struct sctphdr) + sizeof(sctp_chunkhdr_t) | ||
474 | + sizeof(__be32) || | ||
475 | chunkhdr->chunk_hdr.type != SCTP_CID_INIT || | ||
476 | ntohl(chunkhdr->init_hdr.init_tag) != asoc->c.my_vtag) { | ||
477 | goto out; | ||
478 | } | ||
479 | } else if (vtag != asoc->c.peer_vtag) { | ||
456 | goto out; | 480 | goto out; |
457 | } | 481 | } |
458 | 482 | ||
@@ -462,7 +486,7 @@ struct sock *sctp_err_lookup(int family, struct sk_buff *skb, | |||
462 | * servers this needs to be solved differently. | 486 | * servers this needs to be solved differently. |
463 | */ | 487 | */ |
464 | if (sock_owned_by_user(sk)) | 488 | if (sock_owned_by_user(sk)) |
465 | NET_INC_STATS_BH(LINUX_MIB_LOCKDROPPEDICMPS); | 489 | NET_INC_STATS_BH(&init_net, LINUX_MIB_LOCKDROPPEDICMPS); |
466 | 490 | ||
467 | *app = asoc; | 491 | *app = asoc; |
468 | *tpp = transport; | 492 | *tpp = transport; |
@@ -511,7 +535,7 @@ void sctp_v4_err(struct sk_buff *skb, __u32 info) | |||
511 | int err; | 535 | int err; |
512 | 536 | ||
513 | if (skb->len < ihlen + 8) { | 537 | if (skb->len < ihlen + 8) { |
514 | ICMP_INC_STATS_BH(ICMP_MIB_INERRORS); | 538 | ICMP_INC_STATS_BH(&init_net, ICMP_MIB_INERRORS); |
515 | return; | 539 | return; |
516 | } | 540 | } |
517 | 541 | ||
@@ -525,7 +549,7 @@ void sctp_v4_err(struct sk_buff *skb, __u32 info) | |||
525 | skb->network_header = saveip; | 549 | skb->network_header = saveip; |
526 | skb->transport_header = savesctp; | 550 | skb->transport_header = savesctp; |
527 | if (!sk) { | 551 | if (!sk) { |
528 | ICMP_INC_STATS_BH(ICMP_MIB_INERRORS); | 552 | ICMP_INC_STATS_BH(&init_net, ICMP_MIB_INERRORS); |
529 | return; | 553 | return; |
530 | } | 554 | } |
531 | /* Warning: The sock lock is held. Remember to call | 555 | /* Warning: The sock lock is held. Remember to call |
diff --git a/net/sctp/ipv6.c b/net/sctp/ipv6.c index a2f4d4d51593..a238d6834b33 100644 --- a/net/sctp/ipv6.c +++ b/net/sctp/ipv6.c | |||
@@ -818,7 +818,7 @@ static int sctp_inet6_af_supported(sa_family_t family, struct sctp_sock *sp) | |||
818 | return 1; | 818 | return 1; |
819 | /* v4-mapped-v6 addresses */ | 819 | /* v4-mapped-v6 addresses */ |
820 | case AF_INET: | 820 | case AF_INET: |
821 | if (!__ipv6_only_sock(sctp_opt2sk(sp)) && sp->v4mapped) | 821 | if (!__ipv6_only_sock(sctp_opt2sk(sp))) |
822 | return 1; | 822 | return 1; |
823 | default: | 823 | default: |
824 | return 0; | 824 | return 0; |
@@ -840,6 +840,11 @@ static int sctp_inet6_cmp_addr(const union sctp_addr *addr1, | |||
840 | 840 | ||
841 | if (!af1 || !af2) | 841 | if (!af1 || !af2) |
842 | return 0; | 842 | return 0; |
843 | |||
844 | /* If the socket is IPv6 only, v4 addrs will not match */ | ||
845 | if (__ipv6_only_sock(sctp_opt2sk(opt)) && af1 != af2) | ||
846 | return 0; | ||
847 | |||
843 | /* Today, wildcard AF_INET/AF_INET6. */ | 848 | /* Today, wildcard AF_INET/AF_INET6. */ |
844 | if (sctp_is_any(addr1) || sctp_is_any(addr2)) | 849 | if (sctp_is_any(addr1) || sctp_is_any(addr2)) |
845 | return 1; | 850 | return 1; |
@@ -876,7 +881,11 @@ static int sctp_inet6_bind_verify(struct sctp_sock *opt, union sctp_addr *addr) | |||
876 | return 0; | 881 | return 0; |
877 | } | 882 | } |
878 | dev_put(dev); | 883 | dev_put(dev); |
884 | } else if (type == IPV6_ADDR_MAPPED) { | ||
885 | if (!opt->v4mapped) | ||
886 | return 0; | ||
879 | } | 887 | } |
888 | |||
880 | af = opt->pf->af; | 889 | af = opt->pf->af; |
881 | } | 890 | } |
882 | return af->available(addr, opt); | 891 | return af->available(addr, opt); |
@@ -919,9 +928,12 @@ static int sctp_inet6_send_verify(struct sctp_sock *opt, union sctp_addr *addr) | |||
919 | static int sctp_inet6_supported_addrs(const struct sctp_sock *opt, | 928 | static int sctp_inet6_supported_addrs(const struct sctp_sock *opt, |
920 | __be16 *types) | 929 | __be16 *types) |
921 | { | 930 | { |
922 | types[0] = SCTP_PARAM_IPV4_ADDRESS; | 931 | types[0] = SCTP_PARAM_IPV6_ADDRESS; |
923 | types[1] = SCTP_PARAM_IPV6_ADDRESS; | 932 | if (!opt || !ipv6_only_sock(sctp_opt2sk(opt))) { |
924 | return 2; | 933 | types[1] = SCTP_PARAM_IPV4_ADDRESS; |
934 | return 2; | ||
935 | } | ||
936 | return 1; | ||
925 | } | 937 | } |
926 | 938 | ||
927 | static const struct proto_ops inet6_seqpacket_ops = { | 939 | static const struct proto_ops inet6_seqpacket_ops = { |
diff --git a/net/sctp/output.c b/net/sctp/output.c index 6d45bae93b46..45684646b1db 100644 --- a/net/sctp/output.c +++ b/net/sctp/output.c | |||
@@ -50,6 +50,7 @@ | |||
50 | #include <linux/init.h> | 50 | #include <linux/init.h> |
51 | #include <net/inet_ecn.h> | 51 | #include <net/inet_ecn.h> |
52 | #include <net/icmp.h> | 52 | #include <net/icmp.h> |
53 | #include <net/net_namespace.h> | ||
53 | 54 | ||
54 | #ifndef TEST_FRAME | 55 | #ifndef TEST_FRAME |
55 | #include <net/tcp.h> | 56 | #include <net/tcp.h> |
@@ -157,7 +158,8 @@ void sctp_packet_free(struct sctp_packet *packet) | |||
157 | * packet can be sent only after receiving the COOKIE_ACK. | 158 | * packet can be sent only after receiving the COOKIE_ACK. |
158 | */ | 159 | */ |
159 | sctp_xmit_t sctp_packet_transmit_chunk(struct sctp_packet *packet, | 160 | sctp_xmit_t sctp_packet_transmit_chunk(struct sctp_packet *packet, |
160 | struct sctp_chunk *chunk) | 161 | struct sctp_chunk *chunk, |
162 | int one_packet) | ||
161 | { | 163 | { |
162 | sctp_xmit_t retval; | 164 | sctp_xmit_t retval; |
163 | int error = 0; | 165 | int error = 0; |
@@ -175,7 +177,9 @@ sctp_xmit_t sctp_packet_transmit_chunk(struct sctp_packet *packet, | |||
175 | /* If we have an empty packet, then we can NOT ever | 177 | /* If we have an empty packet, then we can NOT ever |
176 | * return PMTU_FULL. | 178 | * return PMTU_FULL. |
177 | */ | 179 | */ |
178 | retval = sctp_packet_append_chunk(packet, chunk); | 180 | if (!one_packet) |
181 | retval = sctp_packet_append_chunk(packet, | ||
182 | chunk); | ||
179 | } | 183 | } |
180 | break; | 184 | break; |
181 | 185 | ||
@@ -361,7 +365,7 @@ int sctp_packet_transmit(struct sctp_packet *packet) | |||
361 | struct sctp_transport *tp = packet->transport; | 365 | struct sctp_transport *tp = packet->transport; |
362 | struct sctp_association *asoc = tp->asoc; | 366 | struct sctp_association *asoc = tp->asoc; |
363 | struct sctphdr *sh; | 367 | struct sctphdr *sh; |
364 | __u32 crc32 = 0; | 368 | __be32 crc32 = __constant_cpu_to_be32(0); |
365 | struct sk_buff *nskb; | 369 | struct sk_buff *nskb; |
366 | struct sctp_chunk *chunk, *tmp; | 370 | struct sctp_chunk *chunk, *tmp; |
367 | struct sock *sk; | 371 | struct sock *sk; |
@@ -534,7 +538,7 @@ int sctp_packet_transmit(struct sctp_packet *packet) | |||
534 | /* 3) Put the resultant value into the checksum field in the | 538 | /* 3) Put the resultant value into the checksum field in the |
535 | * common header, and leave the rest of the bits unchanged. | 539 | * common header, and leave the rest of the bits unchanged. |
536 | */ | 540 | */ |
537 | sh->checksum = htonl(crc32); | 541 | sh->checksum = crc32; |
538 | 542 | ||
539 | /* IP layer ECN support | 543 | /* IP layer ECN support |
540 | * From RFC 2481 | 544 | * From RFC 2481 |
@@ -592,7 +596,7 @@ out: | |||
592 | return err; | 596 | return err; |
593 | no_route: | 597 | no_route: |
594 | kfree_skb(nskb); | 598 | kfree_skb(nskb); |
595 | IP_INC_STATS_BH(IPSTATS_MIB_OUTNOROUTES); | 599 | IP_INC_STATS_BH(&init_net, IPSTATS_MIB_OUTNOROUTES); |
596 | 600 | ||
597 | /* FIXME: Returning the 'err' will effect all the associations | 601 | /* FIXME: Returning the 'err' will effect all the associations |
598 | * associated with a socket, although only one of the paths of the | 602 | * associated with a socket, although only one of the paths of the |
diff --git a/net/sctp/outqueue.c b/net/sctp/outqueue.c index ace6770e9048..70ead8dc3485 100644 --- a/net/sctp/outqueue.c +++ b/net/sctp/outqueue.c | |||
@@ -702,6 +702,7 @@ int sctp_outq_uncork(struct sctp_outq *q) | |||
702 | return error; | 702 | return error; |
703 | } | 703 | } |
704 | 704 | ||
705 | |||
705 | /* | 706 | /* |
706 | * Try to flush an outqueue. | 707 | * Try to flush an outqueue. |
707 | * | 708 | * |
@@ -725,6 +726,7 @@ int sctp_outq_flush(struct sctp_outq *q, int rtx_timeout) | |||
725 | sctp_xmit_t status; | 726 | sctp_xmit_t status; |
726 | int error = 0; | 727 | int error = 0; |
727 | int start_timer = 0; | 728 | int start_timer = 0; |
729 | int one_packet = 0; | ||
728 | 730 | ||
729 | /* These transports have chunks to send. */ | 731 | /* These transports have chunks to send. */ |
730 | struct list_head transport_list; | 732 | struct list_head transport_list; |
@@ -830,20 +832,33 @@ int sctp_outq_flush(struct sctp_outq *q, int rtx_timeout) | |||
830 | if (sctp_test_T_bit(chunk)) { | 832 | if (sctp_test_T_bit(chunk)) { |
831 | packet->vtag = asoc->c.my_vtag; | 833 | packet->vtag = asoc->c.my_vtag; |
832 | } | 834 | } |
833 | case SCTP_CID_SACK: | 835 | /* The following chunks are "response" chunks, i.e. |
834 | case SCTP_CID_HEARTBEAT: | 836 | * they are generated in response to something we |
837 | * received. If we are sending these, then we can | ||
838 | * send only 1 packet containing these chunks. | ||
839 | */ | ||
835 | case SCTP_CID_HEARTBEAT_ACK: | 840 | case SCTP_CID_HEARTBEAT_ACK: |
836 | case SCTP_CID_SHUTDOWN: | ||
837 | case SCTP_CID_SHUTDOWN_ACK: | 841 | case SCTP_CID_SHUTDOWN_ACK: |
838 | case SCTP_CID_ERROR: | ||
839 | case SCTP_CID_COOKIE_ECHO: | ||
840 | case SCTP_CID_COOKIE_ACK: | 842 | case SCTP_CID_COOKIE_ACK: |
841 | case SCTP_CID_ECN_ECNE: | 843 | case SCTP_CID_COOKIE_ECHO: |
844 | case SCTP_CID_ERROR: | ||
842 | case SCTP_CID_ECN_CWR: | 845 | case SCTP_CID_ECN_CWR: |
843 | case SCTP_CID_ASCONF: | ||
844 | case SCTP_CID_ASCONF_ACK: | 846 | case SCTP_CID_ASCONF_ACK: |
847 | one_packet = 1; | ||
848 | /* Fall throught */ | ||
849 | |||
850 | case SCTP_CID_SACK: | ||
851 | case SCTP_CID_HEARTBEAT: | ||
852 | case SCTP_CID_SHUTDOWN: | ||
853 | case SCTP_CID_ECN_ECNE: | ||
854 | case SCTP_CID_ASCONF: | ||
845 | case SCTP_CID_FWD_TSN: | 855 | case SCTP_CID_FWD_TSN: |
846 | sctp_packet_transmit_chunk(packet, chunk); | 856 | status = sctp_packet_transmit_chunk(packet, chunk, |
857 | one_packet); | ||
858 | if (status != SCTP_XMIT_OK) { | ||
859 | /* put the chunk back */ | ||
860 | list_add(&chunk->list, &q->control_chunk_list); | ||
861 | } | ||
847 | break; | 862 | break; |
848 | 863 | ||
849 | default: | 864 | default: |
@@ -974,7 +989,7 @@ int sctp_outq_flush(struct sctp_outq *q, int rtx_timeout) | |||
974 | atomic_read(&chunk->skb->users) : -1); | 989 | atomic_read(&chunk->skb->users) : -1); |
975 | 990 | ||
976 | /* Add the chunk to the packet. */ | 991 | /* Add the chunk to the packet. */ |
977 | status = sctp_packet_transmit_chunk(packet, chunk); | 992 | status = sctp_packet_transmit_chunk(packet, chunk, 0); |
978 | 993 | ||
979 | switch (status) { | 994 | switch (status) { |
980 | case SCTP_XMIT_PMTU_FULL: | 995 | case SCTP_XMIT_PMTU_FULL: |
@@ -1239,7 +1254,6 @@ int sctp_outq_sack(struct sctp_outq *q, struct sctp_sackhdr *sack) | |||
1239 | * Make sure the empty queue handler will get run later. | 1254 | * Make sure the empty queue handler will get run later. |
1240 | */ | 1255 | */ |
1241 | q->empty = (list_empty(&q->out_chunk_list) && | 1256 | q->empty = (list_empty(&q->out_chunk_list) && |
1242 | list_empty(&q->control_chunk_list) && | ||
1243 | list_empty(&q->retransmit)); | 1257 | list_empty(&q->retransmit)); |
1244 | if (!q->empty) | 1258 | if (!q->empty) |
1245 | goto finish; | 1259 | goto finish; |
diff --git a/net/sctp/proc.c b/net/sctp/proc.c index 0aba759cb9b7..5dd89831eceb 100644 --- a/net/sctp/proc.c +++ b/net/sctp/proc.c | |||
@@ -383,3 +383,144 @@ void sctp_assocs_proc_exit(void) | |||
383 | { | 383 | { |
384 | remove_proc_entry("assocs", proc_net_sctp); | 384 | remove_proc_entry("assocs", proc_net_sctp); |
385 | } | 385 | } |
386 | |||
387 | static void *sctp_remaddr_seq_start(struct seq_file *seq, loff_t *pos) | ||
388 | { | ||
389 | if (*pos >= sctp_assoc_hashsize) | ||
390 | return NULL; | ||
391 | |||
392 | if (*pos < 0) | ||
393 | *pos = 0; | ||
394 | |||
395 | if (*pos == 0) | ||
396 | seq_printf(seq, "ADDR ASSOC_ID HB_ACT RTO MAX_PATH_RTX " | ||
397 | "REM_ADDR_RTX START\n"); | ||
398 | |||
399 | return (void *)pos; | ||
400 | } | ||
401 | |||
402 | static void *sctp_remaddr_seq_next(struct seq_file *seq, void *v, loff_t *pos) | ||
403 | { | ||
404 | if (++*pos >= sctp_assoc_hashsize) | ||
405 | return NULL; | ||
406 | |||
407 | return pos; | ||
408 | } | ||
409 | |||
410 | static void sctp_remaddr_seq_stop(struct seq_file *seq, void *v) | ||
411 | { | ||
412 | return; | ||
413 | } | ||
414 | |||
415 | static int sctp_remaddr_seq_show(struct seq_file *seq, void *v) | ||
416 | { | ||
417 | struct sctp_hashbucket *head; | ||
418 | struct sctp_ep_common *epb; | ||
419 | struct sctp_association *assoc; | ||
420 | struct hlist_node *node; | ||
421 | struct sctp_transport *tsp; | ||
422 | int hash = *(loff_t *)v; | ||
423 | |||
424 | if (hash >= sctp_assoc_hashsize) | ||
425 | return -ENOMEM; | ||
426 | |||
427 | head = &sctp_assoc_hashtable[hash]; | ||
428 | sctp_local_bh_disable(); | ||
429 | read_lock(&head->lock); | ||
430 | sctp_for_each_hentry(epb, node, &head->chain) { | ||
431 | assoc = sctp_assoc(epb); | ||
432 | list_for_each_entry(tsp, &assoc->peer.transport_addr_list, | ||
433 | transports) { | ||
434 | /* | ||
435 | * The remote address (ADDR) | ||
436 | */ | ||
437 | tsp->af_specific->seq_dump_addr(seq, &tsp->ipaddr); | ||
438 | seq_printf(seq, " "); | ||
439 | |||
440 | /* | ||
441 | * The association ID (ASSOC_ID) | ||
442 | */ | ||
443 | seq_printf(seq, "%d ", tsp->asoc->assoc_id); | ||
444 | |||
445 | /* | ||
446 | * If the Heartbeat is active (HB_ACT) | ||
447 | * Note: 1 = Active, 0 = Inactive | ||
448 | */ | ||
449 | seq_printf(seq, "%d ", timer_pending(&tsp->hb_timer)); | ||
450 | |||
451 | /* | ||
452 | * Retransmit time out (RTO) | ||
453 | */ | ||
454 | seq_printf(seq, "%lu ", tsp->rto); | ||
455 | |||
456 | /* | ||
457 | * Maximum path retransmit count (PATH_MAX_RTX) | ||
458 | */ | ||
459 | seq_printf(seq, "%d ", tsp->pathmaxrxt); | ||
460 | |||
461 | /* | ||
462 | * remote address retransmit count (REM_ADDR_RTX) | ||
463 | * Note: We don't have a way to tally this at the moment | ||
464 | * so lets just leave it as zero for the moment | ||
465 | */ | ||
466 | seq_printf(seq, "0 "); | ||
467 | |||
468 | /* | ||
469 | * remote address start time (START). This is also not | ||
470 | * currently implemented, but we can record it with a | ||
471 | * jiffies marker in a subsequent patch | ||
472 | */ | ||
473 | seq_printf(seq, "0"); | ||
474 | |||
475 | seq_printf(seq, "\n"); | ||
476 | } | ||
477 | } | ||
478 | |||
479 | read_unlock(&head->lock); | ||
480 | sctp_local_bh_enable(); | ||
481 | |||
482 | return 0; | ||
483 | |||
484 | } | ||
485 | |||
486 | static const struct seq_operations sctp_remaddr_ops = { | ||
487 | .start = sctp_remaddr_seq_start, | ||
488 | .next = sctp_remaddr_seq_next, | ||
489 | .stop = sctp_remaddr_seq_stop, | ||
490 | .show = sctp_remaddr_seq_show, | ||
491 | }; | ||
492 | |||
493 | /* Cleanup the proc fs entry for 'remaddr' object. */ | ||
494 | void sctp_remaddr_proc_exit(void) | ||
495 | { | ||
496 | remove_proc_entry("remaddr", proc_net_sctp); | ||
497 | } | ||
498 | |||
499 | static int sctp_remaddr_seq_open(struct inode *inode, struct file *file) | ||
500 | { | ||
501 | return seq_open(file, &sctp_remaddr_ops); | ||
502 | } | ||
503 | |||
504 | static const struct file_operations sctp_remaddr_seq_fops = { | ||
505 | .open = sctp_remaddr_seq_open, | ||
506 | .read = seq_read, | ||
507 | .llseek = seq_lseek, | ||
508 | .release = seq_release, | ||
509 | }; | ||
510 | |||
511 | int __init sctp_remaddr_proc_init(void) | ||
512 | { | ||
513 | struct proc_dir_entry *p; | ||
514 | |||
515 | p = create_proc_entry("remaddr", S_IRUGO, proc_net_sctp); | ||
516 | if (!p) | ||
517 | return -ENOMEM; | ||
518 | p->proc_fops = &sctp_remaddr_seq_fops; | ||
519 | |||
520 | return 0; | ||
521 | } | ||
522 | |||
523 | void sctp_assoc_proc_exit(void) | ||
524 | { | ||
525 | remove_proc_entry("remaddr", proc_net_sctp); | ||
526 | } | ||
diff --git a/net/sctp/protocol.c b/net/sctp/protocol.c index 9258dfe784ae..a6e0818bcff5 100644 --- a/net/sctp/protocol.c +++ b/net/sctp/protocol.c | |||
@@ -52,6 +52,8 @@ | |||
52 | #include <linux/inetdevice.h> | 52 | #include <linux/inetdevice.h> |
53 | #include <linux/seq_file.h> | 53 | #include <linux/seq_file.h> |
54 | #include <linux/bootmem.h> | 54 | #include <linux/bootmem.h> |
55 | #include <linux/highmem.h> | ||
56 | #include <linux/swap.h> | ||
55 | #include <net/net_namespace.h> | 57 | #include <net/net_namespace.h> |
56 | #include <net/protocol.h> | 58 | #include <net/protocol.h> |
57 | #include <net/ip.h> | 59 | #include <net/ip.h> |
@@ -64,9 +66,12 @@ | |||
64 | 66 | ||
65 | /* Global data structures. */ | 67 | /* Global data structures. */ |
66 | struct sctp_globals sctp_globals __read_mostly; | 68 | struct sctp_globals sctp_globals __read_mostly; |
67 | struct proc_dir_entry *proc_net_sctp; | ||
68 | DEFINE_SNMP_STAT(struct sctp_mib, sctp_statistics) __read_mostly; | 69 | DEFINE_SNMP_STAT(struct sctp_mib, sctp_statistics) __read_mostly; |
69 | 70 | ||
71 | #ifdef CONFIG_PROC_FS | ||
72 | struct proc_dir_entry *proc_net_sctp; | ||
73 | #endif | ||
74 | |||
70 | struct idr sctp_assocs_id; | 75 | struct idr sctp_assocs_id; |
71 | DEFINE_SPINLOCK(sctp_assocs_id_lock); | 76 | DEFINE_SPINLOCK(sctp_assocs_id_lock); |
72 | 77 | ||
@@ -97,6 +102,7 @@ struct sock *sctp_get_ctl_sock(void) | |||
97 | /* Set up the proc fs entry for the SCTP protocol. */ | 102 | /* Set up the proc fs entry for the SCTP protocol. */ |
98 | static __init int sctp_proc_init(void) | 103 | static __init int sctp_proc_init(void) |
99 | { | 104 | { |
105 | #ifdef CONFIG_PROC_FS | ||
100 | if (!proc_net_sctp) { | 106 | if (!proc_net_sctp) { |
101 | struct proc_dir_entry *ent; | 107 | struct proc_dir_entry *ent; |
102 | ent = proc_mkdir("sctp", init_net.proc_net); | 108 | ent = proc_mkdir("sctp", init_net.proc_net); |
@@ -113,9 +119,13 @@ static __init int sctp_proc_init(void) | |||
113 | goto out_eps_proc_init; | 119 | goto out_eps_proc_init; |
114 | if (sctp_assocs_proc_init()) | 120 | if (sctp_assocs_proc_init()) |
115 | goto out_assocs_proc_init; | 121 | goto out_assocs_proc_init; |
122 | if (sctp_remaddr_proc_init()) | ||
123 | goto out_remaddr_proc_init; | ||
116 | 124 | ||
117 | return 0; | 125 | return 0; |
118 | 126 | ||
127 | out_remaddr_proc_init: | ||
128 | sctp_assocs_proc_exit(); | ||
119 | out_assocs_proc_init: | 129 | out_assocs_proc_init: |
120 | sctp_eps_proc_exit(); | 130 | sctp_eps_proc_exit(); |
121 | out_eps_proc_init: | 131 | out_eps_proc_init: |
@@ -127,6 +137,9 @@ out_snmp_proc_init: | |||
127 | } | 137 | } |
128 | out_nomem: | 138 | out_nomem: |
129 | return -ENOMEM; | 139 | return -ENOMEM; |
140 | #else | ||
141 | return 0; | ||
142 | #endif /* CONFIG_PROC_FS */ | ||
130 | } | 143 | } |
131 | 144 | ||
132 | /* Clean up the proc fs entry for the SCTP protocol. | 145 | /* Clean up the proc fs entry for the SCTP protocol. |
@@ -135,14 +148,17 @@ out_nomem: | |||
135 | */ | 148 | */ |
136 | static void sctp_proc_exit(void) | 149 | static void sctp_proc_exit(void) |
137 | { | 150 | { |
151 | #ifdef CONFIG_PROC_FS | ||
138 | sctp_snmp_proc_exit(); | 152 | sctp_snmp_proc_exit(); |
139 | sctp_eps_proc_exit(); | 153 | sctp_eps_proc_exit(); |
140 | sctp_assocs_proc_exit(); | 154 | sctp_assocs_proc_exit(); |
155 | sctp_remaddr_proc_exit(); | ||
141 | 156 | ||
142 | if (proc_net_sctp) { | 157 | if (proc_net_sctp) { |
143 | proc_net_sctp = NULL; | 158 | proc_net_sctp = NULL; |
144 | remove_proc_entry("sctp", init_net.proc_net); | 159 | remove_proc_entry("sctp", init_net.proc_net); |
145 | } | 160 | } |
161 | #endif | ||
146 | } | 162 | } |
147 | 163 | ||
148 | /* Private helper to extract ipv4 address and stash them in | 164 | /* Private helper to extract ipv4 address and stash them in |
@@ -367,6 +383,10 @@ static int sctp_v4_addr_valid(union sctp_addr *addr, | |||
367 | struct sctp_sock *sp, | 383 | struct sctp_sock *sp, |
368 | const struct sk_buff *skb) | 384 | const struct sk_buff *skb) |
369 | { | 385 | { |
386 | /* IPv4 addresses not allowed */ | ||
387 | if (sp && ipv6_only_sock(sctp_opt2sk(sp))) | ||
388 | return 0; | ||
389 | |||
370 | /* Is this a non-unicast address or a unusable SCTP address? */ | 390 | /* Is this a non-unicast address or a unusable SCTP address? */ |
371 | if (IS_IPV4_UNUSABLE_ADDRESS(addr->v4.sin_addr.s_addr)) | 391 | if (IS_IPV4_UNUSABLE_ADDRESS(addr->v4.sin_addr.s_addr)) |
372 | return 0; | 392 | return 0; |
@@ -390,6 +410,9 @@ static int sctp_v4_available(union sctp_addr *addr, struct sctp_sock *sp) | |||
390 | !sysctl_ip_nonlocal_bind) | 410 | !sysctl_ip_nonlocal_bind) |
391 | return 0; | 411 | return 0; |
392 | 412 | ||
413 | if (ipv6_only_sock(sctp_opt2sk(sp))) | ||
414 | return 0; | ||
415 | |||
393 | return 1; | 416 | return 1; |
394 | } | 417 | } |
395 | 418 | ||
@@ -645,7 +668,7 @@ static int sctp_inetaddr_event(struct notifier_block *this, unsigned long ev, | |||
645 | struct sctp_sockaddr_entry *temp; | 668 | struct sctp_sockaddr_entry *temp; |
646 | int found = 0; | 669 | int found = 0; |
647 | 670 | ||
648 | if (dev_net(ifa->ifa_dev->dev) != &init_net) | 671 | if (!net_eq(dev_net(ifa->ifa_dev->dev), &init_net)) |
649 | return NOTIFY_DONE; | 672 | return NOTIFY_DONE; |
650 | 673 | ||
651 | switch (ev) { | 674 | switch (ev) { |
@@ -1059,6 +1082,7 @@ SCTP_STATIC __init int sctp_init(void) | |||
1059 | int status = -EINVAL; | 1082 | int status = -EINVAL; |
1060 | unsigned long goal; | 1083 | unsigned long goal; |
1061 | unsigned long limit; | 1084 | unsigned long limit; |
1085 | unsigned long nr_pages; | ||
1062 | int max_share; | 1086 | int max_share; |
1063 | int order; | 1087 | int order; |
1064 | 1088 | ||
@@ -1154,8 +1178,9 @@ SCTP_STATIC __init int sctp_init(void) | |||
1154 | * Note this initalizes the data in sctpv6_prot too | 1178 | * Note this initalizes the data in sctpv6_prot too |
1155 | * Unabashedly stolen from tcp_init | 1179 | * Unabashedly stolen from tcp_init |
1156 | */ | 1180 | */ |
1157 | limit = min(num_physpages, 1UL<<(28-PAGE_SHIFT)) >> (20-PAGE_SHIFT); | 1181 | nr_pages = totalram_pages - totalhigh_pages; |
1158 | limit = (limit * (num_physpages >> (20-PAGE_SHIFT))) >> (PAGE_SHIFT-11); | 1182 | limit = min(nr_pages, 1UL<<(28-PAGE_SHIFT)) >> (20-PAGE_SHIFT); |
1183 | limit = (limit * (nr_pages >> (20-PAGE_SHIFT))) >> (PAGE_SHIFT-11); | ||
1159 | limit = max(limit, 128UL); | 1184 | limit = max(limit, 128UL); |
1160 | sysctl_sctp_mem[0] = limit / 4 * 3; | 1185 | sysctl_sctp_mem[0] = limit / 4 * 3; |
1161 | sysctl_sctp_mem[1] = limit; | 1186 | sysctl_sctp_mem[1] = limit; |
@@ -1165,7 +1190,7 @@ SCTP_STATIC __init int sctp_init(void) | |||
1165 | limit = (sysctl_sctp_mem[1]) << (PAGE_SHIFT - 7); | 1190 | limit = (sysctl_sctp_mem[1]) << (PAGE_SHIFT - 7); |
1166 | max_share = min(4UL*1024*1024, limit); | 1191 | max_share = min(4UL*1024*1024, limit); |
1167 | 1192 | ||
1168 | sysctl_sctp_rmem[0] = PAGE_SIZE; /* give each asoc 1 page min */ | 1193 | sysctl_sctp_rmem[0] = SK_MEM_QUANTUM; /* give each asoc 1 page min */ |
1169 | sysctl_sctp_rmem[1] = (1500 *(sizeof(struct sk_buff) + 1)); | 1194 | sysctl_sctp_rmem[1] = (1500 *(sizeof(struct sk_buff) + 1)); |
1170 | sysctl_sctp_rmem[2] = max(sysctl_sctp_rmem[1], max_share); | 1195 | sysctl_sctp_rmem[2] = max(sysctl_sctp_rmem[1], max_share); |
1171 | 1196 | ||
diff --git a/net/sctp/sm_make_chunk.c b/net/sctp/sm_make_chunk.c index bbc7107c86cf..e8ca4e54981f 100644 --- a/net/sctp/sm_make_chunk.c +++ b/net/sctp/sm_make_chunk.c | |||
@@ -2364,8 +2364,13 @@ static int sctp_process_param(struct sctp_association *asoc, | |||
2364 | case SCTP_PARAM_IPV6_ADDRESS: | 2364 | case SCTP_PARAM_IPV6_ADDRESS: |
2365 | if (PF_INET6 != asoc->base.sk->sk_family) | 2365 | if (PF_INET6 != asoc->base.sk->sk_family) |
2366 | break; | 2366 | break; |
2367 | /* Fall through. */ | 2367 | goto do_addr_param; |
2368 | |||
2368 | case SCTP_PARAM_IPV4_ADDRESS: | 2369 | case SCTP_PARAM_IPV4_ADDRESS: |
2370 | /* v4 addresses are not allowed on v6-only socket */ | ||
2371 | if (ipv6_only_sock(asoc->base.sk)) | ||
2372 | break; | ||
2373 | do_addr_param: | ||
2369 | af = sctp_get_af_specific(param_type2af(param.p->type)); | 2374 | af = sctp_get_af_specific(param_type2af(param.p->type)); |
2370 | af->from_addr_param(&addr, param.addr, htons(asoc->peer.port), 0); | 2375 | af->from_addr_param(&addr, param.addr, htons(asoc->peer.port), 0); |
2371 | scope = sctp_scope(peer_addr); | 2376 | scope = sctp_scope(peer_addr); |
diff --git a/net/sctp/sm_sideeffect.c b/net/sctp/sm_sideeffect.c index 23a9f1a95b7d..9732c797e8ed 100644 --- a/net/sctp/sm_sideeffect.c +++ b/net/sctp/sm_sideeffect.c | |||
@@ -190,20 +190,28 @@ static int sctp_gen_sack(struct sctp_association *asoc, int force, | |||
190 | * unacknowledged DATA chunk. ... | 190 | * unacknowledged DATA chunk. ... |
191 | */ | 191 | */ |
192 | if (!asoc->peer.sack_needed) { | 192 | if (!asoc->peer.sack_needed) { |
193 | /* We will need a SACK for the next packet. */ | 193 | asoc->peer.sack_cnt++; |
194 | asoc->peer.sack_needed = 1; | ||
195 | 194 | ||
196 | /* Set the SACK delay timeout based on the | 195 | /* Set the SACK delay timeout based on the |
197 | * SACK delay for the last transport | 196 | * SACK delay for the last transport |
198 | * data was received from, or the default | 197 | * data was received from, or the default |
199 | * for the association. | 198 | * for the association. |
200 | */ | 199 | */ |
201 | if (trans) | 200 | if (trans) { |
201 | /* We will need a SACK for the next packet. */ | ||
202 | if (asoc->peer.sack_cnt >= trans->sackfreq - 1) | ||
203 | asoc->peer.sack_needed = 1; | ||
204 | |||
202 | asoc->timeouts[SCTP_EVENT_TIMEOUT_SACK] = | 205 | asoc->timeouts[SCTP_EVENT_TIMEOUT_SACK] = |
203 | trans->sackdelay; | 206 | trans->sackdelay; |
204 | else | 207 | } else { |
208 | /* We will need a SACK for the next packet. */ | ||
209 | if (asoc->peer.sack_cnt >= asoc->sackfreq - 1) | ||
210 | asoc->peer.sack_needed = 1; | ||
211 | |||
205 | asoc->timeouts[SCTP_EVENT_TIMEOUT_SACK] = | 212 | asoc->timeouts[SCTP_EVENT_TIMEOUT_SACK] = |
206 | asoc->sackdelay; | 213 | asoc->sackdelay; |
214 | } | ||
207 | 215 | ||
208 | /* Restart the SACK timer. */ | 216 | /* Restart the SACK timer. */ |
209 | sctp_add_cmd_sf(commands, SCTP_CMD_TIMER_RESTART, | 217 | sctp_add_cmd_sf(commands, SCTP_CMD_TIMER_RESTART, |
@@ -216,6 +224,7 @@ static int sctp_gen_sack(struct sctp_association *asoc, int force, | |||
216 | goto nomem; | 224 | goto nomem; |
217 | 225 | ||
218 | asoc->peer.sack_needed = 0; | 226 | asoc->peer.sack_needed = 0; |
227 | asoc->peer.sack_cnt = 0; | ||
219 | 228 | ||
220 | sctp_add_cmd_sf(commands, SCTP_CMD_REPLY, SCTP_CHUNK(sack)); | 229 | sctp_add_cmd_sf(commands, SCTP_CMD_REPLY, SCTP_CHUNK(sack)); |
221 | 230 | ||
@@ -655,7 +664,7 @@ static int sctp_cmd_process_sack(sctp_cmd_seq_t *cmds, | |||
655 | struct sctp_association *asoc, | 664 | struct sctp_association *asoc, |
656 | struct sctp_sackhdr *sackh) | 665 | struct sctp_sackhdr *sackh) |
657 | { | 666 | { |
658 | int err; | 667 | int err = 0; |
659 | 668 | ||
660 | if (sctp_outq_sack(&asoc->outqueue, sackh)) { | 669 | if (sctp_outq_sack(&asoc->outqueue, sackh)) { |
661 | /* There are no more TSNs awaiting SACK. */ | 670 | /* There are no more TSNs awaiting SACK. */ |
@@ -663,11 +672,6 @@ static int sctp_cmd_process_sack(sctp_cmd_seq_t *cmds, | |||
663 | SCTP_ST_OTHER(SCTP_EVENT_NO_PENDING_TSN), | 672 | SCTP_ST_OTHER(SCTP_EVENT_NO_PENDING_TSN), |
664 | asoc->state, asoc->ep, asoc, NULL, | 673 | asoc->state, asoc->ep, asoc, NULL, |
665 | GFP_ATOMIC); | 674 | GFP_ATOMIC); |
666 | } else { | ||
667 | /* Windows may have opened, so we need | ||
668 | * to check if we have DATA to transmit | ||
669 | */ | ||
670 | err = sctp_outq_flush(&asoc->outqueue, 0); | ||
671 | } | 675 | } |
672 | 676 | ||
673 | return err; | 677 | return err; |
@@ -1472,8 +1476,15 @@ static int sctp_cmd_interpreter(sctp_event_t event_type, | |||
1472 | break; | 1476 | break; |
1473 | 1477 | ||
1474 | case SCTP_CMD_DISCARD_PACKET: | 1478 | case SCTP_CMD_DISCARD_PACKET: |
1475 | /* We need to discard the whole packet. */ | 1479 | /* We need to discard the whole packet. |
1480 | * Uncork the queue since there might be | ||
1481 | * responses pending | ||
1482 | */ | ||
1476 | chunk->pdiscard = 1; | 1483 | chunk->pdiscard = 1; |
1484 | if (asoc) { | ||
1485 | sctp_outq_uncork(&asoc->outqueue); | ||
1486 | local_cork = 0; | ||
1487 | } | ||
1477 | break; | 1488 | break; |
1478 | 1489 | ||
1479 | case SCTP_CMD_RTO_PENDING: | 1490 | case SCTP_CMD_RTO_PENDING: |
@@ -1544,8 +1555,15 @@ static int sctp_cmd_interpreter(sctp_event_t event_type, | |||
1544 | } | 1555 | } |
1545 | 1556 | ||
1546 | out: | 1557 | out: |
1547 | if (local_cork) | 1558 | /* If this is in response to a received chunk, wait until |
1548 | sctp_outq_uncork(&asoc->outqueue); | 1559 | * we are done with the packet to open the queue so that we don't |
1560 | * send multiple packets in response to a single request. | ||
1561 | */ | ||
1562 | if (asoc && SCTP_EVENT_T_CHUNK == event_type && chunk) { | ||
1563 | if (chunk->end_of_packet || chunk->singleton) | ||
1564 | sctp_outq_uncork(&asoc->outqueue); | ||
1565 | } else if (local_cork) | ||
1566 | sctp_outq_uncork(&asoc->outqueue); | ||
1549 | return error; | 1567 | return error; |
1550 | nomem: | 1568 | nomem: |
1551 | error = -ENOMEM; | 1569 | error = -ENOMEM; |
diff --git a/net/sctp/sm_statefuns.c b/net/sctp/sm_statefuns.c index fcdb45d1071b..8848d329aa2c 100644 --- a/net/sctp/sm_statefuns.c +++ b/net/sctp/sm_statefuns.c | |||
@@ -795,8 +795,6 @@ sctp_disposition_t sctp_sf_do_5_1D_ce(const struct sctp_endpoint *ep, | |||
795 | sctp_add_cmd_sf(commands, SCTP_CMD_TIMER_START, | 795 | sctp_add_cmd_sf(commands, SCTP_CMD_TIMER_START, |
796 | SCTP_TO(SCTP_EVENT_TIMEOUT_AUTOCLOSE)); | 796 | SCTP_TO(SCTP_EVENT_TIMEOUT_AUTOCLOSE)); |
797 | 797 | ||
798 | sctp_add_cmd_sf(commands, SCTP_CMD_TRANSMIT, SCTP_NULL()); | ||
799 | |||
800 | /* This will send the COOKIE ACK */ | 798 | /* This will send the COOKIE ACK */ |
801 | sctp_add_cmd_sf(commands, SCTP_CMD_REPLY, SCTP_CHUNK(repl)); | 799 | sctp_add_cmd_sf(commands, SCTP_CMD_REPLY, SCTP_CHUNK(repl)); |
802 | 800 | ||
@@ -883,7 +881,6 @@ sctp_disposition_t sctp_sf_do_5_1E_ca(const struct sctp_endpoint *ep, | |||
883 | if (asoc->autoclose) | 881 | if (asoc->autoclose) |
884 | sctp_add_cmd_sf(commands, SCTP_CMD_TIMER_START, | 882 | sctp_add_cmd_sf(commands, SCTP_CMD_TIMER_START, |
885 | SCTP_TO(SCTP_EVENT_TIMEOUT_AUTOCLOSE)); | 883 | SCTP_TO(SCTP_EVENT_TIMEOUT_AUTOCLOSE)); |
886 | sctp_add_cmd_sf(commands, SCTP_CMD_TRANSMIT, SCTP_NULL()); | ||
887 | 884 | ||
888 | /* It may also notify its ULP about the successful | 885 | /* It may also notify its ULP about the successful |
889 | * establishment of the association with a Communication Up | 886 | * establishment of the association with a Communication Up |
@@ -1781,7 +1778,6 @@ static sctp_disposition_t sctp_sf_do_dupcook_b(const struct sctp_endpoint *ep, | |||
1781 | goto nomem; | 1778 | goto nomem; |
1782 | 1779 | ||
1783 | sctp_add_cmd_sf(commands, SCTP_CMD_REPLY, SCTP_CHUNK(repl)); | 1780 | sctp_add_cmd_sf(commands, SCTP_CMD_REPLY, SCTP_CHUNK(repl)); |
1784 | sctp_add_cmd_sf(commands, SCTP_CMD_TRANSMIT, SCTP_NULL()); | ||
1785 | 1781 | ||
1786 | /* RFC 2960 5.1 Normal Establishment of an Association | 1782 | /* RFC 2960 5.1 Normal Establishment of an Association |
1787 | * | 1783 | * |
@@ -1898,12 +1894,13 @@ static sctp_disposition_t sctp_sf_do_dupcook_d(const struct sctp_endpoint *ep, | |||
1898 | 1894 | ||
1899 | } | 1895 | } |
1900 | } | 1896 | } |
1901 | sctp_add_cmd_sf(commands, SCTP_CMD_TRANSMIT, SCTP_NULL()); | ||
1902 | 1897 | ||
1903 | repl = sctp_make_cookie_ack(new_asoc, chunk); | 1898 | repl = sctp_make_cookie_ack(new_asoc, chunk); |
1904 | if (!repl) | 1899 | if (!repl) |
1905 | goto nomem; | 1900 | goto nomem; |
1906 | 1901 | ||
1902 | sctp_add_cmd_sf(commands, SCTP_CMD_REPLY, SCTP_CHUNK(repl)); | ||
1903 | |||
1907 | if (ev) | 1904 | if (ev) |
1908 | sctp_add_cmd_sf(commands, SCTP_CMD_EVENT_ULP, | 1905 | sctp_add_cmd_sf(commands, SCTP_CMD_EVENT_ULP, |
1909 | SCTP_ULPEVENT(ev)); | 1906 | SCTP_ULPEVENT(ev)); |
@@ -1911,9 +1908,6 @@ static sctp_disposition_t sctp_sf_do_dupcook_d(const struct sctp_endpoint *ep, | |||
1911 | sctp_add_cmd_sf(commands, SCTP_CMD_EVENT_ULP, | 1908 | sctp_add_cmd_sf(commands, SCTP_CMD_EVENT_ULP, |
1912 | SCTP_ULPEVENT(ai_ev)); | 1909 | SCTP_ULPEVENT(ai_ev)); |
1913 | 1910 | ||
1914 | sctp_add_cmd_sf(commands, SCTP_CMD_REPLY, SCTP_CHUNK(repl)); | ||
1915 | sctp_add_cmd_sf(commands, SCTP_CMD_TRANSMIT, SCTP_NULL()); | ||
1916 | |||
1917 | return SCTP_DISPOSITION_CONSUME; | 1911 | return SCTP_DISPOSITION_CONSUME; |
1918 | 1912 | ||
1919 | nomem: | 1913 | nomem: |
@@ -3970,9 +3964,6 @@ sctp_disposition_t sctp_sf_unk_chunk(const struct sctp_endpoint *ep, | |||
3970 | return sctp_sf_pdiscard(ep, asoc, type, arg, commands); | 3964 | return sctp_sf_pdiscard(ep, asoc, type, arg, commands); |
3971 | break; | 3965 | break; |
3972 | case SCTP_CID_ACTION_DISCARD_ERR: | 3966 | case SCTP_CID_ACTION_DISCARD_ERR: |
3973 | /* Discard the packet. */ | ||
3974 | sctp_sf_pdiscard(ep, asoc, type, arg, commands); | ||
3975 | |||
3976 | /* Generate an ERROR chunk as response. */ | 3967 | /* Generate an ERROR chunk as response. */ |
3977 | hdr = unk_chunk->chunk_hdr; | 3968 | hdr = unk_chunk->chunk_hdr; |
3978 | err_chunk = sctp_make_op_error(asoc, unk_chunk, | 3969 | err_chunk = sctp_make_op_error(asoc, unk_chunk, |
@@ -3982,6 +3973,9 @@ sctp_disposition_t sctp_sf_unk_chunk(const struct sctp_endpoint *ep, | |||
3982 | sctp_add_cmd_sf(commands, SCTP_CMD_REPLY, | 3973 | sctp_add_cmd_sf(commands, SCTP_CMD_REPLY, |
3983 | SCTP_CHUNK(err_chunk)); | 3974 | SCTP_CHUNK(err_chunk)); |
3984 | } | 3975 | } |
3976 | |||
3977 | /* Discard the packet. */ | ||
3978 | sctp_sf_pdiscard(ep, asoc, type, arg, commands); | ||
3985 | return SCTP_DISPOSITION_CONSUME; | 3979 | return SCTP_DISPOSITION_CONSUME; |
3986 | break; | 3980 | break; |
3987 | case SCTP_CID_ACTION_SKIP: | 3981 | case SCTP_CID_ACTION_SKIP: |
diff --git a/net/sctp/socket.c b/net/sctp/socket.c index 0dbcde6758ea..79bece16aede 100644 --- a/net/sctp/socket.c +++ b/net/sctp/socket.c | |||
@@ -116,7 +116,7 @@ static int sctp_memory_pressure; | |||
116 | static atomic_t sctp_memory_allocated; | 116 | static atomic_t sctp_memory_allocated; |
117 | static atomic_t sctp_sockets_allocated; | 117 | static atomic_t sctp_sockets_allocated; |
118 | 118 | ||
119 | static void sctp_enter_memory_pressure(void) | 119 | static void sctp_enter_memory_pressure(struct sock *sk) |
120 | { | 120 | { |
121 | sctp_memory_pressure = 1; | 121 | sctp_memory_pressure = 1; |
122 | } | 122 | } |
@@ -308,9 +308,16 @@ static struct sctp_af *sctp_sockaddr_af(struct sctp_sock *opt, | |||
308 | if (len < sizeof (struct sockaddr)) | 308 | if (len < sizeof (struct sockaddr)) |
309 | return NULL; | 309 | return NULL; |
310 | 310 | ||
311 | /* Does this PF support this AF? */ | 311 | /* V4 mapped address are really of AF_INET family */ |
312 | if (!opt->pf->af_supported(addr->sa.sa_family, opt)) | 312 | if (addr->sa.sa_family == AF_INET6 && |
313 | return NULL; | 313 | ipv6_addr_v4mapped(&addr->v6.sin6_addr)) { |
314 | if (!opt->pf->af_supported(AF_INET, opt)) | ||
315 | return NULL; | ||
316 | } else { | ||
317 | /* Does this PF support this AF? */ | ||
318 | if (!opt->pf->af_supported(addr->sa.sa_family, opt)) | ||
319 | return NULL; | ||
320 | } | ||
314 | 321 | ||
315 | /* If we get this far, af is valid. */ | 322 | /* If we get this far, af is valid. */ |
316 | af = sctp_get_af_specific(addr->sa.sa_family); | 323 | af = sctp_get_af_specific(addr->sa.sa_family); |
@@ -370,18 +377,19 @@ SCTP_STATIC int sctp_do_bind(struct sock *sk, union sctp_addr *addr, int len) | |||
370 | if (snum && snum < PROT_SOCK && !capable(CAP_NET_BIND_SERVICE)) | 377 | if (snum && snum < PROT_SOCK && !capable(CAP_NET_BIND_SERVICE)) |
371 | return -EACCES; | 378 | return -EACCES; |
372 | 379 | ||
380 | /* See if the address matches any of the addresses we may have | ||
381 | * already bound before checking against other endpoints. | ||
382 | */ | ||
383 | if (sctp_bind_addr_match(bp, addr, sp)) | ||
384 | return -EINVAL; | ||
385 | |||
373 | /* Make sure we are allowed to bind here. | 386 | /* Make sure we are allowed to bind here. |
374 | * The function sctp_get_port_local() does duplicate address | 387 | * The function sctp_get_port_local() does duplicate address |
375 | * detection. | 388 | * detection. |
376 | */ | 389 | */ |
377 | addr->v4.sin_port = htons(snum); | 390 | addr->v4.sin_port = htons(snum); |
378 | if ((ret = sctp_get_port_local(sk, addr))) { | 391 | if ((ret = sctp_get_port_local(sk, addr))) { |
379 | if (ret == (long) sk) { | 392 | return -EADDRINUSE; |
380 | /* This endpoint has a conflicting address. */ | ||
381 | return -EINVAL; | ||
382 | } else { | ||
383 | return -EADDRINUSE; | ||
384 | } | ||
385 | } | 393 | } |
386 | 394 | ||
387 | /* Refresh ephemeral port. */ | 395 | /* Refresh ephemeral port. */ |
@@ -956,7 +964,8 @@ out: | |||
956 | */ | 964 | */ |
957 | static int __sctp_connect(struct sock* sk, | 965 | static int __sctp_connect(struct sock* sk, |
958 | struct sockaddr *kaddrs, | 966 | struct sockaddr *kaddrs, |
959 | int addrs_size) | 967 | int addrs_size, |
968 | sctp_assoc_t *assoc_id) | ||
960 | { | 969 | { |
961 | struct sctp_sock *sp; | 970 | struct sctp_sock *sp; |
962 | struct sctp_endpoint *ep; | 971 | struct sctp_endpoint *ep; |
@@ -1111,6 +1120,8 @@ static int __sctp_connect(struct sock* sk, | |||
1111 | timeo = sock_sndtimeo(sk, f_flags & O_NONBLOCK); | 1120 | timeo = sock_sndtimeo(sk, f_flags & O_NONBLOCK); |
1112 | 1121 | ||
1113 | err = sctp_wait_for_connect(asoc, &timeo); | 1122 | err = sctp_wait_for_connect(asoc, &timeo); |
1123 | if (!err && assoc_id) | ||
1124 | *assoc_id = asoc->assoc_id; | ||
1114 | 1125 | ||
1115 | /* Don't free association on exit. */ | 1126 | /* Don't free association on exit. */ |
1116 | asoc = NULL; | 1127 | asoc = NULL; |
@@ -1128,7 +1139,8 @@ out_free: | |||
1128 | /* Helper for tunneling sctp_connectx() requests through sctp_setsockopt() | 1139 | /* Helper for tunneling sctp_connectx() requests through sctp_setsockopt() |
1129 | * | 1140 | * |
1130 | * API 8.9 | 1141 | * API 8.9 |
1131 | * int sctp_connectx(int sd, struct sockaddr *addrs, int addrcnt); | 1142 | * int sctp_connectx(int sd, struct sockaddr *addrs, int addrcnt, |
1143 | * sctp_assoc_t *asoc); | ||
1132 | * | 1144 | * |
1133 | * If sd is an IPv4 socket, the addresses passed must be IPv4 addresses. | 1145 | * If sd is an IPv4 socket, the addresses passed must be IPv4 addresses. |
1134 | * If the sd is an IPv6 socket, the addresses passed can either be IPv4 | 1146 | * If the sd is an IPv6 socket, the addresses passed can either be IPv4 |
@@ -1144,8 +1156,10 @@ out_free: | |||
1144 | * representation is termed a "packed array" of addresses). The caller | 1156 | * representation is termed a "packed array" of addresses). The caller |
1145 | * specifies the number of addresses in the array with addrcnt. | 1157 | * specifies the number of addresses in the array with addrcnt. |
1146 | * | 1158 | * |
1147 | * On success, sctp_connectx() returns 0. On failure, sctp_connectx() returns | 1159 | * On success, sctp_connectx() returns 0. It also sets the assoc_id to |
1148 | * -1, and sets errno to the appropriate error code. | 1160 | * the association id of the new association. On failure, sctp_connectx() |
1161 | * returns -1, and sets errno to the appropriate error code. The assoc_id | ||
1162 | * is not touched by the kernel. | ||
1149 | * | 1163 | * |
1150 | * For SCTP, the port given in each socket address must be the same, or | 1164 | * For SCTP, the port given in each socket address must be the same, or |
1151 | * sctp_connectx() will fail, setting errno to EINVAL. | 1165 | * sctp_connectx() will fail, setting errno to EINVAL. |
@@ -1182,11 +1196,12 @@ out_free: | |||
1182 | * addrs The pointer to the addresses in user land | 1196 | * addrs The pointer to the addresses in user land |
1183 | * addrssize Size of the addrs buffer | 1197 | * addrssize Size of the addrs buffer |
1184 | * | 1198 | * |
1185 | * Returns 0 if ok, <0 errno code on error. | 1199 | * Returns >=0 if ok, <0 errno code on error. |
1186 | */ | 1200 | */ |
1187 | SCTP_STATIC int sctp_setsockopt_connectx(struct sock* sk, | 1201 | SCTP_STATIC int __sctp_setsockopt_connectx(struct sock* sk, |
1188 | struct sockaddr __user *addrs, | 1202 | struct sockaddr __user *addrs, |
1189 | int addrs_size) | 1203 | int addrs_size, |
1204 | sctp_assoc_t *assoc_id) | ||
1190 | { | 1205 | { |
1191 | int err = 0; | 1206 | int err = 0; |
1192 | struct sockaddr *kaddrs; | 1207 | struct sockaddr *kaddrs; |
@@ -1209,13 +1224,46 @@ SCTP_STATIC int sctp_setsockopt_connectx(struct sock* sk, | |||
1209 | if (__copy_from_user(kaddrs, addrs, addrs_size)) { | 1224 | if (__copy_from_user(kaddrs, addrs, addrs_size)) { |
1210 | err = -EFAULT; | 1225 | err = -EFAULT; |
1211 | } else { | 1226 | } else { |
1212 | err = __sctp_connect(sk, kaddrs, addrs_size); | 1227 | err = __sctp_connect(sk, kaddrs, addrs_size, assoc_id); |
1213 | } | 1228 | } |
1214 | 1229 | ||
1215 | kfree(kaddrs); | 1230 | kfree(kaddrs); |
1231 | |||
1216 | return err; | 1232 | return err; |
1217 | } | 1233 | } |
1218 | 1234 | ||
1235 | /* | ||
1236 | * This is an older interface. It's kept for backward compatibility | ||
1237 | * to the option that doesn't provide association id. | ||
1238 | */ | ||
1239 | SCTP_STATIC int sctp_setsockopt_connectx_old(struct sock* sk, | ||
1240 | struct sockaddr __user *addrs, | ||
1241 | int addrs_size) | ||
1242 | { | ||
1243 | return __sctp_setsockopt_connectx(sk, addrs, addrs_size, NULL); | ||
1244 | } | ||
1245 | |||
1246 | /* | ||
1247 | * New interface for the API. The since the API is done with a socket | ||
1248 | * option, to make it simple we feed back the association id is as a return | ||
1249 | * indication to the call. Error is always negative and association id is | ||
1250 | * always positive. | ||
1251 | */ | ||
1252 | SCTP_STATIC int sctp_setsockopt_connectx(struct sock* sk, | ||
1253 | struct sockaddr __user *addrs, | ||
1254 | int addrs_size) | ||
1255 | { | ||
1256 | sctp_assoc_t assoc_id = 0; | ||
1257 | int err = 0; | ||
1258 | |||
1259 | err = __sctp_setsockopt_connectx(sk, addrs, addrs_size, &assoc_id); | ||
1260 | |||
1261 | if (err) | ||
1262 | return err; | ||
1263 | else | ||
1264 | return assoc_id; | ||
1265 | } | ||
1266 | |||
1219 | /* API 3.1.4 close() - UDP Style Syntax | 1267 | /* API 3.1.4 close() - UDP Style Syntax |
1220 | * Applications use close() to perform graceful shutdown (as described in | 1268 | * Applications use close() to perform graceful shutdown (as described in |
1221 | * Section 10.1 of [SCTP]) on ALL the associations currently represented | 1269 | * Section 10.1 of [SCTP]) on ALL the associations currently represented |
@@ -2305,74 +2353,98 @@ static int sctp_setsockopt_peer_addr_params(struct sock *sk, | |||
2305 | return 0; | 2353 | return 0; |
2306 | } | 2354 | } |
2307 | 2355 | ||
2308 | /* 7.1.23. Delayed Ack Timer (SCTP_DELAYED_ACK_TIME) | 2356 | /* |
2309 | * | 2357 | * 7.1.23. Get or set delayed ack timer (SCTP_DELAYED_SACK) |
2310 | * This options will get or set the delayed ack timer. The time is set | 2358 | * |
2311 | * in milliseconds. If the assoc_id is 0, then this sets or gets the | 2359 | * This option will effect the way delayed acks are performed. This |
2312 | * endpoints default delayed ack timer value. If the assoc_id field is | 2360 | * option allows you to get or set the delayed ack time, in |
2313 | * non-zero, then the set or get effects the specified association. | 2361 | * milliseconds. It also allows changing the delayed ack frequency. |
2314 | * | 2362 | * Changing the frequency to 1 disables the delayed sack algorithm. If |
2315 | * struct sctp_assoc_value { | 2363 | * the assoc_id is 0, then this sets or gets the endpoints default |
2316 | * sctp_assoc_t assoc_id; | 2364 | * values. If the assoc_id field is non-zero, then the set or get |
2317 | * uint32_t assoc_value; | 2365 | * effects the specified association for the one to many model (the |
2318 | * }; | 2366 | * assoc_id field is ignored by the one to one model). Note that if |
2367 | * sack_delay or sack_freq are 0 when setting this option, then the | ||
2368 | * current values will remain unchanged. | ||
2369 | * | ||
2370 | * struct sctp_sack_info { | ||
2371 | * sctp_assoc_t sack_assoc_id; | ||
2372 | * uint32_t sack_delay; | ||
2373 | * uint32_t sack_freq; | ||
2374 | * }; | ||
2319 | * | 2375 | * |
2320 | * assoc_id - This parameter, indicates which association the | 2376 | * sack_assoc_id - This parameter, indicates which association the user |
2321 | * user is preforming an action upon. Note that if | 2377 | * is performing an action upon. Note that if this field's value is |
2322 | * this field's value is zero then the endpoints | 2378 | * zero then the endpoints default value is changed (effecting future |
2323 | * default value is changed (effecting future | 2379 | * associations only). |
2324 | * associations only). | ||
2325 | * | 2380 | * |
2326 | * assoc_value - This parameter contains the number of milliseconds | 2381 | * sack_delay - This parameter contains the number of milliseconds that |
2327 | * that the user is requesting the delayed ACK timer | 2382 | * the user is requesting the delayed ACK timer be set to. Note that |
2328 | * be set to. Note that this value is defined in | 2383 | * this value is defined in the standard to be between 200 and 500 |
2329 | * the standard to be between 200 and 500 milliseconds. | 2384 | * milliseconds. |
2330 | * | 2385 | * |
2331 | * Note: a value of zero will leave the value alone, | 2386 | * sack_freq - This parameter contains the number of packets that must |
2332 | * but disable SACK delay. A non-zero value will also | 2387 | * be received before a sack is sent without waiting for the delay |
2333 | * enable SACK delay. | 2388 | * timer to expire. The default value for this is 2, setting this |
2389 | * value to 1 will disable the delayed sack algorithm. | ||
2334 | */ | 2390 | */ |
2335 | 2391 | ||
2336 | static int sctp_setsockopt_delayed_ack_time(struct sock *sk, | 2392 | static int sctp_setsockopt_delayed_ack(struct sock *sk, |
2337 | char __user *optval, int optlen) | 2393 | char __user *optval, int optlen) |
2338 | { | 2394 | { |
2339 | struct sctp_assoc_value params; | 2395 | struct sctp_sack_info params; |
2340 | struct sctp_transport *trans = NULL; | 2396 | struct sctp_transport *trans = NULL; |
2341 | struct sctp_association *asoc = NULL; | 2397 | struct sctp_association *asoc = NULL; |
2342 | struct sctp_sock *sp = sctp_sk(sk); | 2398 | struct sctp_sock *sp = sctp_sk(sk); |
2343 | 2399 | ||
2344 | if (optlen != sizeof(struct sctp_assoc_value)) | 2400 | if (optlen == sizeof(struct sctp_sack_info)) { |
2345 | return - EINVAL; | 2401 | if (copy_from_user(¶ms, optval, optlen)) |
2402 | return -EFAULT; | ||
2346 | 2403 | ||
2347 | if (copy_from_user(¶ms, optval, optlen)) | 2404 | if (params.sack_delay == 0 && params.sack_freq == 0) |
2348 | return -EFAULT; | 2405 | return 0; |
2406 | } else if (optlen == sizeof(struct sctp_assoc_value)) { | ||
2407 | printk(KERN_WARNING "SCTP: Use of struct sctp_sack_info " | ||
2408 | "in delayed_ack socket option deprecated\n"); | ||
2409 | printk(KERN_WARNING "SCTP: struct sctp_sack_info instead\n"); | ||
2410 | if (copy_from_user(¶ms, optval, optlen)) | ||
2411 | return -EFAULT; | ||
2412 | |||
2413 | if (params.sack_delay == 0) | ||
2414 | params.sack_freq = 1; | ||
2415 | else | ||
2416 | params.sack_freq = 0; | ||
2417 | } else | ||
2418 | return - EINVAL; | ||
2349 | 2419 | ||
2350 | /* Validate value parameter. */ | 2420 | /* Validate value parameter. */ |
2351 | if (params.assoc_value > 500) | 2421 | if (params.sack_delay > 500) |
2352 | return -EINVAL; | 2422 | return -EINVAL; |
2353 | 2423 | ||
2354 | /* Get association, if assoc_id != 0 and the socket is a one | 2424 | /* Get association, if sack_assoc_id != 0 and the socket is a one |
2355 | * to many style socket, and an association was not found, then | 2425 | * to many style socket, and an association was not found, then |
2356 | * the id was invalid. | 2426 | * the id was invalid. |
2357 | */ | 2427 | */ |
2358 | asoc = sctp_id2assoc(sk, params.assoc_id); | 2428 | asoc = sctp_id2assoc(sk, params.sack_assoc_id); |
2359 | if (!asoc && params.assoc_id && sctp_style(sk, UDP)) | 2429 | if (!asoc && params.sack_assoc_id && sctp_style(sk, UDP)) |
2360 | return -EINVAL; | 2430 | return -EINVAL; |
2361 | 2431 | ||
2362 | if (params.assoc_value) { | 2432 | if (params.sack_delay) { |
2363 | if (asoc) { | 2433 | if (asoc) { |
2364 | asoc->sackdelay = | 2434 | asoc->sackdelay = |
2365 | msecs_to_jiffies(params.assoc_value); | 2435 | msecs_to_jiffies(params.sack_delay); |
2366 | asoc->param_flags = | 2436 | asoc->param_flags = |
2367 | (asoc->param_flags & ~SPP_SACKDELAY) | | 2437 | (asoc->param_flags & ~SPP_SACKDELAY) | |
2368 | SPP_SACKDELAY_ENABLE; | 2438 | SPP_SACKDELAY_ENABLE; |
2369 | } else { | 2439 | } else { |
2370 | sp->sackdelay = params.assoc_value; | 2440 | sp->sackdelay = params.sack_delay; |
2371 | sp->param_flags = | 2441 | sp->param_flags = |
2372 | (sp->param_flags & ~SPP_SACKDELAY) | | 2442 | (sp->param_flags & ~SPP_SACKDELAY) | |
2373 | SPP_SACKDELAY_ENABLE; | 2443 | SPP_SACKDELAY_ENABLE; |
2374 | } | 2444 | } |
2375 | } else { | 2445 | } |
2446 | |||
2447 | if (params.sack_freq == 1) { | ||
2376 | if (asoc) { | 2448 | if (asoc) { |
2377 | asoc->param_flags = | 2449 | asoc->param_flags = |
2378 | (asoc->param_flags & ~SPP_SACKDELAY) | | 2450 | (asoc->param_flags & ~SPP_SACKDELAY) | |
@@ -2382,22 +2454,40 @@ static int sctp_setsockopt_delayed_ack_time(struct sock *sk, | |||
2382 | (sp->param_flags & ~SPP_SACKDELAY) | | 2454 | (sp->param_flags & ~SPP_SACKDELAY) | |
2383 | SPP_SACKDELAY_DISABLE; | 2455 | SPP_SACKDELAY_DISABLE; |
2384 | } | 2456 | } |
2457 | } else if (params.sack_freq > 1) { | ||
2458 | if (asoc) { | ||
2459 | asoc->sackfreq = params.sack_freq; | ||
2460 | asoc->param_flags = | ||
2461 | (asoc->param_flags & ~SPP_SACKDELAY) | | ||
2462 | SPP_SACKDELAY_ENABLE; | ||
2463 | } else { | ||
2464 | sp->sackfreq = params.sack_freq; | ||
2465 | sp->param_flags = | ||
2466 | (sp->param_flags & ~SPP_SACKDELAY) | | ||
2467 | SPP_SACKDELAY_ENABLE; | ||
2468 | } | ||
2385 | } | 2469 | } |
2386 | 2470 | ||
2387 | /* If change is for association, also apply to each transport. */ | 2471 | /* If change is for association, also apply to each transport. */ |
2388 | if (asoc) { | 2472 | if (asoc) { |
2389 | list_for_each_entry(trans, &asoc->peer.transport_addr_list, | 2473 | list_for_each_entry(trans, &asoc->peer.transport_addr_list, |
2390 | transports) { | 2474 | transports) { |
2391 | if (params.assoc_value) { | 2475 | if (params.sack_delay) { |
2392 | trans->sackdelay = | 2476 | trans->sackdelay = |
2393 | msecs_to_jiffies(params.assoc_value); | 2477 | msecs_to_jiffies(params.sack_delay); |
2394 | trans->param_flags = | 2478 | trans->param_flags = |
2395 | (trans->param_flags & ~SPP_SACKDELAY) | | 2479 | (trans->param_flags & ~SPP_SACKDELAY) | |
2396 | SPP_SACKDELAY_ENABLE; | 2480 | SPP_SACKDELAY_ENABLE; |
2397 | } else { | 2481 | } |
2482 | if (params.sack_freq == 1) { | ||
2398 | trans->param_flags = | 2483 | trans->param_flags = |
2399 | (trans->param_flags & ~SPP_SACKDELAY) | | 2484 | (trans->param_flags & ~SPP_SACKDELAY) | |
2400 | SPP_SACKDELAY_DISABLE; | 2485 | SPP_SACKDELAY_DISABLE; |
2486 | } else if (params.sack_freq > 1) { | ||
2487 | trans->sackfreq = params.sack_freq; | ||
2488 | trans->param_flags = | ||
2489 | (trans->param_flags & ~SPP_SACKDELAY) | | ||
2490 | SPP_SACKDELAY_ENABLE; | ||
2401 | } | 2491 | } |
2402 | } | 2492 | } |
2403 | } | 2493 | } |
@@ -3164,10 +3254,18 @@ SCTP_STATIC int sctp_setsockopt(struct sock *sk, int level, int optname, | |||
3164 | optlen, SCTP_BINDX_REM_ADDR); | 3254 | optlen, SCTP_BINDX_REM_ADDR); |
3165 | break; | 3255 | break; |
3166 | 3256 | ||
3257 | case SCTP_SOCKOPT_CONNECTX_OLD: | ||
3258 | /* 'optlen' is the size of the addresses buffer. */ | ||
3259 | retval = sctp_setsockopt_connectx_old(sk, | ||
3260 | (struct sockaddr __user *)optval, | ||
3261 | optlen); | ||
3262 | break; | ||
3263 | |||
3167 | case SCTP_SOCKOPT_CONNECTX: | 3264 | case SCTP_SOCKOPT_CONNECTX: |
3168 | /* 'optlen' is the size of the addresses buffer. */ | 3265 | /* 'optlen' is the size of the addresses buffer. */ |
3169 | retval = sctp_setsockopt_connectx(sk, (struct sockaddr __user *)optval, | 3266 | retval = sctp_setsockopt_connectx(sk, |
3170 | optlen); | 3267 | (struct sockaddr __user *)optval, |
3268 | optlen); | ||
3171 | break; | 3269 | break; |
3172 | 3270 | ||
3173 | case SCTP_DISABLE_FRAGMENTS: | 3271 | case SCTP_DISABLE_FRAGMENTS: |
@@ -3186,8 +3284,8 @@ SCTP_STATIC int sctp_setsockopt(struct sock *sk, int level, int optname, | |||
3186 | retval = sctp_setsockopt_peer_addr_params(sk, optval, optlen); | 3284 | retval = sctp_setsockopt_peer_addr_params(sk, optval, optlen); |
3187 | break; | 3285 | break; |
3188 | 3286 | ||
3189 | case SCTP_DELAYED_ACK_TIME: | 3287 | case SCTP_DELAYED_ACK: |
3190 | retval = sctp_setsockopt_delayed_ack_time(sk, optval, optlen); | 3288 | retval = sctp_setsockopt_delayed_ack(sk, optval, optlen); |
3191 | break; | 3289 | break; |
3192 | case SCTP_PARTIAL_DELIVERY_POINT: | 3290 | case SCTP_PARTIAL_DELIVERY_POINT: |
3193 | retval = sctp_setsockopt_partial_delivery_point(sk, optval, optlen); | 3291 | retval = sctp_setsockopt_partial_delivery_point(sk, optval, optlen); |
@@ -3294,7 +3392,7 @@ SCTP_STATIC int sctp_connect(struct sock *sk, struct sockaddr *addr, | |||
3294 | /* Pass correct addr len to common routine (so it knows there | 3392 | /* Pass correct addr len to common routine (so it knows there |
3295 | * is only one address being passed. | 3393 | * is only one address being passed. |
3296 | */ | 3394 | */ |
3297 | err = __sctp_connect(sk, addr, af->sockaddr_len); | 3395 | err = __sctp_connect(sk, addr, af->sockaddr_len, NULL); |
3298 | } | 3396 | } |
3299 | 3397 | ||
3300 | sctp_release_sock(sk); | 3398 | sctp_release_sock(sk); |
@@ -3446,6 +3544,7 @@ SCTP_STATIC int sctp_init_sock(struct sock *sk) | |||
3446 | sp->pathmaxrxt = sctp_max_retrans_path; | 3544 | sp->pathmaxrxt = sctp_max_retrans_path; |
3447 | sp->pathmtu = 0; // allow default discovery | 3545 | sp->pathmtu = 0; // allow default discovery |
3448 | sp->sackdelay = sctp_sack_timeout; | 3546 | sp->sackdelay = sctp_sack_timeout; |
3547 | sp->sackfreq = 2; | ||
3449 | sp->param_flags = SPP_HB_ENABLE | | 3548 | sp->param_flags = SPP_HB_ENABLE | |
3450 | SPP_PMTUD_ENABLE | | 3549 | SPP_PMTUD_ENABLE | |
3451 | SPP_SACKDELAY_ENABLE; | 3550 | SPP_SACKDELAY_ENABLE; |
@@ -3497,7 +3596,7 @@ SCTP_STATIC int sctp_init_sock(struct sock *sk) | |||
3497 | } | 3596 | } |
3498 | 3597 | ||
3499 | /* Cleanup any SCTP per socket resources. */ | 3598 | /* Cleanup any SCTP per socket resources. */ |
3500 | SCTP_STATIC int sctp_destroy_sock(struct sock *sk) | 3599 | SCTP_STATIC void sctp_destroy_sock(struct sock *sk) |
3501 | { | 3600 | { |
3502 | struct sctp_endpoint *ep; | 3601 | struct sctp_endpoint *ep; |
3503 | 3602 | ||
@@ -3507,7 +3606,6 @@ SCTP_STATIC int sctp_destroy_sock(struct sock *sk) | |||
3507 | ep = sctp_sk(sk)->ep; | 3606 | ep = sctp_sk(sk)->ep; |
3508 | sctp_endpoint_free(ep); | 3607 | sctp_endpoint_free(ep); |
3509 | atomic_dec(&sctp_sockets_allocated); | 3608 | atomic_dec(&sctp_sockets_allocated); |
3510 | return 0; | ||
3511 | } | 3609 | } |
3512 | 3610 | ||
3513 | /* API 4.1.7 shutdown() - TCP Style Syntax | 3611 | /* API 4.1.7 shutdown() - TCP Style Syntax |
@@ -3999,70 +4097,91 @@ static int sctp_getsockopt_peer_addr_params(struct sock *sk, int len, | |||
3999 | return 0; | 4097 | return 0; |
4000 | } | 4098 | } |
4001 | 4099 | ||
4002 | /* 7.1.23. Delayed Ack Timer (SCTP_DELAYED_ACK_TIME) | 4100 | /* |
4003 | * | 4101 | * 7.1.23. Get or set delayed ack timer (SCTP_DELAYED_SACK) |
4004 | * This options will get or set the delayed ack timer. The time is set | 4102 | * |
4005 | * in milliseconds. If the assoc_id is 0, then this sets or gets the | 4103 | * This option will effect the way delayed acks are performed. This |
4006 | * endpoints default delayed ack timer value. If the assoc_id field is | 4104 | * option allows you to get or set the delayed ack time, in |
4007 | * non-zero, then the set or get effects the specified association. | 4105 | * milliseconds. It also allows changing the delayed ack frequency. |
4008 | * | 4106 | * Changing the frequency to 1 disables the delayed sack algorithm. If |
4009 | * struct sctp_assoc_value { | 4107 | * the assoc_id is 0, then this sets or gets the endpoints default |
4010 | * sctp_assoc_t assoc_id; | 4108 | * values. If the assoc_id field is non-zero, then the set or get |
4011 | * uint32_t assoc_value; | 4109 | * effects the specified association for the one to many model (the |
4012 | * }; | 4110 | * assoc_id field is ignored by the one to one model). Note that if |
4111 | * sack_delay or sack_freq are 0 when setting this option, then the | ||
4112 | * current values will remain unchanged. | ||
4113 | * | ||
4114 | * struct sctp_sack_info { | ||
4115 | * sctp_assoc_t sack_assoc_id; | ||
4116 | * uint32_t sack_delay; | ||
4117 | * uint32_t sack_freq; | ||
4118 | * }; | ||
4013 | * | 4119 | * |
4014 | * assoc_id - This parameter, indicates which association the | 4120 | * sack_assoc_id - This parameter, indicates which association the user |
4015 | * user is preforming an action upon. Note that if | 4121 | * is performing an action upon. Note that if this field's value is |
4016 | * this field's value is zero then the endpoints | 4122 | * zero then the endpoints default value is changed (effecting future |
4017 | * default value is changed (effecting future | 4123 | * associations only). |
4018 | * associations only). | ||
4019 | * | 4124 | * |
4020 | * assoc_value - This parameter contains the number of milliseconds | 4125 | * sack_delay - This parameter contains the number of milliseconds that |
4021 | * that the user is requesting the delayed ACK timer | 4126 | * the user is requesting the delayed ACK timer be set to. Note that |
4022 | * be set to. Note that this value is defined in | 4127 | * this value is defined in the standard to be between 200 and 500 |
4023 | * the standard to be between 200 and 500 milliseconds. | 4128 | * milliseconds. |
4024 | * | 4129 | * |
4025 | * Note: a value of zero will leave the value alone, | 4130 | * sack_freq - This parameter contains the number of packets that must |
4026 | * but disable SACK delay. A non-zero value will also | 4131 | * be received before a sack is sent without waiting for the delay |
4027 | * enable SACK delay. | 4132 | * timer to expire. The default value for this is 2, setting this |
4133 | * value to 1 will disable the delayed sack algorithm. | ||
4028 | */ | 4134 | */ |
4029 | static int sctp_getsockopt_delayed_ack_time(struct sock *sk, int len, | 4135 | static int sctp_getsockopt_delayed_ack(struct sock *sk, int len, |
4030 | char __user *optval, | 4136 | char __user *optval, |
4031 | int __user *optlen) | 4137 | int __user *optlen) |
4032 | { | 4138 | { |
4033 | struct sctp_assoc_value params; | 4139 | struct sctp_sack_info params; |
4034 | struct sctp_association *asoc = NULL; | 4140 | struct sctp_association *asoc = NULL; |
4035 | struct sctp_sock *sp = sctp_sk(sk); | 4141 | struct sctp_sock *sp = sctp_sk(sk); |
4036 | 4142 | ||
4037 | if (len < sizeof(struct sctp_assoc_value)) | 4143 | if (len >= sizeof(struct sctp_sack_info)) { |
4038 | return - EINVAL; | 4144 | len = sizeof(struct sctp_sack_info); |
4039 | 4145 | ||
4040 | len = sizeof(struct sctp_assoc_value); | 4146 | if (copy_from_user(¶ms, optval, len)) |
4041 | 4147 | return -EFAULT; | |
4042 | if (copy_from_user(¶ms, optval, len)) | 4148 | } else if (len == sizeof(struct sctp_assoc_value)) { |
4043 | return -EFAULT; | 4149 | printk(KERN_WARNING "SCTP: Use of struct sctp_sack_info " |
4150 | "in delayed_ack socket option deprecated\n"); | ||
4151 | printk(KERN_WARNING "SCTP: struct sctp_sack_info instead\n"); | ||
4152 | if (copy_from_user(¶ms, optval, len)) | ||
4153 | return -EFAULT; | ||
4154 | } else | ||
4155 | return - EINVAL; | ||
4044 | 4156 | ||
4045 | /* Get association, if assoc_id != 0 and the socket is a one | 4157 | /* Get association, if sack_assoc_id != 0 and the socket is a one |
4046 | * to many style socket, and an association was not found, then | 4158 | * to many style socket, and an association was not found, then |
4047 | * the id was invalid. | 4159 | * the id was invalid. |
4048 | */ | 4160 | */ |
4049 | asoc = sctp_id2assoc(sk, params.assoc_id); | 4161 | asoc = sctp_id2assoc(sk, params.sack_assoc_id); |
4050 | if (!asoc && params.assoc_id && sctp_style(sk, UDP)) | 4162 | if (!asoc && params.sack_assoc_id && sctp_style(sk, UDP)) |
4051 | return -EINVAL; | 4163 | return -EINVAL; |
4052 | 4164 | ||
4053 | if (asoc) { | 4165 | if (asoc) { |
4054 | /* Fetch association values. */ | 4166 | /* Fetch association values. */ |
4055 | if (asoc->param_flags & SPP_SACKDELAY_ENABLE) | 4167 | if (asoc->param_flags & SPP_SACKDELAY_ENABLE) { |
4056 | params.assoc_value = jiffies_to_msecs( | 4168 | params.sack_delay = jiffies_to_msecs( |
4057 | asoc->sackdelay); | 4169 | asoc->sackdelay); |
4058 | else | 4170 | params.sack_freq = asoc->sackfreq; |
4059 | params.assoc_value = 0; | 4171 | |
4172 | } else { | ||
4173 | params.sack_delay = 0; | ||
4174 | params.sack_freq = 1; | ||
4175 | } | ||
4060 | } else { | 4176 | } else { |
4061 | /* Fetch socket values. */ | 4177 | /* Fetch socket values. */ |
4062 | if (sp->param_flags & SPP_SACKDELAY_ENABLE) | 4178 | if (sp->param_flags & SPP_SACKDELAY_ENABLE) { |
4063 | params.assoc_value = sp->sackdelay; | 4179 | params.sack_delay = sp->sackdelay; |
4064 | else | 4180 | params.sack_freq = sp->sackfreq; |
4065 | params.assoc_value = 0; | 4181 | } else { |
4182 | params.sack_delay = 0; | ||
4183 | params.sack_freq = 1; | ||
4184 | } | ||
4066 | } | 4185 | } |
4067 | 4186 | ||
4068 | if (copy_to_user(optval, ¶ms, len)) | 4187 | if (copy_to_user(optval, ¶ms, len)) |
@@ -4112,6 +4231,8 @@ static int sctp_getsockopt_peer_addrs_num_old(struct sock *sk, int len, | |||
4112 | if (copy_from_user(&id, optval, sizeof(sctp_assoc_t))) | 4231 | if (copy_from_user(&id, optval, sizeof(sctp_assoc_t))) |
4113 | return -EFAULT; | 4232 | return -EFAULT; |
4114 | 4233 | ||
4234 | printk(KERN_WARNING "SCTP: Use of SCTP_GET_PEER_ADDRS_NUM_OLD " | ||
4235 | "socket option deprecated\n"); | ||
4115 | /* For UDP-style sockets, id specifies the association to query. */ | 4236 | /* For UDP-style sockets, id specifies the association to query. */ |
4116 | asoc = sctp_id2assoc(sk, id); | 4237 | asoc = sctp_id2assoc(sk, id); |
4117 | if (!asoc) | 4238 | if (!asoc) |
@@ -4151,6 +4272,9 @@ static int sctp_getsockopt_peer_addrs_old(struct sock *sk, int len, | |||
4151 | 4272 | ||
4152 | if (getaddrs.addr_num <= 0) return -EINVAL; | 4273 | if (getaddrs.addr_num <= 0) return -EINVAL; |
4153 | 4274 | ||
4275 | printk(KERN_WARNING "SCTP: Use of SCTP_GET_PEER_ADDRS_OLD " | ||
4276 | "socket option deprecated\n"); | ||
4277 | |||
4154 | /* For UDP-style sockets, id specifies the association to query. */ | 4278 | /* For UDP-style sockets, id specifies the association to query. */ |
4155 | asoc = sctp_id2assoc(sk, getaddrs.assoc_id); | 4279 | asoc = sctp_id2assoc(sk, getaddrs.assoc_id); |
4156 | if (!asoc) | 4280 | if (!asoc) |
@@ -4244,6 +4368,9 @@ static int sctp_getsockopt_local_addrs_num_old(struct sock *sk, int len, | |||
4244 | if (copy_from_user(&id, optval, sizeof(sctp_assoc_t))) | 4368 | if (copy_from_user(&id, optval, sizeof(sctp_assoc_t))) |
4245 | return -EFAULT; | 4369 | return -EFAULT; |
4246 | 4370 | ||
4371 | printk(KERN_WARNING "SCTP: Use of SCTP_GET_LOCAL_ADDRS_NUM_OLD " | ||
4372 | "socket option deprecated\n"); | ||
4373 | |||
4247 | /* | 4374 | /* |
4248 | * For UDP-style sockets, id specifies the association to query. | 4375 | * For UDP-style sockets, id specifies the association to query. |
4249 | * If the id field is set to the value '0' then the locally bound | 4376 | * If the id field is set to the value '0' then the locally bound |
@@ -4276,6 +4403,11 @@ static int sctp_getsockopt_local_addrs_num_old(struct sock *sk, int len, | |||
4276 | (AF_INET6 == addr->a.sa.sa_family)) | 4403 | (AF_INET6 == addr->a.sa.sa_family)) |
4277 | continue; | 4404 | continue; |
4278 | 4405 | ||
4406 | if ((PF_INET6 == sk->sk_family) && | ||
4407 | inet_v6_ipv6only(sk) && | ||
4408 | (AF_INET == addr->a.sa.sa_family)) | ||
4409 | continue; | ||
4410 | |||
4279 | cnt++; | 4411 | cnt++; |
4280 | } | 4412 | } |
4281 | rcu_read_unlock(); | 4413 | rcu_read_unlock(); |
@@ -4316,6 +4448,10 @@ static int sctp_copy_laddrs_old(struct sock *sk, __u16 port, | |||
4316 | if ((PF_INET == sk->sk_family) && | 4448 | if ((PF_INET == sk->sk_family) && |
4317 | (AF_INET6 == addr->a.sa.sa_family)) | 4449 | (AF_INET6 == addr->a.sa.sa_family)) |
4318 | continue; | 4450 | continue; |
4451 | if ((PF_INET6 == sk->sk_family) && | ||
4452 | inet_v6_ipv6only(sk) && | ||
4453 | (AF_INET == addr->a.sa.sa_family)) | ||
4454 | continue; | ||
4319 | memcpy(&temp, &addr->a, sizeof(temp)); | 4455 | memcpy(&temp, &addr->a, sizeof(temp)); |
4320 | if (!temp.v4.sin_port) | 4456 | if (!temp.v4.sin_port) |
4321 | temp.v4.sin_port = htons(port); | 4457 | temp.v4.sin_port = htons(port); |
@@ -4351,6 +4487,10 @@ static int sctp_copy_laddrs(struct sock *sk, __u16 port, void *to, | |||
4351 | if ((PF_INET == sk->sk_family) && | 4487 | if ((PF_INET == sk->sk_family) && |
4352 | (AF_INET6 == addr->a.sa.sa_family)) | 4488 | (AF_INET6 == addr->a.sa.sa_family)) |
4353 | continue; | 4489 | continue; |
4490 | if ((PF_INET6 == sk->sk_family) && | ||
4491 | inet_v6_ipv6only(sk) && | ||
4492 | (AF_INET == addr->a.sa.sa_family)) | ||
4493 | continue; | ||
4354 | memcpy(&temp, &addr->a, sizeof(temp)); | 4494 | memcpy(&temp, &addr->a, sizeof(temp)); |
4355 | if (!temp.v4.sin_port) | 4495 | if (!temp.v4.sin_port) |
4356 | temp.v4.sin_port = htons(port); | 4496 | temp.v4.sin_port = htons(port); |
@@ -4404,6 +4544,10 @@ static int sctp_getsockopt_local_addrs_old(struct sock *sk, int len, | |||
4404 | if (getaddrs.addr_num <= 0 || | 4544 | if (getaddrs.addr_num <= 0 || |
4405 | getaddrs.addr_num >= (INT_MAX / sizeof(union sctp_addr))) | 4545 | getaddrs.addr_num >= (INT_MAX / sizeof(union sctp_addr))) |
4406 | return -EINVAL; | 4546 | return -EINVAL; |
4547 | |||
4548 | printk(KERN_WARNING "SCTP: Use of SCTP_GET_LOCAL_ADDRS_OLD " | ||
4549 | "socket option deprecated\n"); | ||
4550 | |||
4407 | /* | 4551 | /* |
4408 | * For UDP-style sockets, id specifies the association to query. | 4552 | * For UDP-style sockets, id specifies the association to query. |
4409 | * If the id field is set to the value '0' then the locally bound | 4553 | * If the id field is set to the value '0' then the locally bound |
@@ -5220,8 +5364,8 @@ SCTP_STATIC int sctp_getsockopt(struct sock *sk, int level, int optname, | |||
5220 | retval = sctp_getsockopt_peer_addr_params(sk, len, optval, | 5364 | retval = sctp_getsockopt_peer_addr_params(sk, len, optval, |
5221 | optlen); | 5365 | optlen); |
5222 | break; | 5366 | break; |
5223 | case SCTP_DELAYED_ACK_TIME: | 5367 | case SCTP_DELAYED_ACK: |
5224 | retval = sctp_getsockopt_delayed_ack_time(sk, len, optval, | 5368 | retval = sctp_getsockopt_delayed_ack(sk, len, optval, |
5225 | optlen); | 5369 | optlen); |
5226 | break; | 5370 | break; |
5227 | case SCTP_INITMSG: | 5371 | case SCTP_INITMSG: |
@@ -5441,12 +5585,13 @@ pp_found: | |||
5441 | struct sctp_endpoint *ep2; | 5585 | struct sctp_endpoint *ep2; |
5442 | ep2 = sctp_sk(sk2)->ep; | 5586 | ep2 = sctp_sk(sk2)->ep; |
5443 | 5587 | ||
5444 | if (reuse && sk2->sk_reuse && | 5588 | if (sk == sk2 || |
5445 | sk2->sk_state != SCTP_SS_LISTENING) | 5589 | (reuse && sk2->sk_reuse && |
5590 | sk2->sk_state != SCTP_SS_LISTENING)) | ||
5446 | continue; | 5591 | continue; |
5447 | 5592 | ||
5448 | if (sctp_bind_addr_match(&ep2->base.bind_addr, addr, | 5593 | if (sctp_bind_addr_conflict(&ep2->base.bind_addr, addr, |
5449 | sctp_sk(sk))) { | 5594 | sctp_sk(sk2), sctp_sk(sk))) { |
5450 | ret = (long)sk2; | 5595 | ret = (long)sk2; |
5451 | goto fail_unlock; | 5596 | goto fail_unlock; |
5452 | } | 5597 | } |
@@ -5559,8 +5704,13 @@ SCTP_STATIC int sctp_seqpacket_listen(struct sock *sk, int backlog) | |||
5559 | if (!ep->base.bind_addr.port) { | 5704 | if (!ep->base.bind_addr.port) { |
5560 | if (sctp_autobind(sk)) | 5705 | if (sctp_autobind(sk)) |
5561 | return -EAGAIN; | 5706 | return -EAGAIN; |
5562 | } else | 5707 | } else { |
5708 | if (sctp_get_port(sk, inet_sk(sk)->num)) { | ||
5709 | sk->sk_state = SCTP_SS_CLOSED; | ||
5710 | return -EADDRINUSE; | ||
5711 | } | ||
5563 | sctp_sk(sk)->bind_hash->fastreuse = 0; | 5712 | sctp_sk(sk)->bind_hash->fastreuse = 0; |
5713 | } | ||
5564 | 5714 | ||
5565 | sctp_hash_endpoint(ep); | 5715 | sctp_hash_endpoint(ep); |
5566 | return 0; | 5716 | return 0; |
@@ -5630,7 +5780,7 @@ int sctp_inet_listen(struct socket *sock, int backlog) | |||
5630 | goto out; | 5780 | goto out; |
5631 | 5781 | ||
5632 | /* Allocate HMAC for generating cookie. */ | 5782 | /* Allocate HMAC for generating cookie. */ |
5633 | if (sctp_hmac_alg) { | 5783 | if (!sctp_sk(sk)->hmac && sctp_hmac_alg) { |
5634 | tfm = crypto_alloc_hash(sctp_hmac_alg, 0, CRYPTO_ALG_ASYNC); | 5784 | tfm = crypto_alloc_hash(sctp_hmac_alg, 0, CRYPTO_ALG_ASYNC); |
5635 | if (IS_ERR(tfm)) { | 5785 | if (IS_ERR(tfm)) { |
5636 | if (net_ratelimit()) { | 5786 | if (net_ratelimit()) { |
@@ -5658,7 +5808,8 @@ int sctp_inet_listen(struct socket *sock, int backlog) | |||
5658 | goto cleanup; | 5808 | goto cleanup; |
5659 | 5809 | ||
5660 | /* Store away the transform reference. */ | 5810 | /* Store away the transform reference. */ |
5661 | sctp_sk(sk)->hmac = tfm; | 5811 | if (!sctp_sk(sk)->hmac) |
5812 | sctp_sk(sk)->hmac = tfm; | ||
5662 | out: | 5813 | out: |
5663 | sctp_release_sock(sk); | 5814 | sctp_release_sock(sk); |
5664 | return err; | 5815 | return err; |
diff --git a/net/sctp/transport.c b/net/sctp/transport.c index 3f34f61221ec..e745c118f239 100644 --- a/net/sctp/transport.c +++ b/net/sctp/transport.c | |||
@@ -100,6 +100,9 @@ static struct sctp_transport *sctp_transport_init(struct sctp_transport *peer, | |||
100 | INIT_LIST_HEAD(&peer->send_ready); | 100 | INIT_LIST_HEAD(&peer->send_ready); |
101 | INIT_LIST_HEAD(&peer->transports); | 101 | INIT_LIST_HEAD(&peer->transports); |
102 | 102 | ||
103 | peer->T3_rtx_timer.expires = 0; | ||
104 | peer->hb_timer.expires = 0; | ||
105 | |||
103 | setup_timer(&peer->T3_rtx_timer, sctp_generate_t3_rtx_event, | 106 | setup_timer(&peer->T3_rtx_timer, sctp_generate_t3_rtx_event, |
104 | (unsigned long)peer); | 107 | (unsigned long)peer); |
105 | setup_timer(&peer->hb_timer, sctp_generate_heartbeat_event, | 108 | setup_timer(&peer->hb_timer, sctp_generate_heartbeat_event, |