forked from Minki/linux
sctp: Push struct net down to sctp_chunk_event_lookup
This trickles up through sctp_sm_lookup_event up to sctp_do_sm and up further into sctp_primitiv_NAME before the code reaches places where struct net can be reliably found. Signed-off-by: "Eric W. Biederman" <ebiederm@xmission.com> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
parent
ebb7e95d93
commit
55e26eb95a
@ -139,12 +139,12 @@ extern int sctp_asconf_mgmt(struct sctp_sock *, struct sctp_sockaddr_entry *);
|
||||
/*
|
||||
* sctp/primitive.c
|
||||
*/
|
||||
int sctp_primitive_ASSOCIATE(struct sctp_association *, void *arg);
|
||||
int sctp_primitive_SHUTDOWN(struct sctp_association *, void *arg);
|
||||
int sctp_primitive_ABORT(struct sctp_association *, void *arg);
|
||||
int sctp_primitive_SEND(struct sctp_association *, void *arg);
|
||||
int sctp_primitive_REQUESTHEARTBEAT(struct sctp_association *, void *arg);
|
||||
int sctp_primitive_ASCONF(struct sctp_association *, void *arg);
|
||||
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);
|
||||
|
||||
/*
|
||||
* sctp/input.c
|
||||
|
@ -178,7 +178,8 @@ sctp_state_fn_t sctp_sf_autoclose_timer_expire;
|
||||
|
||||
/* Prototypes for utility support functions. */
|
||||
__u8 sctp_get_chunk_type(struct sctp_chunk *chunk);
|
||||
const sctp_sm_table_entry_t *sctp_sm_lookup_event(sctp_event_t,
|
||||
const sctp_sm_table_entry_t *sctp_sm_lookup_event(struct net *,
|
||||
sctp_event_t,
|
||||
sctp_state_t,
|
||||
sctp_subtype_t);
|
||||
int sctp_chunk_iif(const struct sctp_chunk *);
|
||||
@ -268,7 +269,7 @@ void sctp_chunk_assign_ssn(struct sctp_chunk *);
|
||||
|
||||
/* Prototypes for statetable processing. */
|
||||
|
||||
int sctp_do_sm(sctp_event_t event_type, sctp_subtype_t subtype,
|
||||
int sctp_do_sm(struct net *net, sctp_event_t event_type, sctp_subtype_t subtype,
|
||||
sctp_state_t state,
|
||||
struct sctp_endpoint *,
|
||||
struct sctp_association *asoc,
|
||||
|
@ -1118,6 +1118,7 @@ static void sctp_assoc_bh_rcv(struct work_struct *work)
|
||||
struct sctp_association *asoc =
|
||||
container_of(work, struct sctp_association,
|
||||
base.inqueue.immediate);
|
||||
struct net *net = sock_net(asoc->base.sk);
|
||||
struct sctp_endpoint *ep;
|
||||
struct sctp_chunk *chunk;
|
||||
struct sctp_inq *inqueue;
|
||||
@ -1150,13 +1151,13 @@ static void sctp_assoc_bh_rcv(struct work_struct *work)
|
||||
if (sctp_chunk_is_data(chunk))
|
||||
asoc->peer.last_data_from = chunk->transport;
|
||||
else
|
||||
SCTP_INC_STATS(sock_net(asoc->base.sk), SCTP_MIB_INCTRLCHUNKS);
|
||||
SCTP_INC_STATS(net, SCTP_MIB_INCTRLCHUNKS);
|
||||
|
||||
if (chunk->transport)
|
||||
chunk->transport->last_time_heard = jiffies;
|
||||
|
||||
/* Run through the state machine. */
|
||||
error = sctp_do_sm(SCTP_EVENT_T_CHUNK, subtype,
|
||||
error = sctp_do_sm(net, SCTP_EVENT_T_CHUNK, subtype,
|
||||
state, ep, asoc, chunk, GFP_ATOMIC);
|
||||
|
||||
/* Check to see if the association is freed in response to
|
||||
|
@ -413,6 +413,7 @@ static void sctp_endpoint_bh_rcv(struct work_struct *work)
|
||||
base.inqueue.immediate);
|
||||
struct sctp_association *asoc;
|
||||
struct sock *sk;
|
||||
struct net *net;
|
||||
struct sctp_transport *transport;
|
||||
struct sctp_chunk *chunk;
|
||||
struct sctp_inq *inqueue;
|
||||
@ -427,6 +428,7 @@ static void sctp_endpoint_bh_rcv(struct work_struct *work)
|
||||
asoc = NULL;
|
||||
inqueue = &ep->base.inqueue;
|
||||
sk = ep->base.sk;
|
||||
net = sock_net(sk);
|
||||
|
||||
while (NULL != (chunk = sctp_inq_pop(inqueue))) {
|
||||
subtype = SCTP_ST_CHUNK(chunk->chunk_hdr->type);
|
||||
@ -483,7 +485,7 @@ normal:
|
||||
if (chunk->transport)
|
||||
chunk->transport->last_time_heard = jiffies;
|
||||
|
||||
error = sctp_do_sm(SCTP_EVENT_T_CHUNK, subtype, state,
|
||||
error = sctp_do_sm(net, SCTP_EVENT_T_CHUNK, subtype, state,
|
||||
ep, asoc, chunk, GFP_ATOMIC);
|
||||
|
||||
if (error && chunk)
|
||||
|
@ -466,11 +466,13 @@ void sctp_icmp_proto_unreachable(struct sock *sk,
|
||||
}
|
||||
|
||||
} else {
|
||||
struct net *net = sock_net(sk);
|
||||
|
||||
if (timer_pending(&t->proto_unreach_timer) &&
|
||||
del_timer(&t->proto_unreach_timer))
|
||||
sctp_association_put(asoc);
|
||||
|
||||
sctp_do_sm(SCTP_EVENT_T_OTHER,
|
||||
sctp_do_sm(net, SCTP_EVENT_T_OTHER,
|
||||
SCTP_ST_OTHER(SCTP_EVENT_ICMP_PROTO_UNREACH),
|
||||
asoc->state, asoc->ep, asoc, t,
|
||||
GFP_ATOMIC);
|
||||
|
@ -57,7 +57,7 @@
|
||||
|
||||
#define DECLARE_PRIMITIVE(name) \
|
||||
/* This is called in the code as sctp_primitive_ ## name. */ \
|
||||
int sctp_primitive_ ## name(struct sctp_association *asoc, \
|
||||
int sctp_primitive_ ## name(struct net *net, struct sctp_association *asoc, \
|
||||
void *arg) { \
|
||||
int error = 0; \
|
||||
sctp_event_t event_type; sctp_subtype_t subtype; \
|
||||
@ -69,7 +69,7 @@ int sctp_primitive_ ## name(struct sctp_association *asoc, \
|
||||
state = asoc ? asoc->state : SCTP_STATE_CLOSED; \
|
||||
ep = asoc ? asoc->ep : NULL; \
|
||||
\
|
||||
error = sctp_do_sm(event_type, subtype, state, ep, asoc, \
|
||||
error = sctp_do_sm(net, event_type, subtype, state, ep, asoc, \
|
||||
arg, GFP_KERNEL); \
|
||||
return error; \
|
||||
}
|
||||
|
@ -251,6 +251,7 @@ void sctp_generate_t3_rtx_event(unsigned long peer)
|
||||
int error;
|
||||
struct sctp_transport *transport = (struct sctp_transport *) peer;
|
||||
struct sctp_association *asoc = transport->asoc;
|
||||
struct net *net = sock_net(asoc->base.sk);
|
||||
|
||||
/* Check whether a task is in the sock. */
|
||||
|
||||
@ -271,7 +272,7 @@ void sctp_generate_t3_rtx_event(unsigned long peer)
|
||||
goto out_unlock;
|
||||
|
||||
/* Run through the state machine. */
|
||||
error = sctp_do_sm(SCTP_EVENT_T_TIMEOUT,
|
||||
error = sctp_do_sm(net, SCTP_EVENT_T_TIMEOUT,
|
||||
SCTP_ST_TIMEOUT(SCTP_EVENT_TIMEOUT_T3_RTX),
|
||||
asoc->state,
|
||||
asoc->ep, asoc,
|
||||
@ -291,6 +292,7 @@ out_unlock:
|
||||
static void sctp_generate_timeout_event(struct sctp_association *asoc,
|
||||
sctp_event_timeout_t timeout_type)
|
||||
{
|
||||
struct net *net = sock_net(asoc->base.sk);
|
||||
int error = 0;
|
||||
|
||||
sctp_bh_lock_sock(asoc->base.sk);
|
||||
@ -312,7 +314,7 @@ static void sctp_generate_timeout_event(struct sctp_association *asoc,
|
||||
goto out_unlock;
|
||||
|
||||
/* Run through the state machine. */
|
||||
error = sctp_do_sm(SCTP_EVENT_T_TIMEOUT,
|
||||
error = sctp_do_sm(net, SCTP_EVENT_T_TIMEOUT,
|
||||
SCTP_ST_TIMEOUT(timeout_type),
|
||||
asoc->state, asoc->ep, asoc,
|
||||
(void *)timeout_type, GFP_ATOMIC);
|
||||
@ -371,6 +373,7 @@ void sctp_generate_heartbeat_event(unsigned long data)
|
||||
int error = 0;
|
||||
struct sctp_transport *transport = (struct sctp_transport *) data;
|
||||
struct sctp_association *asoc = transport->asoc;
|
||||
struct net *net = sock_net(asoc->base.sk);
|
||||
|
||||
sctp_bh_lock_sock(asoc->base.sk);
|
||||
if (sock_owned_by_user(asoc->base.sk)) {
|
||||
@ -388,7 +391,7 @@ void sctp_generate_heartbeat_event(unsigned long data)
|
||||
if (transport->dead)
|
||||
goto out_unlock;
|
||||
|
||||
error = sctp_do_sm(SCTP_EVENT_T_TIMEOUT,
|
||||
error = sctp_do_sm(net, SCTP_EVENT_T_TIMEOUT,
|
||||
SCTP_ST_TIMEOUT(SCTP_EVENT_TIMEOUT_HEARTBEAT),
|
||||
asoc->state, asoc->ep, asoc,
|
||||
transport, GFP_ATOMIC);
|
||||
@ -408,6 +411,7 @@ void sctp_generate_proto_unreach_event(unsigned long data)
|
||||
{
|
||||
struct sctp_transport *transport = (struct sctp_transport *) data;
|
||||
struct sctp_association *asoc = transport->asoc;
|
||||
struct net *net = sock_net(asoc->base.sk);
|
||||
|
||||
sctp_bh_lock_sock(asoc->base.sk);
|
||||
if (sock_owned_by_user(asoc->base.sk)) {
|
||||
@ -426,7 +430,7 @@ void sctp_generate_proto_unreach_event(unsigned long data)
|
||||
if (asoc->base.dead)
|
||||
goto out_unlock;
|
||||
|
||||
sctp_do_sm(SCTP_EVENT_T_OTHER,
|
||||
sctp_do_sm(net, SCTP_EVENT_T_OTHER,
|
||||
SCTP_ST_OTHER(SCTP_EVENT_ICMP_PROTO_UNREACH),
|
||||
asoc->state, asoc->ep, asoc, transport, GFP_ATOMIC);
|
||||
|
||||
@ -753,8 +757,10 @@ static int sctp_cmd_process_sack(sctp_cmd_seq_t *cmds,
|
||||
int err = 0;
|
||||
|
||||
if (sctp_outq_sack(&asoc->outqueue, sackh)) {
|
||||
struct net *net = sock_net(asoc->base.sk);
|
||||
|
||||
/* There are no more TSNs awaiting SACK. */
|
||||
err = sctp_do_sm(SCTP_EVENT_T_OTHER,
|
||||
err = sctp_do_sm(net, SCTP_EVENT_T_OTHER,
|
||||
SCTP_ST_OTHER(SCTP_EVENT_NO_PENDING_TSN),
|
||||
asoc->state, asoc->ep, asoc, NULL,
|
||||
GFP_ATOMIC);
|
||||
@ -1042,6 +1048,8 @@ static int sctp_cmd_send_msg(struct sctp_association *asoc,
|
||||
*/
|
||||
static void sctp_cmd_send_asconf(struct sctp_association *asoc)
|
||||
{
|
||||
struct net *net = sock_net(asoc->base.sk);
|
||||
|
||||
/* Send the next asconf chunk from the addip chunk
|
||||
* queue.
|
||||
*/
|
||||
@ -1053,7 +1061,7 @@ static void sctp_cmd_send_asconf(struct sctp_association *asoc)
|
||||
|
||||
/* Hold the chunk until an ASCONF_ACK is received. */
|
||||
sctp_chunk_hold(asconf);
|
||||
if (sctp_primitive_ASCONF(asoc, asconf))
|
||||
if (sctp_primitive_ASCONF(net, asoc, asconf))
|
||||
sctp_chunk_free(asconf);
|
||||
else
|
||||
asoc->addip_last_asconf = asconf;
|
||||
@ -1089,7 +1097,7 @@ static void sctp_cmd_send_asconf(struct sctp_association *asoc)
|
||||
* If you want to understand all of lksctp, this is a
|
||||
* good place to start.
|
||||
*/
|
||||
int sctp_do_sm(sctp_event_t event_type, sctp_subtype_t subtype,
|
||||
int sctp_do_sm(struct net *net, sctp_event_t event_type, sctp_subtype_t subtype,
|
||||
sctp_state_t state,
|
||||
struct sctp_endpoint *ep,
|
||||
struct sctp_association *asoc,
|
||||
@ -1110,7 +1118,7 @@ int sctp_do_sm(sctp_event_t event_type, sctp_subtype_t subtype,
|
||||
/* Look up the state function, run it, and then process the
|
||||
* side effects. These three steps are the heart of lksctp.
|
||||
*/
|
||||
state_fn = sctp_sm_lookup_event(event_type, state, subtype);
|
||||
state_fn = sctp_sm_lookup_event(net, event_type, state, subtype);
|
||||
|
||||
sctp_init_cmd_seq(&commands);
|
||||
|
||||
|
@ -59,7 +59,8 @@ other_event_table[SCTP_NUM_OTHER_TYPES][SCTP_STATE_NUM_STATES];
|
||||
static const sctp_sm_table_entry_t
|
||||
timeout_event_table[SCTP_NUM_TIMEOUT_TYPES][SCTP_STATE_NUM_STATES];
|
||||
|
||||
static const sctp_sm_table_entry_t *sctp_chunk_event_lookup(sctp_cid_t cid,
|
||||
static const sctp_sm_table_entry_t *sctp_chunk_event_lookup(struct net *net,
|
||||
sctp_cid_t cid,
|
||||
sctp_state_t state);
|
||||
|
||||
|
||||
@ -82,13 +83,14 @@ static const sctp_sm_table_entry_t bug = {
|
||||
rtn; \
|
||||
})
|
||||
|
||||
const sctp_sm_table_entry_t *sctp_sm_lookup_event(sctp_event_t event_type,
|
||||
const sctp_sm_table_entry_t *sctp_sm_lookup_event(struct net *net,
|
||||
sctp_event_t event_type,
|
||||
sctp_state_t state,
|
||||
sctp_subtype_t event_subtype)
|
||||
{
|
||||
switch (event_type) {
|
||||
case SCTP_EVENT_T_CHUNK:
|
||||
return sctp_chunk_event_lookup(event_subtype.chunk, state);
|
||||
return sctp_chunk_event_lookup(net, event_subtype.chunk, state);
|
||||
case SCTP_EVENT_T_TIMEOUT:
|
||||
return DO_LOOKUP(SCTP_EVENT_TIMEOUT_MAX, timeout,
|
||||
timeout_event_table);
|
||||
@ -906,7 +908,8 @@ static const sctp_sm_table_entry_t timeout_event_table[SCTP_NUM_TIMEOUT_TYPES][S
|
||||
TYPE_SCTP_EVENT_TIMEOUT_AUTOCLOSE,
|
||||
};
|
||||
|
||||
static const sctp_sm_table_entry_t *sctp_chunk_event_lookup(sctp_cid_t cid,
|
||||
static const sctp_sm_table_entry_t *sctp_chunk_event_lookup(struct net *net,
|
||||
sctp_cid_t cid,
|
||||
sctp_state_t state)
|
||||
{
|
||||
if (state > SCTP_STATE_MAX)
|
||||
|
@ -427,6 +427,7 @@ SCTP_STATIC int sctp_do_bind(struct sock *sk, union sctp_addr *addr, int len)
|
||||
static int sctp_send_asconf(struct sctp_association *asoc,
|
||||
struct sctp_chunk *chunk)
|
||||
{
|
||||
struct net *net = sock_net(asoc->base.sk);
|
||||
int retval = 0;
|
||||
|
||||
/* If there is an outstanding ASCONF chunk, queue it for later
|
||||
@ -439,7 +440,7 @@ static int sctp_send_asconf(struct sctp_association *asoc,
|
||||
|
||||
/* Hold the chunk until an ASCONF_ACK is received. */
|
||||
sctp_chunk_hold(chunk);
|
||||
retval = sctp_primitive_ASCONF(asoc, chunk);
|
||||
retval = sctp_primitive_ASCONF(net, asoc, chunk);
|
||||
if (retval)
|
||||
sctp_chunk_free(chunk);
|
||||
else
|
||||
@ -1050,6 +1051,7 @@ static int __sctp_connect(struct sock* sk,
|
||||
int addrs_size,
|
||||
sctp_assoc_t *assoc_id)
|
||||
{
|
||||
struct net *net = sock_net(sk);
|
||||
struct sctp_sock *sp;
|
||||
struct sctp_endpoint *ep;
|
||||
struct sctp_association *asoc = NULL;
|
||||
@ -1200,7 +1202,7 @@ static int __sctp_connect(struct sock* sk,
|
||||
goto out_free;
|
||||
}
|
||||
|
||||
err = sctp_primitive_ASSOCIATE(asoc, NULL);
|
||||
err = sctp_primitive_ASSOCIATE(net, asoc, NULL);
|
||||
if (err < 0) {
|
||||
goto out_free;
|
||||
}
|
||||
@ -1458,6 +1460,7 @@ SCTP_STATIC int sctp_getsockopt_connectx3(struct sock* sk, int len,
|
||||
*/
|
||||
SCTP_STATIC void sctp_close(struct sock *sk, long timeout)
|
||||
{
|
||||
struct net *net = sock_net(sk);
|
||||
struct sctp_endpoint *ep;
|
||||
struct sctp_association *asoc;
|
||||
struct list_head *pos, *temp;
|
||||
@ -1499,9 +1502,9 @@ SCTP_STATIC void sctp_close(struct sock *sk, long timeout)
|
||||
|
||||
chunk = sctp_make_abort_user(asoc, NULL, 0);
|
||||
if (chunk)
|
||||
sctp_primitive_ABORT(asoc, chunk);
|
||||
sctp_primitive_ABORT(net, asoc, chunk);
|
||||
} else
|
||||
sctp_primitive_SHUTDOWN(asoc, NULL);
|
||||
sctp_primitive_SHUTDOWN(net, asoc, NULL);
|
||||
}
|
||||
|
||||
/* On a TCP-style socket, block for at most linger_time if set. */
|
||||
@ -1569,6 +1572,7 @@ SCTP_STATIC int sctp_msghdr_parse(const struct msghdr *, sctp_cmsgs_t *);
|
||||
SCTP_STATIC int sctp_sendmsg(struct kiocb *iocb, struct sock *sk,
|
||||
struct msghdr *msg, size_t msg_len)
|
||||
{
|
||||
struct net *net = sock_net(sk);
|
||||
struct sctp_sock *sp;
|
||||
struct sctp_endpoint *ep;
|
||||
struct sctp_association *new_asoc=NULL, *asoc=NULL;
|
||||
@ -1714,7 +1718,7 @@ SCTP_STATIC int sctp_sendmsg(struct kiocb *iocb, struct sock *sk,
|
||||
if (sinfo_flags & SCTP_EOF) {
|
||||
SCTP_DEBUG_PRINTK("Shutting down association: %p\n",
|
||||
asoc);
|
||||
sctp_primitive_SHUTDOWN(asoc, NULL);
|
||||
sctp_primitive_SHUTDOWN(net, asoc, NULL);
|
||||
err = 0;
|
||||
goto out_unlock;
|
||||
}
|
||||
@ -1727,7 +1731,7 @@ SCTP_STATIC int sctp_sendmsg(struct kiocb *iocb, struct sock *sk,
|
||||
}
|
||||
|
||||
SCTP_DEBUG_PRINTK("Aborting association: %p\n", asoc);
|
||||
sctp_primitive_ABORT(asoc, chunk);
|
||||
sctp_primitive_ABORT(net, asoc, chunk);
|
||||
err = 0;
|
||||
goto out_unlock;
|
||||
}
|
||||
@ -1900,7 +1904,7 @@ SCTP_STATIC int sctp_sendmsg(struct kiocb *iocb, struct sock *sk,
|
||||
|
||||
/* Auto-connect, if we aren't connected already. */
|
||||
if (sctp_state(asoc, CLOSED)) {
|
||||
err = sctp_primitive_ASSOCIATE(asoc, NULL);
|
||||
err = sctp_primitive_ASSOCIATE(net, asoc, NULL);
|
||||
if (err < 0)
|
||||
goto out_free;
|
||||
SCTP_DEBUG_PRINTK("We associated primitively.\n");
|
||||
@ -1928,7 +1932,7 @@ SCTP_STATIC int sctp_sendmsg(struct kiocb *iocb, struct sock *sk,
|
||||
* works that way today. Keep it that way or this
|
||||
* breaks.
|
||||
*/
|
||||
err = sctp_primitive_SEND(asoc, datamsg);
|
||||
err = sctp_primitive_SEND(net, asoc, datamsg);
|
||||
/* Did the lower layer accept the chunk? */
|
||||
if (err)
|
||||
sctp_datamsg_free(datamsg);
|
||||
@ -2320,7 +2324,9 @@ static int sctp_apply_peer_addr_params(struct sctp_paddrparams *params,
|
||||
int error;
|
||||
|
||||
if (params->spp_flags & SPP_HB_DEMAND && trans) {
|
||||
error = sctp_primitive_REQUESTHEARTBEAT (trans->asoc, trans);
|
||||
struct net *net = sock_net(trans->asoc->base.sk);
|
||||
|
||||
error = sctp_primitive_REQUESTHEARTBEAT(net, trans->asoc, trans);
|
||||
if (error)
|
||||
return error;
|
||||
}
|
||||
@ -4011,6 +4017,7 @@ SCTP_STATIC void sctp_destroy_sock(struct sock *sk)
|
||||
*/
|
||||
SCTP_STATIC void sctp_shutdown(struct sock *sk, int how)
|
||||
{
|
||||
struct net *net = sock_net(sk);
|
||||
struct sctp_endpoint *ep;
|
||||
struct sctp_association *asoc;
|
||||
|
||||
@ -4022,7 +4029,7 @@ SCTP_STATIC void sctp_shutdown(struct sock *sk, int how)
|
||||
if (!list_empty(&ep->asocs)) {
|
||||
asoc = list_entry(ep->asocs.next,
|
||||
struct sctp_association, asocs);
|
||||
sctp_primitive_SHUTDOWN(asoc, NULL);
|
||||
sctp_primitive_SHUTDOWN(net, asoc, NULL);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user