Netdev List
 help / color / mirror / Atom feed
* Re: CPU: 0 Not tainted  (3.1.9+ #1) when ifconfig rose0 down
From: Folkert van Heusden @ 2012-08-05 17:08 UTC (permalink / raw)
  To: Bernard Pidoux, folkert; +Cc: Eric W. Biederman, linux-hams, Linux Netdev List

Good luck!
I'm to busy myself with debugging the baycom driver.
Can do at most 2 steps a day and it are 15 steps... (54k changesets)

Bernard Pidoux <bernard.pidoux@free.fr> wrote:

>Thanks for suggesting a bissect. However I guess that this bug has 
>always been there !
>
>I am not professionaly involved in programming, however I committed a 
>few patches for ROSE, AX.25 and NetRom modules since a few years.
>
>I reactivated netconfig and here is the report showing that kernel panic 
>occurs when rose_device_event is triggered when issuing command
>ifconfig rose0 down
>
>[ 1215.153302] rose_kill_by_device() rose->neighbour->use 0
>[ 1215.153316] BUG: unable to handle kernel NULL pointer dereference at 
>000000000000002a
>[ 1215.153321] IP: [<ffffffffa065e37d>] rose_device_event+0x11d/0x160 [rose]
>[ 1215.153333] PGD 36340067 PUD 359fa067 PMD 0
>[ 1215.153338] Oops: 0002 [#1] SMP
>[ 1215.153343] CPU 1
>[ 1215.153344] Modules linked in: af_packet rose mkiss ax25 nfsd 
>exportfs nfs nfs_acl auth_rpcgss fscache lockd sunrpc netconsole 
>configfs bnep bluetooth rfkill snd_hda_codec_idt snd_hda_intel 
>snd_hda_codec snd_hwdep snd_pcm snd_page_alloc snd_timer snd 
>i82975x_edac soundcore e1000e ppdev parport_pc parport edac_core 
>iTCO_wdt iTCO_vendor_support serio_raw i2c_i801 processor coretemp evdev 
>ipv6 autofs4 usbhid hid ext4 crc16 jbd2 sd_mod crc_t10dif firewire_ohci 
>firewire_core ehci_hcd crc_itu_t uhci_hcd usbcore usb_common nouveau 
>button video mxm_wmi wmi i2c_algo_bit drm_kms_helper ttm drm i2c_core 
>ahci libahci ata_piix pata_marvell libata scsi_mod [last unloaded: 
>microcode]
>[ 1215.153395]
>[ 1215.153398] Pid: 18637, comm: ifconfig Not tainted 3.4.7 #8 
>/D975XBX2
>[ 1215.153404] RIP: 0010:[<ffffffffa065e37d>]  [<ffffffffa065e37d>] 
>rose_device_event+0x11d/0x160 [rose]
>[ 1215.153411] RSP: 0000:ffff880035271ca8  EFLAGS: 00010296
>[ 1215.153414] RAX: 0000000000000000 RBX: ffff88003d0c2838 RCX: 
>0000000230924000
>[ 1215.153417] RDX: 0000000000000002 RSI: 0000000000000001 RDI: 
>ffffffffa0665f28
>[ 1215.153420] RBP: ffff880035271cb8 R08: 0000000000000002 R09: 
>0000000000000000
>[ 1215.153422] R10: 0000000000000003 R11: 0000000000000000 R12: 
>ffff88003a9e1000
>[ 1215.153425] R13: 00000000fffffff1 R14: ffffffffa05b0000 R15: 
>0000000000000000
>[ 1215.153429] FS:  00007fb7a318f700(0000) GS:ffff88003fa80000(0000) 
>knlGS:0000000000000000
>[ 1215.153433] CS:  0010 DS: 0000 ES: 0000 CR0: 000000008005003b
>[ 1215.153435] CR2: 000000000000002a CR3: 00000000393fd000 CR4: 
>00000000000007e0
>[ 1215.153438] DR0: 0000000000000000 DR1: 0000000000000000 DR2: 
>0000000000000000
>[ 1215.153441] DR3: 0000000000000000 DR6: 00000000ffff0ff0 DR7: 
>0000000000000400
>[ 1215.153445] Process ifconfig (pid: 18637, threadinfo 
>ffff880035270000, task ffff88003f5f5d90)
>[ 1215.153448] Stack:
>[ 1215.153450]  0000000000000002 ffff88003a9e1000 ffff880035271cf8 
>ffffffff8146d86d
>[ 1215.153455]  ffff880036040d00 0000000000000002 ffff88003a9e1000 
>0000000000000000
>[ 1215.153459]  00000000ffffff9d 0000000000000000 ffff880035271d08 
>ffffffff8107a2b6
>[ 1215.153464] Call Trace:
>[ 1215.153470]  [<ffffffff8146d86d>] notifier_call_chain+0x4d/0x70
>[ 1215.153476]  [<ffffffff8107a2b6>] raw_notifier_call_chain+0x16/0x20
>[ 1215.153483]  [<ffffffff81395136>] call_netdevice_notifiers+0x36/0x60
>[ 1215.153487]  [<ffffffff8139b9ea>] __dev_notify_flags+0x6a/0x90
>[ 1215.153491]  [<ffffffff8139ba55>] dev_change_flags+0x45/0x70
>[ 1215.153496]  [<ffffffff81403aed>] devinet_ioctl+0x61d/0x7b0
>[ 1215.153500]  [<ffffffff81403f05>] inet_ioctl+0x75/0x90
>[ 1215.153505]  [<ffffffff8137fbd0>] sock_do_ioctl+0x30/0x70
>[ 1215.153509]  [<ffffffff8137fc89>] sock_ioctl+0x79/0x2f0
>[ 1215.153514]  [<ffffffff811829d8>] do_vfs_ioctl+0x98/0x560
>[ 1215.153517]  [<ffffffff81182f31>] sys_ioctl+0x91/0xa0
>[ 1215.153522]  [<ffffffff81471b39>] system_call_fastpath+0x16/0x1b
>[ 1215.153525] Code: e0 5b 41 5c 31 c0 5d c3 48 8d 7b c8 31 c9 ba 09 00 
>00 00 be 65 00 00 00 e8 a1 5c 00 00 48 8b 83 b8 04 00 00 48 c7 c7 28 5f 
>66 a0 <66> 83 68 2a 01 48 8b 83 b8 04 00 00 0f b7 70 2a 31 c0 e8 d4 10
>[ 1215.153561] RIP  [<ffffffffa065e37d>] rose_device_event+0x11d/0x160 
>[rose]
>[ 1215.153567]  RSP <ffff880035271ca8>
>[ 1215.153569] CR2: 000000000000002a
>[ 1215.177577] ---[ end trace d23a7ddff228876c ]---
>[ 1215.177589] Kernel panic - not syncing: Fatal exception in interrupt
>[ 1215.177662] panic occurred, switching back to text console
>[ 1215.177717] Rebooting in 60 seconds..
>
>I inserted some printk into rose_device_event() and commented calls to 
>subroutines.
>Without calling subroutines, there is no more kernel panic.
>Same results when replacing rose_kill_by_device() in net/rose/af_rose.c, 
>rose_link_device_down() and rose_rt_device() in
>net/rose_route.c by a dummy functions with just a printk inside.
>
>I am glad that I found make parameters that shorten the debugging
>cycle :
>
>make modules SUBDIRS=net/rose
>make modules_install SUBDIRS=net/rose
>
>Now I have to go further into each subroutines step by step in order to 
>find out the falty code !
>
>
>Bernard
>
>
>On 03/08/2012 16:32, folkert wrote:
>>> You might want to simply try moving unregister_netdevice_notifier a bit
>>> earlier in rose_exit and see if that helps.  Otherwise I would recommend
>>> instrumenting the code up with some printk so you can understand what
>>> part of unregistration is failing.
>>
>> Or bisect! Give e.g. the oldest 2.6 kernel a try to find a last known
>> good and then do a bisect upto a known bad kernel.
>>
>>
>> Folkert van Heusden
>>
>

^ permalink raw reply

* Re: [RFC v2 6/7] tracepoint: use new hashtable implementation
From: Sasha Levin @ 2012-08-05 17:03 UTC (permalink / raw)
  To: Mathieu Desnoyers
  Cc: Steven Rostedt, torvalds, tj, akpm, linux-kernel, linux-mm,
	paul.gortmaker, davem, mingo, ebiederm, aarcange, ericvh, netdev
In-Reply-To: <20120805163114.GA21768@Krystal>

On 08/05/2012 06:31 PM, Mathieu Desnoyers wrote:
> * Steven Rostedt (rostedt@goodmis.org) wrote:
>> 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);
> 
> I wonder why the "static" has been embedded within
> "DEFINE_STATIC_HASHTABLE" ? I'm used to see something similar to:
> 
> static DEFINE_HASHTABLE(tracepoint_table, TRACEPOINT_HASH_BITS);
> 
> elsewhere in the kernel (e.g. static DEFINE_PER_CPU(), static
> DEFINE_MUTEX(), etc).

We had to create two different definitions of hashtable, one to be used as static and one to be used in structs. I chose the uglier way of doing it, and Tejun already pointed it out :)

