The Linux Kernel Mailing List
 help / color / mirror / Atom feed
* [PATCH] enhance usability of /proc/sys/net/ipv4/ip_local_reserved_ports
@ 2012-03-10 23:36 Helge Deller
  2012-03-11 22:55 ` David Miller
  2012-03-12  3:42 ` Cong Wang
  0 siblings, 2 replies; 4+ messages in thread
From: Helge Deller @ 2012-03-10 23:36 UTC (permalink / raw)
  To: Octavian Purdila, WANG Cong, Linux Kernel Development,
	Andrew Morton, Eric W. Biederman, Frank Danapfel, Laszlo Ersek,
	Linus

When writing to the ip_local_reserved_ports proc file it will currently clear
all previously reserved ports and update the current list with the one given 
in the input.

This behaviour makes it's usage quite hard, for example:
a) The generic proc filesystem limitation of only handle up to PAGE_SIZE-1
   characters at maximum may not be sufficient to provide all your wished-to-
   be-reserved ports at once.
b) There is no easy way to disable specific given ports, you always need to
   give the full port list at once. This makes shell scripting hard, since
   you need to parse everything yourself.
c) There is no easy way to just add specific ports or port ranges. Again,
   this would be useful for shell scripts.

The following patch solves this problem by simply extending the parser
in proc_do_large_bitmap() to accept the keywords "add" and "release" in front
of given ports or port ranges and to either add or drop the given ports
from the already existing list.

Here is an example:
$ echo "1000-2000,5000" > /proc/sys/net/ipv4/ip_local_reserved_ports
$ cat /proc/sys/net/ipv4/ip_local_reserved_ports
1000-2000,5000   (works as before, current port list is replaced by new one)

$ echo "add 3000-4000" > /proc/sys/net/ipv4/ip_local_reserved_ports
$ cat /proc/sys/net/ipv4/ip_local_reserved_ports
1000-2000,3000-4000,5000   (new ports added)

$ echo "release 1500-3500" > /proc/sys/net/ipv4/ip_local_reserved_ports
$ cat /proc/sys/net/ipv4/ip_local_reserved_ports
1000-1499,3501-4000,5000   (given ports were dropped from the list)

My main motivation for this patch is a huge commercial application which
by default may use lots of ports. The full port list which I would have needed
to echo to the /proc/sys/net/ipv4/ip_local_reserved_ports file was around
30K, and in this case all ports were already combined to regions where possible.
With this patch it's now easy to split up the port ranges into single pieces
and to implement everything in simple bootup shell scripts. Furthermore
adding new or removing unneeded ports dynamically at runtime is now easily
possible.


Signed-off-by: Helge Deller <deller@gmx.de>


 Documentation/networking/ip-sysctl.txt |   10 ++++++
 kernel/sysctl.c                        |   48 +++++++++++++++++++++++++++------
 2 files changed, 49 insertions(+), 9 deletions(-)



diff --git a/Documentation/networking/ip-sysctl.txt b/Documentation/networking/ip-sysctl.txt
index ad3e80e..2ca93ab 100644
--- a/Documentation/networking/ip-sysctl.txt
+++ b/Documentation/networking/ip-sysctl.txt
@@ -624,7 +624,15 @@ ip_local_reserved_ports - list of comma separated ranges
 	list of ranges (e.g. "1,2-4,10-10" for ports 1, 2, 3, 4 and
 	10). Writing to the file will clear all previously reserved
 	ports and update the current list with the one given in the
-	input.
+	input. When writing to the file the keywords "add" or "release"
+	may be used to add or release the given ports or port ranges
+	to/from the already existing port list.
+	Example:
+	$ echo "1000-2000" > /proc/sys/net/ipv4/ip_local_reserved_ports
+	$ echo "add 3000-4000,5000" > /proc/sys/net/ipv4/ip_local_reserved_ports
+	$ echo "release 1500-3500" > /proc/sys/net/ipv4/ip_local_reserved_ports
+	$ cat /proc/sys/net/ipv4/ip_local_reserved_ports
+	1000-1499,3501-4000,5000
 
 	Note that ip_local_port_range and ip_local_reserved_ports
 	settings are independent and both are considered by the kernel
