Commit 1402a73c authored by Jon Grimm's avatar Jon Grimm

[SCTP] Add SCTP_SET_PEER_PRIMARY get/setsockopt.

Also, rename all sctp_protocol_t -> struct sctp_protocol.
Non-UDP-style SCTP sockets should ignore associd fields, so added
this function into sctp_id2assoc() in anticipation of Sridhar's
TCP-style work. 
parent 294cb923
......@@ -121,9 +121,10 @@
/*
* sctp_protocol.c
*/
extern sctp_protocol_t sctp_proto;
extern struct sctp_protocol sctp_proto;
extern struct sock *sctp_get_ctl_sock(void);
extern int sctp_copy_local_addr_list(sctp_protocol_t *, sctp_bind_addr_t *,
extern int sctp_copy_local_addr_list(struct sctp_protocol *,
struct sctp_bind_addr *,
sctp_scope_t, int priority, int flags);
extern struct sctp_pf *sctp_get_pf_specific(sa_family_t family);
extern int sctp_register_pf(struct sctp_pf *, sa_family_t);
......@@ -348,25 +349,10 @@ static inline sctp_assoc_t sctp_assoc2id(const sctp_association_t *asoc)
return (sctp_assoc_t) asoc;
}
/* Look up the association by its id. */
static inline sctp_association_t *sctp_id2assoc(const struct sock *sk, sctp_assoc_t id)
{
sctp_association_t *asoc = NULL;
/* First, verify that this is a kernel address. */
if (sctp_is_valid_kaddr((unsigned long) id)) {
sctp_association_t *temp = (sctp_association_t *) id;
/* Verify that this _is_ an sctp_association_t
* data structure and if so, that the socket matches.
*/
if ((SCTP_ASSOC_EYECATCHER == temp->eyecatcher) &&
(temp->base.sk == sk))
asoc = temp;
}
sctp_association_t *sctp_id2assoc(struct sock *sk, sctp_assoc_t id);
return asoc;
}
/* A macro to walk a list of skbs. */
#define sctp_skb_for_each(pos, head, tmp) \
......@@ -494,7 +480,7 @@ extern void sctp_put_port(struct sock *sk);
/* Static inline functions. */
/* Return the SCTP protocol structure. */
static inline sctp_protocol_t *sctp_get_protocol(void)
static inline struct sctp_protocol *sctp_get_protocol(void)
{
return &sctp_proto;
}
......@@ -523,21 +509,21 @@ static inline int ipver2af(__u8 ipver)
/* This is the hash function for the SCTP port hash table. */
static inline int sctp_phashfn(__u16 lport)
{
sctp_protocol_t *sctp_proto = sctp_get_protocol();
struct sctp_protocol *sctp_proto = sctp_get_protocol();
return (lport & (sctp_proto->port_hashsize - 1));
}
/* This is the hash function for the endpoint hash table. */
static inline int sctp_ep_hashfn(__u16 lport)
{
sctp_protocol_t *sctp_proto = sctp_get_protocol();
struct sctp_protocol *sctp_proto = sctp_get_protocol();
return (lport & (sctp_proto->ep_hashsize - 1));
}
/* This is the hash function for the association hash table. */
static inline int sctp_assoc_hashfn(__u16 lport, __u16 rport)
{
sctp_protocol_t *sctp_proto = sctp_get_protocol();
struct sctp_protocol *sctp_proto = sctp_get_protocol();
int h = (lport << 16) + rport;
h ^= h>>8;
return (h & (sctp_proto->assoc_hashsize - 1));
......@@ -549,7 +535,7 @@ static inline int sctp_assoc_hashfn(__u16 lport, __u16 rport)
*/
static inline int sctp_vtag_hashfn(__u16 lport, __u16 rport, __u32 vtag)
{
sctp_protocol_t *sctp_proto = sctp_get_protocol();
struct sctp_protocol *sctp_proto = sctp_get_protocol();
int h = (lport << 16) + rport;
h ^= vtag;
return (h & (sctp_proto->assoc_hashsize-1));
......
......@@ -118,7 +118,6 @@ struct sctp_opt;
struct sctp_endpoint_common;
struct sctp_ssnmap;
typedef struct sctp_protocol sctp_protocol_t;
typedef struct sctp_endpoint sctp_endpoint_t;
typedef struct sctp_association sctp_association_t;
typedef struct sctp_packet sctp_packet_t;
......@@ -254,7 +253,7 @@ struct sctp_af {
void (*get_saddr) (struct sctp_association *asoc,
struct dst_entry *dst,
union sctp_addr *daddr,
union sctp_addr *saddr);
union sctp_addr *saddr);
void (*copy_addrlist) (struct list_head *,
struct net_device *);
void (*dst_saddr) (union sctp_addr *saddr,
......@@ -1130,8 +1129,9 @@ static inline sctp_endpoint_t *sctp_ep(sctp_endpoint_common_t *base)
}
/* These are function signatures for manipulating endpoints. */
sctp_endpoint_t *sctp_endpoint_new(sctp_protocol_t *, struct sock *, int);
sctp_endpoint_t *sctp_endpoint_init(sctp_endpoint_t *, sctp_protocol_t *,
sctp_endpoint_t *sctp_endpoint_new(struct sctp_protocol *, struct sock *, int);
sctp_endpoint_t *sctp_endpoint_init(struct sctp_endpoint *,
struct sctp_protocol *,
struct sock *, int priority);
void sctp_endpoint_free(sctp_endpoint_t *);
void sctp_endpoint_put(sctp_endpoint_t *);
......@@ -1143,7 +1143,6 @@ sctp_association_t *sctp_endpoint_lookup_assoc(const sctp_endpoint_t *ep,
int sctp_endpoint_is_peeled_off(sctp_endpoint_t *, const union sctp_addr *);
sctp_endpoint_t *sctp_endpoint_is_match(sctp_endpoint_t *,
const union sctp_addr *);
int sctp_has_association(const union sctp_addr *laddr,
const union sctp_addr *paddr);
......@@ -1619,7 +1618,7 @@ struct sctp_transport *sctp_assoc_lookup_paddr(const sctp_association_t *,
struct sctp_transport *sctp_assoc_add_peer(sctp_association_t *,
const union sctp_addr *address,
const int priority);
void sctp_assoc_control_transport(sctp_association_t *,
void sctp_assoc_control_transport(struct sctp_association *,
struct sctp_transport *,
sctp_transport_cmd_t, sctp_sn_error_t);
struct sctp_transport *sctp_assoc_lookup_tsn(sctp_association_t *, __u32);
......@@ -1629,14 +1628,14 @@ struct sctp_transport *sctp_assoc_is_match(sctp_association_t *,
void sctp_assoc_migrate(sctp_association_t *, struct sock *);
void sctp_assoc_update(sctp_association_t *dst, sctp_association_t *src);
__u32 __sctp_association_get_next_tsn(sctp_association_t *);
__u32 __sctp_association_get_tsn_block(sctp_association_t *, int);
__u16 __sctp_association_get_next_ssn(sctp_association_t *, __u16 sid);
void sctp_assoc_sync_pmtu(sctp_association_t *);
void sctp_assoc_rwnd_increase(sctp_association_t *, int);
void sctp_assoc_rwnd_decrease(sctp_association_t *, int);
__u32 sctp_association_get_next_tsn(struct sctp_association *);
__u32 sctp_association_get_tsn_block(struct sctp_association *, int);
void sctp_assoc_sync_pmtu(struct sctp_association *);
void sctp_assoc_rwnd_increase(struct sctp_association *, int);
void sctp_assoc_rwnd_decrease(struct sctp_association *, int);
void sctp_assoc_set_primary(struct sctp_association *,
struct sctp_transport *);
int sctp_assoc_set_bind_addr_from_ep(sctp_association_t *, int);
int sctp_assoc_set_bind_addr_from_cookie(sctp_association_t *,
sctp_cookie_t *, int);
......
......@@ -360,9 +360,25 @@ static void sctp_association_destroy(sctp_association_t *asoc)
}
}
/* Change the primary destination address for the peer. */
void sctp_assoc_set_primary(struct sctp_association *asoc,
struct sctp_transport *transport)
{
asoc->peer.primary_path = transport;
/* Set a default msg_name for events. */
memcpy(&asoc->peer.primary_addr, &transport->ipaddr,
sizeof(union sctp_addr));
/* If the primary path is changing, assume that the
* user wants to use this new path.
*/
if (transport->active)
asoc->peer.active_path = transport;
}
/* Add a transport address to an association. */
struct sctp_transport *sctp_assoc_add_peer(sctp_association_t *asoc,
struct sctp_transport *sctp_assoc_add_peer(struct sctp_association *asoc,
const union sctp_addr *addr,
int priority)
{
......@@ -460,11 +476,7 @@ struct sctp_transport *sctp_assoc_add_peer(sctp_association_t *asoc,
/* If we do not yet have a primary path, set one. */
if (NULL == asoc->peer.primary_path) {
asoc->peer.primary_path = peer;
/* Set a default msg_name for events. */
memcpy(&asoc->peer.primary_addr, &peer->ipaddr,
sizeof(union sctp_addr));
asoc->peer.active_path = peer;
sctp_assoc_set_primary(asoc, peer);
asoc->peer.retran_path = peer;
}
......@@ -603,7 +615,7 @@ void sctp_association_put(sctp_association_t *asoc)
/* Allocate the next TSN, Transmission Sequence Number, for the given
* association.
*/
__u32 __sctp_association_get_next_tsn(sctp_association_t *asoc)
__u32 sctp_association_get_next_tsn(sctp_association_t *asoc)
{
/* From Section 1.6 Serial Number Arithmetic:
* Transmission Sequence Numbers wrap around when they reach
......@@ -618,7 +630,7 @@ __u32 __sctp_association_get_next_tsn(sctp_association_t *asoc)
}
/* Allocate 'num' TSNs by incrementing the association's TSN by num. */
__u32 __sctp_association_get_tsn_block(sctp_association_t *asoc, int num)
__u32 sctp_association_get_tsn_block(sctp_association_t *asoc, int num)
{
__u32 retval = asoc->next_tsn;
......@@ -942,7 +954,7 @@ struct sctp_transport *sctp_assoc_choose_shutdown_transport(sctp_association_t *
{
/* If this is the first time SHUTDOWN is sent, use the active path,
* else use the retran path. If the last SHUTDOWN was sent over the
* retran path, update the retran path and use it.
* retran path, update the retran path and use it.
*/
if (!asoc->shutdown_last_sent_to)
return asoc->peer.active_path;
......
......@@ -302,7 +302,7 @@ int sctp_bind_addr_match(sctp_bind_addr_t *bp, const union sctp_addr *addr,
static int sctp_copy_one_addr(sctp_bind_addr_t *dest, union sctp_addr *addr,
sctp_scope_t scope, int priority, int flags)
{
sctp_protocol_t *proto = sctp_get_protocol();
struct sctp_protocol *proto = sctp_get_protocol();
int error = 0;
if (sctp_is_any(addr)) {
......
......@@ -65,7 +65,7 @@ static void sctp_endpoint_bh_rcv(sctp_endpoint_t *ep);
/* Create a sctp_endpoint_t with all that boring stuff initialized.
* Returns NULL if there isn't enough memory.
*/
sctp_endpoint_t *sctp_endpoint_new(sctp_protocol_t *proto,
sctp_endpoint_t *sctp_endpoint_new(struct sctp_protocol *proto,
struct sock *sk, int priority)
{
sctp_endpoint_t *ep;
......@@ -89,7 +89,8 @@ sctp_endpoint_t *sctp_endpoint_new(sctp_protocol_t *proto,
/*
* Initialize the base fields of the endpoint structure.
*/
sctp_endpoint_t *sctp_endpoint_init(sctp_endpoint_t *ep, sctp_protocol_t *proto,
sctp_endpoint_t *sctp_endpoint_init(sctp_endpoint_t *ep,
struct sctp_protocol *proto,
struct sock *sk, int priority)
{
struct sctp_opt *sp = sctp_sk(sk);
......
......@@ -125,7 +125,7 @@ void sctp_outq_teardown(struct sctp_outq *q)
sctp_free_chunk(chunk);
}
/* Throw away any chunks in the retransmit queue. */
/* Throw away any chunks in the retransmit queue. */
list_for_each_safe(lchunk, temp, &q->retransmit) {
list_del(lchunk);
chunk = list_entry(lchunk, sctp_chunk_t, transmitted_list);
......@@ -241,7 +241,7 @@ void sctp_retransmit_insert(struct list_head *tlchunk, struct sctp_outq *q)
}
/* Mark all the eligible packets on a transport for retransmission. */
void sctp_retransmit_mark(struct sctp_outq *q,
void sctp_retransmit_mark(struct sctp_outq *q,
struct sctp_transport *transport,
__u8 fast_retransmit)
{
......@@ -553,7 +553,7 @@ void sctp_xmit_fragmented_chunks(struct sctp_outq *q, sctp_packet_t *packet,
}
/* Get a TSN block of nfrags TSNs. */
tsn = __sctp_association_get_tsn_block(asoc, nfrags);
tsn = sctp_association_get_tsn_block(asoc, nfrags);
pos = skb_peek(&q->out);
/* Transmit the first fragment. */
......@@ -595,7 +595,7 @@ sctp_chunk_t *sctp_fragment_chunk(sctp_chunk_t *chunk,
old_flags = chunk->chunk_hdr->flags;
if (old_flags & SCTP_DATA_FIRST_FRAG)
flags = SCTP_DATA_FIRST_FRAG;
else
else
flags = SCTP_DATA_MIDDLE_FRAG;
/* Make the first fragment. */
......@@ -1003,7 +1003,7 @@ int sctp_outq_flush(struct sctp_outq *q, int rtx_timeout)
*/
while ((ltransport = sctp_list_dequeue(&transport_list)) != NULL ) {
struct sctp_transport *t = list_entry(ltransport,
struct sctp_transport,
struct sctp_transport,
send_ready);
if (t != transport)
transport = t;
......@@ -1125,7 +1125,7 @@ int sctp_outq_sack(struct sctp_outq *q, sctp_sackhdr_t *sack)
* This is a MASSIVE candidate for optimization.
*/
list_for_each(pos, transport_list) {
transport = list_entry(pos, struct sctp_transport,
transport = list_entry(pos, struct sctp_transport,
transports);
sctp_check_transmitted(q, &transport->transmitted,
transport, sack, highest_new_tsn);
......@@ -1179,7 +1179,7 @@ int sctp_outq_sack(struct sctp_outq *q, sctp_sackhdr_t *sack)
goto finish;
list_for_each(pos, transport_list) {
transport = list_entry(pos, struct sctp_transport,
transport = list_entry(pos, struct sctp_transport,
transports);
q->empty = q->empty && list_empty(&transport->transmitted);
if (!q->empty)
......
......@@ -58,7 +58,7 @@
#include <net/inet_common.h>
/* Global data structures. */
sctp_protocol_t sctp_proto;
struct sctp_protocol sctp_proto;
struct proc_dir_entry *proc_net_sctp;
DEFINE_SNMP_STAT(struct sctp_mib, sctp_statistics);
......@@ -152,7 +152,7 @@ static void sctp_v4_copy_addrlist(struct list_head *addrlist,
/* Extract our IP addresses from the system and stash them in the
* protocol structure.
*/
static void __sctp_get_local_addr_list(sctp_protocol_t *proto)
static void __sctp_get_local_addr_list(struct sctp_protocol *proto)
{
struct net_device *dev;
struct list_head *pos;
......@@ -168,7 +168,7 @@ static void __sctp_get_local_addr_list(sctp_protocol_t *proto)
read_unlock(&dev_base_lock);
}
static void sctp_get_local_addr_list(sctp_protocol_t *proto)
static void sctp_get_local_addr_list(struct sctp_protocol *proto)
{
long flags __attribute__ ((unused));
......@@ -178,7 +178,7 @@ static void sctp_get_local_addr_list(sctp_protocol_t *proto)
}
/* Free the existing local addresses. */
static void __sctp_free_local_addr_list(sctp_protocol_t *proto)
static void __sctp_free_local_addr_list(struct sctp_protocol *proto)
{
struct sockaddr_storage_list *addr;
struct list_head *pos, *temp;
......@@ -191,7 +191,7 @@ static void __sctp_free_local_addr_list(sctp_protocol_t *proto)
}
/* Free the existing local addresses. */
static void sctp_free_local_addr_list(sctp_protocol_t *proto)
static void sctp_free_local_addr_list(struct sctp_protocol *proto)
{
long flags __attribute__ ((unused));
......@@ -201,8 +201,9 @@ static void sctp_free_local_addr_list(sctp_protocol_t *proto)
}
/* Copy the local addresses which are valid for 'scope' into 'bp'. */
int sctp_copy_local_addr_list(sctp_protocol_t *proto, sctp_bind_addr_t *bp,
sctp_scope_t scope, int priority, int copy_flags)
int sctp_copy_local_addr_list(struct sctp_protocol *proto,
struct sctp_bind_addr *bp, sctp_scope_t scope,
int priority, int copy_flags)
{
struct sockaddr_storage_list *addr;
int error = 0;
......@@ -331,7 +332,7 @@ static int sctp_v4_addr_valid(union sctp_addr *addr)
static int sctp_v4_available(const union sctp_addr *addr)
{
int ret = inet_addr_type(addr->v4.sin_addr.s_addr);
/* FIXME: ip_nonlocal_bind sysctl support. */
if (addr->v4.sin_addr.s_addr != INADDR_ANY && ret != RTN_LOCAL)
......@@ -380,7 +381,7 @@ static sctp_scope_t sctp_v4_scope(union sctp_addr *addr)
/* Returns a valid dst cache entry for the given source and destination ip
* addresses. If an association is passed, trys to get a dst entry with a
* source adddress that matches an address in the bind address list.
* source adddress that matches an address in the bind address list.
*/
struct dst_entry *sctp_v4_get_dst(sctp_association_t *asoc,
union sctp_addr *daddr,
......@@ -756,7 +757,7 @@ int sctp_register_pf(struct sctp_pf *pf, sa_family_t family)
static int __init init_sctp_mibs(void)
{
int i;
sctp_statistics[0] = kmalloc_percpu(sizeof (struct sctp_mib),
GFP_KERNEL);
if (!sctp_statistics[0])
......@@ -778,7 +779,7 @@ static int __init init_sctp_mibs(void)
}
}
return 0;
}
static void cleanup_sctp_mibs(void)
......@@ -802,9 +803,9 @@ __init int sctp_init(void)
/* Allocate and initialise sctp mibs. */
status = init_sctp_mibs();
if (status)
if (status)
goto err_init_mibs;
/* Initialize proc fs directory. */
sctp_proc_init();
......@@ -831,7 +832,7 @@ __init int sctp_init(void)
/* Valid.Cookie.Life - 60 seconds */
sctp_proto.valid_cookie_life = 60 * HZ;
/* Whether Cookie Preservative is enabled(1) or not(0) */
/* Whether Cookie Preservative is enabled(1) or not(0) */
sctp_proto.cookie_preserve_enable = 1;
/* Max.Burst - 4 */
......@@ -920,7 +921,7 @@ __init int sctp_init(void)
INIT_LIST_HEAD(&sctp_proto.local_addr_list);
sctp_proto.local_addr_lock = SPIN_LOCK_UNLOCKED;
/* Register notifier for inet address additions/deletions. */
/* Register notifier for inet address additions/deletions. */
register_inetaddr_notifier(&sctp_inetaddr_notifier);
sctp_get_local_addr_list(&sctp_proto);
......@@ -942,7 +943,7 @@ __init int sctp_init(void)
sctp_dbg_objcnt_exit();
sctp_proc_exit();
cleanup_sctp_mibs();
err_init_mibs:
err_init_mibs:
inet_del_protocol(&sctp_protocol, IPPROTO_SCTP);
inet_unregister_protosw(&sctp_protosw);
return status;
......
......@@ -1282,7 +1282,7 @@ void sctp_chunk_assign_tsn(sctp_chunk_t *chunk)
* assign a TSN.
*/
chunk->subh.data_hdr->tsn =
htonl(__sctp_association_get_next_tsn(chunk->asoc));
htonl(sctp_association_get_next_tsn(chunk->asoc));
chunk->has_tsn = 1;
}
}
......
This diff is collapsed.
......@@ -42,7 +42,7 @@
#include <net/sctp/structs.h>
#include <linux/sysctl.h>
extern sctp_protocol_t sctp_proto;
extern struct sctp_protocol sctp_proto;
static ctl_table sctp_table[] = {
{
......
......@@ -83,7 +83,7 @@ struct sctp_transport *sctp_transport_init(struct sctp_transport *peer,
const union sctp_addr *addr,
int priority)
{
sctp_protocol_t *proto = sctp_get_protocol();
struct sctp_protocol *proto = sctp_get_protocol();
/* Copy in the address. */
peer->ipaddr = *addr;
......@@ -262,7 +262,7 @@ void sctp_transport_put(struct sctp_transport *transport)
/* Update transport's RTO based on the newly calculated RTT. */
void sctp_transport_update_rto(struct sctp_transport *tp, __u32 rtt)
{
sctp_protocol_t *proto = sctp_get_protocol();
struct sctp_protocol *proto = sctp_get_protocol();
/* Check for valid transport. */
SCTP_ASSERT(tp, "NULL transport", return);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment