From 173372162ddbd414cc471c1a3a52ad7ea279aaf4 Mon Sep 17 00:00:00 2001 From: Vladislav Yasevich Date: Thu, 28 Apr 2005 11:57:54 -0700 Subject: [SCTP] Fix SCTP_ASSOCINFO getsockopt for 1-1 style Signed-off-by: Vladislav Yasevich Signed-off-by: Sridhar Samudrala Signed-off-by: David S. Miller --- net/sctp/socket.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'net/sctp') diff --git a/net/sctp/socket.c b/net/sctp/socket.c index e8c21018257..32f2249411f 100644 --- a/net/sctp/socket.c +++ b/net/sctp/socket.c @@ -3473,7 +3473,7 @@ static int sctp_getsockopt_associnfo(struct sock *sk, int len, return -EINVAL; /* Values correspoinding to the specific association */ - if (assocparams.sasoc_assoc_id != 0) { + if (asoc) { assocparams.sasoc_asocmaxrxt = asoc->max_retrans; assocparams.sasoc_peer_rwnd = asoc->peer.rwnd; assocparams.sasoc_local_rwnd = asoc->a_rwnd; -- cgit v1.2.3 From 047a2428a14216a83980ed26b6a59b3ca40a1fb0 Mon Sep 17 00:00:00 2001 From: Jerome Forissier Date: Thu, 28 Apr 2005 11:58:43 -0700 Subject: [SCTP] Implement Sec 2.41 of SCTP Implementers guide. - Fixed sctp_vtag_verify_either() to comply with impguide 2.41 B) and C). - Make sure vtag is reflected when T-bit is set in SHUTDOWN-COMPLETE sent due to an OOTB SHUTDOWN-ACK and in ABORT sent due to an OOTB packet. - Do not set T-Bit in ABORT chunk in response to INIT. - Fixed some comments to reflect the new meaning of the T-Bit. Signed-off-by: Jerome Forissier Signed-off-by: Sridhar Samudrala Signed-off-by: David S. Miller --- net/sctp/sm_make_chunk.c | 19 ++++++++---- net/sctp/sm_statefuns.c | 77 ++++++++++++++++++++++++++++++------------------ 2 files changed, 62 insertions(+), 34 deletions(-) (limited to 'net/sctp') diff --git a/net/sctp/sm_make_chunk.c b/net/sctp/sm_make_chunk.c index 1db12cc18cf..33ac8bf47b0 100644 --- a/net/sctp/sm_make_chunk.c +++ b/net/sctp/sm_make_chunk.c @@ -710,7 +710,9 @@ struct sctp_chunk *sctp_make_shutdown_complete( struct sctp_chunk *retval; __u8 flags = 0; - /* Maybe set the T-bit if we have no association. */ + /* Set the T-bit if we have no association (vtag will be + * reflected) + */ flags |= asoc ? 0 : SCTP_CHUNK_FLAG_T; retval = sctp_make_chunk(asoc, SCTP_CID_SHUTDOWN_COMPLETE, flags, 0); @@ -732,7 +734,7 @@ struct sctp_chunk *sctp_make_shutdown_complete( } /* Create an ABORT. Note that we set the T bit if we have no - * association. + * association, except when responding to an INIT (sctpimpguide 2.41). */ struct sctp_chunk *sctp_make_abort(const struct sctp_association *asoc, const struct sctp_chunk *chunk, @@ -741,8 +743,16 @@ struct sctp_chunk *sctp_make_abort(const struct sctp_association *asoc, struct sctp_chunk *retval; __u8 flags = 0; - /* Maybe set the T-bit if we have no association. */ - flags |= asoc ? 0 : SCTP_CHUNK_FLAG_T; + /* Set the T-bit if we have no association and 'chunk' is not + * an INIT (vtag will be reflected). + */ + if (!asoc) { + if (chunk && chunk->chunk_hdr && + chunk->chunk_hdr->type == SCTP_CID_INIT) + flags = 0; + else + flags = SCTP_CHUNK_FLAG_T; + } retval = sctp_make_chunk(asoc, SCTP_CID_ABORT, flags, hint); @@ -2744,7 +2754,6 @@ struct sctp_chunk *sctp_make_fwdtsn(const struct sctp_association *asoc, hint = (nstreams + 1) * sizeof(__u32); - /* Maybe set the T-bit if we have no association. */ retval = sctp_make_chunk(asoc, SCTP_CID_FWD_TSN, 0, hint); if (!retval) diff --git a/net/sctp/sm_statefuns.c b/net/sctp/sm_statefuns.c index 278c56a2d07..8e01b8f09ac 100644 --- a/net/sctp/sm_statefuns.c +++ b/net/sctp/sm_statefuns.c @@ -126,15 +126,18 @@ sctp_chunk_length_valid(struct sctp_chunk *chunk, * should stop the T2-shutdown timer and remove all knowledge of the * association (and thus the association enters the CLOSED state). * - * Verification Tag: 8.5.1(C) + * Verification Tag: 8.5.1(C), sctpimpguide 2.41. * C) Rules for packet carrying SHUTDOWN COMPLETE: * ... - * - The receiver of a SHUTDOWN COMPLETE shall accept the packet if the - * Verification Tag field of the packet matches its own tag OR it is - * set to its peer's tag and the T bit is set in the Chunk Flags. - * Otherwise, the receiver MUST silently discard the packet and take - * no further action. An endpoint MUST ignore the SHUTDOWN COMPLETE if - * it is not in the SHUTDOWN-ACK-SENT state. + * - The receiver of a SHUTDOWN COMPLETE shall accept the packet + * if the Verification Tag field of the packet matches its own tag and + * the T bit is not set + * OR + * it is set to its peer's tag and the T bit is set in the Chunk + * Flags. + * Otherwise, the receiver MUST silently discard the packet + * and take no further action. An endpoint MUST ignore the + * SHUTDOWN COMPLETE if it is not in the SHUTDOWN-ACK-SENT state. * * Inputs * (endpoint, asoc, chunk) @@ -2858,16 +2861,16 @@ sctp_disposition_t sctp_sf_eat_sack_6_2(const struct sctp_endpoint *ep, /* * Generate an ABORT in response to a packet. * - * Section: 8.4 Handle "Out of the blue" Packets + * Section: 8.4 Handle "Out of the blue" Packets, sctpimpguide 2.41 * - * 8) The receiver should respond to the sender of the OOTB packet - * with an ABORT. When sending the ABORT, the receiver of the - * OOTB packet MUST fill in the Verification Tag field of the - * outbound packet with the value found in the Verification Tag - * field of the OOTB packet and set the T-bit in the Chunk Flags - * to indicate that no TCB was found. After sending this ABORT, - * the receiver of the OOTB packet shall discard the OOTB packet - * and take no further action. + * 8) The receiver should respond to the sender of the OOTB packet with + * an ABORT. When sending the ABORT, the receiver of the OOTB packet + * MUST fill in the Verification Tag field of the outbound packet + * with the value found in the Verification Tag field of the OOTB + * packet and set the T-bit in the Chunk Flags to indicate that the + * Verification Tag is reflected. After sending this ABORT, the + * receiver of the OOTB packet shall discard the OOTB packet and take + * no further action. * * Verification Tag: * @@ -2895,6 +2898,10 @@ sctp_disposition_t sctp_sf_tabort_8_4_8(const struct sctp_endpoint *ep, return SCTP_DISPOSITION_NOMEM; } + /* Reflect vtag if T-Bit is set */ + if (sctp_test_T_bit(abort)) + packet->vtag = ntohl(chunk->sctp_hdr->vtag); + /* Set the skb to the belonging sock for accounting. */ abort->skb->sk = ep->base.sk; @@ -3026,22 +3033,24 @@ nomem: } /* - * RFC 2960, 8.4 - Handle "Out of the blue" Packets + * RFC 2960, 8.4 - Handle "Out of the blue" Packets, sctpimpguide 2.41. + * * 5) If the packet contains a SHUTDOWN ACK chunk, the receiver should * respond to the sender of the OOTB packet with a SHUTDOWN COMPLETE. * When sending the SHUTDOWN COMPLETE, the receiver of the OOTB * packet must fill in the Verification Tag field of the outbound * packet with the Verification Tag received in the SHUTDOWN ACK and - * set the T-bit in the Chunk Flags to indicate that no TCB was - * found. Otherwise, + * set the T-bit in the Chunk Flags to indicate that the Verification + * Tag is reflected. * * 8) The receiver should respond to the sender of the OOTB packet with * an ABORT. When sending the ABORT, the receiver of the OOTB packet * MUST fill in the Verification Tag field of the outbound packet * with the value found in the Verification Tag field of the OOTB - * packet and set the T-bit in the Chunk Flags to indicate that no - * TCB was found. After sending this ABORT, the receiver of the OOTB - * packet shall discard the OOTB packet and take no further action. + * packet and set the T-bit in the Chunk Flags to indicate that the + * Verification Tag is reflected. After sending this ABORT, the + * receiver of the OOTB packet shall discard the OOTB packet and take + * no further action. */ sctp_disposition_t sctp_sf_ootb(const struct sctp_endpoint *ep, const struct sctp_association *asoc, @@ -3090,13 +3099,15 @@ sctp_disposition_t sctp_sf_ootb(const struct sctp_endpoint *ep, /* * Handle an "Out of the blue" SHUTDOWN ACK. * - * Section: 8.4 5) + * Section: 8.4 5, sctpimpguide 2.41. + * * 5) If the packet contains a SHUTDOWN ACK chunk, the receiver should - * respond to the sender of the OOTB packet with a SHUTDOWN COMPLETE. - * When sending the SHUTDOWN COMPLETE, the receiver of the OOTB packet - * must fill in the Verification Tag field of the outbound packet with - * the Verification Tag received in the SHUTDOWN ACK and set the - * T-bit in the Chunk Flags to indicate that no TCB was found. + * respond to the sender of the OOTB packet with a SHUTDOWN COMPLETE. + * When sending the SHUTDOWN COMPLETE, the receiver of the OOTB + * packet must fill in the Verification Tag field of the outbound + * packet with the Verification Tag received in the SHUTDOWN ACK and + * set the T-bit in the Chunk Flags to indicate that the Verification + * Tag is reflected. * * Inputs * (endpoint, asoc, type, arg, commands) @@ -3128,6 +3139,10 @@ static sctp_disposition_t sctp_sf_shut_8_4_5(const struct sctp_endpoint *ep, return SCTP_DISPOSITION_NOMEM; } + /* Reflect vtag if T-Bit is set */ + if (sctp_test_T_bit(shut)) + packet->vtag = ntohl(chunk->sctp_hdr->vtag); + /* Set the skb to the belonging sock for accounting. */ shut->skb->sk = ep->base.sk; @@ -3591,7 +3606,6 @@ sctp_disposition_t sctp_sf_discard_chunk(const struct sctp_endpoint *ep, * * 2) If the OOTB packet contains an ABORT chunk, the receiver MUST * silently discard the OOTB packet and take no further action. - * Otherwise, * * Verification Tag: No verification necessary * @@ -4961,6 +4975,11 @@ static struct sctp_packet *sctp_abort_pkt_new(const struct sctp_endpoint *ep, sctp_ootb_pkt_free(packet); return NULL; } + + /* Reflect vtag if T-Bit is set */ + if (sctp_test_T_bit(abort)) + packet->vtag = ntohl(chunk->sctp_hdr->vtag); + /* Add specified error causes, i.e., payload, to the * end of the chunk. */ -- cgit v1.2.3 From b9b9e10f180fa63b55b93412edf0ab9648675646 Mon Sep 17 00:00:00 2001 From: Brian Haley Date: Thu, 28 Apr 2005 11:59:16 -0700 Subject: [SCTP] Use ipv6_addr_any() rather than ipv6_addr_type() in sctp_v6_is_any(). Signed-off-by: Brian Haley Signed-off-by: Sridhar Samudrala Signed-off-by: David S. Miller --- net/sctp/ipv6.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) (limited to 'net/sctp') diff --git a/net/sctp/ipv6.c b/net/sctp/ipv6.c index e42c74e3ec1..c9d9ea06473 100644 --- a/net/sctp/ipv6.c +++ b/net/sctp/ipv6.c @@ -496,9 +496,7 @@ static void sctp_v6_inaddr_any(union sctp_addr *addr, unsigned short port) /* Is this a wildcard address? */ static int sctp_v6_is_any(const union sctp_addr *addr) { - int type; - type = ipv6_addr_type((struct in6_addr *)&addr->v6.sin6_addr); - return IPV6_ADDR_ANY == type; + return ipv6_addr_any(&addr->v6.sin6_addr); } /* Should this be available for binding? */ -- cgit v1.2.3 From 5e6bc34f86e450ff14c4817902d66aa9c786bc06 Mon Sep 17 00:00:00 2001 From: Neil Horman Date: Thu, 28 Apr 2005 11:59:49 -0700 Subject: [SCTP] Fix bug in sctp_init() error handling code. Signed-off-by: Neil Horman Signed-off-by: Sridhar Samudrala Signed-off-by: David S. Miller --- net/sctp/protocol.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'net/sctp') diff --git a/net/sctp/protocol.c b/net/sctp/protocol.c index b9813cf3d91..23c85a236c4 100644 --- a/net/sctp/protocol.c +++ b/net/sctp/protocol.c @@ -1159,8 +1159,6 @@ SCTP_STATIC __init int sctp_init(void) status = 0; out: return status; -err_add_protocol: - proto_unregister(&sctp_prot); err_ctl_sock_init: sctp_v6_exit(); err_v6_init: @@ -1188,6 +1186,8 @@ err_bucket_cachep: inet_del_protocol(&sctp_protocol, IPPROTO_SCTP); inet_unregister_protosw(&sctp_seqpacket_protosw); inet_unregister_protosw(&sctp_stream_protosw); +err_add_protocol: + proto_unregister(&sctp_prot); goto out; } -- cgit v1.2.3 From 594ccc14dfe4d61b476491758425a1c2ca4ec71b Mon Sep 17 00:00:00 2001 From: Sridhar Samudrala Date: Thu, 28 Apr 2005 12:00:23 -0700 Subject: [SCTP] Replace incorrect use of dev_alloc_skb with alloc_skb in sctp_packet_transmit(). Signed-off-by: Sridhar Samudrala Signed-off-by: David S. Miller --- net/sctp/output.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'net/sctp') diff --git a/net/sctp/output.c b/net/sctp/output.c index 9013f64f521..84b5b370b09 100644 --- a/net/sctp/output.c +++ b/net/sctp/output.c @@ -313,12 +313,12 @@ int sctp_packet_transmit(struct sctp_packet *packet) sk = chunk->skb->sk; /* Allocate the new skb. */ - nskb = dev_alloc_skb(packet->size); + nskb = alloc_skb(packet->size + LL_MAX_HEADER, GFP_ATOMIC); if (!nskb) goto nomem; /* Make sure the outbound skb has enough header room reserved. */ - skb_reserve(nskb, packet->overhead); + skb_reserve(nskb, packet->overhead + LL_MAX_HEADER); /* Set the owning socket so that we know where to get the * destination IP address. -- cgit v1.2.3 From 4eb701dfc618491c9b97377df6e61de36dfc39ce Mon Sep 17 00:00:00 2001 From: Neil Horman Date: Thu, 28 Apr 2005 12:02:04 -0700 Subject: [SCTP] Fix SCTP sendbuffer accouting. - Include chunk and skb sizes in sendbuffer accounting. - 2 policies are supported. 0: per socket accouting, 1: per association accounting DaveM: I've made the default per-socket. Signed-off-by: Neil Horman Signed-off-by: Sridhar Samudrala Signed-off-by: David S. Miller --- net/sctp/endpointola.c | 1 + net/sctp/protocol.c | 3 +++ net/sctp/socket.c | 36 +++++++++++++++++++++++++++++++----- net/sctp/sysctl.c | 8 ++++++++ 4 files changed, 43 insertions(+), 5 deletions(-) (limited to 'net/sctp') diff --git a/net/sctp/endpointola.c b/net/sctp/endpointola.c index 544b75077db..334f61773e6 100644 --- a/net/sctp/endpointola.c +++ b/net/sctp/endpointola.c @@ -125,6 +125,7 @@ static struct sctp_endpoint *sctp_endpoint_init(struct sctp_endpoint *ep, sp->autoclose * HZ; /* Use SCTP specific send buffer space queues. */ + ep->sndbuf_policy = sctp_sndbuf_policy; sk->sk_write_space = sctp_write_space; sock_set_flag(sk, SOCK_USE_WRITE_QUEUE); diff --git a/net/sctp/protocol.c b/net/sctp/protocol.c index 23c85a236c4..2e1f9c3556f 100644 --- a/net/sctp/protocol.c +++ b/net/sctp/protocol.c @@ -1043,6 +1043,9 @@ SCTP_STATIC __init int sctp_init(void) sctp_max_retrans_path = 5; sctp_max_retrans_init = 8; + /* Sendbuffer growth - do per-socket accounting */ + sctp_sndbuf_policy = 0; + /* HB.interval - 30 seconds */ sctp_hb_interval = 30 * HZ; diff --git a/net/sctp/socket.c b/net/sctp/socket.c index 32f2249411f..0b338eca6dc 100644 --- a/net/sctp/socket.c +++ b/net/sctp/socket.c @@ -115,9 +115,17 @@ static inline int sctp_wspace(struct sctp_association *asoc) struct sock *sk = asoc->base.sk; int amt = 0; - amt = sk->sk_sndbuf - asoc->sndbuf_used; + if (asoc->ep->sndbuf_policy) { + /* make sure that no association uses more than sk_sndbuf */ + amt = sk->sk_sndbuf - asoc->sndbuf_used; + } else { + /* do socket level accounting */ + amt = sk->sk_sndbuf - atomic_read(&sk->sk_wmem_alloc); + } + if (amt < 0) amt = 0; + return amt; } @@ -138,12 +146,21 @@ static inline void sctp_set_owner_w(struct sctp_chunk *chunk) /* The sndbuf space is tracked per association. */ sctp_association_hold(asoc); + skb_set_owner_w(chunk->skb, sk); + chunk->skb->destructor = sctp_wfree; /* Save the chunk pointer in skb for sctp_wfree to use later. */ *((struct sctp_chunk **)(chunk->skb->cb)) = chunk; - asoc->sndbuf_used += SCTP_DATA_SNDSIZE(chunk); - sk->sk_wmem_queued += SCTP_DATA_SNDSIZE(chunk); + asoc->sndbuf_used += SCTP_DATA_SNDSIZE(chunk) + + sizeof(struct sk_buff) + + sizeof(struct sctp_chunk); + + sk->sk_wmem_queued += SCTP_DATA_SNDSIZE(chunk) + + sizeof(struct sk_buff) + + sizeof(struct sctp_chunk); + + atomic_add(sizeof(struct sctp_chunk), &sk->sk_wmem_alloc); } /* Verify that this is a valid address. */ @@ -4422,8 +4439,17 @@ static void sctp_wfree(struct sk_buff *skb) chunk = *((struct sctp_chunk **)(skb->cb)); asoc = chunk->asoc; sk = asoc->base.sk; - asoc->sndbuf_used -= SCTP_DATA_SNDSIZE(chunk); - sk->sk_wmem_queued -= SCTP_DATA_SNDSIZE(chunk); + asoc->sndbuf_used -= SCTP_DATA_SNDSIZE(chunk) + + sizeof(struct sk_buff) + + sizeof(struct sctp_chunk); + + sk->sk_wmem_queued -= SCTP_DATA_SNDSIZE(chunk) + + sizeof(struct sk_buff) + + sizeof(struct sctp_chunk); + + atomic_sub(sizeof(struct sctp_chunk), &sk->sk_wmem_alloc); + + sock_wfree(skb); __sctp_write_space(asoc); sctp_association_put(asoc); diff --git a/net/sctp/sysctl.c b/net/sctp/sysctl.c index 89fa20c73a5..7fc31849312 100644 --- a/net/sctp/sysctl.c +++ b/net/sctp/sysctl.c @@ -109,6 +109,14 @@ static ctl_table sctp_table[] = { .mode = 0644, .proc_handler = &proc_dointvec }, + { + .ctl_name = NET_SCTP_SNDBUF_POLICY, + .procname = "sndbuf_policy", + .data = &sctp_sndbuf_policy, + .maxlen = sizeof(int), + .mode = 0644, + .proc_handler = &proc_dointvec + }, { .ctl_name = NET_SCTP_PATH_MAX_RETRANS, .procname = "path_max_retrans", -- cgit v1.2.3