It will be much nicer in the future.

>>>  
>>>  /*
>>>   * 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;
>>> -	}
>>> +
> 
> Typically, where there are 2 or more nesting levels, I try to keep the
> outer brackets, even if the 1st level only contain a single statement
> (this is what I did across tracepoint.c). This is especially useful when
> nesting multiple if levels, and ensures the "else" clause match the
> right if. We might want to keep it that way within the file, to ensure
> style consistency.

Roger that, will fix.

> Other than that, it looks good!
> 
> Thanks!
> 
> Mathieu
> 

Thanks for the review Mathieu!

--
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: [RFC v2 6/7] tracepoint: use new hashtable implementation
From: Mathieu Desnoyers @ 2012-08-05 16:31 UTC (permalink / raw)
  To: Steven Rostedt
  Cc: Sasha Levin, torvalds, tj, akpm, linux-kernel, linux-mm,
	paul.gortmaker, davem, mingo, ebiederm, aarcange, ericvh, netdev
In-Reply-To: <1344126994.27983.116.camel@gandalf.stny.rr.com>

* Steven Rostedt (rostedt@goodmis.org) wrote:
> 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);

I wonder why the "static" has been embedded within
"DEFINE_STATIC_HASHTABLE" ? I'm used to see something similar to:

static DEFINE_HASHTABLE(tracepoint_table, TRACEPOINT_HASH_BITS);

elsewhere in the kernel (e.g. static DEFINE_PER_CPU(), static
DEFINE_MUTEX(), etc).

> >  
> >  /*
> >   * 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;
> > -	}
> > +

Typically, where there are 2 or more nesting levels, I try to keep the
outer brackets, even if the 1st level only contain a single statement
(this is what I did across tracepoint.c). This is especially useful when
nesting multiple if levels, and ensures the "else" clause match the
right if. We might want to keep it that way within the file, to ensure
style consistency.

Other than that, it looks good!

Thanks!

Mathieu

> >  	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);
> >  }
> >  
> 
> 

-- 
Mathieu Desnoyers
Operating System Efficiency R&D Consultant
EfficiOS Inc.
http://www.efficios.com

--
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: CPU: 0 Not tainted  (3.1.9+ #1) when ifconfig rose0 down
From: Bernard Pidoux @ 2012-08-05 16:23 UTC (permalink / raw)
  To: folkert; +Cc: Eric W. Biederman, linux-hams, Linux Netdev List
In-Reply-To: <20120803143200.GE10211@belle.intranet.vanheusden.com>

Thanks for suggesting a bissect. However I guess that this bug has 
always been there !

I am not professionaly involved in programming, however I committed a 
few patches for ROSE, AX.25 and NetRom modules since a few years.

I reactivated netconfig and here is the report showing that kernel panic 
occurs when rose_device_event is triggered when issuing command
ifconfig rose0 down

[ 1215.153302] rose_kill_by_device() rose->neighbour->use 0
[ 1215.153316] BUG: unable to handle kernel NULL pointer dereference at 
000000000000002a
[ 1215.153321] IP: [<ffffffffa065e37d>] rose_device_event+0x11d/0x160 [rose]
[ 1215.153333] PGD 36340067 PUD 359fa067 PMD 0
[ 1215.153338] Oops: 0002 [#1] SMP
[ 1215.153343] CPU 1
[ 1215.153344] Modules linked in: af_packet rose mkiss ax25 nfsd 
exportfs nfs nfs_acl auth_rpcgss fscache lockd sunrpc netconsole 
configfs bnep bluetooth rfkill snd_hda_codec_idt snd_hda_intel 
snd_hda_codec snd_hwdep snd_pcm snd_page_alloc snd_timer snd 
i82975x_edac soundcore e1000e ppdev parport_pc parport edac_core 
iTCO_wdt iTCO_vendor_support serio_raw i2c_i801 processor coretemp evdev 
ipv6 autofs4 usbhid hid ext4 crc16 jbd2 sd_mod crc_t10dif firewire_ohci 
firewire_core ehci_hcd crc_itu_t uhci_hcd usbcore usb_common nouveau 
button video mxm_wmi wmi i2c_algo_bit drm_kms_helper ttm drm i2c_core 
ahci libahci ata_piix pata_marvell libata scsi_mod [last unloaded: 
microcode]
[ 1215.153395]
[ 1215.153398] Pid: 18637, comm: ifconfig Not tainted 3.4.7 #8 
/D975XBX2
[ 1215.153404] RIP: 0010:[<ffffffffa065e37d>]  [<ffffffffa065e37d>] 
rose_device_event+0x11d/0x160 [rose]
[ 1215.153411] RSP: 0000:ffff880035271ca8  EFLAGS: 00010296
[ 1215.153414] RAX: 0000000000000000 RBX: ffff88003d0c2838 RCX: 
0000000230924000
[ 1215.153417] RDX: 0000000000000002 RSI: 0000000000000001 RDI: 
ffffffffa0665f28
[ 1215.153420] RBP: ffff880035271cb8 R08: 0000000000000002 R09: 
0000000000000000
[ 1215.153422] R10: 0000000000000003 R11: 0000000000000000 R12: 
ffff88003a9e1000
[ 1215.153425] R13: 00000000fffffff1 R14: ffffffffa05b0000 R15: 
0000000000000000
[ 1215.153429] FS:  00007fb7a318f700(0000) GS:ffff88003fa80000(0000) 
knlGS:0000000000000000
[ 1215.153433] CS:  0010 DS: 0000 ES: 0000 CR0: 000000008005003b
[ 1215.153435] CR2: 000000000000002a CR3: 00000000393fd000 CR4: 
00000000000007e0
[ 1215.153438] DR0: 0000000000000000 DR1: 0000000000000000 DR2: 
0000000000000000
[ 1215.153441] DR3: 0000000000000000 DR6: 00000000ffff0ff0 DR7: 
0000000000000400
[ 1215.153445] Process ifconfig (pid: 18637, threadinfo 
ffff880035270000, task ffff88003f5f5d90)
[ 1215.153448] Stack:
[ 1215.153450]  0000000000000002 ffff88003a9e1000 ffff880035271cf8 
ffffffff8146d86d
[ 1215.153455]  ffff880036040d00 0000000000000002 ffff88003a9e1000 
0000000000000000
[ 1215.153459]  00000000ffffff9d 0000000000000000 ffff880035271d08 
ffffffff8107a2b6
[ 1215.153464] Call Trace:
[ 1215.153470]  [<ffffffff8146d86d>] notifier_call_chain+0x4d/0x70
[ 1215.153476]  [<ffffffff8107a2b6>] raw_notifier_call_chain+0x16/0x20
[ 1215.153483]  [<ffffffff81395136>] call_netdevice_notifiers+0x36/0x60
[ 1215.153487]  [<ffffffff8139b9ea>] __dev_notify_flags+0x6a/0x90
[ 1215.153491]  [<ffffffff8139ba55>] dev_change_flags+0x45/0x70
[ 1215.153496]  [<ffffffff81403aed>] devinet_ioctl+0x61d/0x7b0
[ 1215.153500]  [<ffffffff81403f05>] inet_ioctl+0x75/0x90
[ 1215.153505]  [<ffffffff8137fbd0>] sock_do_ioctl+0x30/0x70
[ 1215.153509]  [<ffffffff8137fc89>] sock_ioctl+0x79/0x2f0
[ 1215.153514]  [<ffffffff811829d8>] do_vfs_ioctl+0x98/0x560
[ 1215.153517]  [<ffffffff81182f31>] sys_ioctl+0x91/0xa0
[ 1215.153522]  [<ffffffff81471b39>] system_call_fastpath+0x16/0x1b
[ 1215.153525] Code: e0 5b 41 5c 31 c0 5d c3 48 8d 7b c8 31 c9 ba 09 00 
00 00 be 65 00 00 00 e8 a1 5c 00 00 48 8b 83 b8 04 00 00 48 c7 c7 28 5f 
66 a0 <66> 83 68 2a 01 48 8b 83 b8 04 00 00 0f b7 70 2a 31 c0 e8 d4 10
[ 1215.153561] RIP  [<ffffffffa065e37d>] rose_device_event+0x11d/0x160 
[rose]
[ 1215.153567]  RSP <ffff880035271ca8>
[ 1215.153569] CR2: 000000000000002a
[ 1215.177577] ---[ end trace d23a7ddff228876c ]---
[ 1215.177589] Kernel panic - not syncing: Fatal exception in interrupt
[ 1215.177662] panic occurred, switching back to text console
[ 1215.177717] Rebooting in 60 seconds..

I inserted some printk into rose_device_event() and commented calls to 
subroutines.
Without calling subroutines, there is no more kernel panic.
Same results when replacing rose_kill_by_device() in net/rose/af_rose.c, 
rose_link_device_down() and rose_rt_device() in
net/rose_route.c by a dummy functions with just a printk inside.

I am glad that I found make parameters that shorten the debugging
cycle :

make modules SUBDIRS=net/rose
make modules_install SUBDIRS=net/rose

Now I have to go further into each subroutines step by step in order to 
find out the falty code !


Bernard


On 03/08/2012 16:32, folkert wrote:
>> You might want to simply try moving unregister_netdevice_notifier a bit
>> earlier in rose_exit and see if that helps.  Otherwise I would recommend
>> instrumenting the code up with some printk so you can understand what
>> part of unregistration is failing.
>
> Or bisect! Give e.g. the oldest 2.6 kernel a try to find a last known
> good and then do a bisect upto a known bad kernel.
>
>
> Folkert van Heusden
>


^ permalink raw reply

* [PATCH 6/6] drivers/atm/iphase.c: fix error return code
From: Julia Lawall @ 2012-08-05  9:52 UTC (permalink / raw)
  To: Chas Williams
  Cc: kernel-janitors, linux-atm-general, netdev, linux-kernel,
	Julia Lawall
In-Reply-To: <1344160356-387-1-git-send-email-Julia.Lawall@lip6.fr>

From: Julia Lawall <julia@diku.dk>

Convert a 0 error return code to a negative one, as returned elsewhere in the
function.

A simplified version of the semantic match that finds this problem is as
follows: (http://coccinelle.lip6.fr/)

// <smpl>
@@
identifier ret;
expression e,e1,e2,e3,e4,x;
@@

(
if (\(ret != 0\|ret < 0\) || ...) { ... return ...; }
|
ret = 0
)
... when != ret = e1
*x = \(kmalloc\|kzalloc\|kcalloc\|devm_kzalloc\|ioremap\|ioremap_nocache\|devm_ioremap\|devm_ioremap_nocache\)(...);
... when != x = e2
    when != ret = e3
*if (x == NULL || ...)
{
  ... when != ret = e4
*  return ret;
}
// </smpl>

Signed-off-by: Julia Lawall <julia@diku.dk>

---
 drivers/atm/iphase.c |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/atm/iphase.c b/drivers/atm/iphase.c
index d438601..96cce6d 100644
--- a/drivers/atm/iphase.c
+++ b/drivers/atm/iphase.c
@@ -2362,7 +2362,7 @@ static int __devinit ia_init(struct atm_dev *dev)
 	{  
 		printk(DEV_LABEL " (itf %d): can't set up page mapping\n",  
 			    dev->number);  
-		return error;  
+		return -ENOMEM;
 	}  
 	IF_INIT(printk(DEV_LABEL " (itf %d): rev.%d,base=%p,irq=%d\n",  
 			dev->number, iadev->pci->revision, base, iadev->irq);)

^ permalink raw reply related

* Re: Huge performance degradation for UDP between 2.4.17 and 2.6
From: Eric Dumazet @ 2012-08-05  8:28 UTC (permalink / raw)
  To: LEROY christophe; +Cc: linux-kernel, netdev
In-Reply-To: <501E2BC5.5020709@c-s.fr>

On Sun, 2012-08-05 at 10:16 +0200, LEROY christophe wrote:
> Le 02/08/2012 16:13, Eric Dumazet a écrit :
> > On Thu, 2012-08-02 at 14:27 +0200, leroy christophe wrote:
> >> Hi
> >>
> >> I'm having a big issue with UDP. Using a powerpc board (MPC860).
> >>
> >> With our board running kernel 2.4.17, I'm able to send 160000 voice
> >> packets (UDP, 96 bytes per packet) in 11 seconds.
> >> With the same board running either Kernel 2.6.35.14 or Kernel 3.4.7, I
> >> need 55 seconds to send the same amount of packets.
> >>
> >>
> >> Is there anything to tune in order to get same output rate as with
> >> Kernel 2.4 ?
> > kernel size is probably too big for your old / slow cpu.
> >
> > Maybe you added too many features on your 3.4.7 kernel. (netfilter ?
> > SLUB debugging ...)
> >
> > Its hard to say, 2.4.17 had less features and was faster.
> >
> 
> Thanks for your answer.
> Yes I have netfilter as I need it. However, I tried without it and still 
> need about 37 seconds to send the 160000 packets I was sending in 11 
> seconds with 2.4.17
> 
> I don't think there is any problem with size of the kernel. I still have 
> plenty of memory available.
> 

I believe you misunderstood me.

I was referring to cpu caches ( dcache & icache )

> All debugging is turned off, and I'm not using SLUB but SLOB.
> I have 32Mbytes of RAM. Would SLUB be more performant than SLOB ?

I never used SLOB I cannot comment

Please provide (on 3.4.7)

cat /proc/cpuinfo
lsmod
dmesg

^ permalink raw reply

* Re: Bridge extensions to iproute2
From: Maciej Żenczykowski @ 2012-08-05  7:27 UTC (permalink / raw)
  To: Stephen Hemminger; +Cc: Stephen Hemminger, Linux NetDev, David Miller
In-Reply-To: <meqjoqmsb19c7jsv7pbldsjc.1344134703305@email.android.com>

Yes, there really isn't much reason for bridge configuration to be a
separate package than iproute, seeing how there's vlan/veth etc
configuration built into 'ip'

On Sat, Aug 4, 2012 at 7:45 PM, Stephen Hemminger
<stephen.hemminger@vyatta.com> wrote:
> There is barely any overlap between bridge-utils and iproute2.
> I was thinking of making a script 'brctl' that does same thing as
> old utility but using new netlink based commands.
>

^ permalink raw reply

* [PATCH net-next] net: reorganize IP MIB values
From: Eric Dumazet @ 2012-08-05  6:33 UTC (permalink / raw)
  To: David Miller; +Cc: netdev

From: Eric Dumazet <edumazet@google.com>

Reduce IP latencies by placing hot MIB IP fields in a single cache line.

Signed-off-by: Eric Dumazet <edumazet@google.com>
---
 include/linux/snmp.h |   12 +++++++-----
 1 file changed, 7 insertions(+), 5 deletions(-)

diff --git a/include/linux/snmp.h b/include/linux/snmp.h
index 00bc189..aa02b9e 100644
--- a/include/linux/snmp.h
+++ b/include/linux/snmp.h
@@ -18,7 +18,14 @@
 enum
 {
 	IPSTATS_MIB_NUM = 0,
+/* frequently written fields in fast path, kept in same cache line */
 	IPSTATS_MIB_INPKTS,			/* InReceives */
+	IPSTATS_MIB_INOCTETS,			/* InOctets */
+	IPSTATS_MIB_INDELIVERS,			/* InDelivers */
+	IPSTATS_MIB_OUTFORWDATAGRAMS,		/* OutForwDatagrams */
+	IPSTATS_MIB_OUTPKTS,			/* OutRequests */
+	IPSTATS_MIB_OUTOCTETS,			/* OutOctets */
+/* other fields */
 	IPSTATS_MIB_INHDRERRORS,		/* InHdrErrors */
 	IPSTATS_MIB_INTOOBIGERRORS,		/* InTooBigErrors */
 	IPSTATS_MIB_INNOROUTES,			/* InNoRoutes */
@@ -26,9 +33,6 @@ enum
 	IPSTATS_MIB_INUNKNOWNPROTOS,		/* InUnknownProtos */
 	IPSTATS_MIB_INTRUNCATEDPKTS,		/* InTruncatedPkts */
 	IPSTATS_MIB_INDISCARDS,			/* InDiscards */
-	IPSTATS_MIB_INDELIVERS,			/* InDelivers */
-	IPSTATS_MIB_OUTFORWDATAGRAMS,		/* OutForwDatagrams */
-	IPSTATS_MIB_OUTPKTS,			/* OutRequests */
 	IPSTATS_MIB_OUTDISCARDS,		/* OutDiscards */
 	IPSTATS_MIB_OUTNOROUTES,		/* OutNoRoutes */
 	IPSTATS_MIB_REASMTIMEOUT,		/* ReasmTimeout */
