diff options
Diffstat (limited to 'net/sctp')
| -rw-r--r-- | net/sctp/bind_addr.c | 1 | ||||
| -rw-r--r-- | net/sctp/input.c | 42 | ||||
| -rw-r--r-- | net/sctp/ipv6.c | 1 | ||||
| -rw-r--r-- | net/sctp/proc.c | 4 | ||||
| -rw-r--r-- | net/sctp/protocol.c | 6 | ||||
| -rw-r--r-- | net/sctp/sm_sideeffect.c | 2 | ||||
| -rw-r--r-- | net/sctp/socket.c | 5 |
7 files changed, 37 insertions, 24 deletions
diff --git a/net/sctp/bind_addr.c b/net/sctp/bind_addr.c index 13a6fba41077..bef133731683 100644 --- a/net/sctp/bind_addr.c +++ b/net/sctp/bind_addr.c | |||
| @@ -186,7 +186,6 @@ int sctp_add_bind_addr(struct sctp_bind_addr *bp, union sctp_addr *new, | |||
| 186 | addr->valid = 1; | 186 | addr->valid = 1; |
| 187 | 187 | ||
| 188 | INIT_LIST_HEAD(&addr->list); | 188 | INIT_LIST_HEAD(&addr->list); |
| 189 | INIT_RCU_HEAD(&addr->rcu); | ||
| 190 | 189 | ||
| 191 | /* We always hold a socket lock when calling this function, | 190 | /* We always hold a socket lock when calling this function, |
| 192 | * and that acts as a writer synchronizing lock. | 191 | * and that acts as a writer synchronizing lock. |
diff --git a/net/sctp/input.c b/net/sctp/input.c index c0c973e67add..3d74b264ea22 100644 --- a/net/sctp/input.c +++ b/net/sctp/input.c | |||
| @@ -75,7 +75,7 @@ static struct sctp_association *__sctp_lookup_association( | |||
| 75 | const union sctp_addr *peer, | 75 | const union sctp_addr *peer, |
| 76 | struct sctp_transport **pt); | 76 | struct sctp_transport **pt); |
| 77 | 77 | ||
| 78 | static void sctp_add_backlog(struct sock *sk, struct sk_buff *skb); | 78 | static int sctp_add_backlog(struct sock *sk, struct sk_buff *skb); |
| 79 | 79 | ||
| 80 | 80 | ||
| 81 | /* Calculate the SCTP checksum of an SCTP packet. */ | 81 | /* Calculate the SCTP checksum of an SCTP packet. */ |
| @@ -265,8 +265,13 @@ int sctp_rcv(struct sk_buff *skb) | |||
| 265 | } | 265 | } |
| 266 | 266 | ||
| 267 | if (sock_owned_by_user(sk)) { | 267 | if (sock_owned_by_user(sk)) { |
| 268 | if (sctp_add_backlog(sk, skb)) { | ||
| 269 | sctp_bh_unlock_sock(sk); | ||
| 270 | sctp_chunk_free(chunk); | ||
| 271 | skb = NULL; /* sctp_chunk_free already freed the skb */ | ||
| 272 | goto discard_release; | ||
| 273 | } | ||
| 268 | SCTP_INC_STATS_BH(SCTP_MIB_IN_PKT_BACKLOG); | 274 | SCTP_INC_STATS_BH(SCTP_MIB_IN_PKT_BACKLOG); |
| 269 | sctp_add_backlog(sk, skb); | ||
| 270 | } else { | 275 | } else { |
| 271 | SCTP_INC_STATS_BH(SCTP_MIB_IN_PKT_SOFTIRQ); | 276 | SCTP_INC_STATS_BH(SCTP_MIB_IN_PKT_SOFTIRQ); |
| 272 | sctp_inq_push(&chunk->rcvr->inqueue, chunk); | 277 | sctp_inq_push(&chunk->rcvr->inqueue, chunk); |
| @@ -336,8 +341,10 @@ int sctp_backlog_rcv(struct sock *sk, struct sk_buff *skb) | |||
| 336 | sctp_bh_lock_sock(sk); | 341 | sctp_bh_lock_sock(sk); |
| 337 | 342 | ||
| 338 | if (sock_owned_by_user(sk)) { | 343 | if (sock_owned_by_user(sk)) { |
| 339 | sk_add_backlog(sk, skb); | 344 | if (sk_add_backlog(sk, skb)) |
| 340 | backloged = 1; | 345 | sctp_chunk_free(chunk); |
| 346 | else | ||
| 347 | backloged = 1; | ||
| 341 | } else | 348 | } else |
| 342 | sctp_inq_push(inqueue, chunk); | 349 | sctp_inq_push(inqueue, chunk); |
| 343 | 350 | ||
| @@ -362,22 +369,27 @@ done: | |||
| 362 | return 0; | 369 | return 0; |
| 363 | } | 370 | } |
| 364 | 371 | ||
| 365 | static void sctp_add_backlog(struct sock *sk, struct sk_buff *skb) | 372 | static int sctp_add_backlog(struct sock *sk, struct sk_buff *skb) |
| 366 | { | 373 | { |
| 367 | struct sctp_chunk *chunk = SCTP_INPUT_CB(skb)->chunk; | 374 | struct sctp_chunk *chunk = SCTP_INPUT_CB(skb)->chunk; |
| 368 | struct sctp_ep_common *rcvr = chunk->rcvr; | 375 | struct sctp_ep_common *rcvr = chunk->rcvr; |
| 376 | int ret; | ||
| 369 | 377 | ||
| 370 | /* Hold the assoc/ep while hanging on the backlog queue. | 378 | ret = sk_add_backlog(sk, skb); |
| 371 | * This way, we know structures we need will not disappear from us | 379 | if (!ret) { |
| 372 | */ | 380 | /* Hold the assoc/ep while hanging on the backlog queue. |
| 373 | if (SCTP_EP_TYPE_ASSOCIATION == rcvr->type) | 381 | * This way, we know structures we need will not disappear |
| 374 | sctp_association_hold(sctp_assoc(rcvr)); | 382 | * from us |
| 375 | else if (SCTP_EP_TYPE_SOCKET == rcvr->type) | 383 | */ |
| 376 | sctp_endpoint_hold(sctp_ep(rcvr)); | 384 | if (SCTP_EP_TYPE_ASSOCIATION == rcvr->type) |
| 377 | else | 385 | sctp_association_hold(sctp_assoc(rcvr)); |
| 378 | BUG(); | 386 | else if (SCTP_EP_TYPE_SOCKET == rcvr->type) |
| 387 | sctp_endpoint_hold(sctp_ep(rcvr)); | ||
| 388 | else | ||
| 389 | BUG(); | ||
| 390 | } | ||
| 391 | return ret; | ||
| 379 | 392 | ||
| 380 | sk_add_backlog(sk, skb); | ||
| 381 | } | 393 | } |
| 382 | 394 | ||
| 383 | /* Handle icmp frag needed error. */ | 395 | /* Handle icmp frag needed error. */ |
diff --git a/net/sctp/ipv6.c b/net/sctp/ipv6.c index cc50fbe99291..1d7ac70ba39f 100644 --- a/net/sctp/ipv6.c +++ b/net/sctp/ipv6.c | |||
| @@ -381,7 +381,6 @@ static void sctp_v6_copy_addrlist(struct list_head *addrlist, | |||
| 381 | addr->a.v6.sin6_scope_id = dev->ifindex; | 381 | addr->a.v6.sin6_scope_id = dev->ifindex; |
| 382 | addr->valid = 1; | 382 | addr->valid = 1; |
| 383 | INIT_LIST_HEAD(&addr->list); | 383 | INIT_LIST_HEAD(&addr->list); |
| 384 | INIT_RCU_HEAD(&addr->rcu); | ||
| 385 | list_add_tail(&addr->list, addrlist); | 384 | list_add_tail(&addr->list, addrlist); |
| 386 | } | 385 | } |
| 387 | } | 386 | } |
diff --git a/net/sctp/proc.c b/net/sctp/proc.c index d093cbfeaac4..784bcc9a979d 100644 --- a/net/sctp/proc.c +++ b/net/sctp/proc.c | |||
| @@ -40,7 +40,7 @@ | |||
| 40 | #include <net/sctp/sctp.h> | 40 | #include <net/sctp/sctp.h> |
| 41 | #include <net/ip.h> /* for snmp_fold_field */ | 41 | #include <net/ip.h> /* for snmp_fold_field */ |
| 42 | 42 | ||
| 43 | static struct snmp_mib sctp_snmp_list[] = { | 43 | static const struct snmp_mib sctp_snmp_list[] = { |
| 44 | SNMP_MIB_ITEM("SctpCurrEstab", SCTP_MIB_CURRESTAB), | 44 | SNMP_MIB_ITEM("SctpCurrEstab", SCTP_MIB_CURRESTAB), |
| 45 | SNMP_MIB_ITEM("SctpActiveEstabs", SCTP_MIB_ACTIVEESTABS), | 45 | SNMP_MIB_ITEM("SctpActiveEstabs", SCTP_MIB_ACTIVEESTABS), |
| 46 | SNMP_MIB_ITEM("SctpPassiveEstabs", SCTP_MIB_PASSIVEESTABS), | 46 | SNMP_MIB_ITEM("SctpPassiveEstabs", SCTP_MIB_PASSIVEESTABS), |
| @@ -83,7 +83,7 @@ static int sctp_snmp_seq_show(struct seq_file *seq, void *v) | |||
| 83 | 83 | ||
| 84 | for (i = 0; sctp_snmp_list[i].name != NULL; i++) | 84 | for (i = 0; sctp_snmp_list[i].name != NULL; i++) |
| 85 | seq_printf(seq, "%-32s\t%ld\n", sctp_snmp_list[i].name, | 85 | seq_printf(seq, "%-32s\t%ld\n", sctp_snmp_list[i].name, |
| 86 | snmp_fold_field((void **)sctp_statistics, | 86 | snmp_fold_field((void __percpu **)sctp_statistics, |
| 87 | sctp_snmp_list[i].entry)); | 87 | sctp_snmp_list[i].entry)); |
| 88 | 88 | ||
| 89 | return 0; | 89 | return 0; |
diff --git a/net/sctp/protocol.c b/net/sctp/protocol.c index a3c8988758b1..e771690f6d5d 100644 --- a/net/sctp/protocol.c +++ b/net/sctp/protocol.c | |||
| @@ -188,7 +188,6 @@ static void sctp_v4_copy_addrlist(struct list_head *addrlist, | |||
| 188 | addr->a.v4.sin_addr.s_addr = ifa->ifa_local; | 188 | addr->a.v4.sin_addr.s_addr = ifa->ifa_local; |
| 189 | addr->valid = 1; | 189 | addr->valid = 1; |
| 190 | INIT_LIST_HEAD(&addr->list); | 190 | INIT_LIST_HEAD(&addr->list); |
| 191 | INIT_RCU_HEAD(&addr->rcu); | ||
| 192 | list_add_tail(&addr->list, addrlist); | 191 | list_add_tail(&addr->list, addrlist); |
| 193 | } | 192 | } |
| 194 | } | 193 | } |
| @@ -996,12 +995,13 @@ int sctp_register_pf(struct sctp_pf *pf, sa_family_t family) | |||
| 996 | 995 | ||
| 997 | static inline int init_sctp_mibs(void) | 996 | static inline int init_sctp_mibs(void) |
| 998 | { | 997 | { |
| 999 | return snmp_mib_init((void**)sctp_statistics, sizeof(struct sctp_mib)); | 998 | return snmp_mib_init((void __percpu **)sctp_statistics, |
| 999 | sizeof(struct sctp_mib)); | ||
| 1000 | } | 1000 | } |
| 1001 | 1001 | ||
| 1002 | static inline void cleanup_sctp_mibs(void) | 1002 | static inline void cleanup_sctp_mibs(void) |
| 1003 | { | 1003 | { |
| 1004 | snmp_mib_free((void**)sctp_statistics); | 1004 | snmp_mib_free((void __percpu **)sctp_statistics); |
| 1005 | } | 1005 | } |
| 1006 | 1006 | ||
| 1007 | static void sctp_v4_pf_init(void) | 1007 | static void sctp_v4_pf_init(void) |
diff --git a/net/sctp/sm_sideeffect.c b/net/sctp/sm_sideeffect.c index 4e4ca65cd320..500886bda9b4 100644 --- a/net/sctp/sm_sideeffect.c +++ b/net/sctp/sm_sideeffect.c | |||
| @@ -475,7 +475,7 @@ static void sctp_do_8_2_transport_strike(struct sctp_association *asoc, | |||
| 475 | * used to provide an upper bound to this doubling operation. | 475 | * used to provide an upper bound to this doubling operation. |
| 476 | * | 476 | * |
| 477 | * Special Case: the first HB doesn't trigger exponential backoff. | 477 | * Special Case: the first HB doesn't trigger exponential backoff. |
| 478 | * The first unacknowleged HB triggers it. We do this with a flag | 478 | * The first unacknowledged HB triggers it. We do this with a flag |
| 479 | * that indicates that we have an outstanding HB. | 479 | * that indicates that we have an outstanding HB. |
| 480 | */ | 480 | */ |
| 481 | if (!is_hb || transport->hb_sent) { | 481 | if (!is_hb || transport->hb_sent) { |
diff --git a/net/sctp/socket.c b/net/sctp/socket.c index 67fdac9d2d33..dfc5c127efd4 100644 --- a/net/sctp/socket.c +++ b/net/sctp/socket.c | |||
| @@ -3720,6 +3720,9 @@ SCTP_STATIC int sctp_init_sock(struct sock *sk) | |||
| 3720 | SCTP_DBG_OBJCNT_INC(sock); | 3720 | SCTP_DBG_OBJCNT_INC(sock); |
| 3721 | percpu_counter_inc(&sctp_sockets_allocated); | 3721 | percpu_counter_inc(&sctp_sockets_allocated); |
| 3722 | 3722 | ||
| 3723 | /* Set socket backlog limit. */ | ||
| 3724 | sk->sk_backlog.limit = sysctl_sctp_rmem[1]; | ||
| 3725 | |||
| 3723 | local_bh_disable(); | 3726 | local_bh_disable(); |
| 3724 | sock_prot_inuse_add(sock_net(sk), sk->sk_prot, 1); | 3727 | sock_prot_inuse_add(sock_net(sk), sk->sk_prot, 1); |
| 3725 | local_bh_enable(); | 3728 | local_bh_enable(); |
| @@ -6359,7 +6362,7 @@ void sctp_copy_sock(struct sock *newsk, struct sock *sk, | |||
| 6359 | struct sctp_association *asoc) | 6362 | struct sctp_association *asoc) |
| 6360 | { | 6363 | { |
| 6361 | struct inet_sock *inet = inet_sk(sk); | 6364 | struct inet_sock *inet = inet_sk(sk); |
| 6362 | struct inet_sock *newinet = inet_sk(newsk); | 6365 | struct inet_sock *newinet; |
| 6363 | 6366 | ||
| 6364 | newsk->sk_type = sk->sk_type; | 6367 | newsk->sk_type = sk->sk_type; |
| 6365 | newsk->sk_bound_dev_if = sk->sk_bound_dev_if; | 6368 | newsk->sk_bound_dev_if = sk->sk_bound_dev_if; |