diff --git a/kernel/sysctl.c b/kernel/sysctl.c
index f487f25..241fc5a 100644
--- a/kernel/sysctl.c
+++ b/kernel/sysctl.c
@@ -2805,6 +2805,8 @@ static int proc_do_cad_pid(struct ctl_table *table, int write,
  * We use a range comma separated format (e.g. 1,3-4,10-10) so that
  * large bitmaps may be represented in a compact manner. Writing into
  * the file will clear the bitmap then update it with the given input.
+ * If "add" or "release" is written in front of numbers or number ranges,
+ * the given bits will be added to or released from the existing bitmap.
  *
  * Returns 0 on success.
  */
@@ -2813,11 +2815,13 @@ int proc_do_large_bitmap(struct ctl_table *table, int write,
 {
 	int err = 0;
 	bool first = 1;
+	bool add_or_release = 0, xadd = 0, xrelease = 0;
 	size_t left = *lenp;
 	unsigned long bitmap_len = table->maxlen;
 	unsigned long *bitmap = (unsigned long *) table->data;
-	unsigned long *tmp_bitmap = NULL;
-	char tr_a[] = { '-', ',', '\n' }, tr_b[] = { ',', '\n', 0 }, c;
+	unsigned long *tmp_bitmap = NULL, *release_bitmap = NULL;
+	char tr_a[] = { '-', ',', ' ', '\n' },
+	     tr_b[] = { ',', ' ', '\n', 0 }, c;
 
 	if (!bitmap_len || !left || (*ppos && !write)) {
 		*lenp = 0;
@@ -2841,8 +2845,9 @@ int proc_do_large_bitmap(struct ctl_table *table, int write,
                 }
 		kbuf[left] = 0;
 
-		tmp_bitmap = kzalloc(BITS_TO_LONGS(bitmap_len) * sizeof(unsigned long),
-				     GFP_KERNEL);
+		tmp_bitmap = kzalloc(2 * BITS_TO_LONGS(bitmap_len) *
+					sizeof(unsigned long), GFP_KERNEL);
+		release_bitmap = &tmp_bitmap[BITS_TO_LONGS(bitmap_len)];
 		if (!tmp_bitmap) {
 			free_page(page);
 			return -ENOMEM;
@@ -2850,7 +2855,30 @@ int proc_do_large_bitmap(struct ctl_table *table, int write,
 		proc_skip_char(&kbuf, &left, '\n');
 		while (!err && left) {
 			unsigned long val_a, val_b;
-			bool neg;
+			bool neg, found;
+
+			left -= proc_skip_spaces(&kbuf);
+			if (!left)
+				continue;
+
+			found = (0 == strnicmp(kbuf, "add ", 4));
+			if (found) {
+				xadd = 1; xrelease = 0;
+				add_or_release = 1;
+				kbuf += 4;
+				left -= 4;
+			}
+			found = (0 == strnicmp(kbuf, "release ", 8));
+			if (found) {
+				xadd = 0; xrelease = 1;
+				add_or_release = 1;
+				kbuf += 8;
+				left -= 8;
+			}
+
+			left -= proc_skip_spaces(&kbuf);
+			if (!left)
+				continue;
 
 			err = proc_get_long(&kbuf, &left, &val_a, &neg, tr_a,
 					     sizeof(tr_a), &c);
@@ -2885,7 +2913,10 @@ int proc_do_large_bitmap(struct ctl_table *table, int write,
 			}
 
 			while (val_a <= val_b)
-				set_bit(val_a++, tmp_bitmap);
+				if (xrelease)
+					set_bit(val_a++, release_bitmap);
+				else
+					set_bit(val_a++, tmp_bitmap);
 
 			first = 0;
 			proc_skip_char(&kbuf, &left, '\n');
@@ -2926,9 +2957,10 @@ int proc_do_large_bitmap(struct ctl_table *table, int write,
 
 	if (!err) {
 		if (write) {
-			if (*ppos)
+			if (*ppos || add_or_release) {
 				bitmap_or(bitmap, bitmap, tmp_bitmap, bitmap_len);
-			else
+				bitmap_andnot(bitmap, bitmap, release_bitmap, bitmap_len);
+			} else
 				memcpy(bitmap, tmp_bitmap,
 					BITS_TO_LONGS(bitmap_len) * sizeof(unsigned long));
 		}

^ permalink raw reply related	[flat|nested] 4+ messages in thread

* Re: [PATCH] enhance usability of /proc/sys/net/ipv4/ip_local_reserved_ports
  2012-03-10 23:36 [PATCH] enhance usability of /proc/sys/net/ipv4/ip_local_reserved_ports Helge Deller
@ 2012-03-11 22:55 ` David Miller
  2012-03-12  3:42 ` Cong Wang
  1 sibling, 0 replies; 4+ messages in thread
From: David Miller @ 2012-03-11 22:55 UTC (permalink / raw)
  To: deller
  Cc: opurdila, amwang, linux-kernel, akpm, ebiederm, fdanapfe, lersek,
	torvalds


Networking patches should be submitted to netdev@vger.kernel.org, most
of the networking developers don't even read linux-kernel


^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [PATCH] enhance usability of /proc/sys/net/ipv4/ip_local_reserved_ports
  2012-03-10 23:36 [PATCH] enhance usability of /proc/sys/net/ipv4/ip_local_reserved_ports Helge Deller
  2012-03-11 22:55 ` David Miller
@ 2012-03-12  3:42 ` Cong Wang
  2012-03-12 21:09   ` Helge Deller
  1 sibling, 1 reply; 4+ messages in thread
From: Cong Wang @ 2012-03-12  3:42 UTC (permalink / raw)
  To: Helge Deller
  Cc: Octavian Purdila, Linux Kernel Development, Andrew Morton,
	Eric W. Biederman, Frank Danapfel, Laszlo Ersek, Linus

Hello, Helge,

On Sun, 2012-03-11 at 00:36 +0100, Helge Deller wrote:
> When writing to the ip_local_reserved_ports proc file it will currently clear
> all previously reserved ports and update the current list with the one given 
> in the input.
> 
> This behaviour makes it's usage quite hard, for example:
> a) The generic proc filesystem limitation of only handle up to PAGE_SIZE-1
>    characters at maximum may not be sufficient to provide all your wished-to-
>    be-reserved ports at once.

Yes, this should be extended IMHO.

> b) There is no easy way to disable specific given ports, you always need to
>    give the full port list at once. This makes shell scripting hard, since
>    you need to parse everything yourself.
> c) There is no easy way to just add specific ports or port ranges. Again,
>    this would be useful for shell scripts.
> 

These could be calculated in user-space, although it maybe not as easy
as you want.

> The following patch solves this problem by simply extending the parser
> in proc_do_large_bitmap() to accept the keywords "add" and "release" in front
> of given ports or port ranges and to either add or drop the given ports
> from the already existing list.

This looks a little odd, because we do "magic" things with a sysctl
file, which is supposed to be plain text file. Do we have existing
examples?

BTW, as David mentioned, please Cc netdev next time.

Thanks.


^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [PATCH] enhance usability of /proc/sys/net/ipv4/ip_local_reserved_ports
  2012-03-12  3:42 ` Cong Wang
@ 2012-03-12 21:09   ` Helge Deller
  0 siblings, 0 replies; 4+ messages in thread
From: Helge Deller @ 2012-03-12 21:09 UTC (permalink / raw)
  To: Cong Wang
  Cc: Octavian Purdila, Linux Kernel Development, Andrew Morton,
	Eric W. Biederman, Frank Danapfel, Laszlo Ersek, Linus

On 03/12/2012 04:42 AM, Cong Wang wrote:
> On Sun, 2012-03-11 at 00:36 +0100, Helge Deller wrote:
>> When writing to the ip_local_reserved_ports proc file it will currently clear
>> all previously reserved ports and update the current list with the one given
>> in the input.
>>
>> This behaviour makes it's usage quite hard, for example:
>> a) The generic proc filesystem limitation of only handle up to PAGE_SIZE-1
>>     characters at maximum may not be sufficient to provide all your wished-to-
>>     be-reserved ports at once.
>
> Yes, this should be extended IMHO.

Yes, known problem and not easy to fix.

>> b) There is no easy way to disable specific given ports, you always need to
>>     give the full port list at once. This makes shell scripting hard, since
>>     you need to parse everything yourself.
>> c) There is no easy way to just add specific ports or port ranges. Again,
>>     this would be useful for shell scripts.
>>
>
> These could be calculated in user-space, although it maybe not as easy
> as you want.

Right.

>> The following patch solves this problem by simply extending the parser
>> in proc_do_large_bitmap() to accept the keywords "add" and "release" in front
>> of given ports or port ranges and to either add or drop the given ports
>> from the already existing list.
>
> This looks a little odd, because we do "magic" things with a sysctl
> file, which is supposed to be plain text file. Do we have existing
> examples?

I don't think the networking sysctl has such tunables.
Overall, ip_local_reserved_ports is the only user of the
large_bitmap function and as such you can't compare the
input/output of this file with other sysctl files which
operate on a limited number of integers/booleans/strings only.
Furthermore my patch does not remove the "plain text"
behaviour of this file. You can still echo plain ports or
port lists into it and a "cat" gives you the same output
as before. It just extends the interface to add/remove
ports more easily if you want.

One somewhat comparable proc file which comes to my mind in this
regard is /proc/scsi/scsi where you can echo commands like
"scsi report-devs 1" and which then reacts. A user of this
interface is e.g. the known rescan-scsi-bus shell script:
http://www.garloff.de/kurt/linux/rescan-scsi-bus.sh-1.25

> BTW, as David mentioned, please Cc netdev next time.

Sure. I'll send an updated patch tomorrow and will CC netdev.

Thanks,
Helge

^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2012-03-12 21:09 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2012-03-10 23:36 [PATCH] enhance usability of /proc/sys/net/ipv4/ip_local_reserved_ports Helge Deller
2012-03-11 22:55 ` David Miller
2012-03-12  3:42 ` Cong Wang
2012-03-12 21:09   ` Helge Deller

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