@@ -42,8 +46,6 @@ enum
 	IPSTATS_MIB_OUTMCASTPKTS,		/* OutMcastPkts */
 	IPSTATS_MIB_INBCASTPKTS,		/* InBcastPkts */
 	IPSTATS_MIB_OUTBCASTPKTS,		/* OutBcastPkts */
-	IPSTATS_MIB_INOCTETS,			/* InOctets */
-	IPSTATS_MIB_OUTOCTETS,			/* OutOctets */
 	IPSTATS_MIB_INMCASTOCTETS,		/* InMcastOctets */
 	IPSTATS_MIB_OUTMCASTOCTETS,		/* OutMcastOctets */
 	IPSTATS_MIB_INBCASTOCTETS,		/* InBcastOctets */

^ permalink raw reply related

* [PATCH] net: avoid reloads in SNMP_UPD_PO_STATS
From: Eric Dumazet @ 2012-08-05  6:26 UTC (permalink / raw)
  To: David Miller; +Cc: netdev

From: Eric Dumazet <edumazet@google.com>

Avoid two instructions to reload dev->nd_net->mib.ip_statistics pointer,
unsing a temp variable, in ip_rcv(), ip_output() paths for example.

Signed-off-by: Eric Dumazet <edumazet@google.com>
---
 include/net/snmp.h |   10 ++++++----
 1 file changed, 6 insertions(+), 4 deletions(-)

