* [PATCH 07/13] SCTP: Make primitive functions pass per-namespace parameters.
From: Jan Ariyasu @ 2012-08-04 21:33 UTC (permalink / raw)
To: Vlad Yasevich, David S. Miller, linux-sctp, netdev, linux-kernel
Cc: Jan Ariyasu
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@hp.com>
---
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
^ permalink raw reply related
* [PATCH 06/13] SCTP: turn on namespace awareness for the state-machine functions.
From: Jan Ariyasu @ 2012-08-04 21:33 UTC (permalink / raw)
To: Vlad Yasevich, David S. Miller, linux-sctp, netdev, linux-kernel
Cc: Jan Ariyasu
In particular, turn on netns-specific control sockets in the
namespaces and set up the groundwork to use per-namespace sysfs
parameters in these functions.
Signed-off-by: Jan Ariyasu <jan.ariyasu@hp.com>
---
include/net/sctp/sm.h | 3 +-
net/sctp/sm_sideeffect.c | 25 +-
net/sctp/sm_statefuns.c | 674 +++++++++++++++++++++++++++-------------------
3 files changed, 428 insertions(+), 274 deletions(-)
diff --git a/include/net/sctp/sm.h b/include/net/sctp/sm.h
index 9148632..a83ce1b 100644
--- a/include/net/sctp/sm.h
+++ b/include/net/sctp/sm.h
@@ -77,7 +77,8 @@ typedef struct {
int action;
} sctp_sm_command_t;
-typedef sctp_disposition_t (sctp_state_fn_t) (const struct sctp_endpoint *,
+typedef sctp_disposition_t (sctp_state_fn_t) (struct net *net,
+ const struct sctp_endpoint *,
const struct sctp_association *,
const sctp_subtype_t type,
void *arg,
diff --git a/net/sctp/sm_sideeffect.c b/net/sctp/sm_sideeffect.c
index 8fe4a25..529e3e4 100644
--- a/net/sctp/sm_sideeffect.c
+++ b/net/sctp/sm_sideeffect.c
@@ -71,6 +71,7 @@ static int sctp_side_effects(sctp_event_t event_type, sctp_subtype_t subtype,
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,
@@ -1106,8 +1107,27 @@ 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.
*/
@@ -1116,11 +1136,11 @@ int sctp_do_sm(sctp_event_t event_type, sctp_subtype_t subtype,
sctp_init_cmd_seq(&commands);
DEBUG_PRE;
- status = (*state_fn->fn)(ep, asoc, subtype, event_arg, &commands);
+ status = (*state_fn->fn)(net, ep, asoc, subtype, event_arg, &commands);
DEBUG_POST;
error = sctp_side_effects(event_type, subtype, state,
- ep, asoc, event_arg, status,
+ ep, asoc, net, event_arg, status,
&commands, gfp);
DEBUG_POST_SFX;
@@ -1137,6 +1157,7 @@ static int sctp_side_effects(sctp_event_t event_type, sctp_subtype_t subtype,
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,
diff --git a/net/sctp/sm_statefuns.c b/net/sctp/sm_statefuns.c
index 85a46ac..b9b6b13 100644
--- a/net/sctp/sm_statefuns.c
+++ b/net/sctp/sm_statefuns.c
@@ -17,7 +17,7 @@
*
* This SCTP implementation is distributed in the hope that it
* will be useful, but WITHOUT ANY WARRANTY; without even the implied
- * ************************
+ * ************************
* warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU General Public License for more details.
*
@@ -35,10 +35,10 @@
*
* Written or modified by:
* La Monte H.P. Yarroll <piggy@acm.org>
- * Karl Knutson <karl@athena.chicago.il.us>
+ * Karl Knutson <karl@athena.chicago.il.us>
* Mathew Kotowsky <kotowsky@sctp.org>
* Sridhar Samudrala <samudrala@us.ibm.com>
- * Jon Grimm <jgrimm@us.ibm.com>
+ * Jon Grimm <jgrimm@us.ibm.com>
* Hui Huang <hui.huang@nokia.com>
* Dajiang Zhang <dajiang.zhang@nokia.com>
* Daisy Chang <daisyc@us.ibm.com>
@@ -70,40 +70,49 @@ static struct sctp_packet *sctp_abort_pkt_new(const struct sctp_endpoint *ep,
const struct sctp_association *asoc,
struct sctp_chunk *chunk,
const void *payload,
- size_t paylen);
-static int sctp_eat_data(const struct sctp_association *asoc,
+ size_t paylen,
+ struct net *net);
+static int sctp_eat_data(struct net *net,
+ const struct sctp_association *asoc,
struct sctp_chunk *chunk,
sctp_cmd_seq_t *commands);
-static struct sctp_packet *sctp_ootb_pkt_new(const struct sctp_association *asoc,
- const struct sctp_chunk *chunk);
-static void sctp_send_stale_cookie_err(const struct sctp_endpoint *ep,
+static struct sctp_packet *sctp_ootb_pkt_new(struct net *net,
+ const struct sctp_association *asoc,
+ const struct sctp_chunk *chunk);
+static void sctp_send_stale_cookie_err(struct net *net,
+ const struct sctp_endpoint *ep,
const struct sctp_association *asoc,
const struct sctp_chunk *chunk,
sctp_cmd_seq_t *commands,
struct sctp_chunk *err_chunk);
-static sctp_disposition_t sctp_sf_do_5_2_6_stale(const struct sctp_endpoint *ep,
+static sctp_disposition_t sctp_sf_do_5_2_6_stale(struct net *net,
+ const struct sctp_endpoint *ep,
const struct sctp_association *asoc,
const sctp_subtype_t type,
void *arg,
sctp_cmd_seq_t *commands);
-static sctp_disposition_t sctp_sf_shut_8_4_5(const struct sctp_endpoint *ep,
+static sctp_disposition_t sctp_sf_shut_8_4_5(struct net *net,
+ const struct sctp_endpoint *ep,
const struct sctp_association *asoc,
const sctp_subtype_t type,
void *arg,
sctp_cmd_seq_t *commands);
-static sctp_disposition_t sctp_sf_tabort_8_4_8(const struct sctp_endpoint *ep,
+static sctp_disposition_t sctp_sf_tabort_8_4_8(struct net *net,
+ const struct sctp_endpoint *ep,
const struct sctp_association *asoc,
const sctp_subtype_t type,
void *arg,
sctp_cmd_seq_t *commands);
static struct sctp_sackhdr *sctp_sm_pull_sack(struct sctp_chunk *chunk);
-static sctp_disposition_t sctp_stop_t1_and_abort(sctp_cmd_seq_t *commands,
+static sctp_disposition_t sctp_stop_t1_and_abort(struct net *net,
+ sctp_cmd_seq_t *commands,
__be16 error, int sk_err,
const struct sctp_association *asoc,
struct sctp_transport *transport);
static sctp_disposition_t sctp_sf_abort_violation(
+ struct net *net,
const struct sctp_endpoint *ep,
const struct sctp_association *asoc,
void *arg,
@@ -112,6 +121,7 @@ static sctp_disposition_t sctp_sf_abort_violation(
const size_t paylen);
static sctp_disposition_t sctp_sf_violation_chunklen(
+ struct net *net,
const struct sctp_endpoint *ep,
const struct sctp_association *asoc,
const sctp_subtype_t type,
@@ -119,6 +129,7 @@ static sctp_disposition_t sctp_sf_violation_chunklen(
sctp_cmd_seq_t *commands);
static sctp_disposition_t sctp_sf_violation_paramlen(
+ struct net *net,
const struct sctp_endpoint *ep,
const struct sctp_association *asoc,
const sctp_subtype_t type,
@@ -126,6 +137,7 @@ static sctp_disposition_t sctp_sf_violation_paramlen(
sctp_cmd_seq_t *commands);
static sctp_disposition_t sctp_sf_violation_ctsn(
+ struct net *net,
const struct sctp_endpoint *ep,
const struct sctp_association *asoc,
const sctp_subtype_t type,
@@ -133,6 +145,7 @@ static sctp_disposition_t sctp_sf_violation_ctsn(
sctp_cmd_seq_t *commands);
static sctp_disposition_t sctp_sf_violation_chunk(
+ struct net *net,
const struct sctp_endpoint *ep,
const struct sctp_association *asoc,
const sctp_subtype_t type,
@@ -144,7 +157,8 @@ static sctp_ierror_t sctp_sf_authenticate(const struct sctp_endpoint *ep,
const sctp_subtype_t type,
struct sctp_chunk *chunk);
-static sctp_disposition_t __sctp_sf_do_9_1_abort(const struct sctp_endpoint *ep,
+static sctp_disposition_t __sctp_sf_do_9_1_abort(struct net *net,
+ const struct sctp_endpoint *ep,
const struct sctp_association *asoc,
const sctp_subtype_t type,
void *arg,
@@ -204,7 +218,8 @@ sctp_chunk_length_valid(struct sctp_chunk *chunk,
*
* The return value is the disposition of the chunk.
*/
-sctp_disposition_t sctp_sf_do_4_C(const struct sctp_endpoint *ep,
+sctp_disposition_t sctp_sf_do_4_C(struct net *net,
+ const struct sctp_endpoint *ep,
const struct sctp_association *asoc,
const sctp_subtype_t type,
void *arg,
@@ -214,7 +229,7 @@ sctp_disposition_t sctp_sf_do_4_C(const struct sctp_endpoint *ep,
struct sctp_ulpevent *ev;
if (!sctp_vtag_verify_either(chunk, asoc))
- return sctp_sf_pdiscard(ep, asoc, type, arg, commands);
+ return sctp_sf_pdiscard(net, ep, asoc, type, arg, commands);
/* RFC 2960 6.10 Bundling
*
@@ -222,11 +237,12 @@ sctp_disposition_t sctp_sf_do_4_C(const struct sctp_endpoint *ep,
* SHUTDOWN COMPLETE with any other chunks.
*/
if (!chunk->singleton)
- return sctp_sf_violation_chunk(ep, asoc, type, arg, commands);
+ return sctp_sf_violation_chunk(net, ep, asoc, type,
+ arg, commands);
/* Make sure that the SHUTDOWN_COMPLETE chunk has a valid length. */
if (!sctp_chunk_length_valid(chunk, sizeof(sctp_chunkhdr_t)))
- return sctp_sf_violation_chunklen(ep, asoc, type, arg,
+ return sctp_sf_violation_chunklen(net, ep, asoc, type, arg,
commands);
/* RFC 2960 10.2 SCTP-to-ULP
@@ -289,7 +305,8 @@ sctp_disposition_t sctp_sf_do_4_C(const struct sctp_endpoint *ep,
*
* The return value is the disposition of the chunk.
*/
-sctp_disposition_t sctp_sf_do_5_1B_init(const struct sctp_endpoint *ep,
+sctp_disposition_t sctp_sf_do_5_1B_init(struct net *net,
+ const struct sctp_endpoint *ep,
const struct sctp_association *asoc,
const sctp_subtype_t type,
void *arg,
@@ -313,21 +330,21 @@ sctp_disposition_t sctp_sf_do_5_1B_init(const struct sctp_endpoint *ep,
* with an INIT chunk that is bundled with other chunks.
*/
if (!chunk->singleton)
- return sctp_sf_pdiscard(ep, asoc, type, arg, commands);
+ return sctp_sf_pdiscard(net, ep, asoc, type, arg, commands);
/* If the packet is an OOTB packet which is temporarily on the
* control endpoint, respond with an ABORT.
*/
- if (ep == sctp_sk((*(sctp_get_ctl_sock(&init_net))))->ep) {
+ if (ep == sctp_sk((*(sctp_get_ctl_sock(net))))->ep) {
SCTP_INC_STATS(SCTP_MIB_OUTOFBLUES);
- return sctp_sf_tabort_8_4_8(ep, asoc, type, arg, commands);
+ return sctp_sf_tabort_8_4_8(net, ep, asoc, type, arg, commands);
}
/* 3.1 A packet containing an INIT chunk MUST have a zero Verification
* Tag.
*/
if (chunk->sctp_hdr->vtag != 0)
- return sctp_sf_tabort_8_4_8(ep, asoc, type, arg, commands);
+ return sctp_sf_tabort_8_4_8(net, ep, asoc, type, arg, commands);
/* Make sure that the INIT chunk has a valid length.
* Normally, this would cause an ABORT with a Protocol Violation
@@ -335,7 +352,7 @@ sctp_disposition_t sctp_sf_do_5_1B_init(const struct sctp_endpoint *ep,
* just discard the packet.
*/
if (!sctp_chunk_length_valid(chunk, sizeof(sctp_init_chunk_t)))
- return sctp_sf_pdiscard(ep, asoc, type, arg, commands);
+ return sctp_sf_pdiscard(net, ep, asoc, type, arg, commands);
/* If the INIT is coming toward a closing socket, we'll send back
* and ABORT. Essentially, this catches the race of INIT being
@@ -344,7 +361,7 @@ sctp_disposition_t sctp_sf_do_5_1B_init(const struct sctp_endpoint *ep,
* can treat this OOTB
*/
if (sctp_sstate(ep->base.sk, CLOSING))
- return sctp_sf_tabort_8_4_8(ep, asoc, type, arg, commands);
+ return sctp_sf_tabort_8_4_8(net, ep, asoc, type, arg, commands);
/* Verify the INIT chunk before processing it. */
err_chunk = NULL;
@@ -359,7 +376,7 @@ sctp_disposition_t sctp_sf_do_5_1B_init(const struct sctp_endpoint *ep,
(__u8 *)(err_chunk->chunk_hdr) +
sizeof(sctp_chunkhdr_t),
ntohs(err_chunk->chunk_hdr->length) -
- sizeof(sctp_chunkhdr_t));
+ sizeof(sctp_chunkhdr_t), net);
sctp_chunk_free(err_chunk);
@@ -372,7 +389,7 @@ sctp_disposition_t sctp_sf_do_5_1B_init(const struct sctp_endpoint *ep,
return SCTP_DISPOSITION_NOMEM;
}
} else {
- return sctp_sf_tabort_8_4_8(ep, asoc, type, arg,
+ return sctp_sf_tabort_8_4_8(net, ep, asoc, type, arg,
commands);
}
}
@@ -387,16 +404,15 @@ sctp_disposition_t sctp_sf_do_5_1B_init(const struct sctp_endpoint *ep,
if (!new_asoc)
goto nomem;
- if (sctp_assoc_set_bind_addr_from_ep(new_asoc,
- &init_net,
+ if (sctp_assoc_set_bind_addr_from_ep(new_asoc, net,
sctp_scope(sctp_source(chunk)),
GFP_ATOMIC) < 0)
goto nomem_init;
/* The call, sctp_process_init(), can fail on memory allocation. */
if (!sctp_process_init(new_asoc, chunk, sctp_source(chunk),
- (sctp_init_chunk_t *)chunk->chunk_hdr,
- &init_net, GFP_ATOMIC))
+ (sctp_init_chunk_t *)chunk->chunk_hdr, net,
+ GFP_ATOMIC))
goto nomem_init;
/* B) "Z" shall respond immediately with an INIT ACK chunk. */
@@ -485,7 +501,8 @@ nomem:
*
* The return value is the disposition of the chunk.
*/
-sctp_disposition_t sctp_sf_do_5_1C_ack(const struct sctp_endpoint *ep,
+sctp_disposition_t sctp_sf_do_5_1C_ack(struct net *net,
+ const struct sctp_endpoint *ep,
const struct sctp_association *asoc,
const sctp_subtype_t type,
void *arg,
@@ -497,18 +514,19 @@ sctp_disposition_t sctp_sf_do_5_1C_ack(const struct sctp_endpoint *ep,
struct sctp_packet *packet;
if (!sctp_vtag_verify(chunk, asoc))
- return sctp_sf_pdiscard(ep, asoc, type, arg, commands);
+ return sctp_sf_pdiscard(net, ep, asoc, type, arg, commands);
/* 6.10 Bundling
* An endpoint MUST NOT bundle INIT, INIT ACK or
* SHUTDOWN COMPLETE with any other chunks.
*/
if (!chunk->singleton)
- return sctp_sf_violation_chunk(ep, asoc, type, arg, commands);
+ return sctp_sf_violation_chunk(net, ep, asoc, type, arg,
+ commands);
/* Make sure that the INIT-ACK chunk has a valid length */
if (!sctp_chunk_length_valid(chunk, sizeof(sctp_initack_chunk_t)))
- return sctp_sf_violation_chunklen(ep, asoc, type, arg,
+ return sctp_sf_violation_chunklen(net, ep, asoc, type, arg,
commands);
/* Grab the INIT header. */
chunk->subh.init_hdr = (sctp_inithdr_t *) chunk->skb->data;
@@ -531,7 +549,7 @@ sctp_disposition_t sctp_sf_do_5_1C_ack(const struct sctp_endpoint *ep,
(__u8 *)(err_chunk->chunk_hdr) +
sizeof(sctp_chunkhdr_t),
ntohs(err_chunk->chunk_hdr->length) -
- sizeof(sctp_chunkhdr_t));
+ sizeof(sctp_chunkhdr_t), net);
sctp_chunk_free(err_chunk);
@@ -555,11 +573,13 @@ sctp_disposition_t sctp_sf_do_5_1C_ack(const struct sctp_endpoint *ep,
* was malformed.
*/
if (sctp_auth_recv_cid(SCTP_CID_ABORT, asoc))
- return sctp_sf_pdiscard(ep, asoc, type, arg, commands);
+ return sctp_sf_pdiscard(net, ep, asoc, type, arg,
+ commands);
SCTP_INC_STATS(SCTP_MIB_ABORTEDS);
- return sctp_stop_t1_and_abort(commands, error, ECONNREFUSED,
- asoc, chunk->transport);
+ return sctp_stop_t1_and_abort(net, commands, error,
+ ECONNREFUSED, asoc,
+ chunk->transport);
}
/* Tag the variable length parameters. Note that we never
@@ -634,7 +654,8 @@ sctp_disposition_t sctp_sf_do_5_1C_ack(const struct sctp_endpoint *ep,
*
* The return value is the disposition of the chunk.
*/
-sctp_disposition_t sctp_sf_do_5_1D_ce(const struct sctp_endpoint *ep,
+sctp_disposition_t sctp_sf_do_5_1D_ce(struct net *net,
+ const struct sctp_endpoint *ep,
const struct sctp_association *asoc,
const sctp_subtype_t type, void *arg,
sctp_cmd_seq_t *commands)
@@ -651,9 +672,9 @@ sctp_disposition_t sctp_sf_do_5_1D_ce(const struct sctp_endpoint *ep,
/* If the packet is an OOTB packet which is temporarily on the
* control endpoint, respond with an ABORT.
*/
- if (ep == sctp_sk((*(sctp_get_ctl_sock(&init_net))))->ep) {
+ if (ep == sctp_sk((*(sctp_get_ctl_sock(net))))->ep) {
SCTP_INC_STATS(SCTP_MIB_OUTOFBLUES);
- return sctp_sf_tabort_8_4_8(ep, asoc, type, arg, commands);
+ return sctp_sf_tabort_8_4_8(net, ep, asoc, type, arg, commands);
}
/* Make sure that the COOKIE_ECHO chunk has a valid length.
@@ -662,7 +683,7 @@ sctp_disposition_t sctp_sf_do_5_1D_ce(const struct sctp_endpoint *ep,
* in sctp_unpack_cookie().
*/
if (!sctp_chunk_length_valid(chunk, sizeof(sctp_chunkhdr_t)))
- return sctp_sf_pdiscard(ep, asoc, type, arg, commands);
+ return sctp_sf_pdiscard(net, ep, asoc, type, arg, commands);
/* If the endpoint is not listening or if the number of associations
* on the TCP-style socket exceed the max backlog, respond with an
@@ -671,7 +692,7 @@ sctp_disposition_t sctp_sf_do_5_1D_ce(const struct sctp_endpoint *ep,
sk = ep->base.sk;
if (!sctp_sstate(sk, LISTENING) ||
(sctp_style(sk, TCP) && sk_acceptq_is_full(sk)))
- return sctp_sf_tabort_8_4_8(ep, asoc, type, arg, commands);
+ return sctp_sf_tabort_8_4_8(net, ep, asoc, type, arg, commands);
/* "Decode" the chunk. We have no optional parameters so we
* are in good shape.
@@ -704,13 +725,15 @@ sctp_disposition_t sctp_sf_do_5_1D_ce(const struct sctp_endpoint *ep,
goto nomem;
case -SCTP_IERROR_STALE_COOKIE:
- sctp_send_stale_cookie_err(ep, asoc, chunk, commands,
- err_chk_p);
- return sctp_sf_pdiscard(ep, asoc, type, arg, commands);
+ sctp_send_stale_cookie_err(net, ep, asoc, chunk,
+ commands, err_chk_p);
+ return sctp_sf_pdiscard(net, ep, asoc, type, arg,
+ commands);
case -SCTP_IERROR_BAD_SIG:
default:
- return sctp_sf_pdiscard(ep, asoc, type, arg, commands);
+ return sctp_sf_pdiscard(net, ep, asoc, type, arg,
+ commands);
}
}
@@ -727,7 +750,7 @@ sctp_disposition_t sctp_sf_do_5_1D_ce(const struct sctp_endpoint *ep,
if (!sctp_process_init(new_asoc, chunk,
&chunk->subh.cookie_hdr->c.peer_addr,
- peer_init, &init_net, GFP_ATOMIC))
+ peer_init, net, GFP_ATOMIC))
goto nomem_init;
/* SCTP-AUTH: Now that we've populate required fields in
@@ -764,7 +787,8 @@ sctp_disposition_t sctp_sf_do_5_1D_ce(const struct sctp_endpoint *ep,
if (ret != SCTP_IERROR_NO_ERROR) {
sctp_association_free(new_asoc);
- return sctp_sf_pdiscard(ep, asoc, type, arg, commands);
+ return sctp_sf_pdiscard(net, ep, asoc, type, arg,
+ commands);
}
}
@@ -857,7 +881,8 @@ nomem:
*
* The return value is the disposition of the chunk.
*/
-sctp_disposition_t sctp_sf_do_5_1E_ca(const struct sctp_endpoint *ep,
+sctp_disposition_t sctp_sf_do_5_1E_ca(struct net *net,
+ const struct sctp_endpoint *ep,
const struct sctp_association *asoc,
const sctp_subtype_t type, void *arg,
sctp_cmd_seq_t *commands)
@@ -866,13 +891,13 @@ sctp_disposition_t sctp_sf_do_5_1E_ca(const struct sctp_endpoint *ep,
struct sctp_ulpevent *ev;
if (!sctp_vtag_verify(chunk, asoc))
- return sctp_sf_pdiscard(ep, asoc, type, arg, commands);
+ return sctp_sf_pdiscard(net, ep, asoc, type, arg, commands);
/* Verify that the chunk length for the COOKIE-ACK is OK.
* If we don't do this, any bundled chunks may be junked.
*/
if (!sctp_chunk_length_valid(chunk, sizeof(sctp_chunkhdr_t)))
- return sctp_sf_violation_chunklen(ep, asoc, type, arg,
+ return sctp_sf_violation_chunklen(net, ep, asoc, type, arg,
commands);
/* Reset init error count upon receipt of COOKIE-ACK,
@@ -934,7 +959,8 @@ nomem:
}
/* Generate and sendout a heartbeat packet. */
-static sctp_disposition_t sctp_sf_heartbeat(const struct sctp_endpoint *ep,
+static sctp_disposition_t sctp_sf_heartbeat(struct net *net,
+ const struct sctp_endpoint *ep,
const struct sctp_association *asoc,
const sctp_subtype_t type,
void *arg,
@@ -959,7 +985,8 @@ static sctp_disposition_t sctp_sf_heartbeat(const struct sctp_endpoint *ep,
}
/* Generate a HEARTBEAT packet on the given transport. */
-sctp_disposition_t sctp_sf_sendbeat_8_3(const struct sctp_endpoint *ep,
+sctp_disposition_t sctp_sf_sendbeat_8_3(struct net *net,
+ const struct sctp_endpoint *ep,
const struct sctp_association *asoc,
const sctp_subtype_t type,
void *arg,
@@ -987,7 +1014,7 @@ sctp_disposition_t sctp_sf_sendbeat_8_3(const struct sctp_endpoint *ep,
if (transport->param_flags & SPP_HB_ENABLE) {
if (SCTP_DISPOSITION_NOMEM ==
- sctp_sf_heartbeat(ep, asoc, type, arg,
+ sctp_sf_heartbeat(net, ep, asoc, type, arg,
commands))
return SCTP_DISPOSITION_NOMEM;
@@ -1029,7 +1056,8 @@ sctp_disposition_t sctp_sf_sendbeat_8_3(const struct sctp_endpoint *ep,
*
* The return value is the disposition of the chunk.
*/
-sctp_disposition_t sctp_sf_beat_8_3(const struct sctp_endpoint *ep,
+sctp_disposition_t sctp_sf_beat_8_3(struct net *net,
+ const struct sctp_endpoint *ep,
const struct sctp_association *asoc,
const sctp_subtype_t type,
void *arg,
@@ -1040,11 +1068,11 @@ sctp_disposition_t sctp_sf_beat_8_3(const struct sctp_endpoint *ep,
size_t paylen = 0;
if (!sctp_vtag_verify(chunk, asoc))
- return sctp_sf_pdiscard(ep, asoc, type, arg, commands);
+ return sctp_sf_pdiscard(net, ep, asoc, type, arg, commands);
/* Make sure that the HEARTBEAT chunk has a valid length. */
if (!sctp_chunk_length_valid(chunk, sizeof(sctp_heartbeat_chunk_t)))
- return sctp_sf_violation_chunklen(ep, asoc, type, arg,
+ return sctp_sf_violation_chunklen(net, ep, asoc, type, arg,
commands);
/* 8.3 The receiver of the HEARTBEAT should immediately
@@ -1096,7 +1124,8 @@ nomem:
*
* The return value is the disposition of the chunk.
*/
-sctp_disposition_t sctp_sf_backbeat_8_3(const struct sctp_endpoint *ep,
+sctp_disposition_t sctp_sf_backbeat_8_3(struct net *net,
+ const struct sctp_endpoint *ep,
const struct sctp_association *asoc,
const sctp_subtype_t type,
void *arg,
@@ -1109,12 +1138,12 @@ sctp_disposition_t sctp_sf_backbeat_8_3(const struct sctp_endpoint *ep,
unsigned long max_interval;
if (!sctp_vtag_verify(chunk, asoc))
- return sctp_sf_pdiscard(ep, asoc, type, arg, commands);
+ return sctp_sf_pdiscard(net, ep, asoc, type, arg, commands);
/* Make sure that the HEARTBEAT-ACK chunk has a valid length. */
if (!sctp_chunk_length_valid(chunk, sizeof(sctp_chunkhdr_t) +
sizeof(sctp_sender_hb_info_t)))
- return sctp_sf_violation_chunklen(ep, asoc, type, arg,
+ return sctp_sf_violation_chunklen(net, ep, asoc, type, arg,
commands);
hbinfo = (sctp_sender_hb_info_t *) chunk->skb->data;
@@ -1172,7 +1201,8 @@ sctp_disposition_t sctp_sf_backbeat_8_3(const struct sctp_endpoint *ep,
/* Helper function to send out an abort for the restart
* condition.
*/
-static int sctp_sf_send_restart_abort(union sctp_addr *ssa,
+static int sctp_sf_send_restart_abort(struct net *net,
+ union sctp_addr *ssa,
struct sctp_chunk *init,
sctp_cmd_seq_t *commands)
{
@@ -1198,12 +1228,12 @@ static int sctp_sf_send_restart_abort(union sctp_addr *ssa,
errhdr->length = htons(len);
/* Assign to the control socket. */
- ep = sctp_sk(*(sctp_get_ctl_sock(&init_net)))->ep;
+ ep = sctp_sk(*(sctp_get_ctl_sock(net)))->ep;
/* Association is NULL since this may be a restart attack and we
* want to send back the attacker's vtag.
*/
- pkt = sctp_abort_pkt_new(ep, NULL, init, errhdr, len);
+ pkt = sctp_abort_pkt_new(ep, NULL, init, errhdr, len, net);
if (!pkt)
goto out;
@@ -1243,6 +1273,7 @@ static int sctp_sf_check_restart_addrs(const struct sctp_association *new_asoc,
{
struct sctp_transport *new_addr;
int ret = 1;
+ struct net *net = sock_net(asoc->base.sk);
/* Implementor's Guide - Section 5.2.2
* ...
@@ -1259,7 +1290,7 @@ static int sctp_sf_check_restart_addrs(const struct sctp_association *new_asoc,
transports) {
if (!list_has_sctp_addr(&asoc->peer.transport_addr_list,
&new_addr->ipaddr)) {
- sctp_sf_send_restart_abort(&new_addr->ipaddr, init,
+ sctp_sf_send_restart_abort(net, &new_addr->ipaddr, init,
commands);
ret = 0;
break;
@@ -1307,10 +1338,10 @@ static void sctp_tietags_populate(struct sctp_association *new_asoc,
* existing parameters of the association (e.g. number of
* outbound streams) into the INIT ACK and cookie.
*/
- new_asoc->rwnd = asoc->rwnd;
+ new_asoc->rwnd = asoc->rwnd;
new_asoc->c.sinit_num_ostreams = asoc->c.sinit_num_ostreams;
new_asoc->c.sinit_max_instreams = asoc->c.sinit_max_instreams;
- new_asoc->c.initial_tsn = asoc->c.initial_tsn;
+ new_asoc->c.initial_tsn = asoc->c.initial_tsn;
}
/*
@@ -1359,6 +1390,7 @@ static char sctp_tietags_compare(struct sctp_association *new_asoc,
* chunk handling.
*/
static sctp_disposition_t sctp_sf_do_unexpected_init(
+ struct net *net,
const struct sctp_endpoint *ep,
const struct sctp_association *asoc,
const sctp_subtype_t type,
@@ -1383,20 +1415,20 @@ static sctp_disposition_t sctp_sf_do_unexpected_init(
* with an INIT chunk that is bundled with other chunks.
*/
if (!chunk->singleton)
- return sctp_sf_pdiscard(ep, asoc, type, arg, commands);
+ return sctp_sf_pdiscard(net, ep, asoc, type, arg, commands);
/* 3.1 A packet containing an INIT chunk MUST have a zero Verification
* Tag.
*/
if (chunk->sctp_hdr->vtag != 0)
- return sctp_sf_tabort_8_4_8(ep, asoc, type, arg, commands);
+ return sctp_sf_tabort_8_4_8(net, ep, asoc, type, arg, commands);
/* Make sure that the INIT chunk has a valid length.
* In this case, we generate a protocol violation since we have
* an association established.
*/
if (!sctp_chunk_length_valid(chunk, sizeof(sctp_init_chunk_t)))
- return sctp_sf_violation_chunklen(ep, asoc, type, arg,
+ return sctp_sf_violation_chunklen(net, ep, asoc, type, arg,
commands);
/* Grab the INIT header. */
chunk->subh.init_hdr = (sctp_inithdr_t *) chunk->skb->data;
@@ -1417,7 +1449,7 @@ static sctp_disposition_t sctp_sf_do_unexpected_init(
(__u8 *)(err_chunk->chunk_hdr) +
sizeof(sctp_chunkhdr_t),
ntohs(err_chunk->chunk_hdr->length) -
- sizeof(sctp_chunkhdr_t));
+ sizeof(sctp_chunkhdr_t), net);
if (packet) {
sctp_add_cmd_sf(commands, SCTP_CMD_SEND_PKT,
@@ -1429,7 +1461,7 @@ static sctp_disposition_t sctp_sf_do_unexpected_init(
}
goto cleanup;
} else {
- return sctp_sf_tabort_8_4_8(ep, asoc, type, arg,
+ return sctp_sf_tabort_8_4_8(net, ep, asoc, type, arg,
commands);
}
}
@@ -1445,7 +1477,7 @@ static sctp_disposition_t sctp_sf_do_unexpected_init(
if (!new_asoc)
goto nomem;
- if (sctp_assoc_set_bind_addr_from_ep(new_asoc, &init_net,
+ if (sctp_assoc_set_bind_addr_from_ep(new_asoc, net,
sctp_scope(sctp_source(chunk)), GFP_ATOMIC) < 0)
goto nomem;
@@ -1455,7 +1487,7 @@ static sctp_disposition_t sctp_sf_do_unexpected_init(
*/
if (!sctp_process_init(new_asoc, chunk, sctp_source(chunk),
(sctp_init_chunk_t *)chunk->chunk_hdr,
- &init_net, GFP_ATOMIC))
+ net, GFP_ATOMIC))
goto nomem;
/* Make sure no new addresses are being added during the
@@ -1571,7 +1603,8 @@ cleanup:
*
* The return value is the disposition of the chunk.
*/
-sctp_disposition_t sctp_sf_do_5_2_1_siminit(const struct sctp_endpoint *ep,
+sctp_disposition_t sctp_sf_do_5_2_1_siminit(struct net *net,
+ const struct sctp_endpoint *ep,
const struct sctp_association *asoc,
const sctp_subtype_t type,
void *arg,
@@ -1580,7 +1613,7 @@ sctp_disposition_t sctp_sf_do_5_2_1_siminit(const struct sctp_endpoint *ep,
/* Call helper to do the real work for both simulataneous and
* duplicate INIT chunk handling.
*/
- return sctp_sf_do_unexpected_init(ep, asoc, type, arg, commands);
+ return sctp_sf_do_unexpected_init(net, ep, asoc, type, arg, commands);
}
/*
@@ -1624,7 +1657,8 @@ sctp_disposition_t sctp_sf_do_5_2_1_siminit(const struct sctp_endpoint *ep,
*
* The return value is the disposition of the chunk.
*/
-sctp_disposition_t sctp_sf_do_5_2_2_dupinit(const struct sctp_endpoint *ep,
+sctp_disposition_t sctp_sf_do_5_2_2_dupinit(struct net *net,
+ const struct sctp_endpoint *ep,
const struct sctp_association *asoc,
const sctp_subtype_t type,
void *arg,
@@ -1633,7 +1667,7 @@ sctp_disposition_t sctp_sf_do_5_2_2_dupinit(const struct sctp_endpoint *ep,
/* Call helper to do the real work for both simulataneous and
* duplicate INIT chunk handling.
*/
- return sctp_sf_do_unexpected_init(ep, asoc, type, arg, commands);
+ return sctp_sf_do_unexpected_init(net, ep, asoc, type, arg, commands);
}
@@ -1646,7 +1680,8 @@ sctp_disposition_t sctp_sf_do_5_2_2_dupinit(const struct sctp_endpoint *ep,
* An unexpected INIT ACK usually indicates the processing of an old or
* duplicated INIT chunk.
*/
-sctp_disposition_t sctp_sf_do_5_2_3_initack(const struct sctp_endpoint *ep,
+sctp_disposition_t sctp_sf_do_5_2_3_initack(struct net *net,
+ const struct sctp_endpoint *ep,
const struct sctp_association *asoc,
const sctp_subtype_t type,
void *arg, sctp_cmd_seq_t *commands)
@@ -1654,10 +1689,11 @@ sctp_disposition_t sctp_sf_do_5_2_3_initack(const struct sctp_endpoint *ep,
/* Per the above section, we'll discard the chunk if we have an
* endpoint. If this is an OOTB INIT-ACK, treat it as such.
*/
- if (ep == sctp_sk(*(sctp_get_ctl_sock(&init_net)))->ep)
- return sctp_sf_ootb(ep, asoc, type, arg, commands);
+ if (ep == sctp_sk(*(sctp_get_ctl_sock(net)))->ep)
+ return sctp_sf_ootb(net, ep, asoc, type, arg, commands);
else
- return sctp_sf_discard_chunk(ep, asoc, type, arg, commands);
+ return sctp_sf_discard_chunk(net, ep, asoc, type, arg,
+ commands);
}
/* Unexpected COOKIE-ECHO handler for peer restart (Table 2, action 'A')
@@ -1665,7 +1701,8 @@ sctp_disposition_t sctp_sf_do_5_2_3_initack(const struct sctp_endpoint *ep,
* Section 5.2.4
* A) In this case, the peer may have restarted.
*/
-static sctp_disposition_t sctp_sf_do_dupcook_a(const struct sctp_endpoint *ep,
+static sctp_disposition_t sctp_sf_do_dupcook_a(struct net *net,
+ const struct sctp_endpoint *ep,
const struct sctp_association *asoc,
struct sctp_chunk *chunk,
sctp_cmd_seq_t *commands,
@@ -1683,7 +1720,7 @@ static sctp_disposition_t sctp_sf_do_dupcook_a(const struct sctp_endpoint *ep,
peer_init = &chunk->subh.cookie_hdr->c.peer_init[0];
if (!sctp_process_init(new_asoc, chunk, sctp_source(chunk), peer_init,
- &init_net, GFP_ATOMIC))
+ net, GFP_ATOMIC))
goto nomem;
/* Make sure no new addresses are being added during the
@@ -1701,7 +1738,7 @@ static sctp_disposition_t sctp_sf_do_dupcook_a(const struct sctp_endpoint *ep,
* its peer.
*/
if (sctp_state(asoc, SHUTDOWN_ACK_SENT)) {
- disposition = sctp_sf_do_9_2_reshutack(ep, asoc,
+ disposition = sctp_sf_do_9_2_reshutack(net, ep, asoc,
SCTP_ST_CHUNK(chunk->chunk_hdr->type),
chunk, commands);
if (SCTP_DISPOSITION_NOMEM == disposition)
@@ -1764,7 +1801,8 @@ nomem:
* after responding to the local endpoint's INIT
*/
/* This case represents an initialization collision. */
-static sctp_disposition_t sctp_sf_do_dupcook_b(const struct sctp_endpoint *ep,
+static sctp_disposition_t sctp_sf_do_dupcook_b(struct net *net,
+ const struct sctp_endpoint *ep,
const struct sctp_association *asoc,
struct sctp_chunk *chunk,
sctp_cmd_seq_t *commands,
@@ -1778,7 +1816,7 @@ static sctp_disposition_t sctp_sf_do_dupcook_b(const struct sctp_endpoint *ep,
*/
peer_init = &chunk->subh.cookie_hdr->c.peer_init[0];
if (!sctp_process_init(new_asoc, chunk, sctp_source(chunk), peer_init,
- &init_net, GFP_ATOMIC))
+ net, GFP_ATOMIC))
goto nomem;
/* Update the content of current association. */
@@ -1834,7 +1872,8 @@ nomem:
* but a new tag of its own.
*/
/* This case represents an initialization collision. */
-static sctp_disposition_t sctp_sf_do_dupcook_c(const struct sctp_endpoint *ep,
+static sctp_disposition_t sctp_sf_do_dupcook_c(struct net *net,
+ const struct sctp_endpoint *ep,
const struct sctp_association *asoc,
struct sctp_chunk *chunk,
sctp_cmd_seq_t *commands,
@@ -1855,7 +1894,8 @@ static sctp_disposition_t sctp_sf_do_dupcook_c(const struct sctp_endpoint *ep,
* enter the ESTABLISHED state, if it has not already done so.
*/
/* This case represents an initialization collision. */
-static sctp_disposition_t sctp_sf_do_dupcook_d(const struct sctp_endpoint *ep,
+static sctp_disposition_t sctp_sf_do_dupcook_d(struct net *net,
+ const struct sctp_endpoint *ep,
const struct sctp_association *asoc,
struct sctp_chunk *chunk,
sctp_cmd_seq_t *commands,
@@ -1949,7 +1989,8 @@ nomem:
*
* The return value is the disposition of the chunk.
*/
-sctp_disposition_t sctp_sf_do_5_2_4_dupcook(const struct sctp_endpoint *ep,
+sctp_disposition_t sctp_sf_do_5_2_4_dupcook(struct net *net,
+ const struct sctp_endpoint *ep,
const struct sctp_association *asoc,
const sctp_subtype_t type,
void *arg,
@@ -1968,7 +2009,7 @@ sctp_disposition_t sctp_sf_do_5_2_4_dupcook(const struct sctp_endpoint *ep,
* done later.
*/
if (!sctp_chunk_length_valid(chunk, sizeof(sctp_chunkhdr_t)))
- return sctp_sf_violation_chunklen(ep, asoc, type, arg,
+ return sctp_sf_violation_chunklen(net, ep, asoc, type, arg,
commands);
/* "Decode" the chunk. We have no optional parameters so we
@@ -2002,12 +2043,14 @@ sctp_disposition_t sctp_sf_do_5_2_4_dupcook(const struct sctp_endpoint *ep,
goto nomem;
case -SCTP_IERROR_STALE_COOKIE:
- sctp_send_stale_cookie_err(ep, asoc, chunk, commands,
- err_chk_p);
- return sctp_sf_pdiscard(ep, asoc, type, arg, commands);
+ sctp_send_stale_cookie_err(net, ep, asoc, chunk,
+ commands, err_chk_p);
+ return sctp_sf_pdiscard(net, ep, asoc, type, arg,
+ commands);
case -SCTP_IERROR_BAD_SIG:
default:
- return sctp_sf_pdiscard(ep, asoc, type, arg, commands);
+ return sctp_sf_pdiscard(net, ep, asoc, type, arg,
+ commands);
}
}
@@ -2018,27 +2061,27 @@ sctp_disposition_t sctp_sf_do_5_2_4_dupcook(const struct sctp_endpoint *ep,
switch (action) {
case 'A': /* Association restart. */
- retval = sctp_sf_do_dupcook_a(ep, asoc, chunk, commands,
+ retval = sctp_sf_do_dupcook_a(net, ep, asoc, chunk, commands,
new_asoc);
break;
case 'B': /* Collision case B. */
- retval = sctp_sf_do_dupcook_b(ep, asoc, chunk, commands,
+ retval = sctp_sf_do_dupcook_b(net, ep, asoc, chunk, commands,
new_asoc);
break;
case 'C': /* Collision case C. */
- retval = sctp_sf_do_dupcook_c(ep, asoc, chunk, commands,
+ retval = sctp_sf_do_dupcook_c(net, ep, asoc, chunk, commands,
new_asoc);
break;
case 'D': /* Collision case D. */
- retval = sctp_sf_do_dupcook_d(ep, asoc, chunk, commands,
+ retval = sctp_sf_do_dupcook_d(net, ep, asoc, chunk, commands,
new_asoc);
break;
default: /* Discard packet for all others. */
- retval = sctp_sf_pdiscard(ep, asoc, type, arg, commands);
+ retval = sctp_sf_pdiscard(net, ep, asoc, type, arg, commands);
break;
}
@@ -2064,6 +2107,7 @@ nomem:
* See sctp_sf_do_9_1_abort().
*/
sctp_disposition_t sctp_sf_shutdown_pending_abort(
+ struct net *net,
const struct sctp_endpoint *ep,
const struct sctp_association *asoc,
const sctp_subtype_t type,
@@ -2073,7 +2117,7 @@ sctp_disposition_t sctp_sf_shutdown_pending_abort(
struct sctp_chunk *chunk = arg;
if (!sctp_vtag_verify_either(chunk, asoc))
- return sctp_sf_pdiscard(ep, asoc, type, arg, commands);
+ return sctp_sf_pdiscard(net, ep, asoc, type, arg, commands);
/* Make sure that the ABORT chunk has a valid length.
* Since this is an ABORT chunk, we have to discard it
@@ -2086,7 +2130,7 @@ sctp_disposition_t sctp_sf_shutdown_pending_abort(
* packet.
*/
if (!sctp_chunk_length_valid(chunk, sizeof(sctp_abort_chunk_t)))
- return sctp_sf_pdiscard(ep, asoc, type, arg, commands);
+ return sctp_sf_pdiscard(net, ep, asoc, type, arg, commands);
/* ADD-IP: Special case for ABORT chunks
* F4) One special consideration is that ABORT Chunks arriving
@@ -2095,9 +2139,10 @@ sctp_disposition_t sctp_sf_shutdown_pending_abort(
*/
if (SCTP_ADDR_DEL ==
sctp_bind_addr_state(&asoc->base.bind_addr, &chunk->dest))
- return sctp_sf_discard_chunk(ep, asoc, type, arg, commands);
+ return sctp_sf_discard_chunk(net, ep, asoc, type, arg,
+ commands);
- return __sctp_sf_do_9_1_abort(ep, asoc, type, arg, commands);
+ return __sctp_sf_do_9_1_abort(net, ep, asoc, type, arg, commands);
}
/*
@@ -2105,7 +2150,8 @@ sctp_disposition_t sctp_sf_shutdown_pending_abort(
*
* See sctp_sf_do_9_1_abort().
*/
-sctp_disposition_t sctp_sf_shutdown_sent_abort(const struct sctp_endpoint *ep,
+sctp_disposition_t sctp_sf_shutdown_sent_abort(struct net *net,
+ const struct sctp_endpoint *ep,
const struct sctp_association *asoc,
const sctp_subtype_t type,
void *arg,
@@ -2114,7 +2160,7 @@ sctp_disposition_t sctp_sf_shutdown_sent_abort(const struct sctp_endpoint *ep,
struct sctp_chunk *chunk = arg;
if (!sctp_vtag_verify_either(chunk, asoc))
- return sctp_sf_pdiscard(ep, asoc, type, arg, commands);
+ return sctp_sf_pdiscard(net, ep, asoc, type, arg, commands);
/* Make sure that the ABORT chunk has a valid length.
* Since this is an ABORT chunk, we have to discard it
@@ -2127,7 +2173,7 @@ sctp_disposition_t sctp_sf_shutdown_sent_abort(const struct sctp_endpoint *ep,
* packet.
*/
if (!sctp_chunk_length_valid(chunk, sizeof(sctp_abort_chunk_t)))
- return sctp_sf_pdiscard(ep, asoc, type, arg, commands);
+ return sctp_sf_pdiscard(net, ep, asoc, type, arg, commands);
/* ADD-IP: Special case for ABORT chunks
* F4) One special consideration is that ABORT Chunks arriving
@@ -2136,7 +2182,8 @@ sctp_disposition_t sctp_sf_shutdown_sent_abort(const struct sctp_endpoint *ep,
*/
if (SCTP_ADDR_DEL ==
sctp_bind_addr_state(&asoc->base.bind_addr, &chunk->dest))
- return sctp_sf_discard_chunk(ep, asoc, type, arg, commands);
+ return sctp_sf_discard_chunk(net, ep, asoc, type, arg,
+ commands);
/* Stop the T2-shutdown timer. */
sctp_add_cmd_sf(commands, SCTP_CMD_TIMER_STOP,
@@ -2146,7 +2193,7 @@ sctp_disposition_t sctp_sf_shutdown_sent_abort(const struct sctp_endpoint *ep,
sctp_add_cmd_sf(commands, SCTP_CMD_TIMER_STOP,
SCTP_TO(SCTP_EVENT_TIMEOUT_T5_SHUTDOWN_GUARD));
- return __sctp_sf_do_9_1_abort(ep, asoc, type, arg, commands);
+ return __sctp_sf_do_9_1_abort(net, ep, asoc, type, arg, commands);
}
/*
@@ -2155,6 +2202,7 @@ sctp_disposition_t sctp_sf_shutdown_sent_abort(const struct sctp_endpoint *ep,
* See sctp_sf_do_9_1_abort().
*/
sctp_disposition_t sctp_sf_shutdown_ack_sent_abort(
+ struct net *net,
const struct sctp_endpoint *ep,
const struct sctp_association *asoc,
const sctp_subtype_t type,
@@ -2164,7 +2212,7 @@ sctp_disposition_t sctp_sf_shutdown_ack_sent_abort(
/* The same T2 timer, so we should be able to use
* common function with the SHUTDOWN-SENT state.
*/
- return sctp_sf_shutdown_sent_abort(ep, asoc, type, arg, commands);
+ return sctp_sf_shutdown_sent_abort(net, ep, asoc, type, arg, commands);
}
/*
@@ -2181,7 +2229,8 @@ sctp_disposition_t sctp_sf_shutdown_ack_sent_abort(
*
* The return value is the disposition of the chunk.
*/
-sctp_disposition_t sctp_sf_cookie_echoed_err(const struct sctp_endpoint *ep,
+sctp_disposition_t sctp_sf_cookie_echoed_err(struct net *net,
+ const struct sctp_endpoint *ep,
const struct sctp_association *asoc,
const sctp_subtype_t type,
void *arg,
@@ -2191,13 +2240,13 @@ sctp_disposition_t sctp_sf_cookie_echoed_err(const struct sctp_endpoint *ep,
sctp_errhdr_t *err;
if (!sctp_vtag_verify(chunk, asoc))
- return sctp_sf_pdiscard(ep, asoc, type, arg, commands);
+ return sctp_sf_pdiscard(net, ep, asoc, type, arg, commands);
/* Make sure that the ERROR chunk has a valid length.
* The parameter walking depends on this as well.
*/
if (!sctp_chunk_length_valid(chunk, sizeof(sctp_operr_chunk_t)))
- return sctp_sf_violation_chunklen(ep, asoc, type, arg,
+ return sctp_sf_violation_chunklen(net, ep, asoc, type, arg,
commands);
/* Process the error here */
@@ -2207,7 +2256,7 @@ sctp_disposition_t sctp_sf_cookie_echoed_err(const struct sctp_endpoint *ep,
*/
sctp_walk_errors(err, chunk->chunk_hdr) {
if (SCTP_ERROR_STALE_COOKIE == err->cause)
- return sctp_sf_do_5_2_6_stale(ep, asoc, type,
+ return sctp_sf_do_5_2_6_stale(net, ep, asoc, type,
arg, commands);
}
@@ -2216,7 +2265,7 @@ sctp_disposition_t sctp_sf_cookie_echoed_err(const struct sctp_endpoint *ep,
* we are discarding the packet, there should be no adverse
* affects.
*/
- return sctp_sf_pdiscard(ep, asoc, type, arg, commands);
+ return sctp_sf_pdiscard(net, ep, asoc, type, arg, commands);
}
/*
@@ -2244,7 +2293,8 @@ sctp_disposition_t sctp_sf_cookie_echoed_err(const struct sctp_endpoint *ep,
*
* The return value is the disposition of the chunk.
*/
-static sctp_disposition_t sctp_sf_do_5_2_6_stale(const struct sctp_endpoint *ep,
+static sctp_disposition_t sctp_sf_do_5_2_6_stale(struct net *net,
+ const struct sctp_endpoint *ep,
const struct sctp_association *asoc,
const sctp_subtype_t type,
void *arg,
@@ -2366,7 +2416,8 @@ nomem:
*
* The return value is the disposition of the chunk.
*/
-sctp_disposition_t sctp_sf_do_9_1_abort(const struct sctp_endpoint *ep,
+sctp_disposition_t sctp_sf_do_9_1_abort(struct net *net,
+ const struct sctp_endpoint *ep,
const struct sctp_association *asoc,
const sctp_subtype_t type,
void *arg,
@@ -2375,7 +2426,7 @@ sctp_disposition_t sctp_sf_do_9_1_abort(const struct sctp_endpoint *ep,
struct sctp_chunk *chunk = arg;
if (!sctp_vtag_verify_either(chunk, asoc))
- return sctp_sf_pdiscard(ep, asoc, type, arg, commands);
+ return sctp_sf_pdiscard(net, ep, asoc, type, arg, commands);
/* Make sure that the ABORT chunk has a valid length.
* Since this is an ABORT chunk, we have to discard it
@@ -2388,7 +2439,7 @@ sctp_disposition_t sctp_sf_do_9_1_abort(const struct sctp_endpoint *ep,
* packet.
*/
if (!sctp_chunk_length_valid(chunk, sizeof(sctp_abort_chunk_t)))
- return sctp_sf_pdiscard(ep, asoc, type, arg, commands);
+ return sctp_sf_pdiscard(net, ep, asoc, type, arg, commands);
/* ADD-IP: Special case for ABORT chunks
* F4) One special consideration is that ABORT Chunks arriving
@@ -2397,12 +2448,14 @@ sctp_disposition_t sctp_sf_do_9_1_abort(const struct sctp_endpoint *ep,
*/
if (SCTP_ADDR_DEL ==
sctp_bind_addr_state(&asoc->base.bind_addr, &chunk->dest))
- return sctp_sf_discard_chunk(ep, asoc, type, arg, commands);
+ return sctp_sf_discard_chunk(net, ep, asoc, type, arg,
+ commands);
- return __sctp_sf_do_9_1_abort(ep, asoc, type, arg, commands);
+ return __sctp_sf_do_9_1_abort(net, ep, asoc, type, arg, commands);
}
-static sctp_disposition_t __sctp_sf_do_9_1_abort(const struct sctp_endpoint *ep,
+static sctp_disposition_t __sctp_sf_do_9_1_abort(struct net *net,
+ const struct sctp_endpoint *ep,
const struct sctp_association *asoc,
const sctp_subtype_t type,
void *arg,
@@ -2419,7 +2472,8 @@ static sctp_disposition_t __sctp_sf_do_9_1_abort(const struct sctp_endpoint *ep,
sctp_errhdr_t *err;
sctp_walk_errors(err, chunk->chunk_hdr);
if ((void *)err != (void *)chunk->chunk_end)
- return sctp_sf_pdiscard(ep, asoc, type, arg, commands);
+ return sctp_sf_pdiscard(net, ep, asoc, type, arg,
+ commands);
error = ((sctp_errhdr_t *)chunk->skb->data)->cause;
}
@@ -2438,7 +2492,8 @@ static sctp_disposition_t __sctp_sf_do_9_1_abort(const struct sctp_endpoint *ep,
*
* See sctp_sf_do_9_1_abort() above.
*/
-sctp_disposition_t sctp_sf_cookie_wait_abort(const struct sctp_endpoint *ep,
+sctp_disposition_t sctp_sf_cookie_wait_abort(struct net *net,
+ const struct sctp_endpoint *ep,
const struct sctp_association *asoc,
const sctp_subtype_t type,
void *arg,
@@ -2449,7 +2504,7 @@ sctp_disposition_t sctp_sf_cookie_wait_abort(const struct sctp_endpoint *ep,
__be16 error = SCTP_ERROR_NO_ERROR;
if (!sctp_vtag_verify_either(chunk, asoc))
- return sctp_sf_pdiscard(ep, asoc, type, arg, commands);
+ return sctp_sf_pdiscard(net, ep, asoc, type, arg, commands);
/* Make sure that the ABORT chunk has a valid length.
* Since this is an ABORT chunk, we have to discard it
@@ -2462,27 +2517,28 @@ sctp_disposition_t sctp_sf_cookie_wait_abort(const struct sctp_endpoint *ep,
* packet.
*/
if (!sctp_chunk_length_valid(chunk, sizeof(sctp_abort_chunk_t)))
- return sctp_sf_pdiscard(ep, asoc, type, arg, commands);
+ return sctp_sf_pdiscard(net, ep, asoc, type, arg, commands);
/* See if we have an error cause code in the chunk. */
len = ntohs(chunk->chunk_hdr->length);
if (len >= sizeof(struct sctp_chunkhdr) + sizeof(struct sctp_errhdr))
error = ((sctp_errhdr_t *)chunk->skb->data)->cause;
- return sctp_stop_t1_and_abort(commands, error, ECONNREFUSED, asoc,
+ return sctp_stop_t1_and_abort(net, commands, error, ECONNREFUSED, asoc,
chunk->transport);
}
/*
* Process an incoming ICMP as an ABORT. (COOKIE-WAIT state)
*/
-sctp_disposition_t sctp_sf_cookie_wait_icmp_abort(const struct sctp_endpoint *ep,
+sctp_disposition_t sctp_sf_cookie_wait_icmp_abort(struct net *net,
+ const struct sctp_endpoint *ep,
const struct sctp_association *asoc,
const sctp_subtype_t type,
void *arg,
sctp_cmd_seq_t *commands)
{
- return sctp_stop_t1_and_abort(commands, SCTP_ERROR_NO_ERROR,
+ return sctp_stop_t1_and_abort(net, commands, SCTP_ERROR_NO_ERROR,
ENOPROTOOPT, asoc,
(struct sctp_transport *)arg);
}
@@ -2490,7 +2546,8 @@ sctp_disposition_t sctp_sf_cookie_wait_icmp_abort(const struct sctp_endpoint *ep
/*
* Process an ABORT. (COOKIE-ECHOED state)
*/
-sctp_disposition_t sctp_sf_cookie_echoed_abort(const struct sctp_endpoint *ep,
+sctp_disposition_t sctp_sf_cookie_echoed_abort(struct net *net,
+ const struct sctp_endpoint *ep,
const struct sctp_association *asoc,
const sctp_subtype_t type,
void *arg,
@@ -2499,7 +2556,7 @@ sctp_disposition_t sctp_sf_cookie_echoed_abort(const struct sctp_endpoint *ep,
/* There is a single T1 timer, so we should be able to use
* common function with the COOKIE-WAIT state.
*/
- return sctp_sf_cookie_wait_abort(ep, asoc, type, arg, commands);
+ return sctp_sf_cookie_wait_abort(net, ep, asoc, type, arg, commands);
}
/*
@@ -2507,7 +2564,8 @@ sctp_disposition_t sctp_sf_cookie_echoed_abort(const struct sctp_endpoint *ep,
*
* This is common code called by several sctp_sf_*_abort() functions above.
*/
-static sctp_disposition_t sctp_stop_t1_and_abort(sctp_cmd_seq_t *commands,
+static sctp_disposition_t sctp_stop_t1_and_abort(struct net *net,
+ sctp_cmd_seq_t *commands,
__be16 error, int sk_err,
const struct sctp_association *asoc,
struct sctp_transport *transport)
@@ -2558,7 +2616,8 @@ static sctp_disposition_t sctp_stop_t1_and_abort(sctp_cmd_seq_t *commands,
*
* The return value is the disposition of the chunk.
*/
-sctp_disposition_t sctp_sf_do_9_2_shutdown(const struct sctp_endpoint *ep,
+sctp_disposition_t sctp_sf_do_9_2_shutdown(struct net *net,
+ const struct sctp_endpoint *ep,
const struct sctp_association *asoc,
const sctp_subtype_t type,
void *arg,
@@ -2571,12 +2630,12 @@ sctp_disposition_t sctp_sf_do_9_2_shutdown(const struct sctp_endpoint *ep,
__u32 ctsn;
if (!sctp_vtag_verify(chunk, asoc))
- return sctp_sf_pdiscard(ep, asoc, type, arg, commands);
+ return sctp_sf_pdiscard(net, ep, asoc, type, arg, commands);
/* Make sure that the SHUTDOWN chunk has a valid length. */
if (!sctp_chunk_length_valid(chunk,
sizeof(struct sctp_shutdown_chunk_t)))
- return sctp_sf_violation_chunklen(ep, asoc, type, arg,
+ return sctp_sf_violation_chunklen(net, ep, asoc, type, arg,
commands);
/* Convert the elaborate header. */
@@ -2596,7 +2655,8 @@ sctp_disposition_t sctp_sf_do_9_2_shutdown(const struct sctp_endpoint *ep,
* sender with an ABORT.
*/
if (!TSN_lt(ctsn, asoc->next_tsn))
- return sctp_sf_violation_ctsn(ep, asoc, type, arg, commands);
+ return sctp_sf_violation_ctsn(net, ep, asoc, type, arg,
+ commands);
/* API 5.3.1.5 SCTP_SHUTDOWN_EVENT
* When a peer sends a SHUTDOWN, SCTP delivers this notification to
@@ -2620,7 +2680,7 @@ sctp_disposition_t sctp_sf_do_9_2_shutdown(const struct sctp_endpoint *ep,
disposition = SCTP_DISPOSITION_CONSUME;
if (sctp_outq_is_empty(&asoc->outqueue)) {
- disposition = sctp_sf_do_9_2_shutdown_ack(ep, asoc, type,
+ disposition = sctp_sf_do_9_2_shutdown_ack(net, ep, asoc, type,
arg, commands);
}
@@ -2646,7 +2706,8 @@ out:
* The Cumulative TSN Ack of the received SHUTDOWN chunk
* MUST be processed.
*/
-sctp_disposition_t sctp_sf_do_9_2_shut_ctsn(const struct sctp_endpoint *ep,
+sctp_disposition_t sctp_sf_do_9_2_shut_ctsn(struct net *net,
+ const struct sctp_endpoint *ep,
const struct sctp_association *asoc,
const sctp_subtype_t type,
void *arg,
@@ -2657,12 +2718,12 @@ sctp_disposition_t sctp_sf_do_9_2_shut_ctsn(const struct sctp_endpoint *ep,
__u32 ctsn;
if (!sctp_vtag_verify(chunk, asoc))
- return sctp_sf_pdiscard(ep, asoc, type, arg, commands);
+ return sctp_sf_pdiscard(net, ep, asoc, type, arg, commands);
/* Make sure that the SHUTDOWN chunk has a valid length. */
if (!sctp_chunk_length_valid(chunk,
sizeof(struct sctp_shutdown_chunk_t)))
- return sctp_sf_violation_chunklen(ep, asoc, type, arg,
+ return sctp_sf_violation_chunklen(net, ep, asoc, type, arg,
commands);
sdh = (sctp_shutdownhdr_t *)chunk->skb->data;
@@ -2679,7 +2740,8 @@ sctp_disposition_t sctp_sf_do_9_2_shut_ctsn(const struct sctp_endpoint *ep,
* sender with an ABORT.
*/
if (!TSN_lt(ctsn, asoc->next_tsn))
- return sctp_sf_violation_ctsn(ep, asoc, type, arg, commands);
+ return sctp_sf_violation_ctsn(net, ep, asoc, type, arg,
+ commands);
/* verify, by checking the Cumulative TSN Ack field of the
* chunk, that all its outstanding DATA chunks have been
@@ -2698,7 +2760,8 @@ sctp_disposition_t sctp_sf_do_9_2_shut_ctsn(const struct sctp_endpoint *ep,
* that belong to this association, it should discard the INIT chunk and
* retransmit the SHUTDOWN ACK chunk.
*/
-sctp_disposition_t sctp_sf_do_9_2_reshutack(const struct sctp_endpoint *ep,
+sctp_disposition_t sctp_sf_do_9_2_reshutack(struct net *net,
+ const struct sctp_endpoint *ep,
const struct sctp_association *asoc,
const sctp_subtype_t type,
void *arg,
@@ -2709,7 +2772,7 @@ sctp_disposition_t sctp_sf_do_9_2_reshutack(const struct sctp_endpoint *ep,
/* Make sure that the chunk has a valid length */
if (!sctp_chunk_length_valid(chunk, sizeof(sctp_chunkhdr_t)))
- return sctp_sf_violation_chunklen(ep, asoc, type, arg,
+ return sctp_sf_violation_chunklen(net, ep, asoc, type, arg,
commands);
/* Since we are not going to really process this INIT, there
@@ -2761,7 +2824,8 @@ nomem:
*
* The return value is the disposition of the chunk.
*/
-sctp_disposition_t sctp_sf_do_ecn_cwr(const struct sctp_endpoint *ep,
+sctp_disposition_t sctp_sf_do_ecn_cwr(struct net *net,
+ const struct sctp_endpoint *ep,
const struct sctp_association *asoc,
const sctp_subtype_t type,
void *arg,
@@ -2772,10 +2836,10 @@ sctp_disposition_t sctp_sf_do_ecn_cwr(const struct sctp_endpoint *ep,
u32 lowest_tsn;
if (!sctp_vtag_verify(chunk, asoc))
- return sctp_sf_pdiscard(ep, asoc, type, arg, commands);
+ return sctp_sf_pdiscard(net, ep, asoc, type, arg, commands);
if (!sctp_chunk_length_valid(chunk, sizeof(sctp_ecne_chunk_t)))
- return sctp_sf_violation_chunklen(ep, asoc, type, arg,
+ return sctp_sf_violation_chunklen(net, ep, asoc, type, arg,
commands);
cwr = (sctp_cwrhdr_t *) chunk->skb->data;
@@ -2816,7 +2880,8 @@ sctp_disposition_t sctp_sf_do_ecn_cwr(const struct sctp_endpoint *ep,
*
* The return value is the disposition of the chunk.
*/
-sctp_disposition_t sctp_sf_do_ecne(const struct sctp_endpoint *ep,
+sctp_disposition_t sctp_sf_do_ecne(struct net *net,
+ const struct sctp_endpoint *ep,
const struct sctp_association *asoc,
const sctp_subtype_t type,
void *arg,
@@ -2826,10 +2891,10 @@ sctp_disposition_t sctp_sf_do_ecne(const struct sctp_endpoint *ep,
struct sctp_chunk *chunk = arg;
if (!sctp_vtag_verify(chunk, asoc))
- return sctp_sf_pdiscard(ep, asoc, type, arg, commands);
+ return sctp_sf_pdiscard(net, ep, asoc, type, arg, commands);
if (!sctp_chunk_length_valid(chunk, sizeof(sctp_ecne_chunk_t)))
- return sctp_sf_violation_chunklen(ep, asoc, type, arg,
+ return sctp_sf_violation_chunklen(net, ep, asoc, type, arg,
commands);
ecne = (sctp_ecnehdr_t *) chunk->skb->data;
@@ -2872,7 +2937,8 @@ sctp_disposition_t sctp_sf_do_ecne(const struct sctp_endpoint *ep,
*
* The return value is the disposition of the chunk.
*/
-sctp_disposition_t sctp_sf_eat_data_6_2(const struct sctp_endpoint *ep,
+sctp_disposition_t sctp_sf_eat_data_6_2(struct net *net,
+ const struct sctp_endpoint *ep,
const struct sctp_association *asoc,
const sctp_subtype_t type,
void *arg,
@@ -2885,14 +2951,14 @@ sctp_disposition_t sctp_sf_eat_data_6_2(const struct sctp_endpoint *ep,
if (!sctp_vtag_verify(chunk, asoc)) {
sctp_add_cmd_sf(commands, SCTP_CMD_REPORT_BAD_TAG,
SCTP_NULL());
- return sctp_sf_pdiscard(ep, asoc, type, arg, commands);
+ return sctp_sf_pdiscard(net, ep, asoc, type, arg, commands);
}
if (!sctp_chunk_length_valid(chunk, sizeof(sctp_data_chunk_t)))
- return sctp_sf_violation_chunklen(ep, asoc, type, arg,
+ return sctp_sf_violation_chunklen(net, ep, asoc, type, arg,
commands);
- error = sctp_eat_data(asoc, chunk, commands );
+ error = sctp_eat_data(net, asoc, chunk, commands);
switch (error) {
case SCTP_IERROR_NO_ERROR:
break;
@@ -2907,7 +2973,7 @@ sctp_disposition_t sctp_sf_eat_data_6_2(const struct sctp_endpoint *ep,
case SCTP_IERROR_NO_DATA:
goto consume;
case SCTP_IERROR_PROTO_VIOLATION:
- return sctp_sf_abort_violation(ep, asoc, chunk, commands,
+ return sctp_sf_abort_violation(net, ep, asoc, chunk, commands,
(u8 *)chunk->subh.data_hdr, sizeof(sctp_datahdr_t));
default:
BUG();
@@ -2993,7 +3059,8 @@ consume:
*
* The return value is the disposition of the chunk.
*/
-sctp_disposition_t sctp_sf_eat_data_fast_4_4(const struct sctp_endpoint *ep,
+sctp_disposition_t sctp_sf_eat_data_fast_4_4(struct net *net,
+ const struct sctp_endpoint *ep,
const struct sctp_association *asoc,
const sctp_subtype_t type,
void *arg,
@@ -3005,14 +3072,14 @@ sctp_disposition_t sctp_sf_eat_data_fast_4_4(const struct sctp_endpoint *ep,
if (!sctp_vtag_verify(chunk, asoc)) {
sctp_add_cmd_sf(commands, SCTP_CMD_REPORT_BAD_TAG,
SCTP_NULL());
- return sctp_sf_pdiscard(ep, asoc, type, arg, commands);
+ return sctp_sf_pdiscard(net, ep, asoc, type, arg, commands);
}
if (!sctp_chunk_length_valid(chunk, sizeof(sctp_data_chunk_t)))
- return sctp_sf_violation_chunklen(ep, asoc, type, arg,
+ return sctp_sf_violation_chunklen(net, ep, asoc, type, arg,
commands);
- error = sctp_eat_data(asoc, chunk, commands );
+ error = sctp_eat_data(net, asoc, chunk, commands);
switch (error) {
case SCTP_IERROR_NO_ERROR:
case SCTP_IERROR_HIGH_TSN:
@@ -3023,7 +3090,7 @@ sctp_disposition_t sctp_sf_eat_data_fast_4_4(const struct sctp_endpoint *ep,
case SCTP_IERROR_NO_DATA:
goto consume;
case SCTP_IERROR_PROTO_VIOLATION:
- return sctp_sf_abort_violation(ep, asoc, chunk, commands,
+ return sctp_sf_abort_violation(net, ep, asoc, chunk, commands,
(u8 *)chunk->subh.data_hdr, sizeof(sctp_datahdr_t));
default:
BUG();
@@ -3083,7 +3150,8 @@ consume:
*
* The return value is the disposition of the chunk.
*/
-sctp_disposition_t sctp_sf_eat_sack_6_2(const struct sctp_endpoint *ep,
+sctp_disposition_t sctp_sf_eat_sack_6_2(struct net *net,
+ const struct sctp_endpoint *ep,
const struct sctp_association *asoc,
const sctp_subtype_t type,
void *arg,
@@ -3094,18 +3162,18 @@ sctp_disposition_t sctp_sf_eat_sack_6_2(const struct sctp_endpoint *ep,
__u32 ctsn;
if (!sctp_vtag_verify(chunk, asoc))
- return sctp_sf_pdiscard(ep, asoc, type, arg, commands);
+ return sctp_sf_pdiscard(net, ep, asoc, type, arg, commands);
/* Make sure that the SACK chunk has a valid length. */
if (!sctp_chunk_length_valid(chunk, sizeof(sctp_sack_chunk_t)))
- return sctp_sf_violation_chunklen(ep, asoc, type, arg,
+ return sctp_sf_violation_chunklen(net, ep, asoc, type, arg,
commands);
/* Pull the SACK chunk from the data buffer */
sackh = sctp_sm_pull_sack(chunk);
/* Was this a bogus SACK? */
if (!sackh)
- return sctp_sf_pdiscard(ep, asoc, type, arg, commands);
+ return sctp_sf_pdiscard(net, ep, asoc, type, arg, commands);
chunk->subh.sack_hdr = sackh;
ctsn = ntohl(sackh->cum_tsn_ack);
@@ -3126,7 +3194,8 @@ sctp_disposition_t sctp_sf_eat_sack_6_2(const struct sctp_endpoint *ep,
* sender with an ABORT.
*/
if (!TSN_lt(ctsn, asoc->next_tsn))
- return sctp_sf_violation_ctsn(ep, asoc, type, arg, commands);
+ return sctp_sf_violation_ctsn(net, ep, asoc, type, arg,
+ commands);
/* Return this SACK for further processing. */
sctp_add_cmd_sf(commands, SCTP_CMD_PROCESS_SACK, SCTP_SACKH(sackh));
@@ -3155,7 +3224,8 @@ sctp_disposition_t sctp_sf_eat_sack_6_2(const struct sctp_endpoint *ep,
*
* The return value is the disposition of the chunk.
*/
-static sctp_disposition_t sctp_sf_tabort_8_4_8(const struct sctp_endpoint *ep,
+static sctp_disposition_t sctp_sf_tabort_8_4_8(struct net *net,
+ const struct sctp_endpoint *ep,
const struct sctp_association *asoc,
const sctp_subtype_t type,
void *arg,
@@ -3165,7 +3235,7 @@ static sctp_disposition_t sctp_sf_tabort_8_4_8(const struct sctp_endpoint *ep,
struct sctp_chunk *chunk = arg;
struct sctp_chunk *abort;
- packet = sctp_ootb_pkt_new(asoc, chunk);
+ packet = sctp_ootb_pkt_new(net, asoc, chunk);
if (packet) {
/* Make an ABORT. The T bit will be set if the asoc
@@ -3191,7 +3261,7 @@ static sctp_disposition_t sctp_sf_tabort_8_4_8(const struct sctp_endpoint *ep,
SCTP_INC_STATS(SCTP_MIB_OUTCTRLCHUNKS);
- sctp_sf_pdiscard(ep, asoc, type, arg, commands);
+ sctp_sf_pdiscard(net, ep, asoc, type, arg, commands);
return SCTP_DISPOSITION_CONSUME;
}
@@ -3206,7 +3276,8 @@ static sctp_disposition_t sctp_sf_tabort_8_4_8(const struct sctp_endpoint *ep,
*
* The return value is the disposition of the chunk.
*/
-sctp_disposition_t sctp_sf_operr_notify(const struct sctp_endpoint *ep,
+sctp_disposition_t sctp_sf_operr_notify(struct net *net,
+ const struct sctp_endpoint *ep,
const struct sctp_association *asoc,
const sctp_subtype_t type,
void *arg,
@@ -3216,15 +3287,15 @@ sctp_disposition_t sctp_sf_operr_notify(const struct sctp_endpoint *ep,
sctp_errhdr_t *err;
if (!sctp_vtag_verify(chunk, asoc))
- return sctp_sf_pdiscard(ep, asoc, type, arg, commands);
+ return sctp_sf_pdiscard(net, ep, asoc, type, arg, commands);
/* Make sure that the ERROR chunk has a valid length. */
if (!sctp_chunk_length_valid(chunk, sizeof(sctp_operr_chunk_t)))
- return sctp_sf_violation_chunklen(ep, asoc, type, arg,
+ return sctp_sf_violation_chunklen(net, ep, asoc, type, arg,
commands);
sctp_walk_errors(err, chunk->chunk_hdr);
if ((void *)err != (void *)chunk->chunk_end)
- return sctp_sf_violation_paramlen(ep, asoc, type, arg,
+ return sctp_sf_violation_paramlen(net, ep, asoc, type, arg,
(void *)err, commands);
sctp_add_cmd_sf(commands, SCTP_CMD_PROCESS_OPERR,
@@ -3243,7 +3314,8 @@ sctp_disposition_t sctp_sf_operr_notify(const struct sctp_endpoint *ep,
*
* The return value is the disposition.
*/
-sctp_disposition_t sctp_sf_do_9_2_final(const struct sctp_endpoint *ep,
+sctp_disposition_t sctp_sf_do_9_2_final(struct net *net,
+ const struct sctp_endpoint *ep,
const struct sctp_association *asoc,
const sctp_subtype_t type,
void *arg,
@@ -3254,11 +3326,11 @@ sctp_disposition_t sctp_sf_do_9_2_final(const struct sctp_endpoint *ep,
struct sctp_ulpevent *ev;
if (!sctp_vtag_verify(chunk, asoc))
- return sctp_sf_pdiscard(ep, asoc, type, arg, commands);
+ return sctp_sf_pdiscard(net, ep, asoc, type, arg, commands);
/* Make sure that the SHUTDOWN_ACK chunk has a valid length. */
if (!sctp_chunk_length_valid(chunk, sizeof(sctp_chunkhdr_t)))
- return sctp_sf_violation_chunklen(ep, asoc, type, arg,
+ return sctp_sf_violation_chunklen(net, ep, asoc, type, arg,
commands);
/* 10.2 H) SHUTDOWN COMPLETE notification
*
@@ -3325,7 +3397,8 @@ nomem:
* receiver of the OOTB packet shall discard the OOTB packet and take
* no further action.
*/
-sctp_disposition_t sctp_sf_ootb(const struct sctp_endpoint *ep,
+sctp_disposition_t sctp_sf_ootb(struct net *net,
+ const struct sctp_endpoint *ep,
const struct sctp_association *asoc,
const sctp_subtype_t type,
void *arg,
@@ -3345,8 +3418,8 @@ sctp_disposition_t sctp_sf_ootb(const struct sctp_endpoint *ep,
do {
/* Report violation if the chunk is less then minimal */
if (ntohs(ch->length) < sizeof(sctp_chunkhdr_t))
- return sctp_sf_violation_chunklen(ep, asoc, type, arg,
- commands);
+ return sctp_sf_violation_chunklen(net, ep, asoc, type,
+ arg, commands);
/* Now that we know we at least have a chunk header,
* do things that are type appropriate.
@@ -3360,7 +3433,8 @@ sctp_disposition_t sctp_sf_ootb(const struct sctp_endpoint *ep,
* sending an ABORT of its own.
*/
if (SCTP_CID_ABORT == ch->type)
- return sctp_sf_pdiscard(ep, asoc, type, arg, commands);
+ return sctp_sf_pdiscard(net, ep, asoc, type, arg,
+ commands);
/* RFC 8.4, 7) If the packet contains a "Stale cookie" ERROR
* or a COOKIE ACK the SCTP Packet should be silently
@@ -3382,18 +3456,18 @@ sctp_disposition_t sctp_sf_ootb(const struct sctp_endpoint *ep,
/* Report violation if chunk len overflows */
ch_end = ((__u8 *)ch) + WORD_ROUND(ntohs(ch->length));
if (ch_end > skb_tail_pointer(skb))
- return sctp_sf_violation_chunklen(ep, asoc, type, arg,
- commands);
+ return sctp_sf_violation_chunklen(net, ep, asoc, type,
+ arg, commands);
ch = (sctp_chunkhdr_t *) ch_end;
} while (ch_end < skb_tail_pointer(skb));
if (ootb_shut_ack)
- return sctp_sf_shut_8_4_5(ep, asoc, type, arg, commands);
+ return sctp_sf_shut_8_4_5(net, ep, asoc, type, arg, commands);
else if (ootb_cookie_ack)
- return sctp_sf_pdiscard(ep, asoc, type, arg, commands);
+ return sctp_sf_pdiscard(net, ep, asoc, type, arg, commands);
else
- return sctp_sf_tabort_8_4_8(ep, asoc, type, arg, commands);
+ return sctp_sf_tabort_8_4_8(net, ep, asoc, type, arg, commands);
}
/*
@@ -3417,7 +3491,8 @@ sctp_disposition_t sctp_sf_ootb(const struct sctp_endpoint *ep,
*
* The return value is the disposition of the chunk.
*/
-static sctp_disposition_t sctp_sf_shut_8_4_5(const struct sctp_endpoint *ep,
+static sctp_disposition_t sctp_sf_shut_8_4_5(struct net *net,
+ const struct sctp_endpoint *ep,
const struct sctp_association *asoc,
const sctp_subtype_t type,
void *arg,
@@ -3427,7 +3502,7 @@ static sctp_disposition_t sctp_sf_shut_8_4_5(const struct sctp_endpoint *ep,
struct sctp_chunk *chunk = arg;
struct sctp_chunk *shut;
- packet = sctp_ootb_pkt_new(asoc, chunk);
+ packet = sctp_ootb_pkt_new(net, asoc, chunk);
if (packet) {
/* Make an SHUTDOWN_COMPLETE.
@@ -3457,13 +3532,14 @@ static sctp_disposition_t sctp_sf_shut_8_4_5(const struct sctp_endpoint *ep,
* the reset of the packet.
*/
if (!sctp_chunk_length_valid(chunk, sizeof(sctp_chunkhdr_t)))
- return sctp_sf_pdiscard(ep, asoc, type, arg, commands);
+ return sctp_sf_pdiscard(net, ep, asoc, type, arg,
+ commands);
/* We need to discard the rest of the packet to prevent
* potential bomming attacks from additional bundled chunks.
* This is documented in SCTP Threats ID.
*/
- return sctp_sf_pdiscard(ep, asoc, type, arg, commands);
+ return sctp_sf_pdiscard(net, ep, asoc, type, arg, commands);
}
return SCTP_DISPOSITION_NOMEM;
@@ -3480,7 +3556,8 @@ static sctp_disposition_t sctp_sf_shut_8_4_5(const struct sctp_endpoint *ep,
* chunks. --piggy ]
*
*/
-sctp_disposition_t sctp_sf_do_8_5_1_E_sa(const struct sctp_endpoint *ep,
+sctp_disposition_t sctp_sf_do_8_5_1_E_sa(struct net *net,
+ const struct sctp_endpoint *ep,
const struct sctp_association *asoc,
const sctp_subtype_t type,
void *arg,
@@ -3490,7 +3567,7 @@ sctp_disposition_t sctp_sf_do_8_5_1_E_sa(const struct sctp_endpoint *ep,
/* Make sure that the SHUTDOWN_ACK chunk has a valid length. */
if (!sctp_chunk_length_valid(chunk, sizeof(sctp_chunkhdr_t)))
- return sctp_sf_violation_chunklen(ep, asoc, type, arg,
+ return sctp_sf_violation_chunklen(net, ep, asoc, type, arg,
commands);
/* Although we do have an association in this case, it corresponds
@@ -3500,11 +3577,12 @@ sctp_disposition_t sctp_sf_do_8_5_1_E_sa(const struct sctp_endpoint *ep,
*/
SCTP_INC_STATS(SCTP_MIB_OUTOFBLUES);
- return sctp_sf_shut_8_4_5(ep, NULL, type, arg, commands);
+ return sctp_sf_shut_8_4_5(net, ep, NULL, type, arg, commands);
}
/* ADDIP Section 4.2 Upon reception of an ASCONF Chunk. */
-sctp_disposition_t sctp_sf_do_asconf(const struct sctp_endpoint *ep,
+sctp_disposition_t sctp_sf_do_asconf(struct net *net,
+ const struct sctp_endpoint *ep,
const struct sctp_association *asoc,
const sctp_subtype_t type, void *arg,
sctp_cmd_seq_t *commands)
@@ -3520,7 +3598,7 @@ sctp_disposition_t sctp_sf_do_asconf(const struct sctp_endpoint *ep,
if (!sctp_vtag_verify(chunk, asoc)) {
sctp_add_cmd_sf(commands, SCTP_CMD_REPORT_BAD_TAG,
SCTP_NULL());
- return sctp_sf_pdiscard(ep, asoc, type, arg, commands);
+ return sctp_sf_pdiscard(net, ep, asoc, type, arg, commands);
}
/* ADD-IP: Section 4.1.1
@@ -3530,11 +3608,12 @@ sctp_disposition_t sctp_sf_do_asconf(const struct sctp_endpoint *ep,
* described in [I-D.ietf-tsvwg-sctp-auth].
*/
if (!sctp_addip_noauth && !chunk->auth)
- return sctp_sf_discard_chunk(ep, asoc, type, arg, commands);
+ return sctp_sf_discard_chunk(net, ep, asoc, type,
+ arg, commands);
/* Make sure that the ASCONF ADDIP chunk has a valid length. */
if (!sctp_chunk_length_valid(chunk, sizeof(sctp_addip_chunk_t)))
- return sctp_sf_violation_chunklen(ep, asoc, type, arg,
+ return sctp_sf_violation_chunklen(net, ep, asoc, type, arg,
commands);
hdr = (sctp_addiphdr_t *)chunk->skb->data;
@@ -3543,7 +3622,7 @@ sctp_disposition_t sctp_sf_do_asconf(const struct sctp_endpoint *ep,
addr_param = (union sctp_addr_param *)hdr->params;
length = ntohs(addr_param->p.length);
if (length < sizeof(sctp_paramhdr_t))
- return sctp_sf_violation_paramlen(ep, asoc, type, arg,
+ return sctp_sf_violation_paramlen(net, ep, asoc, type, arg,
(void *)addr_param, commands);
/* Verify the ASCONF chunk before processing it. */
@@ -3551,7 +3630,7 @@ sctp_disposition_t sctp_sf_do_asconf(const struct sctp_endpoint *ep,
(sctp_paramhdr_t *)((void *)addr_param + length),
(void *)chunk->chunk_end,
&err_param))
- return sctp_sf_violation_paramlen(ep, asoc, type, arg,
+ return sctp_sf_violation_paramlen(net, ep, asoc, type, arg,
(void *)err_param, commands);
/* ADDIP 5.2 E1) Compare the value of the serial number to the value
@@ -3618,8 +3697,8 @@ sctp_disposition_t sctp_sf_do_asconf(const struct sctp_endpoint *ep,
asconf_ack->dest = chunk->source;
sctp_add_cmd_sf(commands, SCTP_CMD_REPLY, SCTP_CHUNK(asconf_ack));
if (asoc->new_transport) {
- sctp_sf_heartbeat(ep, asoc, type, asoc->new_transport,
- commands);
+ sctp_sf_heartbeat(net, ep, asoc, type, asoc->new_transport,
+ commands);
((struct sctp_association *)asoc)->new_transport = NULL;
}
@@ -3631,7 +3710,8 @@ sctp_disposition_t sctp_sf_do_asconf(const struct sctp_endpoint *ep,
* When building TLV parameters for the ASCONF Chunk that will add or
* delete IP addresses the D0 to D13 rules should be applied:
*/
-sctp_disposition_t sctp_sf_do_asconf_ack(const struct sctp_endpoint *ep,
+sctp_disposition_t sctp_sf_do_asconf_ack(struct net *net,
+ const struct sctp_endpoint *ep,
const struct sctp_association *asoc,
const sctp_subtype_t type, void *arg,
sctp_cmd_seq_t *commands)
@@ -3646,7 +3726,7 @@ sctp_disposition_t sctp_sf_do_asconf_ack(const struct sctp_endpoint *ep,
if (!sctp_vtag_verify(asconf_ack, asoc)) {
sctp_add_cmd_sf(commands, SCTP_CMD_REPORT_BAD_TAG,
SCTP_NULL());
- return sctp_sf_pdiscard(ep, asoc, type, arg, commands);
+ return sctp_sf_pdiscard(net, ep, asoc, type, arg, commands);
}
/* ADD-IP, Section 4.1.2:
@@ -3656,11 +3736,12 @@ sctp_disposition_t sctp_sf_do_asconf_ack(const struct sctp_endpoint *ep,
* described in [I-D.ietf-tsvwg-sctp-auth].
*/
if (!sctp_addip_noauth && !asconf_ack->auth)
- return sctp_sf_discard_chunk(ep, asoc, type, arg, commands);
+ return sctp_sf_discard_chunk(net, ep, asoc, type, arg,
+ commands);
/* Make sure that the ADDIP chunk has a valid length. */
if (!sctp_chunk_length_valid(asconf_ack, sizeof(sctp_addip_chunk_t)))
- return sctp_sf_violation_chunklen(ep, asoc, type, arg,
+ return sctp_sf_violation_chunklen(net, ep, asoc, type, arg,
commands);
addip_hdr = (sctp_addiphdr_t *)asconf_ack->skb->data;
@@ -3671,7 +3752,7 @@ sctp_disposition_t sctp_sf_do_asconf_ack(const struct sctp_endpoint *ep,
(sctp_paramhdr_t *)addip_hdr->params,
(void *)asconf_ack->chunk_end,
&err_param))
- return sctp_sf_violation_paramlen(ep, asoc, type, arg,
+ return sctp_sf_violation_paramlen(net, ep, asoc, type, arg,
(void *)err_param, commands);
if (last_asconf) {
@@ -3762,7 +3843,8 @@ sctp_disposition_t sctp_sf_do_asconf_ack(const struct sctp_endpoint *ep,
*
* The return value is the disposition of the chunk.
*/
-sctp_disposition_t sctp_sf_eat_fwd_tsn(const struct sctp_endpoint *ep,
+sctp_disposition_t sctp_sf_eat_fwd_tsn(struct net *net,
+ const struct sctp_endpoint *ep,
const struct sctp_association *asoc,
const sctp_subtype_t type,
void *arg,
@@ -3777,12 +3859,12 @@ sctp_disposition_t sctp_sf_eat_fwd_tsn(const struct sctp_endpoint *ep,
if (!sctp_vtag_verify(chunk, asoc)) {
sctp_add_cmd_sf(commands, SCTP_CMD_REPORT_BAD_TAG,
SCTP_NULL());
- return sctp_sf_pdiscard(ep, asoc, type, arg, commands);
+ return sctp_sf_pdiscard(net, ep, asoc, type, arg, commands);
}
/* Make sure that the FORWARD_TSN chunk has valid length. */
if (!sctp_chunk_length_valid(chunk, sizeof(struct sctp_fwdtsn_chunk)))
- return sctp_sf_violation_chunklen(ep, asoc, type, arg,
+ return sctp_sf_violation_chunklen(net, ep, asoc, type, arg,
commands);
fwdtsn_hdr = (struct sctp_fwdtsn_hdr *)chunk->skb->data;
@@ -3829,6 +3911,7 @@ discard_noforce:
}
sctp_disposition_t sctp_sf_eat_fwd_tsn_fast(
+ struct net *net,
const struct sctp_endpoint *ep,
const struct sctp_association *asoc,
const sctp_subtype_t type,
@@ -3844,12 +3927,12 @@ sctp_disposition_t sctp_sf_eat_fwd_tsn_fast(
if (!sctp_vtag_verify(chunk, asoc)) {
sctp_add_cmd_sf(commands, SCTP_CMD_REPORT_BAD_TAG,
SCTP_NULL());
- return sctp_sf_pdiscard(ep, asoc, type, arg, commands);
+ return sctp_sf_pdiscard(net, ep, asoc, type, arg, commands);
}
/* Make sure that the FORWARD_TSN chunk has a valid length. */
if (!sctp_chunk_length_valid(chunk, sizeof(struct sctp_fwdtsn_chunk)))
- return sctp_sf_violation_chunklen(ep, asoc, type, arg,
+ return sctp_sf_violation_chunklen(net, ep, asoc, type, arg,
commands);
fwdtsn_hdr = (struct sctp_fwdtsn_hdr *)chunk->skb->data;
@@ -3989,7 +4072,8 @@ nomem:
return SCTP_IERROR_NOMEM;
}
-sctp_disposition_t sctp_sf_eat_auth(const struct sctp_endpoint *ep,
+sctp_disposition_t sctp_sf_eat_auth(struct net *net,
+ const struct sctp_endpoint *ep,
const struct sctp_association *asoc,
const sctp_subtype_t type,
void *arg,
@@ -4002,17 +4086,17 @@ sctp_disposition_t sctp_sf_eat_auth(const struct sctp_endpoint *ep,
/* Make sure that the peer has AUTH capable */
if (!asoc->peer.auth_capable)
- return sctp_sf_unk_chunk(ep, asoc, type, arg, commands);
+ return sctp_sf_unk_chunk(net, ep, asoc, type, arg, commands);
if (!sctp_vtag_verify(chunk, asoc)) {
sctp_add_cmd_sf(commands, SCTP_CMD_REPORT_BAD_TAG,
SCTP_NULL());
- return sctp_sf_pdiscard(ep, asoc, type, arg, commands);
+ return sctp_sf_pdiscard(net, ep, asoc, type, arg, commands);
}
/* Make sure that the AUTH chunk has valid length. */
if (!sctp_chunk_length_valid(chunk, sizeof(struct sctp_auth_chunk)))
- return sctp_sf_violation_chunklen(ep, asoc, type, arg,
+ return sctp_sf_violation_chunklen(net, ep, asoc, type, arg,
commands);
auth_hdr = (struct sctp_authhdr *)chunk->skb->data;
@@ -4033,10 +4117,10 @@ sctp_disposition_t sctp_sf_eat_auth(const struct sctp_endpoint *ep,
/* Fall Through */
case SCTP_IERROR_AUTH_BAD_KEYID:
case SCTP_IERROR_BAD_SIG:
- return sctp_sf_pdiscard(ep, asoc, type, arg, commands);
+ return sctp_sf_pdiscard(net, ep, asoc, type, arg, commands);
case SCTP_IERROR_PROTO_VIOLATION:
- return sctp_sf_violation_chunklen(ep, asoc, type, arg,
+ return sctp_sf_violation_chunklen(net, ep, asoc, type, arg,
commands);
case SCTP_IERROR_NOMEM:
@@ -4085,7 +4169,8 @@ sctp_disposition_t sctp_sf_eat_auth(const struct sctp_endpoint *ep,
*
* The return value is the disposition of the chunk.
*/
-sctp_disposition_t sctp_sf_unk_chunk(const struct sctp_endpoint *ep,
+sctp_disposition_t sctp_sf_unk_chunk(struct net *net,
+ const struct sctp_endpoint *ep,
const struct sctp_association *asoc,
const sctp_subtype_t type,
void *arg,
@@ -4098,20 +4183,20 @@ sctp_disposition_t sctp_sf_unk_chunk(const struct sctp_endpoint *ep,
SCTP_DEBUG_PRINTK("Processing the unknown chunk id %d.\n", type.chunk);
if (!sctp_vtag_verify(unk_chunk, asoc))
- return sctp_sf_pdiscard(ep, asoc, type, arg, commands);
+ return sctp_sf_pdiscard(net, ep, asoc, type, arg, commands);
/* Make sure that the chunk has a valid length.
* Since we don't know the chunk type, we use a general
* chunkhdr structure to make a comparison.
*/
if (!sctp_chunk_length_valid(unk_chunk, sizeof(sctp_chunkhdr_t)))
- return sctp_sf_violation_chunklen(ep, asoc, type, arg,
+ return sctp_sf_violation_chunklen(net, ep, asoc, type, arg,
commands);
switch (type.chunk & SCTP_CID_ACTION_MASK) {
case SCTP_CID_ACTION_DISCARD:
/* Discard the packet. */
- return sctp_sf_pdiscard(ep, asoc, type, arg, commands);
+ return sctp_sf_pdiscard(net, ep, asoc, type, arg, commands);
break;
case SCTP_CID_ACTION_DISCARD_ERR:
/* Generate an ERROR chunk as response. */
@@ -4126,7 +4211,7 @@ sctp_disposition_t sctp_sf_unk_chunk(const struct sctp_endpoint *ep,
}
/* Discard the packet. */
- sctp_sf_pdiscard(ep, asoc, type, arg, commands);
+ sctp_sf_pdiscard(net, ep, asoc, type, arg, commands);
return SCTP_DISPOSITION_CONSUME;
break;
case SCTP_CID_ACTION_SKIP:
@@ -4168,7 +4253,8 @@ sctp_disposition_t sctp_sf_unk_chunk(const struct sctp_endpoint *ep,
*
* The return value is the disposition of the chunk.
*/
-sctp_disposition_t sctp_sf_discard_chunk(const struct sctp_endpoint *ep,
+sctp_disposition_t sctp_sf_discard_chunk(struct net *net,
+ const struct sctp_endpoint *ep,
const struct sctp_association *asoc,
const sctp_subtype_t type,
void *arg,
@@ -4181,7 +4267,7 @@ sctp_disposition_t sctp_sf_discard_chunk(const struct sctp_endpoint *ep,
* chunkhdr structure to make a comparison.
*/
if (!sctp_chunk_length_valid(chunk, sizeof(sctp_chunkhdr_t)))
- return sctp_sf_violation_chunklen(ep, asoc, type, arg,
+ return sctp_sf_violation_chunklen(net, ep, asoc, type, arg,
commands);
SCTP_DEBUG_PRINTK("Chunk %d is discarded\n", type.chunk);
@@ -4206,7 +4292,8 @@ sctp_disposition_t sctp_sf_discard_chunk(const struct sctp_endpoint *ep,
*
* The return value is the disposition of the chunk.
*/
-sctp_disposition_t sctp_sf_pdiscard(const struct sctp_endpoint *ep,
+sctp_disposition_t sctp_sf_pdiscard(struct net *net,
+ const struct sctp_endpoint *ep,
const struct sctp_association *asoc,
const sctp_subtype_t type,
void *arg,
@@ -4233,7 +4320,8 @@ sctp_disposition_t sctp_sf_pdiscard(const struct sctp_endpoint *ep,
* We simply tag the chunk as a violation. The state machine will log
* the violation and continue.
*/
-sctp_disposition_t sctp_sf_violation(const struct sctp_endpoint *ep,
+sctp_disposition_t sctp_sf_violation(struct net *net,
+ const struct sctp_endpoint *ep,
const struct sctp_association *asoc,
const sctp_subtype_t type,
void *arg,
@@ -4243,7 +4331,7 @@ sctp_disposition_t sctp_sf_violation(const struct sctp_endpoint *ep,
/* Make sure that the chunk has a valid length. */
if (!sctp_chunk_length_valid(chunk, sizeof(sctp_chunkhdr_t)))
- return sctp_sf_violation_chunklen(ep, asoc, type, arg,
+ return sctp_sf_violation_chunklen(net, ep, asoc, type, arg,
commands);
return SCTP_DISPOSITION_VIOLATION;
@@ -4253,6 +4341,7 @@ sctp_disposition_t sctp_sf_violation(const struct sctp_endpoint *ep,
* Common function to handle a protocol violation.
*/
static sctp_disposition_t sctp_sf_abort_violation(
+ struct net *net,
const struct sctp_endpoint *ep,
const struct sctp_association *asoc,
void *arg,
@@ -4320,7 +4409,7 @@ static sctp_disposition_t sctp_sf_abort_violation(
SCTP_DEC_STATS(SCTP_MIB_CURRESTAB);
}
} else {
- packet = sctp_ootb_pkt_new(asoc, chunk);
+ packet = sctp_ootb_pkt_new(net, asoc, chunk);
if (!packet)
goto nomem_pkt;
@@ -4341,7 +4430,7 @@ static sctp_disposition_t sctp_sf_abort_violation(
SCTP_INC_STATS(SCTP_MIB_ABORTEDS);
discard:
- sctp_sf_pdiscard(ep, asoc, SCTP_ST_CHUNK(0), arg, commands);
+ sctp_sf_pdiscard(net, ep, asoc, SCTP_ST_CHUNK(0), arg, commands);
return SCTP_DISPOSITION_ABORT;
nomem_pkt:
@@ -4370,6 +4459,7 @@ nomem:
* Generate an ABORT chunk and terminate the association.
*/
static sctp_disposition_t sctp_sf_violation_chunklen(
+ struct net *net,
const struct sctp_endpoint *ep,
const struct sctp_association *asoc,
const sctp_subtype_t type,
@@ -4378,7 +4468,7 @@ static sctp_disposition_t sctp_sf_violation_chunklen(
{
static const char err_str[]="The following chunk had invalid length:";
- return sctp_sf_abort_violation(ep, asoc, arg, commands, err_str,
+ return sctp_sf_abort_violation(net, ep, asoc, arg, commands, err_str,
sizeof(err_str));
}
@@ -4389,6 +4479,7 @@ static sctp_disposition_t sctp_sf_violation_chunklen(
* the length is considered as invalid.
*/
static sctp_disposition_t sctp_sf_violation_paramlen(
+ struct net *net,
const struct sctp_endpoint *ep,
const struct sctp_association *asoc,
const sctp_subtype_t type,
@@ -4418,7 +4509,7 @@ static sctp_disposition_t sctp_sf_violation_paramlen(
SCTP_INC_STATS(SCTP_MIB_ABORTEDS);
discard:
- sctp_sf_pdiscard(ep, asoc, SCTP_ST_CHUNK(0), arg, commands);
+ sctp_sf_pdiscard(net, ep, asoc, SCTP_ST_CHUNK(0), arg, commands);
return SCTP_DISPOSITION_ABORT;
nomem:
return SCTP_DISPOSITION_NOMEM;
@@ -4431,6 +4522,7 @@ nomem:
* error code.
*/
static sctp_disposition_t sctp_sf_violation_ctsn(
+ struct net *net,
const struct sctp_endpoint *ep,
const struct sctp_association *asoc,
const sctp_subtype_t type,
@@ -4439,7 +4531,7 @@ static sctp_disposition_t sctp_sf_violation_ctsn(
{
static const char err_str[]="The cumulative tsn ack beyond the max tsn currently sent:";
- return sctp_sf_abort_violation(ep, asoc, arg, commands, err_str,
+ return sctp_sf_abort_violation(net, ep, asoc, arg, commands, err_str,
sizeof(err_str));
}
@@ -4450,6 +4542,7 @@ static sctp_disposition_t sctp_sf_violation_ctsn(
* on the path and we may not want to continue this communication.
*/
static sctp_disposition_t sctp_sf_violation_chunk(
+ struct net *net,
const struct sctp_endpoint *ep,
const struct sctp_association *asoc,
const sctp_subtype_t type,
@@ -4459,9 +4552,9 @@ static sctp_disposition_t sctp_sf_violation_chunk(
static const char err_str[]="The following chunk violates protocol:";
if (!asoc)
- return sctp_sf_violation(ep, asoc, type, arg, commands);
+ return sctp_sf_violation(net, ep, asoc, type, arg, commands);
- return sctp_sf_abort_violation(ep, asoc, arg, commands, err_str,
+ return sctp_sf_abort_violation(net, ep, asoc, arg, commands, err_str,
sizeof(err_str));
}
/***************************************************************************
@@ -4524,7 +4617,8 @@ static sctp_disposition_t sctp_sf_violation_chunk(
*
* The return value is a disposition.
*/
-sctp_disposition_t sctp_sf_do_prm_asoc(const struct sctp_endpoint *ep,
+sctp_disposition_t sctp_sf_do_prm_asoc(struct net *net,
+ const struct sctp_endpoint *ep,
const struct sctp_association *asoc,
const sctp_subtype_t type,
void *arg,
@@ -4581,8 +4675,8 @@ nomem:
* E) Send
*
* Format: SEND(association id, buffer address, byte count [,context]
- * [,stream id] [,life time] [,destination transport address]
- * [,unorder flag] [,no-bundle flag] [,payload protocol-id] )
+ * [,stream id] [,life time] [,destination transport address]
+ * [,unorder flag] [,no-bundle flag] [,payload protocol-id] )
* -> result
*
* This is the main method to send user data via SCTP.
@@ -4635,7 +4729,8 @@ nomem:
*
* The return value is the disposition.
*/
-sctp_disposition_t sctp_sf_do_prm_send(const struct sctp_endpoint *ep,
+sctp_disposition_t sctp_sf_do_prm_send(struct net *net,
+ const struct sctp_endpoint *ep,
const struct sctp_association *asoc,
const sctp_subtype_t type,
void *arg,
@@ -4674,6 +4769,7 @@ sctp_disposition_t sctp_sf_do_prm_send(const struct sctp_endpoint *ep,
* The return value is the disposition.
*/
sctp_disposition_t sctp_sf_do_9_2_prm_shutdown(
+ struct net *net,
const struct sctp_endpoint *ep,
const struct sctp_association *asoc,
const sctp_subtype_t type,
@@ -4695,7 +4791,7 @@ sctp_disposition_t sctp_sf_do_9_2_prm_shutdown(
disposition = SCTP_DISPOSITION_CONSUME;
if (sctp_outq_is_empty(&asoc->outqueue)) {
- disposition = sctp_sf_do_9_2_start_shutdown(ep, asoc, type,
+ disposition = sctp_sf_do_9_2_start_shutdown(net, ep, asoc, type,
arg, commands);
}
return disposition;
@@ -4729,6 +4825,7 @@ sctp_disposition_t sctp_sf_do_9_2_prm_shutdown(
* The return value is the disposition.
*/
sctp_disposition_t sctp_sf_do_9_1_prm_abort(
+ struct net *net,
const struct sctp_endpoint *ep,
const struct sctp_association *asoc,
const sctp_subtype_t type,
@@ -4767,7 +4864,8 @@ sctp_disposition_t sctp_sf_do_9_1_prm_abort(
}
/* We tried an illegal operation on an association which is closed. */
-sctp_disposition_t sctp_sf_error_closed(const struct sctp_endpoint *ep,
+sctp_disposition_t sctp_sf_error_closed(struct net *net,
+ const struct sctp_endpoint *ep,
const struct sctp_association *asoc,
const sctp_subtype_t type,
void *arg,
@@ -4780,7 +4878,8 @@ sctp_disposition_t sctp_sf_error_closed(const struct sctp_endpoint *ep,
/* We tried an illegal operation on an association which is shutting
* down.
*/
-sctp_disposition_t sctp_sf_error_shutdown(const struct sctp_endpoint *ep,
+sctp_disposition_t sctp_sf_error_shutdown(struct net *net,
+ const struct sctp_endpoint *ep,
const struct sctp_association *asoc,
const sctp_subtype_t type,
void *arg,
@@ -4806,6 +4905,7 @@ sctp_disposition_t sctp_sf_error_shutdown(const struct sctp_endpoint *ep,
* (timers)
*/
sctp_disposition_t sctp_sf_cookie_wait_prm_shutdown(
+ struct net *net,
const struct sctp_endpoint *ep,
const struct sctp_association *asoc,
const sctp_subtype_t type,
@@ -4840,6 +4940,7 @@ sctp_disposition_t sctp_sf_cookie_wait_prm_shutdown(
* (timers)
*/
sctp_disposition_t sctp_sf_cookie_echoed_prm_shutdown(
+ struct net *net,
const struct sctp_endpoint *ep,
const struct sctp_association *asoc,
const sctp_subtype_t type,
@@ -4848,7 +4949,8 @@ sctp_disposition_t sctp_sf_cookie_echoed_prm_shutdown(
/* There is a single T1 timer, so we should be able to use
* common function with the COOKIE-WAIT state.
*/
- return sctp_sf_cookie_wait_prm_shutdown(ep, asoc, type, arg, commands);
+ return sctp_sf_cookie_wait_prm_shutdown(net, ep, asoc, type,
+ arg, commands);
}
/*
@@ -4866,6 +4968,7 @@ sctp_disposition_t sctp_sf_cookie_echoed_prm_shutdown(
* (timers)
*/
sctp_disposition_t sctp_sf_cookie_wait_prm_abort(
+ struct net *net,
const struct sctp_endpoint *ep,
const struct sctp_association *asoc,
const sctp_subtype_t type,
@@ -4915,6 +5018,7 @@ sctp_disposition_t sctp_sf_cookie_wait_prm_abort(
* (timers)
*/
sctp_disposition_t sctp_sf_cookie_echoed_prm_abort(
+ struct net *net,
const struct sctp_endpoint *ep,
const struct sctp_association *asoc,
const sctp_subtype_t type,
@@ -4924,7 +5028,8 @@ sctp_disposition_t sctp_sf_cookie_echoed_prm_abort(
/* There is a single T1 timer, so we should be able to use
* common function with the COOKIE-WAIT state.
*/
- return sctp_sf_cookie_wait_prm_abort(ep, asoc, type, arg, commands);
+ return sctp_sf_cookie_wait_prm_abort(net, ep, asoc, type,
+ arg, commands);
}
/*
@@ -4940,6 +5045,7 @@ sctp_disposition_t sctp_sf_cookie_echoed_prm_abort(
* (timers)
*/
sctp_disposition_t sctp_sf_shutdown_pending_prm_abort(
+ struct net *net,
const struct sctp_endpoint *ep,
const struct sctp_association *asoc,
const sctp_subtype_t type,
@@ -4950,7 +5056,7 @@ sctp_disposition_t sctp_sf_shutdown_pending_prm_abort(
sctp_add_cmd_sf(commands, SCTP_CMD_TIMER_STOP,
SCTP_TO(SCTP_EVENT_TIMEOUT_T5_SHUTDOWN_GUARD));
- return sctp_sf_do_9_1_prm_abort(ep, asoc, type, arg, commands);
+ return sctp_sf_do_9_1_prm_abort(net, ep, asoc, type, arg, commands);
}
/*
@@ -4966,6 +5072,7 @@ sctp_disposition_t sctp_sf_shutdown_pending_prm_abort(
* (timers)
*/
sctp_disposition_t sctp_sf_shutdown_sent_prm_abort(
+ struct net *net,
const struct sctp_endpoint *ep,
const struct sctp_association *asoc,
const sctp_subtype_t type,
@@ -4980,7 +5087,7 @@ sctp_disposition_t sctp_sf_shutdown_sent_prm_abort(
sctp_add_cmd_sf(commands, SCTP_CMD_TIMER_STOP,
SCTP_TO(SCTP_EVENT_TIMEOUT_T5_SHUTDOWN_GUARD));
- return sctp_sf_do_9_1_prm_abort(ep, asoc, type, arg, commands);
+ return sctp_sf_do_9_1_prm_abort(net, ep, asoc, type, arg, commands);
}
/*
@@ -4996,6 +5103,7 @@ sctp_disposition_t sctp_sf_shutdown_sent_prm_abort(
* (timers)
*/
sctp_disposition_t sctp_sf_shutdown_ack_sent_prm_abort(
+ struct net *net,
const struct sctp_endpoint *ep,
const struct sctp_association *asoc,
const sctp_subtype_t type,
@@ -5005,7 +5113,8 @@ sctp_disposition_t sctp_sf_shutdown_ack_sent_prm_abort(
/* The same T2 timer, so we should be able to use
* common function with the SHUTDOWN-SENT state.
*/
- return sctp_sf_shutdown_sent_prm_abort(ep, asoc, type, arg, commands);
+ return sctp_sf_shutdown_sent_prm_abort(net, ep, asoc, type,
+ arg, commands);
}
/*
@@ -5031,13 +5140,14 @@ sctp_disposition_t sctp_sf_shutdown_ack_sent_prm_abort(
* association on which a heartbeat should be issued.
*/
sctp_disposition_t sctp_sf_do_prm_requestheartbeat(
+ struct net *net,
const struct sctp_endpoint *ep,
const struct sctp_association *asoc,
const sctp_subtype_t type,
void *arg,
sctp_cmd_seq_t *commands)
{
- if (SCTP_DISPOSITION_NOMEM == sctp_sf_heartbeat(ep, asoc, type,
+ if (SCTP_DISPOSITION_NOMEM == sctp_sf_heartbeat(net, ep, asoc, type,
(struct sctp_transport *)arg, commands))
return SCTP_DISPOSITION_NOMEM;
@@ -5062,7 +5172,8 @@ sctp_disposition_t sctp_sf_do_prm_requestheartbeat(
* When an endpoint has an ASCONF signaled change to be sent to the
* remote endpoint it should do A1 to A9
*/
-sctp_disposition_t sctp_sf_do_prm_asconf(const struct sctp_endpoint *ep,
+sctp_disposition_t sctp_sf_do_prm_asconf(struct net *net,
+ const struct sctp_endpoint *ep,
const struct sctp_association *asoc,
const sctp_subtype_t type,
void *arg,
@@ -5083,6 +5194,7 @@ sctp_disposition_t sctp_sf_do_prm_asconf(const struct sctp_endpoint *ep,
* The return value is the disposition of the primitive.
*/
sctp_disposition_t sctp_sf_ignore_primitive(
+ struct net *net,
const struct sctp_endpoint *ep,
const struct sctp_association *asoc,
const sctp_subtype_t type,
@@ -5104,6 +5216,7 @@ sctp_disposition_t sctp_sf_ignore_primitive(
* retransmit, the stack will immediately send up this notification.
*/
sctp_disposition_t sctp_sf_do_no_pending_tsn(
+ struct net *net,
const struct sctp_endpoint *ep,
const struct sctp_association *asoc,
const sctp_subtype_t type,
@@ -5135,6 +5248,7 @@ sctp_disposition_t sctp_sf_do_no_pending_tsn(
* The return value is the disposition.
*/
sctp_disposition_t sctp_sf_do_9_2_start_shutdown(
+ struct net *net,
const struct sctp_endpoint *ep,
const struct sctp_association *asoc,
const sctp_subtype_t type,
@@ -5204,6 +5318,7 @@ nomem:
* The return value is the disposition.
*/
sctp_disposition_t sctp_sf_do_9_2_shutdown_ack(
+ struct net *net,
const struct sctp_endpoint *ep,
const struct sctp_association *asoc,
const sctp_subtype_t type,
@@ -5222,12 +5337,14 @@ sctp_disposition_t sctp_sf_do_9_2_shutdown_ack(
*/
if (chunk) {
if (!sctp_vtag_verify(chunk, asoc))
- return sctp_sf_pdiscard(ep, asoc, type, arg, commands);
+ return sctp_sf_pdiscard(net, ep, asoc, type, arg,
+ commands);
/* Make sure that the SHUTDOWN chunk has a valid length. */
- if (!sctp_chunk_length_valid(chunk, sizeof(struct sctp_shutdown_chunk_t)))
- return sctp_sf_violation_chunklen(ep, asoc, type, arg,
- commands);
+ if (!sctp_chunk_length_valid(chunk,
+ sizeof(struct sctp_shutdown_chunk_t)))
+ return sctp_sf_violation_chunklen(net, ep, asoc, type,
+ arg, commands);
}
/* If it has no more outstanding DATA chunks, the SHUTDOWN receiver
@@ -5274,7 +5391,8 @@ nomem:
*
* The return value is the disposition of the event.
*/
-sctp_disposition_t sctp_sf_ignore_other(const struct sctp_endpoint *ep,
+sctp_disposition_t sctp_sf_ignore_other(struct net *net,
+ const struct sctp_endpoint *ep,
const struct sctp_association *asoc,
const sctp_subtype_t type,
void *arg,
@@ -5299,7 +5417,8 @@ sctp_disposition_t sctp_sf_ignore_other(const struct sctp_endpoint *ep,
*
* The return value is the disposition of the chunk.
*/
-sctp_disposition_t sctp_sf_do_6_3_3_rtx(const struct sctp_endpoint *ep,
+sctp_disposition_t sctp_sf_do_6_3_3_rtx(struct net *net,
+ const struct sctp_endpoint *ep,
const struct sctp_association *asoc,
const sctp_subtype_t type,
void *arg,
@@ -5385,7 +5504,8 @@ sctp_disposition_t sctp_sf_do_6_3_3_rtx(const struct sctp_endpoint *ep,
* allow. However, an SCTP transmitter MUST NOT be more aggressive than
* the following algorithms allow.
*/
-sctp_disposition_t sctp_sf_do_6_2_sack(const struct sctp_endpoint *ep,
+sctp_disposition_t sctp_sf_do_6_2_sack(struct net *net,
+ const struct sctp_endpoint *ep,
const struct sctp_association *asoc,
const sctp_subtype_t type,
void *arg,
@@ -5415,7 +5535,8 @@ sctp_disposition_t sctp_sf_do_6_2_sack(const struct sctp_endpoint *ep,
* (timers, events)
*
*/
-sctp_disposition_t sctp_sf_t1_init_timer_expire(const struct sctp_endpoint *ep,
+sctp_disposition_t sctp_sf_t1_init_timer_expire(struct net *net,
+ const struct sctp_endpoint *ep,
const struct sctp_association *asoc,
const sctp_subtype_t type,
void *arg,
@@ -5476,7 +5597,8 @@ sctp_disposition_t sctp_sf_t1_init_timer_expire(const struct sctp_endpoint *ep,
* (timers, events)
*
*/
-sctp_disposition_t sctp_sf_t1_cookie_timer_expire(const struct sctp_endpoint *ep,
+sctp_disposition_t sctp_sf_t1_cookie_timer_expire(struct net *net,
+ const struct sctp_endpoint *ep,
const struct sctp_association *asoc,
const sctp_subtype_t type,
void *arg,
@@ -5524,7 +5646,8 @@ sctp_disposition_t sctp_sf_t1_cookie_timer_expire(const struct sctp_endpoint *ep
* the T2-Shutdown timer, giving its peer ample opportunity to transmit
* all of its queued DATA chunks that have not yet been sent.
*/
-sctp_disposition_t sctp_sf_t2_timer_expire(const struct sctp_endpoint *ep,
+sctp_disposition_t sctp_sf_t2_timer_expire(struct net *net,
+ const struct sctp_endpoint *ep,
const struct sctp_association *asoc,
const sctp_subtype_t type,
void *arg,
@@ -5593,6 +5716,7 @@ nomem:
* If the T4 RTO timer expires the endpoint should do B1 to B5
*/
sctp_disposition_t sctp_sf_t4_timer_expire(
+ struct net *net,
const struct sctp_endpoint *ep,
const struct sctp_association *asoc,
const sctp_subtype_t type,
@@ -5663,7 +5787,8 @@ sctp_disposition_t sctp_sf_t4_timer_expire(
* At the expiration of this timer the sender SHOULD abort the association
* by sending an ABORT chunk.
*/
-sctp_disposition_t sctp_sf_t5_timer_expire(const struct sctp_endpoint *ep,
+sctp_disposition_t sctp_sf_t5_timer_expire(struct net *net,
+ const struct sctp_endpoint *ep,
const struct sctp_association *asoc,
const sctp_subtype_t type,
void *arg,
@@ -5698,6 +5823,7 @@ nomem:
* the user. So this routine looks same as sctp_sf_do_9_2_prm_shutdown().
*/
sctp_disposition_t sctp_sf_autoclose_timer_expire(
+ struct net *net,
const struct sctp_endpoint *ep,
const struct sctp_association *asoc,
const sctp_subtype_t type,
@@ -5721,7 +5847,7 @@ sctp_disposition_t sctp_sf_autoclose_timer_expire(
disposition = SCTP_DISPOSITION_CONSUME;
if (sctp_outq_is_empty(&asoc->outqueue)) {
- disposition = sctp_sf_do_9_2_start_shutdown(ep, asoc, type,
+ disposition = sctp_sf_do_9_2_start_shutdown(net, ep, asoc, type,
arg, commands);
}
return disposition;
@@ -5739,7 +5865,8 @@ sctp_disposition_t sctp_sf_autoclose_timer_expire(
*
* The return value is the disposition of the chunk.
*/
-sctp_disposition_t sctp_sf_not_impl(const struct sctp_endpoint *ep,
+sctp_disposition_t sctp_sf_not_impl(struct net *net,
+ const struct sctp_endpoint *ep,
const struct sctp_association *asoc,
const sctp_subtype_t type,
void *arg,
@@ -5756,7 +5883,8 @@ sctp_disposition_t sctp_sf_not_impl(const struct sctp_endpoint *ep,
*
* The return value is the disposition of the chunk.
*/
-sctp_disposition_t sctp_sf_bug(const struct sctp_endpoint *ep,
+sctp_disposition_t sctp_sf_bug(struct net *net,
+ const struct sctp_endpoint *ep,
const struct sctp_association *asoc,
const sctp_subtype_t type,
void *arg,
@@ -5776,7 +5904,8 @@ sctp_disposition_t sctp_sf_bug(const struct sctp_endpoint *ep,
*
* The return value is the disposition of the chunk.
*/
-sctp_disposition_t sctp_sf_timer_ignore(const struct sctp_endpoint *ep,
+sctp_disposition_t sctp_sf_timer_ignore(struct net *net,
+ const struct sctp_endpoint *ep,
const struct sctp_association *asoc,
const sctp_subtype_t type,
void *arg,
@@ -5822,12 +5951,13 @@ static struct sctp_packet *sctp_abort_pkt_new(const struct sctp_endpoint *ep,
const struct sctp_association *asoc,
struct sctp_chunk *chunk,
const void *payload,
- size_t paylen)
+ size_t paylen,
+ struct net *net)
{
struct sctp_packet *packet;
struct sctp_chunk *abort;
- packet = sctp_ootb_pkt_new(asoc, chunk);
+ packet = sctp_ootb_pkt_new(net, asoc, chunk);
if (packet) {
/* Make an ABORT.
@@ -5859,8 +5989,9 @@ static struct sctp_packet *sctp_abort_pkt_new(const struct sctp_endpoint *ep,
}
/* Allocate a packet for responding in the OOTB conditions. */
-static struct sctp_packet *sctp_ootb_pkt_new(const struct sctp_association *asoc,
- const struct sctp_chunk *chunk)
+static struct sctp_packet *sctp_ootb_pkt_new(struct net *net,
+ const struct sctp_association *asoc,
+ const struct sctp_chunk *chunk)
{
struct sctp_packet *packet;
struct sctp_transport *transport;
@@ -5919,9 +6050,8 @@ static struct sctp_packet *sctp_ootb_pkt_new(const struct sctp_association *asoc
/* Cache a route for the transport with the chunk's destination as
* the source address.
*/
- sctp_transport_route(&init_net, transport,
- (union sctp_addr *)&chunk->dest,
- sctp_sk(*sctp_get_ctl_sock(&init_net)));
+ sctp_transport_route(net, transport, (union sctp_addr *)&chunk->dest,
+ sctp_sk(*sctp_get_ctl_sock(net)));
packet = sctp_packet_init(&transport->packet, transport, sport, dport);
packet = sctp_packet_config(packet, vtag, 0);
@@ -5939,7 +6069,8 @@ void sctp_ootb_pkt_free(struct sctp_packet *packet)
}
/* Send a stale cookie error when a invalid COOKIE ECHO chunk is found */
-static void sctp_send_stale_cookie_err(const struct sctp_endpoint *ep,
+static void sctp_send_stale_cookie_err(struct net *net,
+ const struct sctp_endpoint *ep,
const struct sctp_association *asoc,
const struct sctp_chunk *chunk,
sctp_cmd_seq_t *commands,
@@ -5948,7 +6079,7 @@ static void sctp_send_stale_cookie_err(const struct sctp_endpoint *ep,
struct sctp_packet *packet;
if (err_chunk) {
- packet = sctp_ootb_pkt_new(asoc, chunk);
+ packet = sctp_ootb_pkt_new(net, asoc, chunk);
if (packet) {
struct sctp_signed_cookie *cookie;
@@ -5969,7 +6100,8 @@ static void sctp_send_stale_cookie_err(const struct sctp_endpoint *ep,
/* Process a data chunk */
-static int sctp_eat_data(const struct sctp_association *asoc,
+static int sctp_eat_data(struct net *net,
+ const struct sctp_association *asoc,
struct sctp_chunk *chunk,
sctp_cmd_seq_t *commands)
{
@@ -6083,7 +6215,7 @@ static int sctp_eat_data(const struct sctp_association *asoc,
*/
if (*sk->sk_prot_creator->memory_pressure) {
if (sctp_tsnmap_has_gap(map) &&
- (sctp_tsnmap_get_ctsn(map) + 1) == tsn) {
+ (sctp_tsnmap_get_ctsn(map) + 1) == tsn) {
SCTP_DEBUG_PRINTK("Under Pressure! Reneging for tsn:%u\n", tsn);
deliver = SCTP_CMD_RENEGE;
}
--
1.7.9.5
^ permalink raw reply related
* Re: [PATCH V2 09/12] net/eipoib: Add main driver functionality
From: Or Gerlitz @ 2012-08-04 21:33 UTC (permalink / raw)
To: Eric W. Biederman
Cc: Ali Ayoub, David Miller, ogerlitz, roland, netdev, sean.hefty,
erezsh
In-Reply-To: <1d3bddff-4b3a-4ed1-b8f9-21bd531ba20b@email.android.com>
On Sat, Aug 4, 2012 at 4:34 AM, Eric W. Biederman <ebiederm@xmission.com> wrote:
> Ali Ayoub <ali@mellanox.com> wrote:
>>With this driver, existing VMs, and their existing IP applications, can
>>run as-is on InfiniBand network.
> Actually it doesn't work like that.
> If my application really needs ethernet it will not work with your driver.
Eric,
Starting to address your email
If your application really needs Ethernet, it will not work with
IPoIB, since the latter only supports IP apps. So this isn't the
problem we're trying to solve here, but rather allow IP app running in
PV mode to use IPoIB.
> I can not run decnet or appletalk or ATAoE or PPPoE or LACP
[...]
> or use VLANs
YES you can, vlan devices can be set over eipoib devices, and the
eipoib driver maps the vlan ID to IB Partition using a mapping defined
by the admin.
> or any of a thousand other things that require real live ethernet to function.
[...]
> Similarly eIPoIB does not make sense from a performance standpoint because
> the best performance requires the applications and hypervisors are infiniband
> and teaching the apps to cope.
agree 100% re the "best performance" part of this sentence, if your
app looks for best perf, yes you can use IB in either native or SRIOV
mode, as I mentioned in my response to Dave.
Or.
Or.
^ permalink raw reply
* [PATCH 05/13] SCTP: register per-namespace sysctl.
From: Jan Ariyasu @ 2012-08-04 21:33 UTC (permalink / raw)
To: Vlad Yasevich, David S. Miller, linux-sctp, netdev, linux-kernel
Cc: Jan Ariyasu
Updated sysctl registration to be per-netns and to use per-net
protocol parameters.
Signed-off-by: Jan Ariyasu <jan.ariyasu@hp.com>
---
include/net/sctp/sctp.h | 8 +-
net/sctp/protocol.c | 24 +++++-
net/sctp/sysctl.c | 218 +++++++++++++++++++++++++++++++++++++++++------
3 files changed, 221 insertions(+), 29 deletions(-)
diff --git a/include/net/sctp/sctp.h b/include/net/sctp/sctp.h
index bda317a..eb2ec98 100644
--- a/include/net/sctp/sctp.h
+++ b/include/net/sctp/sctp.h
@@ -381,11 +381,15 @@ static inline void sctp_dbg_objcnt_exit(void) { return; }
#endif /* CONFIG_SCTP_DBG_OBJCOUNT */
#if defined CONFIG_SYSCTL
-void sctp_sysctl_register(void);
+int sctp_sysctl_register(void);
void sctp_sysctl_unregister(void);
+int __net_init sctp_sysctl_init_net(struct net *net);
+void __net_exit sctp_sysctl_exit_net(struct net *net);
#else
-static inline void sctp_sysctl_register(void) { return; }
+static inline int sctp_sysctl_register(void) { return 0; }
static inline void sctp_sysctl_unregister(void) { return; }
+static inline int sctp_sysctl_init_net(struct net *net) { return 0; };
+static inline void sctp_sysctl_exit_net(struct net *net) { return 0; };
#endif
/* Size of Supported Address Parameter for 'x' address types. */
diff --git a/net/sctp/protocol.c b/net/sctp/protocol.c
index dce07d6..32bb8f4e2 100644
--- a/net/sctp/protocol.c
+++ b/net/sctp/protocol.c
@@ -1582,8 +1582,15 @@ static int __net_init sctp_net_init(struct net *net)
if (err)
goto err_param_init;
+#ifdef CONFIG_SYSCTL
+ err = sctp_sysctl_init_net(net);
+ if (err)
+ goto err_param_init;
+#endif
+
sctp_get_local_addr_list(net);
goto out;
+
err_param_init:
sctp_proc_exit(net);
err_proc_init:
@@ -1601,6 +1608,10 @@ static void __net_exit sctp_net_exit(struct net *net)
sctp_free_local_addr_list(net);
/* Clean up procfs */
sctp_proc_exit(net);
+#ifdef CONFIG_SYSCTL
+ /* Clean up sysfs */
+ sctp_sysctl_exit_net(net);
+#endif
}
static __net_initdata struct pernet_operations sctp_sk_ops = {
@@ -1671,7 +1682,11 @@ SCTP_STATIC __init int sctp_init(void)
goto err_v6_add_protocol;
/* Set up sysctl parameters. */
- sctp_sysctl_register();
+#ifdef CONFIG_SYSCTL
+ status = sctp_sysctl_register();
+ if (status)
+ goto err_sysctl_init;
+#endif
/*
* Register for pernet packet handling
@@ -1694,10 +1709,13 @@ SCTP_STATIC __init int sctp_init(void)
goto out;
err_mib_init:
- sctp_sysctl_unregister();
sctp_dbg_objcnt_exit();
sctp_ns_exit();
err_ns_init:
+#ifdef CONFIG_SYSCTL
+ sctp_sysctl_unregister();
+#endif
+err_sysctl_init:
sctp_v6_del_protocol();
err_v6_add_protocol:
sctp_v4_del_protocol();
@@ -1735,7 +1753,9 @@ SCTP_STATIC __exit void sctp_exit(void)
sctp_v6_pf_exit();
sctp_v4_pf_exit();
+#ifdef CONFIG_SYSCTL
sctp_sysctl_unregister();
+#endif
sctp_hashtable_globals_free();
sctp_dbg_objcnt_exit();
diff --git a/net/sctp/sysctl.c b/net/sctp/sysctl.c
index 2b2bfe9..0d42d90 100644
--- a/net/sctp/sysctl.c
+++ b/net/sctp/sysctl.c
@@ -219,27 +219,6 @@ static ctl_table sctp_table[] = {
.extra2 = &sack_timer_max,
},
{
- .procname = "sctp_mem",
- .data = &sysctl_sctp_mem,
- .maxlen = sizeof(sysctl_sctp_mem),
- .mode = 0644,
- .proc_handler = proc_doulongvec_minmax
- },
- {
- .procname = "sctp_rmem",
- .data = &sysctl_sctp_rmem,
- .maxlen = sizeof(sysctl_sctp_rmem),
- .mode = 0644,
- .proc_handler = proc_dointvec,
- },
- {
- .procname = "sctp_wmem",
- .data = &sysctl_sctp_wmem,
- .maxlen = sizeof(sysctl_sctp_wmem),
- .mode = 0644,
- .proc_handler = proc_dointvec,
- },
- {
.procname = "auth_enable",
.data = &sctp_auth_enable,
.maxlen = sizeof(int),
@@ -284,16 +263,205 @@ static ctl_table sctp_table[] = {
{ /* sentinel */ }
};
-static struct ctl_table_header * sctp_sysctl_header;
+static struct ctl_table sctp_mem_table[] = {
+ {
+ .procname = "sctp_mem",
+ .data = &sysctl_sctp_mem,
+ .maxlen = sizeof(sysctl_sctp_mem),
+ .mode = 0644,
+ .proc_handler = proc_doulongvec_minmax
+ },
+ {
+ .procname = "sctp_rmem",
+ .data = &sysctl_sctp_rmem,
+ .maxlen = sizeof(sysctl_sctp_rmem),
+ .mode = 0644,
+ .proc_handler = proc_dointvec,
+ },
+ {
+ .procname = "sctp_wmem",
+ .data = &sysctl_sctp_wmem,
+ .maxlen = sizeof(sysctl_sctp_wmem),
+ .mode = 0644,
+ .proc_handler = proc_dointvec,
+ },
+
+ { /* sentinel */ }
+};
+
+static struct ctl_path sctp_path[] = {
+ { .procname = "net", },
+ { .procname = "sctp", },
+ { }
+};
+
+static struct ctl_table_header *sctp_sysctl_mem_header;
/* Sysctl registration. */
-void sctp_sysctl_register(void)
+int sctp_sysctl_register(void)
{
- sctp_sysctl_header = register_net_sysctl(&init_net, "net/sctp", sctp_table);
+ int err = 0;
+ sctp_sysctl_mem_header = NULL;
+ sctp_sysctl_mem_header = register_sysctl_paths(sctp_path,
+ sctp_mem_table);
+ if (sctp_sysctl_mem_header == NULL) {
+ pr_err("Failed to register sctp_mem_table sysctl path\n");
+ err = -ENOMEM;
+ }
+ return err;
}
/* Sysctl deregistration. */
void sctp_sysctl_unregister(void)
{
- unregister_net_sysctl_table(sctp_sysctl_header);
+ unregister_net_sysctl_table(sctp_sysctl_mem_header);
+}
+
+/* Per-net sysctl registration */
+int __net_init sctp_sysctl_init_net(struct net *net)
+{
+ struct sctp_ns_globals *ns_globals = sctp_get_ns_globals(net);
+ struct sctp_net_params *net_params = sctp_get_params(net);
+ struct ctl_table *table, *tmp_tbl;
+
+ table = sctp_table;
+ if (!net_eq(net, &init_net)) {
+ table = kmemdup(table, sizeof(sctp_table), GFP_KERNEL);
+ if (table == NULL)
+ goto err_alloc;
+
+ for (tmp_tbl = table; tmp_tbl->procname; tmp_tbl++) {
+ if (strcmp(tmp_tbl->procname, "rto_initial") == 0) {
+ tmp_tbl->data = &net_params->rto_initial;
+ continue;
+ }
+ if (strcmp(tmp_tbl->procname, "rto_min") == 0) {
+ tmp_tbl->data = &net_params->rto_min;
+ continue;
+ }
+ if (strcmp(tmp_tbl->procname, "rto_max") == 0) {
+ tmp_tbl->data = &net_params->rto_max;
+ continue;
+ }
+ if (strcmp(tmp_tbl->procname,
+ "valid_cookie_life") == 0) {
+ tmp_tbl->data = &net_params->valid_cookie_life;
+ continue;
+ }
+ if (strcmp(tmp_tbl->procname, "max_burst") == 0) {
+ tmp_tbl->data = &net_params->max_burst;
+ continue;
+ }
+ if (strcmp(tmp_tbl->procname,
+ "association_max_retrans") == 0) {
+ tmp_tbl->data =
+ &net_params->max_retrans_association;
+ continue;
+ }
+ if (strcmp(tmp_tbl->procname, "sndbuf_policy") == 0) {
+ tmp_tbl->data = &net_params->sndbuf_policy;
+ continue;
+ }
+ if (strcmp(tmp_tbl->procname, "rcvbuf_policy") == 0) {
+ tmp_tbl->data = &net_params->rcvbuf_policy;
+ continue;
+ }
+ if (strcmp(tmp_tbl->procname,
+ "path_max_retrans") == 0) {
+ tmp_tbl->data = &net_params->max_retrans_path;
+ continue;
+ }
+ if (strcmp(tmp_tbl->procname, "pf_retrans") == 0) {
+ tmp_tbl->data = &net_params->pf_retrans;
+ continue;
+ }
+ if (strcmp(tmp_tbl->procname,
+ "max_init_retransmits") == 0) {
+ tmp_tbl->data = &net_params->max_retrans_init;
+ continue;
+ }
+ if (strcmp(tmp_tbl->procname, "hb_interval") == 0) {
+ tmp_tbl->data = &net_params->hb_interval;
+ continue;
+ }
+ if (strcmp(tmp_tbl->procname,
+ "cookie_preserve_enable") == 0) {
+ tmp_tbl->data =
+ &net_params->cookie_preserve_enable;
+ continue;
+ }
+ if (strcmp(tmp_tbl->procname,
+ "rto_alpha_exp_divisor") == 0) {
+ tmp_tbl->data = &net_params->rto_alpha;
+ continue;
+ }
+ if (strcmp(tmp_tbl->procname,
+ "rto_beta_exp_divisor") == 0) {
+ tmp_tbl->data = &net_params->rto_beta;
+ continue;
+ }
+ if (strcmp(tmp_tbl->procname, "addip_enable") == 0) {
+ tmp_tbl->data = &net_params->addip_enable;
+ continue;
+ }
+ if (strcmp(tmp_tbl->procname,
+ "default_auto_asconf") == 0) {
+ tmp_tbl->data =
+ &net_params->default_auto_asconf;
+ continue;
+ }
+ if (strcmp(tmp_tbl->procname, "prsctp_enable") == 0) {
+ tmp_tbl->data = &net_params->prsctp_enable;
+ continue;
+ }
+ if (strcmp(tmp_tbl->procname, "sack_timeout") == 0) {
+ tmp_tbl->data = &net_params->sack_timeout;
+ continue;
+ }
+ if (strcmp(tmp_tbl->procname, "auth_enable") == 0) {
+ tmp_tbl->data = &net_params->auth_enable;
+ continue;
+ }
+ if (strcmp(tmp_tbl->procname,
+ "addip_noauth_enable") == 0) {
+ tmp_tbl->data =
+ &net_params->addip_noauth_enable;
+ continue;
+ }
+ if (strcmp(tmp_tbl->procname,
+ "addr_scope_policy") == 0) {
+ tmp_tbl->data = &net_params->ipv4_scope_policy;
+ continue;
+ }
+ if (strcmp(tmp_tbl->procname,
+ "rwnd_update_shift") == 0) {
+ tmp_tbl->data = &net_params->rwnd_update_shift;
+ continue;
+ }
+ if (strcmp(tmp_tbl->procname, "max_autoclose") == 0) {
+ tmp_tbl->data = &net_params->max_autoclose;
+ continue;
+ }
+ }
+ }
+ ns_globals->sctp_sysctl_tbl = register_net_sysctl(net,
+ "net/sctp", table);
+ if (ns_globals->sctp_sysctl_tbl == NULL)
+ goto err_reg;
+
+ return 0;
+err_reg:
+ if (!net_eq(net, &init_net))
+ kfree(table);
+
+err_alloc:
+ return -ENOMEM;
+}
+
+void __net_exit sctp_sysctl_exit_net(struct net *net)
+{
+ struct sctp_ns_globals *ns_globals = sctp_get_ns_globals(net);
+ struct ctl_table *table = ns_globals->sctp_sysctl_tbl->ctl_table_arg;
+ unregister_net_sysctl_table(ns_globals->sctp_sysctl_tbl);
+ kfree(table);
}
--
1.7.9.5
^ permalink raw reply related
* [PATCH 04/13] SCTP: enable per-namespace address handling.
From: Jan Ariyasu @ 2012-08-04 21:32 UTC (permalink / raw)
To: Vlad Yasevich, David S. Miller, linux-sctp, netdev, linux-kernel
Cc: Jan Ariyasu
Make a separate local_addr_list for each netns, and use that list
to when creating associations.
Signed-off-by: Jan Ariyasu <jan.ariyasu@hp.com>
---
include/net/sctp/sctp.h | 8 ++-
include/net/sctp/structs.h | 28 ++++----
net/sctp/associola.c | 6 +-
net/sctp/bind_addr.c | 25 ++++---
net/sctp/ipv6.c | 47 ++++++++------
net/sctp/output.c | 4 +-
net/sctp/protocol.c | 154 ++++++++++++++++++++++++--------------------
net/sctp/sm_make_chunk.c | 8 ++-
net/sctp/sm_sideeffect.c | 3 +-
net/sctp/sm_statefuns.c | 16 +++--
net/sctp/socket.c | 59 ++++++++++-------
net/sctp/transport.c | 15 +++--
12 files changed, 216 insertions(+), 157 deletions(-)
diff --git a/include/net/sctp/sctp.h b/include/net/sctp/sctp.h
index 97ba550..bda317a 100644
--- a/include/net/sctp/sctp.h
+++ b/include/net/sctp/sctp.h
@@ -121,10 +121,11 @@ extern int sctp_net_id;
*/
extern int sctp_copy_local_addr_list(struct sctp_bind_addr *,
sctp_scope_t, gfp_t gfp,
- int flags);
+ int flags, struct net *);
extern struct sctp_pf *sctp_get_pf_specific(sa_family_t family);
extern int sctp_register_pf(struct sctp_pf *, sa_family_t);
-extern void sctp_addr_wq_mgmt(struct sctp_sockaddr_entry *, int);
+extern void sctp_addr_wq_mgmt(struct net *,
+ struct sctp_sockaddr_entry *, int);
/*
* sctp/socket.c
@@ -139,7 +140,8 @@ void sctp_sock_rfree(struct sk_buff *skb);
void sctp_copy_sock(struct sock *newsk, struct sock *sk,
struct sctp_association *asoc);
extern struct percpu_counter sctp_sockets_allocated;
-extern int sctp_asconf_mgmt(struct sctp_sock *, struct sctp_sockaddr_entry *);
+extern int sctp_asconf_mgmt(struct net *, struct sctp_sock *,
+ struct sctp_sockaddr_entry *);
/*
* sctp/primitive.c
diff --git a/include/net/sctp/structs.h b/include/net/sctp/structs.h
index bc65718..2034d53 100644
--- a/include/net/sctp/structs.h
+++ b/include/net/sctp/structs.h
@@ -718,7 +718,8 @@ struct sctp_af {
int optname,
char __user *optval,
int __user *optlen);
- void (*get_dst) (struct sctp_transport *t,
+ void (*get_dst) (struct net *net,
+ struct sctp_transport *t,
union sctp_addr *saddr,
struct flowi *fl,
struct sock *sk);
@@ -751,7 +752,7 @@ struct sctp_af {
sctp_scope_t (*scope) (union sctp_addr *);
void (*inaddr_any) (union sctp_addr *, __be16);
int (*is_any) (const union sctp_addr *);
- int (*available) (union sctp_addr *,
+ int (*available) (struct net *, union sctp_addr *,
struct sctp_sock *);
int (*skb_iif) (const struct sk_buff *sk);
int (*is_ce) (const struct sk_buff *sk);
@@ -775,8 +776,10 @@ struct sctp_pf {
int (*cmp_addr) (const union sctp_addr *,
const union sctp_addr *,
struct sctp_sock *);
- int (*bind_verify) (struct sctp_sock *, union sctp_addr *);
- int (*send_verify) (struct sctp_sock *, union sctp_addr *);
+ int (*bind_verify) (struct net *, struct sctp_sock *,
+ union sctp_addr *);
+ int (*send_verify) (struct net *, struct sctp_sock *,
+ union sctp_addr *);
int (*supported_addrs)(const struct sctp_sock *, __be16 *);
struct sock *(*create_accept_sk) (struct sock *sk,
struct sctp_association *asoc);
@@ -1220,9 +1223,10 @@ struct sctp_transport *sctp_transport_new(const union sctp_addr *,
gfp_t);
void sctp_transport_set_owner(struct sctp_transport *,
struct sctp_association *);
-void sctp_transport_route(struct sctp_transport *, union sctp_addr *,
- struct sctp_sock *);
-void sctp_transport_pmtu(struct sctp_transport *, struct sock *sk);
+void sctp_transport_route(struct net *, struct sctp_transport *,
+ union sctp_addr *, struct sctp_sock *);
+void sctp_transport_pmtu(struct net *, struct sctp_transport *,
+ struct sock *sk);
void sctp_transport_free(struct sctp_transport *);
void sctp_transport_reset_timers(struct sctp_transport *);
void sctp_transport_hold(struct sctp_transport *);
@@ -1373,6 +1377,7 @@ void sctp_bind_addr_init(struct sctp_bind_addr *, __u16 port);
void sctp_bind_addr_free(struct sctp_bind_addr *);
int sctp_bind_addr_copy(struct sctp_bind_addr *dest,
const struct sctp_bind_addr *src,
+ struct net *net,
sctp_scope_t scope, gfp_t gfp,
int flags);
int sctp_bind_addr_dup(struct sctp_bind_addr *dest,
@@ -1398,7 +1403,8 @@ int sctp_raw_to_bind_addrs(struct sctp_bind_addr *bp, __u8 *raw, int len,
__u16 port, gfp_t gfp);
sctp_scope_t sctp_scope(const union sctp_addr *);
-int sctp_in_scope(const union sctp_addr *addr, const sctp_scope_t scope);
+int sctp_in_scope(const union sctp_addr *addr, const sctp_scope_t scope,
+ struct net *net);
int sctp_is_any(struct sock *sk, const union sctp_addr *addr);
int sctp_addr_is_valid(const union sctp_addr *addr);
int sctp_is_ep_boundall(struct sock *sk);
@@ -1564,8 +1570,8 @@ int sctp_verify_init(const struct sctp_association *asoc, sctp_cid_t,
sctp_init_chunk_t *peer_init, struct sctp_chunk *chunk,
struct sctp_chunk **err_chunk);
int sctp_process_init(struct sctp_association *, struct sctp_chunk *chunk,
- const union sctp_addr *peer,
- sctp_init_chunk_t *init, gfp_t gfp);
+ const union sctp_addr *peer, sctp_init_chunk_t *init,
+ struct net *net, gfp_t gfp);
__u32 sctp_generate_tag(const struct sctp_endpoint *);
__u32 sctp_generate_tsn(const struct sctp_endpoint *);
@@ -2160,7 +2166,7 @@ void sctp_assoc_set_primary(struct sctp_association *,
void sctp_assoc_del_nonprimary_peers(struct sctp_association *,
struct sctp_transport *);
int sctp_assoc_set_bind_addr_from_ep(struct sctp_association *,
- sctp_scope_t, gfp_t);
+ struct net *, sctp_scope_t, gfp_t);
int sctp_assoc_set_bind_addr_from_cookie(struct sctp_association *,
struct sctp_cookie*,
gfp_t gfp);
diff --git a/net/sctp/associola.c b/net/sctp/associola.c
index ebaef3e..001f44b 100644
--- a/net/sctp/associola.c
+++ b/net/sctp/associola.c
@@ -644,6 +644,7 @@ struct sctp_transport *sctp_assoc_add_peer(struct sctp_association *asoc,
struct sctp_transport *peer;
struct sctp_sock *sp;
unsigned short port;
+ struct net *net = sock_net(asoc->base.sk);
sp = sctp_sk(asoc->base.sk);
@@ -702,7 +703,7 @@ struct sctp_transport *sctp_assoc_add_peer(struct sctp_association *asoc,
*/
peer->param_flags = asoc->param_flags;
- sctp_transport_route(peer, NULL, sp);
+ sctp_transport_route(net, peer, NULL, sp);
/* Initialize the pmtu of the transport. */
if (peer->param_flags & SPP_PMTUD_DISABLE) {
@@ -1529,6 +1530,7 @@ void sctp_assoc_rwnd_decrease(struct sctp_association *asoc, unsigned int len)
* local endpoint and the remote peer.
*/
int sctp_assoc_set_bind_addr_from_ep(struct sctp_association *asoc,
+ struct net *net,
sctp_scope_t scope, gfp_t gfp)
{
int flags;
@@ -1543,7 +1545,7 @@ int sctp_assoc_set_bind_addr_from_ep(struct sctp_association *asoc,
flags |= SCTP_ADDR6_PEERSUPP;
return sctp_bind_addr_copy(&asoc->base.bind_addr,
- &asoc->ep->base.bind_addr,
+ &asoc->ep->base.bind_addr, net,
scope, gfp, flags);
}
diff --git a/net/sctp/bind_addr.c b/net/sctp/bind_addr.c
index 4ece451..2b18722 100644
--- a/net/sctp/bind_addr.c
+++ b/net/sctp/bind_addr.c
@@ -52,9 +52,10 @@
#include <net/sctp/sm.h>
/* Forward declarations for internal helpers. */
-static int sctp_copy_one_addr(struct sctp_bind_addr *, union sctp_addr *,
- sctp_scope_t scope, gfp_t gfp,
- int flags);
+static int sctp_copy_one_addr(struct sctp_bind_addr *,
+ union sctp_addr *, struct net *,
+ sctp_scope_t scope,
+ gfp_t gfp, int flags);
static void sctp_bind_addr_clean(struct sctp_bind_addr *);
/* First Level Abstractions. */
@@ -64,6 +65,7 @@ static void sctp_bind_addr_clean(struct sctp_bind_addr *);
*/
int sctp_bind_addr_copy(struct sctp_bind_addr *dest,
const struct sctp_bind_addr *src,
+ struct net *net,
sctp_scope_t scope, gfp_t gfp,
int flags)
{
@@ -75,8 +77,8 @@ int sctp_bind_addr_copy(struct sctp_bind_addr *dest,
/* Extract the addresses which are relevant for this scope. */
list_for_each_entry(addr, &src->address_list, list) {
- error = sctp_copy_one_addr(dest, &addr->a, scope,
- gfp, flags);
+ error = sctp_copy_one_addr(dest, &addr->a, net,
+ scope, gfp, flags);
if (error < 0)
goto out;
}
@@ -87,7 +89,7 @@ int sctp_bind_addr_copy(struct sctp_bind_addr *dest,
*/
if (list_empty(&dest->address_list) && (SCTP_SCOPE_GLOBAL == scope)) {
list_for_each_entry(addr, &src->address_list, list) {
- error = sctp_copy_one_addr(dest, &addr->a,
+ error = sctp_copy_one_addr(dest, &addr->a, net,
SCTP_SCOPE_LINK, gfp,
flags);
if (error < 0)
@@ -450,14 +452,15 @@ union sctp_addr *sctp_find_unmatch_addr(struct sctp_bind_addr *bp,
/* Copy out addresses from the global local address list. */
static int sctp_copy_one_addr(struct sctp_bind_addr *dest,
union sctp_addr *addr,
+ struct net *net,
sctp_scope_t scope, gfp_t gfp,
int flags)
{
int error = 0;
if (sctp_is_any(NULL, addr)) {
- error = sctp_copy_local_addr_list(dest, scope, gfp, flags);
- } else if (sctp_in_scope(addr, scope)) {
+ error = sctp_copy_local_addr_list(dest, scope, gfp, flags, net);
+ } else if (sctp_in_scope(addr, scope, net)) {
/* Now that the address is in scope, check to see if
* the address type is supported by local sock as
* well as the remote peer.
@@ -494,9 +497,11 @@ int sctp_is_any(struct sock *sk, const union sctp_addr *addr)
}
/* Is 'addr' valid for 'scope'? */
-int sctp_in_scope(const union sctp_addr *addr, sctp_scope_t scope)
+int sctp_in_scope(const union sctp_addr *addr, sctp_scope_t scope,
+ struct net *net)
{
sctp_scope_t addr_scope = sctp_scope(addr);
+ struct sctp_net_params *net_params = sctp_get_params(net);
/* The unusable SCTP addresses will not be considered with
* any defined scopes.
@@ -512,7 +517,7 @@ int sctp_in_scope(const union sctp_addr *addr, sctp_scope_t scope)
* Address scoping can be selectively controlled via sysctl
* option
*/
- switch (sctp_scope_policy) {
+ switch (net_params->ipv4_scope_policy) {
case SCTP_SCOPE_POLICY_DISABLE:
return 1;
case SCTP_SCOPE_POLICY_ENABLE:
diff --git a/net/sctp/ipv6.c b/net/sctp/ipv6.c
index ed7139e..67cae63 100644
--- a/net/sctp/ipv6.c
+++ b/net/sctp/ipv6.c
@@ -88,7 +88,7 @@ static int sctp_v6_cmp_addr(const union sctp_addr *addr1,
const union sctp_addr *addr2);
/* Event handler for inet6 address addition/deletion events.
- * The sctp_local_addr_list needs to be protocted by a spin lock since
+ * The local_addr_list needs to be protocted by a spin lock since
* multiple notifiers (say IPv4 and IPv6) may be running at the same
* time and thus corrupt the list.
* The reader side is protected with RCU.
@@ -100,6 +100,8 @@ static int sctp_inet6addr_event(struct notifier_block *this, unsigned long ev,
struct sctp_sockaddr_entry *addr = NULL;
struct sctp_sockaddr_entry *temp;
int found = 0;
+ struct net *net = dev_net(ifa->idev->dev);
+ struct sctp_net_params *net_params = sctp_get_params(net);
switch (ev) {
case NETDEV_UP:
@@ -110,27 +112,28 @@ static int sctp_inet6addr_event(struct notifier_block *this, unsigned long ev,
addr->a.v6.sin6_addr = ifa->addr;
addr->a.v6.sin6_scope_id = ifa->idev->dev->ifindex;
addr->valid = 1;
- spin_lock_bh(&sctp_local_addr_lock);
- list_add_tail_rcu(&addr->list, &sctp_local_addr_list);
- sctp_addr_wq_mgmt(addr, SCTP_ADDR_NEW);
- spin_unlock_bh(&sctp_local_addr_lock);
+ spin_lock_bh(&net_params->addr_list_lock);
+ list_add_tail_rcu(&addr->list,
+ &net_params->local_addr_list);
+ sctp_addr_wq_mgmt(net, addr, SCTP_ADDR_NEW);
+ spin_unlock_bh(&net_params->addr_list_lock);
}
break;
case NETDEV_DOWN:
- spin_lock_bh(&sctp_local_addr_lock);
+ spin_lock_bh(&net_params->addr_list_lock);
list_for_each_entry_safe(addr, temp,
- &sctp_local_addr_list, list) {
+ &net_params->local_addr_list, list) {
if (addr->a.sa.sa_family == AF_INET6 &&
ipv6_addr_equal(&addr->a.v6.sin6_addr,
&ifa->addr)) {
- sctp_addr_wq_mgmt(addr, SCTP_ADDR_DEL);
+ sctp_addr_wq_mgmt(net, addr, SCTP_ADDR_DEL);
found = 1;
addr->valid = 0;
list_del_rcu(&addr->list);
break;
}
}
- spin_unlock_bh(&sctp_local_addr_lock);
+ spin_unlock_bh(&net_params->addr_list_lock);
if (found)
kfree_rcu(addr, rcu);
break;
@@ -252,8 +255,9 @@ static int sctp_v6_xmit(struct sk_buff *skb, struct sctp_transport *transport)
/* Returns the dst cache entry for the given source and destination ip
* addresses.
*/
-static void sctp_v6_get_dst(struct sctp_transport *t, union sctp_addr *saddr,
- struct flowi *fl, struct sock *sk)
+static void sctp_v6_get_dst(struct net *net, struct sctp_transport *t,
+ union sctp_addr *saddr, struct flowi *fl,
+ struct sock *sk)
{
struct sctp_association *asoc = t->asoc;
struct dst_entry *dst = NULL;
@@ -561,7 +565,8 @@ static int sctp_v6_is_any(const union sctp_addr *addr)
}
/* Should this be available for binding? */
-static int sctp_v6_available(union sctp_addr *addr, struct sctp_sock *sp)
+static int sctp_v6_available(struct net *net, union sctp_addr *addr,
+ struct sctp_sock *sp)
{
int type;
const struct in6_addr *in6 = (const struct in6_addr *)&addr->v6.sin6_addr;
@@ -575,12 +580,12 @@ static int sctp_v6_available(union sctp_addr *addr, struct sctp_sock *sp)
if (sp && ipv6_only_sock(sctp_opt2sk(sp)))
return 0;
sctp_v6_map_v4(addr);
- return sctp_get_af_specific(AF_INET)->available(addr, sp);
+ return sctp_get_af_specific(AF_INET)->available(net, addr, sp);
}
if (!(type & IPV6_ADDR_UNICAST))
return 0;
- return ipv6_chk_addr(&init_net, in6, NULL, 0);
+ return ipv6_chk_addr(net, in6, NULL, 0);
}
/* This function checks if the address is a valid address to be used for
@@ -845,7 +850,8 @@ static int sctp_inet6_cmp_addr(const union sctp_addr *addr1,
/* Verify that the provided sockaddr looks bindable. Common verification,
* has already been taken care of.
*/
-static int sctp_inet6_bind_verify(struct sctp_sock *opt, union sctp_addr *addr)
+static int sctp_inet6_bind_verify(struct net *net, struct sctp_sock *opt,
+ union sctp_addr *addr)
{
struct sctp_af *af;
@@ -860,10 +866,10 @@ static int sctp_inet6_bind_verify(struct sctp_sock *opt, union sctp_addr *addr)
if (!addr->v6.sin6_scope_id)
return 0;
rcu_read_lock();
- dev = dev_get_by_index_rcu(&init_net,
+ dev = dev_get_by_index_rcu(net,
addr->v6.sin6_scope_id);
if (!dev ||
- !ipv6_chk_addr(&init_net, &addr->v6.sin6_addr,
+ !ipv6_chk_addr(net, &addr->v6.sin6_addr,
dev, 0)) {
rcu_read_unlock();
return 0;
@@ -876,13 +882,14 @@ static int sctp_inet6_bind_verify(struct sctp_sock *opt, union sctp_addr *addr)
af = opt->pf->af;
}
- return af->available(addr, opt);
+ return af->available(net, addr, opt);
}
/* Verify that the provided sockaddr looks sendable. Common verification,
* has already been taken care of.
*/
-static int sctp_inet6_send_verify(struct sctp_sock *opt, union sctp_addr *addr)
+static int sctp_inet6_send_verify(struct net *net, struct sctp_sock *opt,
+ union sctp_addr *addr)
{
struct sctp_af *af = NULL;
@@ -897,7 +904,7 @@ static int sctp_inet6_send_verify(struct sctp_sock *opt, union sctp_addr *addr)
if (!addr->v6.sin6_scope_id)
return 0;
rcu_read_lock();
- dev = dev_get_by_index_rcu(&init_net,
+ dev = dev_get_by_index_rcu(net,
addr->v6.sin6_scope_id);
rcu_read_unlock();
if (!dev)
diff --git a/net/sctp/output.c b/net/sctp/output.c
index 838e18b..f9c5ffa 100644
--- a/net/sctp/output.c
+++ b/net/sctp/output.c
@@ -377,6 +377,7 @@ int sctp_packet_transmit(struct sctp_packet *packet)
struct sk_buff *nskb;
struct sctp_chunk *chunk, *tmp;
struct sock *sk;
+ struct net *net;
int err = 0;
int padding; /* How much padding do we need? */
__u8 has_data = 0;
@@ -393,6 +394,7 @@ int sctp_packet_transmit(struct sctp_packet *packet)
/* Set up convenience variables... */
chunk = list_entry(packet->chunk_list.next, struct sctp_chunk, list);
sk = chunk->skb->sk;
+ net = sock_net(sk);
/* Allocate the new skb. */
nskb = alloc_skb(packet->size + LL_MAX_HEADER, GFP_ATOMIC);
@@ -408,7 +410,7 @@ int sctp_packet_transmit(struct sctp_packet *packet)
skb_set_owner_w(nskb, sk);
if (!sctp_transport_dst_check(tp)) {
- sctp_transport_route(tp, NULL, sctp_sk(sk));
+ sctp_transport_route(net, tp, NULL, sctp_sk(sk));
if (asoc && (asoc->param_flags & SPP_PMTUD_ENABLE)) {
sctp_assoc_sync_pmtu(sk, asoc);
}
diff --git a/net/sctp/protocol.c b/net/sctp/protocol.c
index 28dbef2..dce07d6 100644
--- a/net/sctp/protocol.c
+++ b/net/sctp/protocol.c
@@ -196,29 +196,32 @@ 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(void)
+static void sctp_get_local_addr_list(struct net *net)
{
struct net_device *dev;
struct list_head *pos;
struct sctp_af *af;
+ struct sctp_net_params *net_params = sctp_get_params(net);
rcu_read_lock();
- for_each_netdev_rcu(&init_net, dev) {
+ for_each_netdev_rcu(net, dev) {
__list_for_each(pos, &sctp_address_families) {
af = list_entry(pos, struct sctp_af, list);
- af->copy_addrlist(&sctp_local_addr_list, dev);
+ af->copy_addrlist(&net_params->local_addr_list, dev);
}
}
rcu_read_unlock();
}
/* Free the existing local addresses. */
-static void sctp_free_local_addr_list(void)
+static void sctp_free_local_addr_list(struct net *net)
{
struct sctp_sockaddr_entry *addr;
struct list_head *pos, *temp;
+ struct sctp_net_params *net_params =
+ sctp_get_params(net);
- list_for_each_safe(pos, temp, &sctp_local_addr_list) {
+ list_for_each_safe(pos, temp, &net_params->local_addr_list) {
addr = list_entry(pos, struct sctp_sockaddr_entry, list);
list_del(pos);
kfree(addr);
@@ -227,16 +230,17 @@ static void sctp_free_local_addr_list(void)
/* Copy the local addresses which are valid for 'scope' into 'bp'. */
int sctp_copy_local_addr_list(struct sctp_bind_addr *bp, sctp_scope_t scope,
- gfp_t gfp, int copy_flags)
+ gfp_t gfp, int copy_flags, struct net *net)
{
struct sctp_sockaddr_entry *addr;
int error = 0;
+ struct sctp_net_params *net_params = sctp_get_params(net);
rcu_read_lock();
- list_for_each_entry_rcu(addr, &sctp_local_addr_list, list) {
+ list_for_each_entry_rcu(addr, &net_params->local_addr_list, list) {
if (!addr->valid)
continue;
- if (sctp_in_scope(&addr->a, scope)) {
+ if (sctp_in_scope(&addr->a, scope, net)) {
/* Now that the address is in scope, check to see if
* the address type is really supported by the local
* sock as well as the remote peer.
@@ -389,11 +393,15 @@ static int sctp_v4_addr_valid(union sctp_addr *addr,
return 1;
}
-/* Should this be available for binding? */
-static int sctp_v4_available(union sctp_addr *addr, struct sctp_sock *sp)
+/* Should this be available for binding?
+ * Note that we could derive struct net *net from the sctp_sock *sp,
+ * but the IPv6 version of this code doesn't have the same information
+ * in the last argument.
+ */
+static int sctp_v4_available(struct net *net, union sctp_addr *addr,
+ struct sctp_sock *sp)
{
- int ret = inet_addr_type(&init_net, addr->v4.sin_addr.s_addr);
-
+ int ret = inet_addr_type(net, addr->v4.sin_addr.s_addr);
if (addr->v4.sin_addr.s_addr != htonl(INADDR_ANY) &&
ret != RTN_LOCAL &&
@@ -450,8 +458,9 @@ static sctp_scope_t sctp_v4_scope(union sctp_addr *addr)
* addresses. If an association is passed, trys to get a dst entry with a
* source address that matches an address in the bind address list.
*/
-static void sctp_v4_get_dst(struct sctp_transport *t, union sctp_addr *saddr,
- struct flowi *fl, struct sock *sk)
+static void sctp_v4_get_dst(struct net *net, struct sctp_transport *t,
+ union sctp_addr *saddr, struct flowi *fl,
+ struct sock *sk)
{
struct sctp_association *asoc = t->asoc;
struct rtable *rt;
@@ -479,7 +488,7 @@ static void sctp_v4_get_dst(struct sctp_transport *t, union sctp_addr *saddr,
SCTP_DEBUG_PRINTK("%s: DST:%pI4, SRC:%pI4 - ",
__func__, &fl4->daddr, &fl4->saddr);
- rt = ip_route_output_key(&init_net, fl4);
+ rt = ip_route_output_key(net, fl4);
if (!IS_ERR(rt))
dst = &rt->dst;
@@ -525,7 +534,7 @@ static void sctp_v4_get_dst(struct sctp_transport *t, union sctp_addr *saddr,
(AF_INET == laddr->a.sa.sa_family)) {
fl4->saddr = laddr->a.v4.sin_addr.s_addr;
fl4->fl4_sport = laddr->a.v4.sin_port;
- rt = ip_route_output_key(&init_net, fl4);
+ rt = ip_route_output_key(sock_net(asoc->base.sk), fl4);
if (!IS_ERR(rt)) {
dst = &rt->dst;
goto out_unlock;
@@ -624,13 +633,15 @@ void sctp_addr_wq_timeout_handler(unsigned long arg)
{
struct sctp_sockaddr_entry *addrw, *temp;
struct sctp_sock *sp;
+ struct net *net = (struct net *)arg;
+ struct sctp_net_params *net_params = sctp_get_params(net);
- spin_lock_bh(&sctp_addr_wq_lock);
+ spin_lock_bh(&net_params->addr_wq_lock);
- list_for_each_entry_safe(addrw, temp, &sctp_addr_waitq, list) {
+ list_for_each_entry_safe(addrw, temp, &net_params->addr_waitq, list) {
SCTP_DEBUG_PRINTK_IPADDR("sctp_addrwq_timo_handler: the first ent in wq %p is ",
- " for cmd %d at entry %p\n", &sctp_addr_waitq, &addrw->a, addrw->state,
- addrw);
+ " for cmd %d at entry %p\n", &net_params->addr_waitq,
+ &addrw->a, addrw->state, addrw);
#if IS_ENABLED(CONFIG_IPV6)
/* Now we send an ASCONF for each association */
@@ -643,7 +654,7 @@ void sctp_addr_wq_timeout_handler(unsigned long arg)
goto free_next;
in6 = (struct in6_addr *)&addrw->a.v6.sin6_addr;
- if (ipv6_chk_addr(&init_net, in6, NULL, 0) == 0 &&
+ if (ipv6_chk_addr(net, in6, NULL, 0) == 0 &&
addrw->state == SCTP_ADDR_NEW) {
unsigned long timeo_val;
@@ -651,7 +662,8 @@ void sctp_addr_wq_timeout_handler(unsigned long arg)
SCTP_ADDRESS_TICK_DELAY);
timeo_val = jiffies;
timeo_val += msecs_to_jiffies(SCTP_ADDRESS_TICK_DELAY);
- mod_timer(&sctp_addr_wq_timer, timeo_val);
+ mod_timer(&net_params->addr_wq_timer,
+ timeo_val);
break;
}
}
@@ -664,7 +676,7 @@ void sctp_addr_wq_timeout_handler(unsigned long arg)
if (!sctp_is_ep_boundall(sk))
continue;
sctp_bh_lock_sock(sk);
- if (sctp_asconf_mgmt(sp, addrw) < 0)
+ if (sctp_asconf_mgmt(net, sp, addrw) < 0)
SCTP_DEBUG_PRINTK("sctp_addrwq_timo_handler: sctp_asconf_mgmt failed\n");
sctp_bh_unlock_sock(sk);
}
@@ -674,31 +686,35 @@ free_next:
list_del(&addrw->list);
kfree(addrw);
}
- spin_unlock_bh(&sctp_addr_wq_lock);
+ spin_unlock_bh(&net_params->addr_wq_lock);
}
-static void sctp_free_addr_wq(void)
+static void sctp_free_addr_wq(struct net *net)
{
struct sctp_sockaddr_entry *addrw;
struct sctp_sockaddr_entry *temp;
+ struct sctp_net_params *net_params = sctp_get_params(net);
- spin_lock_bh(&sctp_addr_wq_lock);
- del_timer(&sctp_addr_wq_timer);
- list_for_each_entry_safe(addrw, temp, &sctp_addr_waitq, list) {
+ spin_lock_bh(&net_params->addr_wq_lock);
+ del_timer(&net_params->addr_wq_timer);
+ list_for_each_entry_safe(addrw, temp, &net_params->addr_waitq, list) {
list_del(&addrw->list);
kfree(addrw);
}
- spin_unlock_bh(&sctp_addr_wq_lock);
+ spin_unlock_bh(&net_params->addr_wq_lock);
}
/* lookup the entry for the same address in the addr_waitq
* sctp_addr_wq MUST be locked
*/
-static struct sctp_sockaddr_entry *sctp_addr_wq_lookup(struct sctp_sockaddr_entry *addr)
+static struct sctp_sockaddr_entry *sctp_addr_wq_lookup(
+ struct net *net,
+ struct sctp_sockaddr_entry *addr)
{
struct sctp_sockaddr_entry *addrw;
+ struct sctp_net_params *net_params = sctp_get_params(net);
- list_for_each_entry(addrw, &sctp_addr_waitq, list) {
+ list_for_each_entry(addrw, &net_params->addr_waitq, list) {
if (addrw->a.sa.sa_family != addr->a.sa.sa_family)
continue;
if (addrw->a.sa.sa_family == AF_INET) {
@@ -714,10 +730,12 @@ static struct sctp_sockaddr_entry *sctp_addr_wq_lookup(struct sctp_sockaddr_entr
return NULL;
}
-void sctp_addr_wq_mgmt(struct sctp_sockaddr_entry *addr, int cmd)
+void sctp_addr_wq_mgmt(struct net *net, struct sctp_sockaddr_entry *addr,
+ int cmd)
{
struct sctp_sockaddr_entry *addrw;
unsigned long timeo_val;
+ struct sctp_net_params *net_params = sctp_get_params(net);
/* first, we check if an opposite message already exist in the queue.
* If we found such message, it is removed.
@@ -725,38 +743,38 @@ void sctp_addr_wq_mgmt(struct sctp_sockaddr_entry *addr, int cmd)
* new address after a couple of addition and deletion of that address
*/
- spin_lock_bh(&sctp_addr_wq_lock);
+ spin_lock_bh(&net_params->addr_wq_lock);
/* Offsets existing events in addr_wq */
- addrw = sctp_addr_wq_lookup(addr);
+ addrw = sctp_addr_wq_lookup(net, addr);
if (addrw) {
if (addrw->state != cmd) {
SCTP_DEBUG_PRINTK_IPADDR("sctp_addr_wq_mgmt offsets existing entry for %d ",
" in wq %p\n", addrw->state, &addrw->a,
- &sctp_addr_waitq);
+ &net_params->addr_waitq);
list_del(&addrw->list);
kfree(addrw);
}
- spin_unlock_bh(&sctp_addr_wq_lock);
+ spin_unlock_bh(&net_params->addr_wq_lock);
return;
}
/* OK, we have to add the new address to the wait queue */
addrw = kmemdup(addr, sizeof(struct sctp_sockaddr_entry), GFP_ATOMIC);
if (addrw == NULL) {
- spin_unlock_bh(&sctp_addr_wq_lock);
+ spin_unlock_bh(&net_params->addr_wq_lock);
return;
}
addrw->state = cmd;
- list_add_tail(&addrw->list, &sctp_addr_waitq);
+ list_add_tail(&addrw->list, &net_params->addr_waitq);
SCTP_DEBUG_PRINTK_IPADDR("sctp_addr_wq_mgmt add new entry for cmd:%d ",
- " in wq %p\n", addrw->state, &addrw->a, &sctp_addr_waitq);
+ " in wq %p\n", addrw->state, &addrw->a, &net_params->addr_waitq);
- if (!timer_pending(&sctp_addr_wq_timer)) {
+ if (!timer_pending(&net_params->addr_wq_timer)) {
timeo_val = jiffies;
timeo_val += msecs_to_jiffies(SCTP_ADDRESS_TICK_DELAY);
- mod_timer(&sctp_addr_wq_timer, timeo_val);
+ mod_timer(&net_params->addr_wq_timer, timeo_val);
}
- spin_unlock_bh(&sctp_addr_wq_lock);
+ spin_unlock_bh(&net_params->addr_wq_lock);
}
/* Event handler for inet address addition/deletion events.
@@ -772,9 +790,8 @@ static int sctp_inetaddr_event(struct notifier_block *this, unsigned long ev,
struct sctp_sockaddr_entry *addr = NULL;
struct sctp_sockaddr_entry *temp;
int found = 0;
-
- if (!net_eq(dev_net(ifa->ifa_dev->dev), &init_net))
- return NOTIFY_DONE;
+ struct net *net = dev_net(ifa->ifa_dev->dev);
+ struct sctp_net_params *net_params = sctp_get_params(net);
switch (ev) {
case NETDEV_UP:
@@ -784,27 +801,28 @@ static int sctp_inetaddr_event(struct notifier_block *this, unsigned long ev,
addr->a.v4.sin_port = 0;
addr->a.v4.sin_addr.s_addr = ifa->ifa_local;
addr->valid = 1;
- spin_lock_bh(&sctp_local_addr_lock);
- list_add_tail_rcu(&addr->list, &sctp_local_addr_list);
- sctp_addr_wq_mgmt(addr, SCTP_ADDR_NEW);
- spin_unlock_bh(&sctp_local_addr_lock);
+ spin_lock_bh(&net_params->addr_list_lock);
+ list_add_tail_rcu(&addr->list,
+ &net_params->local_addr_list);
+ sctp_addr_wq_mgmt(net, addr, SCTP_ADDR_NEW);
+ spin_unlock_bh(&net_params->addr_list_lock);
}
break;
case NETDEV_DOWN:
- spin_lock_bh(&sctp_local_addr_lock);
+ spin_lock_bh(&net_params->addr_list_lock);
list_for_each_entry_safe(addr, temp,
- &sctp_local_addr_list, list) {
+ &net_params->local_addr_list, list) {
if (addr->a.sa.sa_family == AF_INET &&
addr->a.v4.sin_addr.s_addr ==
ifa->ifa_local) {
- sctp_addr_wq_mgmt(addr, SCTP_ADDR_DEL);
+ sctp_addr_wq_mgmt(net, addr, SCTP_ADDR_DEL);
found = 1;
addr->valid = 0;
list_del_rcu(&addr->list);
break;
}
}
- spin_unlock_bh(&sctp_local_addr_lock);
+ spin_unlock_bh(&net_params->addr_list_lock);
if (found)
kfree_rcu(addr, rcu);
break;
@@ -955,15 +973,17 @@ static int sctp_inet_cmp_addr(const union sctp_addr *addr1,
/* Verify that provided sockaddr looks bindable. Common verification has
* already been taken care of.
*/
-static int sctp_inet_bind_verify(struct sctp_sock *opt, union sctp_addr *addr)
+static int sctp_inet_bind_verify(struct net *net, struct sctp_sock *opt,
+ union sctp_addr *addr)
{
- return sctp_v4_available(addr, opt);
+ return sctp_v4_available(net, addr, opt);
}
/* Verify that sockaddr looks sendable. Common verification has already
* been taken care of.
*/
-static int sctp_inet_send_verify(struct sctp_sock *opt, union sctp_addr *addr)
+static int sctp_inet_send_verify(struct net *net, struct sctp_sock *opt,
+ union sctp_addr *addr)
{
return 1;
}
@@ -1562,6 +1582,8 @@ static int __net_init sctp_net_init(struct net *net)
if (err)
goto err_param_init;
+ sctp_get_local_addr_list(net);
+ goto out;
err_param_init:
sctp_proc_exit(net);
err_proc_init:
@@ -1572,7 +1594,12 @@ out:
static void __net_exit sctp_net_exit(struct net *net)
{
+ sctp_free_addr_wq(net);
+ /* Free the control sock */
sctp_ctl_sock_destroy(net);
+ /* Free the local address list. */
+ sctp_free_local_addr_list(net);
+ /* Clean up procfs */
sctp_proc_exit(net);
}
@@ -1623,17 +1650,7 @@ SCTP_STATIC __init int sctp_init(void)
sctp_v4_pf_init();
sctp_v6_pf_init();
- /* Initialize the local address list. */
- INIT_LIST_HEAD(&sctp_local_addr_list);
- spin_lock_init(&sctp_local_addr_lock);
- sctp_get_local_addr_list();
- /* Initialize the address event list */
- INIT_LIST_HEAD(&sctp_addr_waitq);
- INIT_LIST_HEAD(&sctp_auto_asconf_splist);
- spin_lock_init(&sctp_addr_wq_lock);
- sctp_addr_wq_timer.expires = 0;
- setup_timer(&sctp_addr_wq_timer, sctp_addr_wq_timeout_handler, 0);
/* Register SCTP protocol */
status = sctp_v4_protosw_init();
@@ -1689,7 +1706,6 @@ err_add_protocol:
err_v6_protosw_init:
sctp_v4_protosw_exit();
err_protosw_init:
- sctp_free_local_addr_list();
sctp_v6_pf_exit();
sctp_v4_pf_exit();
sctp_hashtable_globals_free();
@@ -1710,15 +1726,11 @@ SCTP_STATIC __exit void sctp_exit(void)
/* Unregister with inet6/inet layers. */
sctp_v6_del_protocol();
sctp_v4_del_protocol();
- sctp_free_addr_wq();
/* Free protosw registrations */
sctp_v6_protosw_exit();
sctp_v4_protosw_exit();
- /* Free the local address list. */
- sctp_free_local_addr_list();
-
/* Unregister with socket layer. */
sctp_v6_pf_exit();
sctp_v4_pf_exit();
diff --git a/net/sctp/sm_make_chunk.c b/net/sctp/sm_make_chunk.c
index 479a70e..af02b44 100644
--- a/net/sctp/sm_make_chunk.c
+++ b/net/sctp/sm_make_chunk.c
@@ -79,6 +79,7 @@ static sctp_cookie_param_t *sctp_pack_cookie(const struct sctp_endpoint *ep,
static int sctp_process_param(struct sctp_association *asoc,
union sctp_params param,
const union sctp_addr *peer_addr,
+ struct net *net,
gfp_t gfp);
static void *sctp_addto_param(struct sctp_chunk *chunk, int len,
const void *data);
@@ -2268,7 +2269,7 @@ int sctp_verify_init(const struct sctp_association *asoc,
*/
int sctp_process_init(struct sctp_association *asoc, struct sctp_chunk *chunk,
const union sctp_addr *peer_addr,
- sctp_init_chunk_t *peer_init, gfp_t gfp)
+ sctp_init_chunk_t *peer_init, struct net *net, gfp_t gfp)
{
union sctp_params param;
struct sctp_transport *transport;
@@ -2305,7 +2306,7 @@ int sctp_process_init(struct sctp_association *asoc, struct sctp_chunk *chunk,
src_match = 1;
}
- if (!sctp_process_param(asoc, param, peer_addr, gfp))
+ if (!sctp_process_param(asoc, param, peer_addr, net, gfp))
goto clean_up;
}
@@ -2464,6 +2465,7 @@ nomem:
static int sctp_process_param(struct sctp_association *asoc,
union sctp_params param,
const union sctp_addr *peer_addr,
+ struct net *net,
gfp_t gfp)
{
union sctp_addr addr;
@@ -2494,7 +2496,7 @@ do_addr_param:
af = sctp_get_af_specific(param_type2af(param.p->type));
af->from_addr_param(&addr, param.addr, htons(asoc->peer.port), 0);
scope = sctp_scope(peer_addr);
- if (sctp_in_scope(&addr, scope))
+ if (sctp_in_scope(&addr, scope, net))
if (!sctp_assoc_add_peer(asoc, &addr, gfp, SCTP_UNCONFIRMED))
return 0;
break;
diff --git a/net/sctp/sm_sideeffect.c b/net/sctp/sm_sideeffect.c
index fe99628..8fe4a25 100644
--- a/net/sctp/sm_sideeffect.c
+++ b/net/sctp/sm_sideeffect.c
@@ -615,7 +615,8 @@ static int sctp_cmd_process_init(sctp_cmd_seq_t *commands,
* fail during INIT processing (due to malloc problems),
* just return the error and stop processing the stack.
*/
- if (!sctp_process_init(asoc, chunk, sctp_source(chunk), peer_init, gfp))
+ if (!sctp_process_init(asoc, chunk, sctp_source(chunk), peer_init,
+ &init_net, gfp))
error = -ENOMEM;
else
error = 0;
diff --git a/net/sctp/sm_statefuns.c b/net/sctp/sm_statefuns.c
index 91dcdd6..85a46ac 100644
--- a/net/sctp/sm_statefuns.c
+++ b/net/sctp/sm_statefuns.c
@@ -388,6 +388,7 @@ sctp_disposition_t sctp_sf_do_5_1B_init(const struct sctp_endpoint *ep,
goto nomem;
if (sctp_assoc_set_bind_addr_from_ep(new_asoc,
+ &init_net,
sctp_scope(sctp_source(chunk)),
GFP_ATOMIC) < 0)
goto nomem_init;
@@ -395,7 +396,7 @@ sctp_disposition_t sctp_sf_do_5_1B_init(const struct sctp_endpoint *ep,
/* The call, sctp_process_init(), can fail on memory allocation. */
if (!sctp_process_init(new_asoc, chunk, sctp_source(chunk),
(sctp_init_chunk_t *)chunk->chunk_hdr,
- GFP_ATOMIC))
+ &init_net, GFP_ATOMIC))
goto nomem_init;
/* B) "Z" shall respond immediately with an INIT ACK chunk. */
@@ -726,7 +727,7 @@ sctp_disposition_t sctp_sf_do_5_1D_ce(const struct sctp_endpoint *ep,
if (!sctp_process_init(new_asoc, chunk,
&chunk->subh.cookie_hdr->c.peer_addr,
- peer_init, GFP_ATOMIC))
+ peer_init, &init_net, GFP_ATOMIC))
goto nomem_init;
/* SCTP-AUTH: Now that we've populate required fields in
@@ -1444,7 +1445,7 @@ static sctp_disposition_t sctp_sf_do_unexpected_init(
if (!new_asoc)
goto nomem;
- if (sctp_assoc_set_bind_addr_from_ep(new_asoc,
+ if (sctp_assoc_set_bind_addr_from_ep(new_asoc, &init_net,
sctp_scope(sctp_source(chunk)), GFP_ATOMIC) < 0)
goto nomem;
@@ -1454,7 +1455,7 @@ static sctp_disposition_t sctp_sf_do_unexpected_init(
*/
if (!sctp_process_init(new_asoc, chunk, sctp_source(chunk),
(sctp_init_chunk_t *)chunk->chunk_hdr,
- GFP_ATOMIC))
+ &init_net, GFP_ATOMIC))
goto nomem;
/* Make sure no new addresses are being added during the
@@ -1682,7 +1683,7 @@ static sctp_disposition_t sctp_sf_do_dupcook_a(const struct sctp_endpoint *ep,
peer_init = &chunk->subh.cookie_hdr->c.peer_init[0];
if (!sctp_process_init(new_asoc, chunk, sctp_source(chunk), peer_init,
- GFP_ATOMIC))
+ &init_net, GFP_ATOMIC))
goto nomem;
/* Make sure no new addresses are being added during the
@@ -1777,7 +1778,7 @@ static sctp_disposition_t sctp_sf_do_dupcook_b(const struct sctp_endpoint *ep,
*/
peer_init = &chunk->subh.cookie_hdr->c.peer_init[0];
if (!sctp_process_init(new_asoc, chunk, sctp_source(chunk), peer_init,
- GFP_ATOMIC))
+ &init_net, GFP_ATOMIC))
goto nomem;
/* Update the content of current association. */
@@ -5918,7 +5919,8 @@ static struct sctp_packet *sctp_ootb_pkt_new(const struct sctp_association *asoc
/* Cache a route for the transport with the chunk's destination as
* the source address.
*/
- sctp_transport_route(transport, (union sctp_addr *)&chunk->dest,
+ sctp_transport_route(&init_net, transport,
+ (union sctp_addr *)&chunk->dest,
sctp_sk(*sctp_get_ctl_sock(&init_net)));
packet = sctp_packet_init(&transport->packet, transport, sport, dport);
diff --git a/net/sctp/socket.c b/net/sctp/socket.c
index 5e25981..790e597 100644
--- a/net/sctp/socket.c
+++ b/net/sctp/socket.c
@@ -101,8 +101,10 @@ static struct sctp_af *sctp_sockaddr_af(struct sctp_sock *opt,
union sctp_addr *addr, int len);
static int sctp_bindx_add(struct sock *, struct sockaddr *, int);
static int sctp_bindx_rem(struct sock *, struct sockaddr *, int);
-static int sctp_send_asconf_add_ip(struct sock *, struct sockaddr *, int);
-static int sctp_send_asconf_del_ip(struct sock *, struct sockaddr *, int);
+static int sctp_send_asconf_add_ip(struct net*, struct sock *,
+ struct sockaddr *, int);
+static int sctp_send_asconf_del_ip(struct net*, struct sock *,
+ struct sockaddr *, int);
static int sctp_send_asconf(struct sctp_association *asoc,
struct sctp_chunk *chunk);
static int sctp_do_bind(struct sock *, union sctp_addr *, int);
@@ -197,7 +199,7 @@ static inline int sctp_verify_addr(struct sock *sk, union sctp_addr *addr,
if (!af->addr_valid(addr, sctp_sk(sk), NULL))
return -EINVAL;
- if (!sctp_sk(sk)->pf->send_verify(sctp_sk(sk), (addr)))
+ if (!sctp_sk(sk)->pf->send_verify(sock_net(sk), sctp_sk(sk), (addr)))
return -EINVAL;
return 0;
@@ -360,7 +362,7 @@ SCTP_STATIC int sctp_do_bind(struct sock *sk, union sctp_addr *addr, int len)
len);
/* PF specific bind() address verification. */
- if (!sp->pf->bind_verify(sp, addr))
+ if (!sp->pf->bind_verify(sock_net(sk), sp, addr))
return -EADDRNOTAVAIL;
/* We must either be unbound, or bind to the same port.
@@ -511,7 +513,8 @@ err_bindx_add:
*
* Only sctp_setsockopt_bindx() is supposed to call this function.
*/
-static int sctp_send_asconf_add_ip(struct sock *sk,
+static int sctp_send_asconf_add_ip(struct net *net,
+ struct sock *sk,
struct sockaddr *addrs,
int addrcnt)
{
@@ -608,7 +611,7 @@ static int sctp_send_asconf_add_ip(struct sock *sk,
trans->ssthresh = asoc->peer.i.a_rwnd;
trans->rto = asoc->rto_initial;
trans->rtt = trans->srtt = trans->rttvar = 0;
- sctp_transport_route(trans, NULL,
+ sctp_transport_route(net, trans, NULL,
sctp_sk(asoc->base.sk));
}
}
@@ -713,7 +716,8 @@ err_bindx_rem:
*
* Only sctp_setsockopt_bindx() is supposed to call this function.
*/
-static int sctp_send_asconf_del_ip(struct sock *sk,
+static int sctp_send_asconf_del_ip(struct net *net,
+ struct sock *sk,
struct sockaddr *addrs,
int addrcnt)
{
@@ -847,7 +851,7 @@ skip_mkasconf:
list_for_each_entry(transport, &asoc->peer.transport_addr_list,
transports) {
dst_release(transport->dst);
- sctp_transport_route(transport, NULL,
+ sctp_transport_route(net, transport, NULL,
sctp_sk(asoc->base.sk));
}
@@ -861,7 +865,8 @@ out:
}
/* set addr events to assocs in the endpoint. ep and addr_wq must be locked */
-int sctp_asconf_mgmt(struct sctp_sock *sp, struct sctp_sockaddr_entry *addrw)
+int sctp_asconf_mgmt(struct net *net, struct sctp_sock *sp,
+ struct sctp_sockaddr_entry *addrw)
{
struct sock *sk = sctp_opt2sk(sp);
union sctp_addr *addr;
@@ -877,9 +882,11 @@ int sctp_asconf_mgmt(struct sctp_sock *sp, struct sctp_sockaddr_entry *addrw)
return -EINVAL;
if (addrw->state == SCTP_ADDR_NEW)
- return sctp_send_asconf_add_ip(sk, (struct sockaddr *)addr, 1);
+ return sctp_send_asconf_add_ip(net, sk,
+ (struct sockaddr *)addr, 1);
else
- return sctp_send_asconf_del_ip(sk, (struct sockaddr *)addr, 1);
+ return sctp_send_asconf_del_ip(net, sk,
+ (struct sockaddr *)addr, 1);
}
/* Helper for tunneling sctp_bindx() requests through sctp_setsockopt()
@@ -969,6 +976,7 @@ SCTP_STATIC int sctp_setsockopt_bindx(struct sock* sk,
struct sockaddr *sa_addr;
void *addr_buf;
struct sctp_af *af;
+ struct net *net = sock_net(sk);
SCTP_DEBUG_PRINTK("sctp_setsocktopt_bindx: sk %p addrs %p"
" addrs_size %d opt %d\n", sk, addrs, addrs_size, op);
@@ -1019,14 +1027,14 @@ SCTP_STATIC int sctp_setsockopt_bindx(struct sock* sk,
err = sctp_bindx_add(sk, kaddrs, addrcnt);
if (err)
goto out;
- err = sctp_send_asconf_add_ip(sk, kaddrs, addrcnt);
+ err = sctp_send_asconf_add_ip(net, sk, kaddrs, addrcnt);
break;
case SCTP_BINDX_REM_ADDR:
err = sctp_bindx_rem(sk, kaddrs, addrcnt);
if (err)
goto out;
- err = sctp_send_asconf_del_ip(sk, kaddrs, addrcnt);
+ err = sctp_send_asconf_del_ip(net, sk, kaddrs, addrcnt);
break;
default:
@@ -1170,8 +1178,9 @@ static int __sctp_connect(struct sock* sk,
goto out_free;
}
- err = sctp_assoc_set_bind_addr_from_ep(asoc, scope,
- GFP_KERNEL);
+ err = sctp_assoc_set_bind_addr_from_ep(asoc,
+ sock_net(sk),
+ scope, GFP_KERNEL);
if (err < 0) {
goto out_free;
}
@@ -1797,7 +1806,8 @@ SCTP_STATIC int sctp_sendmsg(struct kiocb *iocb, struct sock *sk,
goto out_unlock;
}
asoc = new_asoc;
- err = sctp_assoc_set_bind_addr_from_ep(asoc, scope, GFP_KERNEL);
+ err = sctp_assoc_set_bind_addr_from_ep(asoc, sock_net(sk),
+ scope, GFP_KERNEL);
if (err < 0) {
err = -ENOMEM;
goto out_free;
@@ -2309,7 +2319,8 @@ static int sctp_setsockopt_autoclose(struct sock *sk, char __user *optval,
* SPP_SACKDELAY_ENABLE, setting both will have undefined
* results.
*/
-static int sctp_apply_peer_addr_params(struct sctp_paddrparams *params,
+static int sctp_apply_peer_addr_params(struct net *net,
+ struct sctp_paddrparams *params,
struct sctp_transport *trans,
struct sctp_association *asoc,
struct sctp_sock *sp,
@@ -2389,7 +2400,8 @@ static int sctp_apply_peer_addr_params(struct sctp_paddrparams *params,
trans->param_flags =
(trans->param_flags & ~SPP_PMTUD) | pmtud_change;
if (update) {
- sctp_transport_pmtu(trans, sctp_opt2sk(sp));
+ sctp_transport_pmtu(net, trans,
+ sctp_opt2sk(sp));
sctp_assoc_sync_pmtu(sctp_opt2sk(sp), asoc);
}
} else if (asoc) {
@@ -2457,6 +2469,7 @@ static int sctp_setsockopt_peer_addr_params(struct sock *sk,
struct sctp_transport *trans = NULL;
struct sctp_association *asoc = NULL;
struct sctp_sock *sp = sctp_sk(sk);
+ struct net *net = sock_net(sk);
int error;
int hb_change, pmtud_change, sackdelay_change;
@@ -2504,7 +2517,7 @@ static int sctp_setsockopt_peer_addr_params(struct sock *sk,
return -EINVAL;
/* Process parameters. */
- error = sctp_apply_peer_addr_params(¶ms, trans, asoc, sp,
+ error = sctp_apply_peer_addr_params(net, ¶ms, trans, asoc, sp,
hb_change, pmtud_change,
sackdelay_change);
@@ -2517,8 +2530,8 @@ static int sctp_setsockopt_peer_addr_params(struct sock *sk,
if (!trans && asoc) {
list_for_each_entry(trans, &asoc->peer.transport_addr_list,
transports) {
- sctp_apply_peer_addr_params(¶ms, trans, asoc, sp,
- hb_change, pmtud_change,
+ sctp_apply_peer_addr_params(net, ¶ms, trans, asoc,
+ sp, hb_change, pmtud_change,
sackdelay_change);
}
}
@@ -4653,9 +4666,11 @@ 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, &sctp_local_addr_list, list) {
+ list_for_each_entry_rcu(addr, &net_params->local_addr_list, list) {
if (!addr->valid)
continue;
diff --git a/net/sctp/transport.c b/net/sctp/transport.c
index c97472b..856ba86 100644
--- a/net/sctp/transport.c
+++ b/net/sctp/transport.c
@@ -214,12 +214,14 @@ void sctp_transport_set_owner(struct sctp_transport *transport,
}
/* Initialize the pmtu of a transport. */
-void sctp_transport_pmtu(struct sctp_transport *transport, struct sock *sk)
+void sctp_transport_pmtu(struct net *net, struct sctp_transport *transport,
+ struct sock *sk)
{
/* If we don't have a fresh route, look one up */
if (!transport->dst || transport->dst->obsolete) {
dst_release(transport->dst);
- transport->af_specific->get_dst(transport, &transport->saddr,
+ transport->af_specific->get_dst(net, transport,
+ &transport->saddr,
&transport->fl, sk);
}
@@ -247,27 +249,28 @@ void sctp_transport_update_pmtu(struct sock *sk, struct sctp_transport *t, u32 p
dst = sctp_transport_dst_check(t);
if (!dst)
- t->af_specific->get_dst(t, &t->saddr, &t->fl, sk);
+ t->af_specific->get_dst(sock_net(sk), t, &t->saddr, &t->fl, sk);
if (dst) {
dst->ops->update_pmtu(dst, sk, NULL, pmtu);
dst = sctp_transport_dst_check(t);
if (!dst)
- t->af_specific->get_dst(t, &t->saddr, &t->fl, sk);
+ t->af_specific->get_dst(sock_net(sk), t, &t->saddr,
+ &t->fl, sk);
}
}
/* Caches the dst entry and source address for a transport's destination
* address.
*/
-void sctp_transport_route(struct sctp_transport *transport,
+void sctp_transport_route(struct net *net, struct sctp_transport *transport,
union sctp_addr *saddr, struct sctp_sock *opt)
{
struct sctp_association *asoc = transport->asoc;
struct sctp_af *af = transport->af_specific;
- af->get_dst(transport, saddr, &transport->fl, sctp_opt2sk(opt));
+ af->get_dst(net, transport, saddr, &transport->fl, sctp_opt2sk(opt));
if (saddr)
memcpy(&transport->saddr, saddr, sizeof(union sctp_addr));
--
1.7.9.5
^ permalink raw reply related
* [PATCH 03/13] SCTP: These changes register procfs for netns.
From: Jan Ariyasu @ 2012-08-04 21:32 UTC (permalink / raw)
To: Vlad Yasevich, David S. Miller, linux-sctp, netdev, linux-kernel
Cc: Jan Ariyasu
Modified proc to initialization to be namespace compatible.
Signed-off-by: Jan Ariyasu <jan.ariyasu@hp.com>
---
include/net/sctp/sctp.h | 17 +++++-----
net/sctp/objcnt.c | 8 ++---
net/sctp/proc.c | 77 +++++++++++++++++++++++++-------------------
net/sctp/protocol.c | 81 +++++++++++++++++++++++------------------------
4 files changed, 97 insertions(+), 86 deletions(-)
diff --git a/include/net/sctp/sctp.h b/include/net/sctp/sctp.h
index c2dfeea..97ba550 100644
--- a/include/net/sctp/sctp.h
+++ b/include/net/sctp/sctp.h
@@ -177,14 +177,14 @@ void sctp_backlog_migrate(struct sctp_association *assoc,
/*
* sctp/proc.c
*/
-int sctp_snmp_proc_init(void);
-void sctp_snmp_proc_exit(void);
-int sctp_eps_proc_init(void);
-void sctp_eps_proc_exit(void);
-int sctp_assocs_proc_init(void);
-void sctp_assocs_proc_exit(void);
-int sctp_remaddr_proc_init(void);
-void sctp_remaddr_proc_exit(void);
+int sctp_snmp_proc_init(struct net *);
+void sctp_snmp_proc_exit(struct net *);
+int sctp_eps_proc_init(struct net *);
+void sctp_eps_proc_exit(struct net *);
+int sctp_assocs_proc_init(struct net *);
+void sctp_assocs_proc_exit(struct net *);
+int sctp_remaddr_proc_init(struct net *);
+void sctp_remaddr_proc_exit(struct net *);
/*
@@ -590,7 +590,6 @@ for (pos = chunk->subh.fwdtsn_hdr->skip;\
extern struct proto sctp_prot;
extern struct proto sctpv6_prot;
-extern struct proc_dir_entry *proc_net_sctp;
void sctp_put_port(struct sock *sk);
extern struct idr sctp_assocs_id;
diff --git a/net/sctp/objcnt.c b/net/sctp/objcnt.c
index 8ef8e7d..42fa43a 100644
--- a/net/sctp/objcnt.c
+++ b/net/sctp/objcnt.c
@@ -132,9 +132,10 @@ static const struct file_operations sctp_objcnt_ops = {
void sctp_dbg_objcnt_init(void)
{
struct proc_dir_entry *ent;
+ struct sctp_ns_globals *ns_globals = sctp_get_ns_globals(&init_net);
ent = proc_create("sctp_dbg_objcnt", 0,
- proc_net_sctp, &sctp_objcnt_ops);
+ ns_globals->sctp_proc_dir, &sctp_objcnt_ops);
if (!ent)
pr_warn("sctp_dbg_objcnt: Unable to create /proc entry.\n");
}
@@ -142,7 +143,6 @@ void sctp_dbg_objcnt_init(void)
/* Cleanup the objcount entry in the proc filesystem. */
void sctp_dbg_objcnt_exit(void)
{
- remove_proc_entry("sctp_dbg_objcnt", proc_net_sctp);
+ struct sctp_ns_globals *ns_globals = sctp_get_ns_globals(&init_net);
+ remove_proc_entry("sctp_dbg_objcnt", ns_globals->sctp_proc_dir);
}
-
-
diff --git a/net/sctp/proc.c b/net/sctp/proc.c
index 1e2eee8..d8f7b94 100644
--- a/net/sctp/proc.c
+++ b/net/sctp/proc.c
@@ -40,6 +40,7 @@
#include <linux/export.h>
#include <net/sctp/sctp.h>
#include <net/ip.h> /* for snmp_fold_field */
+#include <net/net_namespace.h>
static const struct snmp_mib sctp_snmp_list[] = {
SNMP_MIB_ITEM("SctpCurrEstab", SCTP_MIB_CURRESTAB),
@@ -93,7 +94,7 @@ static int sctp_snmp_seq_show(struct seq_file *seq, void *v)
/* Initialize the seq file operations for 'snmp' object. */
static int sctp_snmp_seq_open(struct inode *inode, struct file *file)
{
- return single_open(file, sctp_snmp_seq_show, NULL);
+ return single_open_net(inode, file, sctp_snmp_seq_show);
}
static const struct file_operations sctp_snmp_seq_fops = {
@@ -101,25 +102,29 @@ static const struct file_operations sctp_snmp_seq_fops = {
.open = sctp_snmp_seq_open,
.read = seq_read,
.llseek = seq_lseek,
- .release = single_release,
+ .release = single_release_net,
};
/* Set up the proc fs entry for 'snmp' object. */
-int __init sctp_snmp_proc_init(void)
+int __net_init sctp_snmp_proc_init(struct net *net)
{
- struct proc_dir_entry *p;
-
- p = proc_create("snmp", S_IRUGO, proc_net_sctp, &sctp_snmp_seq_fops);
- if (!p)
+ struct sctp_ns_globals *ns_globals = sctp_get_ns_globals(net);
+ ns_globals->sctp_proc_snmp =
+ proc_create("snmp", S_IRUGO, ns_globals->sctp_proc_dir,
+ &sctp_snmp_seq_fops);
+ if (!ns_globals->sctp_proc_snmp) {
+ pr_err("Couldn't create proc snmp for sctp\n");
return -ENOMEM;
+ }
return 0;
}
/* Cleanup the proc fs entry for 'snmp' object. */
-void sctp_snmp_proc_exit(void)
+void sctp_snmp_proc_exit(struct net *net)
{
- remove_proc_entry("snmp", proc_net_sctp);
+ struct sctp_ns_globals *ns_globals = sctp_get_ns_globals(net);
+ remove_proc_entry("snmp", ns_globals->sctp_proc_dir);
}
/* Dump local addresses of an association/endpoint. */
@@ -238,7 +243,8 @@ static const struct seq_operations sctp_eps_ops = {
/* Initialize the seq file operations for 'eps' object. */
static int sctp_eps_seq_open(struct inode *inode, struct file *file)
{
- return seq_open(file, &sctp_eps_ops);
+ return seq_open_net(inode, file, &sctp_eps_ops,
+ sizeof(struct seq_net_private));
}
static const struct file_operations sctp_eps_seq_fops = {
@@ -249,21 +255,23 @@ static const struct file_operations sctp_eps_seq_fops = {
};
/* Set up the proc fs entry for 'eps' object. */
-int __init sctp_eps_proc_init(void)
+int __net_init sctp_eps_proc_init(struct net *net)
{
- struct proc_dir_entry *p;
-
- p = proc_create("eps", S_IRUGO, proc_net_sctp, &sctp_eps_seq_fops);
- if (!p)
+ struct sctp_ns_globals *ns_globals = sctp_get_ns_globals(net);
+ ns_globals->sctp_proc_eps =
+ proc_create("eps", S_IRUGO, ns_globals->sctp_proc_dir,
+ &sctp_eps_seq_fops);
+ if (!ns_globals->sctp_proc_eps)
return -ENOMEM;
return 0;
}
/* Cleanup the proc fs entry for 'eps' object. */
-void sctp_eps_proc_exit(void)
+void sctp_eps_proc_exit(struct net *net)
{
- remove_proc_entry("eps", proc_net_sctp);
+ struct sctp_ns_globals *ns_globals = sctp_get_ns_globals(net);
+ remove_proc_entry("eps", ns_globals->sctp_proc_dir);
}
@@ -354,7 +362,8 @@ static const struct seq_operations sctp_assoc_ops = {
/* Initialize the seq file operations for 'assocs' object. */
static int sctp_assocs_seq_open(struct inode *inode, struct file *file)
{
- return seq_open(file, &sctp_assoc_ops);
+ return seq_open_net(inode, file, &sctp_assoc_ops,
+ sizeof(struct seq_net_private));
}
static const struct file_operations sctp_assocs_seq_fops = {
@@ -365,22 +374,23 @@ static const struct file_operations sctp_assocs_seq_fops = {
};
/* Set up the proc fs entry for 'assocs' object. */
-int __init sctp_assocs_proc_init(void)
+int __net_init sctp_assocs_proc_init(struct net *net)
{
- struct proc_dir_entry *p;
+ struct sctp_ns_globals *ns_globals = sctp_get_ns_globals(net);
- p = proc_create("assocs", S_IRUGO, proc_net_sctp,
- &sctp_assocs_seq_fops);
- if (!p)
+ ns_globals->sctp_proc_assocs = proc_create("assocs", S_IRUGO,
+ ns_globals->sctp_proc_dir, &sctp_assocs_seq_fops);
+ if (!ns_globals->sctp_proc_assocs)
return -ENOMEM;
return 0;
}
/* Cleanup the proc fs entry for 'assocs' object. */
-void sctp_assocs_proc_exit(void)
+void sctp_assocs_proc_exit(struct net *net)
{
- remove_proc_entry("assocs", proc_net_sctp);
+ struct sctp_ns_globals *ns_globals = sctp_get_ns_globals(net);
+ remove_proc_entry("assocs", ns_globals->sctp_proc_dir);
}
static void *sctp_remaddr_seq_start(struct seq_file *seq, loff_t *pos)
@@ -489,14 +499,16 @@ static const struct seq_operations sctp_remaddr_ops = {
};
/* Cleanup the proc fs entry for 'remaddr' object. */
-void sctp_remaddr_proc_exit(void)
+void sctp_remaddr_proc_exit(struct net *net)
{
- remove_proc_entry("remaddr", proc_net_sctp);
+ struct sctp_ns_globals *ns_globals = sctp_get_ns_globals(net);
+ remove_proc_entry("remaddr", ns_globals->sctp_proc_dir);
}
static int sctp_remaddr_seq_open(struct inode *inode, struct file *file)
{
- return seq_open(file, &sctp_remaddr_ops);
+ return seq_open_net(inode, file, &sctp_remaddr_ops,
+ sizeof(struct seq_net_private));
}
static const struct file_operations sctp_remaddr_seq_fops = {
@@ -506,12 +518,13 @@ static const struct file_operations sctp_remaddr_seq_fops = {
.release = seq_release,
};
-int __init sctp_remaddr_proc_init(void)
+int __net_init sctp_remaddr_proc_init(struct net *net)
{
- struct proc_dir_entry *p;
+ struct sctp_ns_globals *ns_globals = sctp_get_ns_globals(net);
- p = proc_create("remaddr", S_IRUGO, proc_net_sctp, &sctp_remaddr_seq_fops);
- if (!p)
+ ns_globals->sctp_proc_remaddr = proc_create("remaddr", S_IRUGO,
+ ns_globals->sctp_proc_dir, &sctp_remaddr_seq_fops);
+ if (!ns_globals->sctp_proc_remaddr)
return -ENOMEM;
return 0;
}
diff --git a/net/sctp/protocol.c b/net/sctp/protocol.c
index 5c1a18c..28dbef2 100644
--- a/net/sctp/protocol.c
+++ b/net/sctp/protocol.c
@@ -71,10 +71,6 @@
struct sctp_globals sctp_globals __read_mostly;
DEFINE_SNMP_STAT(struct sctp_mib, sctp_statistics) __read_mostly;
-#ifdef CONFIG_PROC_FS
-struct proc_dir_entry *proc_net_sctp;
-#endif
-
struct idr sctp_assocs_id;
DEFINE_SPINLOCK(sctp_assocs_id_lock);
@@ -97,43 +93,46 @@ int sysctl_sctp_rmem[3];
int sysctl_sctp_wmem[3];
/* Set up the proc fs entry for the SCTP protocol. */
-static __init int sctp_proc_init(void)
+static __net_init int sctp_proc_init(struct net *net)
{
#ifdef CONFIG_PROC_FS
int status = 0;
- if (!proc_net_sctp) {
- proc_net_sctp = proc_mkdir("sctp", init_net.proc_net);
- if (!proc_net_sctp) {
- status = -ENOMEM;
+ struct sctp_ns_globals *ns_globals = sctp_get_ns_globals(net);
+ ns_globals->sctp_proc_dir = proc_net_mkdir(net, "sctp", net->proc_net);
+ if (!ns_globals->sctp_proc_dir->name) {
+ pr_err("Failed to create sctp procfs directory\n");
+ status = -ENOBUFS;
goto out;
}
- }
- status = sctp_snmp_proc_init();
+ status = sctp_snmp_proc_init(net);
if (status)
goto out_snmp_proc_init;
- status = sctp_eps_proc_init();
+
+ status = sctp_eps_proc_init(net);
if (status)
goto out_eps_proc_init;
- status = sctp_assocs_proc_init();
+
+ status = sctp_assocs_proc_init(net);
if (status)
goto out_assocs_proc_init;
- status = sctp_remaddr_proc_init();
+
+ status = sctp_remaddr_proc_init(net);
if (status)
goto out_remaddr_proc_init;
return status;
out_remaddr_proc_init:
- sctp_assocs_proc_exit();
+ sctp_assocs_proc_exit(net);
out_assocs_proc_init:
- sctp_eps_proc_exit();
+ sctp_eps_proc_exit(net);
out_eps_proc_init:
- sctp_snmp_proc_exit();
+ sctp_snmp_proc_exit(net);
out_snmp_proc_init:
- if (proc_net_sctp) {
- proc_net_sctp = NULL;
- remove_proc_entry("sctp", init_net.proc_net);
+ if (ns_globals->sctp_proc_dir) {
+ ns_globals->sctp_proc_dir = NULL;
+ remove_proc_entry("sctp", ns_globals->sctp_proc_dir);
}
out:
return status;
@@ -146,17 +145,18 @@ out:
* Note: Do not make this __exit as it is used in the init error
* path.
*/
-static void sctp_proc_exit(void)
+static void sctp_proc_exit(struct net *net)
{
#ifdef CONFIG_PROC_FS
- sctp_snmp_proc_exit();
- sctp_eps_proc_exit();
- sctp_assocs_proc_exit();
- sctp_remaddr_proc_exit();
-
- if (proc_net_sctp) {
- proc_net_sctp = NULL;
- remove_proc_entry("sctp", init_net.proc_net);
+ struct sctp_ns_globals *ns_globals = sctp_get_ns_globals(net);
+ sctp_snmp_proc_exit(net);
+ sctp_eps_proc_exit(net);
+ sctp_assocs_proc_exit(net);
+ sctp_remaddr_proc_exit(net);
+
+ if (ns_globals->sctp_proc_dir) {
+ proc_net_remove(net, "sctp");
+ ns_globals->sctp_proc_dir = NULL;
}
#endif
}
@@ -1271,7 +1271,6 @@ static void sctp_global_param_init(void)
return;
}
-
static int sctp_net_param_init(struct net *net)
{
struct sctp_net_params *net_params = sctp_get_params(net);
@@ -1555,11 +1554,17 @@ static int __net_init sctp_net_init(struct net *net)
if (err)
goto out;
+ err = sctp_proc_init(net);
+ if (err)
+ goto err_proc_init;
+
err = sctp_net_param_init(net);
if (err)
goto err_param_init;
err_param_init:
+ sctp_proc_exit(net);
+err_proc_init:
sctp_ctl_sock_destroy(net);
out:
return err;
@@ -1568,6 +1573,7 @@ out:
static void __net_exit sctp_net_exit(struct net *net)
{
sctp_ctl_sock_destroy(net);
+ sctp_proc_exit(net);
}
static __net_initdata struct pernet_operations sctp_sk_ops = {
@@ -1642,10 +1648,14 @@ SCTP_STATIC __init int sctp_init(void)
if (status)
goto err_add_protocol;
+ /* Register SCTP with inet6 layer. */
status = sctp_v6_add_protocol();
if (status)
goto err_v6_add_protocol;
+ /* Set up sysctl parameters. */
+ sctp_sysctl_register();
+
/*
* Register for pernet packet handling
*/
@@ -1655,17 +1665,9 @@ SCTP_STATIC __init int sctp_init(void)
goto err_ns_init;
}
- /* Initialize proc fs directory. */
- status = sctp_proc_init();
- if (status)
- goto err_init_proc;
-
/* Initialize object count debugging. */
sctp_dbg_objcnt_init();
- /* Set up sysctl parameters. */
- sctp_sysctl_register();
-
/* Allocate and initialise sctp mibs. */
status = init_sctp_mibs();
if (status)
@@ -1677,8 +1679,6 @@ SCTP_STATIC __init int sctp_init(void)
err_mib_init:
sctp_sysctl_unregister();
sctp_dbg_objcnt_exit();
- sctp_proc_exit();
-err_init_proc:
sctp_ns_exit();
err_ns_init:
sctp_v6_del_protocol();
@@ -1727,7 +1727,6 @@ SCTP_STATIC __exit void sctp_exit(void)
sctp_hashtable_globals_free();
sctp_dbg_objcnt_exit();
- sctp_proc_exit();
percpu_counter_destroy(&sctp_sockets_allocated);
cleanup_sctp_mibs();
--
1.7.9.5
^ permalink raw reply related
* [PATCH 01/13] SCTP: Preparation for namespace enablement
From: Jan Ariyasu @ 2012-08-04 21:31 UTC (permalink / raw)
To: Vlad Yasevich, David S. Miller, linux-sctp, netdev, linux-kernel
Cc: Jan Ariyasu
Introduce data structures and break up module initialization and
exit into subroutines with common functionality for namespace
registration.
Signed-off-by: Jan Ariyasu <jan.ariyasu@hp.com>
---
include/net/sctp/structs.h | 150 ++++++++++++++++++++
net/sctp/protocol.c | 332 +++++++++++++++++++++++++++-----------------
2 files changed, 353 insertions(+), 129 deletions(-)
diff --git a/include/net/sctp/structs.h b/include/net/sctp/structs.h
index fc5e600..bc65718 100644
--- a/include/net/sctp/structs.h
+++ b/include/net/sctp/structs.h
@@ -77,6 +77,8 @@ union sctp_addr {
/* Forward declarations for data structures. */
struct sctp_globals;
+struct sctp_ns_globals;
+struct sctp_net_params;
struct sctp_endpoint;
struct sctp_association;
struct sctp_transport;
@@ -293,6 +295,135 @@ extern struct sctp_globals {
#define sctp_rwnd_upd_shift (sctp_globals.rwnd_update_shift)
#define sctp_max_autoclose (sctp_globals.max_autoclose)
+struct sctp_net_params {
+ /* RFC2960 Section 14. Suggested SCTP Protocol Parameter Values
+ *
+ * The following protocol parameters are RECOMMENDED:
+ *
+ * RTO.Initial - 3 seconds
+ * RTO.Min - 1 second
+ * RTO.Max - 60 seconds
+ * RTO.Alpha - 1/8 (3 when converted to right shifts.)
+ * RTO.Beta - 1/4 (2 when converted to right shifts.)
+ */
+ unsigned int rto_initial;
+ unsigned int rto_min;
+ unsigned int rto_max;
+
+ /* Note: rto_alpha and rto_beta are really defined as inverse
+ * powers of two to facilitate integer operations.
+ */
+ int rto_alpha;
+ int rto_beta;
+
+ /* Max.Burst - 4 */
+ int max_burst;
+
+ /* Whether Cookie Preservative is enabled(1) or not(0) */
+ int cookie_preserve_enable;
+
+ /* Valid.Cookie.Life - 60 seconds */
+ unsigned int valid_cookie_life;
+
+ /* Delayed SACK timeout 200ms default*/
+ unsigned int sack_timeout;
+
+ /* HB.interval - 30 seconds */
+ unsigned int hb_interval;
+
+ /* Association.Max.Retrans - 10 attempts
+ * Path.Max.Retrans - 5 attempts (per destination address)
+ * Max.Init.Retransmits - 8 attempts
+ */
+ int max_retrans_association;
+ int max_retrans_path;
+ int max_retrans_init;
+
+ /* Potentially-Failed.Max.Retrans sysctl value
+ * taken from:
+ * http://tools.ietf.org/html/draft-nishida-tsvwg-sctp-failover-05
+ */
+ int pf_retrans;
+
+ /*
+ * Policy for preforming sctp/socket accounting
+ * 0 - do socket level accounting, all assocs share sk_sndbuf
+ * 1 - do sctp accounting, each asoc may use sk_sndbuf bytes
+ */
+ int sndbuf_policy;
+
+ /*
+ * Policy for preforming sctp/socket accounting
+ * 0 - do socket level accounting, all assocs share sk_rcvbuf
+ * 1 - do sctp accounting, each asoc may use sk_rcvbuf bytes
+ */
+ int rcvbuf_policy;
+
+ /* The following variables are implementation specific. */
+
+ /* Default initialization values to be applied to new associations. */
+ __u16 max_instreams;
+ __u16 max_outstreams;
+
+
+ /* This is the hash of all endpoints. */
+ int ep_hashsize;
+ struct sctp_hashbucket *ep_hashtable;
+
+ /* This is the hash of all associations. */
+ int assoc_hashsize;
+ struct sctp_hashbucket *assoc_hashtable;
+
+ /* This is the sctp port control hash. */
+ int port_hashsize;
+ struct sctp_bind_hashbucket *port_hashtable;
+
+ /* This is the global local address list.
+ * We actively maintain this complete list of addresses on
+ * the system by catching address add/delete events.
+ *
+ * It is a list of sctp_sockaddr_entry.
+ */
+ struct list_head local_addr_list;
+
+ /* Lock that protects the local_addr_list writers */
+ spinlock_t addr_list_lock;
+
+ /* Address Event Parameters */
+ int default_auto_asconf;
+ struct list_head addr_waitq;
+ struct timer_list addr_wq_timer;
+ struct list_head auto_asconf_splist;
+ spinlock_t addr_wq_lock;
+
+ /* Flag to indicate if addip is enabled. */
+ int addip_enable;
+ int addip_noauth_enable;
+
+ /* Flag to indicate if PR-SCTP is enabled. */
+ int prsctp_enable;
+
+ /* Flag to idicate if SCTP-AUTH is enabled */
+ int auth_enable;
+
+ /*
+ * Policy to control SCTP IPv4 address scoping
+ * 0 - Disable IPv4 address scoping
+ * 1 - Enable IPv4 address scoping
+ * 2 - Selectively allow only IPv4 private addresses
+ * 3 - Selectively allow only IPv4 link local address
+ */
+ int ipv4_scope_policy;
+
+ /* Threshold for rwnd update SACKS. Receive buffer shifted this many
+ * bits is an indicator of when to send and window update SACK.
+ */
+ int rwnd_update_shift;
+
+ /* Threshold for autoclose timeout, in seconds. */
+ unsigned long max_autoclose;
+};
+
/* SCTP Socket type: UDP or TCP style. */
typedef enum {
SCTP_SOCKET_UDP = 0,
@@ -2056,4 +2187,23 @@ typedef struct {
atomic_t *counter;
} sctp_dbg_objcnt_entry_t;
+
+/* Structure for keeping track of namespace globals */
+struct sctp_ns_globals {
+ struct sock *sctp_ctl_sock;
+ struct sctp_net_params protocol_params;
+ struct idr assocs_id;
+ spinlock_t assocs_id_lock;
+#ifdef CONFIG_SYSCTL
+ struct ctl_table_header *sctp_sysctl_tbl;
+#endif
+#ifdef CONFIG_PROC_FS
+ struct proc_dir_entry *sctp_proc_dir;
+ struct proc_dir_entry *sctp_proc_snmp;
+ struct proc_dir_entry *sctp_proc_assocs;
+ struct proc_dir_entry *sctp_proc_eps;
+ struct proc_dir_entry *sctp_proc_remaddr;
+#endif
+};
+
#endif /* __sctp_structs_h__ */
diff --git a/net/sctp/protocol.c b/net/sctp/protocol.c
index 1f89c4e..cafdaac 100644
--- a/net/sctp/protocol.c
+++ b/net/sctp/protocol.c
@@ -105,13 +105,11 @@ struct sock *sctp_get_ctl_sock(void)
/* Set up the proc fs entry for the SCTP protocol. */
static __init int sctp_proc_init(void)
{
- if (percpu_counter_init(&sctp_sockets_allocated, 0))
- goto out_nomem;
#ifdef CONFIG_PROC_FS
if (!proc_net_sctp) {
proc_net_sctp = proc_mkdir("sctp", init_net.proc_net);
if (!proc_net_sctp)
- goto out_free_percpu;
+ goto out_nomem;
}
if (sctp_snmp_proc_init())
@@ -136,14 +134,12 @@ out_snmp_proc_init:
proc_net_sctp = NULL;
remove_proc_entry("sctp", init_net.proc_net);
}
-out_free_percpu:
- percpu_counter_destroy(&sctp_sockets_allocated);
-#else
- return 0;
-#endif /* CONFIG_PROC_FS */
out_nomem:
return -ENOMEM;
+#else
+ return 0;
+#endif /* CONFIG_PROC_FS */
}
/* Clean up the proc fs entry for the SCTP protocol.
@@ -163,7 +159,6 @@ static void sctp_proc_exit(void)
remove_proc_entry("sctp", init_net.proc_net);
}
#endif
- percpu_counter_destroy(&sctp_sockets_allocated);
}
/* Private helper to extract ipv4 address and stash them in
@@ -1194,105 +1189,91 @@ static void sctp_v4_del_protocol(void)
unregister_inetaddr_notifier(&sctp_inetaddr_notifier);
}
-/* Initialize the universe into something sensible. */
-SCTP_STATIC __init int sctp_init(void)
+static void sctp_global_param_init(void)
{
- int i;
- int status = -EINVAL;
- unsigned long goal;
- unsigned long limit;
- int max_share;
- int order;
-
- /* SCTP_DEBUG sanity check. */
- if (!sctp_sanity_check())
- goto out;
-
- /* Allocate bind_bucket and chunk caches. */
- status = -ENOBUFS;
- sctp_bucket_cachep = kmem_cache_create("sctp_bind_bucket",
- sizeof(struct sctp_bind_bucket),
- 0, SLAB_HWCACHE_ALIGN,
- NULL);
- if (!sctp_bucket_cachep)
- goto out;
-
- sctp_chunk_cachep = kmem_cache_create("sctp_chunk",
- sizeof(struct sctp_chunk),
- 0, SLAB_HWCACHE_ALIGN,
- NULL);
- if (!sctp_chunk_cachep)
- goto err_chunk_cachep;
-
- /* Allocate and initialise sctp mibs. */
- status = init_sctp_mibs();
- if (status)
- goto err_init_mibs;
-
- /* Initialize proc fs directory. */
- status = sctp_proc_init();
- if (status)
- goto err_init_proc;
-
- /* Initialize object count debugging. */
- sctp_dbg_objcnt_init();
-
/*
* 14. Suggested SCTP Protocol Parameter Values
*/
/* The following protocol parameters are RECOMMENDED: */
- /* RTO.Initial - 3 seconds */
- sctp_rto_initial = SCTP_RTO_INITIAL;
- /* RTO.Min - 1 second */
- sctp_rto_min = SCTP_RTO_MIN;
- /* RTO.Max - 60 seconds */
- sctp_rto_max = SCTP_RTO_MAX;
- /* RTO.Alpha - 1/8 */
- sctp_rto_alpha = SCTP_RTO_ALPHA;
- /* RTO.Beta - 1/4 */
- sctp_rto_beta = SCTP_RTO_BETA;
-
- /* Valid.Cookie.Life - 60 seconds */
- sctp_valid_cookie_life = SCTP_DEFAULT_COOKIE_LIFE;
+ /* RTO.Initial - 3 seconds */
+ sctp_rto_initial = SCTP_RTO_INITIAL;
+ /* RTO.Min - 1 second */
+ sctp_rto_min = SCTP_RTO_MIN;
+ /* RTO.Max - 60 seconds */
+ sctp_rto_max = SCTP_RTO_MAX;
+ /* RTO.Alpha - 1/8 */
+ sctp_rto_alpha = SCTP_RTO_ALPHA;
+ /* RTO.Beta - 1/4 */
+ sctp_rto_beta = SCTP_RTO_BETA;
+
+ /* Valid.Cookie.Life - 60 seconds */
+ sctp_valid_cookie_life = SCTP_DEFAULT_COOKIE_LIFE;
/* Whether Cookie Preservative is enabled(1) or not(0) */
- sctp_cookie_preserve_enable = 1;
+ sctp_cookie_preserve_enable = 1;
- /* Max.Burst - 4 */
- sctp_max_burst = SCTP_DEFAULT_MAX_BURST;
+ /* Max.Burst - 4 */
+ sctp_max_burst = SCTP_DEFAULT_MAX_BURST;
- /* Association.Max.Retrans - 10 attempts
- * Path.Max.Retrans - 5 attempts (per destination address)
- * Max.Init.Retransmits - 8 attempts
+ /* Association.Max.Retrans - 10 attempts
+ * Path.Max.Retrans - 5 attempts (per destination address)
+ * Max.Init.Retransmits - 8 attempts
*/
- sctp_max_retrans_association = 10;
- sctp_max_retrans_path = 5;
- sctp_max_retrans_init = 8;
+ sctp_max_retrans_association = 10;
+ sctp_max_retrans_path = 5;
+ sctp_max_retrans_init = 8;
- /* Sendbuffer growth - do per-socket accounting */
- sctp_sndbuf_policy = 0;
+ /* Sendbuffer growth - do per-socket accounting */
+ sctp_sndbuf_policy = 0;
- /* Rcvbuffer growth - do per-socket accounting */
- sctp_rcvbuf_policy = 0;
+ /* Rcvbuffer growth - do per-socket accounting */
+ sctp_rcvbuf_policy = 0;
- /* HB.interval - 30 seconds */
+ /* HB.interval - 30 seconds */
sctp_hb_interval = SCTP_DEFAULT_TIMEOUT_HEARTBEAT;
/* delayed SACK timeout */
- sctp_sack_timeout = SCTP_DEFAULT_TIMEOUT_SACK;
+ sctp_sack_timeout = SCTP_DEFAULT_TIMEOUT_SACK;
/* Implementation specific variables. */
/* Initialize default stream count setup information. */
- sctp_max_instreams = SCTP_DEFAULT_INSTREAMS;
- sctp_max_outstreams = SCTP_DEFAULT_OUTSTREAMS;
+ sctp_max_instreams = SCTP_DEFAULT_INSTREAMS;
+ sctp_max_outstreams = SCTP_DEFAULT_OUTSTREAMS;
/* Initialize maximum autoclose timeout. */
- sctp_max_autoclose = INT_MAX / HZ;
+ sctp_max_autoclose = INT_MAX / HZ;
+
+ /* Disable ADDIP by default. */
+ sctp_addip_enable = 0;
+ sctp_addip_noauth = 0;
+ sctp_default_auto_asconf = 0;
- /* Initialize handle used for association ids. */
- idr_init(&sctp_assocs_id);
+ /* Enable PR-SCTP by default. */
+ sctp_prsctp_enable = 1;
+
+ /* Disable AUTH by default. */
+ sctp_auth_enable = 0;
+ /* Set SCOPE policy to enabled */
+ sctp_scope_policy = SCTP_SCOPE_POLICY_ENABLE;
+
+ /* Set the default rwnd update threshold */
+ sctp_rwnd_upd_shift = SCTP_DEFAULT_RWND_SHIFT;
+ return;
+}
+
+static void sctp_memory_globals_init(void)
+{
+ unsigned long limit;
+ int max_share;
+
+ /* Set the pressure threshold to be a fraction of global memory that
+ * is up to 1/2 at 256 MB, decreasing toward zero with the amount of
+ * memory, with a floor of 128 pages.
+ * Note this initializes the data in sctpv6_prot too
+ * Unabashedly stolen from tcp_init
+ */
limit = nr_free_buffer_pages() / 8;
limit = max(limit, 128UL);
sysctl_sctp_mem[0] = limit / 4 * 3;
@@ -1310,6 +1291,14 @@ SCTP_STATIC __init int sctp_init(void)
sysctl_sctp_wmem[0] = SK_MEM_QUANTUM;
sysctl_sctp_wmem[1] = 16*1024;
sysctl_sctp_wmem[2] = max(64*1024, max_share);
+}
+
+static int sctp_hashtable_globals_init(void)
+{
+ unsigned long goal;
+ int status = -ENOMEM;
+ int order;
+ int i;
/* Size and allocate the association hash table.
* The methodology is similar to that of the tcp hash tables.
@@ -1325,11 +1314,13 @@ SCTP_STATIC __init int sctp_init(void)
do {
sctp_assoc_hashsize = (1UL << order) * PAGE_SIZE /
sizeof(struct sctp_hashbucket);
- if ((sctp_assoc_hashsize > (64 * 1024)) && order > 0)
- continue;
+ if ((sctp_assoc_hashsize > (64 * 1024)) && (order > 0))
+ continue;
sctp_assoc_hashtable = (struct sctp_hashbucket *)
- __get_free_pages(GFP_ATOMIC|__GFP_NOWARN, order);
- } while (!sctp_assoc_hashtable && --order > 0);
+ __get_free_pages(GFP_ATOMIC|__GFP_NOWARN|__GFP_ZERO,
+ order);
+ } while (!sctp_assoc_hashtable && (--order > 0));
+
if (!sctp_assoc_hashtable) {
pr_err("Failed association hash alloc\n");
status = -ENOMEM;
@@ -1358,11 +1349,12 @@ SCTP_STATIC __init int sctp_init(void)
do {
sctp_port_hashsize = (1UL << order) * PAGE_SIZE /
sizeof(struct sctp_bind_hashbucket);
- if ((sctp_port_hashsize > (64 * 1024)) && order > 0)
+ if ((sctp_port_hashsize > (64 * 1024)) && (order > 0))
continue;
sctp_port_hashtable = (struct sctp_bind_hashbucket *)
__get_free_pages(GFP_ATOMIC|__GFP_NOWARN, order);
- } while (!sctp_port_hashtable && --order > 0);
+ } while (!sctp_port_hashtable && (--order > 0));
+
if (!sctp_port_hashtable) {
pr_err("Failed bind hash alloc\n");
status = -ENOMEM;
@@ -1376,25 +1368,111 @@ SCTP_STATIC __init int sctp_init(void)
pr_info("Hash tables configured (established %d bind %d)\n",
sctp_assoc_hashsize, sctp_port_hashsize);
- /* Disable ADDIP by default. */
- sctp_addip_enable = 0;
- sctp_addip_noauth = 0;
- sctp_default_auto_asconf = 0;
+ goto out;
- /* Enable PR-SCTP by default. */
- sctp_prsctp_enable = 1;
- /* Disable AUTH by default. */
- sctp_auth_enable = 0;
+err_bhash_alloc:
+ kfree(sctp_ep_hashtable);
+err_ehash_alloc:
+ free_pages((unsigned long)sctp_assoc_hashtable,
+ get_order(sctp_assoc_hashsize *
+ sizeof(struct sctp_hashbucket)));
+err_ahash_alloc:
+ sctp_proc_exit();
+out:
+ return status;
+}
- /* Set SCOPE policy to enabled */
- sctp_scope_policy = SCTP_SCOPE_POLICY_ENABLE;
+static void sctp_hashtable_globals_free(void)
+{
+ free_pages((unsigned long)sctp_assoc_hashtable,
+ get_order(sctp_assoc_hashsize *
+ sizeof(struct sctp_hashbucket)));
- /* Set the default rwnd update threshold */
- sctp_rwnd_upd_shift = SCTP_DEFAULT_RWND_SHIFT;
+ kfree(sctp_ep_hashtable);
+
+ free_pages((unsigned long)sctp_port_hashtable,
+ get_order(sctp_port_hashsize *
+ sizeof(struct sctp_bind_hashbucket)));
+}
+
+static int sctp_kmem_cache_create(void)
+{
+ /* Allocate bind_bucket and chunk caches. */
+ sctp_bucket_cachep = kmem_cache_create("sctp_bind_bucket",
+ sizeof(struct sctp_bind_bucket),
+ 0, SLAB_HWCACHE_ALIGN,
+ NULL);
+
+ if (!sctp_bucket_cachep) {
+ pr_err("failed to allocate bucket cache\n");
+ goto err_bucket_cachep;
+ }
+ sctp_chunk_cachep = kmem_cache_create("sctp_chunk",
+ sizeof(struct sctp_chunk),
+ 0, SLAB_HWCACHE_ALIGN,
+ NULL);
+ if (!sctp_chunk_cachep) {
+ pr_err("failed to allocate chunk cache\n");
+ goto err_chunk_cachep;
+ }
+
+ return 0;
+
+err_chunk_cachep:
+ kmem_cache_destroy(sctp_bucket_cachep);
+err_bucket_cachep:
+ return -ENOBUFS;
+}
+
+static void sctp_kmem_cache_destroy(void)
+{
+ /* deallocate bind_bucket and chunk caches. */
+ kmem_cache_destroy(sctp_chunk_cachep);
+ kmem_cache_destroy(sctp_bucket_cachep);
+}
+
+/* Initialize the universe into something sensible. */
+SCTP_STATIC __init int sctp_init(void)
+{
+ int status = -EINVAL;
+
+ /* SCTP_DEBUG sanity check. */
+ if (!sctp_sanity_check())
+ goto out;
+
+ /* Allocate bind_bucket and chunk caches. */
+ status = sctp_kmem_cache_create();
+ if (status)
+ return status;
+
+ /* Initialize sockets counter */
+ if (percpu_counter_init(&sctp_sockets_allocated, 0)) {
+ status = -ENOMEM;
+ goto err_percpu_counter_init;
+ }
+
+ /* Allocate and initialise sctp mibs. */
+ status = init_sctp_mibs();
+ if (status)
+ goto err_init_mibs;
+
+ /* Initialize proc fs directory. */
+ status = sctp_proc_init();
+ if (status)
+ goto err_init_proc;
+
+ /* Initialize object count debugging. */
+ sctp_dbg_objcnt_init();
+
+ /* Initialize global parameters */
+ sctp_global_param_init();
+ sctp_memory_globals_init();
+ sctp_hashtable_globals_init();
sctp_sysctl_register();
+ /* Register the routines for different a-f handling */
INIT_LIST_HEAD(&sctp_address_families);
sctp_v4_pf_init();
sctp_v6_pf_init();
@@ -1411,8 +1489,8 @@ SCTP_STATIC __init int sctp_init(void)
sctp_addr_wq_timer.expires = 0;
setup_timer(&sctp_addr_wq_timer, sctp_addr_wq_timeout_handler, 0);
+ /* Register SCTP protocol */
status = sctp_v4_protosw_init();
-
if (status)
goto err_protosw_init;
@@ -1435,9 +1513,20 @@ SCTP_STATIC __init int sctp_init(void)
if (status)
goto err_v6_add_protocol;
+ /* Set up sysctl parameters. */
+ sctp_sysctl_register();
+
+ /* Allocate and initialise sctp mibs. */
+ status = init_sctp_mibs();
+ if (status)
+ goto err_mib_init;
+
status = 0;
-out:
- return status;
+ goto out;
+
+err_mib_init:
+ sctp_sysctl_unregister();
+ sctp_v6_del_protocol();
err_v6_add_protocol:
sctp_v4_del_protocol();
err_add_protocol:
@@ -1451,25 +1540,17 @@ err_protosw_init:
sctp_v4_pf_exit();
sctp_v6_pf_exit();
sctp_sysctl_unregister();
- free_pages((unsigned long)sctp_port_hashtable,
- get_order(sctp_port_hashsize *
- sizeof(struct sctp_bind_hashbucket)));
-err_bhash_alloc:
- kfree(sctp_ep_hashtable);
-err_ehash_alloc:
- free_pages((unsigned long)sctp_assoc_hashtable,
- get_order(sctp_assoc_hashsize *
- sizeof(struct sctp_hashbucket)));
-err_ahash_alloc:
+ sctp_hashtable_globals_free();
sctp_dbg_objcnt_exit();
sctp_proc_exit();
err_init_proc:
cleanup_sctp_mibs();
err_init_mibs:
- kmem_cache_destroy(sctp_chunk_cachep);
-err_chunk_cachep:
- kmem_cache_destroy(sctp_bucket_cachep);
- goto out;
+ percpu_counter_destroy(&sctp_sockets_allocated);
+err_percpu_counter_init:
+ sctp_kmem_cache_destroy();
+out:
+ return status;
}
/* Exit handler for the SCTP protocol. */
@@ -1500,22 +1581,15 @@ SCTP_STATIC __exit void sctp_exit(void)
sctp_sysctl_unregister();
- free_pages((unsigned long)sctp_assoc_hashtable,
- get_order(sctp_assoc_hashsize *
- sizeof(struct sctp_hashbucket)));
- kfree(sctp_ep_hashtable);
- free_pages((unsigned long)sctp_port_hashtable,
- get_order(sctp_port_hashsize *
- sizeof(struct sctp_bind_hashbucket)));
+ sctp_hashtable_globals_free();
sctp_dbg_objcnt_exit();
sctp_proc_exit();
+ percpu_counter_destroy(&sctp_sockets_allocated);
cleanup_sctp_mibs();
rcu_barrier(); /* Wait for completion of call_rcu()'s */
-
- kmem_cache_destroy(sctp_chunk_cachep);
- kmem_cache_destroy(sctp_bucket_cachep);
+ sctp_kmem_cache_destroy();
}
module_init(sctp_init);
--
1.7.9.5
^ permalink raw reply related
* [PATCH 00/13] SCTP: Enable netns
From: Jan Ariyasu @ 2012-08-04 21:30 UTC (permalink / raw)
To: Vlad Yasevich, David S. Miller, linux-sctp, netdev, linux-kernel
Cc: Jan Ariyasu
The following set of patches enable network-namespaces for the SCTP protocol.
The multitude of global parameters are stored in a net_generic
structure, and the bulk of the patches enable the protocol to access
the parameters on a per-namespace basis. The first five patches
enable netns handling of the protocol, procfs and sysfs.
Signed-off-by: Jan Ariyasu <jan.ariyasu@hp.com>
---
^ permalink raw reply
* Re: [PATCH V2 09/12] net/eipoib: Add main driver functionality
From: Or Gerlitz @ 2012-08-04 21:23 UTC (permalink / raw)
To: David Miller; +Cc: ali, ebiederm, ogerlitz, roland, netdev, sean.hefty, erezsh
In-Reply-To: <20120803.163627.1867181085116225405.davem@davemloft.net>
On Sat, Aug 4, 2012 at 2:36 AM, David Miller <davem@davemloft.net> wrote:
> From: Ali Ayoub <ali@mellanox.com>
> Date: Fri, 03 Aug 2012 15:39:36 -0700
>> Users would like to use sockets API from the VM without re-writing their
>> applications on top of IB verbs, this driver meant to allow such a user
>> to do so.
> That's what IPoIB was for, the application writers who don't want to have
> to be knowledgable about IB verbs.
>
> You're messing with the link layer here, and that's what is upsetting me.
>
> It's a complete cop-out to changing the VM tools and emulators properly to
> handle a new link layer.
>
> The applications writers already have a way to use IB whilst using
> something familiar, like IPv4, via IPoIB. You're doing something
> completely different here, and it stinks.
Dave,
Just quick recap of things to make sure we're in sync on the facts
here and (me) trying to better follow your arguments:
Bringing IB to app usage is done through the IB verbs / RDMA CM, which
is supported
for quite a long while for native mode and BTW as for SRIOV, there's a
now running patch set @ linux-rdma submitted to Roland
http://marc.info/?l=linux-rdma&m=134398354428293&w=2
IPoIB is meant to allow IP apps to use IB, defined by IETF spec (RFC 4391/4392)
The idea in eIPoIB was to allow IP apps running on VMs under a
Para-Virtual set of mind, e.g when the Linux PV networking stack comes
into play, to use that stack w.o modifying it.
When looking on that, we thought so far so good, and went in the way
posted here. If reusing your last sentence... this driver provides a
way for apps to use the PV stack AND IB whilst using something
familiar, like IPv4.
I'd like to better understand your "messing with the link layer here,
and that's what is upsetting" claim --- since the service here is IP,
and this service has well defined mechanisms, eIPoIB is basically a
shim layer that allows to provide this service for VMs that interacts
with the emulators, drivers and tools used in Linux and the related
guest OS PV drivers (virtio and friends). For example, that messing
mostly goes down to translating ARP requests/replies from being
carried in Ethernet frame to be carried in IPoIB packet, is that
really too hacky? why and what?
Or.
^ permalink raw reply
* [PATCH] tcp_output: fix sparse warning for tcp_wfree
From: Silviu-Mihai Popescu @ 2012-08-04 19:31 UTC (permalink / raw)
To: netdev
Cc: davem, kuznet, jmorris, yoshfuji, kaber, linux-kernel,
Silviu-Mihai Popescu
Fix sparse warning:
* symbol 'tcp_wfree' was not declared. Should it be static?
Signed-off-by: Silviu-Mihai Popescu <silviupopescu1990@gmail.com>
---
net/ipv4/tcp_output.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/net/ipv4/tcp_output.c b/net/ipv4/tcp_output.c
index 3f1bcff..18475e0 100644
--- a/net/ipv4/tcp_output.c
+++ b/net/ipv4/tcp_output.c
@@ -940,7 +940,7 @@ void __init tcp_tasklet_init(void)
* We cant xmit new skbs from this context, as we might already
* hold qdisc lock.
*/
-void tcp_wfree(struct sk_buff *skb)
+static void tcp_wfree(struct sk_buff *skb)
{
struct sock *sk = skb->sk;
struct tcp_sock *tp = tcp_sk(sk);
--
1.7.9.5
^ permalink raw reply related
* Re: TCP stalls with 802.3ad + bridge + kvm guest
From: Sławek Janecki @ 2012-08-04 19:21 UTC (permalink / raw)
To: Peter Samuelson; +Cc: Jesse Brandeburg, Jay Vosburgh, netdev, jgoerzen
In-Reply-To: <CACS4u_y23MvgnK-sbcNv7pxgaDYJLvzXZa68QKE__NckwM_XSQ@mail.gmail.com>
wrong mail sorry
On Sat, Aug 4, 2012 at 8:07 PM, Sławek Janecki <janecki@gmail.com> wrote:
> I have no such info in dmsg.
> I think I will file a issue to Node.js Dev Team.
> Thanks for reply.
>
> On Sat, Aug 4, 2012 at 6:22 PM, Peter Samuelson <psamuelson@efolder.net> wrote:
>>
>> [Jesse Brandeburg]
>>> try
>>> # ethtool -K ethx tso off gso off lro off
>>
>> Wow - that worked! Thanks so much! Now I'll see if I can narrow it
>> down a bit from there.
>>
>> Then it's on to the mystery of why I have to explicitly set eth2+eth3
>> 'promisc' - the bond0 device is supposed to propagate that setting but
>> apparently it doesn't. (Lower priority, though, since there's an easy
>> workaround.)
>>
>> Peter
>> --
>> To unsubscribe from this list: send the line "unsubscribe netdev" in
>> the body of a message to majordomo@vger.kernel.org
>> More majordomo info at http://vger.kernel.org/majordomo-info.html
>
>
>
> --
>
> pozdrawiam
> Sławomir Janecki
--
pozdrawiam
Sławomir Janecki
^ permalink raw reply
* Re: TCP Delayed ACK in FIN/ACK
From: Sławek Janecki @ 2012-08-04 19:20 UTC (permalink / raw)
To: Eric Dumazet; +Cc: richard -rw- weinberger, linux-kernel, netdev
In-Reply-To: <1344098083.9299.1503.camel@edumazet-glaptop>
I have no such info in dmsg.
I think I will file a issue to Node.js Dev Team.
Thanks for reply.
On Sat, Aug 4, 2012 at 6:34 PM, Eric Dumazet <eric.dumazet@gmail.com> wrote:
> On Sat, 2012-08-04 at 16:51 +0200, richard -rw- weinberger wrote:
>> On Sat, Aug 4, 2012 at 4:45 PM, Sławek Janecki <janecki@gmail.com> wrote:
>> > I have a node.js client (10.177.62.7) requesting some data from http
>> > rest service from server (10.177.0.1).
>> > Client is simply using nodejs http.request() method (agent=false).
>> > Client is on Ubuntu 11.10 box.
>> > Why client sends FIN ACK after 475ms? Why so slow? He should send FIN
>> > ACK immediately.
>> > I have many situations like this. About 1% of whole traffic is request
>> > with delayed FIN ACK.
>> > Cpu idle on the client is about 99%, so nothing is draining CPU.
>> > How to debug this? What could it be? Is there any sysctl option I need to tune?
>> > I think this behaviour is the Delayed ACK feature of RFC1122 TCP stack.
>> >
>> > Link to tcpdump picture (done on a client machine) :
>> > http://i48.tinypic.com/35cpogx.png
>> >
>> > Can you tell why kernel delayed that FIN/ACK.
>> > In tcpflow data there is exacly one ACK per packet comming from server.
>> > Why kernel delayed client FIN/ACK.
>> > It could avoid sending ACK every 'data' packet.
>> > But it choose to delay FIN/ACK?
>> > Is this possible? Is this a bug?
>> >
>> > I've also posted question on stackexchange:
>> > http://stackoverflow.com/questions/11711218/client-sends-delayed-fin-ack-500ms-to-server
>> >
>> > Please help.
>>
>> CC'ing netdev.
>>
>
> I see nothing wrong in this tcpdump. You should strace the application
> instead.
>
> FIN/ACK is sent when client closes its socket (or calls shutdown()), and
> not in reply of FIN sent by the server.
>
> Kernel has no additional delay. I suspect your client is slow processing
> the server answer, then close() its socket _after_ data processing.
>
> Its possible tcp_send_fin() has to loop while allocating one skb under
> very high memory pressure, and it seems we have no counters for this
> case. But if it _was_ ever happening, you would have lot of messages in
> kernel log (dmesg) about alloc_skb_clone() failures.
>
>
>
--
pozdrawiam
Sławomir Janecki
^ permalink raw reply
* Re: TCP stalls with 802.3ad + bridge + kvm guest
From: Sławek Janecki @ 2012-08-04 18:07 UTC (permalink / raw)
To: Peter Samuelson; +Cc: Jesse Brandeburg, Jay Vosburgh, netdev, jgoerzen
In-Reply-To: <20120804162219.GT17572@p12n.org>
I have no such info in dmsg.
I think I will file a issue to Node.js Dev Team.
Thanks for reply.
On Sat, Aug 4, 2012 at 6:22 PM, Peter Samuelson <psamuelson@efolder.net> wrote:
>
> [Jesse Brandeburg]
>> try
>> # ethtool -K ethx tso off gso off lro off
>
> Wow - that worked! Thanks so much! Now I'll see if I can narrow it
> down a bit from there.
>
> Then it's on to the mystery of why I have to explicitly set eth2+eth3
> 'promisc' - the bond0 device is supposed to propagate that setting but
> apparently it doesn't. (Lower priority, though, since there's an easy
> workaround.)
>
> Peter
> --
> To unsubscribe from this list: send the line "unsubscribe netdev" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at http://vger.kernel.org/majordomo-info.html
--
pozdrawiam
Sławomir Janecki
^ permalink raw reply
* [PATCH 6/6] drivers/net/phy/mdio-mux-gpio.c: drop devm_kfree of devm_kzalloc'd data
From: Julia Lawall @ 2012-08-04 16:50 UTC (permalink / raw)
To: netdev; +Cc: kernel-janitors, linux-kernel
From: Julia Lawall <Julia.Lawall@lip6.fr>
devm_kfree should not have to be explicitly used.
The semantic patch that fixes this problem is as follows:
(http://coccinelle.lip6.fr/)
// <smpl>
@@
expression x,d;
@@
x = devm_kzalloc(...)
...
?-devm_kfree(d,x);
// </smpl>
Signed-off-by: Julia Lawall <Julia.Lawall@lip6.fr>
---
drivers/net/phy/mdio-mux-gpio.c | 1 -
1 file changed, 1 deletion(-)
diff --git a/drivers/net/phy/mdio-mux-gpio.c b/drivers/net/phy/mdio-mux-gpio.c
index e0cc4ef..eefe49e 100644
--- a/drivers/net/phy/mdio-mux-gpio.c
+++ b/drivers/net/phy/mdio-mux-gpio.c
@@ -101,7 +101,6 @@ err:
n--;
gpio_free(s->gpio[n]);
}
- devm_kfree(&pdev->dev, s);
return r;
}
^ permalink raw reply related
* Re: TCP Delayed ACK in FIN/ACK
From: Eric Dumazet @ 2012-08-04 16:34 UTC (permalink / raw)
To: richard -rw- weinberger; +Cc: Sławek Janecki, linux-kernel, netdev
In-Reply-To: <CAFLxGvxqj+-rf5twsMPk-pRQqzqsK8-MSsKaez9cwarPmyEqzw@mail.gmail.com>
On Sat, 2012-08-04 at 16:51 +0200, richard -rw- weinberger wrote:
> On Sat, Aug 4, 2012 at 4:45 PM, Sławek Janecki <janecki@gmail.com> wrote:
> > I have a node.js client (10.177.62.7) requesting some data from http
> > rest service from server (10.177.0.1).
> > Client is simply using nodejs http.request() method (agent=false).
> > Client is on Ubuntu 11.10 box.
> > Why client sends FIN ACK after 475ms? Why so slow? He should send FIN
> > ACK immediately.
> > I have many situations like this. About 1% of whole traffic is request
> > with delayed FIN ACK.
> > Cpu idle on the client is about 99%, so nothing is draining CPU.
> > How to debug this? What could it be? Is there any sysctl option I need to tune?
> > I think this behaviour is the Delayed ACK feature of RFC1122 TCP stack.
> >
> > Link to tcpdump picture (done on a client machine) :
> > http://i48.tinypic.com/35cpogx.png
> >
> > Can you tell why kernel delayed that FIN/ACK.
> > In tcpflow data there is exacly one ACK per packet comming from server.
> > Why kernel delayed client FIN/ACK.
> > It could avoid sending ACK every 'data' packet.
> > But it choose to delay FIN/ACK?
> > Is this possible? Is this a bug?
> >
> > I've also posted question on stackexchange:
> > http://stackoverflow.com/questions/11711218/client-sends-delayed-fin-ack-500ms-to-server
> >
> > Please help.
>
> CC'ing netdev.
>
I see nothing wrong in this tcpdump. You should strace the application
instead.
FIN/ACK is sent when client closes its socket (or calls shutdown()), and
not in reply of FIN sent by the server.
Kernel has no additional delay. I suspect your client is slow processing
the server answer, then close() its socket _after_ data processing.
Its possible tcp_send_fin() has to loop while allocating one skb under
very high memory pressure, and it seems we have no counters for this
case. But if it _was_ ever happening, you would have lot of messages in
kernel log (dmesg) about alloc_skb_clone() failures.
^ permalink raw reply
* Re: TCP stalls with 802.3ad + bridge + kvm guest
From: Peter Samuelson @ 2012-08-04 16:22 UTC (permalink / raw)
To: Jesse Brandeburg; +Cc: Jay Vosburgh, netdev, jgoerzen
In-Reply-To: <CAEuXFExg2X9r0zE8wUs9Npd7jPUN2WHbyJcnH6eT_23f2DoPjw@mail.gmail.com>
[Jesse Brandeburg]
> try
> # ethtool -K ethx tso off gso off lro off
Wow - that worked! Thanks so much! Now I'll see if I can narrow it
down a bit from there.
Then it's on to the mystery of why I have to explicitly set eth2+eth3
'promisc' - the bond0 device is supposed to propagate that setting but
apparently it doesn't. (Lower priority, though, since there's an easy
workaround.)
Peter
^ permalink raw reply
* Re: TCP Delayed ACK in FIN/ACK
From: richard -rw- weinberger @ 2012-08-04 14:51 UTC (permalink / raw)
To: Sławek Janecki; +Cc: linux-kernel, netdev
In-Reply-To: <CACS4u_zUF9T0rSsndhyVzgaauOBFJ4LTUeb432B1zg_oLHvTsg@mail.gmail.com>
On Sat, Aug 4, 2012 at 4:45 PM, Sławek Janecki <janecki@gmail.com> wrote:
> I have a node.js client (10.177.62.7) requesting some data from http
> rest service from server (10.177.0.1).
> Client is simply using nodejs http.request() method (agent=false).
> Client is on Ubuntu 11.10 box.
> Why client sends FIN ACK after 475ms? Why so slow? He should send FIN
> ACK immediately.
> I have many situations like this. About 1% of whole traffic is request
> with delayed FIN ACK.
> Cpu idle on the client is about 99%, so nothing is draining CPU.
> How to debug this? What could it be? Is there any sysctl option I need to tune?
> I think this behaviour is the Delayed ACK feature of RFC1122 TCP stack.
>
> Link to tcpdump picture (done on a client machine) :
> http://i48.tinypic.com/35cpogx.png
>
> Can you tell why kernel delayed that FIN/ACK.
> In tcpflow data there is exacly one ACK per packet comming from server.
> Why kernel delayed client FIN/ACK.
> It could avoid sending ACK every 'data' packet.
> But it choose to delay FIN/ACK?
> Is this possible? Is this a bug?
>
> I've also posted question on stackexchange:
> http://stackoverflow.com/questions/11711218/client-sends-delayed-fin-ack-500ms-to-server
>
> Please help.
CC'ing netdev.
--
Thanks,
//richard
^ permalink raw reply
* [PATCH iproute2] Install the bridge command under the same name we build it.
From: Nick Alcock @ 2012-08-04 14:36 UTC (permalink / raw)
To: netdev
Signed-off-by: Nick Alcock <nick.alcock@oracle.com>
---
bridge/Makefile | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/bridge/Makefile b/bridge/Makefile
index 0c333bf..9a6743e 100644
--- a/bridge/Makefile
+++ b/bridge/Makefile
@@ -7,8 +7,8 @@ all: bridge
bridge: $(BROBJ) $(LIBNETLINK)
install: all
- install -m 0755 br $(DESTDIR)$(SBINDIR)
+ install -m 0755 bridge $(DESTDIR)$(SBINDIR)
clean:
- rm -f $(BROBJ) br
+ rm -f $(BROBJ) bridge
--
1.7.11.2.155.g5ceeb62
^ permalink raw reply related
* [PATCH iproute2] Add missing space preventing the installation of tc.8 and tc-codel.8.
From: Nick Alcock @ 2012-08-04 14:35 UTC (permalink / raw)
To: netdev
Signed-off-by: Nick Alcock <nick.alcock@oracle.com>
---
man/man8/Makefile | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/man/man8/Makefile b/man/man8/Makefile
index 1b671a4..c344094 100644
--- a/man/man8/Makefile
+++ b/man/man8/Makefile
@@ -3,7 +3,7 @@ TARGETS = ip-address.8 ip-link.8 ip-route.8
MAN8PAGES = $(TARGETS) ip.8 arpd.8 lnstat.8 routel.8 rtacct.8 rtmon.8 ss.8 \
tc-bfifo.8 tc-cbq-details.8 tc-cbq.8 tc-drr.8 tc-htb.8 \
tc-pfifo.8 tc-pfifo_fast.8 tc-prio.8 tc-red.8 tc-sfq.8 \
- tc-tbf.8 tc.8tc-codel.8 tc-fq_codel.8 tc-sfb.8 tc-netem.8 tc-choke.8 \
+ tc-tbf.8 tc.8 tc-codel.8 tc-fq_codel.8 tc-sfb.8 tc-netem.8 tc-choke.8 \
bridge.8 rtstat.8 ctstat.8 nstat.8 routef.8 \
ip-tunnel.8 ip-rule.8 ip-ntable.8 \
ip-monitor.8 tc-stab.8 tc-hfsc.8 ip-xfrm.8 ip-netns.8 \
--
1.7.11.2.155.g5ceeb62
^ permalink raw reply related
* [PATCH net] batman-adv: select an internet gateway if none was chosen
From: Antonio Quartulli @ 2012-08-04 14:13 UTC (permalink / raw)
To: davem-fT/PcQaiUtIeIZ0/mPfg9Q
Cc: netdev-u79uwXL29TY76Z2rM5mHXA,
b.a.t.m.a.n-ZwoEplunGu2X36UT3dwllkB+6BGkLq7r, Marek Lindner
From: Marek Lindner <lindner_marek-LWAfsSFWpa4@public.gmane.org>
This is a regression introduced by: 2265c141086474bbae55a5bb3afa1ebb78ccaa7c
Reported-by: Nicolás Echániz <nicoechaniz-A9NS9UNFlhlrovVCs/uTlw@public.gmane.org>
Signed-off-by: Marek Lindner <lindner_marek-LWAfsSFWpa4@public.gmane.org>
Acked-by: Antonio Quartulli <ordex-GaUfNO9RBHfsrOwW+9ziJQ@public.gmane.org>
Signed-off-by: Antonio Quartulli <ordex-GaUfNO9RBHfsrOwW+9ziJQ@public.gmane.org>
---
net/batman-adv/gateway_client.c | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/net/batman-adv/gateway_client.c b/net/batman-adv/gateway_client.c
index b421cc4..fc866f2 100644
--- a/net/batman-adv/gateway_client.c
+++ b/net/batman-adv/gateway_client.c
@@ -200,11 +200,11 @@ void batadv_gw_election(struct batadv_priv *bat_priv)
if (atomic_read(&bat_priv->gw_mode) != BATADV_GW_MODE_CLIENT)
goto out;
- if (!batadv_atomic_dec_not_zero(&bat_priv->gw_reselect))
- goto out;
-
curr_gw = batadv_gw_get_selected_gw_node(bat_priv);
+ if (!batadv_atomic_dec_not_zero(&bat_priv->gw_reselect) && curr_gw)
+ goto out;
+
next_gw = batadv_gw_get_best_gw_node(bat_priv);
if (curr_gw == next_gw)
--
1.7.9.4
^ permalink raw reply related
* Re: 3.4-rc: NETDEV WATCHDOG: eth0 (r8169): transmit queue 0 timed out
From: Stefan Richter @ 2012-08-04 12:22 UTC (permalink / raw)
To: Francois Romieu; +Cc: netdev
In-Reply-To: <20120602111335.0b94fb59@stein>
On Jun 02 Stefan Richter wrote:
> I haven't had time to look further into it yet. Just two minor findings:
>
> (a) After update from 3.4-rc5 to 3.4, the problem persisted.
>
> (b) Later I noticed that silent file corruptions on FireWire disks happened
> and happen under 3.4-rc5 and 3.4, so I reverted into 3.3.1 which fixed
> that issue. Furthermore, since 6 days uptime of 3.3.1, the eth0 (r8169)
> transmit queue time-out did never occur.
After a month uptime of 3.3.1 without any problems, I rebooted into 3.5
six days ago. The frequent "r8169 0000:0b:00.0: eth0: link up" messages
which I got with 3.4-rc5 and 3.4 no longer happen. Whatever was wrong
with my system, it no longer is. Either 3.5 fixed it or it was an issue
external to the kernel or even external to the PC.
--
Stefan Richter
-=====-===-- =--- --=--
http://arcgraph.de/sr/
^ permalink raw reply
* Re: [net 0/3][pull request] Intel Wired LAN Driver Updates
From: David Miller @ 2012-08-04 10:37 UTC (permalink / raw)
To: peter.p.waskiewicz.jr; +Cc: netdev, gospo, sassmann
In-Reply-To: <1344075952-4198-1-git-send-email-peter.p.waskiewicz.jr@intel.com>
From: Peter P Waskiewicz Jr <peter.p.waskiewicz.jr@intel.com>
Date: Sat, 4 Aug 2012 03:25:49 -0700
> This series contains various fixes to the igb driver.
>
> The following are changes since commit ff6e1225957cce9e93b8d84dc240e5a44094d0ec:
> cris: fix eth_v10.c build error
> and are available in the git repository at:
> git://git.kernel.org/pub/scm/linux/kernel/git/ppwaskie/net master
Pulled, thanks PJ.
^ permalink raw reply
* [net 3/3] igb: don't break user visible strings over multiple lines in igb_ethtool.c
From: Peter P Waskiewicz Jr @ 2012-08-04 10:25 UTC (permalink / raw)
To: davem; +Cc: Jesper Juhl, netdev, gospo, sassmann, Peter P Waskiewicz Jr
In-Reply-To: <1344075952-4198-1-git-send-email-peter.p.waskiewicz.jr@intel.com>
From: Jesper Juhl <jj@chaosbits.net>
Even when they go beyond 80 characters, user visible strings should be
on one line to make them easy to grep for.
Signed-off-by: Jesper Juhl <jj@chaosbits.net>
Tested-by: Jeff Pieper <jeffrey.e.pieper@intel.com>
Signed-off-by: Peter P Waskiewicz Jr <peter.p.waskiewicz.jr@intel.com>
---
drivers/net/ethernet/intel/igb/igb_ethtool.c | 23 +++++++++++------------
1 file changed, 11 insertions(+), 12 deletions(-)
diff --git a/drivers/net/ethernet/intel/igb/igb_ethtool.c b/drivers/net/ethernet/intel/igb/igb_ethtool.c
index ad489b7..90550f5 100644
--- a/drivers/net/ethernet/intel/igb/igb_ethtool.c
+++ b/drivers/net/ethernet/intel/igb/igb_ethtool.c
@@ -209,8 +209,8 @@ static int igb_set_settings(struct net_device *netdev, struct ethtool_cmd *ecmd)
/* When SoL/IDER sessions are active, autoneg/speed/duplex
* cannot be changed */
if (igb_check_reset_block(hw)) {
- dev_err(&adapter->pdev->dev, "Cannot change link "
- "characteristics when SoL/IDER is active.\n");
+ dev_err(&adapter->pdev->dev,
+ "Cannot change link characteristics when SoL/IDER is active.\n");
return -EINVAL;
}
@@ -1089,8 +1089,8 @@ static bool reg_pattern_test(struct igb_adapter *adapter, u64 *data,
wr32(reg, (_test[pat] & write));
val = rd32(reg) & mask;
if (val != (_test[pat] & write & mask)) {
- dev_err(&adapter->pdev->dev, "pattern test reg %04X "
- "failed: got 0x%08X expected 0x%08X\n",
+ dev_err(&adapter->pdev->dev,
+ "pattern test reg %04X failed: got 0x%08X expected 0x%08X\n",
reg, val, (_test[pat] & write & mask));
*data = reg;
return 1;
@@ -1108,8 +1108,8 @@ static bool reg_set_and_check(struct igb_adapter *adapter, u64 *data,
wr32(reg, write & mask);
val = rd32(reg);
if ((write & mask) != (val & mask)) {
- dev_err(&adapter->pdev->dev, "set/check reg %04X test failed:"
- " got 0x%08X expected 0x%08X\n", reg,
+ dev_err(&adapter->pdev->dev,
+ "set/check reg %04X test failed: got 0x%08X expected 0x%08X\n", reg,
(val & mask), (write & mask));
*data = reg;
return 1;
@@ -1171,8 +1171,9 @@ static int igb_reg_test(struct igb_adapter *adapter, u64 *data)
wr32(E1000_STATUS, toggle);
after = rd32(E1000_STATUS) & toggle;
if (value != after) {
- dev_err(&adapter->pdev->dev, "failed STATUS register test "
- "got: 0x%08X expected: 0x%08X\n", after, value);
+ dev_err(&adapter->pdev->dev,
+ "failed STATUS register test got: 0x%08X expected: 0x%08X\n",
+ after, value);
*data = 1;
return 1;
}
@@ -1777,16 +1778,14 @@ static int igb_loopback_test(struct igb_adapter *adapter, u64 *data)
* sessions are active */
if (igb_check_reset_block(&adapter->hw)) {
dev_err(&adapter->pdev->dev,
- "Cannot do PHY loopback test "
- "when SoL/IDER is active.\n");
+ "Cannot do PHY loopback test when SoL/IDER is active.\n");
*data = 0;
goto out;
}
if ((adapter->hw.mac.type == e1000_i210)
|| (adapter->hw.mac.type == e1000_i211)) {
dev_err(&adapter->pdev->dev,
- "Loopback test not supported "
- "on this part at this time.\n");
+ "Loopback test not supported on this part at this time.\n");
*data = 0;
goto out;
}
--
1.7.10.4
^ permalink raw reply related
* [net 2/3] igb: correct hardware type (i210/i211) check in igb_loopback_test()
From: Peter P Waskiewicz Jr @ 2012-08-04 10:25 UTC (permalink / raw)
To: davem; +Cc: Jesper Juhl, netdev, gospo, sassmann, Peter P Waskiewicz Jr
In-Reply-To: <1344075952-4198-1-git-send-email-peter.p.waskiewicz.jr@intel.com>
From: Jesper Juhl <jj@chaosbits.net>
In the original code
...
if ((adapter->hw.mac.type == e1000_i210)
|| (adapter->hw.mac.type == e1000_i210)) {
...
the second check of 'adapter->hw.mac.type' is pointless since it tests
for the exact same value as the first.
Signed-off-by: Jesper Juhl <jj@chaosbits.net>
Acked-by: Carolyn Wyborny <carolyn.wyborny@intel.com>
Tested-by: Jeff Pieper <jeffrey.e.pieper@intel.com>
Signed-off-by: Peter P Waskiewicz Jr <peter.p.waskiewicz.jr@intel.com>
---
drivers/net/ethernet/intel/igb/igb_ethtool.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/net/ethernet/intel/igb/igb_ethtool.c b/drivers/net/ethernet/intel/igb/igb_ethtool.c
index a19c84c..ad489b7 100644
--- a/drivers/net/ethernet/intel/igb/igb_ethtool.c
+++ b/drivers/net/ethernet/intel/igb/igb_ethtool.c
@@ -1783,7 +1783,7 @@ static int igb_loopback_test(struct igb_adapter *adapter, u64 *data)
goto out;
}
if ((adapter->hw.mac.type == e1000_i210)
- || (adapter->hw.mac.type == e1000_i210)) {
+ || (adapter->hw.mac.type == e1000_i211)) {
dev_err(&adapter->pdev->dev,
"Loopback test not supported "
"on this part at this time.\n");
--
1.7.10.4
^ permalink raw reply related
* [net 1/3] igb: Fix for failure to init on some 82576 devices.
From: Peter P Waskiewicz Jr @ 2012-08-04 10:25 UTC (permalink / raw)
To: davem; +Cc: Carolyn Wyborny, netdev, gospo, sassmann, Peter P Waskiewicz Jr
In-Reply-To: <1344075952-4198-1-git-send-email-peter.p.waskiewicz.jr@intel.com>
From: Carolyn Wyborny <carolyn.wyborny@intel.com>
Move nvm invalid size check to before size assigned by mac_type for
82575 and later parts in get_invariants function. This fixes a problem
found on some 82576 devices where the part will not initialize because
the nvm_read function pointer ends up getting assigned to the incorrect
function.
Reported By: Stefan Assmann <sassmann@redhat.com>
Signed-off-by: Carolyn Wyborny <carolyn.wyborny@intel.com>
Tested-by: Jeff Pieper <jeffrey.e.pieper@intel.com>
Signed-off-by: Peter P Waskiewicz Jr <peter.p.waskiewicz.jr@intel.com>
---
drivers/net/ethernet/intel/igb/e1000_82575.c | 16 ++++++++--------
1 file changed, 8 insertions(+), 8 deletions(-)
diff --git a/drivers/net/ethernet/intel/igb/e1000_82575.c b/drivers/net/ethernet/intel/igb/e1000_82575.c
index 5e84eaa..ba994fb 100644
--- a/drivers/net/ethernet/intel/igb/e1000_82575.c
+++ b/drivers/net/ethernet/intel/igb/e1000_82575.c
@@ -254,6 +254,14 @@ static s32 igb_get_invariants_82575(struct e1000_hw *hw)
*/
size += NVM_WORD_SIZE_BASE_SHIFT;
+ /*
+ * Check for invalid size
+ */
+ if ((hw->mac.type == e1000_82576) && (size > 15)) {
+ pr_notice("The NVM size is not valid, defaulting to 32K\n");
+ size = 15;
+ }
+
nvm->word_size = 1 << size;
if (hw->mac.type < e1000_i210) {
nvm->opcode_bits = 8;
@@ -281,14 +289,6 @@ static s32 igb_get_invariants_82575(struct e1000_hw *hw)
} else
nvm->type = e1000_nvm_flash_hw;
- /*
- * Check for invalid size
- */
- if ((hw->mac.type == e1000_82576) && (size > 15)) {
- pr_notice("The NVM size is not valid, defaulting to 32K\n");
- size = 15;
- }
-
/* NVM Function Pointers */
switch (hw->mac.type) {
case e1000_82580:
--
1.7.10.4
^ permalink raw reply related
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox