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 @@ ...@@ -121,9 +121,10 @@
/* /*
* sctp_protocol.c * sctp_protocol.c
*/ */
extern sctp_protocol_t sctp_proto; extern struct sctp_protocol sctp_proto;
extern struct sock *sctp_get_ctl_sock(void); 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); sctp_scope_t, int priority, int flags);
extern struct sctp_pf *sctp_get_pf_specific(sa_family_t family); extern struct sctp_pf *sctp_get_pf_specific(sa_family_t family);
extern int sctp_register_pf(struct sctp_pf *, sa_family_t); 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) ...@@ -348,25 +349,10 @@ static inline sctp_assoc_t sctp_assoc2id(const sctp_association_t *asoc)
return (sctp_assoc_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. */ /* Look up the association by its id. */
if (sctp_is_valid_kaddr((unsigned long) id)) { sctp_association_t *sctp_id2assoc(struct sock *sk, sctp_assoc_t 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;
}
return asoc;
}
/* A macro to walk a list of skbs. */ /* A macro to walk a list of skbs. */
#define sctp_skb_for_each(pos, head, tmp) \ #define sctp_skb_for_each(pos, head, tmp) \
...@@ -494,7 +480,7 @@ extern void sctp_put_port(struct sock *sk); ...@@ -494,7 +480,7 @@ extern void sctp_put_port(struct sock *sk);
/* Static inline functions. */ /* Static inline functions. */
/* Return the SCTP protocol structure. */ /* 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; return &sctp_proto;
} }
...@@ -523,21 +509,21 @@ static inline int ipver2af(__u8 ipver) ...@@ -523,21 +509,21 @@ static inline int ipver2af(__u8 ipver)
/* This is the hash function for the SCTP port hash table. */ /* This is the hash function for the SCTP port hash table. */
static inline int sctp_phashfn(__u16 lport) 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)); return (lport & (sctp_proto->port_hashsize - 1));
} }
/* This is the hash function for the endpoint hash table. */ /* This is the hash function for the endpoint hash table. */
static inline int sctp_ep_hashfn(__u16 lport) 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)); return (lport & (sctp_proto->ep_hashsize - 1));
} }
/* This is the hash function for the association hash table. */ /* This is the hash function for the association hash table. */
static inline int sctp_assoc_hashfn(__u16 lport, __u16 rport) 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; int h = (lport << 16) + rport;
h ^= h>>8; h ^= h>>8;
return (h & (sctp_proto->assoc_hashsize - 1)); return (h & (sctp_proto->assoc_hashsize - 1));
...@@ -549,7 +535,7 @@ static inline int sctp_assoc_hashfn(__u16 lport, __u16 rport) ...@@ -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) 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; int h = (lport << 16) + rport;
h ^= vtag; h ^= vtag;
return (h & (sctp_proto->assoc_hashsize-1)); return (h & (sctp_proto->assoc_hashsize-1));
......
...@@ -118,7 +118,6 @@ struct sctp_opt; ...@@ -118,7 +118,6 @@ struct sctp_opt;
struct sctp_endpoint_common; struct sctp_endpoint_common;
struct sctp_ssnmap; struct sctp_ssnmap;
typedef struct sctp_protocol sctp_protocol_t;
typedef struct sctp_endpoint sctp_endpoint_t; typedef struct sctp_endpoint sctp_endpoint_t;
typedef struct sctp_association sctp_association_t; typedef struct sctp_association sctp_association_t;
typedef struct sctp_packet sctp_packet_t; typedef struct sctp_packet sctp_packet_t;
...@@ -1130,8 +1129,9 @@ static inline sctp_endpoint_t *sctp_ep(sctp_endpoint_common_t *base) ...@@ -1130,8 +1129,9 @@ static inline sctp_endpoint_t *sctp_ep(sctp_endpoint_common_t *base)
} }
/* These are function signatures for manipulating endpoints. */ /* These are function signatures for manipulating endpoints. */
sctp_endpoint_t *sctp_endpoint_new(sctp_protocol_t *, struct sock *, int); sctp_endpoint_t *sctp_endpoint_new(struct sctp_protocol *, struct sock *, int);
sctp_endpoint_t *sctp_endpoint_init(sctp_endpoint_t *, sctp_protocol_t *, sctp_endpoint_t *sctp_endpoint_init(struct sctp_endpoint *,
struct sctp_protocol *,
struct sock *, int priority); struct sock *, int priority);
void sctp_endpoint_free(sctp_endpoint_t *); void sctp_endpoint_free(sctp_endpoint_t *);
void sctp_endpoint_put(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, ...@@ -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 *); int sctp_endpoint_is_peeled_off(sctp_endpoint_t *, const union sctp_addr *);
sctp_endpoint_t *sctp_endpoint_is_match(sctp_endpoint_t *, sctp_endpoint_t *sctp_endpoint_is_match(sctp_endpoint_t *,
const union sctp_addr *); const union sctp_addr *);
int sctp_has_association(const union sctp_addr *laddr, int sctp_has_association(const union sctp_addr *laddr,
const union sctp_addr *paddr); const union sctp_addr *paddr);
...@@ -1619,7 +1618,7 @@ struct sctp_transport *sctp_assoc_lookup_paddr(const sctp_association_t *, ...@@ -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 *, struct sctp_transport *sctp_assoc_add_peer(sctp_association_t *,
const union sctp_addr *address, const union sctp_addr *address,
const int priority); const int priority);
void sctp_assoc_control_transport(sctp_association_t *, void sctp_assoc_control_transport(struct sctp_association *,
struct sctp_transport *, struct sctp_transport *,
sctp_transport_cmd_t, sctp_sn_error_t); sctp_transport_cmd_t, sctp_sn_error_t);
struct sctp_transport *sctp_assoc_lookup_tsn(sctp_association_t *, __u32); 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 *, ...@@ -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_migrate(sctp_association_t *, struct sock *);
void sctp_assoc_update(sctp_association_t *dst, sctp_association_t *src); 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_next_tsn(struct sctp_association *);
__u32 __sctp_association_get_tsn_block(sctp_association_t *, int); __u32 sctp_association_get_tsn_block(struct sctp_association *, 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);
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_ep(sctp_association_t *, int);
int sctp_assoc_set_bind_addr_from_cookie(sctp_association_t *, int sctp_assoc_set_bind_addr_from_cookie(sctp_association_t *,
sctp_cookie_t *, int); sctp_cookie_t *, int);
......
...@@ -360,9 +360,25 @@ static void sctp_association_destroy(sctp_association_t *asoc) ...@@ -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. */ /* 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, const union sctp_addr *addr,
int priority) int priority)
{ {
...@@ -460,11 +476,7 @@ struct sctp_transport *sctp_assoc_add_peer(sctp_association_t *asoc, ...@@ -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 we do not yet have a primary path, set one. */
if (NULL == asoc->peer.primary_path) { if (NULL == asoc->peer.primary_path) {
asoc->peer.primary_path = peer; sctp_assoc_set_primary(asoc, peer);
/* Set a default msg_name for events. */
memcpy(&asoc->peer.primary_addr, &peer->ipaddr,
sizeof(union sctp_addr));
asoc->peer.active_path = peer;
asoc->peer.retran_path = peer; asoc->peer.retran_path = peer;
} }
...@@ -603,7 +615,7 @@ void sctp_association_put(sctp_association_t *asoc) ...@@ -603,7 +615,7 @@ void sctp_association_put(sctp_association_t *asoc)
/* Allocate the next TSN, Transmission Sequence Number, for the given /* Allocate the next TSN, Transmission Sequence Number, for the given
* association. * 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: /* From Section 1.6 Serial Number Arithmetic:
* Transmission Sequence Numbers wrap around when they reach * Transmission Sequence Numbers wrap around when they reach
...@@ -618,7 +630,7 @@ __u32 __sctp_association_get_next_tsn(sctp_association_t *asoc) ...@@ -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. */ /* 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; __u32 retval = asoc->next_tsn;
......
...@@ -302,7 +302,7 @@ int sctp_bind_addr_match(sctp_bind_addr_t *bp, const union sctp_addr *addr, ...@@ -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, static int sctp_copy_one_addr(sctp_bind_addr_t *dest, union sctp_addr *addr,
sctp_scope_t scope, int priority, int flags) 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; int error = 0;
if (sctp_is_any(addr)) { if (sctp_is_any(addr)) {
......
...@@ -65,7 +65,7 @@ static void sctp_endpoint_bh_rcv(sctp_endpoint_t *ep); ...@@ -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. /* Create a sctp_endpoint_t with all that boring stuff initialized.
* Returns NULL if there isn't enough memory. * 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) struct sock *sk, int priority)
{ {
sctp_endpoint_t *ep; sctp_endpoint_t *ep;
...@@ -89,7 +89,8 @@ sctp_endpoint_t *sctp_endpoint_new(sctp_protocol_t *proto, ...@@ -89,7 +89,8 @@ sctp_endpoint_t *sctp_endpoint_new(sctp_protocol_t *proto,
/* /*
* Initialize the base fields of the endpoint structure. * 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 sock *sk, int priority)
{ {
struct sctp_opt *sp = sctp_sk(sk); struct sctp_opt *sp = sctp_sk(sk);
......
...@@ -553,7 +553,7 @@ void sctp_xmit_fragmented_chunks(struct sctp_outq *q, sctp_packet_t *packet, ...@@ -553,7 +553,7 @@ void sctp_xmit_fragmented_chunks(struct sctp_outq *q, sctp_packet_t *packet,
} }
/* Get a TSN block of nfrags TSNs. */ /* 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); pos = skb_peek(&q->out);
/* Transmit the first fragment. */ /* Transmit the first fragment. */
......
...@@ -58,7 +58,7 @@ ...@@ -58,7 +58,7 @@
#include <net/inet_common.h> #include <net/inet_common.h>
/* Global data structures. */ /* Global data structures. */
sctp_protocol_t sctp_proto; struct sctp_protocol sctp_proto;
struct proc_dir_entry *proc_net_sctp; struct proc_dir_entry *proc_net_sctp;
DEFINE_SNMP_STAT(struct sctp_mib, sctp_statistics); DEFINE_SNMP_STAT(struct sctp_mib, sctp_statistics);
...@@ -152,7 +152,7 @@ static void sctp_v4_copy_addrlist(struct list_head *addrlist, ...@@ -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 /* Extract our IP addresses from the system and stash them in the
* protocol structure. * 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 net_device *dev;
struct list_head *pos; struct list_head *pos;
...@@ -168,7 +168,7 @@ static void __sctp_get_local_addr_list(sctp_protocol_t *proto) ...@@ -168,7 +168,7 @@ static void __sctp_get_local_addr_list(sctp_protocol_t *proto)
read_unlock(&dev_base_lock); 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)); long flags __attribute__ ((unused));
...@@ -178,7 +178,7 @@ static void sctp_get_local_addr_list(sctp_protocol_t *proto) ...@@ -178,7 +178,7 @@ static void sctp_get_local_addr_list(sctp_protocol_t *proto)
} }
/* Free the existing local addresses. */ /* 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 sockaddr_storage_list *addr;
struct list_head *pos, *temp; struct list_head *pos, *temp;
...@@ -191,7 +191,7 @@ static void __sctp_free_local_addr_list(sctp_protocol_t *proto) ...@@ -191,7 +191,7 @@ static void __sctp_free_local_addr_list(sctp_protocol_t *proto)
} }
/* Free the existing local addresses. */ /* 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)); long flags __attribute__ ((unused));
...@@ -201,8 +201,9 @@ static void sctp_free_local_addr_list(sctp_protocol_t *proto) ...@@ -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'. */ /* 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, int sctp_copy_local_addr_list(struct sctp_protocol *proto,
sctp_scope_t scope, int priority, int copy_flags) struct sctp_bind_addr *bp, sctp_scope_t scope,
int priority, int copy_flags)
{ {
struct sockaddr_storage_list *addr; struct sockaddr_storage_list *addr;
int error = 0; int error = 0;
......
...@@ -1282,7 +1282,7 @@ void sctp_chunk_assign_tsn(sctp_chunk_t *chunk) ...@@ -1282,7 +1282,7 @@ void sctp_chunk_assign_tsn(sctp_chunk_t *chunk)
* assign a TSN. * assign a TSN.
*/ */
chunk->subh.data_hdr->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; chunk->has_tsn = 1;
} }
} }
......
This diff is collapsed.
...@@ -42,7 +42,7 @@ ...@@ -42,7 +42,7 @@
#include <net/sctp/structs.h> #include <net/sctp/structs.h>
#include <linux/sysctl.h> #include <linux/sysctl.h>
extern sctp_protocol_t sctp_proto; extern struct sctp_protocol sctp_proto;
static ctl_table sctp_table[] = { static ctl_table sctp_table[] = {
{ {
......
...@@ -83,7 +83,7 @@ struct sctp_transport *sctp_transport_init(struct sctp_transport *peer, ...@@ -83,7 +83,7 @@ struct sctp_transport *sctp_transport_init(struct sctp_transport *peer,
const union sctp_addr *addr, const union sctp_addr *addr,
int priority) int priority)
{ {
sctp_protocol_t *proto = sctp_get_protocol(); struct sctp_protocol *proto = sctp_get_protocol();
/* Copy in the address. */ /* Copy in the address. */
peer->ipaddr = *addr; peer->ipaddr = *addr;
...@@ -262,7 +262,7 @@ void sctp_transport_put(struct sctp_transport *transport) ...@@ -262,7 +262,7 @@ void sctp_transport_put(struct sctp_transport *transport)
/* Update transport's RTO based on the newly calculated RTT. */ /* Update transport's RTO based on the newly calculated RTT. */
void sctp_transport_update_rto(struct sctp_transport *tp, __u32 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. */ /* Check for valid transport. */
SCTP_ASSERT(tp, "NULL transport", return); 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