#include <net/sctp/sm.h>
/* Forward declarations for internal functions. */
-static void sctp_assoc_bh_rcv(struct sctp_association *asoc);
+static void sctp_assoc_bh_rcv(struct work_struct *work);
/* 1st Level Abstractions. */
* If the 'T5-shutdown-guard' timer is used, it SHOULD be set to the
* recommended value of 5 times 'RTO.Max'.
*/
- asoc->timeouts[SCTP_EVENT_TIMEOUT_T5_SHUTDOWN_GUARD]
+ asoc->timeouts[SCTP_EVENT_TIMEOUT_T5_SHUTDOWN_GUARD]
= 5 * asoc->rto_max;
asoc->timeouts[SCTP_EVENT_TIMEOUT_HEARTBEAT] = 0;
asoc->timeouts[SCTP_EVENT_TIMEOUT_SACK] = asoc->sackdelay;
asoc->timeouts[SCTP_EVENT_TIMEOUT_AUTOCLOSE] =
sp->autoclose * HZ;
-
+
/* Initilizes the timers */
for (i = SCTP_EVENT_TIMEOUT_NONE; i < SCTP_NUM_TIMEOUT_TYPES; ++i) {
init_timer(&asoc->timers[i]);
/* Create an input queue. */
sctp_inq_init(&asoc->base.inqueue);
- sctp_inq_set_th_handler(&asoc->base.inqueue,
- (void (*)(void *))sctp_assoc_bh_rcv,
- asoc);
+ sctp_inq_set_th_handler(&asoc->base.inqueue, sctp_assoc_bh_rcv);
/* Create an output queue. */
sctp_outq_init(asoc, &asoc->outqueue);
asoc->default_flags = sp->default_flags;
asoc->default_context = sp->default_context;
asoc->default_timetolive = sp->default_timetolive;
+ asoc->default_rcv_context = sp->default_rcv_context;
return asoc;
SCTP_DEBUG_PRINTK_IPADDR("sctp_assoc_rm_peer:association %p addr: ",
" port: %d\n",
asoc,
- (&peer->ipaddr_h),
- peer->ipaddr_h.v4.sin_port);
+ (&peer->ipaddr),
+ ntohs(peer->ipaddr.v4.sin_port));
/* If we are to remove the current retran_path, update it
* to the next peer before removing this peer from the list.
struct sctp_transport *peer;
struct sctp_sock *sp;
unsigned short port;
- union sctp_addr tmp;
- flip_to_n(&tmp, addr);
sp = sctp_sk(asoc->base.sk);
/* AF_INET and AF_INET6 share common port field. */
- port = addr->v4.sin_port;
+ port = ntohs(addr->v4.sin_port);
SCTP_DEBUG_PRINTK_IPADDR("sctp_assoc_add_peer:association %p addr: ",
" port: %d state:%d\n",
asoc,
addr,
- addr->v4.sin_port,
+ port,
peer_state);
/* Set the port if it has not been set yet. */
asoc->peer.port = port;
/* Check to see if this is a duplicate. */
- peer = sctp_assoc_lookup_paddr(asoc, &tmp);
+ peer = sctp_assoc_lookup_paddr(asoc, addr);
if (peer) {
if (peer->state == SCTP_UNKNOWN) {
if (peer_state == SCTP_ACTIVE)
* user.
*/
memset(&addr, 0, sizeof(struct sockaddr_storage));
- flip_to_n((union sctp_addr *)&addr, &transport->ipaddr_h);
+ memcpy(&addr, &transport->ipaddr, transport->af_specific->sockaddr_len);
event = sctp_ulpevent_make_peer_addr_change(asoc, &addr,
0, spc_state, error, GFP_ATOMIC);
if (event)
const union sctp_addr *paddr)
{
struct sctp_transport *transport;
- union sctp_addr tmp, tmp2;
- flip_to_n(&tmp, laddr);
- flip_to_n(&tmp2, paddr);
sctp_read_lock(&asoc->base.addr_lock);
- if ((asoc->base.bind_addr.port == laddr->v4.sin_port) &&
- (asoc->peer.port == paddr->v4.sin_port)) {
- transport = sctp_assoc_lookup_paddr(asoc, &tmp2);
+ if ((htons(asoc->base.bind_addr.port) == laddr->v4.sin_port) &&
+ (htons(asoc->peer.port) == paddr->v4.sin_port)) {
+ transport = sctp_assoc_lookup_paddr(asoc, paddr);
if (!transport)
goto out;
- if (sctp_bind_addr_match(&asoc->base.bind_addr, &tmp,
+ if (sctp_bind_addr_match(&asoc->base.bind_addr, laddr,
sctp_sk(asoc->base.sk)))
goto out;
}
}
/* Do delayed input processing. This is scheduled by sctp_rcv(). */
-static void sctp_assoc_bh_rcv(struct sctp_association *asoc)
+static void sctp_assoc_bh_rcv(struct work_struct *work)
{
+ struct sctp_association *asoc =
+ container_of(work, struct sctp_association,
+ base.inqueue.immediate);
struct sctp_endpoint *ep;
struct sctp_chunk *chunk;
struct sock *sk;
trans = list_entry(pos, struct sctp_transport,
transports);
if (!sctp_assoc_lookup_paddr(asoc, &trans->ipaddr))
- sctp_assoc_add_peer(asoc, &trans->ipaddr_h,
+ sctp_assoc_add_peer(asoc, &trans->ipaddr,
GFP_ATOMIC, trans->state);
}
" %p addr: ",
" port: %d\n",
asoc,
- (&t->ipaddr_h),
- t->ipaddr_h.v4.sin_port);
+ (&t->ipaddr),
+ ntohs(t->ipaddr.v4.sin_port));
}
/* Choose the transport for sending a INIT packet. */
" %p addr: ",
" port: %d\n",
asoc,
- (&t->ipaddr_h),
- t->ipaddr_h.v4.sin_port);
+ (&t->ipaddr),
+ ntohs(t->ipaddr.v4.sin_port));
return t;
}
/* Use scoping rules to determine the subset of addresses from
* the endpoint.
*/
- scope = sctp_scope(&asoc->peer.active_path->ipaddr_h);
+ scope = sctp_scope(&asoc->peer.active_path->ipaddr);
flags = (PF_INET6 == asoc->base.sk->sk_family) ? SCTP_ADDR6_ALLOWED : 0;
if (asoc->peer.ipv4_address)
flags |= SCTP_ADDR4_PEERSUPP;
asoc->ep->base.bind_addr.port, gfp);
}
-/* Lookup laddr in the bind address list of an association. */
-int sctp_assoc_lookup_laddr(struct sctp_association *asoc,
+/* Lookup laddr in the bind address list of an association. */
+int sctp_assoc_lookup_laddr(struct sctp_association *asoc,
const union sctp_addr *laddr)
{
int found;
sctp_read_lock(&asoc->base.addr_lock);
if ((asoc->base.bind_addr.port == ntohs(laddr->v4.sin_port)) &&
sctp_bind_addr_match(&asoc->base.bind_addr, laddr,
- sctp_sk(asoc->base.sk))) {
+ sctp_sk(asoc->base.sk))) {
found = 1;
goto out;
}