From 9c5c62be2f794c7cee533d856f9f34c3cf21ff1b Mon Sep 17 00:00:00 2001 From: Vlad Yasevich Date: Mon, 10 Aug 2009 13:51:03 -0400 Subject: sctp: Send user messages to the lower layer as one Currenlty, sctp breaks up user messages into fragments and sends each fragment to the lower layer by itself. This means that for each fragment we go all the way down the stack and back up. This also discourages bundling of multiple fragments when they can fit into a sigle packet (ex: due to user setting a low fragmentation threashold). We introduce a new command SCTP_CMD_SND_MSG and hand the whole message down state machine. The state machine and the side-effect parser will cork the queue, add all chunks from the message to the queue, and then un-cork the queue thus causing the chunks to get transmitted. Signed-off-by: Vlad Yasevich --- include/net/sctp/structs.h | 1 + 1 file changed, 1 insertion(+) (limited to 'include/net/sctp/structs.h') diff --git a/include/net/sctp/structs.h b/include/net/sctp/structs.h index edfcacf3250e..97024faaa08f 100644 --- a/include/net/sctp/structs.h +++ b/include/net/sctp/structs.h @@ -643,6 +643,7 @@ struct sctp_datamsg { struct sctp_datamsg *sctp_datamsg_from_user(struct sctp_association *, struct sctp_sndrcvinfo *, struct msghdr *, int len); +void sctp_datamsg_free(struct sctp_datamsg *); void sctp_datamsg_put(struct sctp_datamsg *); void sctp_chunk_fail(struct sctp_chunk *, int error); int sctp_chunk_abandoned(struct sctp_chunk *); -- cgit v1.2.3-59-g8ed1b From 4d3c46e6833208428d366630aa708f6876e61fc1 Mon Sep 17 00:00:00 2001 From: Vlad Yasevich Date: Fri, 4 Sep 2009 18:20:59 -0400 Subject: sctp: drop a_rwnd to 0 when receive buffer overflows. SCTP has a problem that when small chunks are used, it is possible to exhaust the receiver buffer without fully closing receive window. This happens due to all overhead that we have account for with small messages. To fix this, when receive buffer is exceeded, we'll drop the window to 0 and save the 'drop' portion. When application starts reading data and freeing up recevie buffer space, we'll wait until we've reached the 'drop' window and then add back this 'drop' one mtu at a time. This worked well in testing and under stress produced rather even recovery. Signed-off-by: Vlad Yasevich --- include/net/sctp/structs.h | 6 ++++++ net/sctp/associola.c | 37 +++++++++++++++++++++++++++++++++++-- 2 files changed, 41 insertions(+), 2 deletions(-) (limited to 'include/net/sctp/structs.h') diff --git a/include/net/sctp/structs.h b/include/net/sctp/structs.h index 97024faaa08f..b1bd2689bb70 100644 --- a/include/net/sctp/structs.h +++ b/include/net/sctp/structs.h @@ -1739,6 +1739,12 @@ struct sctp_association { */ __u32 rwnd_over; + /* Keeps treack of rwnd pressure. This happens when we have + * a window, but not recevie buffer (i.e small packets). This one + * is releases slowly (1 PMTU at a time ). + */ + __u32 rwnd_press; + /* This is the sndbuf size in use for the association. * This corresponds to the sndbuf size for the association, * as specified in the sk->sndbuf. diff --git a/net/sctp/associola.c b/net/sctp/associola.c index 215b56951d76..39c3821b7d3d 100644 --- a/net/sctp/associola.c +++ b/net/sctp/associola.c @@ -202,6 +202,7 @@ static struct sctp_association *sctp_association_init(struct sctp_association *a asoc->a_rwnd = asoc->rwnd; asoc->rwnd_over = 0; + asoc->rwnd_press = 0; /* Use my own max window until I learn something better. */ asoc->peer.rwnd = SCTP_DEFAULT_MAXWINDOW; @@ -1374,6 +1375,17 @@ void sctp_assoc_rwnd_increase(struct sctp_association *asoc, unsigned len) asoc->rwnd += len; } + /* If we had window pressure, start recovering it + * once our rwnd had reached the accumulated pressure + * threshold. The idea is to recover slowly, but up + * to the initial advertised window. + */ + if (asoc->rwnd_press && asoc->rwnd >= asoc->rwnd_press) { + int change = min(asoc->pathmtu, asoc->rwnd_press); + asoc->rwnd += change; + asoc->rwnd_press -= change; + } + SCTP_DEBUG_PRINTK("%s: asoc %p rwnd increased by %d to (%u, %u) " "- %u\n", __func__, asoc, len, asoc->rwnd, asoc->rwnd_over, asoc->a_rwnd); @@ -1406,17 +1418,38 @@ void sctp_assoc_rwnd_increase(struct sctp_association *asoc, unsigned len) /* Decrease asoc's rwnd by len. */ void sctp_assoc_rwnd_decrease(struct sctp_association *asoc, unsigned len) { + int rx_count; + int over = 0; + SCTP_ASSERT(asoc->rwnd, "rwnd zero", return); SCTP_ASSERT(!asoc->rwnd_over, "rwnd_over not zero", return); + + if (asoc->ep->rcvbuf_policy) + rx_count = atomic_read(&asoc->rmem_alloc); + else + rx_count = atomic_read(&asoc->base.sk->sk_rmem_alloc); + + /* If we've reached or overflowed our receive buffer, announce + * a 0 rwnd if rwnd would still be positive. Store the + * the pottential pressure overflow so that the window can be restored + * back to original value. + */ + if (rx_count >= asoc->base.sk->sk_rcvbuf) + over = 1; + if (asoc->rwnd >= len) { asoc->rwnd -= len; + if (over) { + asoc->rwnd_press = asoc->rwnd; + asoc->rwnd = 0; + } } else { asoc->rwnd_over = len - asoc->rwnd; asoc->rwnd = 0; } - SCTP_DEBUG_PRINTK("%s: asoc %p rwnd decreased by %d to (%u, %u)\n", + SCTP_DEBUG_PRINTK("%s: asoc %p rwnd decreased by %d to (%u, %u, %u)\n", __func__, asoc, len, asoc->rwnd, - asoc->rwnd_over); + asoc->rwnd_over, asoc->rwnd_press); } /* Build the bind address list for the association based on info from the -- cgit v1.2.3-59-g8ed1b From cb95ea32a457871f72752164de8d94fa20f4703c Mon Sep 17 00:00:00 2001 From: Vlad Yasevich Date: Fri, 4 Sep 2009 18:20:59 -0400 Subject: sctp: Don't do NAGLE delay on large writes that were fragmented small SCTP will delay the last part of a large write due to NAGLE, if that part is smaller then MTU. Since we are doing large writes, we might as well send the last portion now instead of waiting untill the next large write happens. The small portion will be sent as is regardless, so it's better to not delay it. This is a result of much discussions with Wei Yongjun and Doug Graham . Many thanks go out to them. Signed-off-by: Vlad Yasevich --- include/net/sctp/structs.h | 2 +- net/sctp/chunk.c | 2 ++ net/sctp/output.c | 4 +++- 3 files changed, 6 insertions(+), 2 deletions(-) (limited to 'include/net/sctp/structs.h') diff --git a/include/net/sctp/structs.h b/include/net/sctp/structs.h index b1bd2689bb70..df4c6321996d 100644 --- a/include/net/sctp/structs.h +++ b/include/net/sctp/structs.h @@ -628,7 +628,7 @@ struct sctp_datamsg { /* Chunks waiting to be submitted to lower layer. */ struct list_head chunks; /* Chunks that have been transmitted. */ - struct list_head track; + size_t msg_size; /* Reference counting. */ atomic_t refcnt; /* When is this message no longer interesting to the peer? */ diff --git a/net/sctp/chunk.c b/net/sctp/chunk.c index 645577ddc33e..acf7c4d128f7 100644 --- a/net/sctp/chunk.c +++ b/net/sctp/chunk.c @@ -59,6 +59,7 @@ static void sctp_datamsg_init(struct sctp_datamsg *msg) msg->can_abandon = 0; msg->expires_at = 0; INIT_LIST_HEAD(&msg->chunks); + msg->msg_size = 0; } /* Allocate and initialize datamsg. */ @@ -155,6 +156,7 @@ static void sctp_datamsg_assign(struct sctp_datamsg *msg, struct sctp_chunk *chu { sctp_datamsg_hold(msg); chunk->msg = msg; + msg->msg_size += chunk->skb->len; } diff --git a/net/sctp/output.c b/net/sctp/output.c index d0b84f6eba4d..b801bc9fb639 100644 --- a/net/sctp/output.c +++ b/net/sctp/output.c @@ -703,8 +703,10 @@ static sctp_xmit_t sctp_packet_can_append_data(struct sctp_packet *packet, /* Check whether this chunk and all the rest of pending * data will fit or delay in hopes of bundling a full * sized packet. + * Don't delay large message writes that may have been + * fragmeneted into small peices. */ - if (len < max) { + if ((len < max) && (chunk->msg->msg_size < max)) { retval = SCTP_XMIT_NAGLE_DELAY; goto finish; } -- cgit v1.2.3-59-g8ed1b From f68b2e05f326971cd76c65aa91a1a41771dd7485 Mon Sep 17 00:00:00 2001 From: Vlad Yasevich Date: Fri, 4 Sep 2009 18:21:00 -0400 Subject: sctp: Fix SCTP_MAXSEG socket option to comply to spec. We had a bug that we never stored the user-defined value for MAXSEG when setting the value on an association. Thus future PMTU events ended up re-writing the frag point and increasing it past user limit. Additionally, when setting the option on the socket/endpoint, we effect all current associations, which is against spec. Now, we store the user 'maxseg' value along with the computed 'frag_point'. We inherit 'maxseg' from the socket at association creation and use it as an upper limit for 'frag_point' when its set. Signed-off-by: Vlad Yasevich --- include/net/sctp/sctp.h | 7 ++++--- include/net/sctp/structs.h | 1 + net/sctp/associola.c | 6 +++--- net/sctp/socket.c | 11 +++-------- 4 files changed, 11 insertions(+), 14 deletions(-) (limited to 'include/net/sctp/structs.h') diff --git a/include/net/sctp/sctp.h b/include/net/sctp/sctp.h index d16a304cbed4..8a6d5297de16 100644 --- a/include/net/sctp/sctp.h +++ b/include/net/sctp/sctp.h @@ -486,15 +486,16 @@ static inline __s32 sctp_jitter(__u32 rto) } /* Break down data chunks at this point. */ -static inline int sctp_frag_point(const struct sctp_sock *sp, int pmtu) +static inline int sctp_frag_point(const struct sctp_association *asoc, int pmtu) { + struct sctp_sock *sp = sctp_sk(asoc->base.sk); int frag = pmtu; frag -= sp->pf->af->net_header_len; frag -= sizeof(struct sctphdr) + sizeof(struct sctp_data_chunk); - if (sp->user_frag) - frag = min_t(int, frag, sp->user_frag); + if (asoc->user_frag) + frag = min_t(int, frag, asoc->user_frag); frag = min_t(int, frag, SCTP_MAX_CHUNK_LEN); diff --git a/include/net/sctp/structs.h b/include/net/sctp/structs.h index df4c6321996d..b10612810f56 100644 --- a/include/net/sctp/structs.h +++ b/include/net/sctp/structs.h @@ -1763,6 +1763,7 @@ struct sctp_association { /* The message size at which SCTP fragmentation will occur. */ __u32 frag_point; + __u32 user_frag; /* Counter used to count INIT errors. */ int init_err_counter; diff --git a/net/sctp/associola.c b/net/sctp/associola.c index 39c3821b7d3d..1f05b942564e 100644 --- a/net/sctp/associola.c +++ b/net/sctp/associola.c @@ -112,6 +112,7 @@ static struct sctp_association *sctp_association_init(struct sctp_association *a asoc->cookie_life.tv_usec = (sp->assocparams.sasoc_cookie_life % 1000) * 1000; asoc->frag_point = 0; + asoc->user_frag = sp->user_frag; /* Set the association max_retrans and RTO values from the * socket values. @@ -674,7 +675,7 @@ struct sctp_transport *sctp_assoc_add_peer(struct sctp_association *asoc, "%d\n", asoc, asoc->pathmtu); peer->pmtu_pending = 0; - asoc->frag_point = sctp_frag_point(sp, asoc->pathmtu); + asoc->frag_point = sctp_frag_point(asoc, asoc->pathmtu); /* The asoc->peer.port might not be meaningful yet, but * initialize the packet structure anyway. @@ -1330,9 +1331,8 @@ void sctp_assoc_sync_pmtu(struct sctp_association *asoc) } if (pmtu) { - struct sctp_sock *sp = sctp_sk(asoc->base.sk); asoc->pathmtu = pmtu; - asoc->frag_point = sctp_frag_point(sp, pmtu); + asoc->frag_point = sctp_frag_point(asoc, pmtu); } SCTP_DEBUG_PRINTK("%s: asoc:%p, pmtu:%d, frag_point:%d\n", diff --git a/net/sctp/socket.c b/net/sctp/socket.c index 95a5623d79a0..89af37a6c871 100644 --- a/net/sctp/socket.c +++ b/net/sctp/socket.c @@ -2243,7 +2243,7 @@ static int sctp_apply_peer_addr_params(struct sctp_paddrparams *params, sctp_assoc_sync_pmtu(asoc); } else if (asoc) { asoc->pathmtu = params->spp_pathmtu; - sctp_frag_point(sp, params->spp_pathmtu); + sctp_frag_point(asoc, params->spp_pathmtu); } else { sp->pathmtu = params->spp_pathmtu; } @@ -2880,15 +2880,10 @@ static int sctp_setsockopt_maxseg(struct sock *sk, char __user *optval, int optl val -= sizeof(struct sctphdr) + sizeof(struct sctp_data_chunk); } - - asoc->frag_point = val; + asoc->user_frag = val; + asoc->frag_point = sctp_frag_point(asoc, asoc->pathmtu); } else { sp->user_frag = val; - - /* Update the frag_point of the existing associations. */ - list_for_each_entry(asoc, &(sp->ep->asocs), asocs) { - asoc->frag_point = sctp_frag_point(sp, asoc->pathmtu); - } } return 0; -- cgit v1.2.3-59-g8ed1b From a803c942303e6a4ef0ab6b80114529852cffa058 Mon Sep 17 00:00:00 2001 From: Vlad Yasevich Date: Fri, 4 Sep 2009 18:21:01 -0400 Subject: sctp: Turn flags in 'sctp_packet' into bit fields This shrinks the size of sctp_packet a little. Signed-off-by: Vlad Yasevich --- include/net/sctp/structs.h | 22 ++++++---------------- 1 file changed, 6 insertions(+), 16 deletions(-) (limited to 'include/net/sctp/structs.h') diff --git a/include/net/sctp/structs.h b/include/net/sctp/structs.h index b10612810f56..993cfff9218e 100644 --- a/include/net/sctp/structs.h +++ b/include/net/sctp/structs.h @@ -812,22 +812,12 @@ struct sctp_packet { /* pointer to the auth chunk for this packet */ struct sctp_chunk *auth; - /* This packet contains a COOKIE-ECHO chunk. */ - __u8 has_cookie_echo; - - /* This packet contains a SACK chunk. */ - __u8 has_sack; - - /* This packet contains an AUTH chunk */ - __u8 has_auth; - - /* This packet contains at least 1 DATA chunk */ - __u8 has_data; - - /* SCTP cannot fragment this packet. So let ip fragment it. */ - __u8 ipfragok; - - __u8 malloced; + u8 has_cookie_echo:1, /* This packet contains a COOKIE-ECHO chunk. */ + has_sack:1, /* This packet contains a SACK chunk. */ + has_auth:1, /* This packet contains an AUTH chunk */ + has_data:1, /* This packet contains at least 1 DATA chunk */ + ipfragok:1, /* So let ip fragment this packet */ + malloced:1; /* Is it malloced? */ }; struct sctp_packet *sctp_packet_init(struct sctp_packet *, -- cgit v1.2.3-59-g8ed1b From 723884339f90a9c420783135168cc1045750eb5d Mon Sep 17 00:00:00 2001 From: Bhaskar Dutta Date: Thu, 3 Sep 2009 17:25:47 +0530 Subject: sctp: Sysctl configuration for IPv4 Address Scoping This patch introduces a new sysctl option to make IPv4 Address Scoping configurable . In networking environments where DNAT rules in iptables prerouting chains convert destination IP's to link-local/private IP addresses, SCTP connections fail to establish as the INIT chunk is dropped by the kernel due to address scope match failure. For example to support overlapping IP addresses (same IP address with different vlan id) a Layer-5 application listens on link local IP's, and there is a DNAT rule that maps the destination IP to a link local IP. Such applications never get the SCTP INIT if the address-scoping draft is strictly followed. This sysctl configuration allows SCTP to function in such unconventional networking environments. Sysctl options: 0 - Disable IPv4 address scoping draft altogether 1 - Enable IPv4 address scoping (default, current behavior) 2 - Enable address scoping but allow IPv4 private addresses in init/init-ack 3 - Enable address scoping but allow IPv4 link local address in init/init-ack Signed-off-by: Bhaskar Dutta Signed-off-by: Vlad Yasevich --- Documentation/networking/ip-sysctl.txt | 10 ++++++++++ include/net/sctp/constants.h | 7 +++++++ include/net/sctp/structs.h | 10 ++++++++++ net/sctp/bind_addr.c | 21 ++++++++++++++++++++- net/sctp/protocol.c | 11 ++++++----- net/sctp/sysctl.c | 12 ++++++++++++ 6 files changed, 65 insertions(+), 6 deletions(-) (limited to 'include/net/sctp/structs.h') diff --git a/Documentation/networking/ip-sysctl.txt b/Documentation/networking/ip-sysctl.txt index 4e9c6d7b4efc..fbe427a6580c 100644 --- a/Documentation/networking/ip-sysctl.txt +++ b/Documentation/networking/ip-sysctl.txt @@ -1297,6 +1297,16 @@ sctp_rmem - vector of 3 INTEGERs: min, default, max sctp_wmem - vector of 3 INTEGERs: min, default, max See tcp_wmem for a description. +addr_scope_policy - INTEGER + Control IPv4 address scoping - draft-stewart-tsvwg-sctp-ipv4-00 + + 0 - Disable IPv4 address scoping + 1 - Enable IPv4 address scoping + 2 - Follow draft but allow IPv4 private addresses + 3 - Follow draft but allow IPv4 link local addresses + + Default: 1 + /proc/sys/net/core/* dev_weight - INTEGER diff --git a/include/net/sctp/constants.h b/include/net/sctp/constants.h index af8c1508109e..58f714a3b670 100644 --- a/include/net/sctp/constants.h +++ b/include/net/sctp/constants.h @@ -363,6 +363,13 @@ typedef enum { SCTP_SCOPE_UNUSABLE, /* IPv4 unusable addresses */ } sctp_scope_t; +typedef enum { + SCTP_SCOPE_POLICY_DISABLE, /* Disable IPv4 address scoping */ + SCTP_SCOPE_POLICY_ENABLE, /* Enable IPv4 address scoping */ + SCTP_SCOPE_POLICY_PRIVATE, /* Follow draft but allow IPv4 private addresses */ + SCTP_SCOPE_POLICY_LINK, /* Follow draft but allow IPv4 link local addresses */ +} sctp_scope_policy_t; + /* Based on IPv4 scoping , * SCTP IPv4 unusable addresses: 0.0.0.0/8, 224.0.0.0/4, 198.18.0.0/24, * 192.88.99.0/24. diff --git a/include/net/sctp/structs.h b/include/net/sctp/structs.h index 993cfff9218e..a48d80e77cd7 100644 --- a/include/net/sctp/structs.h +++ b/include/net/sctp/structs.h @@ -219,6 +219,15 @@ extern struct sctp_globals { /* Flag to idicate if SCTP-AUTH is enabled */ int auth_enable; + /* + * Policy to control SCTP IPv4 address scoping + * 0 - Disable IPv4 address scoping + * 1 - Enable IPv4 address scoping + * 2 - Selectively allow only IPv4 private addresses + * 3 - Selectively allow only IPv4 link local address + */ + int ipv4_scope_policy; + /* Flag to indicate whether computing and verifying checksum * is disabled. */ int checksum_disable; @@ -252,6 +261,7 @@ extern struct sctp_globals { #define sctp_port_hashtable (sctp_globals.port_hashtable) #define sctp_local_addr_list (sctp_globals.local_addr_list) #define sctp_local_addr_lock (sctp_globals.addr_list_lock) +#define sctp_scope_policy (sctp_globals.ipv4_scope_policy) #define sctp_addip_enable (sctp_globals.addip_enable) #define sctp_addip_noauth (sctp_globals.addip_noauth_enable) #define sctp_prsctp_enable (sctp_globals.prsctp_enable) diff --git a/net/sctp/bind_addr.c b/net/sctp/bind_addr.c index 6d5944a745d4..13a6fba41077 100644 --- a/net/sctp/bind_addr.c +++ b/net/sctp/bind_addr.c @@ -510,9 +510,28 @@ int sctp_in_scope(const union sctp_addr *addr, sctp_scope_t scope) * of requested destination address, sender and receiver * SHOULD include all of its addresses with level greater * than or equal to L. + * + * Address scoping can be selectively controlled via sysctl + * option */ - if (addr_scope <= scope) + switch (sctp_scope_policy) { + case SCTP_SCOPE_POLICY_DISABLE: return 1; + case SCTP_SCOPE_POLICY_ENABLE: + if (addr_scope <= scope) + return 1; + break; + case SCTP_SCOPE_POLICY_PRIVATE: + if (addr_scope <= scope || SCTP_SCOPE_PRIVATE == addr_scope) + return 1; + break; + case SCTP_SCOPE_POLICY_LINK: + if (addr_scope <= scope || SCTP_SCOPE_LINK == addr_scope) + return 1; + break; + default: + break; + } return 0; } diff --git a/net/sctp/protocol.c b/net/sctp/protocol.c index a76da657244a..60093be8385d 100644 --- a/net/sctp/protocol.c +++ b/net/sctp/protocol.c @@ -431,16 +431,14 @@ static int sctp_v4_available(union sctp_addr *addr, struct sctp_sock *sp) * of requested destination address, sender and receiver * SHOULD include all of its addresses with level greater * than or equal to L. + * + * IPv4 scoping can be controlled through sysctl option + * net.sctp.addr_scope_policy */ static sctp_scope_t sctp_v4_scope(union sctp_addr *addr) { sctp_scope_t retval; - /* Should IPv4 scoping be a sysctl configurable option - * so users can turn it off (default on) for certain - * unconventional networking environments? - */ - /* Check for unusable SCTP addresses. */ if (IS_IPV4_UNUSABLE_ADDRESS(addr->v4.sin_addr.s_addr)) { retval = SCTP_SCOPE_UNUSABLE; @@ -1259,6 +1257,9 @@ SCTP_STATIC __init int sctp_init(void) /* Disable AUTH by default. */ sctp_auth_enable = 0; + /* Set SCOPE policy to enabled */ + sctp_scope_policy = SCTP_SCOPE_POLICY_ENABLE; + sctp_sysctl_register(); INIT_LIST_HEAD(&sctp_address_families); diff --git a/net/sctp/sysctl.c b/net/sctp/sysctl.c index 63eabbc71298..ab7151da120f 100644 --- a/net/sctp/sysctl.c +++ b/net/sctp/sysctl.c @@ -51,6 +51,7 @@ static int timer_max = 86400000; /* ms in one day */ static int int_max = INT_MAX; static int sack_timer_min = 1; static int sack_timer_max = 500; +static int addr_scope_max = 3; /* check sctp_scope_policy_t in include/net/sctp/constants.h for max entries */ extern int sysctl_sctp_mem[3]; extern int sysctl_sctp_rmem[3]; @@ -272,6 +273,17 @@ static ctl_table sctp_table[] = { .proc_handler = proc_dointvec, .strategy = sysctl_intvec }, + { + .ctl_name = CTL_UNNUMBERED, + .procname = "addr_scope_policy", + .data = &sctp_scope_policy, + .maxlen = sizeof(int), + .mode = 0644, + .proc_handler = &proc_dointvec_minmax, + .strategy = &sysctl_intvec, + .extra1 = &zero, + .extra2 = &addr_scope_max, + }, { .ctl_name = 0 } }; -- cgit v1.2.3-59-g8ed1b From 9237ccbc0b22b5aa5396463ba0b14dc5efe5b98c Mon Sep 17 00:00:00 2001 From: Wei Yongjun Date: Fri, 4 Sep 2009 14:33:19 +0800 Subject: sctp: turn flags in 'struct sctp_association' into bit fields This shrinks the size of struct sctp_association a little. Signed-off-by: Wei Yongjun Signed-off-by: Vlad Yasevich --- include/net/sctp/structs.h | 21 +++++++++------------ 1 file changed, 9 insertions(+), 12 deletions(-) (limited to 'include/net/sctp/structs.h') diff --git a/include/net/sctp/structs.h b/include/net/sctp/structs.h index a48d80e77cd7..42d00ced5eb8 100644 --- a/include/net/sctp/structs.h +++ b/include/net/sctp/structs.h @@ -1568,13 +1568,13 @@ struct sctp_association { __u32 sack_cnt; /* These are capabilities which our peer advertised. */ - __u8 ecn_capable; /* Can peer do ECN? */ - __u8 ipv4_address; /* Peer understands IPv4 addresses? */ - __u8 ipv6_address; /* Peer understands IPv6 addresses? */ - __u8 hostname_address;/* Peer understands DNS addresses? */ - __u8 asconf_capable; /* Does peer support ADDIP? */ - __u8 prsctp_capable; /* Can peer do PR-SCTP? */ - __u8 auth_capable; /* Is peer doing SCTP-AUTH? */ + __u8 ecn_capable:1, /* Can peer do ECN? */ + ipv4_address:1, /* Peer understands IPv4 addresses? */ + ipv6_address:1, /* Peer understands IPv6 addresses? */ + hostname_address:1, /* Peer understands DNS addresses? */ + asconf_capable:1, /* Does peer support ADDIP? */ + prsctp_capable:1, /* Can peer do PR-SCTP? */ + auth_capable:1; /* Is peer doing SCTP-AUTH? */ __u32 adaptation_ind; /* Adaptation Code point. */ @@ -1913,11 +1913,8 @@ struct sctp_association { __u16 active_key_id; - /* Need to send an ECNE Chunk? */ - char need_ecne; - - /* Is it a temporary association? */ - char temp; + __u8 need_ecne:1, /* Need to send an ECNE Chunk? */ + temp:1; /* Is it a temporary association? */ }; -- cgit v1.2.3-59-g8ed1b