* Re: [RFC v2 6/7] tracepoint: use new hashtable implementation
From: Steven Rostedt @ 2012-08-05 0:36 UTC (permalink / raw)
To: Sasha Levin
Cc: torvalds, tj, akpm, linux-kernel, linux-mm, paul.gortmaker, davem,
mingo, ebiederm, aarcange, ericvh, netdev, Mathieu Desnoyers
In-Reply-To: <1344003788-1417-7-git-send-email-levinsasha928@gmail.com>
FYI, Mathieu is the author of this file.
-- Steve
On Fri, 2012-08-03 at 16:23 +0200, Sasha Levin wrote:
> Switch tracepoints to use the new hashtable implementation. This reduces the amount of
> generic unrelated code in the tracepoints.
>
> Signed-off-by: Sasha Levin <levinsasha928@gmail.com>
> ---
> kernel/tracepoint.c | 26 +++++++++-----------------
> 1 files changed, 9 insertions(+), 17 deletions(-)
>
> diff --git a/kernel/tracepoint.c b/kernel/tracepoint.c
> index d96ba22..b5a2650 100644
> --- a/kernel/tracepoint.c
> +++ b/kernel/tracepoint.c
> @@ -26,6 +26,7 @@
> #include <linux/slab.h>
> #include <linux/sched.h>
> #include <linux/static_key.h>
> +#include <linux/hashtable.h>
>
> extern struct tracepoint * const __start___tracepoints_ptrs[];
> extern struct tracepoint * const __stop___tracepoints_ptrs[];
> @@ -49,8 +50,7 @@ static LIST_HEAD(tracepoint_module_list);
> * Protected by tracepoints_mutex.
> */
> #define TRACEPOINT_HASH_BITS 6
> -#define TRACEPOINT_TABLE_SIZE (1 << TRACEPOINT_HASH_BITS)
> -static struct hlist_head tracepoint_table[TRACEPOINT_TABLE_SIZE];
> +DEFINE_STATIC_HASHTABLE(tracepoint_table, TRACEPOINT_HASH_BITS);
>
> /*
> * Note about RCU :
> @@ -191,16 +191,14 @@ tracepoint_entry_remove_probe(struct tracepoint_entry *entry,
> */
> static struct tracepoint_entry *get_tracepoint(const char *name)
> {
> - struct hlist_head *head;
> struct hlist_node *node;
> struct tracepoint_entry *e;
> u32 hash = jhash(name, strlen(name), 0);
>
> - head = &tracepoint_table[hash & (TRACEPOINT_TABLE_SIZE - 1)];
> - hlist_for_each_entry(e, node, head, hlist) {
> + hash_for_each_possible(&tracepoint_table, node, e, hlist, hash)
> if (!strcmp(name, e->name))
> return e;
> - }
> +
> return NULL;
> }
>
> @@ -210,19 +208,13 @@ static struct tracepoint_entry *get_tracepoint(const char *name)
> */
> static struct tracepoint_entry *add_tracepoint(const char *name)
> {
> - struct hlist_head *head;
> - struct hlist_node *node;
> struct tracepoint_entry *e;
> size_t name_len = strlen(name) + 1;
> u32 hash = jhash(name, name_len-1, 0);
>
> - head = &tracepoint_table[hash & (TRACEPOINT_TABLE_SIZE - 1)];
> - hlist_for_each_entry(e, node, head, hlist) {
> - if (!strcmp(name, e->name)) {
> - printk(KERN_NOTICE
> - "tracepoint %s busy\n", name);
> - return ERR_PTR(-EEXIST); /* Already there */
> - }
> + if (get_tracepoint(name)) {
> + printk(KERN_NOTICE "tracepoint %s busy\n", name);
> + return ERR_PTR(-EEXIST); /* Already there */
> }
> /*
> * Using kmalloc here to allocate a variable length element. Could
> @@ -234,7 +226,7 @@ static struct tracepoint_entry *add_tracepoint(const char *name)
> memcpy(&e->name[0], name, name_len);
> e->funcs = NULL;
> e->refcount = 0;
> - hlist_add_head(&e->hlist, head);
> + hash_add(&tracepoint_table, &e->hlist, hash);
> return e;
> }
>
> @@ -244,7 +236,7 @@ static struct tracepoint_entry *add_tracepoint(const char *name)
> */
> static inline void remove_tracepoint(struct tracepoint_entry *e)
> {
> - hlist_del(&e->hlist);
> + hash_del(&e->hlist);
> kfree(e);
> }
>
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>
^ permalink raw reply
* Re: [PATCH 00/13] SCTP: Enable netns
From: David Miller @ 2012-08-04 23:57 UTC (permalink / raw)
To: jan.ariyasu; +Cc: vyasevich, linux-sctp, netdev, linux-kernel, jan.ariyasu
In-Reply-To: <1344115837-6150-1-git-send-email-jan.ariyasu@hp.com>
From: Jan Ariyasu <jan.ariyasu@gmail.com>
Date: Sat, 4 Aug 2012 15:30:37 -0600
> 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>
Patch 02/13 didn't show up at all.
^ permalink raw reply
* Re: [PATCH V2 09/12] net/eipoib: Add main driver functionality
From: Eric W. Biederman @ 2012-08-04 23:19 UTC (permalink / raw)
To: Or Gerlitz, David Miller
Cc: ali, ogerlitz, roland, netdev, sean.hefty, erezsh
In-Reply-To: <CAJZOPZ+TJ7JLdvmh7a9mNAp0bujv0jQBG+5Aq9aU9MEVOJobeA@mail.gmail.com>
Or Gerlitz <or.gerlitz@gmail.com> wrote:
>On Sun, Aug 5, 2012 at 12:23 AM, Or Gerlitz <or.gerlitz@gmail.com>
>wrote:
>
>> 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.
>
>OK, when I said the PV stack, I meant the portion of the PV stack
>which assumes Ethernet link layer, ofcourse... If someone uses routing
>they don't need this driver.
>
>Again, since the app only uses IP, which is well defined, etc. the
>work done by the eipoib driver, didn't seem as hackish messing, so I'm
>again with that WW (Why/What) question from 5m ago.
Something is missing from your sentence.
What is the alternative that you view as worse?
Juast as a point of information. In general when bridging is desired but not possible people deploy proxy arp.
I completely fail to see how having the VM output to a tun interface and then routing that, would not be supported by current solutions. I believe that is where VM solutions all started networking wise. Outputting to an interface is needed to support interfaces like 802.11 where bridging frequently does not work.
Eric
^ permalink raw reply
* Re: TCP stalls with 802.3ad + bridge + kvm guest
From: Peter Samuelson @ 2012-08-04 22:45 UTC (permalink / raw)
To: Jesse Brandeburg; +Cc: Jay Vosburgh, netdev, jgoerzen
In-Reply-To: <20120804162219.GT17572@p12n.org>
> [Jesse Brandeburg]
> > try
> > # ethtool -K ethx tso off gso off lro off
Specifically, 'lro off' is the trick. The others don't have a
noticeable effect. Now I can get 70 MB/s or better most of the time,
in either direction.
Thanks again,
Peter
^ permalink raw reply
* Re: [PATCH V2 09/12] net/eipoib: Add main driver functionality
From: Or Gerlitz @ 2012-08-04 21:44 UTC (permalink / raw)
To: David Miller; +Cc: ali, ebiederm, ogerlitz, roland, netdev, sean.hefty, erezsh
In-Reply-To: <CAJZOPZJ=WPXcEysh-2p+pmY7RJME24zySWHGzGYbOq9LKidvBA@mail.gmail.com>
On Sun, Aug 5, 2012 at 12:23 AM, Or Gerlitz <or.gerlitz@gmail.com> wrote:
> 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.
OK, when I said the PV stack, I meant the portion of the PV stack
which assumes Ethernet link layer, ofcourse... If someone uses routing
they don't need this driver.
Again, since the app only uses IP, which is well defined, etc. the
work done by the eipoib driver, didn't seem as hackish messing, so I'm
again with that WW (Why/What) question from 5m ago.
Or.
^ permalink raw reply
* [PATCH 13/13] SCTP: make socket-initialization use per-namespace protocol parameters.
From: Jan Ariyasu @ 2012-08-04 21:34 UTC (permalink / raw)
To: Vlad Yasevich, David S. Miller, linux-sctp, netdev, linux-kernel
Cc: Jan Ariyasu
Made the last few protocol parameters per-namespace; sndbuf_policy,
rcvbuf_policy, addip_enable, addip_noauth_enable and prsctp_enable.
Signed-off-by: Jan Ariyasu <jan.ariyasu@hp.com>
---
net/sctp/endpointola.c | 6 ++---
net/sctp/protocol.c | 6 ++---
net/sctp/sm_statefuns.c | 12 ++++++---
net/sctp/sm_statetable.c | 4 +--
net/sctp/socket.c | 67 +++++++++++++++++++++++++++-------------------
5 files changed, 55 insertions(+), 40 deletions(-)
diff --git a/net/sctp/endpointola.c b/net/sctp/endpointola.c
index 5fa20a1..b919d71 100644
--- a/net/sctp/endpointola.c
+++ b/net/sctp/endpointola.c
@@ -109,7 +109,7 @@ static struct sctp_endpoint *sctp_endpoint_init(struct sctp_endpoint *ep,
/* If the Add-IP functionality is enabled, we must
* authenticate, ASCONF and ASCONF-ACK chunks
*/
- if (sctp_addip_enable) {
+ if (net_params->addip_enable) {
auth_chunks->chunks[0] = SCTP_CID_ASCONF;
auth_chunks->chunks[1] = SCTP_CID_ASCONF_ACK;
auth_chunks->param_hdr.length =
@@ -143,14 +143,14 @@ static struct sctp_endpoint *sctp_endpoint_init(struct sctp_endpoint *ep,
INIT_LIST_HEAD(&ep->asocs);
/* Use SCTP specific send buffer space queues. */
- ep->sndbuf_policy = sctp_sndbuf_policy;
+ ep->sndbuf_policy = net_params->sndbuf_policy;
sk->sk_data_ready = sctp_data_ready;
sk->sk_write_space = sctp_write_space;
sock_set_flag(sk, SOCK_USE_WRITE_QUEUE);
/* Get the receive buffer policy for this endpoint */
- ep->rcvbuf_policy = sctp_rcvbuf_policy;
+ ep->rcvbuf_policy = net_params->rcvbuf_policy;
/* Initialize the secret key used with cookie. */
get_random_bytes(&ep->secret_key[0], SCTP_SECRET_SIZE);
diff --git a/net/sctp/protocol.c b/net/sctp/protocol.c
index 6862bf0..b819424 100644
--- a/net/sctp/protocol.c
+++ b/net/sctp/protocol.c
@@ -665,7 +665,8 @@ void sctp_addr_wq_timeout_handler(unsigned long arg)
}
}
#endif
- list_for_each_entry(sp, &sctp_auto_asconf_splist, auto_asconf_list) {
+ list_for_each_entry(sp, &net_params->auto_asconf_splist,
+ auto_asconf_list) {
struct sock *sk;
sk = sctp_opt2sk(sp);
@@ -1082,6 +1083,7 @@ static const struct net_protocol sctp_protocol = {
.handler = sctp_rcv,
.err_handler = sctp_v4_err,
.no_policy = 1,
+ .netns_ok = 1,
};
/* IPv4 address related functions. */
@@ -1658,8 +1660,6 @@ SCTP_STATIC __init int sctp_init(void)
sctp_v4_pf_init();
sctp_v6_pf_init();
-
-
/* Register SCTP protocol */
status = sctp_v4_protosw_init();
if (status)
diff --git a/net/sctp/sm_statefuns.c b/net/sctp/sm_statefuns.c
index 8f41f42..0778f05 100644
--- a/net/sctp/sm_statefuns.c
+++ b/net/sctp/sm_statefuns.c
@@ -3594,6 +3594,8 @@ sctp_disposition_t sctp_sf_do_asconf(struct net *net,
union sctp_addr_param *addr_param;
__u32 serial;
int length;
+ struct sctp_net_params *net_params =
+ sctp_get_params(net);
if (!sctp_vtag_verify(chunk, asoc)) {
sctp_add_cmd_sf(commands, SCTP_CMD_REPORT_BAD_TAG,
@@ -3607,9 +3609,9 @@ sctp_disposition_t sctp_sf_do_asconf(struct net *net,
* is received unauthenticated it MUST be silently discarded as
* described in [I-D.ietf-tsvwg-sctp-auth].
*/
- if (!sctp_addip_noauth && !chunk->auth)
- return sctp_sf_discard_chunk(net, ep, asoc, type,
- arg, commands);
+ if (!net_params->addip_noauth_enable && !chunk->auth)
+ 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)))
@@ -3723,6 +3725,8 @@ sctp_disposition_t sctp_sf_do_asconf_ack(struct net *net,
struct sctp_paramhdr *err_param = NULL;
sctp_addiphdr_t *addip_hdr;
__u32 sent_serial, rcvd_serial;
+ struct sctp_net_params *net_params =
+ sctp_get_params(net);
if (!sctp_vtag_verify(asconf_ack, asoc)) {
sctp_add_cmd_sf(commands, SCTP_CMD_REPORT_BAD_TAG,
@@ -3736,7 +3740,7 @@ sctp_disposition_t sctp_sf_do_asconf_ack(struct net *net,
* is received unauthenticated it MUST be silently discarded as
* described in [I-D.ietf-tsvwg-sctp-auth].
*/
- if (!sctp_addip_noauth && !asconf_ack->auth)
+ if (!net_params->addip_noauth_enable && !asconf_ack->auth)
return sctp_sf_discard_chunk(net, ep, asoc, type, arg,
commands);
diff --git a/net/sctp/sm_statetable.c b/net/sctp/sm_statetable.c
index 5177130..b5d1801 100644
--- a/net/sctp/sm_statetable.c
+++ b/net/sctp/sm_statetable.c
@@ -919,12 +919,12 @@ static const sctp_sm_table_entry_t *sctp_chunk_event_lookup(struct net *net,
if (cid <= SCTP_CID_BASE_MAX)
return &chunk_event_table[cid][state];
- if (sctp_prsctp_enable) {
+ if (net_params->prsctp_enable) {
if (cid == SCTP_CID_FWD_TSN)
return &prsctp_chunk_event_table[0][state];
}
- if (sctp_addip_enable) {
+ if (net_params->addip_enable) {
if (cid == SCTP_CID_ASCONF)
return &addip_chunk_event_table[0][state];
diff --git a/net/sctp/socket.c b/net/sctp/socket.c
index e8148a0..219712c 100644
--- a/net/sctp/socket.c
+++ b/net/sctp/socket.c
@@ -534,8 +534,10 @@ static int sctp_send_asconf_add_ip(struct net *net,
struct list_head *p;
int i;
int retval = 0;
+ struct sctp_net_params *net_params =
+ sctp_get_params(net);
- if (!sctp_addip_enable)
+ if (!net_params->addip_enable)
return retval;
sp = sctp_sk(sk);
@@ -737,9 +739,11 @@ static int sctp_send_asconf_del_ip(struct net *net,
int i;
int retval = 0;
int stored = 0;
+ struct sctp_net_params *net_params =
+ sctp_get_params(net);
chunk = NULL;
- if (!sctp_addip_enable)
+ if (!net_params->addip_enable)
return retval;
sp = sctp_sk(sk);
@@ -1077,6 +1081,7 @@ static int __sctp_connect(struct sock* sk,
void *addr_buf;
unsigned short port;
unsigned int f_flags = 0;
+ struct net *net = sock_net(sk);
sp = sctp_sk(sk);
ep = sp->ep;
@@ -1181,9 +1186,8 @@ static int __sctp_connect(struct sock* sk,
goto out_free;
}
- err = sctp_assoc_set_bind_addr_from_ep(asoc,
- sock_net(sk), scope,
- GFP_KERNEL);
+ err = sctp_assoc_set_bind_addr_from_ep(asoc, net,
+ scope, GFP_KERNEL);
if (err < 0) {
goto out_free;
}
@@ -1212,7 +1216,7 @@ static int __sctp_connect(struct sock* sk,
goto out_free;
}
- err = sctp_primitive_ASSOCIATE(sock_net(sk), asoc, NULL);
+ err = sctp_primitive_ASSOCIATE(net, asoc, NULL);
if (err < 0) {
goto out_free;
}
@@ -3059,10 +3063,12 @@ static int sctp_setsockopt_peer_primary_addr(struct sock *sk, char __user *optva
struct sctp_chunk *chunk;
struct sctp_af *af;
int err;
+ struct sctp_net_params *net_params =
+ sctp_get_params(sock_net(sk));
sp = sctp_sk(sk);
- if (!sctp_addip_enable)
+ if (!net_params->addip_enable)
return -EPERM;
if (optlen != sizeof(struct sctp_setpeerprim))
@@ -3417,9 +3423,8 @@ static int sctp_setsockopt_active_key(struct sock *sk,
{
struct sctp_authkeyid val;
struct sctp_association *asoc;
- struct net *net = sock_net(sk);
struct sctp_net_params *net_params =
- sctp_get_params(net);
+ sctp_get_params(sock_net(sk));
if (!net_params->auth_enable)
return -EACCES;
@@ -3433,8 +3438,8 @@ static int sctp_setsockopt_active_key(struct sock *sk,
if (!asoc && val.scact_assoc_id && sctp_style(sk, UDP))
return -EINVAL;
- return sctp_auth_set_active_key(net, sctp_sk(sk)->ep, asoc,
- val.scact_keynumber);
+ return sctp_auth_set_active_key(sock_net(sk), sctp_sk(sk)->ep,
+ asoc, val.scact_keynumber);
}
/*
@@ -3487,6 +3492,8 @@ static int sctp_setsockopt_auto_asconf(struct sock *sk, char __user *optval,
{
int val;
struct sctp_sock *sp = sctp_sk(sk);
+ struct sctp_net_params *net_params =
+ sctp_get_params(sock_net(sk));
if (optlen < sizeof(int))
return -EINVAL;
@@ -3502,7 +3509,7 @@ static int sctp_setsockopt_auto_asconf(struct sock *sk, char __user *optval,
sp->do_auto_asconf = 0;
} else if (val && !sp->do_auto_asconf) {
list_add_tail(&sp->auto_asconf_list,
- &sctp_auto_asconf_splist);
+ &net_params->auto_asconf_splist);
sp->do_auto_asconf = 1;
}
return 0;
@@ -3876,6 +3883,8 @@ SCTP_STATIC int sctp_init_sock(struct sock *sk)
{
struct sctp_endpoint *ep;
struct sctp_sock *sp;
+ struct sctp_net_params *net_params =
+ sctp_get_params(sock_net(sk));
SCTP_DEBUG_PRINTK("sctp_init_sock(sk: %p)\n", sk);
@@ -3903,32 +3912,32 @@ SCTP_STATIC int sctp_init_sock(struct sock *sk)
sp->default_timetolive = 0;
sp->default_rcv_context = 0;
- sp->max_burst = sctp_max_burst;
+ sp->max_burst = net_params->max_burst;
/* Initialize default setup parameters. These parameters
* can be modified with the SCTP_INITMSG socket option or
* overridden by the SCTP_INIT CMSG.
*/
- sp->initmsg.sinit_num_ostreams = sctp_max_outstreams;
- sp->initmsg.sinit_max_instreams = sctp_max_instreams;
- sp->initmsg.sinit_max_attempts = sctp_max_retrans_init;
- sp->initmsg.sinit_max_init_timeo = sctp_rto_max;
+ sp->initmsg.sinit_num_ostreams = net_params->max_outstreams;
+ sp->initmsg.sinit_max_instreams = net_params->max_instreams;
+ sp->initmsg.sinit_max_attempts = net_params->max_retrans_init;
+ sp->initmsg.sinit_max_init_timeo = net_params->rto_max;
/* Initialize default RTO related parameters. These parameters can
* be modified for with the SCTP_RTOINFO socket option.
*/
- sp->rtoinfo.srto_initial = sctp_rto_initial;
- sp->rtoinfo.srto_max = sctp_rto_max;
- sp->rtoinfo.srto_min = sctp_rto_min;
+ sp->rtoinfo.srto_initial = net_params->rto_initial;
+ sp->rtoinfo.srto_max = net_params->rto_max;
+ sp->rtoinfo.srto_min = net_params->rto_min;
/* Initialize default association related parameters. These parameters
* can be modified with the SCTP_ASSOCINFO socket option.
*/
- sp->assocparams.sasoc_asocmaxrxt = sctp_max_retrans_association;
+ sp->assocparams.sasoc_asocmaxrxt = net_params->max_retrans_association;
sp->assocparams.sasoc_number_peer_destinations = 0;
sp->assocparams.sasoc_peer_rwnd = 0;
sp->assocparams.sasoc_local_rwnd = 0;
- sp->assocparams.sasoc_cookie_life = sctp_valid_cookie_life;
+ sp->assocparams.sasoc_cookie_life = net_params->valid_cookie_life;
/* Initialize default event subscriptions. By default, all the
* options are off.
@@ -3938,10 +3947,10 @@ SCTP_STATIC int sctp_init_sock(struct sock *sk)
/* Default Peer Address Parameters. These defaults can
* be modified via SCTP_PEER_ADDR_PARAMS
*/
- sp->hbinterval = sctp_hb_interval;
- sp->pathmaxrxt = sctp_max_retrans_path;
+ sp->hbinterval = net_params->hb_interval;
+ sp->pathmaxrxt = net_params->max_retrans_path;
sp->pathmtu = 0; // allow default discovery
- sp->sackdelay = sctp_sack_timeout;
+ sp->sackdelay = net_params->sack_timeout;
sp->sackfreq = 2;
sp->param_flags = SPP_HB_ENABLE |
SPP_PMTUD_ENABLE |
@@ -3993,9 +4002,9 @@ SCTP_STATIC int sctp_init_sock(struct sock *sk)
local_bh_disable();
percpu_counter_inc(&sctp_sockets_allocated);
sock_prot_inuse_add(sock_net(sk), sk->sk_prot, 1);
- if (sctp_default_auto_asconf) {
+ if (net_params->default_auto_asconf) {
list_add_tail(&sp->auto_asconf_list,
- &sctp_auto_asconf_splist);
+ &net_params->auto_asconf_splist);
sp->do_auto_asconf = 1;
} else
sp->do_auto_asconf = 0;
@@ -4684,9 +4693,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;
--
1.7.9.5
^ permalink raw reply related
* [PATCH 12/13] SCTP: Enable chunk-auth verification (RFC4895).
From: Jan Ariyasu @ 2012-08-04 21:34 UTC (permalink / raw)
To: Vlad Yasevich, David S. Miller, linux-sctp, netdev, linux-kernel
Cc: Jan Ariyasu
This patch replaces the global parameter sctp_auth_enable with
the per-namespace parameter stored in struct net.
Signed-off-by: Jan Ariyasu <jan.ariyasu@hp.com>
---
net/sctp/endpointola.c | 4 +++-
net/sctp/sm_statetable.c | 11 +++++++----
net/sctp/socket.c | 32 ++++++++++++++++++++++++--------
3 files changed, 34 insertions(+), 13 deletions(-)
diff --git a/net/sctp/endpointola.c b/net/sctp/endpointola.c
index 750df47..5fa20a1 100644
--- a/net/sctp/endpointola.c
+++ b/net/sctp/endpointola.c
@@ -70,12 +70,14 @@ static struct sctp_endpoint *sctp_endpoint_init(struct sctp_endpoint *ep,
struct sctp_shared_key *null_key;
int err;
struct net *net = sock_net(sk);
+ struct sctp_net_params *net_params =
+ sctp_get_params(net);
ep->digest = kzalloc(SCTP_SIGNATURE_SIZE, gfp);
if (!ep->digest)
return NULL;
- if (sctp_auth_enable) {
+ if (net_params->auth_enable) {
/* Allocate space for HMACS and CHUNKS authentication
* variables. There are arrays that we encode directly
* into parameters to make the rest of the operations easier.
diff --git a/net/sctp/sm_statetable.c b/net/sctp/sm_statetable.c
index c249e59..5177130 100644
--- a/net/sctp/sm_statetable.c
+++ b/net/sctp/sm_statetable.c
@@ -59,7 +59,8 @@ other_event_table[SCTP_NUM_OTHER_TYPES][SCTP_STATE_NUM_STATES];
static const sctp_sm_table_entry_t
timeout_event_table[SCTP_NUM_TIMEOUT_TYPES][SCTP_STATE_NUM_STATES];
-static const sctp_sm_table_entry_t *sctp_chunk_event_lookup(sctp_cid_t cid,
+static const sctp_sm_table_entry_t *sctp_chunk_event_lookup(struct net *net,
+ sctp_cid_t cid,
sctp_state_t state);
@@ -89,7 +90,7 @@ const sctp_sm_table_entry_t *sctp_sm_lookup_event(struct net *net,
{
switch (event_type) {
case SCTP_EVENT_T_CHUNK:
- return sctp_chunk_event_lookup(event_subtype.chunk, state);
+ return sctp_chunk_event_lookup(net, event_subtype.chunk, state);
case SCTP_EVENT_T_TIMEOUT:
return DO_LOOKUP(SCTP_EVENT_TIMEOUT_MAX, timeout,
timeout_event_table);
@@ -907,9 +908,11 @@ static const sctp_sm_table_entry_t timeout_event_table[SCTP_NUM_TIMEOUT_TYPES][S
TYPE_SCTP_EVENT_TIMEOUT_AUTOCLOSE,
};
-static const sctp_sm_table_entry_t *sctp_chunk_event_lookup(sctp_cid_t cid,
+static const sctp_sm_table_entry_t *sctp_chunk_event_lookup(struct net *net,
+ sctp_cid_t cid,
sctp_state_t state)
{
+ struct sctp_net_params *net_params = sctp_get_params(net);
if (state > SCTP_STATE_MAX)
return &bug;
@@ -929,7 +932,7 @@ static const sctp_sm_table_entry_t *sctp_chunk_event_lookup(sctp_cid_t cid,
return &addip_chunk_event_table[1][state];
}
- if (sctp_auth_enable) {
+ if (net_params->auth_enable) {
if (cid == SCTP_CID_AUTH)
return &auth_chunk_event_table[0][state];
}
diff --git a/net/sctp/socket.c b/net/sctp/socket.c
index 9712ea5..e8148a0 100644
--- a/net/sctp/socket.c
+++ b/net/sctp/socket.c
@@ -3300,8 +3300,10 @@ static int sctp_setsockopt_auth_chunk(struct sock *sk,
unsigned int optlen)
{
struct sctp_authchunk val;
+ struct sctp_net_params *net_params =
+ sctp_get_params(sock_net(sk));
- if (!sctp_auth_enable)
+ if (!net_params->auth_enable)
return -EACCES;
if (optlen != sizeof(struct sctp_authchunk))
@@ -3334,8 +3336,10 @@ static int sctp_setsockopt_hmac_ident(struct sock *sk,
struct sctp_hmacalgo *hmacs;
u32 idents;
int err;
+ struct sctp_net_params *net_params =
+ sctp_get_params(sock_net(sk));
- if (!sctp_auth_enable)
+ if (!net_params->auth_enable)
return -EACCES;
if (optlen < sizeof(struct sctp_hmacalgo))
@@ -3371,8 +3375,10 @@ static int sctp_setsockopt_auth_key(struct sock *sk,
struct sctp_authkey *authkey;
struct sctp_association *asoc;
int ret;
+ struct sctp_net_params *net_params =
+ sctp_get_params(sock_net(sk));
- if (!sctp_auth_enable)
+ if (!net_params->auth_enable)
return -EACCES;
if (optlen <= sizeof(struct sctp_authkey))
@@ -3442,8 +3448,10 @@ static int sctp_setsockopt_del_key(struct sock *sk,
{
struct sctp_authkeyid val;
struct sctp_association *asoc;
+ struct sctp_net_params *net_params =
+ sctp_get_params(sock_net(sk));
- if (!sctp_auth_enable)
+ if (!net_params->auth_enable)
return -EACCES;
if (optlen != sizeof(struct sctp_authkeyid))
@@ -5326,8 +5334,10 @@ static int sctp_getsockopt_hmac_ident(struct sock *sk, int len,
struct sctp_hmac_algo_param *hmacs;
__u16 data_len = 0;
u32 num_idents;
+ struct sctp_net_params *net_params =
+ sctp_get_params(sock_net(sk));
- if (!sctp_auth_enable)
+ if (!net_params->auth_enable)
return -EACCES;
hmacs = sctp_sk(sk)->ep->auth_hmacs_list;
@@ -5353,8 +5363,10 @@ static int sctp_getsockopt_active_key(struct sock *sk, int len,
{
struct sctp_authkeyid val;
struct sctp_association *asoc;
+ struct sctp_net_params *net_params =
+ sctp_get_params(sock_net(sk));
- if (!sctp_auth_enable)
+ if (!net_params->auth_enable)
return -EACCES;
if (len < sizeof(struct sctp_authkeyid))
@@ -5389,8 +5401,10 @@ static int sctp_getsockopt_peer_auth_chunks(struct sock *sk, int len,
struct sctp_chunks_param *ch;
u32 num_chunks = 0;
char __user *to;
+ struct sctp_net_params *net_params =
+ sctp_get_params(sock_net(sk));
- if (!sctp_auth_enable)
+ if (!net_params->auth_enable)
return -EACCES;
if (len < sizeof(struct sctp_authchunks))
@@ -5432,8 +5446,10 @@ static int sctp_getsockopt_local_auth_chunks(struct sock *sk, int len,
struct sctp_chunks_param *ch;
u32 num_chunks = 0;
char __user *to;
+ struct sctp_net_params *net_params =
+ sctp_get_params(sock_net(sk));
- if (!sctp_auth_enable)
+ if (!net_params->auth_enable)
return -EACCES;
if (len < sizeof(struct sctp_authchunks))
--
1.7.9.5
^ permalink raw reply related
* [PATCH 11/13] SCTP: enable chunks to use per-namespace parameters.
From: Jan Ariyasu @ 2012-08-04 21:34 UTC (permalink / raw)
To: Vlad Yasevich, David S. Miller, linux-sctp, netdev, linux-kernel
Cc: Jan Ariyasu
This patch set enables the chunk-formatting machinery to use
per-namespace protocol parameters.
Signed-off-by: Jan Ariyasu <jan.ariyasu@hp.com>
---
include/net/sctp/sm.h | 66 ++++++++----
include/net/sctp/structs.h | 3 +-
net/sctp/chunk.c | 6 +-
net/sctp/protocol.c | 3 -
net/sctp/sm_make_chunk.c | 254 +++++++++++++++++++++++++++-----------------
net/sctp/sm_sideeffect.c | 23 ++--
net/sctp/sm_statefuns.c | 82 +++++++-------
net/sctp/socket.c | 25 +++--
8 files changed, 272 insertions(+), 190 deletions(-)
diff --git a/include/net/sctp/sm.h b/include/net/sctp/sm.h
index 8b1a4a6..a7b635c 100644
--- a/include/net/sctp/sm.h
+++ b/include/net/sctp/sm.h
@@ -191,74 +191,95 @@ __u32 sctp_generate_verification_tag(void);
void sctp_populate_tie_tags(__u8 *cookie, __u32 curTag, __u32 hisTag);
/* Prototypes for chunk-building functions. */
-struct sctp_chunk *sctp_make_init(const struct sctp_association *,
+struct sctp_chunk *sctp_make_init(struct net *,
+ const struct sctp_association *,
const struct sctp_bind_addr *,
gfp_t gfp, int vparam_len);
-struct sctp_chunk *sctp_make_init_ack(const struct sctp_association *,
+struct sctp_chunk *sctp_make_init_ack(struct net *net,
+ const struct sctp_association *,
const struct sctp_chunk *,
const gfp_t gfp,
const int unkparam_len);
-struct sctp_chunk *sctp_make_cookie_echo(const struct sctp_association *,
+struct sctp_chunk *sctp_make_cookie_echo(struct net *,
+ const struct sctp_association *,
const struct sctp_chunk *);
-struct sctp_chunk *sctp_make_cookie_ack(const struct sctp_association *,
+struct sctp_chunk *sctp_make_cookie_ack(struct net *,
+ const struct sctp_association *,
const struct sctp_chunk *);
-struct sctp_chunk *sctp_make_cwr(const struct sctp_association *,
+struct sctp_chunk *sctp_make_cwr(struct net *,
+ const struct sctp_association *,
const __u32 lowest_tsn,
const struct sctp_chunk *);
-struct sctp_chunk * sctp_make_datafrag_empty(struct sctp_association *,
+struct sctp_chunk *sctp_make_datafrag_empty(struct net *,
+ struct sctp_association *,
const struct sctp_sndrcvinfo *sinfo,
int len, const __u8 flags,
__u16 ssn);
struct sctp_chunk *sctp_make_ecne(const struct sctp_association *,
const __u32);
struct sctp_chunk *sctp_make_sack(const struct sctp_association *);
-struct sctp_chunk *sctp_make_shutdown(const struct sctp_association *asoc,
+struct sctp_chunk *sctp_make_shutdown(struct net *net,
+ const struct sctp_association *asoc,
const struct sctp_chunk *chunk);
-struct sctp_chunk *sctp_make_shutdown_ack(const struct sctp_association *asoc,
+struct sctp_chunk *sctp_make_shutdown_ack(struct net *net,
+ const struct sctp_association *asoc,
const struct sctp_chunk *);
-struct sctp_chunk *sctp_make_shutdown_complete(const struct sctp_association *,
+struct sctp_chunk *sctp_make_shutdown_complete(struct net *net,
+ const struct sctp_association *,
const struct sctp_chunk *);
void sctp_init_cause(struct sctp_chunk *, __be16 cause, size_t);
-struct sctp_chunk *sctp_make_abort(const struct sctp_association *,
+struct sctp_chunk *sctp_make_abort(struct net *,
+ const struct sctp_association *,
const struct sctp_chunk *,
const size_t hint);
-struct sctp_chunk *sctp_make_abort_no_data(const struct sctp_association *,
+struct sctp_chunk *sctp_make_abort_no_data(struct net *,
+ const struct sctp_association *,
const struct sctp_chunk *,
__u32 tsn);
-struct sctp_chunk *sctp_make_abort_user(const struct sctp_association *,
+struct sctp_chunk *sctp_make_abort_user(struct net *,
+ const struct sctp_association *,
const struct msghdr *, size_t msg_len);
-struct sctp_chunk *sctp_make_abort_violation(const struct sctp_association *,
+struct sctp_chunk *sctp_make_abort_violation(struct net *,
+ const struct sctp_association *,
const struct sctp_chunk *,
const __u8 *,
const size_t );
-struct sctp_chunk *sctp_make_violation_paramlen(const struct sctp_association *,
+struct sctp_chunk *sctp_make_violation_paramlen(struct net *,
+ const struct sctp_association *,
const struct sctp_chunk *,
struct sctp_paramhdr *);
-struct sctp_chunk *sctp_make_heartbeat(const struct sctp_association *,
+struct sctp_chunk *sctp_make_heartbeat(struct net *,
+ const struct sctp_association *,
const struct sctp_transport *);
-struct sctp_chunk *sctp_make_heartbeat_ack(const struct sctp_association *,
+struct sctp_chunk *sctp_make_heartbeat_ack(struct net *net,
+ const struct sctp_association *,
const struct sctp_chunk *,
const void *payload,
const size_t paylen);
-struct sctp_chunk *sctp_make_op_error(const struct sctp_association *,
+struct sctp_chunk *sctp_make_op_error(struct net *net,
+ const struct sctp_association *,
const struct sctp_chunk *chunk,
__be16 cause_code,
const void *payload,
size_t paylen,
size_t reserve_tail);
-struct sctp_chunk *sctp_make_asconf_update_ip(struct sctp_association *,
+struct sctp_chunk *sctp_make_asconf_update_ip(struct net *,
+ struct sctp_association *,
union sctp_addr *,
struct sockaddr *,
int, __be16);
-struct sctp_chunk *sctp_make_asconf_set_prim(struct sctp_association *asoc,
+struct sctp_chunk *sctp_make_asconf_set_prim(struct net *net,
+ struct sctp_association *asoc,
union sctp_addr *addr);
int sctp_verify_asconf(const struct sctp_association *asoc,
struct sctp_paramhdr *param_hdr, void *chunk_end,
struct sctp_paramhdr **errp);
-struct sctp_chunk *sctp_process_asconf(struct sctp_association *asoc,
+struct sctp_chunk *sctp_process_asconf(struct net *net,
+ struct sctp_association *asoc,
struct sctp_chunk *asconf);
-int sctp_process_asconf_ack(struct sctp_association *asoc,
+int sctp_process_asconf_ack(struct net *net,
+ struct sctp_association *asoc,
struct sctp_chunk *asconf_ack);
struct sctp_chunk *sctp_make_fwdtsn(const struct sctp_association *asoc,
__u32 new_cum_tsn, size_t nstreams,
@@ -285,7 +306,8 @@ void sctp_generate_proto_unreach_event(unsigned long peer);
void sctp_ootb_pkt_free(struct sctp_packet *);
-struct sctp_association *sctp_unpack_cookie(const struct sctp_endpoint *,
+struct sctp_association *sctp_unpack_cookie(struct net *net,
+ const struct sctp_endpoint *,
const struct sctp_association *,
struct sctp_chunk *,
gfp_t gfp, int *err,
diff --git a/include/net/sctp/structs.h b/include/net/sctp/structs.h
index dc2998a..bee5f74 100644
--- a/include/net/sctp/structs.h
+++ b/include/net/sctp/structs.h
@@ -1568,7 +1568,8 @@ struct sctp_endpoint *sctp_endpoint_is_match(struct sctp_endpoint *,
int sctp_has_association(const union sctp_addr *laddr,
const union sctp_addr *paddr);
-int sctp_verify_init(const struct sctp_association *asoc, sctp_cid_t,
+int sctp_verify_init(struct net *net,
+ 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,
diff --git a/net/sctp/chunk.c b/net/sctp/chunk.c
index 5211278..8c691aa 100644
--- a/net/sctp/chunk.c
+++ b/net/sctp/chunk.c
@@ -279,7 +279,8 @@ struct sctp_datamsg *sctp_datamsg_from_user(struct net *net,
frag |= SCTP_DATA_SACK_IMM;
}
- chunk = sctp_make_datafrag_empty(asoc, sinfo, len, frag, 0);
+ chunk = sctp_make_datafrag_empty(net, asoc, sinfo, len,
+ frag, 0);
if (!chunk)
goto errout;
@@ -314,7 +315,8 @@ struct sctp_datamsg *sctp_datamsg_from_user(struct net *net,
(sinfo->sinfo_flags & SCTP_SACK_IMMEDIATELY))
frag |= SCTP_DATA_SACK_IMM;
- chunk = sctp_make_datafrag_empty(asoc, sinfo, over, frag, 0);
+ chunk = sctp_make_datafrag_empty(net, asoc, sinfo, over,
+ frag, 0);
if (!chunk)
goto errout;
diff --git a/net/sctp/protocol.c b/net/sctp/protocol.c
index 32bb8f4e2..6862bf0 100644
--- a/net/sctp/protocol.c
+++ b/net/sctp/protocol.c
@@ -71,9 +71,6 @@
struct sctp_globals sctp_globals __read_mostly;
DEFINE_SNMP_STAT(struct sctp_mib, sctp_statistics) __read_mostly;
-struct idr sctp_assocs_id;
-DEFINE_SPINLOCK(sctp_assocs_id_lock);
-
/*
* This id will allow us to access per-namespace globals in
* struct sctp_ns_globals, defined as net_generic in struct net.
diff --git a/net/sctp/sm_make_chunk.c b/net/sctp/sm_make_chunk.c
index 1d6c8b6..6cecff5 100644
--- a/net/sctp/sm_make_chunk.c
+++ b/net/sctp/sm_make_chunk.c
@@ -69,7 +69,8 @@
#include <net/sctp/sm.h>
SCTP_STATIC
-struct sctp_chunk *sctp_make_chunk(const struct sctp_association *asoc,
+struct sctp_chunk *sctp_make_chunk(struct net *net,
+ const struct sctp_association *asoc,
__u8 type, __u8 flags, int paylen);
static sctp_cookie_param_t *sctp_pack_cookie(const struct sctp_endpoint *ep,
const struct sctp_association *asoc,
@@ -195,7 +196,8 @@ static int sctp_init_cause_fixed(struct sctp_chunk *chunk, __be16 cause_code,
* Host Name Address (Note 3) Optional 11
* Supported Address Types (Note 4) Optional 12
*/
-struct sctp_chunk *sctp_make_init(const struct sctp_association *asoc,
+struct sctp_chunk *sctp_make_init(struct net *net,
+ const struct sctp_association *asoc,
const struct sctp_bind_addr *bp,
gfp_t gfp, int vparam_len)
{
@@ -213,6 +215,8 @@ struct sctp_chunk *sctp_make_init(const struct sctp_association *asoc,
__u8 extensions[3];
sctp_paramhdr_t *auth_chunks = NULL,
*auth_hmacs = NULL;
+ /* to get per-net parameters */
+ struct sctp_net_params *net_params = sctp_get_params(net);
/* RFC 2960 3.3.2 Initiation (INIT) (1)
*
@@ -238,7 +242,7 @@ struct sctp_chunk *sctp_make_init(const struct sctp_association *asoc,
chunksize += WORD_ROUND(SCTP_SAT_LEN(num_types));
chunksize += sizeof(ecap_param);
- if (sctp_prsctp_enable)
+ if (net_params->prsctp_enable)
chunksize += sizeof(prsctp_param);
/* ADDIP: Section 4.2.7:
@@ -246,7 +250,7 @@ struct sctp_chunk *sctp_make_init(const struct sctp_association *asoc,
* the ASCONF,the ASCONF-ACK, and the AUTH chunks in its INIT and
* INIT-ACK parameters.
*/
- if (sctp_addip_enable) {
+ if (net_params->addip_enable) {
extensions[num_ext] = SCTP_CID_ASCONF;
extensions[num_ext+1] = SCTP_CID_ASCONF_ACK;
num_ext += 2;
@@ -258,7 +262,7 @@ struct sctp_chunk *sctp_make_init(const struct sctp_association *asoc,
chunksize += vparam_len;
/* Account for AUTH related parameters */
- if (sctp_auth_enable) {
+ if (net_params->auth_enable) {
/* Add random parameter length*/
chunksize += sizeof(asoc->c.auth_random);
@@ -297,7 +301,7 @@ struct sctp_chunk *sctp_make_init(const struct sctp_association *asoc,
* PLEASE DO NOT FIXME [This version does not support Host Name.]
*/
- retval = sctp_make_chunk(asoc, SCTP_CID_INIT, 0, chunksize);
+ retval = sctp_make_chunk(net, asoc, SCTP_CID_INIT, 0, chunksize);
if (!retval)
goto nodata;
@@ -332,7 +336,7 @@ struct sctp_chunk *sctp_make_init(const struct sctp_association *asoc,
sctp_addto_param(retval, num_ext, extensions);
}
- if (sctp_prsctp_enable)
+ if (net_params->prsctp_enable)
sctp_addto_chunk(retval, sizeof(prsctp_param), &prsctp_param);
if (sp->adaptation_ind) {
@@ -343,7 +347,7 @@ struct sctp_chunk *sctp_make_init(const struct sctp_association *asoc,
}
/* Add SCTP-AUTH chunks to the parameter list */
- if (sctp_auth_enable) {
+ if (net_params->auth_enable) {
sctp_addto_chunk(retval, sizeof(asoc->c.auth_random),
asoc->c.auth_random);
if (auth_hmacs)
@@ -358,7 +362,8 @@ nodata:
return retval;
}
-struct sctp_chunk *sctp_make_init_ack(const struct sctp_association *asoc,
+struct sctp_chunk *sctp_make_init_ack(struct net *net,
+ const struct sctp_association *asoc,
const struct sctp_chunk *chunk,
gfp_t gfp, int unkparam_len)
{
@@ -444,7 +449,7 @@ struct sctp_chunk *sctp_make_init_ack(const struct sctp_association *asoc,
num_ext);
/* Now allocate and fill out the chunk. */
- retval = sctp_make_chunk(asoc, SCTP_CID_INIT_ACK, 0, chunksize);
+ retval = sctp_make_chunk(net, asoc, SCTP_CID_INIT_ACK, 0, chunksize);
if (!retval)
goto nomem_chunk;
@@ -538,7 +543,8 @@ nomem_cookie:
* An implementation SHOULD make the cookie as small as possible
* to insure interoperability.
*/
-struct sctp_chunk *sctp_make_cookie_echo(const struct sctp_association *asoc,
+struct sctp_chunk *sctp_make_cookie_echo(struct net *net,
+ const struct sctp_association *asoc,
const struct sctp_chunk *chunk)
{
struct sctp_chunk *retval;
@@ -549,7 +555,8 @@ struct sctp_chunk *sctp_make_cookie_echo(const struct sctp_association *asoc,
cookie_len = asoc->peer.cookie_len;
/* Build a cookie echo chunk. */
- retval = sctp_make_chunk(asoc, SCTP_CID_COOKIE_ECHO, 0, cookie_len);
+ retval = sctp_make_chunk(net, asoc, SCTP_CID_COOKIE_ECHO, 0,
+ cookie_len);
if (!retval)
goto nodata;
retval->subh.cookie_hdr =
@@ -589,12 +596,13 @@ nodata:
*
* Set to zero on transmit and ignored on receipt.
*/
-struct sctp_chunk *sctp_make_cookie_ack(const struct sctp_association *asoc,
+struct sctp_chunk *sctp_make_cookie_ack(struct net *net,
+ const struct sctp_association *asoc,
const struct sctp_chunk *chunk)
{
struct sctp_chunk *retval;
- retval = sctp_make_chunk(asoc, SCTP_CID_COOKIE_ACK, 0, 0);
+ retval = sctp_make_chunk(net, asoc, SCTP_CID_COOKIE_ACK, 0, 0);
/* RFC 2960 6.4 Multi-homed SCTP Endpoints
*
@@ -634,7 +642,8 @@ struct sctp_chunk *sctp_make_cookie_ack(const struct sctp_association *asoc,
*
* Note: The CWR is considered a Control chunk.
*/
-struct sctp_chunk *sctp_make_cwr(const struct sctp_association *asoc,
+struct sctp_chunk *sctp_make_cwr(struct net *net,
+ const struct sctp_association *asoc,
const __u32 lowest_tsn,
const struct sctp_chunk *chunk)
{
@@ -642,7 +651,7 @@ struct sctp_chunk *sctp_make_cwr(const struct sctp_association *asoc,
sctp_cwrhdr_t cwr;
cwr.lowest_tsn = htonl(lowest_tsn);
- retval = sctp_make_chunk(asoc, SCTP_CID_ECN_CWR, 0,
+ retval = sctp_make_chunk(net, asoc, SCTP_CID_ECN_CWR, 0,
sizeof(sctp_cwrhdr_t));
if (!retval)
@@ -674,9 +683,10 @@ struct sctp_chunk *sctp_make_ecne(const struct sctp_association *asoc,
{
struct sctp_chunk *retval;
sctp_ecnehdr_t ecne;
+ struct net *net = sock_net(asoc->base.sk);
ecne.lowest_tsn = htonl(lowest_tsn);
- retval = sctp_make_chunk(asoc, SCTP_CID_ECN_ECNE, 0,
+ retval = sctp_make_chunk(net, asoc, SCTP_CID_ECN_ECNE, 0,
sizeof(sctp_ecnehdr_t));
if (!retval)
goto nodata;
@@ -690,7 +700,8 @@ nodata:
/* Make a DATA chunk for the given association from the provided
* parameters. However, do not populate the data payload.
*/
-struct sctp_chunk *sctp_make_datafrag_empty(struct sctp_association *asoc,
+struct sctp_chunk *sctp_make_datafrag_empty(struct net *net,
+ struct sctp_association *asoc,
const struct sctp_sndrcvinfo *sinfo,
int data_len, __u8 flags, __u16 ssn)
{
@@ -713,7 +724,7 @@ struct sctp_chunk *sctp_make_datafrag_empty(struct sctp_association *asoc,
dp.ssn = htons(ssn);
chunk_len = sizeof(dp) + data_len;
- retval = sctp_make_chunk(asoc, SCTP_CID_DATA, flags, chunk_len);
+ retval = sctp_make_chunk(net, asoc, SCTP_CID_DATA, flags, chunk_len);
if (!retval)
goto nodata;
@@ -759,7 +770,8 @@ struct sctp_chunk *sctp_make_sack(const struct sctp_association *asoc)
+ sizeof(__u32) * num_dup_tsns;
/* Create the chunk. */
- retval = sctp_make_chunk(asoc, SCTP_CID_SACK, 0, len);
+ retval = sctp_make_chunk(sock_net(asoc->base.sk), asoc, SCTP_CID_SACK,
+ 0, len);
if (!retval)
goto nodata;
@@ -827,7 +839,8 @@ nodata:
}
/* Make a SHUTDOWN chunk. */
-struct sctp_chunk *sctp_make_shutdown(const struct sctp_association *asoc,
+struct sctp_chunk *sctp_make_shutdown(struct net *net,
+ const struct sctp_association *asoc,
const struct sctp_chunk *chunk)
{
struct sctp_chunk *retval;
@@ -837,8 +850,8 @@ struct sctp_chunk *sctp_make_shutdown(const struct sctp_association *asoc,
ctsn = sctp_tsnmap_get_ctsn(&asoc->peer.tsn_map);
shut.cum_tsn_ack = htonl(ctsn);
- retval = sctp_make_chunk(asoc, SCTP_CID_SHUTDOWN, 0,
- sizeof(sctp_shutdownhdr_t));
+ retval = sctp_make_chunk(net, asoc, SCTP_CID_SHUTDOWN,
+ 0, sizeof(sctp_shutdownhdr_t));
if (!retval)
goto nodata;
@@ -851,12 +864,13 @@ nodata:
return retval;
}
-struct sctp_chunk *sctp_make_shutdown_ack(const struct sctp_association *asoc,
+struct sctp_chunk *sctp_make_shutdown_ack(struct net *net,
+ const struct sctp_association *asoc,
const struct sctp_chunk *chunk)
{
struct sctp_chunk *retval;
- retval = sctp_make_chunk(asoc, SCTP_CID_SHUTDOWN_ACK, 0, 0);
+ retval = sctp_make_chunk(net, asoc, SCTP_CID_SHUTDOWN_ACK, 0, 0);
/* RFC 2960 6.4 Multi-homed SCTP Endpoints
*
@@ -874,6 +888,7 @@ struct sctp_chunk *sctp_make_shutdown_ack(const struct sctp_association *asoc,
}
struct sctp_chunk *sctp_make_shutdown_complete(
+ struct net *net,
const struct sctp_association *asoc,
const struct sctp_chunk *chunk)
{
@@ -885,7 +900,8 @@ struct sctp_chunk *sctp_make_shutdown_complete(
*/
flags |= asoc ? 0 : SCTP_CHUNK_FLAG_T;
- retval = sctp_make_chunk(asoc, SCTP_CID_SHUTDOWN_COMPLETE, flags, 0);
+ retval = sctp_make_chunk(net, asoc, SCTP_CID_SHUTDOWN_COMPLETE,
+ flags, 0);
/* RFC 2960 6.4 Multi-homed SCTP Endpoints
*
@@ -906,7 +922,8 @@ struct sctp_chunk *sctp_make_shutdown_complete(
/* Create an ABORT. Note that we set the T bit if we have no
* association, except when responding to an INIT (sctpimpguide 2.41).
*/
-struct sctp_chunk *sctp_make_abort(const struct sctp_association *asoc,
+struct sctp_chunk *sctp_make_abort(struct net *net,
+ const struct sctp_association *asoc,
const struct sctp_chunk *chunk,
const size_t hint)
{
@@ -924,7 +941,7 @@ struct sctp_chunk *sctp_make_abort(const struct sctp_association *asoc,
flags = SCTP_CHUNK_FLAG_T;
}
- retval = sctp_make_chunk(asoc, SCTP_CID_ABORT, flags, hint);
+ retval = sctp_make_chunk(net, asoc, SCTP_CID_ABORT, flags, hint);
/* RFC 2960 6.4 Multi-homed SCTP Endpoints
*
@@ -943,13 +960,14 @@ struct sctp_chunk *sctp_make_abort(const struct sctp_association *asoc,
/* Helper to create ABORT with a NO_USER_DATA error. */
struct sctp_chunk *sctp_make_abort_no_data(
+ struct net *net,
const struct sctp_association *asoc,
const struct sctp_chunk *chunk, __u32 tsn)
{
struct sctp_chunk *retval;
__be32 payload;
- retval = sctp_make_abort(asoc, chunk, sizeof(sctp_errhdr_t)
+ retval = sctp_make_abort(net, asoc, chunk, sizeof(sctp_errhdr_t)
+ sizeof(tsn));
if (!retval)
@@ -977,7 +995,8 @@ no_mem:
}
/* Helper to create ABORT with a SCTP_ERROR_USER_ABORT error. */
-struct sctp_chunk *sctp_make_abort_user(const struct sctp_association *asoc,
+struct sctp_chunk *sctp_make_abort_user(struct net *net,
+ const struct sctp_association *asoc,
const struct msghdr *msg,
size_t paylen)
{
@@ -985,7 +1004,8 @@ struct sctp_chunk *sctp_make_abort_user(const struct sctp_association *asoc,
void *payload = NULL;
int err;
- retval = sctp_make_abort(asoc, NULL, sizeof(sctp_errhdr_t) + paylen);
+ retval = sctp_make_abort(net, asoc, NULL,
+ sizeof(sctp_errhdr_t) + paylen);
if (!retval)
goto err_chunk;
@@ -1042,6 +1062,7 @@ static void *sctp_addto_param(struct sctp_chunk *chunk, int len,
/* Make an ABORT chunk with a PROTOCOL VIOLATION cause code. */
struct sctp_chunk *sctp_make_abort_violation(
+ struct net *net,
const struct sctp_association *asoc,
const struct sctp_chunk *chunk,
const __u8 *payload,
@@ -1050,8 +1071,8 @@ struct sctp_chunk *sctp_make_abort_violation(
struct sctp_chunk *retval;
struct sctp_paramhdr phdr;
- retval = sctp_make_abort(asoc, chunk, sizeof(sctp_errhdr_t) + paylen
- + sizeof(sctp_paramhdr_t));
+ retval = sctp_make_abort(net, asoc, chunk, sizeof(sctp_errhdr_t)
+ + paylen + sizeof(sctp_paramhdr_t));
if (!retval)
goto end;
@@ -1068,6 +1089,7 @@ end:
}
struct sctp_chunk *sctp_make_violation_paramlen(
+ struct net *net,
const struct sctp_association *asoc,
const struct sctp_chunk *chunk,
struct sctp_paramhdr *param)
@@ -1077,7 +1099,7 @@ struct sctp_chunk *sctp_make_violation_paramlen(
size_t payload_len = sizeof(error) + sizeof(sctp_errhdr_t) +
sizeof(sctp_paramhdr_t);
- retval = sctp_make_abort(asoc, chunk, payload_len);
+ retval = sctp_make_abort(net, asoc, chunk, payload_len);
if (!retval)
goto nodata;
@@ -1091,13 +1113,15 @@ nodata:
}
/* Make a HEARTBEAT chunk. */
-struct sctp_chunk *sctp_make_heartbeat(const struct sctp_association *asoc,
+struct sctp_chunk *sctp_make_heartbeat(struct net *net,
+ const struct sctp_association *asoc,
const struct sctp_transport *transport)
{
struct sctp_chunk *retval;
sctp_sender_hb_info_t hbinfo;
- retval = sctp_make_chunk(asoc, SCTP_CID_HEARTBEAT, 0, sizeof(hbinfo));
+ retval = sctp_make_chunk(net, asoc, SCTP_CID_HEARTBEAT, 0,
+ sizeof(hbinfo));
if (!retval)
goto nodata;
@@ -1119,13 +1143,14 @@ nodata:
return retval;
}
-struct sctp_chunk *sctp_make_heartbeat_ack(const struct sctp_association *asoc,
+struct sctp_chunk *sctp_make_heartbeat_ack(struct net *net,
+ const struct sctp_association *asoc,
const struct sctp_chunk *chunk,
const void *payload, const size_t paylen)
{
struct sctp_chunk *retval;
- retval = sctp_make_chunk(asoc, SCTP_CID_HEARTBEAT_ACK, 0, paylen);
+ retval = sctp_make_chunk(net, asoc, SCTP_CID_HEARTBEAT_ACK, 0, paylen);
if (!retval)
goto nodata;
@@ -1151,13 +1176,14 @@ nodata:
* This routine can be used for containing multiple causes in the chunk.
*/
static struct sctp_chunk *sctp_make_op_error_space(
+ struct net *net,
const struct sctp_association *asoc,
const struct sctp_chunk *chunk,
size_t size)
{
struct sctp_chunk *retval;
- retval = sctp_make_chunk(asoc, SCTP_CID_ERROR, 0,
+ retval = sctp_make_chunk(net, asoc, SCTP_CID_ERROR, 0,
sizeof(sctp_errhdr_t) + size);
if (!retval)
goto nodata;
@@ -1184,6 +1210,7 @@ nodata:
* to report all the errors, if the incomming chunk is large
*/
static inline struct sctp_chunk *sctp_make_op_error_fixed(
+ struct net *net,
const struct sctp_association *asoc,
const struct sctp_chunk *chunk)
{
@@ -1192,18 +1219,20 @@ static inline struct sctp_chunk *sctp_make_op_error_fixed(
if (!size)
size = SCTP_DEFAULT_MAXSEGMENT;
- return sctp_make_op_error_space(asoc, chunk, size);
+ return sctp_make_op_error_space(net, asoc, chunk, size);
}
/* Create an Operation Error chunk. */
-struct sctp_chunk *sctp_make_op_error(const struct sctp_association *asoc,
+struct sctp_chunk *sctp_make_op_error(struct net *net,
+ const struct sctp_association *asoc,
const struct sctp_chunk *chunk,
__be16 cause_code, const void *payload,
size_t paylen, size_t reserve_tail)
{
struct sctp_chunk *retval;
- retval = sctp_make_op_error_space(asoc, chunk, paylen + reserve_tail);
+ retval = sctp_make_op_error_space(net, asoc, chunk,
+ paylen + reserve_tail);
if (!retval)
goto nodata;
@@ -1228,8 +1257,8 @@ struct sctp_chunk *sctp_make_auth(const struct sctp_association *asoc)
if (unlikely(!hmac_desc))
return NULL;
- retval = sctp_make_chunk(asoc, SCTP_CID_AUTH, 0,
- hmac_desc->hmac_len + sizeof(sctp_authhdr_t));
+ retval = sctp_make_chunk(sock_net(asoc->base.sk), asoc, SCTP_CID_AUTH,
+ 0, hmac_desc->hmac_len + sizeof(sctp_authhdr_t));
if (!retval)
return NULL;
@@ -1334,7 +1363,8 @@ const union sctp_addr *sctp_source(const struct sctp_chunk *chunk)
* arguments, reserving enough space for a 'paylen' byte payload.
*/
SCTP_STATIC
-struct sctp_chunk *sctp_make_chunk(const struct sctp_association *asoc,
+struct sctp_chunk *sctp_make_chunk(struct net *net,
+ const struct sctp_association *asoc,
__u8 type, __u8 flags, int paylen)
{
struct sctp_chunk *retval;
@@ -1365,7 +1395,7 @@ struct sctp_chunk *sctp_make_chunk(const struct sctp_association *asoc,
retval->chunk_end = ((__u8 *)chunk_hdr) + sizeof(struct sctp_chunkhdr);
/* Determine if the chunk needs to be authenticated */
- if (sctp_auth_send_cid(&init_net, type, asoc))
+ if (sctp_auth_send_cid(net, type, asoc))
retval->auth = 1;
/* Set the skb to the belonging sock for accounting. */
@@ -1651,6 +1681,7 @@ nodata:
/* Unpack the cookie from COOKIE ECHO chunk, recreating the association. */
struct sctp_association *sctp_unpack_cookie(
+ struct net *net,
const struct sctp_endpoint *ep,
const struct sctp_association *asoc,
struct sctp_chunk *chunk, gfp_t gfp,
@@ -1770,7 +1801,7 @@ no_hmac:
* Cookie that has expired.
*/
len = ntohs(chunk->chunk_hdr->length);
- *errp = sctp_make_op_error_space(asoc, chunk, len);
+ *errp = sctp_make_op_error_space(net, asoc, chunk, len);
if (*errp) {
suseconds_t usecs = (tv.tv_sec -
bear_cookie->expiration.tv_sec) * 1000000L +
@@ -1849,7 +1880,8 @@ struct __sctp_missing {
/*
* Report a missing mandatory parameter.
*/
-static int sctp_process_missing_param(const struct sctp_association *asoc,
+static int sctp_process_missing_param(struct net *net,
+ const struct sctp_association *asoc,
sctp_param_t paramtype,
struct sctp_chunk *chunk,
struct sctp_chunk **errp)
@@ -1863,7 +1895,7 @@ static int sctp_process_missing_param(const struct sctp_association *asoc,
* returning multiple unknown parameters.
*/
if (!*errp)
- *errp = sctp_make_op_error_space(asoc, chunk, len);
+ *errp = sctp_make_op_error_space(net, asoc, chunk, len);
if (*errp) {
report.num_missing = htonl(1);
@@ -1878,14 +1910,15 @@ static int sctp_process_missing_param(const struct sctp_association *asoc,
}
/* Report an Invalid Mandatory Parameter. */
-static int sctp_process_inv_mandatory(const struct sctp_association *asoc,
+static int sctp_process_inv_mandatory(struct net *net,
+ const struct sctp_association *asoc,
struct sctp_chunk *chunk,
struct sctp_chunk **errp)
{
/* Invalid Mandatory Parameter Error has no payload. */
if (!*errp)
- *errp = sctp_make_op_error_space(asoc, chunk, 0);
+ *errp = sctp_make_op_error_space(net, asoc, chunk, 0);
if (*errp)
sctp_init_cause(*errp, SCTP_ERROR_INV_PARAM, 0);
@@ -1894,7 +1927,8 @@ static int sctp_process_inv_mandatory(const struct sctp_association *asoc,
return 0;
}
-static int sctp_process_inv_paramlength(const struct sctp_association *asoc,
+static int sctp_process_inv_paramlength(struct net *net,
+ const struct sctp_association *asoc,
struct sctp_paramhdr *param,
const struct sctp_chunk *chunk,
struct sctp_chunk **errp)
@@ -1906,7 +1940,7 @@ static int sctp_process_inv_paramlength(const struct sctp_association *asoc,
sctp_chunk_free(*errp);
/* Create an error chunk and fill it in with our payload. */
- *errp = sctp_make_violation_paramlen(asoc, chunk, param);
+ *errp = sctp_make_violation_paramlen(net, asoc, chunk, param);
return 0;
}
@@ -1915,7 +1949,8 @@ static int sctp_process_inv_paramlength(const struct sctp_association *asoc,
/* Do not attempt to handle the HOST_NAME parm. However, do
* send back an indicator to the peer.
*/
-static int sctp_process_hn_param(const struct sctp_association *asoc,
+static int sctp_process_hn_param(struct net *net,
+ const struct sctp_association *asoc,
union sctp_params param,
struct sctp_chunk *chunk,
struct sctp_chunk **errp)
@@ -1930,7 +1965,7 @@ static int sctp_process_hn_param(const struct sctp_association *asoc,
if (*errp)
sctp_chunk_free(*errp);
- *errp = sctp_make_op_error_space(asoc, chunk, len);
+ *errp = sctp_make_op_error_space(net, asoc, chunk, len);
if (*errp) {
sctp_init_cause(*errp, SCTP_ERROR_DNS_FAILED, len);
@@ -1941,8 +1976,9 @@ static int sctp_process_hn_param(const struct sctp_association *asoc,
return 0;
}
-static int sctp_verify_ext_param(union sctp_params param)
+static int sctp_verify_ext_param(struct net *net, union sctp_params param)
{
+ struct sctp_net_params *net_params = sctp_get_params(net);
__u16 num_ext = ntohs(param.p->length) - sizeof(sctp_paramhdr_t);
int have_auth = 0;
int have_asconf = 0;
@@ -1965,10 +2001,10 @@ static int sctp_verify_ext_param(union sctp_params param)
* only if ADD-IP is turned on and we are not backward-compatible
* mode.
*/
- if (sctp_addip_noauth)
+ if (net_params->addip_noauth_enable)
return 1;
- if (sctp_addip_enable && !have_auth && have_asconf)
+ if (net_params->addip_enable && !have_auth && have_asconf)
return 0;
return 1;
@@ -1979,11 +2015,13 @@ static void sctp_process_ext_param(struct sctp_association *asoc,
{
__u16 num_ext = ntohs(param.p->length) - sizeof(sctp_paramhdr_t);
int i;
+ struct sctp_net_params *net_params =
+ sctp_get_params(sock_net(asoc->base.sk));
for (i = 0; i < num_ext; i++) {
switch (param.ext->chunks[i]) {
case SCTP_CID_FWD_TSN:
- if (sctp_prsctp_enable &&
+ if (net_params->prsctp_enable &&
!asoc->peer.prsctp_capable)
asoc->peer.prsctp_capable = 1;
break;
@@ -1991,12 +2029,12 @@ static void sctp_process_ext_param(struct sctp_association *asoc,
/* if the peer reports AUTH, assume that he
* supports AUTH.
*/
- if (sctp_auth_enable)
+ if (net_params->auth_enable)
asoc->peer.auth_capable = 1;
break;
case SCTP_CID_ASCONF:
case SCTP_CID_ASCONF_ACK:
- if (sctp_addip_enable)
+ if (net_params->addip_enable)
asoc->peer.asconf_capable = 1;
break;
default:
@@ -2030,7 +2068,8 @@ static void sctp_process_ext_param(struct sctp_association *asoc,
* SCTP_IERROR_ERROR - stop and report an error.
* SCTP_IERROR_NOMEME - out of memory.
*/
-static sctp_ierror_t sctp_process_unk_param(const struct sctp_association *asoc,
+static sctp_ierror_t sctp_process_unk_param(struct net *net,
+ const struct sctp_association *asoc,
union sctp_params param,
struct sctp_chunk *chunk,
struct sctp_chunk **errp)
@@ -2051,7 +2090,7 @@ static sctp_ierror_t sctp_process_unk_param(const struct sctp_association *asoc,
* returning multiple unknown parameters.
*/
if (NULL == *errp)
- *errp = sctp_make_op_error_fixed(asoc, chunk);
+ *errp = sctp_make_op_error_fixed(net, asoc, chunk);
if (*errp) {
if (!sctp_init_cause_fixed(*errp, SCTP_ERROR_UNKNOWN_PARAM,
@@ -2082,7 +2121,8 @@ static sctp_ierror_t sctp_process_unk_param(const struct sctp_association *asoc,
* SCTP_IERROR_ERROR - stop processing, trigger an ERROR
* SCTP_IERROR_NO_ERROR - continue with the chunk
*/
-static sctp_ierror_t sctp_verify_param(const struct sctp_association *asoc,
+static sctp_ierror_t sctp_verify_param(struct net *net,
+ const struct sctp_association *asoc,
union sctp_params param,
sctp_cid_t cid,
struct sctp_chunk *chunk,
@@ -2092,6 +2132,7 @@ static sctp_ierror_t sctp_verify_param(const struct sctp_association *asoc,
int retval = SCTP_IERROR_NO_ERROR;
__u16 n_elt, id = 0;
int i;
+ struct sctp_net_params *net_params = sctp_get_params(net);
/* FIXME - This routine is not looking at each parameter per the
* chunk type, i.e., unrecognized parameters should be further
@@ -2111,28 +2152,28 @@ static sctp_ierror_t sctp_verify_param(const struct sctp_association *asoc,
break;
case SCTP_PARAM_SUPPORTED_EXT:
- if (!sctp_verify_ext_param(param))
+ if (!sctp_verify_ext_param(net, param))
return SCTP_IERROR_ABORT;
break;
case SCTP_PARAM_SET_PRIMARY:
- if (sctp_addip_enable)
+ if (net_params->addip_enable)
break;
goto fallthrough;
case SCTP_PARAM_HOST_NAME_ADDRESS:
/* Tell the peer, we won't support this param. */
- sctp_process_hn_param(asoc, param, chunk, err_chunk);
+ sctp_process_hn_param(net, asoc, param, chunk, err_chunk);
retval = SCTP_IERROR_ABORT;
break;
case SCTP_PARAM_FWD_TSN_SUPPORT:
- if (sctp_prsctp_enable)
+ if (net_params->prsctp_enable)
break;
goto fallthrough;
case SCTP_PARAM_RANDOM:
- if (!sctp_auth_enable)
+ if (!net_params->auth_enable)
goto fallthrough;
/* SCTP-AUTH: Secion 6.1
@@ -2142,14 +2183,14 @@ static sctp_ierror_t sctp_verify_param(const struct sctp_association *asoc,
*/
if (SCTP_AUTH_RANDOM_LENGTH !=
ntohs(param.p->length) - sizeof(sctp_paramhdr_t)) {
- sctp_process_inv_paramlength(asoc, param.p,
+ sctp_process_inv_paramlength(net, asoc, param.p,
chunk, err_chunk);
retval = SCTP_IERROR_ABORT;
}
break;
case SCTP_PARAM_CHUNKS:
- if (!sctp_auth_enable)
+ if (!net_params->auth_enable)
goto fallthrough;
/* SCTP-AUTH: Section 3.2
@@ -2158,14 +2199,14 @@ static sctp_ierror_t sctp_verify_param(const struct sctp_association *asoc,
* chunks. Its maximum length is 260 bytes.
*/
if (260 < ntohs(param.p->length)) {
- sctp_process_inv_paramlength(asoc, param.p,
+ sctp_process_inv_paramlength(net, asoc, param.p,
chunk, err_chunk);
retval = SCTP_IERROR_ABORT;
}
break;
case SCTP_PARAM_HMAC_ALGO:
- if (!sctp_auth_enable)
+ if (!net_params->auth_enable)
goto fallthrough;
hmacs = (struct sctp_hmac_algo_param *)param.p;
@@ -2183,7 +2224,7 @@ static sctp_ierror_t sctp_verify_param(const struct sctp_association *asoc,
}
if (id != SCTP_AUTH_HMAC_ID_SHA1) {
- sctp_process_inv_paramlength(asoc, param.p, chunk,
+ sctp_process_inv_paramlength(net, asoc, param.p, chunk,
err_chunk);
retval = SCTP_IERROR_ABORT;
}
@@ -2192,14 +2233,16 @@ fallthrough:
default:
SCTP_DEBUG_PRINTK("Unrecognized param: %d for chunk %d.\n",
ntohs(param.p->type), cid);
- retval = sctp_process_unk_param(asoc, param, chunk, err_chunk);
+ retval = sctp_process_unk_param(net, asoc, param, chunk,
+ err_chunk);
break;
}
return retval;
}
/* Verify the INIT packet before we process it. */
-int sctp_verify_init(const struct sctp_association *asoc,
+int sctp_verify_init(struct net *net,
+ const struct sctp_association *asoc,
sctp_cid_t cid,
sctp_init_chunk_t *peer_init,
struct sctp_chunk *chunk,
@@ -2215,7 +2258,7 @@ int sctp_verify_init(const struct sctp_association *asoc,
(0 == peer_init->init_hdr.init_tag) ||
(SCTP_DEFAULT_MINWINDOW > ntohl(peer_init->init_hdr.a_rwnd))) {
- return sctp_process_inv_mandatory(asoc, chunk, errp);
+ return sctp_process_inv_mandatory(net, asoc, chunk, errp);
}
/* Check for missing mandatory parameters. */
@@ -2234,19 +2277,21 @@ int sctp_verify_init(const struct sctp_association *asoc,
* error handling code build and send the packet.
*/
if (param.v != (void*)chunk->chunk_end)
- return sctp_process_inv_paramlength(asoc, param.p, chunk, errp);
+ return sctp_process_inv_paramlength(net, asoc, param.p,
+ chunk, errp);
/* The only missing mandatory param possible today is
* the state cookie for an INIT-ACK chunk.
*/
if ((SCTP_CID_INIT_ACK == cid) && !has_cookie)
- return sctp_process_missing_param(asoc, SCTP_PARAM_STATE_COOKIE,
+ return sctp_process_missing_param(net, asoc,
+ SCTP_PARAM_STATE_COOKIE,
chunk, errp);
/* Verify all the variable length parameters */
sctp_walk_params(param, peer_init, init_hdr.params) {
- result = sctp_verify_param(asoc, param, cid, chunk, errp);
+ result = sctp_verify_param(net, asoc, param, cid, chunk, errp);
switch (result) {
case SCTP_IERROR_ABORT:
case SCTP_IERROR_NOMEM:
@@ -2278,6 +2323,7 @@ int sctp_process_init(struct sctp_association *asoc, struct sctp_chunk *chunk,
union sctp_addr addr;
char *cookie;
int src_match = 0;
+ struct sctp_net_params *net_params = sctp_get_params(net);
/* We must include the address that the INIT packet came from.
* This is the only address that matters for an INIT packet.
@@ -2327,7 +2373,7 @@ int sctp_process_init(struct sctp_association *asoc, struct sctp_chunk *chunk,
* also give us an option to silently ignore the packet, which
* is what we'll do here.
*/
- if (!sctp_addip_noauth &&
+ if (!net_params->addip_noauth_enable &&
(asoc->peer.asconf_capable && !asoc->peer.auth_capable)) {
asoc->peer.addip_disabled_mask |= (SCTP_PARAM_ADD_IP |
SCTP_PARAM_DEL_IP |
@@ -2477,6 +2523,7 @@ static int sctp_process_param(struct sctp_association *asoc,
struct sctp_af *af;
union sctp_addr_param *addr_param;
struct sctp_transport *t;
+ struct sctp_net_params *net_params = sctp_get_params(net);
/* We maintain all INIT parameters in network byte order all the
* time. This allows us to not worry about whether the parameters
@@ -2502,7 +2549,7 @@ do_addr_param:
break;
case SCTP_PARAM_COOKIE_PRESERVATIVE:
- if (!sctp_cookie_preserve_enable)
+ if (!net_params->cookie_preserve_enable)
break;
stale = ntohl(param.life->lifespan_increment);
@@ -2582,7 +2629,7 @@ do_addr_param:
break;
case SCTP_PARAM_SET_PRIMARY:
- if (!sctp_addip_enable)
+ if (!net_params->addip_enable)
goto fall_through;
addr_param = param.v + sizeof(sctp_addip_param_t);
@@ -2609,7 +2656,7 @@ do_addr_param:
break;
case SCTP_PARAM_FWD_TSN_SUPPORT:
- if (sctp_prsctp_enable) {
+ if (net_params->prsctp_enable) {
asoc->peer.prsctp_capable = 1;
break;
}
@@ -2617,7 +2664,7 @@ do_addr_param:
goto fall_through;
case SCTP_PARAM_RANDOM:
- if (!sctp_auth_enable)
+ if (!net_params->auth_enable)
goto fall_through;
/* Save peer's random parameter */
@@ -2630,7 +2677,7 @@ do_addr_param:
break;
case SCTP_PARAM_HMAC_ALGO:
- if (!sctp_auth_enable)
+ if (!net_params->auth_enable)
goto fall_through;
/* Save peer's HMAC list */
@@ -2646,7 +2693,7 @@ do_addr_param:
break;
case SCTP_PARAM_CHUNKS:
- if (!sctp_auth_enable)
+ if (!net_params->auth_enable)
goto fall_through;
asoc->peer.peer_chunks = kmemdup(param.p,
@@ -2715,7 +2762,8 @@ __u32 sctp_generate_tsn(const struct sctp_endpoint *ep)
*
* Address Parameter and other parameter will not be wrapped in this function
*/
-static struct sctp_chunk *sctp_make_asconf(struct sctp_association *asoc,
+static struct sctp_chunk *sctp_make_asconf(struct net *net,
+ struct sctp_association *asoc,
union sctp_addr *addr,
int vparam_len)
{
@@ -2732,7 +2780,7 @@ static struct sctp_chunk *sctp_make_asconf(struct sctp_association *asoc,
length += addrlen;
/* Create the chunk. */
- retval = sctp_make_chunk(asoc, SCTP_CID_ASCONF, 0, length);
+ retval = sctp_make_chunk(net, asoc, SCTP_CID_ASCONF, 0, length);
if (!retval)
return NULL;
@@ -2770,7 +2818,8 @@ static struct sctp_chunk *sctp_make_asconf(struct sctp_association *asoc,
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
*
*/
-struct sctp_chunk *sctp_make_asconf_update_ip(struct sctp_association *asoc,
+struct sctp_chunk *sctp_make_asconf_update_ip(struct net *net,
+ struct sctp_association *asoc,
union sctp_addr *laddr,
struct sockaddr *addrs,
int addrcnt,
@@ -2809,7 +2858,7 @@ struct sctp_chunk *sctp_make_asconf_update_ip(struct sctp_association *asoc,
}
/* Create an asconf chunk with the required length. */
- retval = sctp_make_asconf(asoc, laddr, totallen);
+ retval = sctp_make_asconf(net, asoc, laddr, totallen);
if (!retval)
return NULL;
@@ -2856,7 +2905,8 @@ struct sctp_chunk *sctp_make_asconf_update_ip(struct sctp_association *asoc,
*
* Create an ASCONF chunk with Set Primary IP address parameter.
*/
-struct sctp_chunk *sctp_make_asconf_set_prim(struct sctp_association *asoc,
+struct sctp_chunk *sctp_make_asconf_set_prim(struct net *net,
+ struct sctp_association *asoc,
union sctp_addr *addr)
{
sctp_addip_param_t param;
@@ -2872,7 +2922,7 @@ struct sctp_chunk *sctp_make_asconf_set_prim(struct sctp_association *asoc,
len += addrlen;
/* Create the chunk and make asconf header. */
- retval = sctp_make_asconf(asoc, addr, len);
+ retval = sctp_make_asconf(net, asoc, addr, len);
if (!retval)
return NULL;
@@ -2905,15 +2955,16 @@ struct sctp_chunk *sctp_make_asconf_set_prim(struct sctp_association *asoc,
*
* Create an ASCONF_ACK chunk with enough space for the parameter responses.
*/
-static struct sctp_chunk *sctp_make_asconf_ack(const struct sctp_association *asoc,
- __u32 serial, int vparam_len)
+static struct sctp_chunk *sctp_make_asconf_ack(struct net *net,
+ const struct sctp_association *asoc,
+ __u32 serial, int vparam_len)
{
sctp_addiphdr_t asconf;
struct sctp_chunk *retval;
int length = sizeof(asconf) + vparam_len;
/* Create the chunk. */
- retval = sctp_make_chunk(asoc, SCTP_CID_ASCONF_ACK, 0, length);
+ retval = sctp_make_chunk(net, asoc, SCTP_CID_ASCONF_ACK, 0, length);
if (!retval)
return NULL;
@@ -3135,7 +3186,8 @@ int sctp_verify_asconf(const struct sctp_association *asoc,
/* Process an incoming ASCONF chunk with the next expected serial no. and
* return an ASCONF_ACK chunk to be sent in response.
*/
-struct sctp_chunk *sctp_process_asconf(struct sctp_association *asoc,
+struct sctp_chunk *sctp_process_asconf(struct net *net,
+ struct sctp_association *asoc,
struct sctp_chunk *asconf)
{
sctp_addiphdr_t *hdr;
@@ -3170,7 +3222,7 @@ struct sctp_chunk *sctp_process_asconf(struct sctp_association *asoc,
* ASCONF_ACK parameters are less than or equal to the fourfold of ASCONF
* parameters.
*/
- asconf_ack = sctp_make_asconf_ack(asoc, serial, chunk_len * 4);
+ asconf_ack = sctp_make_asconf_ack(net, asoc, serial, chunk_len * 4);
if (!asconf_ack)
goto done;
@@ -3339,7 +3391,8 @@ static __be16 sctp_get_asconf_response(struct sctp_chunk *asconf_ack,
}
/* Process an incoming ASCONF_ACK chunk against the cached last ASCONF chunk. */
-int sctp_process_asconf_ack(struct sctp_association *asoc,
+int sctp_process_asconf_ack(struct net *net,
+ struct sctp_association *asoc,
struct sctp_chunk *asconf_ack)
{
struct sctp_chunk *asconf = asoc->addip_last_asconf;
@@ -3444,7 +3497,8 @@ struct sctp_chunk *sctp_make_fwdtsn(const struct sctp_association *asoc,
hint = (nstreams + 1) * sizeof(__u32);
- retval = sctp_make_chunk(asoc, SCTP_CID_FWD_TSN, 0, hint);
+ retval = sctp_make_chunk(sock_net(asoc->base.sk), asoc,
+ SCTP_CID_FWD_TSN, 0, hint);
if (!retval)
return NULL;
diff --git a/net/sctp/sm_sideeffect.c b/net/sctp/sm_sideeffect.c
index 7bd2d6d..a90ddfa 100644
--- a/net/sctp/sm_sideeffect.c
+++ b/net/sctp/sm_sideeffect.c
@@ -106,7 +106,8 @@ static void sctp_do_ecn_ce_work(struct sctp_association *asoc,
* This element represents the lowest TSN number in the datagram
* that was originally marked with the CE bit.
*/
-static struct sctp_chunk *sctp_do_ecn_ecne_work(struct sctp_association *asoc,
+static struct sctp_chunk *sctp_do_ecn_ecne_work(struct net *net,
+ struct sctp_association *asoc,
__u32 lowest_tsn,
struct sctp_chunk *chunk)
{
@@ -140,7 +141,7 @@ static struct sctp_chunk *sctp_do_ecn_ecne_work(struct sctp_association *asoc,
/* Always try to quiet the other end. In case of lost CWR,
* resend last_cwr_tsn.
*/
- repl = sctp_make_cwr(asoc, asoc->last_cwr_tsn, chunk);
+ repl = sctp_make_cwr(net, asoc, asoc->last_cwr_tsn, chunk);
/* If we run out of memory, it will look like a lost CWR. We'll
* get back in sync eventually.
@@ -1059,8 +1060,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(sock_net(asoc->base.sk),
- asoc, asconf))
+ if (sctp_primitive_ASCONF(sock_net(asoc->base.sk), asoc,
+ asconf))
sctp_chunk_free(asconf);
else
asoc->addip_last_asconf = asconf;
@@ -1339,8 +1340,8 @@ static int sctp_cmd_interpreter(sctp_event_t event_type,
case SCTP_CMD_GEN_INIT_ACK:
/* Generate an INIT ACK chunk. */
- new_obj = sctp_make_init_ack(asoc, chunk, GFP_ATOMIC,
- 0);
+ new_obj = sctp_make_init_ack(net, asoc, chunk,
+ GFP_ATOMIC, 0);
if (!new_obj)
goto nomem;
@@ -1360,7 +1361,7 @@ static int sctp_cmd_interpreter(sctp_event_t event_type,
case SCTP_CMD_GEN_COOKIE_ECHO:
/* Generate a COOKIE ECHO chunk. */
- new_obj = sctp_make_cookie_echo(asoc, chunk);
+ new_obj = sctp_make_cookie_echo(net, asoc, chunk);
if (!new_obj) {
if (cmd->obj.ptr)
sctp_chunk_free(cmd->obj.ptr);
@@ -1410,7 +1411,7 @@ static int sctp_cmd_interpreter(sctp_event_t event_type,
asoc->overall_error_count = 0;
/* Generate a SHUTDOWN chunk. */
- new_obj = sctp_make_shutdown(asoc, chunk);
+ new_obj = sctp_make_shutdown(net, asoc, chunk);
if (!new_obj)
goto nomem;
sctp_add_cmd_sf(commands, SCTP_CMD_REPLY,
@@ -1470,7 +1471,7 @@ static int sctp_cmd_interpreter(sctp_event_t event_type,
case SCTP_CMD_ECN_ECNE:
/* Do delayed ECNE processing. */
- new_obj = sctp_do_ecn_ecne_work(asoc, cmd->obj.u32,
+ new_obj = sctp_do_ecn_ecne_work(net, asoc, cmd->obj.u32,
chunk);
if (new_obj)
sctp_add_cmd_sf(commands, SCTP_CMD_REPLY,
@@ -1711,8 +1712,8 @@ static int sctp_cmd_interpreter(sctp_event_t event_type,
break;
case SCTP_CMD_ASSOC_SHKEY:
- error = sctp_auth_asoc_init_active_key(net, asoc,
- GFP_ATOMIC);
+ error = sctp_auth_asoc_init_active_key(net,
+ asoc, GFP_ATOMIC);
break;
case SCTP_CMD_UPDATE_INITTAG:
asoc->peer.i.init_tag = cmd->obj.u32;
diff --git a/net/sctp/sm_statefuns.c b/net/sctp/sm_statefuns.c
index 4cd027a..8f41f42 100644
--- a/net/sctp/sm_statefuns.c
+++ b/net/sctp/sm_statefuns.c
@@ -365,7 +365,7 @@ sctp_disposition_t sctp_sf_do_5_1B_init(struct net *net,
/* Verify the INIT chunk before processing it. */
err_chunk = NULL;
- if (!sctp_verify_init(asoc, chunk->chunk_hdr->type,
+ if (!sctp_verify_init(net, asoc, chunk->chunk_hdr->type,
(sctp_init_chunk_t *)chunk->chunk_hdr, chunk,
&err_chunk)) {
/* This chunk contains fatal error. It is to be discarded.
@@ -425,7 +425,7 @@ sctp_disposition_t sctp_sf_do_5_1B_init(struct net *net,
len = ntohs(err_chunk->chunk_hdr->length) -
sizeof(sctp_chunkhdr_t);
- repl = sctp_make_init_ack(new_asoc, chunk, GFP_ATOMIC, len);
+ repl = sctp_make_init_ack(net, new_asoc, chunk, GFP_ATOMIC, len);
if (!repl)
goto nomem_init;
@@ -533,7 +533,7 @@ sctp_disposition_t sctp_sf_do_5_1C_ack(struct net *net,
/* Verify the INIT chunk before processing it. */
err_chunk = NULL;
- if (!sctp_verify_init(asoc, chunk->chunk_hdr->type,
+ if (!sctp_verify_init(net, asoc, chunk->chunk_hdr->type,
(sctp_init_chunk_t *)chunk->chunk_hdr, chunk,
&err_chunk)) {
@@ -707,7 +707,7 @@ sctp_disposition_t sctp_sf_do_5_1D_ce(struct net *net,
* "Z" will reply with a COOKIE ACK chunk after building a TCB
* and moving to the ESTABLISHED state.
*/
- new_asoc = sctp_unpack_cookie(ep, asoc, chunk, GFP_ATOMIC, &error,
+ new_asoc = sctp_unpack_cookie(net, ep, asoc, chunk, GFP_ATOMIC, &error,
&err_chk_p);
/* FIXME:
@@ -792,7 +792,7 @@ sctp_disposition_t sctp_sf_do_5_1D_ce(struct net *net,
}
}
- repl = sctp_make_cookie_ack(new_asoc, chunk);
+ repl = sctp_make_cookie_ack(net, new_asoc, chunk);
if (!repl)
goto nomem_init;
@@ -970,7 +970,7 @@ static sctp_disposition_t sctp_sf_heartbeat(struct net *net,
struct sctp_chunk *reply;
/* Send a heartbeat to our peer. */
- reply = sctp_make_heartbeat(asoc, transport);
+ reply = sctp_make_heartbeat(net, asoc, transport);
if (!reply)
return SCTP_DISPOSITION_NOMEM;
@@ -1084,7 +1084,7 @@ sctp_disposition_t sctp_sf_beat_8_3(struct net *net,
if (!pskb_pull(chunk->skb, paylen))
goto nomem;
- reply = sctp_make_heartbeat_ack(asoc, chunk,
+ reply = sctp_make_heartbeat_ack(net, asoc, chunk,
chunk->subh.hb_hdr, paylen);
if (!reply)
goto nomem;
@@ -1438,7 +1438,7 @@ static sctp_disposition_t sctp_sf_do_unexpected_init(
/* Verify the INIT chunk before processing it. */
err_chunk = NULL;
- if (!sctp_verify_init(asoc, chunk->chunk_hdr->type,
+ if (!sctp_verify_init(net, asoc, chunk->chunk_hdr->type,
(sctp_init_chunk_t *)chunk->chunk_hdr, chunk,
&err_chunk)) {
/* This chunk contains fatal error. It is to be discarded.
@@ -1516,7 +1516,7 @@ static sctp_disposition_t sctp_sf_do_unexpected_init(
sizeof(sctp_chunkhdr_t);
}
- repl = sctp_make_init_ack(new_asoc, chunk, GFP_ATOMIC, len);
+ repl = sctp_make_init_ack(net, new_asoc, chunk, GFP_ATOMIC, len);
if (!repl)
goto nomem;
@@ -1744,7 +1744,7 @@ static sctp_disposition_t sctp_sf_do_dupcook_a(struct net *net,
if (SCTP_DISPOSITION_NOMEM == disposition)
goto nomem;
- err = sctp_make_op_error(asoc, chunk,
+ err = sctp_make_op_error(net, asoc, chunk,
SCTP_ERROR_COOKIE_IN_SHUTDOWN,
NULL, 0, 0);
if (err)
@@ -1769,7 +1769,7 @@ static sctp_disposition_t sctp_sf_do_dupcook_a(struct net *net,
SCTP_TO(SCTP_EVENT_TIMEOUT_T4_RTO));
sctp_add_cmd_sf(commands, SCTP_CMD_PURGE_ASCONF_QUEUE, SCTP_NULL());
- repl = sctp_make_cookie_ack(new_asoc, chunk);
+ repl = sctp_make_cookie_ack(net, new_asoc, chunk);
if (!repl)
goto nomem;
@@ -1826,7 +1826,7 @@ static sctp_disposition_t sctp_sf_do_dupcook_b(struct net *net,
SCTP_INC_STATS(SCTP_MIB_CURRESTAB);
sctp_add_cmd_sf(commands, SCTP_CMD_HB_TIMERS_START, SCTP_NULL());
- repl = sctp_make_cookie_ack(new_asoc, chunk);
+ repl = sctp_make_cookie_ack(net, new_asoc, chunk);
if (!repl)
goto nomem;
@@ -1950,7 +1950,7 @@ static sctp_disposition_t sctp_sf_do_dupcook_d(struct net *net,
}
}
- repl = sctp_make_cookie_ack(new_asoc, chunk);
+ repl = sctp_make_cookie_ack(net, new_asoc, chunk);
if (!repl)
goto nomem;
@@ -2025,7 +2025,7 @@ sctp_disposition_t sctp_sf_do_5_2_4_dupcook(struct net *net,
* current association, consider the State Cookie valid even if
* the lifespan is exceeded.
*/
- new_asoc = sctp_unpack_cookie(ep, asoc, chunk, GFP_ATOMIC, &error,
+ new_asoc = sctp_unpack_cookie(net, ep, asoc, chunk, GFP_ATOMIC, &error,
&err_chk_p);
/* FIXME:
@@ -2341,7 +2341,7 @@ static sctp_disposition_t sctp_sf_do_5_2_6_stale(struct net *net,
/* Build that new INIT chunk. */
bp = (struct sctp_bind_addr *) &asoc->base.bind_addr;
- reply = sctp_make_init(asoc, bp, GFP_ATOMIC, sizeof(bht));
+ reply = sctp_make_init(net, asoc, bp, GFP_ATOMIC, sizeof(bht));
if (!reply)
goto nomem;
@@ -2779,7 +2779,7 @@ sctp_disposition_t sctp_sf_do_9_2_reshutack(struct net *net,
* is no point in verifying chunk boundries. Just generate
* the SHUTDOWN ACK.
*/
- reply = sctp_make_shutdown_ack(asoc, chunk);
+ reply = sctp_make_shutdown_ack(net, asoc, chunk);
if (NULL == reply)
goto nomem;
@@ -3241,7 +3241,7 @@ static sctp_disposition_t sctp_sf_tabort_8_4_8(struct net *net,
/* Make an ABORT. The T bit will be set if the asoc
* is NULL.
*/
- abort = sctp_make_abort(asoc, chunk, 0);
+ abort = sctp_make_abort(net, asoc, chunk, 0);
if (!abort) {
sctp_ootb_pkt_free(packet);
return SCTP_DISPOSITION_NOMEM;
@@ -3343,7 +3343,7 @@ sctp_disposition_t sctp_sf_do_9_2_final(struct net *net,
goto nomem;
/* ...send a SHUTDOWN COMPLETE chunk to its peer, */
- reply = sctp_make_shutdown_complete(asoc, chunk);
+ reply = sctp_make_shutdown_complete(net, asoc, chunk);
if (!reply)
goto nomem_chunk;
@@ -3508,7 +3508,7 @@ static sctp_disposition_t sctp_sf_shut_8_4_5(struct net *net,
/* Make an SHUTDOWN_COMPLETE.
* The T bit will be set if the asoc is NULL.
*/
- shut = sctp_make_shutdown_complete(asoc, chunk);
+ shut = sctp_make_shutdown_complete(net, asoc, chunk);
if (!shut) {
sctp_ootb_pkt_free(packet);
return SCTP_DISPOSITION_NOMEM;
@@ -3652,8 +3652,9 @@ sctp_disposition_t sctp_sf_do_asconf(struct net *net,
*
* Essentially, do V1-V5.
*/
- asconf_ack = sctp_process_asconf((struct sctp_association *)
- asoc, chunk);
+ asconf_ack = sctp_process_asconf(net,
+ (struct sctp_association *) asoc,
+ chunk);
if (!asconf_ack)
return SCTP_DISPOSITION_NOMEM;
} else if (serial < asoc->peer.addip_serial + 1) {
@@ -3770,7 +3771,7 @@ sctp_disposition_t sctp_sf_do_asconf_ack(struct net *net,
*/
if (ADDIP_SERIAL_gte(rcvd_serial, sent_serial + 1) &&
!(asoc->addip_last_asconf)) {
- abort = sctp_make_abort(asoc, asconf_ack,
+ abort = sctp_make_abort(net, asoc, asconf_ack,
sizeof(sctp_errhdr_t));
if (abort) {
sctp_init_cause(abort, SCTP_ERROR_ASCONF_ACK, 0);
@@ -3796,7 +3797,8 @@ sctp_disposition_t sctp_sf_do_asconf_ack(struct net *net,
sctp_add_cmd_sf(commands, SCTP_CMD_TIMER_STOP,
SCTP_TO(SCTP_EVENT_TIMEOUT_T4_RTO));
- if (!sctp_process_asconf_ack((struct sctp_association *)asoc,
+ if (!sctp_process_asconf_ack(net,
+ (struct sctp_association *)asoc,
asconf_ack)) {
/* Successfully processed ASCONF_ACK. We can
* release the next asconf if we have one.
@@ -3806,7 +3808,7 @@ sctp_disposition_t sctp_sf_do_asconf_ack(struct net *net,
return SCTP_DISPOSITION_CONSUME;
}
- abort = sctp_make_abort(asoc, asconf_ack,
+ abort = sctp_make_abort(net, asoc, asconf_ack,
sizeof(sctp_errhdr_t));
if (abort) {
sctp_init_cause(abort, SCTP_ERROR_RSRC_LOW, 0);
@@ -4106,7 +4108,7 @@ sctp_disposition_t sctp_sf_eat_auth(struct net *net,
/* Generate the ERROR chunk and discard the rest
* of the packet
*/
- err_chunk = sctp_make_op_error(asoc, chunk,
+ err_chunk = sctp_make_op_error(net, asoc, chunk,
SCTP_ERROR_UNSUP_HMAC,
&auth_hdr->hmac_id,
sizeof(__u16), 0);
@@ -4201,7 +4203,7 @@ sctp_disposition_t sctp_sf_unk_chunk(struct net *net,
case SCTP_CID_ACTION_DISCARD_ERR:
/* Generate an ERROR chunk as response. */
hdr = unk_chunk->chunk_hdr;
- err_chunk = sctp_make_op_error(asoc, unk_chunk,
+ err_chunk = sctp_make_op_error(net, asoc, unk_chunk,
SCTP_ERROR_UNKNOWN_CHUNK, hdr,
WORD_ROUND(ntohs(hdr->length)),
0);
@@ -4221,7 +4223,7 @@ sctp_disposition_t sctp_sf_unk_chunk(struct net *net,
case SCTP_CID_ACTION_SKIP_ERR:
/* Generate an ERROR chunk as response. */
hdr = unk_chunk->chunk_hdr;
- err_chunk = sctp_make_op_error(asoc, unk_chunk,
+ err_chunk = sctp_make_op_error(net, asoc, unk_chunk,
SCTP_ERROR_UNKNOWN_CHUNK, hdr,
WORD_ROUND(ntohs(hdr->length)),
0);
@@ -4368,7 +4370,7 @@ static sctp_disposition_t sctp_sf_abort_violation(
goto discard;
/* Make the abort chunk. */
- abort = sctp_make_abort_violation(asoc, chunk, payload, paylen);
+ abort = sctp_make_abort_violation(net, asoc, chunk, payload, paylen);
if (!abort)
goto nomem;
@@ -4494,7 +4496,7 @@ static sctp_disposition_t sctp_sf_violation_paramlen(
goto discard;
/* Make the abort chunk. */
- abort = sctp_make_violation_paramlen(asoc, chunk, param);
+ abort = sctp_make_violation_paramlen(net, asoc, chunk, param);
if (!abort)
goto nomem;
@@ -4642,7 +4644,7 @@ sctp_disposition_t sctp_sf_do_prm_asoc(struct net *net,
* 1 to 4294967295 (see 5.3.1 for Tag value selection). ...
*/
- repl = sctp_make_init(asoc, &asoc->base.bind_addr, GFP_ATOMIC, 0);
+ repl = sctp_make_init(net, asoc, &asoc->base.bind_addr, GFP_ATOMIC, 0);
if (!repl)
goto nomem;
@@ -5262,7 +5264,7 @@ sctp_disposition_t sctp_sf_do_9_2_start_shutdown(
* in the Cumulative TSN Ack field the last sequential TSN it
* has received from the peer.
*/
- reply = sctp_make_shutdown(asoc, NULL);
+ reply = sctp_make_shutdown(net, asoc, NULL);
if (!reply)
goto nomem;
@@ -5350,7 +5352,7 @@ sctp_disposition_t sctp_sf_do_9_2_shutdown_ack(
/* If it has no more outstanding DATA chunks, the SHUTDOWN receiver
* shall send a SHUTDOWN ACK ...
*/
- reply = sctp_make_shutdown_ack(asoc, chunk);
+ reply = sctp_make_shutdown_ack(net, asoc, chunk);
if (!reply)
goto nomem;
@@ -5551,7 +5553,7 @@ sctp_disposition_t sctp_sf_t1_init_timer_expire(struct net *net,
if (attempts <= asoc->max_init_attempts) {
bp = (struct sctp_bind_addr *) &asoc->base.bind_addr;
- repl = sctp_make_init(asoc, bp, GFP_ATOMIC, 0);
+ repl = sctp_make_init(net, asoc, bp, GFP_ATOMIC, 0);
if (!repl)
return SCTP_DISPOSITION_NOMEM;
@@ -5611,7 +5613,7 @@ sctp_disposition_t sctp_sf_t1_cookie_timer_expire(struct net *net,
SCTP_INC_STATS(SCTP_MIB_T1_COOKIE_EXPIREDS);
if (attempts <= asoc->max_init_attempts) {
- repl = sctp_make_cookie_echo(asoc, NULL);
+ repl = sctp_make_cookie_echo(net, asoc, NULL);
if (!repl)
return SCTP_DISPOSITION_NOMEM;
@@ -5673,11 +5675,11 @@ sctp_disposition_t sctp_sf_t2_timer_expire(struct net *net,
switch (asoc->state) {
case SCTP_STATE_SHUTDOWN_SENT:
- reply = sctp_make_shutdown(asoc, NULL);
+ reply = sctp_make_shutdown(net, asoc, NULL);
break;
case SCTP_STATE_SHUTDOWN_ACK_SENT:
- reply = sctp_make_shutdown_ack(asoc, NULL);
+ reply = sctp_make_shutdown_ack(net, asoc, NULL);
break;
default:
@@ -5799,7 +5801,7 @@ sctp_disposition_t sctp_sf_t5_timer_expire(struct net *net,
SCTP_DEBUG_PRINTK("Timer T5 expired.\n");
SCTP_INC_STATS(SCTP_MIB_T5_SHUTDOWN_GUARD_EXPIREDS);
- reply = sctp_make_abort(asoc, NULL, 0);
+ reply = sctp_make_abort(net, asoc, NULL, 0);
if (!reply)
goto nomem;
@@ -5963,7 +5965,7 @@ static struct sctp_packet *sctp_abort_pkt_new(const struct sctp_endpoint *ep,
/* Make an ABORT.
* The T bit will be set if the asoc is NULL.
*/
- abort = sctp_make_abort(asoc, chunk, paylen);
+ abort = sctp_make_abort(net, asoc, chunk, paylen);
if (!abort) {
sctp_ootb_pkt_free(packet);
return NULL;
@@ -6230,7 +6232,7 @@ static int sctp_eat_data(struct net *net,
* DATA chunk if a received DATA chunk has no user data.
*/
if (unlikely(0 == datalen)) {
- err = sctp_make_abort_no_data(asoc, chunk, tsn);
+ err = sctp_make_abort_no_data(net, asoc, chunk, tsn);
if (err) {
sctp_add_cmd_sf(commands, SCTP_CMD_REPLY,
SCTP_CHUNK(err));
@@ -6273,7 +6275,7 @@ static int sctp_eat_data(struct net *net,
/* Mark tsn as received even though we drop it */
sctp_add_cmd_sf(commands, SCTP_CMD_REPORT_TSN, SCTP_U32(tsn));
- err = sctp_make_op_error(asoc, chunk, SCTP_ERROR_INV_STRM,
+ err = sctp_make_op_error(net, asoc, chunk, SCTP_ERROR_INV_STRM,
&data_hdr->stream,
sizeof(data_hdr->stream),
sizeof(u16));
diff --git a/net/sctp/socket.c b/net/sctp/socket.c
index d14ac7d..9712ea5 100644
--- a/net/sctp/socket.c
+++ b/net/sctp/socket.c
@@ -583,7 +583,7 @@ static int sctp_send_asconf_add_ip(struct net *net,
bp = &asoc->base.bind_addr;
p = bp->address_list.next;
laddr = list_entry(p, struct sctp_sockaddr_entry, list);
- chunk = sctp_make_asconf_update_ip(asoc, &laddr->a, addrs,
+ chunk = sctp_make_asconf_update_ip(net, asoc, &laddr->a, addrs,
addrcnt, SCTP_PARAM_ADD_IP);
if (!chunk) {
retval = -ENOMEM;
@@ -825,8 +825,8 @@ static int sctp_send_asconf_del_ip(struct net *net,
* because this is done under a socket lock from the
* setsockopt call.
*/
- chunk = sctp_make_asconf_update_ip(asoc, laddr, addrs, addrcnt,
- SCTP_PARAM_DEL_IP);
+ chunk = sctp_make_asconf_update_ip(net, asoc, laddr, addrs,
+ addrcnt, SCTP_PARAM_DEL_IP);
if (!chunk) {
retval = -ENOMEM;
goto out;
@@ -1509,7 +1509,8 @@ SCTP_STATIC void sctp_close(struct sock *sk, long timeout)
(sock_flag(sk, SOCK_LINGER) && !sk->sk_lingertime)) {
struct sctp_chunk *chunk;
- chunk = sctp_make_abort_user(asoc, NULL, 0);
+ chunk = sctp_make_abort_user(sock_net(sk), asoc,
+ NULL, 0);
if (chunk)
sctp_primitive_ABORT(sock_net(sk), asoc, chunk);
} else
@@ -1727,20 +1728,20 @@ 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(sock_net(sk), asoc, NULL);
+ sctp_primitive_SHUTDOWN(net, asoc, NULL);
err = 0;
goto out_unlock;
}
if (sinfo_flags & SCTP_ABORT) {
- chunk = sctp_make_abort_user(asoc, msg, msg_len);
+ chunk = sctp_make_abort_user(net, asoc, msg, msg_len);
if (!chunk) {
err = -ENOMEM;
goto out_unlock;
}
SCTP_DEBUG_PRINTK("Aborting association: %p\n", asoc);
- sctp_primitive_ABORT(sock_net(sk), asoc, chunk);
+ sctp_primitive_ABORT(net, asoc, chunk);
err = 0;
goto out_unlock;
}
@@ -1914,7 +1915,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(sock_net(sk), asoc, NULL);
+ err = sctp_primitive_ASSOCIATE(net, asoc, NULL);
if (err < 0)
goto out_free;
SCTP_DEBUG_PRINTK("We associated primitively.\n");
@@ -1942,7 +1943,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(sock_net(sk), asoc, datamsg);
+ err = sctp_primitive_SEND(net, asoc, datamsg);
/* Did the lower layer accept the chunk? */
if (err)
sctp_datamsg_free(datamsg);
@@ -3094,7 +3095,7 @@ static int sctp_setsockopt_peer_primary_addr(struct sock *sk, char __user *optva
return -EADDRNOTAVAIL;
/* Create an ASCONF chunk with SET_PRIMARY parameter */
- chunk = sctp_make_asconf_set_prim(asoc,
+ chunk = sctp_make_asconf_set_prim(sock_net(sk), asoc,
(union sctp_addr *)&prim.sspp_addr);
if (!chunk)
return -ENOMEM;
@@ -3411,8 +3412,10 @@ static int sctp_setsockopt_active_key(struct sock *sk,
struct sctp_authkeyid val;
struct sctp_association *asoc;
struct net *net = sock_net(sk);
+ struct sctp_net_params *net_params =
+ sctp_get_params(net);
- if (!sctp_auth_enable)
+ if (!net_params->auth_enable)
return -EACCES;
if (optlen != sizeof(struct sctp_authkeyid))
--
1.7.9.5
^ permalink raw reply related
* [PATCH 10/13] SCTP: enable per-namespace authentication configuration.
From: Jan Ariyasu @ 2012-08-04 21:34 UTC (permalink / raw)
To: Vlad Yasevich, David S. Miller, linux-sctp, netdev, linux-kernel
Cc: Jan Ariyasu
This is the first of three patches to set authentication
by namespace. In this patch, the relevant routines in auth.c
now check to see if auth_enable is set as a namespace parameter
instead of checking the global parameter sctp_auth_enable.
Signed-off-by: Jan Ariyasu <jan.ariyasu@hp.com>
---
include/net/sctp/auth.h | 14 +++++++++-----
include/net/sctp/structs.h | 3 ++-
net/sctp/associola.c | 7 ++++---
net/sctp/auth.c | 29 +++++++++++++++++++----------
net/sctp/chunk.c | 5 +++--
net/sctp/endpointola.c | 6 ++++--
net/sctp/sm_make_chunk.c | 2 +-
net/sctp/sm_sideeffect.c | 2 +-
net/sctp/sm_statefuns.c | 16 ++++++++--------
net/sctp/socket.c | 10 ++++++----
10 files changed, 57 insertions(+), 37 deletions(-)
diff --git a/include/net/sctp/auth.h b/include/net/sctp/auth.h
index 49bc957..e4e88cb 100644
--- a/include/net/sctp/auth.h
+++ b/include/net/sctp/auth.h
@@ -89,14 +89,15 @@ static inline void sctp_auth_key_hold(struct sctp_auth_bytes *key)
void sctp_auth_key_put(struct sctp_auth_bytes *key);
struct sctp_shared_key *sctp_auth_shkey_create(__u16 key_id, gfp_t gfp);
void sctp_auth_destroy_keys(struct list_head *keys);
-int sctp_auth_asoc_init_active_key(struct sctp_association *asoc, gfp_t gfp);
+int sctp_auth_asoc_init_active_key(struct net *net,
+ struct sctp_association *asoc, gfp_t gfp);
struct sctp_shared_key *sctp_auth_get_shkey(
const struct sctp_association *asoc,
__u16 key_id);
int sctp_auth_asoc_copy_shkeys(const struct sctp_endpoint *ep,
struct sctp_association *asoc,
gfp_t gfp);
-int sctp_auth_init_hmacs(struct sctp_endpoint *ep, gfp_t gfp);
+int sctp_auth_init_hmacs(struct net *net, struct sctp_endpoint *ep, gfp_t gfp);
void sctp_auth_destroy_hmacs(struct crypto_hash *auth_hmacs[]);
struct sctp_hmac *sctp_auth_get_hmac(__u16 hmac_id);
struct sctp_hmac *sctp_auth_asoc_get_hmac(const struct sctp_association *asoc);
@@ -104,8 +105,10 @@ void sctp_auth_asoc_set_default_hmac(struct sctp_association *asoc,
struct sctp_hmac_algo_param *hmacs);
int sctp_auth_asoc_verify_hmac_id(const struct sctp_association *asoc,
__be16 hmac_id);
-int sctp_auth_send_cid(sctp_cid_t chunk, const struct sctp_association *asoc);
-int sctp_auth_recv_cid(sctp_cid_t chunk, const struct sctp_association *asoc);
+int sctp_auth_send_cid(struct net *net,
+ sctp_cid_t chunk, const struct sctp_association *asoc);
+int sctp_auth_recv_cid(struct net *net,
+ sctp_cid_t chunk, const struct sctp_association *asoc);
void sctp_auth_calculate_hmac(const struct sctp_association *asoc,
struct sk_buff *skb,
struct sctp_auth_chunk *auth, gfp_t gfp);
@@ -117,7 +120,8 @@ int sctp_auth_ep_set_hmacs(struct sctp_endpoint *ep,
int sctp_auth_set_key(struct sctp_endpoint *ep,
struct sctp_association *asoc,
struct sctp_authkey *auth_key);
-int sctp_auth_set_active_key(struct sctp_endpoint *ep,
+int sctp_auth_set_active_key(struct net *net,
+ struct sctp_endpoint *ep,
struct sctp_association *asoc,
__u16 key_id);
int sctp_auth_del_key_id(struct sctp_endpoint *ep,
diff --git a/include/net/sctp/structs.h b/include/net/sctp/structs.h
index b016da6..dc2998a 100644
--- a/include/net/sctp/structs.h
+++ b/include/net/sctp/structs.h
@@ -805,7 +805,8 @@ struct sctp_datamsg {
can_delay; /* should this message be Nagle delayed */
};
-struct sctp_datamsg *sctp_datamsg_from_user(struct sctp_association *,
+struct sctp_datamsg *sctp_datamsg_from_user(struct net *,
+ struct sctp_association *,
struct sctp_sndrcvinfo *,
struct msghdr *, int len);
void sctp_datamsg_free(struct sctp_datamsg *);
diff --git a/net/sctp/associola.c b/net/sctp/associola.c
index b778eba..b640162 100644
--- a/net/sctp/associola.c
+++ b/net/sctp/associola.c
@@ -1147,8 +1147,9 @@ static void sctp_assoc_bh_rcv(struct work_struct *work)
* MUST silently discard these chunks if they are not placed
* after an AUTH chunk in the packet.
*/
- if (sctp_auth_recv_cid(subtype.chunk, asoc) && !chunk->auth)
- continue;
+ if (sctp_auth_recv_cid(net, subtype.chunk, asoc) &&
+ !chunk->auth)
+ continue;
/* Remember where the last DATA chunk came from so we
* know where to send the SACK.
@@ -1305,7 +1306,7 @@ void sctp_assoc_update(struct net *net,
new->peer.peer_hmacs = NULL;
sctp_auth_key_put(asoc->asoc_shared_key);
- sctp_auth_asoc_init_active_key(asoc, GFP_ATOMIC);
+ sctp_auth_asoc_init_active_key(net, asoc, GFP_ATOMIC);
}
/* Update the retran path for sending a retransmitted packet.
diff --git a/net/sctp/auth.c b/net/sctp/auth.c
index bf81204..36d8059 100644
--- a/net/sctp/auth.c
+++ b/net/sctp/auth.c
@@ -390,15 +390,18 @@ nomem:
/* Public interface to creat the association shared key.
* See code above for the algorithm.
*/
-int sctp_auth_asoc_init_active_key(struct sctp_association *asoc, gfp_t gfp)
+int sctp_auth_asoc_init_active_key(struct net *net,
+ struct sctp_association *asoc,
+ gfp_t gfp)
{
struct sctp_auth_bytes *secret;
struct sctp_shared_key *ep_key;
+ struct sctp_net_params *net_params = sctp_get_params(net);
/* If we don't support AUTH, or peer is not capable
* we don't need to do anything.
*/
- if (!sctp_auth_enable || !asoc->peer.auth_capable)
+ if (!net_params->auth_enable || !asoc->peer.auth_capable)
return 0;
/* If the key_id is non-zero and we couldn't find an
@@ -443,13 +446,14 @@ struct sctp_shared_key *sctp_auth_get_shkey(
* user context. This forces us to pre-allocated all possible transforms
* at the endpoint init time.
*/
-int sctp_auth_init_hmacs(struct sctp_endpoint *ep, gfp_t gfp)
+int sctp_auth_init_hmacs(struct net *net, struct sctp_endpoint *ep, gfp_t gfp)
{
struct crypto_hash *tfm = NULL;
__u16 id;
+ struct sctp_net_params *net_params = sctp_get_params(net);
/* if the transforms are already allocted, we are done */
- if (!sctp_auth_enable) {
+ if (!net_params->auth_enable) {
ep->auth_hmacs = NULL;
return 0;
}
@@ -672,18 +676,22 @@ static int __sctp_auth_cid(sctp_cid_t chunk, struct sctp_chunks_param *param)
}
/* Check if peer requested that this chunk is authenticated */
-int sctp_auth_send_cid(sctp_cid_t chunk, const struct sctp_association *asoc)
+int sctp_auth_send_cid(struct net *net, sctp_cid_t chunk,
+ const struct sctp_association *asoc)
{
- if (!sctp_auth_enable || !asoc || !asoc->peer.auth_capable)
+ struct sctp_net_params *net_params = sctp_get_params(net);
+ if (!net_params->auth_enable || !asoc || !asoc->peer.auth_capable)
return 0;
return __sctp_auth_cid(chunk, asoc->peer.peer_chunks);
}
/* Check if we requested that peer authenticate this chunk. */
-int sctp_auth_recv_cid(sctp_cid_t chunk, const struct sctp_association *asoc)
+int sctp_auth_recv_cid(struct net *net, sctp_cid_t chunk,
+ const struct sctp_association *asoc)
{
- if (!sctp_auth_enable || !asoc)
+ struct sctp_net_params *net_params = sctp_get_params(net);
+ if (!net_params->auth_enable || !asoc)
return 0;
return __sctp_auth_cid(chunk,
@@ -876,7 +884,8 @@ nomem:
return -ENOMEM;
}
-int sctp_auth_set_active_key(struct sctp_endpoint *ep,
+int sctp_auth_set_active_key(struct net *net,
+ struct sctp_endpoint *ep,
struct sctp_association *asoc,
__u16 key_id)
{
@@ -902,7 +911,7 @@ int sctp_auth_set_active_key(struct sctp_endpoint *ep,
if (asoc) {
asoc->active_key_id = key_id;
- sctp_auth_asoc_init_active_key(asoc, GFP_KERNEL);
+ sctp_auth_asoc_init_active_key(net, asoc, GFP_KERNEL);
} else
ep->active_key_id = key_id;
diff --git a/net/sctp/chunk.c b/net/sctp/chunk.c
index 6c85564..5211278 100644
--- a/net/sctp/chunk.c
+++ b/net/sctp/chunk.c
@@ -169,7 +169,8 @@ static void sctp_datamsg_assign(struct sctp_datamsg *msg, struct sctp_chunk *chu
* with a reasonable guess than always doing our fragmentation on the
* soft-interrupt.
*/
-struct sctp_datamsg *sctp_datamsg_from_user(struct sctp_association *asoc,
+struct sctp_datamsg *sctp_datamsg_from_user(struct net *net,
+ struct sctp_association *asoc,
struct sctp_sndrcvinfo *sinfo,
struct msghdr *msgh, int msg_len)
{
@@ -209,7 +210,7 @@ struct sctp_datamsg *sctp_datamsg_from_user(struct sctp_association *asoc,
* we need to accound for bundling of the AUTH chunks along with
* DATA.
*/
- if (sctp_auth_send_cid(SCTP_CID_DATA, asoc)) {
+ if (sctp_auth_send_cid(net, SCTP_CID_DATA, asoc)) {
struct sctp_hmac *hmac_desc = sctp_auth_asoc_get_hmac(asoc);
if (hmac_desc)
diff --git a/net/sctp/endpointola.c b/net/sctp/endpointola.c
index de42bd4..750df47 100644
--- a/net/sctp/endpointola.c
+++ b/net/sctp/endpointola.c
@@ -69,6 +69,7 @@ static struct sctp_endpoint *sctp_endpoint_init(struct sctp_endpoint *ep,
struct sctp_chunks_param *auth_chunks = NULL;
struct sctp_shared_key *null_key;
int err;
+ struct net *net = sock_net(sk);
ep->digest = kzalloc(SCTP_SIGNATURE_SIZE, gfp);
if (!ep->digest)
@@ -163,7 +164,7 @@ static struct sctp_endpoint *sctp_endpoint_init(struct sctp_endpoint *ep,
list_add(&null_key->key_list, &ep->endpoint_shared_keys);
/* Allocate and initialize transorms arrays for suported HMACs. */
- err = sctp_auth_init_hmacs(ep, gfp);
+ err = sctp_auth_init_hmacs(net, ep, gfp);
if (err)
goto nomem_hmacs;
@@ -465,7 +466,8 @@ normal:
}
state = asoc ? asoc->state : SCTP_STATE_CLOSED;
- if (sctp_auth_recv_cid(subtype.chunk, asoc) && !chunk->auth)
+ if (sctp_auth_recv_cid(sock_net(sk), subtype.chunk, asoc)
+ && !chunk->auth)
continue;
/* Remember where the last DATA chunk came from so we
diff --git a/net/sctp/sm_make_chunk.c b/net/sctp/sm_make_chunk.c
index af02b44..1d6c8b6 100644
--- a/net/sctp/sm_make_chunk.c
+++ b/net/sctp/sm_make_chunk.c
@@ -1365,7 +1365,7 @@ struct sctp_chunk *sctp_make_chunk(const struct sctp_association *asoc,
retval->chunk_end = ((__u8 *)chunk_hdr) + sizeof(struct sctp_chunkhdr);
/* Determine if the chunk needs to be authenticated */
- if (sctp_auth_send_cid(type, asoc))
+ if (sctp_auth_send_cid(&init_net, type, asoc))
retval->auth = 1;
/* Set the skb to the belonging sock for accounting. */
diff --git a/net/sctp/sm_sideeffect.c b/net/sctp/sm_sideeffect.c
index c683d88..7bd2d6d 100644
--- a/net/sctp/sm_sideeffect.c
+++ b/net/sctp/sm_sideeffect.c
@@ -1711,7 +1711,7 @@ static int sctp_cmd_interpreter(sctp_event_t event_type,
break;
case SCTP_CMD_ASSOC_SHKEY:
- error = sctp_auth_asoc_init_active_key(asoc,
+ error = sctp_auth_asoc_init_active_key(net, asoc,
GFP_ATOMIC);
break;
case SCTP_CMD_UPDATE_INITTAG:
diff --git a/net/sctp/sm_statefuns.c b/net/sctp/sm_statefuns.c
index 0d4aaa9..4cd027a 100644
--- a/net/sctp/sm_statefuns.c
+++ b/net/sctp/sm_statefuns.c
@@ -572,14 +572,14 @@ sctp_disposition_t sctp_sf_do_5_1C_ack(struct net *net,
* can't destroy this association just because the packet
* was malformed.
*/
- if (sctp_auth_recv_cid(SCTP_CID_ABORT, asoc))
- return sctp_sf_pdiscard(net, ep, asoc, type, arg,
- commands);
+ if (sctp_auth_recv_cid(net, SCTP_CID_ABORT, asoc))
+ return sctp_sf_pdiscard(net, ep, asoc, type,
+ arg, commands);
SCTP_INC_STATS(SCTP_MIB_ABORTEDS);
return sctp_stop_t1_and_abort(net, commands, error,
- ECONNREFUSED, asoc,
- chunk->transport);
+ ECONNREFUSED,
+ asoc, chunk->transport);
}
/* Tag the variable length parameters. Note that we never
@@ -757,7 +757,7 @@ sctp_disposition_t sctp_sf_do_5_1D_ce(struct net *net,
* sctp_process_init, set up the assocaition shared keys as
* necessary so that we can potentially authenticate the ACK
*/
- error = sctp_auth_asoc_init_active_key(new_asoc, GFP_ATOMIC);
+ error = sctp_auth_asoc_init_active_key(net, new_asoc, GFP_ATOMIC);
if (error)
goto nomem_init;
@@ -4364,7 +4364,7 @@ static sctp_disposition_t sctp_sf_abort_violation(
* can't destroy this association just because the packet
* was malformed.
*/
- if (sctp_auth_recv_cid(SCTP_CID_ABORT, asoc))
+ if (sctp_auth_recv_cid(net, SCTP_CID_ABORT, asoc))
goto discard;
/* Make the abort chunk. */
@@ -4490,7 +4490,7 @@ static sctp_disposition_t sctp_sf_violation_paramlen(
struct sctp_paramhdr *param = ext;
struct sctp_chunk *abort = NULL;
- if (sctp_auth_recv_cid(SCTP_CID_ABORT, asoc))
+ if (sctp_auth_recv_cid(net, SCTP_CID_ABORT, asoc))
goto discard;
/* Make the abort chunk. */
diff --git a/net/sctp/socket.c b/net/sctp/socket.c
index 78e4576..d14ac7d 100644
--- a/net/sctp/socket.c
+++ b/net/sctp/socket.c
@@ -101,9 +101,9 @@ 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 net*, struct sock *,
+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 *,
+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);
@@ -1599,6 +1599,7 @@ SCTP_STATIC int sctp_sendmsg(struct kiocb *iocb, struct sock *sk,
__u16 sinfo_flags = 0;
struct sctp_datamsg *datamsg;
int msg_flags = msg->msg_flags;
+ struct net *net = sock_net(sk);
SCTP_DEBUG_PRINTK("sctp_sendmsg(sk: %p, msg: %p, msg_len: %zu)\n",
sk, msg, msg_len);
@@ -1920,7 +1921,7 @@ SCTP_STATIC int sctp_sendmsg(struct kiocb *iocb, struct sock *sk,
}
/* Break the message into multiple chunks of maximum size. */
- datamsg = sctp_datamsg_from_user(asoc, sinfo, msg, msg_len);
+ datamsg = sctp_datamsg_from_user(net, asoc, sinfo, msg, msg_len);
if (!datamsg) {
err = -ENOMEM;
goto out_free;
@@ -3409,6 +3410,7 @@ static int sctp_setsockopt_active_key(struct sock *sk,
{
struct sctp_authkeyid val;
struct sctp_association *asoc;
+ struct net *net = sock_net(sk);
if (!sctp_auth_enable)
return -EACCES;
@@ -3422,7 +3424,7 @@ static int sctp_setsockopt_active_key(struct sock *sk,
if (!asoc && val.scact_assoc_id && sctp_style(sk, UDP))
return -EINVAL;
- return sctp_auth_set_active_key(sctp_sk(sk)->ep, asoc,
+ return sctp_auth_set_active_key(net, sctp_sk(sk)->ep, asoc,
val.scact_keynumber);
}
--
1.7.9.5
^ permalink raw reply related
* [PATCH 09/13] SCTP: Make transmitted packets use 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 set makes transmitted packets use per-namespace protocol
parameters such as rto_initial, max_retrans_path, etc.
Signed-off-by: Jan Ariyasu <jan.ariyasu@hp.com>
---
include/net/sctp/structs.h | 5 +++--
net/sctp/associola.c | 2 +-
net/sctp/output.c | 2 +-
net/sctp/outqueue.c | 16 ++++++++++------
net/sctp/sm_sideeffect.c | 7 ++++---
net/sctp/sm_statefuns.c | 2 +-
net/sctp/transport.c | 28 +++++++++++++++++-----------
7 files changed, 37 insertions(+), 25 deletions(-)
diff --git a/include/net/sctp/structs.h b/include/net/sctp/structs.h
index 72d473b..b016da6 100644
--- a/include/net/sctp/structs.h
+++ b/include/net/sctp/structs.h
@@ -1219,7 +1219,8 @@ struct sctp_transport {
__u64 hb_nonce;
};
-struct sctp_transport *sctp_transport_new(const union sctp_addr *,
+struct sctp_transport *sctp_transport_new(struct net *net,
+ const union sctp_addr *,
gfp_t);
void sctp_transport_set_owner(struct sctp_transport *,
struct sctp_association *);
@@ -1231,7 +1232,7 @@ void sctp_transport_free(struct sctp_transport *);
void sctp_transport_reset_timers(struct sctp_transport *);
void sctp_transport_hold(struct sctp_transport *);
void sctp_transport_put(struct sctp_transport *);
-void sctp_transport_update_rto(struct sctp_transport *, __u32);
+void sctp_transport_update_rto(struct net *, struct sctp_transport *, __u32);
void sctp_transport_raise_cwnd(struct sctp_transport *, __u32, __u32);
void sctp_transport_lower_cwnd(struct sctp_transport *, sctp_lower_cwnd_t);
void sctp_transport_burst_limited(struct sctp_transport *);
diff --git a/net/sctp/associola.c b/net/sctp/associola.c
index 5b4be66..b778eba 100644
--- a/net/sctp/associola.c
+++ b/net/sctp/associola.c
@@ -681,7 +681,7 @@ struct sctp_transport *sctp_assoc_add_peer(struct sctp_association *asoc,
return peer;
}
- peer = sctp_transport_new(addr, gfp);
+ peer = sctp_transport_new(net, addr, gfp);
if (!peer)
return NULL;
diff --git a/net/sctp/output.c b/net/sctp/output.c
index f9c5ffa..93a8b01 100644
--- a/net/sctp/output.c
+++ b/net/sctp/output.c
@@ -599,7 +599,7 @@ out:
return err;
no_route:
kfree_skb(nskb);
- IP_INC_STATS_BH(&init_net, IPSTATS_MIB_OUTNOROUTES);
+ IP_INC_STATS_BH(sock_net(asoc->base.sk), IPSTATS_MIB_OUTNOROUTES);
/* FIXME: Returning the 'err' will effect all the associations
* associated with a socket, although only one of the paths of the
diff --git a/net/sctp/outqueue.c b/net/sctp/outqueue.c
index e7aa177c..1334bad 100644
--- a/net/sctp/outqueue.c
+++ b/net/sctp/outqueue.c
@@ -60,7 +60,8 @@
/* Declare internal functions here. */
static int sctp_acked(struct sctp_sackhdr *sack, __u32 tsn);
-static void sctp_check_transmitted(struct sctp_outq *q,
+static void sctp_check_transmitted(struct net *net,
+ struct sctp_outq *q,
struct list_head *transmitted_queue,
struct sctp_transport *transport,
struct sctp_sackhdr *sack,
@@ -1154,6 +1155,7 @@ int sctp_outq_sack(struct sctp_outq *q, struct sctp_sackhdr *sack)
int count_of_newacks = 0;
int gap_ack_blocks;
u8 accum_moved = 0;
+ struct net *net = sock_net(asoc->base.sk);
/* Grab the association's destination address list. */
transport_list = &asoc->peer.transport_addr_list;
@@ -1210,7 +1212,8 @@ int sctp_outq_sack(struct sctp_outq *q, struct sctp_sackhdr *sack)
/* Run through the retransmit queue. Credit bytes received
* and free those chunks that we can.
*/
- sctp_check_transmitted(q, &q->retransmit, NULL, sack, &highest_new_tsn);
+ sctp_check_transmitted(net, q, &q->retransmit, NULL, sack,
+ &highest_new_tsn);
/* Run through the transmitted queue.
* Credit bytes received and free those chunks which we can.
@@ -1218,7 +1221,7 @@ int sctp_outq_sack(struct sctp_outq *q, struct sctp_sackhdr *sack)
* This is a MASSIVE candidate for optimization.
*/
list_for_each_entry(transport, transport_list, transports) {
- sctp_check_transmitted(q, &transport->transmitted,
+ sctp_check_transmitted(net, q, &transport->transmitted,
transport, sack, &highest_new_tsn);
/*
* SFR-CACC algorithm:
@@ -1323,7 +1326,8 @@ int sctp_outq_is_empty(const struct sctp_outq *q)
* transmitted_queue, we print a range: SACKED: TSN1-TSN2, TSN3, TSN4-TSN5.
* KEPT TSN6-TSN7, etc.
*/
-static void sctp_check_transmitted(struct sctp_outq *q,
+static void sctp_check_transmitted(struct net *net,
+ struct sctp_outq *q,
struct list_head *transmitted_queue,
struct sctp_transport *transport,
struct sctp_sackhdr *sack,
@@ -1402,8 +1406,8 @@ static void sctp_check_transmitted(struct sctp_outq *q,
tchunk->rtt_in_progress) {
tchunk->rtt_in_progress = 0;
rtt = jiffies - tchunk->sent_at;
- sctp_transport_update_rto(transport,
- rtt);
+ sctp_transport_update_rto(net,
+ transport, rtt);
}
}
diff --git a/net/sctp/sm_sideeffect.c b/net/sctp/sm_sideeffect.c
index 35cbbe5..c683d88 100644
--- a/net/sctp/sm_sideeffect.c
+++ b/net/sctp/sm_sideeffect.c
@@ -685,7 +685,8 @@ static void sctp_cmd_hb_timer_update(sctp_cmd_seq_t *cmds,
}
/* Helper function to handle the reception of an HEARTBEAT ACK. */
-static void sctp_cmd_transport_on(sctp_cmd_seq_t *cmds,
+static void sctp_cmd_transport_on(struct net *net,
+ sctp_cmd_seq_t *cmds,
struct sctp_association *asoc,
struct sctp_transport *t,
struct sctp_chunk *chunk)
@@ -739,7 +740,7 @@ static void sctp_cmd_transport_on(sctp_cmd_seq_t *cmds,
t->rto_pending = 1;
hbinfo = (sctp_sender_hb_info_t *) chunk->skb->data;
- sctp_transport_update_rto(t, (jiffies - hbinfo->sent_at));
+ sctp_transport_update_rto(net, t, (jiffies - hbinfo->sent_at));
/* Update the heartbeat timer. */
if (!mod_timer(&t->hb_timer, sctp_transport_timeout(t)))
@@ -1617,7 +1618,7 @@ static int sctp_cmd_interpreter(sctp_event_t event_type,
case SCTP_CMD_TRANSPORT_ON:
t = cmd->obj.transport;
- sctp_cmd_transport_on(commands, asoc, t, chunk);
+ sctp_cmd_transport_on(net, commands, asoc, t, chunk);
break;
case SCTP_CMD_HB_TIMERS_START:
diff --git a/net/sctp/sm_statefuns.c b/net/sctp/sm_statefuns.c
index b9b6b13..0d4aaa9 100644
--- a/net/sctp/sm_statefuns.c
+++ b/net/sctp/sm_statefuns.c
@@ -6043,7 +6043,7 @@ static struct sctp_packet *sctp_ootb_pkt_new(struct net *net,
}
/* Make a transport for the bucket, Eliza... */
- transport = sctp_transport_new(sctp_source(chunk), GFP_ATOMIC);
+ transport = sctp_transport_new(net, sctp_source(chunk), GFP_ATOMIC);
if (!transport)
goto nomem;
diff --git a/net/sctp/transport.c b/net/sctp/transport.c
index 856ba86..c4fc596 100644
--- a/net/sctp/transport.c
+++ b/net/sctp/transport.c
@@ -59,10 +59,13 @@
/* 1st Level Abstractions. */
/* Initialize a new transport from provided memory. */
-static struct sctp_transport *sctp_transport_init(struct sctp_transport *peer,
+static struct sctp_transport *sctp_transport_init(struct net *net,
+ struct sctp_transport *peer,
const union sctp_addr *addr,
gfp_t gfp)
{
+ struct sctp_net_params *net_params = sctp_get_params(net);
+
/* Copy in the address. */
peer->ipaddr = *addr;
peer->af_specific = sctp_get_af_specific(addr->sa.sa_family);
@@ -76,7 +79,7 @@ static struct sctp_transport *sctp_transport_init(struct sctp_transport *peer,
* given destination transport address, set RTO to the protocol
* parameter 'RTO.Initial'.
*/
- peer->rto = msecs_to_jiffies(sctp_rto_initial);
+ peer->rto = msecs_to_jiffies(net_params->rto_initial);
peer->last_time_heard = jiffies;
peer->last_time_ecne_reduced = jiffies;
@@ -86,8 +89,8 @@ static struct sctp_transport *sctp_transport_init(struct sctp_transport *peer,
SPP_SACKDELAY_ENABLE;
/* Initialize the default path max_retrans. */
- peer->pathmaxrxt = sctp_max_retrans_path;
- peer->pf_retrans = sctp_pf_retrans;
+ peer->pathmaxrxt = net_params->max_retrans_path;
+ peer->pf_retrans = net_params->pf_retrans;
INIT_LIST_HEAD(&peer->transmitted);
INIT_LIST_HEAD(&peer->send_ready);
@@ -109,7 +112,8 @@ static struct sctp_transport *sctp_transport_init(struct sctp_transport *peer,
}
/* Allocate and initialize a new transport. */
-struct sctp_transport *sctp_transport_new(const union sctp_addr *addr,
+struct sctp_transport *sctp_transport_new(struct net *net,
+ const union sctp_addr *addr,
gfp_t gfp)
{
struct sctp_transport *transport;
@@ -118,7 +122,7 @@ struct sctp_transport *sctp_transport_new(const union sctp_addr *addr,
if (!transport)
goto fail;
- if (!sctp_transport_init(transport, addr, gfp))
+ if (!sctp_transport_init(net, transport, addr, gfp))
goto fail_init;
transport->malloced = 1;
@@ -310,8 +314,10 @@ void sctp_transport_put(struct sctp_transport *transport)
}
/* Update transport's RTO based on the newly calculated RTT. */
-void sctp_transport_update_rto(struct sctp_transport *tp, __u32 rtt)
+void sctp_transport_update_rto(struct net *net, struct sctp_transport *tp,
+ __u32 rtt)
{
+ struct sctp_net_params *net_params = sctp_get_params(net);
/* Check for valid transport. */
SCTP_ASSERT(tp, "NULL transport", return);
@@ -330,10 +336,10 @@ void sctp_transport_update_rto(struct sctp_transport *tp, __u32 rtt)
* For example, assuming the default value of RTO.Alpha of
* 1/8, rto_alpha would be expressed as 3.
*/
- tp->rttvar = tp->rttvar - (tp->rttvar >> sctp_rto_beta)
- + ((abs(tp->srtt - rtt)) >> sctp_rto_beta);
- tp->srtt = tp->srtt - (tp->srtt >> sctp_rto_alpha)
- + (rtt >> sctp_rto_alpha);
+ tp->rttvar = tp->rttvar - (tp->rttvar >> net_params->rto_beta)
+ + ((abs(tp->srtt - rtt)) >> net_params->rto_beta);
+ tp->srtt = tp->srtt - (tp->srtt >> net_params->rto_alpha)
+ + (rtt >> net_params->rto_alpha);
} else {
/* 6.3.1 C2) When the first RTT measurement R is made, set
* SRTT <- R, RTTVAR <- R/2.
--
1.7.9.5
^ permalink raw reply related
* [PATCH 08/13] SCTP: Make associations use per-namespace configuration.
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
These changes make associations namespace aware, including
association ID lists and their associated locks.
Signed-off-by: Jan Ariyasu <jan.ariyasu@hp.com>
---
include/net/sctp/sctp.h | 3 ---
include/net/sctp/structs.h | 3 ++-
net/sctp/associola.c | 37 ++++++++++++++++++++++++-------------
net/sctp/input.c | 25 +++++++++++++++----------
net/sctp/sm_sideeffect.c | 9 ++++-----
5 files changed, 45 insertions(+), 32 deletions(-)
diff --git a/include/net/sctp/sctp.h b/include/net/sctp/sctp.h
index 8488d5e..363a786 100644
--- a/include/net/sctp/sctp.h
+++ b/include/net/sctp/sctp.h
@@ -601,9 +601,6 @@ extern struct proto sctp_prot;
extern struct proto sctpv6_prot;
void sctp_put_port(struct sock *sk);
-extern struct idr sctp_assocs_id;
-extern spinlock_t sctp_assocs_id_lock;
-
/* Static inline functions. */
/* Convert from an IP version number to an Address Family symbol. */
diff --git a/include/net/sctp/structs.h b/include/net/sctp/structs.h
index 2034d53..72d473b 100644
--- a/include/net/sctp/structs.h
+++ b/include/net/sctp/structs.h
@@ -2153,7 +2153,8 @@ struct sctp_transport *sctp_assoc_is_match(struct sctp_association *,
const union sctp_addr *,
const union sctp_addr *);
void sctp_assoc_migrate(struct sctp_association *, struct sock *);
-void sctp_assoc_update(struct sctp_association *old,
+void sctp_assoc_update(struct net *net,
+ struct sctp_association *old,
struct sctp_association *new);
__u32 sctp_association_get_next_tsn(struct sctp_association *);
diff --git a/net/sctp/associola.c b/net/sctp/associola.c
index 1bd956b..5b4be66 100644
--- a/net/sctp/associola.c
+++ b/net/sctp/associola.c
@@ -86,6 +86,8 @@ static struct sctp_association *sctp_association_init(struct sctp_association *a
int i;
sctp_paramhdr_t *p;
int err;
+ struct sctp_net_params *net_params =
+ sctp_get_params(sock_net(sk));
/* Retrieve the SCTP per socket area. */
sp = sctp_sk((struct sock *)sk);
@@ -124,7 +126,7 @@ static struct sctp_association *sctp_association_init(struct sctp_association *a
* socket values.
*/
asoc->max_retrans = sp->assocparams.sasoc_asocmaxrxt;
- asoc->pf_retrans = sctp_pf_retrans;
+ asoc->pf_retrans = net_params->pf_retrans;
asoc->rto_initial = msecs_to_jiffies(sp->rtoinfo.srto_initial);
asoc->rto_max = msecs_to_jiffies(sp->rtoinfo.srto_max);
@@ -175,7 +177,8 @@ static struct sctp_association *sctp_association_init(struct sctp_association *a
asoc->timeouts[SCTP_EVENT_TIMEOUT_HEARTBEAT] = 0;
asoc->timeouts[SCTP_EVENT_TIMEOUT_SACK] = asoc->sackdelay;
asoc->timeouts[SCTP_EVENT_TIMEOUT_AUTOCLOSE] =
- min_t(unsigned long, sp->autoclose, sctp_max_autoclose) * HZ;
+ min_t(unsigned long, sp->autoclose,
+ net_params->max_autoclose) * HZ;
/* Initializes the timers */
for (i = SCTP_EVENT_TIMEOUT_NONE; i < SCTP_NUM_TIMEOUT_TYPES; ++i)
@@ -281,7 +284,7 @@ static struct sctp_association *sctp_association_init(struct sctp_association *a
* and will revert old behavior.
*/
asoc->peer.asconf_capable = 0;
- if (sctp_addip_noauth)
+ if (net_params->addip_noauth_enable)
asoc->peer.asconf_capable = 1;
asoc->asconf_addr_del_pending = NULL;
asoc->src_out_of_asoc_ok = 0;
@@ -468,15 +471,18 @@ void sctp_association_free(struct sctp_association *asoc)
/* Cleanup and free up an association. */
static void sctp_association_destroy(struct sctp_association *asoc)
{
+ struct sctp_ns_globals *ns_globals =
+ sctp_get_ns_globals(sock_net(asoc->base.sk));
+
SCTP_ASSERT(asoc->base.dead, "Assoc is not dead", return);
sctp_endpoint_put(asoc->ep);
sock_put(asoc->base.sk);
if (asoc->assoc_id != 0) {
- spin_lock_bh(&sctp_assocs_id_lock);
- idr_remove(&sctp_assocs_id, asoc->assoc_id);
- spin_unlock_bh(&sctp_assocs_id_lock);
+ spin_lock_bh(&ns_globals->assocs_id_lock);
+ idr_remove(&ns_globals->assocs_id, asoc->assoc_id);
+ spin_unlock_bh(&ns_globals->assocs_id_lock);
}
WARN_ON(atomic_read(&asoc->rmem_alloc));
@@ -1204,7 +1210,8 @@ void sctp_assoc_migrate(struct sctp_association *assoc, struct sock *newsk)
}
/* Update an association (possibly from unexpected COOKIE-ECHO processing). */
-void sctp_assoc_update(struct sctp_association *asoc,
+void sctp_assoc_update(struct net *net,
+ struct sctp_association *asoc,
struct sctp_association *new)
{
struct sctp_transport *trans;
@@ -1416,6 +1423,8 @@ void sctp_assoc_sync_pmtu(struct sock *sk, struct sctp_association *asoc)
/* Should we send a SACK to update our peer? */
static inline int sctp_peer_needs_update(struct sctp_association *asoc)
{
+ struct sctp_net_params *net_params =
+ sctp_get_params(sock_net(asoc->base.sk));
switch (asoc->state) {
case SCTP_STATE_ESTABLISHED:
case SCTP_STATE_SHUTDOWN_PENDING:
@@ -1423,8 +1432,8 @@ static inline int sctp_peer_needs_update(struct sctp_association *asoc)
case SCTP_STATE_SHUTDOWN_SENT:
if ((asoc->rwnd > asoc->a_rwnd) &&
((asoc->rwnd - asoc->a_rwnd) >= max_t(__u32,
- (asoc->base.sk->sk_rcvbuf >> sctp_rwnd_upd_shift),
- asoc->pathmtu)))
+ (asoc->base.sk->sk_rcvbuf >>
+ net_params->rwnd_update_shift), asoc->pathmtu)))
return 1;
break;
default:
@@ -1582,23 +1591,25 @@ int sctp_assoc_set_id(struct sctp_association *asoc, gfp_t gfp)
{
int assoc_id;
int error = 0;
+ struct sctp_ns_globals *ns_globals =
+ sctp_get_ns_globals(sock_net(asoc->base.sk));
/* If the id is already assigned, keep it. */
if (asoc->assoc_id)
return error;
retry:
- if (unlikely(!idr_pre_get(&sctp_assocs_id, gfp)))
+ if (unlikely(!idr_pre_get(&ns_globals->assocs_id, gfp)))
return -ENOMEM;
- spin_lock_bh(&sctp_assocs_id_lock);
- error = idr_get_new_above(&sctp_assocs_id, (void *)asoc,
+ spin_lock_bh(&ns_globals->assocs_id_lock);
+ error = idr_get_new_above(&ns_globals->assocs_id, (void *)asoc,
idr_low, &assoc_id);
if (!error) {
idr_low = assoc_id + 1;
if (idr_low == INT_MAX)
idr_low = 1;
}
- spin_unlock_bh(&sctp_assocs_id_lock);
+ spin_unlock_bh(&ns_globals->assocs_id_lock);
if (error == -EAGAIN)
goto retry;
else if (error)
diff --git a/net/sctp/input.c b/net/sctp/input.c
index 1b92da2..9b53b95 100644
--- a/net/sctp/input.c
+++ b/net/sctp/input.c
@@ -70,7 +70,8 @@ static struct sctp_association *__sctp_rcv_lookup(struct sk_buff *skb,
const union sctp_addr *laddr,
const union sctp_addr *paddr,
struct sctp_transport **transportp);
-static struct sctp_endpoint *__sctp_rcv_lookup_endpoint(const union sctp_addr *laddr);
+static struct sctp_endpoint *__sctp_rcv_lookup_endpoint(struct net *net,
+ const union sctp_addr *laddr);
static struct sctp_association *__sctp_lookup_association(
const union sctp_addr *local,
const union sctp_addr *peer,
@@ -129,6 +130,7 @@ int sctp_rcv(struct sk_buff *skb)
union sctp_addr dest;
int family;
struct sctp_af *af;
+ struct net *net = dev_net(skb->dev);
if (skb->pkt_type!=PACKET_HOST)
goto discard_it;
@@ -181,7 +183,7 @@ int sctp_rcv(struct sk_buff *skb)
asoc = __sctp_rcv_lookup(skb, &src, &dest, &transport);
if (!asoc)
- ep = __sctp_rcv_lookup_endpoint(&dest);
+ ep = __sctp_rcv_lookup_endpoint(net, &dest);
/* Retrieve the common input handling substructure. */
rcvr = asoc ? &asoc->base : &ep->base;
@@ -200,7 +202,7 @@ int sctp_rcv(struct sk_buff *skb)
sctp_endpoint_put(ep);
ep = NULL;
}
- sk = *(sctp_get_ctl_sock(&init_net));
+ sk = *(sctp_get_ctl_sock(net));
ep = sctp_sk(sk)->ep;
sctp_endpoint_hold(ep);
rcvr = &ep->base;
@@ -539,7 +541,7 @@ struct sock *sctp_err_lookup(int family, struct sk_buff *skb,
* servers this needs to be solved differently.
*/
if (sock_owned_by_user(sk))
- NET_INC_STATS_BH(&init_net, LINUX_MIB_LOCKDROPPEDICMPS);
+ NET_INC_STATS_BH(sock_net(sk), LINUX_MIB_LOCKDROPPEDICMPS);
*app = asoc;
*tpp = transport;
@@ -588,7 +590,7 @@ void sctp_v4_err(struct sk_buff *skb, __u32 info)
int err;
if (skb->len < ihlen + 8) {
- ICMP_INC_STATS_BH(&init_net, ICMP_MIB_INERRORS);
+ ICMP_INC_STATS_BH(dev_net(skb->dev), ICMP_MIB_INERRORS);
return;
}
@@ -602,7 +604,7 @@ void sctp_v4_err(struct sk_buff *skb, __u32 info)
skb->network_header = saveip;
skb->transport_header = savesctp;
if (!sk) {
- ICMP_INC_STATS_BH(&init_net, ICMP_MIB_INERRORS);
+ ICMP_INC_STATS_BH(dev_net(skb->dev), ICMP_MIB_INERRORS);
return;
}
/* Warning: The sock lock is held. Remember to call
@@ -770,7 +772,8 @@ void sctp_unhash_endpoint(struct sctp_endpoint *ep)
}
/* Look up an endpoint. */
-static struct sctp_endpoint *__sctp_rcv_lookup_endpoint(const union sctp_addr *laddr)
+static struct sctp_endpoint *__sctp_rcv_lookup_endpoint(struct net *net,
+ const union sctp_addr *laddr)
{
struct sctp_hashbucket *head;
struct sctp_ep_common *epb;
@@ -787,7 +790,7 @@ static struct sctp_endpoint *__sctp_rcv_lookup_endpoint(const union sctp_addr *l
goto hit;
}
- ep = sctp_sk(*(sctp_get_ctl_sock(&init_net)))->ep;
+ ep = sctp_sk(*(sctp_get_ctl_sock(net)))->ep;
hit:
sctp_endpoint_hold(ep);
@@ -1042,6 +1045,8 @@ static struct sctp_association *__sctp_rcv_walk_lookup(struct sk_buff *skb,
int have_auth = 0;
unsigned int chunk_num = 1;
__u8 *ch_end;
+ struct sctp_net_params *net_params =
+ sctp_get_params(dev_net(skb->dev));
/* Walk through the chunks looking for AUTH or ASCONF chunks
* to help us find the association.
@@ -1074,8 +1079,8 @@ static struct sctp_association *__sctp_rcv_walk_lookup(struct sk_buff *skb,
break;
case SCTP_CID_ASCONF:
- if (have_auth || sctp_addip_noauth)
- asoc = __sctp_rcv_asconf_lookup(ch, laddr,
+ if (have_auth || net_params->addip_noauth_enable)
+ asoc = __sctp_rcv_asconf_lookup(ch, laddr,
sctp_hdr(skb)->source,
transportp);
default:
diff --git a/net/sctp/sm_sideeffect.c b/net/sctp/sm_sideeffect.c
index 2c895fd..35cbbe5 100644
--- a/net/sctp/sm_sideeffect.c
+++ b/net/sctp/sm_sideeffect.c
@@ -1058,8 +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(sock_net(asoc->base.sk), asoc,
- asconf))
+ if (sctp_primitive_ASCONF(sock_net(asoc->base.sk),
+ asoc, asconf))
sctp_chunk_free(asconf);
else
asoc->addip_last_asconf = asconf;
@@ -1277,7 +1277,7 @@ static int sctp_cmd_interpreter(sctp_event_t event_type,
break;
case SCTP_CMD_UPDATE_ASSOC:
- sctp_assoc_update(asoc, cmd->obj.ptr);
+ sctp_assoc_update(net, asoc, cmd->obj.ptr);
break;
case SCTP_CMD_PURGE_OUTQUEUE:
@@ -1354,8 +1354,7 @@ static int sctp_cmd_interpreter(sctp_event_t event_type,
* layer which will bail.
*/
error = sctp_cmd_process_init(net, commands, asoc,
- chunk, cmd->obj.ptr,
- gfp);
+ chunk, cmd->obj.ptr, gfp);
break;
case SCTP_CMD_GEN_COOKIE_ECHO:
--
1.7.9.5
^ permalink raw reply related
* [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
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