diff --git a/include/net/snmp.h b/include/net/snmp.h
index 0147b90..7159626 100644
--- a/include/net/snmp.h
+++ b/include/net/snmp.h
@@ -154,13 +154,15 @@ struct linux_xfrm_mib {
  */
 #define SNMP_UPD_PO_STATS(mib, basefield, addend)	\
 	do { \
-		this_cpu_inc(mib[0]->mibs[basefield##PKTS]);		\
-		this_cpu_add(mib[0]->mibs[basefield##OCTETS], addend);	\
+		__typeof__(*mib[0]->mibs) *ptr = mib[0]->mibs;	\
+		this_cpu_inc(ptr[basefield##PKTS]);		\
+		this_cpu_add(ptr[basefield##OCTETS], addend);	\
 	} while (0)
 #define SNMP_UPD_PO_STATS_BH(mib, basefield, addend)	\
 	do { \
-		__this_cpu_inc(mib[0]->mibs[basefield##PKTS]);		\
-		__this_cpu_add(mib[0]->mibs[basefield##OCTETS], addend);	\
+		__typeof__(*mib[0]->mibs) *ptr = mib[0]->mibs;	\
+		__this_cpu_inc(ptr[basefield##PKTS]);		\
+		__this_cpu_add(ptr[basefield##OCTETS], addend);	\
 	} while (0)
 
 

^ permalink raw reply related

* Re: Bridge extensions to iproute2
From: Stephen Hemminger @ 2012-08-05  2:45 UTC (permalink / raw)
  To: Maciej Żenczykowski; +Cc: Stephen Hemminger, Linux NetDev, David Miller

There is barely any overlap between bridge-utils and iproute2.
I was thinking of making a script 'brctl' that does same thing as
old utility but using new netlink based commands.


^ permalink raw reply

* Re: Bridge extensions to iproute2
From: Maciej Żenczykowski @ 2012-08-05  1:49 UTC (permalink / raw)
  To: Stephen Hemminger; +Cc: Linux NetDev, David Miller
In-Reply-To: <20120801170713.289e078e@nehalam.linuxnetplumber.net>

Thanks.  Would it make sense to merge bridge-utils / brctl into iproute2?

On Wed, Aug 1, 2012 at 5:07 PM, Stephen Hemminger <shemminger@vyatta.com> wrote:
> On Tue, 10 Jul 2012 15:01:26 -0700
> Maciej Żenczykowski <zenczykowski@gmail.com> wrote:
>
>> > I will get back to these. There wasn't a motivation to go fast because
>> > there wasn't a user of these. Now with fdb offload support they are needed.
>>
>> Do you have some semi-ready patches that could be used for test purposes?
>>
>> While it looks like the forwarding database capability is there in the kernel,
>> I can't currently find an interface to turn learning off.
>
> I cleaned it up an put in 3.5.0 just released version.

^ permalink raw reply

* [PATCH 02/13] SCTP: register protocol for namespace handling.
From: Jan Ariyasu @ 2012-08-05  1:26 UTC (permalink / raw)
  To: Vlad Yasevich, David S. Miller, linux-sctp, netdev, linux-kernel
  Cc: Jan Ariyasu

Add namespace-helper functions to access per-namespace parameters
and variables.  Create per-namespace control socket for out-of-the-
blue packets, initialize per-namespace protocol parameters, and
register SCTP protocol for namespace handling.

Signed-off-by: Jan Ariyasu <jan.ariyasu@hp.com>
---
 include/net/sctp/sctp.h |   31 ++++-
 net/sctp/input.c        |    4 +-
 net/sctp/protocol.c     |  292 +++++++++++++++++++++++++++++++++++------------
 net/sctp/sm_statefuns.c |   10 +-
 4 files changed, 256 insertions(+), 81 deletions(-)

diff --git a/include/net/sctp/sctp.h b/include/net/sctp/sctp.h
index ff49964..c2dfeea 100644
--- a/include/net/sctp/sctp.h
+++ b/include/net/sctp/sctp.h
@@ -70,6 +70,8 @@
 #include <linux/spinlock.h>
 #include <linux/jiffies.h>
 #include <linux/idr.h>
+#include <net/net_namespace.h>
+#include <net/netns/generic.h>
 
 #if IS_ENABLED(CONFIG_IPV6)
 #include <net/ipv6.h>
@@ -107,6 +109,9 @@
 #define SCTP_STATIC static
 #endif
 
+/* For namespace identification */
+extern int sctp_net_id;
+
 /*
  * Function declarations.
  */
@@ -114,7 +119,6 @@
 /*
  * sctp/protocol.c
  */
-extern struct sock *sctp_get_ctl_sock(void);
 extern int sctp_copy_local_addr_list(struct sctp_bind_addr *,
 				     sctp_scope_t, gfp_t gfp,
 				     int flags);
@@ -719,4 +723,29 @@ static inline struct dst_entry *sctp_transport_dst_check(struct sctp_transport *
 	return t->dst;
 }
 
+/* Namespace helper functions */
+static inline struct sctp_ns_globals *sctp_get_ns_globals(struct net *net)
+{
+	struct sctp_ns_globals *ns_globals =
+		(struct sctp_ns_globals *) net_generic(net, sctp_net_id);
+	return ns_globals;
+
+}
+
+/* Return the address of the control sock. */
+static inline struct sock **sctp_get_ctl_sock(struct net *net)
+{
+	struct sctp_ns_globals *ns_globals =
+		(struct sctp_ns_globals *) net_generic(net, sctp_net_id);
+	return &ns_globals->sctp_ctl_sock;
+}
+
+/* Return the address of the protocol globals. */
+static inline struct sctp_net_params *sctp_get_params(struct net *net)
+{
+	struct sctp_ns_globals *ns_globals =
+		(struct sctp_ns_globals *) net_generic(net, sctp_net_id);
+	return &ns_globals->protocol_params;
+}
+
 #endif /* __net_sctp_h__ */
diff --git a/net/sctp/input.c b/net/sctp/input.c
index e64d521..fc94829 100644
--- a/net/sctp/input.c
+++ b/net/sctp/input.c
@@ -200,7 +200,7 @@ int sctp_rcv(struct sk_buff *skb)
 			sctp_endpoint_put(ep);
 			ep = NULL;
 		}
-		sk = sctp_get_ctl_sock();
+		sk = *(sctp_get_ctl_sock(&init_net));
 		ep = sctp_sk(sk)->ep;
 		sctp_endpoint_hold(ep);
 		rcvr = &ep->base;
@@ -787,7 +787,7 @@ static struct sctp_endpoint *__sctp_rcv_lookup_endpoint(const union sctp_addr *l
 			goto hit;
 	}
 
-	ep = sctp_sk((sctp_get_ctl_sock()))->ep;
+	ep = sctp_sk(*(sctp_get_ctl_sock(&init_net)))->ep;
 
 hit:
 	sctp_endpoint_hold(ep);
diff --git a/net/sctp/protocol.c b/net/sctp/protocol.c
index cafdaac..5c1a18c 100644
--- a/net/sctp/protocol.c
+++ b/net/sctp/protocol.c
@@ -78,11 +78,11 @@ struct proc_dir_entry	*proc_net_sctp;
 struct idr sctp_assocs_id;
 DEFINE_SPINLOCK(sctp_assocs_id_lock);
 
-/* This is the global socket data structure used for responding to
- * the Out-of-the-blue (OOTB) packets.  A control sock will be created
- * for this socket at the initialization time.
+/*
+ * This id will allow us to access per-namespace globals in
+ * struct sctp_ns_globals, defined as net_generic in struct net.
  */
-static struct sock *sctp_ctl_sock;
+int sctp_net_id __read_mostly;
 
 static struct sctp_pf *sctp_pf_inet6_specific;
 static struct sctp_pf *sctp_pf_inet_specific;
@@ -96,32 +96,33 @@ long sysctl_sctp_mem[3];
 int sysctl_sctp_rmem[3];
 int sysctl_sctp_wmem[3];
 
-/* Return the address of the control sock. */
-struct sock *sctp_get_ctl_sock(void)
-{
-	return sctp_ctl_sock;
-}
-
 /* Set up the proc fs entry for the SCTP protocol. */
 static __init int sctp_proc_init(void)
 {
 #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)
-			goto out_nomem;
+		if (!proc_net_sctp) {
+			status = -ENOMEM;
+			goto out;
+		}
 	}
 
-	if (sctp_snmp_proc_init())
+	status = sctp_snmp_proc_init();
+	if (status)
 		goto out_snmp_proc_init;
-	if (sctp_eps_proc_init())
+	status = sctp_eps_proc_init();
+	if (status)
 		goto out_eps_proc_init;
-	if (sctp_assocs_proc_init())
+	status = sctp_assocs_proc_init();
+	if (status)
 		goto out_assocs_proc_init;
-	if (sctp_remaddr_proc_init())
+	status = sctp_remaddr_proc_init();
+	if (status)
 		goto out_remaddr_proc_init;
 
-	return 0;
+	return status;
 
 out_remaddr_proc_init:
 	sctp_assocs_proc_exit();
@@ -134,9 +135,8 @@ out_snmp_proc_init:
 		proc_net_sctp = NULL;
 		remove_proc_entry("sctp", init_net.proc_net);
 	}
-
-out_nomem:
-	return -ENOMEM;
+out:
+	return status;
 #else
 	return 0;
 #endif /* CONFIG_PROC_FS */
@@ -817,22 +817,23 @@ static int sctp_inetaddr_event(struct notifier_block *this, unsigned long ev,
  * Initialize the control inode/socket with a control endpoint data
  * structure.  This endpoint is reserved exclusively for the OOTB processing.
  */
-static int sctp_ctl_sock_init(void)
+static int sctp_ctl_sock_init(struct net *net)
 {
 	int err;
 	sa_family_t family = PF_INET;
+	struct sock **ctl_sock = sctp_get_ctl_sock(net);
 
 	if (sctp_get_pf_specific(PF_INET6))
 		family = PF_INET6;
 
-	err = inet_ctl_sock_create(&sctp_ctl_sock, family,
-				   SOCK_SEQPACKET, IPPROTO_SCTP, &init_net);
+	err = inet_ctl_sock_create(ctl_sock, family,
+				   SOCK_SEQPACKET, IPPROTO_SCTP, net);
 
 	/* If IPv6 socket could not be created, try the IPv4 socket */
 	if (err < 0 && family == PF_INET6)
-		err = inet_ctl_sock_create(&sctp_ctl_sock, AF_INET,
+		err = inet_ctl_sock_create(ctl_sock, AF_INET,
 					   SOCK_SEQPACKET, IPPROTO_SCTP,
-					   &init_net);
+					   net);
 
 	if (err < 0) {
 		pr_err("Failed to create the SCTP control socket\n");
@@ -841,6 +842,12 @@ static int sctp_ctl_sock_init(void)
 	return 0;
 }
 
+static inline void sctp_ctl_sock_destroy(struct net *net)
+{
+	struct sock **sctp_ctl_sk = sctp_get_ctl_sock(net);
+	inet_ctl_sock_destroy(*sctp_ctl_sk);
+}
+
 /* Register address family specific functions. */
 int sctp_register_af(struct sctp_af *af)
 {
@@ -1151,17 +1158,18 @@ static void sctp_v4_pf_exit(void)
 
 static int sctp_v4_protosw_init(void)
 {
-	int rc;
-
+	int rc = 0;
 	rc = proto_register(&sctp_prot, 1);
-	if (rc)
+	if (rc) {
+		pr_err("Failed to register SCTP protocol\n");
 		return rc;
+	}
 
 	/* Register SCTP(UDP and TCP style) with socket layer.  */
 	inet_register_protosw(&sctp_seqpacket_protosw);
 	inet_register_protosw(&sctp_stream_protosw);
 
-	return 0;
+	return rc;
 }
 
 static void sctp_v4_protosw_exit(void)
@@ -1219,8 +1227,8 @@ static void sctp_global_param_init(void)
 	 * 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_association		= 10;
+	sctp_max_retrans_path			= 5;
 	sctp_max_retrans_init			= 8;
 
 	/* Sendbuffer growth	- do per-socket accounting */
@@ -1238,8 +1246,8 @@ static void sctp_global_param_init(void)
 	/* 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;
@@ -1263,6 +1271,112 @@ 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);
+	struct sctp_ns_globals *ns_globals = sctp_get_ns_globals(net);
+	if ((net_params == NULL) || (ns_globals == NULL))
+		return -ENOMEM;
+
+	/* Initialize SCTP protocol parameters
+	 * 14. Suggested SCTP Protocol Parameter Values
+	 */
+	/* The following protocol parameters are RECOMMENDED:  */
+	/* RTO.Initial              - 3  seconds */
+	net_params->rto_initial			= SCTP_RTO_INITIAL;
+	/* RTO.Min                  - 1  second */
+	net_params->rto_min			= SCTP_RTO_MIN;
+	/* RTO.Max                 -  60 seconds */
+	net_params->rto_max			= SCTP_RTO_MAX;
+	/* RTO.Alpha                - 1/8 */
+	net_params->rto_alpha			= SCTP_RTO_ALPHA;
+	/* RTO.Beta                 - 1/4 */
+	net_params->rto_beta			= SCTP_RTO_BETA;
+
+	/* Max.Burst		    - 4 */
+	net_params->max_burst			= SCTP_DEFAULT_MAX_BURST;
+
+	/* Whether Cookie Preservative is enabled(1) or not(0) */
+	net_params->cookie_preserve_enable	= 1;
+
+	/* Valid.Cookie.Life        - 60  seconds */
+	net_params->valid_cookie_life		= SCTP_DEFAULT_COOKIE_LIFE;
+
+	/* delayed SACK timeout */
+	net_params->sack_timeout		= SCTP_DEFAULT_TIMEOUT_SACK;
+
+	/* HB.interval              - 30 seconds */
+	net_params->hb_interval		= SCTP_DEFAULT_TIMEOUT_HEARTBEAT;
+
+	/* Association.Max.Retrans  - 10 attempts
+	 * Path.Max.Retrans         - 5  attempts (per destination address)
+	 * Max.Init.Retransmits     - 8  attempts
+	 */
+	net_params->max_retrans_association	= 10;
+	net_params->max_retrans_path		= 5;
+	net_params->max_retrans_init		= 8;
+
+	/* Sendbuffer growth	    - do per-socket accounting */
+	net_params->sndbuf_policy			= 0;
+
+	/* Rcvbuffer growth	    - do per-socket accounting */
+	net_params->rcvbuf_policy			= 0;
+
+	/* Implementation specific variables. */
+
+	/* Initialize default stream count setup information. */
+	net_params->max_instreams		= SCTP_DEFAULT_INSTREAMS;
+	net_params->max_outstreams		= SCTP_DEFAULT_OUTSTREAMS;
+
+	/* hash of all endpoints */
+	net_params->ep_hashsize			= 64;
+	net_params->ep_hashtable		= NULL;
+
+	/* hash of all associations */
+	net_params->assoc_hashsize		= 0;
+	net_params->assoc_hashtable		= NULL;
+
+	/* port-control hash  */
+	net_params->port_hashsize		= 0;
+	net_params->port_hashtable		= NULL;
+
+	/* Initialize local address list */
+	INIT_LIST_HEAD(&net_params->local_addr_list);
+	spin_lock_init(&net_params->addr_list_lock);
+	idr_init(&ns_globals->assocs_id);
+	spin_lock_init(&ns_globals->assocs_id_lock);
+
+	/* Disable ADDIP by default. */
+	net_params->addip_enable		= 0;
+	net_params->addip_noauth_enable		= 0;
+	net_params->default_auto_asconf		= 0;
+
+	/* Set SCOPE policy to enabled */
+	net_params->ipv4_scope_policy		= SCTP_SCOPE_POLICY_ENABLE;
+
+	/* Set the default rwnd update threshold */
+	net_params->rwnd_update_shift		= SCTP_DEFAULT_RWND_SHIFT;
+
+	/* Enable PR-SCTP by default. */
+	net_params->prsctp_enable		= 1;
+
+	/* Disable AUTH by default. */
+	net_params->auth_enable			= 0;
+
+	/* Initialize maximum autoclose timeout. */
+	net_params->max_autoclose		=  INT_MAX / HZ;
+
+	/* Initialize address event list */
+	INIT_LIST_HEAD(&net_params->addr_waitq);
+	net_params->addr_wq_timer.expires	= 0;
+	INIT_LIST_HEAD(&net_params->auto_asconf_splist);
+	spin_lock_init(&net_params->addr_wq_lock);
+	setup_timer(&net_params->addr_wq_timer, sctp_addr_wq_timeout_handler,
+			(unsigned long)net);
+	return 0;
+}
+
 static void sctp_memory_globals_init(void)
 {
 	unsigned long limit;
@@ -1318,13 +1432,13 @@ static int sctp_hashtable_globals_init(void)
 				continue;
 		sctp_assoc_hashtable = (struct sctp_hashbucket *)
 			__get_free_pages(GFP_ATOMIC|__GFP_NOWARN|__GFP_ZERO,
-				order);
+					 order);
 	} while (!sctp_assoc_hashtable && (--order > 0));
 
 	if (!sctp_assoc_hashtable) {
 		pr_err("Failed association hash alloc\n");
 		status = -ENOMEM;
-		goto err_ahash_alloc;
+		goto out;
 	}
 	for (i = 0; i < sctp_assoc_hashsize; i++) {
 		rwlock_init(&sctp_assoc_hashtable[i].lock);
@@ -1377,8 +1491,6 @@ 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;
 }
@@ -1432,6 +1544,49 @@ static void sctp_kmem_cache_destroy(void)
 	kmem_cache_destroy(sctp_bucket_cachep);
 }
 
+/* namespace enablers for init */
+
+static int __net_init sctp_net_init(struct net *net)
+{
+	int err = 0;
+
+	/* Set up the control socket for OOTB packets */
+	err = sctp_ctl_sock_init(net);
+	if (err)
+		goto out;
+
+	err = sctp_net_param_init(net);
+	if (err)
+		goto err_param_init;
+
+err_param_init:
+	sctp_ctl_sock_destroy(net);
+out:
+	return err;
+}
+
+static void __net_exit sctp_net_exit(struct net *net)
+{
+	sctp_ctl_sock_destroy(net);
+}
+
+static __net_initdata struct pernet_operations sctp_sk_ops = {
+	.init = sctp_net_init,
+	.exit = sctp_net_exit,
+	.id   = &sctp_net_id,
+	.size = sizeof(struct sctp_ns_globals),
+};
+
+static int __net_init sctp_ns_init(void)
+{
+	return register_pernet_subsys(&sctp_sk_ops);
+}
+
+static void __net_exit sctp_ns_exit(void)
+{
+	unregister_pernet_subsys(&sctp_sk_ops);
+}
+
 /* Initialize the universe into something sensible.  */
 SCTP_STATIC __init int sctp_init(void)
 {
@@ -1452,26 +1607,11 @@ SCTP_STATIC __init int sctp_init(void)
 		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();
@@ -1498,22 +1638,32 @@ SCTP_STATIC __init int sctp_init(void)
 	if (status)
 		goto err_v6_protosw_init;
 
-	/* Initialize the control inode/socket for handling OOTB packets.  */
-	if ((status = sctp_ctl_sock_init())) {
-		pr_err("Failed to initialize the SCTP control sock\n");
-		goto err_ctl_sock_init;
-	}
-
 	status = sctp_v4_add_protocol();
 	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. */
+	/*
+	 * Register for pernet packet handling
+	 */
+	status = sctp_ns_init();
+	if (status) {
+		pr_err("Failed to register SCTP for namespaces\n");
+		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.  */
@@ -1526,26 +1676,23 @@ 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();
 err_v6_add_protocol:
 	sctp_v4_del_protocol();
 err_add_protocol:
-	inet_ctl_sock_destroy(sctp_ctl_sock);
-err_ctl_sock_init:
 	sctp_v6_protosw_exit();
 err_v6_protosw_init:
 	sctp_v4_protosw_exit();
 err_protosw_init:
 	sctp_free_local_addr_list();
-	sctp_v4_pf_exit();
 	sctp_v6_pf_exit();
-	sctp_sysctl_unregister();
+	sctp_v4_pf_exit();
 	sctp_hashtable_globals_free();
-	sctp_dbg_objcnt_exit();
-	sctp_proc_exit();
-err_init_proc:
-	cleanup_sctp_mibs();
-err_init_mibs:
 	percpu_counter_destroy(&sctp_sockets_allocated);
 err_percpu_counter_init:
 	sctp_kmem_cache_destroy();
@@ -1565,9 +1712,6 @@ SCTP_STATIC __exit void sctp_exit(void)
 	sctp_v4_del_protocol();
 	sctp_free_addr_wq();
 
-	/* Free the control endpoint.  */
-	inet_ctl_sock_destroy(sctp_ctl_sock);
-
 	/* Free protosw registrations */
 	sctp_v6_protosw_exit();
 	sctp_v4_protosw_exit();
@@ -1580,7 +1724,6 @@ SCTP_STATIC __exit void sctp_exit(void)
 	sctp_v4_pf_exit();
 
 	sctp_sysctl_unregister();
-
 	sctp_hashtable_globals_free();
 
 	sctp_dbg_objcnt_exit();
@@ -1588,6 +1731,9 @@ SCTP_STATIC __exit void sctp_exit(void)
 	percpu_counter_destroy(&sctp_sockets_allocated);
 	cleanup_sctp_mibs();
 
+	/* Unregister from namespaces */
+	sctp_ns_exit();
+
 	rcu_barrier(); /* Wait for completion of call_rcu()'s */
 	sctp_kmem_cache_destroy();
 }
diff --git a/net/sctp/sm_statefuns.c b/net/sctp/sm_statefuns.c
index 9fca103..91dcdd6 100644
--- a/net/sctp/sm_statefuns.c
+++ b/net/sctp/sm_statefuns.c
@@ -318,7 +318,7 @@ sctp_disposition_t sctp_sf_do_5_1B_init(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()))->ep) {
+	if (ep == sctp_sk((*(sctp_get_ctl_sock(&init_net))))->ep) {
 		SCTP_INC_STATS(SCTP_MIB_OUTOFBLUES);
 		return sctp_sf_tabort_8_4_8(ep, asoc, type, arg, commands);
 	}
@@ -650,7 +650,7 @@ 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()))->ep) {
+	if (ep == sctp_sk((*(sctp_get_ctl_sock(&init_net))))->ep) {
 		SCTP_INC_STATS(SCTP_MIB_OUTOFBLUES);
 		return sctp_sf_tabort_8_4_8(ep, asoc, type, arg, commands);
 	}
@@ -1197,7 +1197,7 @@ 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()))->ep;
+	ep = sctp_sk(*(sctp_get_ctl_sock(&init_net)))->ep;
 
 	/* Association is NULL since this may be a restart attack and we
 	 * want to send back the attacker's vtag.
@@ -1653,7 +1653,7 @@ 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()))->ep)
+	if (ep == sctp_sk(*(sctp_get_ctl_sock(&init_net)))->ep)
 		return sctp_sf_ootb(ep, asoc, type, arg, commands);
 	else
 		return sctp_sf_discard_chunk(ep, asoc, type, arg, commands);
@@ -5919,7 +5919,7 @@ static struct sctp_packet *sctp_ootb_pkt_new(const struct sctp_association *asoc
 	 * the source address.
 	 */
 	sctp_transport_route(transport, (union sctp_addr *)&chunk->dest,
-			     sctp_sk(sctp_get_ctl_sock()));
+			     sctp_sk(*sctp_get_ctl_sock(&init_net)));
 
 	packet = sctp_packet_init(&transport->packet, transport, sport, dport);
 	packet = sctp_packet_config(packet, vtag, 0);
-- 
1.7.9.5

^ permalink raw reply related

* Re: [RFC v2 2/7] user_ns: use new hashtable implementation
From: Eric W. Biederman @ 2012-08-05  0:58 UTC (permalink / raw)
  To: Sasha Levin
  Cc: torvalds, tj, akpm, linux-kernel, linux-mm, paul.gortmaker, davem,
	rostedt, mingo, aarcange, ericvh, netdev
In-Reply-To: <1344003788-1417-3-git-send-email-levinsasha928@gmail.com>

Sasha Levin <levinsasha928@gmail.com> writes:

> Switch user_ns to use the new hashtable implementation. This reduces the amount of
> generic unrelated code in user_ns.


Just looking at this ick.

- Your comparison function is broken.
- The naming is awkward.
    hash_get without a reference count being  incremented?
- The magic is deep.
   hash_get is named like a function but takes a piece of code to call
   like only a macro can.
- uid_hash_find always bumped the reference count
  but your uidhash_entry doesn't nor do all of the callers of
  uidhash_entry bump the reference count.

Nacked-by: "Eric W. Biederman" <ebiederm@xmission.com>

I don't have the time for a new improved better hash table that makes
the code buggier.

Eric


> Signed-off-by: Sasha Levin <levinsasha928@gmail.com>
> ---
>  kernel/user.c |   53 ++++++++++++++++++-----------------------------------
>  1 files changed, 18 insertions(+), 35 deletions(-)
>
> diff --git a/kernel/user.c b/kernel/user.c
> index b815fef..555c71a 100644
> --- a/kernel/user.c
> +++ b/kernel/user.c
> @@ -16,6 +16,7 @@
>  #include <linux/interrupt.h>
>  #include <linux/export.h>
>  #include <linux/user_namespace.h>
> +#include <linux/hashtable.h>
>  
>  /*
>   * userns count is 1 for root user, 1 for init_uts_ns,
> @@ -50,15 +51,14 @@ EXPORT_SYMBOL_GPL(init_user_ns);
>   * UID task count cache, to get fast user lookup in "alloc_uid"
>   * when changing user ID's (ie setuid() and friends).
>   */
> -
> -#define UIDHASH_BITS	(CONFIG_BASE_SMALL ? 3 : 7)
> -#define UIDHASH_SZ	(1 << UIDHASH_BITS)
> -#define UIDHASH_MASK		(UIDHASH_SZ - 1)
> -#define __uidhashfn(uid)	(((uid >> UIDHASH_BITS) + uid) & UIDHASH_MASK)
> -#define uidhashentry(uid)	(uidhash_table + __uidhashfn((__kuid_val(uid))))
> +#define UIDHASH_BITS		(CONFIG_BASE_SMALL ? 3 : 7)
> +#define UIDHASH_CMP(obj, key) 	((obj)->uid == (key))
> +#define uidhash_entry(key)	(hash_get(&uidhash_table, key,		\
> +				struct user_struct, uidhash_node,	\
> +				UIDHASH_CMP))
>  
>  static struct kmem_cache *uid_cachep;
> -struct hlist_head uidhash_table[UIDHASH_SZ];
> +DEFINE_STATIC_HASHTABLE(uidhash_table, UIDHASH_BITS);
>  
>  /*
>   * The uidhash_lock is mostly taken from process context, but it is
> @@ -84,29 +84,14 @@ struct user_struct root_user = {
>  /*
>   * These routines must be called with the uidhash spinlock held!
>   */
> -static void uid_hash_insert(struct user_struct *up, struct hlist_head *hashent)
> +static void uid_hash_insert(struct user_struct *up)
>  {
> -	hlist_add_head(&up->uidhash_node, hashent);
> +	hash_add(&uidhash_table, &up->uidhash_node, up->uid);
>  }
>  
>  static void uid_hash_remove(struct user_struct *up)
>  {
> -	hlist_del_init(&up->uidhash_node);
> -}
> -
> -static struct user_struct *uid_hash_find(kuid_t uid, struct hlist_head *hashent)
> -{
> -	struct user_struct *user;
> -	struct hlist_node *h;
> -
> -	hlist_for_each_entry(user, h, hashent, uidhash_node) {
> -		if (uid_eq(user->uid, uid)) {
> -			atomic_inc(&user->__count);
> -			return user;
> -		}
> -	}
> -
> -	return NULL;
> +	hash_del(&up->uidhash_node);
>  }
>  
>  /* IRQs are disabled and uidhash_lock is held upon function entry.
> @@ -135,7 +120,9 @@ struct user_struct *find_user(kuid_t uid)
>  	unsigned long flags;
>  
>  	spin_lock_irqsave(&uidhash_lock, flags);
> -	ret = uid_hash_find(uid, uidhashentry(uid));
> +	ret = uidhash_entry(uid);
> +	if (ret)
> +		atomic_inc(&ret->__count);
>  	spin_unlock_irqrestore(&uidhash_lock, flags);
>  	return ret;
>  }
> @@ -156,11 +143,10 @@ void free_uid(struct user_struct *up)
>  
>  struct user_struct *alloc_uid(kuid_t uid)
>  {
> -	struct hlist_head *hashent = uidhashentry(uid);
>  	struct user_struct *up, *new;
>  
>  	spin_lock_irq(&uidhash_lock);
> -	up = uid_hash_find(uid, hashent);
> +	up = uidhash_entry(uid);
>  	spin_unlock_irq(&uidhash_lock);
>  
>  	if (!up) {
> @@ -176,13 +162,13 @@ struct user_struct *alloc_uid(kuid_t uid)
>  		 * on adding the same user already..
>  		 */
>  		spin_lock_irq(&uidhash_lock);
> -		up = uid_hash_find(uid, hashent);
> +		up = uidhash_entry(uid);
>  		if (up) {
>  			key_put(new->uid_keyring);
>  			key_put(new->session_keyring);
>  			kmem_cache_free(uid_cachep, new);
>  		} else {
> -			uid_hash_insert(new, hashent);
> +			uid_hash_insert(new);
>  			up = new;
>  		}
>  		spin_unlock_irq(&uidhash_lock);
> @@ -196,17 +182,14 @@ out_unlock:
>  
>  static int __init uid_cache_init(void)
>  {
> -	int n;
> -
>  	uid_cachep = kmem_cache_create("uid_cache", sizeof(struct user_struct),
>  			0, SLAB_HWCACHE_ALIGN|SLAB_PANIC, NULL);
>  
> -	for(n = 0; n < UIDHASH_SZ; ++n)
> -		INIT_HLIST_HEAD(uidhash_table + n);
> +	hash_init(&uidhash_table, UIDHASH_BITS);
>  
>  	/* Insert the root user immediately (init already runs as root) */
>  	spin_lock_irq(&uidhash_lock);
> -	uid_hash_insert(&root_user, uidhashentry(GLOBAL_ROOT_UID));
> +	uid_hash_insert(&root_user);
>  	spin_unlock_irq(&uidhash_lock);
>  
>  	return 0;

--
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: [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


This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox