diff options
Diffstat (limited to 'include/net/sctp/structs.h')
| -rw-r--r-- | include/net/sctp/structs.h | 838 |
1 files changed, 536 insertions, 302 deletions
diff --git a/include/net/sctp/structs.h b/include/net/sctp/structs.h index e745c92a1532..affee44bd38e 100644 --- a/include/net/sctp/structs.h +++ b/include/net/sctp/structs.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ /* SCTP kernel implementation * (C) Copyright IBM Corp. 2001, 2004 * Copyright (c) 1999-2000 Cisco, Inc. @@ -6,29 +7,9 @@ * * This file is part of the SCTP kernel implementation * - * This SCTP implementation is free software; - * you can redistribute it and/or modify it under the terms of - * the GNU General Public License as published by - * the Free Software Foundation; either version 2, or (at your option) - * any later version. - * - * This SCTP implementation is distributed in the hope that it - * will be useful, but WITHOUT ANY WARRANTY; without even the implied - * ************************ - * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - * See the GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GNU CC; see the file COPYING. If not, write to - * the Free Software Foundation, 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - * * Please send any bug reports or fixes you make to the * email addresses: - * lksctp developers <lksctp-developers@lists.sourceforge.net> - * - * Or submit a bug report through the following website: - * http://www.sf.net/projects/lksctp + * lksctp developers <linux-sctp@vger.kernel.org> * * Written or modified by: * Randall Stewart <randall@sctp.chicago.il.us> @@ -46,15 +27,15 @@ * Ryan Layer <rmlayer@us.ibm.com> * Anup Pemmaiah <pemmaiah@cc.usu.edu> * Kevin Gao <kevin.gao@intel.com> - * - * Any bugs reported given to us we will try to fix... any fixes shared will - * be incorporated into the next SCTP release. */ #ifndef __sctp_structs_h__ #define __sctp_structs_h__ +#include <crypto/sha2.h> #include <linux/ktime.h> +#include <linux/generic-radix-tree.h> +#include <linux/rhashtable-types.h> #include <linux/socket.h> /* linux/in.h needs this!! */ #include <linux/in.h> /* We get struct sockaddr_in. */ #include <linux/in6.h> /* We get struct in6_addr */ @@ -65,14 +46,15 @@ #include <linux/workqueue.h> /* We need tq_struct. */ #include <linux/sctp.h> /* We need sctp* header structs. */ #include <net/sctp/auth.h> /* We need auth specific structs */ +#include <net/ip.h> /* For inet_skb_parm */ /* A convenience structure for handling sockaddr structures. * We should wean ourselves off this. */ union sctp_addr { + struct sockaddr_inet sa; /* Large enough for both address families */ struct sockaddr_in v4; struct sockaddr_in6 v6; - struct sockaddr sa; }; /* Forward declarations for data structures. */ @@ -87,19 +69,21 @@ struct sctp_outq; struct sctp_bind_addr; struct sctp_ulpq; struct sctp_ep_common; -struct sctp_ssnmap; -struct crypto_hash; +struct sctp_stream; #include <net/sctp/tsnmap.h> #include <net/sctp/ulpevent.h> #include <net/sctp/ulpqueue.h> +#include <net/sctp/stream_interleave.h> /* Structures useful for managing bind/connect. */ struct sctp_bind_bucket { unsigned short port; - unsigned short fastreuse; + signed char fastreuse; + signed char fastreuseport; + kuid_t fastuid; struct hlist_node node; struct hlist_head owner; struct net *net; @@ -119,28 +103,25 @@ struct sctp_hashbucket { /* The SCTP globals structure. */ extern struct sctp_globals { - /* The following variables are implementation specific. */ - - /* Default initialization values to be applied to new associations. */ - __u16 max_instreams; - __u16 max_outstreams; - /* This is a list of groups of functions for each address * family that we support. */ struct list_head address_families; /* This is the hash of all endpoints. */ - int ep_hashsize; struct sctp_hashbucket *ep_hashtable; - - /* This is the hash of all associations. */ - int assoc_hashsize; - struct sctp_hashbucket *assoc_hashtable; - /* This is the sctp port control hash. */ - int port_hashsize; struct sctp_bind_hashbucket *port_hashtable; + /* This is the hash of all transports. */ + struct rhltable transport_hashtable; + + /* Sizes of above hashtables. */ + int ep_hashsize; + int port_hashsize; + + /* Default initialization values to be applied to new associations. */ + __u16 max_instreams; + __u16 max_outstreams; /* Flag to indicate whether computing and verifying checksum * is disabled. */ @@ -152,33 +133,28 @@ extern struct sctp_globals { #define sctp_address_families (sctp_globals.address_families) #define sctp_ep_hashsize (sctp_globals.ep_hashsize) #define sctp_ep_hashtable (sctp_globals.ep_hashtable) -#define sctp_assoc_hashsize (sctp_globals.assoc_hashsize) -#define sctp_assoc_hashtable (sctp_globals.assoc_hashtable) #define sctp_port_hashsize (sctp_globals.port_hashsize) #define sctp_port_hashtable (sctp_globals.port_hashtable) +#define sctp_transport_hashtable (sctp_globals.transport_hashtable) #define sctp_checksum_disable (sctp_globals.checksum_disable) /* SCTP Socket type: UDP or TCP style. */ -typedef enum { +enum sctp_socket_type { SCTP_SOCKET_UDP = 0, SCTP_SOCKET_UDP_HIGH_BANDWIDTH, SCTP_SOCKET_TCP -} sctp_socket_type_t; +}; /* Per socket SCTP information. */ struct sctp_sock { /* inet_sock has to be the first member of sctp_sock */ struct inet_sock inet; /* What kind of a socket is this? */ - sctp_socket_type_t type; + enum sctp_socket_type type; /* PF_ family specific functions. */ struct sctp_pf *pf; - /* Access to HMAC transform. */ - struct crypto_hash *hmac; - char *sctp_hmac_alg; - /* What is our base endpointer? */ struct sctp_endpoint *ep; @@ -197,10 +173,20 @@ struct sctp_sock { * will be inherited by all new associations. */ __u32 hbinterval; + __u32 probe_interval; + + __be16 udp_port; + __be16 encap_port; /* This is the max_retrans value for new associations. */ __u16 pathmaxrxt; + __u32 flowlabel; + __u8 dscp; + + __u16 pf_retrans; + __u16 ps_retrans; + /* The initial Path MTU to use for new associations. */ __u32 pathmtu; @@ -211,31 +197,45 @@ struct sctp_sock { /* Flags controlling Heartbeat, SACK delay, and Path MTU Discovery. */ __u32 param_flags; - struct sctp_initmsg initmsg; + __u32 default_ss; + struct sctp_rtoinfo rtoinfo; struct sctp_paddrparams paddrparam; - struct sctp_event_subscribe subscribe; struct sctp_assocparams assocparams; + + /* + * These two structures must be grouped together for the usercopy + * whitelist region. + */ + __u16 subscribe; + struct sctp_initmsg initmsg; + int user_frag; + __u32 autoclose; - __u8 nodelay; - __u8 disable_fragments; - __u8 v4mapped; - __u8 frag_interleave; __u32 adaptation_ind; __u32 pd_point; + __u16 nodelay:1, + pf_expose:2, + reuse:1, + disable_fragments:1, + v4mapped:1, + frag_interleave:1, + recvrcvinfo:1, + recvnxtinfo:1, + data_ready_signalled:1, + cookie_auth_enable:1; atomic_t pd_mode; + /* Receive to here while partial delivery is in effect. */ struct sk_buff_head pd_lobby; + struct list_head auto_asconf_list; int do_auto_asconf; }; -static inline struct sctp_sock *sctp_sk(const struct sock *sk) -{ - return (struct sctp_sock *)sk; -} +#define sctp_sk(ptr) container_of_const(ptr, struct sctp_sock, inet.sk) static inline struct sock *sctp_opt2sk(const struct sctp_sock *sp) { @@ -310,9 +310,10 @@ struct sctp_cookie { __u32 adaptation_ind; - __u8 auth_random[sizeof(sctp_paramhdr_t) + SCTP_AUTH_RANDOM_LENGTH]; + __u8 auth_random[sizeof(struct sctp_paramhdr) + + SCTP_AUTH_RANDOM_LENGTH]; __u8 auth_hmacs[SCTP_AUTH_NUM_HMACS * sizeof(__u16) + 2]; - __u8 auth_chunks[sizeof(sctp_paramhdr_t) + SCTP_AUTH_MAX_CHUNKS]; + __u8 auth_chunks[sizeof(struct sctp_paramhdr) + SCTP_AUTH_MAX_CHUNKS]; /* This is a shim for my peer's INIT packet, followed by * a copy of the raw address list of the association. @@ -321,13 +322,13 @@ struct sctp_cookie { * the association TCB is re-constructed from the cookie. */ __u32 raw_addr_list_len; - struct sctp_init_chunk peer_init[0]; + /* struct sctp_init_chunk peer_init[]; */ }; /* The format of our cookie that we send to our peer. */ struct sctp_signed_cookie { - __u8 signature[SCTP_SECRET_SIZE]; + __u8 mac[SCTP_COOKIE_MAC_SIZE]; __u32 __pad; /* force sctp_cookie alignment to 64 bits */ struct sctp_cookie c; } __packed; @@ -370,61 +371,53 @@ union sctp_params { * chunk is sent and the destination transport address to which this * HEARTBEAT is sent (see Section 8.3). */ -typedef struct sctp_sender_hb_info { +struct sctp_sender_hb_info { struct sctp_paramhdr param_hdr; union sctp_addr daddr; unsigned long sent_at; __u64 hb_nonce; -} __packed sctp_sender_hb_info_t; - -/* - * RFC 2960 1.3.2 Sequenced Delivery within Streams - * - * The term "stream" is used in SCTP to refer to a sequence of user - * messages that are to be delivered to the upper-layer protocol in - * order with respect to other messages within the same stream. This is - * in contrast to its usage in TCP, where it refers to a sequence of - * bytes (in this document a byte is assumed to be eight bits). - * ... - * - * This is the structure we use to track both our outbound and inbound - * SSN, or Stream Sequence Numbers. - */ - -struct sctp_stream { - __u16 *ssn; - unsigned int len; + __u32 probe_size; }; -struct sctp_ssnmap { - struct sctp_stream in; - struct sctp_stream out; -}; - -struct sctp_ssnmap *sctp_ssnmap_new(__u16 in, __u16 out, - gfp_t gfp); -void sctp_ssnmap_free(struct sctp_ssnmap *map); -void sctp_ssnmap_clear(struct sctp_ssnmap *map); +int sctp_stream_init(struct sctp_stream *stream, __u16 outcnt, __u16 incnt, + gfp_t gfp); +int sctp_stream_init_ext(struct sctp_stream *stream, __u16 sid); +void sctp_stream_free(struct sctp_stream *stream); +void sctp_stream_clear(struct sctp_stream *stream); +void sctp_stream_update(struct sctp_stream *stream, struct sctp_stream *new); /* What is the current SSN number for this stream? */ -static inline __u16 sctp_ssn_peek(struct sctp_stream *stream, __u16 id) -{ - return stream->ssn[id]; -} +#define sctp_ssn_peek(stream, type, sid) \ + (sctp_stream_##type((stream), (sid))->ssn) /* Return the next SSN number for this stream. */ -static inline __u16 sctp_ssn_next(struct sctp_stream *stream, __u16 id) -{ - return stream->ssn[id]++; -} +#define sctp_ssn_next(stream, type, sid) \ + (sctp_stream_##type((stream), (sid))->ssn++) /* Skip over this ssn and all below. */ -static inline void sctp_ssn_skip(struct sctp_stream *stream, __u16 id, - __u16 ssn) -{ - stream->ssn[id] = ssn+1; -} - +#define sctp_ssn_skip(stream, type, sid, ssn) \ + (sctp_stream_##type((stream), (sid))->ssn = ssn + 1) + +/* What is the current MID number for this stream? */ +#define sctp_mid_peek(stream, type, sid) \ + (sctp_stream_##type((stream), (sid))->mid) + +/* Return the next MID number for this stream. */ +#define sctp_mid_next(stream, type, sid) \ + (sctp_stream_##type((stream), (sid))->mid++) + +/* Skip over this mid and all below. */ +#define sctp_mid_skip(stream, type, sid, mid) \ + (sctp_stream_##type((stream), (sid))->mid = mid + 1) + +/* What is the current MID_uo number for this stream? */ +#define sctp_mid_uo_peek(stream, type, sid) \ + (sctp_stream_##type((stream), (sid))->mid_uo) + +/* Return the next MID_uo number for this stream. */ +#define sctp_mid_uo_next(stream, type, sid) \ + (sctp_stream_##type((stream), (sid))->mid_uo++) + /* * Pointers to address related SCTP functions. * (i.e. things that depend on the address family.) @@ -435,23 +428,13 @@ struct sctp_af { int (*setsockopt) (struct sock *sk, int level, int optname, - char __user *optval, + sockptr_t optval, unsigned int optlen); int (*getsockopt) (struct sock *sk, int level, int optname, char __user *optval, int __user *optlen); - int (*compat_setsockopt) (struct sock *sk, - int level, - int optname, - char __user *optval, - unsigned int optlen); - int (*compat_getsockopt) (struct sock *sk, - int level, - int optname, - char __user *optval, - int __user *optlen); void (*get_dst) (struct sctp_transport *t, union sctp_addr *saddr, struct flowi *fl, @@ -470,11 +453,7 @@ struct sctp_af { int saddr); void (*from_sk) (union sctp_addr *, struct sock *sk); - void (*to_sk_saddr) (union sctp_addr *, - struct sock *sk); - void (*to_sk_daddr) (union sctp_addr *, - struct sock *sk); - void (*from_addr_param) (union sctp_addr *, + bool (*from_addr_param) (union sctp_addr *, union sctp_addr_param *, __be16 port, int iif); int (*to_addr_param) (const union sctp_addr *, @@ -482,18 +461,20 @@ struct sctp_af { int (*addr_valid) (union sctp_addr *, struct sctp_sock *, const struct sk_buff *); - sctp_scope_t (*scope) (union sctp_addr *); + enum sctp_scope (*scope)(union sctp_addr *); void (*inaddr_any) (union sctp_addr *, __be16); int (*is_any) (const union sctp_addr *); int (*available) (union sctp_addr *, struct sctp_sock *); int (*skb_iif) (const struct sk_buff *sk); + int (*skb_sdif)(const struct sk_buff *sk); int (*is_ce) (const struct sk_buff *sk); void (*seq_dump_addr)(struct seq_file *seq, union sctp_addr *addr); void (*ecn_capable)(struct sock *sk); __u16 net_header_len; int sockaddr_len; + int (*ip_options_len)(struct sock *sk); sa_family_t sa_family; struct list_head list; }; @@ -512,9 +493,10 @@ struct sctp_pf { int (*bind_verify) (struct sctp_sock *, union sctp_addr *); int (*send_verify) (struct sctp_sock *, union sctp_addr *); int (*supported_addrs)(const struct sctp_sock *, __be16 *); - struct sock *(*create_accept_sk) (struct sock *sk, - struct sctp_association *asoc); - void (*addr_v4map) (struct sctp_sock *, union sctp_addr *); + int (*addr_to_user)(struct sctp_sock *sk, union sctp_addr *addr); + void (*to_sk_saddr)(union sctp_addr *, struct sock *sk); + void (*to_sk_daddr)(union sctp_addr *, struct sock *sk); + void (*copy_ip_options)(struct sock *sk, struct sock *newsk); struct sctp_af *af; }; @@ -526,19 +508,19 @@ struct sctp_datamsg { /* Chunks waiting to be submitted to lower layer. */ struct list_head chunks; /* Reference counting. */ - atomic_t refcnt; + refcount_t refcnt; /* When is this message no longer interesting to the peer? */ unsigned long expires_at; - /* Did the messenge fail to send? */ + /* Did the message fail to send? */ int send_error; u8 send_failed:1, - can_abandon:1, /* can chunks from this message can be abandoned. */ - can_delay; /* should this message be Nagle delayed */ + can_delay:1, /* should this message be Nagle delayed */ + abandoned:1; /* should this message be abandoned */ }; struct sctp_datamsg *sctp_datamsg_from_user(struct sctp_association *, struct sctp_sndrcvinfo *, - struct msghdr *, int len); + struct iov_iter *); void sctp_datamsg_free(struct sctp_datamsg *); void sctp_datamsg_put(struct sctp_datamsg *); void sctp_chunk_fail(struct sctp_chunk *, int error); @@ -555,10 +537,17 @@ int sctp_chunk_abandoned(struct sctp_chunk *); struct sctp_chunk { struct list_head list; - atomic_t refcnt; + refcount_t refcnt; - /* This is our link to the per-transport transmitted list. */ - struct list_head transmitted_list; + /* How many times this chunk have been sent, for prsctp RTX policy */ + int sent_count; + + union { + /* This is our link to the per-transport transmitted list. */ + struct list_head transmitted_list; + /* List in specific stream outq */ + struct list_head stream_list; + }; /* This field is used by chunks that hold fragmented data. * For the first fragment this is the list that holds the rest of @@ -570,6 +559,13 @@ struct sctp_chunk { /* This points to the sk_buff containing the actual data. */ struct sk_buff *skb; + union { + /* In case of GSO packets, this will store the head one */ + struct sk_buff *head_skb; + /* In case of auth enabled, this will point to the shkey */ + struct sctp_shared_key *shkey; + }; + /* These are the SCTP headers by reverse order in a packet. * Note that some of these may happen more than once. In that * case, we point at the "current" one, whatever that means @@ -593,6 +589,8 @@ struct sctp_chunk { struct sctp_addiphdr *addip_hdr; struct sctp_fwdtsn_hdr *fwdtsn_hdr; struct sctp_authhdr *auth_hdr; + struct sctp_idatahdr *idata_hdr; + struct sctp_ifwdtsn_hdr *ifwdtsn_hdr; } subh; __u8 *chunk_end; @@ -639,6 +637,7 @@ struct sctp_chunk { __u16 rtt_in_progress:1, /* This chunk used for RTT calc? */ has_tsn:1, /* Does this chunk have a TSN yet? */ has_ssn:1, /* Does this chunk have a SSN yet? */ +#define has_mid has_ssn singleton:1, /* Only chunk in the packet? */ end_of_packet:1, /* Last chunk in the packet? */ ecn_ce_done:1, /* Have we processed the ECN CE bit? */ @@ -647,24 +646,30 @@ struct sctp_chunk { data_accepted:1, /* At least 1 chunk accepted */ auth:1, /* IN: was auth'ed | OUT: needs auth */ has_asconf:1, /* IN: have seen an asconf before */ + pmtu_probe:1, /* Used by PLPMTUD, can be set in s HB chunk */ tsn_missing_report:2, /* Data chunk missing counter. */ fast_retransmit:2; /* Is this chunk fast retransmitted? */ }; +#define sctp_chunk_retransmitted(chunk) (chunk->sent_count > 1) void sctp_chunk_hold(struct sctp_chunk *); void sctp_chunk_put(struct sctp_chunk *); -int sctp_user_addto_chunk(struct sctp_chunk *chunk, int off, int len, - struct iovec *data); +int sctp_user_addto_chunk(struct sctp_chunk *chunk, int len, + struct iov_iter *from); void sctp_chunk_free(struct sctp_chunk *); void *sctp_addto_chunk(struct sctp_chunk *, int len, const void *data); -void *sctp_addto_chunk_fixed(struct sctp_chunk *, int len, const void *data); struct sctp_chunk *sctp_chunkify(struct sk_buff *, const struct sctp_association *, - struct sock *); + struct sock *, gfp_t gfp); void sctp_init_addrs(struct sctp_chunk *, union sctp_addr *, union sctp_addr *); const union sctp_addr *sctp_source(const struct sctp_chunk *chunk); +static inline __u16 sctp_chunk_stream_no(struct sctp_chunk *ch) +{ + return ntohs(ch->subh.data_hdr->stream); +} + enum { SCTP_ADDR_NEW, /* new address added to assoc/ep */ SCTP_ADDR_SRC, /* address can be used as source */ @@ -682,8 +687,6 @@ struct sctp_sockaddr_entry { #define SCTP_ADDRESS_TICK_DELAY 500 -typedef struct sctp_chunk *(sctp_packet_phandler_t)(struct sctp_association *); - /* This structure holds lists of chunks as we are assembling for * transmission. */ @@ -700,6 +703,8 @@ struct sctp_packet { size_t overhead; /* This is the total size of all chunks INCLUDING padding. */ size_t size; + /* This is the maximum size this packet may have */ + size_t max_size; /* The packet is destined for this transport address. * The function we finally use to pass down to the next lower @@ -717,15 +722,15 @@ struct sctp_packet { ipfragok:1; /* So let ip fragment this packet */ }; -struct sctp_packet *sctp_packet_init(struct sctp_packet *, - struct sctp_transport *, - __u16 sport, __u16 dport); -struct sctp_packet *sctp_packet_config(struct sctp_packet *, __u32 vtag, int); -sctp_xmit_t sctp_packet_transmit_chunk(struct sctp_packet *, - struct sctp_chunk *, int); -sctp_xmit_t sctp_packet_append_chunk(struct sctp_packet *, - struct sctp_chunk *); -int sctp_packet_transmit(struct sctp_packet *); +void sctp_packet_init(struct sctp_packet *, struct sctp_transport *, + __u16 sport, __u16 dport); +void sctp_packet_config(struct sctp_packet *, __u32 vtag, int); +enum sctp_xmit sctp_packet_transmit_chunk(struct sctp_packet *packet, + struct sctp_chunk *chunk, + int one_packet, gfp_t gfp); +enum sctp_xmit sctp_packet_append_chunk(struct sctp_packet *packet, + struct sctp_chunk *chunk); +int sctp_packet_transmit(struct sctp_packet *, gfp_t); void sctp_packet_free(struct sctp_packet *); static inline int sctp_packet_empty(struct sctp_packet *packet) @@ -756,10 +761,11 @@ static inline int sctp_packet_empty(struct sctp_packet *packet) struct sctp_transport { /* A list of transports. */ struct list_head transports; + struct rhlist_head node; /* Reference counting. */ - atomic_t refcnt; - __u32 dead:1, + refcount_t refcnt; + __u32 dead:1, /* RTO-Pending : A flag used to track if one of the DATA * chunks sent to this address is currently being * used to compute a RTT. If this flag is 0, @@ -769,7 +775,7 @@ struct sctp_transport { * calculation completes (i.e. the DATA chunk * is SACK'd) clear this flag. */ - rto_pending:1, + rto_pending:1, /* * hb_sent : a flag that signals that we have a pending @@ -777,11 +783,14 @@ struct sctp_transport { */ hb_sent:1, - /* Is the Path MTU update pending on this tranport */ - pmtu_pending:1; + /* Is the Path MTU update pending on this transport */ + pmtu_pending:1, - /* Has this transport moved the ctsn since we last sacked */ - __u32 sack_generation; + dst_pending_confirm:1, /* need to confirm neighbour */ + + /* Has this transport moved the ctsn since we last sacked */ + sack_generation:1; + u32 dst_cookie; struct flowi fl; @@ -841,32 +850,47 @@ struct sctp_transport { * the destination address every heartbeat interval. */ unsigned long hbinterval; + unsigned long probe_interval; /* SACK delay timeout */ unsigned long sackdelay; __u32 sackfreq; - /* When was the last time (in jiffies) that we heard from this - * transport? We use this to pick new active and retran paths. + atomic_t mtu_info; + + /* When was the last time that we heard from this transport? We use + * this to pick new active and retran paths. + */ + ktime_t last_time_heard; + + /* When was the last time that we sent a chunk using this + * transport? We use this to check for idle transports */ - unsigned long last_time_heard; + unsigned long last_time_sent; /* Last time(in jiffies) when cwnd is reduced due to the congestion * indication based on ECNE chunk. */ unsigned long last_time_ecne_reduced; + __be16 encap_port; + /* This is the max_retrans value for the transport and will * be initialized from the assocs value. This can be changed * using the SCTP_SET_PEER_ADDR_PARAMS socket option. */ __u16 pathmaxrxt; + __u32 flowlabel; + __u8 dscp; + /* This is the partially failed retrans value for the transport * and will be initialized from the assocs value. This can be changed * using the SCTP_PEER_ADDR_THLDS socket option */ - int pf_retrans; + __u16 pf_retrans; + /* Used for primary path switchover. */ + __u16 ps_retrans; /* PMTU : The current known path MTU. */ __u32 pathmtu; @@ -900,6 +924,12 @@ struct sctp_transport { /* Timer to handle ICMP proto unreachable envets */ struct timer_list proto_unreach_timer; + /* Timer to handler reconf chunk rtx */ + struct timer_list reconf_timer; + + /* Timer to send a probe HB packet for PLPMTUD */ + struct timer_list probe_timer; + /* Since we're using per-destination retransmission timers * (see above), we're also using per-destination "transmitted" * queues. This probably ought to be a private struct @@ -942,6 +972,14 @@ struct sctp_transport { char cacc_saw_newack; } cacc; + struct { + __u16 pmtu; + __u16 probe_size; + __u16 probe_high; + __u8 probe_count; + __u8 state; + } pl; /* plpmtud related */ + /* 64-bit random number sent with heartbeat. */ __u64 hb_nonce; @@ -956,18 +994,27 @@ void sctp_transport_route(struct sctp_transport *, union sctp_addr *, struct sctp_sock *); void sctp_transport_pmtu(struct sctp_transport *, struct sock *sk); void sctp_transport_free(struct sctp_transport *); -void sctp_transport_reset_timers(struct sctp_transport *); -void sctp_transport_hold(struct sctp_transport *); +void sctp_transport_reset_t3_rtx(struct sctp_transport *); +void sctp_transport_reset_hb_timer(struct sctp_transport *); +void sctp_transport_reset_reconf_timer(struct sctp_transport *transport); +void sctp_transport_reset_probe_timer(struct sctp_transport *transport); +void sctp_transport_reset_raise_timer(struct sctp_transport *transport); +int sctp_transport_hold(struct sctp_transport *); void sctp_transport_put(struct sctp_transport *); void sctp_transport_update_rto(struct sctp_transport *, __u32); void sctp_transport_raise_cwnd(struct sctp_transport *, __u32, __u32); -void sctp_transport_lower_cwnd(struct sctp_transport *, sctp_lower_cwnd_t); +void sctp_transport_lower_cwnd(struct sctp_transport *t, + enum sctp_lower_cwnd reason); void sctp_transport_burst_limited(struct sctp_transport *); void sctp_transport_burst_reset(struct sctp_transport *); unsigned long sctp_transport_timeout(struct sctp_transport *); -void sctp_transport_reset(struct sctp_transport *); -void sctp_transport_update_pmtu(struct sock *, struct sctp_transport *, u32); +void sctp_transport_reset(struct sctp_transport *t); +bool sctp_transport_update_pmtu(struct sctp_transport *t, u32 pmtu); void sctp_transport_immediate_rtx(struct sctp_transport *); +void sctp_transport_dst_release(struct sctp_transport *t); +void sctp_transport_dst_confirm(struct sctp_transport *t); +void sctp_transport_pl_send(struct sctp_transport *t); +bool sctp_transport_pl_recv(struct sctp_transport *t); /* This is the structure we use to queue packets as they come into @@ -1021,6 +1068,9 @@ struct sctp_outq { /* Data pending that has never been transmitted. */ struct list_head out_chunk_list; + /* Stream scheduler being used */ + const struct sctp_sched_ops *sched; + unsigned int out_qlen; /* Total length of queued data chunks. */ /* Error of send failed, may used in SCTP_SEND_FAILED event. */ @@ -1052,29 +1102,55 @@ struct sctp_outq { /* Corked? */ char cork; - - /* Is this structure empty? */ - char empty; }; void sctp_outq_init(struct sctp_association *, struct sctp_outq *); void sctp_outq_teardown(struct sctp_outq *); void sctp_outq_free(struct sctp_outq*); -int sctp_outq_tail(struct sctp_outq *, struct sctp_chunk *chunk); +void sctp_outq_tail(struct sctp_outq *, struct sctp_chunk *chunk, gfp_t); int sctp_outq_sack(struct sctp_outq *, struct sctp_chunk *); int sctp_outq_is_empty(const struct sctp_outq *); -void sctp_outq_restart(struct sctp_outq *); - -void sctp_retransmit(struct sctp_outq *, struct sctp_transport *, - sctp_retransmit_reason_t); +void sctp_retransmit(struct sctp_outq *q, struct sctp_transport *transport, + enum sctp_retransmit_reason reason); void sctp_retransmit_mark(struct sctp_outq *, struct sctp_transport *, __u8); -int sctp_outq_uncork(struct sctp_outq *); +void sctp_outq_uncork(struct sctp_outq *, gfp_t gfp); +void sctp_prsctp_prune(struct sctp_association *asoc, + struct sctp_sndrcvinfo *sinfo, int msg_len); +void sctp_generate_fwdtsn(struct sctp_outq *q, __u32 sack_ctsn); /* Uncork and flush an outqueue. */ static inline void sctp_outq_cork(struct sctp_outq *q) { q->cork = 1; } +/* SCTP skb control block. + * sctp_input_cb is currently used on rx and sock rx queue + */ +struct sctp_input_cb { + union { + struct inet_skb_parm h4; +#if IS_ENABLED(CONFIG_IPV6) + struct inet6_skb_parm h6; +#endif + } header; + struct sctp_chunk *chunk; + struct sctp_af *af; + __be16 encap_port; +}; +#define SCTP_INPUT_CB(__skb) ((struct sctp_input_cb *)&((__skb)->cb[0])) + +struct sctp_output_cb { + struct sk_buff *last; +}; +#define SCTP_OUTPUT_CB(__skb) ((struct sctp_output_cb *)&((__skb)->cb[0])) + +static inline const struct sk_buff *sctp_gso_headskb(const struct sk_buff *skb) +{ + const struct sctp_chunk *chunk = SCTP_INPUT_CB(skb)->chunk; + + return chunk->head_skb ? : skb; +} + /* These bind address data fields common between endpoints and associations */ struct sctp_bind_addr { @@ -1098,13 +1174,13 @@ void sctp_bind_addr_init(struct sctp_bind_addr *, __u16 port); void sctp_bind_addr_free(struct sctp_bind_addr *); int sctp_bind_addr_copy(struct net *net, struct sctp_bind_addr *dest, const struct sctp_bind_addr *src, - sctp_scope_t scope, gfp_t gfp, + enum sctp_scope scope, gfp_t gfp, int flags); int sctp_bind_addr_dup(struct sctp_bind_addr *dest, const struct sctp_bind_addr *src, gfp_t gfp); int sctp_add_bind_addr(struct sctp_bind_addr *, union sctp_addr *, - __u8 addr_state, gfp_t gfp); + int new_size, __u8 addr_state, gfp_t gfp); int sctp_del_bind_addr(struct sctp_bind_addr *, union sctp_addr *); int sctp_bind_addr_match(struct sctp_bind_addr *, const union sctp_addr *, struct sctp_sock *); @@ -1112,6 +1188,8 @@ int sctp_bind_addr_conflict(struct sctp_bind_addr *, const union sctp_addr *, struct sctp_sock *, struct sctp_sock *); int sctp_bind_addr_state(const struct sctp_bind_addr *bp, const union sctp_addr *addr); +int sctp_bind_addrs_check(struct sctp_sock *sp, + struct sctp_sock *sp2, int cnt2); union sctp_addr *sctp_find_unmatch_addr(struct sctp_bind_addr *bp, const union sctp_addr *addrs, int addrcnt, @@ -1122,21 +1200,21 @@ union sctp_params sctp_bind_addrs_to_raw(const struct sctp_bind_addr *bp, int sctp_raw_to_bind_addrs(struct sctp_bind_addr *bp, __u8 *raw, int len, __u16 port, gfp_t gfp); -sctp_scope_t sctp_scope(const union sctp_addr *); -int sctp_in_scope(struct net *net, const union sctp_addr *addr, const sctp_scope_t scope); +enum sctp_scope sctp_scope(const union sctp_addr *addr); +int sctp_in_scope(struct net *net, const union sctp_addr *addr, + const enum sctp_scope scope); int sctp_is_any(struct sock *sk, const union sctp_addr *addr); -int sctp_addr_is_valid(const union sctp_addr *addr); int sctp_is_ep_boundall(struct sock *sk); /* What type of endpoint? */ -typedef enum { +enum sctp_endpoint_type { SCTP_EP_TYPE_SOCKET, SCTP_EP_TYPE_ASSOCIATION, -} sctp_endpoint_type_t; +}; /* - * A common base class to bridge the implmentation view of a + * A common base class to bridge the implementation view of a * socket (usually listening) endpoint versus an association's * local endpoint. * This common structure is useful for several purposes: @@ -1152,23 +1230,22 @@ typedef enum { */ struct sctp_ep_common { - /* Fields to help us manage our entries in the hash tables. */ - struct hlist_node node; - int hashent; - /* Runtime type information. What kind of endpoint is this? */ - sctp_endpoint_type_t type; + enum sctp_endpoint_type type; /* Some fields to help us manage this object. * refcnt - Reference count access to this object. * dead - Do not attempt to use this object. */ - atomic_t refcnt; + refcount_t refcnt; bool dead; /* What socket does this endpoint belong to? */ struct sock *sk; + /* Cache netns and it won't change once set */ + struct net *net; + /* This is where we receive inbound chunks. */ struct sctp_inq inqueue; @@ -1204,6 +1281,10 @@ struct sctp_endpoint { /* Common substructure for endpoint and association. */ struct sctp_ep_common base; + /* Fields to help us manage our entries in the hash tables. */ + struct hlist_node node; + int hashent; + /* Associations: A list of current associations and mappings * to the data consumers for each association. This * may be in the form of a hash table or other @@ -1216,33 +1297,15 @@ struct sctp_endpoint { /* This is really a list of struct sctp_association entries. */ struct list_head asocs; - /* Secret Key: A secret key used by this endpoint to compute - * the MAC. This SHOULD be a cryptographic quality - * random number with a sufficient length. - * Discussion in [RFC1750] can be helpful in - * selection of the key. - */ - __u8 secret_key[SCTP_SECRET_SIZE]; - - /* digest: This is a digest of the sctp cookie. This field is - * only used on the receive path when we try to validate - * that the cookie has not been tampered with. We put - * this here so we pre-allocate this once and can re-use - * on every receive. - */ - __u8 *digest; - + /* Cookie authentication key used by this endpoint */ + struct hmac_sha256_key cookie_auth_key; + /* sendbuf acct. policy. */ __u32 sndbuf_policy; /* rcvbuf acct. policy. */ __u32 rcvbuf_policy; - /* SCTP AUTH: array of the HMACs that will be allocated - * we need this per association so that we don't serialize - */ - struct crypto_hash **auth_hmacs; - /* SCTP-AUTH: hmacs for the endpoint encoded into parameter */ struct sctp_hmac_algo_param *auth_hmacs_list; @@ -1252,9 +1315,18 @@ struct sctp_endpoint { /* SCTP-AUTH: endpoint shared keys */ struct list_head endpoint_shared_keys; __u16 active_key_id; + __u8 ecn_enable:1, + auth_enable:1, + intl_enable:1, + prsctp_enable:1, + asconf_enable:1, + reconf_enable:1; + + __u8 strreset_enable; + struct rcu_head rcu; }; -/* Recover the outter endpoint structure. */ +/* Recover the outer endpoint structure. */ static inline struct sctp_endpoint *sctp_ep(struct sctp_ep_common *base) { struct sctp_endpoint *ep; @@ -1267,25 +1339,28 @@ static inline struct sctp_endpoint *sctp_ep(struct sctp_ep_common *base) struct sctp_endpoint *sctp_endpoint_new(struct sock *, gfp_t); void sctp_endpoint_free(struct sctp_endpoint *); void sctp_endpoint_put(struct sctp_endpoint *); -void sctp_endpoint_hold(struct sctp_endpoint *); +int sctp_endpoint_hold(struct sctp_endpoint *ep); void sctp_endpoint_add_asoc(struct sctp_endpoint *, struct sctp_association *); struct sctp_association *sctp_endpoint_lookup_assoc( const struct sctp_endpoint *ep, const union sctp_addr *paddr, struct sctp_transport **); -int sctp_endpoint_is_peeled_off(struct sctp_endpoint *, - const union sctp_addr *); -struct sctp_endpoint *sctp_endpoint_is_match(struct sctp_endpoint *, - struct net *, const union sctp_addr *); -int sctp_has_association(struct net *net, const union sctp_addr *laddr, - const union sctp_addr *paddr); - -int sctp_verify_init(struct net *net, const struct sctp_association *asoc, - sctp_cid_t, sctp_init_chunk_t *peer_init, +bool sctp_endpoint_is_peeled_off(struct sctp_endpoint *ep, + const union sctp_addr *paddr); +struct sctp_endpoint *sctp_endpoint_is_match(struct sctp_endpoint *ep, + struct net *net, + const union sctp_addr *laddr, + int dif, int sdif); +bool sctp_has_association(struct net *net, const union sctp_addr *laddr, + const union sctp_addr *paddr, int dif, int sdif); + +int sctp_verify_init(struct net *net, const struct sctp_endpoint *ep, + const struct sctp_association *asoc, + enum sctp_cid cid, struct sctp_init_chunk *peer_init, struct sctp_chunk *chunk, struct sctp_chunk **err_chunk); int sctp_process_init(struct sctp_association *, struct sctp_chunk *chunk, const union sctp_addr *peer, - sctp_init_chunk_t *init, gfp_t gfp); + struct sctp_init_chunk *init, gfp_t gfp); __u32 sctp_generate_tag(const struct sctp_endpoint *); __u32 sctp_generate_tsn(const struct sctp_endpoint *); @@ -1297,6 +1372,129 @@ struct sctp_inithdr_host { __u32 initial_tsn; }; +struct sctp_stream_priorities { + /* List of priorities scheduled */ + struct list_head prio_sched; + /* List of streams scheduled */ + struct list_head active; + /* The next stream in line */ + struct sctp_stream_out_ext *next; + __u16 prio; + __u16 users; +}; + +struct sctp_stream_out_ext { + __u64 abandoned_unsent[SCTP_PR_INDEX(MAX) + 1]; + __u64 abandoned_sent[SCTP_PR_INDEX(MAX) + 1]; + struct list_head outq; /* chunks enqueued by this stream */ + union { + struct { + /* Scheduled streams list */ + struct list_head prio_list; + struct sctp_stream_priorities *prio_head; + }; + /* Fields used by RR scheduler */ + struct { + struct list_head rr_list; + }; + struct { + struct list_head fc_list; + __u32 fc_length; + __u16 fc_weight; + }; + }; +}; + +struct sctp_stream_out { + union { + __u32 mid; + __u16 ssn; + }; + __u32 mid_uo; + struct sctp_stream_out_ext *ext; + __u8 state; +}; + +struct sctp_stream_in { + union { + __u32 mid; + __u16 ssn; + }; + __u32 mid_uo; + __u32 fsn; + __u32 fsn_uo; + char pd_mode; + char pd_mode_uo; +}; + +struct sctp_stream { + GENRADIX(struct sctp_stream_out) out; + GENRADIX(struct sctp_stream_in) in; + + __u16 outcnt; + __u16 incnt; + /* Current stream being sent, if any */ + struct sctp_stream_out *out_curr; + union { + /* Fields used by priority scheduler */ + struct { + /* List of priorities scheduled */ + struct list_head prio_list; + }; + /* Fields used by RR scheduler */ + struct { + /* List of streams scheduled */ + struct list_head rr_list; + /* The next stream in line */ + struct sctp_stream_out_ext *rr_next; + }; + struct { + struct list_head fc_list; + }; + }; + struct sctp_stream_interleave *si; +}; + +static inline struct sctp_stream_out *sctp_stream_out( + struct sctp_stream *stream, + __u16 sid) +{ + return genradix_ptr(&stream->out, sid); +} + +static inline struct sctp_stream_in *sctp_stream_in( + struct sctp_stream *stream, + __u16 sid) +{ + return genradix_ptr(&stream->in, sid); +} + +#define SCTP_SO(s, i) sctp_stream_out((s), (i)) +#define SCTP_SI(s, i) sctp_stream_in((s), (i)) + +#define SCTP_STREAM_CLOSED 0x00 +#define SCTP_STREAM_OPEN 0x01 + +static inline __u16 sctp_datachk_len(const struct sctp_stream *stream) +{ + return stream->si->data_chunk_len; +} + +static inline __u16 sctp_datahdr_len(const struct sctp_stream *stream) +{ + return stream->si->data_chunk_len - sizeof(struct sctp_chunkhdr); +} + +static inline __u16 sctp_ftsnchk_len(const struct sctp_stream *stream) +{ + return stream->si->ftsn_chunk_len; +} + +static inline __u16 sctp_ftsnhdr_len(const struct sctp_stream *stream) +{ + return stream->si->ftsn_chunk_len - sizeof(struct sctp_chunkhdr); +} + /* SCTP_GET_ASSOC_STATS counters */ struct sctp_priv_assoc_stats { /* Maximum observed rto in the association during subsequent @@ -1367,12 +1565,6 @@ struct sctp_association { /* This is all information about our peer. */ struct { - /* rwnd - * - * Peer Rwnd : Current calculated value of the peer's rwnd. - */ - __u32 rwnd; - /* transport_addr_list * * Peer : A list of SCTP transport addresses that the @@ -1390,6 +1582,12 @@ struct sctp_association { */ struct list_head transport_addr_list; + /* rwnd + * + * Peer Rwnd : Current calculated value of the peer's rwnd. + */ + __u32 rwnd; + /* transport_count * * Peer : A count of the number of peer addresses @@ -1472,39 +1670,42 @@ struct sctp_association { */ struct sctp_tsnmap tsn_map; - /* Ack State : This flag indicates if the next received - * : packet is to be responded to with a - * : SACK. This is initializedto 0. When a packet - * : is received it is incremented. If this value - * : reaches 2 or more, a SACK is sent and the - * : value is reset to 0. Note: This is used only - * : when no DATA chunks are received out of - * : order. When DATA chunks are out of order, - * : SACK's are not delayed (see Section 6). + /* This mask is used to disable sending the ASCONF chunk + * with specified parameter to peer. */ - __u8 sack_needed; /* Do we need to sack the peer? */ - __u32 sack_cnt; - __u32 sack_generation; + __be16 addip_disabled_mask; /* These are capabilities which our peer advertised. */ - __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? */ + __u16 ecn_capable:1, /* Can peer do ECN? */ + ipv4_address:1, /* Peer understands IPv4 addresses? */ + ipv6_address:1, /* Peer understands IPv6 addresses? */ asconf_capable:1, /* Does peer support ADDIP? */ prsctp_capable:1, /* Can peer do PR-SCTP? */ - auth_capable:1; /* Is peer doing SCTP-AUTH? */ + reconf_capable:1, /* Can peer do RE-CONFIG? */ + intl_capable:1, /* Can peer do INTERLEAVE */ + auth_capable:1, /* Is peer doing SCTP-AUTH? */ + /* sack_needed: + * This flag indicates if the next received + * packet is to be responded to with a + * SACK. This is initialized to 0. When a packet + * is received sack_cnt is incremented. If this value + * reaches 2 or more, a SACK is sent and the + * value is reset to 0. Note: This is used only + * when no DATA chunks are received out of + * order. When DATA chunks are out of order, + * SACK's are not delayed (see Section 6). + */ + sack_needed:1, /* Do we need to sack the peer? */ + sack_generation:1, + zero_window_announced:1; - __u32 adaptation_ind; /* Adaptation Code point. */ + __u32 sack_cnt; - /* This mask is used to disable sending the ASCONF chunk - * with specified parameter to peer. - */ - __be16 addip_disabled_mask; + __u32 adaptation_ind; /* Adaptation Code point. */ struct sctp_inithdr_host i; - int cookie_len; void *cookie; + int cookie_len; /* ADDIP Section 4.2 Upon reception of an ASCONF Chunk. * C1) ... "Peer-Serial-Number'. This value MUST be initialized to the @@ -1516,9 +1717,9 @@ struct sctp_association { * and authenticated chunk list. All that is part of the * cookie and these are just pointers to those locations */ - sctp_random_param_t *peer_random; - sctp_chunks_param_t *peer_chunks; - sctp_hmac_algo_param_t *peer_hmacs; + struct sctp_random_param *peer_random; + struct sctp_chunks_param *peer_chunks; + struct sctp_hmac_algo_param *peer_hmacs; } peer; /* State : A state variable indicating what state the @@ -1534,16 +1735,16 @@ struct sctp_association { * * State takes values from SCTP_STATE_*. */ - sctp_state_t state; - - /* The cookie life I award for any cookie. */ - ktime_t cookie_life; + enum sctp_state state; /* Overall : The overall association error count. * Error Count : [Clear this any time I get something.] */ int overall_error_count; + /* The cookie life I award for any cookie. */ + ktime_t cookie_life; + /* These are the association's initial, max, and min RTO values. * These values will be initialized by system defaults, but can * be modified via the SCTP_RTOINFO socket option. @@ -1556,7 +1757,7 @@ struct sctp_association { int max_burst; /* This is the max_retrans value for the association. This value will - * be initialized initialized from system defaults, but can be + * be initialized from system defaults, but can be * modified by the SCTP_ASSOCINFO socket option. */ int max_retrans; @@ -1565,7 +1766,9 @@ struct sctp_association { * and will be initialized from the assocs value. This can be * changed using the SCTP_PEER_ADDR_THLDS socket option */ - int pf_retrans; + __u16 pf_retrans; + /* Used for primary path switchover. */ + __u16 ps_retrans; /* Maximum number of times the endpoint will retransmit INIT */ __u16 max_init_attempts; @@ -1581,12 +1784,18 @@ struct sctp_association { * will be inherited by all new transports. */ unsigned long hbinterval; + unsigned long probe_interval; + + __be16 encap_port; /* This is the max_retrans value for new transports in the * association. */ __u16 pathmaxrxt; + __u32 flowlabel; + __u8 dscp; + /* Flag that path mtu update is pending */ __u8 pmtu_pending; @@ -1598,10 +1807,9 @@ struct sctp_association { /* Flags controlling Heartbeat, SACK delay, and Path MTU Discovery. */ __u32 param_flags; + __u32 sackfreq; /* SACK delay timeout */ unsigned long sackdelay; - __u32 sackfreq; - unsigned long timeouts[SCTP_NUM_TIMEOUT_TYPES]; struct timer_list timers[SCTP_NUM_TIMEOUT_TYPES]; @@ -1609,12 +1817,12 @@ struct sctp_association { /* Transport to which SHUTDOWN chunk was last sent. */ struct sctp_transport *shutdown_last_sent_to; - /* How many times have we resent a SHUTDOWN */ - int shutdown_retries; - /* Transport to which INIT chunk was last sent. */ struct sctp_transport *init_last_sent_to; + /* How many times have we resent a SHUTDOWN */ + int shutdown_retries; + /* Next TSN : The next TSN number to be assigned to a new * : DATA chunk. This is sent in the INIT or INIT * : ACK chunk to the peer and incremented each @@ -1671,7 +1879,7 @@ 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 + * a window, but not receive buffer (i.e small packets). This one * is releases slowly (1 PMTU at a time ). */ __u32 rwnd_press; @@ -1712,8 +1920,8 @@ struct sctp_association { /* Default receive parameters */ __u32 default_rcv_context; - /* This tracks outbound ssn for a given stream. */ - struct sctp_ssnmap *ssnmap; + /* Stream arrays */ + struct sctp_stream stream; /* All outbound chunks go through this structure. */ struct sctp_outq outqueue; @@ -1732,12 +1940,6 @@ struct sctp_association { /* How many duplicated TSNs have we seen? */ int numduptsns; - /* Number of seconds of idle time before an association is closed. - * In the association context, this is really used as a boolean - * since the real timeout is stored in the timeouts array - */ - __u32 autoclose; - /* These are to support * "SCTP Extensions for Dynamic Reconfiguration of IP Addresses * and Enforcement of Flow and Message Limits" @@ -1765,7 +1967,7 @@ struct sctp_association { /* ADDIP Section 5.2 Upon reception of an ASCONF Chunk. * - * This is needed to implement itmes E1 - E4 of the updated + * This is needed to implement items E1 - E4 of the updated * spec. Here is the justification: * * Since the peer may bundle multiple ASCONF chunks toward us, @@ -1776,7 +1978,7 @@ struct sctp_association { /* These ASCONF chunks are waiting to be sent. * - * These chunaks can't be pushed to outqueue until receiving + * These chunks can't be pushed to outqueue until receiving * ASCONF_ACK for the previous ASCONF indicated by * addip_last_asconf, so as to guarantee that only one ASCONF * is in flight at any time. @@ -1825,20 +2027,21 @@ struct sctp_association { * after reaching 4294967295. */ __u32 addip_serial; - union sctp_addr *asconf_addr_del_pending; int src_out_of_asoc_ok; + union sctp_addr *asconf_addr_del_pending; struct sctp_transport *new_transport; /* SCTP AUTH: list of the endpoint shared keys. These - * keys are provided out of band by the user applicaton + * keys are provided out of band by the user application * and can't change during the lifetime of the association */ struct list_head endpoint_shared_keys; /* SCTP AUTH: - * The current generated assocaition shared key (secret) + * The current generated association shared key (secret) */ struct sctp_auth_bytes *asoc_shared_key; + struct sctp_shared_key *shkey; /* SCTP AUTH: hmac id of the first peer requested algorithm * that we support. @@ -1848,9 +2051,39 @@ struct sctp_association { __u16 active_key_id; __u8 need_ecne:1, /* Need to send an ECNE Chunk? */ - temp:1; /* Is it a temporary association? */ + temp:1, /* Is it a temporary association? */ + pf_expose:2, /* Expose pf state? */ + force_delay:1; + + __u8 strreset_enable; + __u8 strreset_outstanding; /* request param count on the fly */ + + __u32 strreset_outseq; /* Update after receiving response */ + __u32 strreset_inseq; /* Update after receiving request */ + __u32 strreset_result[2]; /* save the results of last 2 responses */ + + struct sctp_chunk *strreset_chunk; /* save request chunk */ struct sctp_priv_assoc_stats stats; + + int sent_cnt_removable; + + __u16 subscribe; + + __u64 abandoned_unsent[SCTP_PR_INDEX(MAX) + 1]; + __u64 abandoned_sent[SCTP_PR_INDEX(MAX) + 1]; + + /* Security identifiers from incoming (INIT). These are set by + * security_sctp_assoc_request(). These will only be used by + * SCTP TCP type sockets and peeled off connections as they + * cause a new socket to be generated. security_sctp_sk_clone() + * will then plug these into the new socket. + */ + + u32 secid; + u32 peer_secid; + + struct rcu_head rcu; }; @@ -1861,7 +2094,7 @@ enum { SCTP_ASSOC_EYECATCHER = 0xa550c123, }; -/* Recover the outter association structure. */ +/* Recover the outer association structure. */ static inline struct sctp_association *sctp_assoc(struct sctp_ep_common *base) { struct sctp_association *asoc; @@ -1874,8 +2107,8 @@ static inline struct sctp_association *sctp_assoc(struct sctp_ep_common *base) struct sctp_association * -sctp_association_new(const struct sctp_endpoint *, const struct sock *, - sctp_scope_t scope, gfp_t gfp); +sctp_association_new(const struct sctp_endpoint *ep, const struct sock *sk, + enum sctp_scope scope, gfp_t gfp); void sctp_association_free(struct sctp_association *); void sctp_association_put(struct sctp_association *); void sctp_association_hold(struct sctp_association *); @@ -1891,33 +2124,30 @@ struct sctp_transport *sctp_assoc_add_peer(struct sctp_association *, const union sctp_addr *address, const gfp_t gfp, const int peer_state); -void sctp_assoc_del_peer(struct sctp_association *asoc, - const union sctp_addr *addr); void sctp_assoc_rm_peer(struct sctp_association *asoc, struct sctp_transport *peer); -void sctp_assoc_control_transport(struct sctp_association *, - struct sctp_transport *, - sctp_transport_cmd_t, sctp_sn_error_t); +void sctp_assoc_control_transport(struct sctp_association *asoc, + struct sctp_transport *transport, + enum sctp_transport_cmd command, + sctp_sn_error_t error); struct sctp_transport *sctp_assoc_lookup_tsn(struct sctp_association *, __u32); -struct sctp_transport *sctp_assoc_is_match(struct sctp_association *, - struct net *, - const union sctp_addr *, - const union sctp_addr *); void sctp_assoc_migrate(struct sctp_association *, struct sock *); -void sctp_assoc_update(struct sctp_association *old, - struct sctp_association *new); +int sctp_assoc_update(struct sctp_association *old, + struct sctp_association *new); __u32 sctp_association_get_next_tsn(struct sctp_association *); -void sctp_assoc_sync_pmtu(struct sock *, struct sctp_association *); +void sctp_assoc_update_frag_point(struct sctp_association *asoc); +void sctp_assoc_set_pmtu(struct sctp_association *asoc, __u32 pmtu); +void sctp_assoc_sync_pmtu(struct sctp_association *asoc); void sctp_assoc_rwnd_increase(struct sctp_association *, unsigned int); void sctp_assoc_rwnd_decrease(struct sctp_association *, unsigned int); void sctp_assoc_set_primary(struct sctp_association *, struct sctp_transport *); void sctp_assoc_del_nonprimary_peers(struct sctp_association *, struct sctp_transport *); -int sctp_assoc_set_bind_addr_from_ep(struct sctp_association *, - sctp_scope_t, gfp_t); +int sctp_assoc_set_bind_addr_from_ep(struct sctp_association *asoc, + enum sctp_scope scope, gfp_t gfp); int sctp_assoc_set_bind_addr_from_cookie(struct sctp_association *, struct sctp_cookie*, gfp_t gfp); @@ -1933,15 +2163,19 @@ int sctp_cmp_addr_exact(const union sctp_addr *ss1, struct sctp_chunk *sctp_get_ecne_prepend(struct sctp_association *asoc); /* A convenience structure to parse out SCTP specific CMSGs. */ -typedef struct sctp_cmsgs { +struct sctp_cmsgs { struct sctp_initmsg *init; - struct sctp_sndrcvinfo *info; -} sctp_cmsgs_t; + struct sctp_sndrcvinfo *srinfo; + struct sctp_sndinfo *sinfo; + struct sctp_prinfo *prinfo; + struct sctp_authinfo *authinfo; + struct msghdr *addrs_msg; +}; /* Structure for tracking memory objects */ -typedef struct { +struct sctp_dbg_objcnt_entry { char *label; atomic_t *counter; -} sctp_dbg_objcnt_entry_t; +}; #endif /* __sctp_structs_h__ */ |
