/* SPDX-License-Identifier: GPL-2.0-or-later */ /* SCTP kernel implementation * (C) Copyright IBM Corp. 2001, 2004 * Copyright (c) 1999-2000 Cisco, Inc. * Copyright (c) 1999-2001 Motorola, Inc. * Copyright (c) 2001-2003 Intel Corp. * * This file is part of the SCTP kernel implementation * * The base lksctp header. * * Please send any bug reports or fixes you make to the * email address(es): * lksctp developers <linux-sctp@vger.kernel.org> * * Written or modified by: * La Monte H.P. Yarroll <piggy@acm.org> * Xingang Guo <xingang.guo@intel.com> * Jon Grimm <jgrimm@us.ibm.com> * Daisy Chang <daisyc@us.ibm.com> * Sridhar Samudrala <sri@us.ibm.com> * Ardelle Fan <ardelle.fan@intel.com> * Ryan Layer <rmlayer@us.ibm.com> * Kevin Gao <kevin.gao@intel.com>
*/
#ifndef __net_sctp_h__ #define __net_sctp_h__
/* Header Strategy. * Start getting some control over the header file dependencies: * includes * constants * structs * prototypes * macros, externs, and inlines * * Move test_frame specific items out of the kernel headers * and into the test frame headers. This is not perfect in any sense * and will continue to evolve.
*/
/* * sctp/protocol.c
*/ int sctp_copy_local_addr_list(struct net *net, struct sctp_bind_addr *addr, enum sctp_scope, gfp_t gfp, int flags); struct sctp_pf *sctp_get_pf_specific(sa_family_t family); int sctp_register_pf(struct sctp_pf *, sa_family_t); void sctp_addr_wq_mgmt(struct net *, struct sctp_sockaddr_entry *, int); int sctp_udp_sock_start(struct net *net); void sctp_udp_sock_stop(struct net *net);
/* * sctp/socket.c
*/ int sctp_inet_connect(struct socket *sock, struct sockaddr *uaddr, int addr_len, int flags); int sctp_backlog_rcv(struct sock *sk, struct sk_buff *skb); int sctp_inet_listen(struct socket *sock, int backlog); void sctp_write_space(struct sock *sk); void sctp_data_ready(struct sock *sk);
__poll_t sctp_poll(struct file *file, struct socket *sock,
poll_table *wait); void sctp_sock_rfree(struct sk_buff *skb); void sctp_copy_sock(struct sock *newsk, struct sock *sk, struct sctp_association *asoc); externstruct percpu_counter sctp_sockets_allocated; int sctp_asconf_mgmt(struct sctp_sock *, struct sctp_sockaddr_entry *); struct sk_buff *sctp_skb_recv_datagram(struct sock *, int, int *);
typedefint (*sctp_callback_t)(struct sctp_endpoint *, struct sctp_transport *, void *); void sctp_transport_walk_start(struct rhashtable_iter *iter); void sctp_transport_walk_stop(struct rhashtable_iter *iter); struct sctp_transport *sctp_transport_get_next(struct net *net, struct rhashtable_iter *iter); struct sctp_transport *sctp_transport_get_idx(struct net *net, struct rhashtable_iter *iter, int pos); int sctp_transport_lookup_process(sctp_callback_t cb, struct net *net, constunion sctp_addr *laddr, constunion sctp_addr *paddr, void *p, int dif); int sctp_transport_traverse_process(sctp_callback_t cb, sctp_callback_t cb_done, struct net *net, int *pos, void *p); int sctp_for_each_endpoint(int (*cb)(struct sctp_endpoint *, void *), void *p); int sctp_get_sctp_info(struct sock *sk, struct sctp_association *asoc, struct sctp_info *info);
/* * sctp/primitive.c
*/ int sctp_primitive_ASSOCIATE(struct net *, struct sctp_association *, void *arg); int sctp_primitive_SHUTDOWN(struct net *, struct sctp_association *, void *arg); int sctp_primitive_ABORT(struct net *, struct sctp_association *, void *arg); int sctp_primitive_SEND(struct net *, struct sctp_association *, void *arg); int sctp_primitive_REQUESTHEARTBEAT(struct net *, struct sctp_association *, void *arg); int sctp_primitive_ASCONF(struct net *, struct sctp_association *, void *arg); int sctp_primitive_RECONF(struct net *net, struct sctp_association *asoc, void *arg);
/* * sctp/input.c
*/ int sctp_rcv(struct sk_buff *skb); int sctp_v4_err(struct sk_buff *skb, u32 info); int sctp_hash_endpoint(struct sctp_endpoint *ep); void sctp_unhash_endpoint(struct sctp_endpoint *); struct sock *sctp_err_lookup(struct net *net, int family, struct sk_buff *, struct sctphdr *, struct sctp_association **, struct sctp_transport **); void sctp_err_finish(struct sock *, struct sctp_transport *); int sctp_udp_v4_err(struct sock *sk, struct sk_buff *skb); int sctp_udp_v6_err(struct sock *sk, struct sk_buff *skb); void sctp_icmp_frag_needed(struct sock *, struct sctp_association *, struct sctp_transport *t, __u32 pmtu); void sctp_icmp_redirect(struct sock *, struct sctp_transport *, struct sk_buff *); void sctp_icmp_proto_unreachable(struct sock *sk, struct sctp_association *asoc, struct sctp_transport *t); int sctp_transport_hashtable_init(void); void sctp_transport_hashtable_destroy(void); int sctp_hash_transport(struct sctp_transport *t); void sctp_unhash_transport(struct sctp_transport *t); struct sctp_transport *sctp_addrs_lookup_transport( struct net *net, constunion sctp_addr *laddr, constunion sctp_addr *paddr, int dif, int sdif); struct sctp_transport *sctp_epaddr_lookup_transport( conststruct sctp_endpoint *ep, constunion sctp_addr *paddr); bool sctp_sk_bound_dev_eq(struct net *net, int bound_dev_if, int dif, int sdif);
/* * sctp/proc.c
*/ int __net_init sctp_proc_init(struct net *net);
/* * sctp/offload.c
*/ int sctp_offload_init(void);
/* helper function to track stats about max rto and related transport */ staticinlinevoid sctp_max_rto(struct sctp_association *asoc, struct sctp_transport *trans)
{ if (asoc->stats.max_obs_rto < (__u64)trans->rto) {
asoc->stats.max_obs_rto = trans->rto;
memset(&asoc->stats.obs_rto_ipaddr, 0, sizeof(struct sockaddr_storage));
memcpy(&asoc->stats.obs_rto_ipaddr, &trans->ipaddr,
trans->af_specific->sockaddr_len);
}
}
/* * Macros for keeping a global reference of object allocations.
*/ #ifdef CONFIG_SCTP_DBG_OBJCNT
/* Macro to help create new entries in the global array of * objcnt counters.
*/ #define SCTP_DBG_OBJCNT_ENTRY(name) \
{.label= #name, .counter= &sctp_dbg_objcnt_## name}
/* Map an association to an assoc_id. */ staticinline sctp_assoc_t sctp_assoc2id(conststruct sctp_association *asoc)
{ return asoc ? asoc->assoc_id : 0;
}
staticinlineenum sctp_sstat_state
sctp_assoc_to_state(conststruct sctp_association *asoc)
{ /* SCTP's uapi always had SCTP_EMPTY(=0) as a dummy state, but we * got rid of it in kernel space. Therefore SCTP_CLOSED et al * start at =1 in user space, but actually as =0 in kernel space. * Now that we can not break user space and SCTP_EMPTY is exposed * there, we need to fix it up with an ugly offset not to break * applications. :(
*/ return asoc->state + 1;
}
/* Look up the association by its id. */ struct sctp_association *sctp_id2assoc(struct sock *sk, sctp_assoc_t id);
/* A macro to walk a list of skbs. */ #define sctp_skb_for_each(pos, head, tmp) \
skb_queue_walk_safe(head, pos, tmp)
/** * sctp_list_dequeue - remove from the head of the queue * @list: list to dequeue from * * Remove the head of the list. The head item is * returned or %NULL if the list is empty.
*/
if (!list_empty(list)) {
result = list->next;
list_del_init(result);
} return result;
}
/* SCTP version of skb_set_owner_r. We need this one because * of the way we have to do receive buffer accounting on bundled * chunks.
*/ staticinlinevoid sctp_skb_set_owner_r(struct sk_buff *skb, struct sock *sk)
{ struct sctp_ulpevent *event = sctp_skb2event(skb);
skb_orphan(skb);
skb->sk = sk;
skb->destructor = sctp_sock_rfree;
atomic_add(event->rmem_len, &sk->sk_rmem_alloc); /* * This mimics the behavior of skb_set_owner_r
*/
sk_mem_charge(sk, event->rmem_len);
}
/* Tests if the list has one and only one entry. */ staticinlineint sctp_list_single_entry(struct list_head *head)
{ return list_is_singular(head);
}
/* Walk through a list of TLV parameters. Don't trust the * individual parameter lengths and instead depend on * the chunk length to indicate when to stop. Make sure * there is room for a param header too.
*/ #define sctp_walk_params(pos, chunk)\
_sctp_walk_params((pos), (chunk), ntohs((chunk)->chunk_hdr.length))
/* Convert from an IP version number to an Address Family symbol. */ staticinlineint ipver2af(__u8 ipver)
{ switch (ipver) { case 4: return AF_INET; case 6: return AF_INET6; default: return 0;
}
}
/* Convert from an address parameter type to an address family. */ staticinlineint param_type2af(__be16 type)
{ switch (type) { case SCTP_PARAM_IPV4_ADDRESS: return AF_INET; case SCTP_PARAM_IPV6_ADDRESS: return AF_INET6; default: return 0;
}
}
/* Warning: The following hash functions assume a power of two 'size'. */ /* This is the hash function for the SCTP port hash table. */ staticinlineint sctp_phashfn(struct net *net, __u16 lport)
{ return (net_hash_mix(net) + lport) & (sctp_port_hashsize - 1);
}
/* This is the hash function for the endpoint hash table. */ staticinlineint sctp_ep_hashfn(struct net *net, __u16 lport)
{ return (net_hash_mix(net) + lport) & (sctp_ep_hashsize - 1);
}
/* The cookie is always 0 since this is how it's used in the * pmtu code.
*/ staticinlinestruct dst_entry *sctp_transport_dst_check(struct sctp_transport *t)
{ if (t->dst && !dst_check(t->dst, t->dst_cookie))
sctp_transport_dst_release(t);
return t->dst;
}
/* Calculate max payload size given a MTU, or the total overhead if * given MTU is zero
*/ staticinline __u32 __sctp_mtu_payload(conststruct sctp_sock *sp, conststruct sctp_transport *t,
__u32 mtu, __u32 extra)
{
__u32 overhead = sizeof(struct sctphdr) + extra;
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.