[PATCH 07/13] SCTP: Make primitive functions pass per-namespace parameters.

From: Jan Ariyasu
Date: Sat Aug 04 2012 - 17:33:46 EST


This patch sets up the primitive functions to pass on struct net
in preparation for SCTP to use per-net protocol parameters.

Signed-off-by: Jan Ariyasu <jan.ariyasu@xxxxxx>
---
include/net/sctp/sctp.h | 15 ++++++++------
include/net/sctp/sm.h | 6 ++++--
net/sctp/associola.c | 3 ++-
net/sctp/endpointola.c | 4 ++--
net/sctp/input.c | 2 +-
net/sctp/primitive.c | 4 ++--
net/sctp/sm_sideeffect.c | 51 ++++++++++++++++++----------------------------
net/sctp/sm_statetable.c | 3 ++-
net/sctp/socket.c | 41 ++++++++++++++++++++-----------------
9 files changed, 64 insertions(+), 65 deletions(-)

diff --git a/include/net/sctp/sctp.h b/include/net/sctp/sctp.h
index eb2ec98..8488d5e 100644
--- a/include/net/sctp/sctp.h
+++ b/include/net/sctp/sctp.h
@@ -146,12 +146,15 @@ extern int sctp_asconf_mgmt(struct net *, struct sctp_sock *,
/*
* 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
diff --git a/include/net/sctp/sm.h b/include/net/sctp/sm.h
index a83ce1b..8b1a4a6 100644
--- a/include/net/sctp/sm.h
+++ b/include/net/sctp/sm.h
@@ -179,7 +179,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 *);
@@ -269,7 +270,8 @@ 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 *,
+ sctp_event_t event_type, sctp_subtype_t subtype,
sctp_state_t state,
struct sctp_endpoint *,
struct sctp_association *asoc,
diff --git a/net/sctp/associola.c b/net/sctp/associola.c
index 001f44b..1bd956b 100644
--- a/net/sctp/associola.c
+++ b/net/sctp/associola.c
@@ -1123,6 +1123,7 @@ static void sctp_assoc_bh_rcv(struct work_struct *work)
int state;
sctp_subtype_t subtype;
int error = 0;
+ struct net *net = sock_net(asoc->base.sk);

/* The association should be held so we should be safe. */
ep = asoc->ep;
@@ -1155,7 +1156,7 @@ static void sctp_assoc_bh_rcv(struct work_struct *work)
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
diff --git a/net/sctp/endpointola.c b/net/sctp/endpointola.c
index 68a385d..de42bd4 100644
--- a/net/sctp/endpointola.c
+++ b/net/sctp/endpointola.c
@@ -479,8 +479,8 @@ normal:
if (chunk->transport)
chunk->transport->last_time_heard = jiffies;

- error = sctp_do_sm(SCTP_EVENT_T_CHUNK, subtype, state,
- ep, asoc, chunk, GFP_ATOMIC);
+ error = sctp_do_sm(sock_net(sk), SCTP_EVENT_T_CHUNK, subtype,
+ state, ep, asoc, chunk, GFP_ATOMIC);

if (error && chunk)
chunk->pdiscard = 1;
diff --git a/net/sctp/input.c b/net/sctp/input.c
index fc94829..1b92da2 100644
--- a/net/sctp/input.c
+++ b/net/sctp/input.c
@@ -466,7 +466,7 @@ void sctp_icmp_proto_unreachable(struct sock *sk,
del_timer(&t->proto_unreach_timer))
sctp_association_put(asoc);

- sctp_do_sm(SCTP_EVENT_T_OTHER,
+ sctp_do_sm(sock_net(sk), SCTP_EVENT_T_OTHER,
SCTP_ST_OTHER(SCTP_EVENT_ICMP_PROTO_UNREACH),
asoc->state, asoc->ep, asoc, t,
GFP_ATOMIC);
diff --git a/net/sctp/primitive.c b/net/sctp/primitive.c
index 534c7ea..a84a602 100644
--- a/net/sctp/primitive.c
+++ b/net/sctp/primitive.c
@@ -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; \
}
diff --git a/net/sctp/sm_sideeffect.c b/net/sctp/sm_sideeffect.c
index 529e3e4..2c895fd 100644
--- a/net/sctp/sm_sideeffect.c
+++ b/net/sctp/sm_sideeffect.c
@@ -63,6 +63,7 @@ static int sctp_cmd_interpreter(sctp_event_t event_type,
sctp_state_t state,
struct sctp_endpoint *ep,
struct sctp_association *asoc,
+ struct net *net,
void *event_arg,
sctp_disposition_t status,
sctp_cmd_seq_t *commands,
@@ -252,6 +253,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. */

@@ -272,7 +274,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,
@@ -313,7 +315,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(sock_net(asoc->base.sk), SCTP_EVENT_T_TIMEOUT,
SCTP_ST_TIMEOUT(timeout_type),
asoc->state, asoc->ep, asoc,
(void *)timeout_type, GFP_ATOMIC);
@@ -389,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(sock_net(asoc->base.sk), SCTP_EVENT_T_TIMEOUT,
SCTP_ST_TIMEOUT(SCTP_EVENT_TIMEOUT_HEARTBEAT),
asoc->state, asoc->ep, asoc,
transport, GFP_ATOMIC);
@@ -427,7 +429,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(sock_net(asoc->base.sk), SCTP_EVENT_T_OTHER,
SCTP_ST_OTHER(SCTP_EVENT_ICMP_PROTO_UNREACH),
asoc->state, asoc->ep, asoc, transport, GFP_ATOMIC);

@@ -603,7 +605,8 @@ static void sctp_cmd_assoc_failed(sctp_cmd_seq_t *commands,
* since all other cases use "temporary" associations and can do all
* their work in statefuns directly.
*/
-static int sctp_cmd_process_init(sctp_cmd_seq_t *commands,
+static int sctp_cmd_process_init(struct net *net,
+ sctp_cmd_seq_t *commands,
struct sctp_association *asoc,
struct sctp_chunk *chunk,
sctp_init_chunk_t *peer_init,
@@ -617,7 +620,7 @@ static int sctp_cmd_process_init(sctp_cmd_seq_t *commands,
* just return the error and stop processing the stack.
*/
if (!sctp_process_init(asoc, chunk, sctp_source(chunk), peer_init,
- &init_net, gfp))
+ net, gfp))
error = -ENOMEM;
else
error = 0;
@@ -756,7 +759,7 @@ static int sctp_cmd_process_sack(sctp_cmd_seq_t *cmds,

if (sctp_outq_sack(&asoc->outqueue, sackh)) {
/* There are no more TSNs awaiting SACK. */
- err = sctp_do_sm(SCTP_EVENT_T_OTHER,
+ err = sctp_do_sm(sock_net(asoc->base.sk), SCTP_EVENT_T_OTHER,
SCTP_ST_OTHER(SCTP_EVENT_NO_PENDING_TSN),
asoc->state, asoc->ep, asoc, NULL,
GFP_ATOMIC);
@@ -1055,7 +1058,8 @@ 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(sock_net(asoc->base.sk), asoc,
+ asconf))
sctp_chunk_free(asconf);
else
asoc->addip_last_asconf = asconf;
@@ -1091,7 +1095,8 @@ 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,
@@ -1107,31 +1112,13 @@ int sctp_do_sm(sctp_event_t event_type, sctp_subtype_t subtype,
static printfn_t *table[] = {
NULL, sctp_cname, sctp_tname, sctp_oname, sctp_pname,
};
- struct net *net;

printfn_t *debug_fn __attribute__ ((unused)) = table[event_type];

- /* The following is a temporary kludge. It'll be fixed in the next
- * patch. We need struct net to pass to the various
- * sctp_disposition_t functions, so Check if there's struct net
- * information in the association, if not, get the information
- * from the endpoint.
- */
- if ((ep) && (&ep->base) && (ep->base.sk) &&
- (ep->base.sk->sk_net)) {
- net = sock_net(ep->base.sk);
- } else {
- if ((asoc) && (&asoc->base) && (asoc->base.sk)
- && (asoc->base.sk->sk_net)) {
- net = sock_net(asoc->base.sk);
- } else
- net = &init_net;
- }
-
/* 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);

@@ -1172,7 +1159,7 @@ static int sctp_side_effects(sctp_event_t event_type, sctp_subtype_t subtype,
* disposition SCTP_DISPOSITION_CONSUME.
*/
if (0 != (error = sctp_cmd_interpreter(event_type, subtype, state,
- ep, asoc,
+ ep, asoc, net,
event_arg, status,
commands, gfp)))
goto bail;
@@ -1243,6 +1230,7 @@ static int sctp_cmd_interpreter(sctp_event_t event_type,
sctp_state_t state,
struct sctp_endpoint *ep,
struct sctp_association *asoc,
+ struct net *net,
void *event_arg,
sctp_disposition_t status,
sctp_cmd_seq_t *commands,
@@ -1365,8 +1353,9 @@ static int sctp_cmd_interpreter(sctp_event_t event_type,
* there is an error just return to the outter
* layer which will bail.
*/
- error = sctp_cmd_process_init(commands, asoc, chunk,
- cmd->obj.ptr, gfp);
+ error = sctp_cmd_process_init(net, commands, asoc,
+ chunk, cmd->obj.ptr,
+ gfp);
break;

case SCTP_CMD_GEN_COOKIE_ECHO:
diff --git a/net/sctp/sm_statetable.c b/net/sctp/sm_statetable.c
index 7c211a7..c249e59 100644
--- a/net/sctp/sm_statetable.c
+++ b/net/sctp/sm_statetable.c
@@ -82,7 +82,8 @@ 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)
{
diff --git a/net/sctp/socket.c b/net/sctp/socket.c
index 790e597..78e4576 100644
--- a/net/sctp/socket.c
+++ b/net/sctp/socket.c
@@ -211,6 +211,8 @@ static inline int sctp_verify_addr(struct sock *sk, union sctp_addr *addr,
struct sctp_association *sctp_id2assoc(struct sock *sk, sctp_assoc_t id)
{
struct sctp_association *asoc = NULL;
+ struct sctp_ns_globals *ns_globals =
+ sctp_get_ns_globals(sock_net(sk));

/* If this is not a UDP-style socket, assoc id should be ignored. */
if (!sctp_style(sk, UDP)) {
@@ -232,9 +234,10 @@ struct sctp_association *sctp_id2assoc(struct sock *sk, sctp_assoc_t id)
if (!id || (id == (sctp_assoc_t)-1))
return NULL;

- spin_lock_bh(&sctp_assocs_id_lock);
- asoc = (struct sctp_association *)idr_find(&sctp_assocs_id, (int)id);
- spin_unlock_bh(&sctp_assocs_id_lock);
+ spin_lock_bh(&ns_globals->assocs_id_lock);
+ asoc = (struct sctp_association *)idr_find(&ns_globals->assocs_id,
+ (int)id);
+ spin_unlock_bh(&ns_globals->assocs_id_lock);

if (!asoc || (asoc->base.sk != sk) || asoc->base.dead)
return NULL;
@@ -441,7 +444,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(sock_net(asoc->base.sk), asoc, chunk);
if (retval)
sctp_chunk_free(chunk);
else
@@ -1179,8 +1182,8 @@ static int __sctp_connect(struct sock* sk,
}

err = sctp_assoc_set_bind_addr_from_ep(asoc,
- sock_net(sk),
- scope, GFP_KERNEL);
+ sock_net(sk), scope,
+ GFP_KERNEL);
if (err < 0) {
goto out_free;
}
@@ -1209,7 +1212,7 @@ static int __sctp_connect(struct sock* sk,
goto out_free;
}

- err = sctp_primitive_ASSOCIATE(asoc, NULL);
+ err = sctp_primitive_ASSOCIATE(sock_net(sk), asoc, NULL);
if (err < 0) {
goto out_free;
}
@@ -1508,9 +1511,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(sock_net(sk), asoc, chunk);
} else
- sctp_primitive_SHUTDOWN(asoc, NULL);
+ sctp_primitive_SHUTDOWN(sock_net(sk), asoc, NULL);
}

/* On a TCP-style socket, block for at most linger_time if set. */
@@ -1723,7 +1726,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(sock_net(sk), asoc, NULL);
err = 0;
goto out_unlock;
}
@@ -1736,7 +1739,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(sock_net(sk), asoc, chunk);
err = 0;
goto out_unlock;
}
@@ -1910,7 +1913,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(sock_net(sk), asoc, NULL);
if (err < 0)
goto out_free;
SCTP_DEBUG_PRINTK("We associated primitively.\n");
@@ -1938,7 +1941,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(sock_net(sk), asoc, datamsg);
/* Did the lower layer accept the chunk? */
if (err)
sctp_datamsg_free(datamsg);
@@ -2331,7 +2334,8 @@ static int sctp_apply_peer_addr_params(struct net *net,
int error;

if (params->spp_flags & SPP_HB_DEMAND && trans) {
- error = sctp_primitive_REQUESTHEARTBEAT (trans->asoc, trans);
+ error = sctp_primitive_REQUESTHEARTBEAT(net, trans->asoc,
+ trans);
if (error)
return error;
}
@@ -2398,7 +2402,8 @@ static int sctp_apply_peer_addr_params(struct net *net,
int update = (trans->param_flags & SPP_PMTUD_DISABLE) &&
(params->spp_flags & SPP_PMTUD_ENABLE);
trans->param_flags =
- (trans->param_flags & ~SPP_PMTUD) | pmtud_change;
+ (trans->param_flags & ~SPP_PMTUD) |
+ pmtud_change;
if (update) {
sctp_transport_pmtu(net, trans,
sctp_opt2sk(sp));
@@ -4035,7 +4040,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(sock_net(sk), asoc, NULL);
}
}
}
@@ -4666,11 +4671,9 @@ static int sctp_copy_laddrs(struct sock *sk, __u16 port, void *to,
union sctp_addr temp;
int cnt = 0;
int addrlen;
- struct sctp_net_params *net_params =
- sctp_get_params(sock_net(sk));

rcu_read_lock();
- list_for_each_entry_rcu(addr, &net_params->local_addr_list, list) {
+ list_for_each_entry_rcu(addr, &sctp_local_addr_list, list) {
if (!addr->valid)
continue;

--
1.7.9.5

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/