Re: [RFC Patch] net: reserve ports for applications using fixed port numbers

2010-02-08 Thread Octavian Purdila
On Monday 08 February 2010 05:21:50 you wrote:
> Octavian Purdila wrote:
> > On Friday 05 February 2010 06:45:38 you wrote:
> >> Again, using bitmap algorithm is not a problem and it's better, the
> >> problem is sysctl interface, how would you plan to interact with users
> >> via sysctl/proc if you use bitmap to handle this? I would like to hear
> >> more details about this.
> >
> > We could use something like positive values for setting and negative for
> > reset (e.g. 3 would set the port in the bitmap and -3 would reset it).
> 
> Hmm, then how do you output the info of those ports? Arrays of bitmaps?
> 

See the patch bellow (work in progress).

BTW, while working on it I added some helpers, which we can use to rewrite the 
proc_doint/long stuff. I think it will help with readability and eliminates 
some code duplication as well. What do you guys think about that?

--- linux_2.6.32/main/src/kernel/sysctl.c
+++ linux_2.6.32/main/src/kernel/sysctl.c
@@ -250,6 +250,11 @@
 static int max_wakeup_granularity_ns = NSEC_PER_SEC;   /* 1 second */
 #endif
 
+static unsigned long test_bitmap[65535/sizeof(long)];
+static int proc_dobitmap(struct ctl_table *table, int write,
+void __user *buf, size_t *lenp, loff_t *ppos);
+
+
 static struct ctl_table kern_table[] = {
{
.ctl_name   = CTL_UNNUMBERED,
@@ -1032,6 +1037,15 @@
.proc_handler   = &proc_dointvec,
},
 #endif
+   {
+   .ctl_name   = CTL_UNNUMBERED,
+   .procname   = "bitmap_test",
+   .data   = &test_bitmap,
+   .maxlen = 65535,
+   .mode   = 0644,
+   .proc_handler   = &proc_dobitmap,
+   },
+   
 /*
  * NOTE: do not add new entries to this table unless you have read
  * Documentation/sysctl/ctl_unnumbered.txt
@@ -2902,6 +2916,194 @@
return 0;
 }
 
+static int proc_skip_wspace(char __user **buf, size_t *size)
+{
+   char c;
+
+   while (*size) {
+   if (get_user(c, *buf))
+   return -EFAULT;
+   if (!isspace(c))
+   break;
+   *size--; *buf++;
+   }
+
+   return 0;
+}
+
+static inline int _proc_get_ulong(char __user **buf, size_t *size, 
+ unsigned long *val, bool *neg)
+{
+#define TMPBUFLEN 21
+   int len = *size;
+   char *p, tmp[TMPBUFLEN];
+
+   if (len > TMPBUFLEN-1)
+   len = TMPBUFLEN-1;
+
+   if (copy_from_user(tmp, *buf, len))
+   return -EFAULT;
+
+   tmp[len] = 0;
+   p = tmp;
+   if (*p == '-' && *size > 1) {
+   *neg = 1;
+   p++;
+   }
+   if (*p < '0' || *p > '9')
+   return -EINVAL;
+
+   *val = simple_strtoul(p, &p, 0);
+
+   len = p - tmp;
+   if ((len < *size) && *p && !isspace(*p))
+   return -EINVAL;
+
+   *buf += len; *size -= len;
+
+   return 0;
+#undef TMPBUFLEN
+}
+
+static int proc_get_long(char __user **buf, size_t *size, long *val)
+{
+   int err;
+   bool neg;
+   unsigned long uval;
+
+   err = _proc_get_ulong(buf, size, &uval, &neg);
+   if (err)
+   return err;
+
+   if (neg)
+   *val = -uval;
+   else
+   *val = uval;
+
+   return 0;
+}
+
+static int proc_get_ulong(char __user **buf, size_t *size, unsigned long *val)
+{
+   int err;
+   bool neg;
+
+   err = _proc_get_ulong(buf, size, val, &neg);
+   if (err)
+   return err;
+   if (neg)
+   return -EINVAL;
+
+   return 0;
+}
+
+static int proc_put_ulong(char __user **buf, size_t *size, unsigned long val,
+ bool first)
+{
+#define TMPBUFLEN 21
+   int len;
+   char tmp[TMPBUFLEN], *p = tmp;
+
+   if (!first)
+   *p++ = '\t';
+   sprintf(p, "%lu", val);
+   len = strlen(tmp);
+   if (len > *size)
+   len = *size;
+   if (copy_to_user(*buf, tmp, len))
+   return -EFAULT;
+   *size -= len;
+   *buf += len;
+   return 0;
+#undef TMPBUFLEN
+}
+
+static int proc_put_newline(char __user **buf, size_t *size)
+{
+   if (*size) {
+   if (put_user('\n', *buf))
+   return -EFAULT;
+   *size--, *buf++;
+   }
+   return 0;
+}
+
+static int proc_dobitmap(struct ctl_table *table, int write,
+void __user *buf, size_t *lenp, loff_t *ppos)
+{
+   bool first = 1;
+   unsigned long *bitmap = (unsigned long *) table->data;
+   unsigned long bitmap_len = table->maxlen;
+   int left = *lenp, err = 0;
+   char __user *buffer = (char __user *) buf;
+
+   if (!bitmap_len || !left || (*ppos && !write)) {
+   *lenp = 0;
+   return 0;
+   }
+
+   if (write) {
+   while (left) {
+   lo

Re: [RFC Patch] net: reserve ports for applications using fixed port numbers

2010-02-07 Thread Cong Wang

Octavian Purdila wrote:

On Friday 05 February 2010 06:45:38 you wrote:


Again, using bitmap algorithm is not a problem and it's better, the
problem is sysctl interface, how would you plan to interact with users
via sysctl/proc if you use bitmap to handle this? I would like to hear
more details about this.



We could use something like positive values for setting and negative for reset 
(e.g. 3 would set the port in the bitmap and -3 would reset it).



Hmm, then how do you output the info of those ports? Arrays of bitmaps?



But we would need new sysctl and proc handlers to handle the bitmap case (e.g. 
sysctl_bitmap, proc_dobitmap_minmax).


Maybe.

Thanks.
--
To unsubscribe from this list: send the line "unsubscribe linux-rdma" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [RFC Patch] net: reserve ports for applications using fixed port numbers

2010-02-05 Thread Octavian Purdila
On Friday 05 February 2010 08:01:43 you wrote:

> >> If you can accept his version, I want to use his version (with an
> >> interface for updating above "reserved_ports" by not only root user's
> >> sysctl() but also MAC's policy configuration).
> >
> > I think that simply using an interface to update the reserved_ports from
> > MAC policy configuration module wouldn't work, as root will be able to
> > modify the policy via sysctl.
> >
> > I think that we might need to:
> >
> > a) have a reserved_port updater
> >
> > b) put a LSM hook into that
> >
> > c) use the reserved_port updater from sysctl
> 
> Ideally, you'd provide an interface for port allocator to use, so
> doing port reservation will be easier.
> 

If I understand the TOMOYO requirements correctly, we need a way to restrict a 
user action based on some security policy (in this case the ability to clear 
reserved ports). Traditionally that has been done with LSM hooks, so I think 
that approach is preferable.
--
To unsubscribe from this list: send the line "unsubscribe linux-rdma" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [RFC Patch] net: reserve ports for applications using fixed port numbers

2010-02-05 Thread Octavian Purdila
On Friday 05 February 2010 06:45:38 you wrote:

> Again, using bitmap algorithm is not a problem and it's better, the
> problem is sysctl interface, how would you plan to interact with users
> via sysctl/proc if you use bitmap to handle this? I would like to hear
> more details about this.
> 

We could use something like positive values for setting and negative for reset 
(e.g. 3 would set the port in the bitmap and -3 would reset it).

But we would need new sysctl and proc handlers to handle the bitmap case (e.g. 
sysctl_bitmap, proc_dobitmap_minmax).
--
To unsubscribe from this list: send the line "unsubscribe linux-rdma" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [RFC Patch] net: reserve ports for applications using fixed port numbers

2010-02-04 Thread Cong Wang

Bart Van Assche wrote:

On Wed, Feb 3, 2010 at 5:30 AM, Amerigo Wang  wrote:

This patch introduces /proc/sys/net/ipv4/ip_local_reserved_ports,
it can be used like ip_local_port_range, but this is used to
reserve ports for third-party applications which use fixed
port numbers within ip_local_port_range.

This only affects the applications which call socket functions
like bind(2) with port number 0, to prevent the kernel getting the ports
within the specified range for them. For applications which use fixed
port number, it will have no effects.

Any comments are welcome.


Relying on fixed port numbers is generally considered as a shortcoming
in the application. It would be helpful if you could explain more in
detail why port number reservation is necessary. Maybe there exists
another solution that does not require modifying the bind() system
call.



The problem is that there are some existing applications which use
fixed port number, we don't have chances to change this for them,
thus making them working is desired, so they want to reserve these
port for those applications.

For example, if I have an appliction which uses port 4, but
before this application starts, another application gets this port
number by bind() with port 0 (i.e. chosen by kernel), in this case,
that application will fail to start. Again, we don't have any chance
to change the source code of that application.

Hope this can make the problem clear.

Thanks.

--
To unsubscribe from this list: send the line "unsubscribe linux-rdma" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [RFC Patch] net: reserve ports for applications using fixed port numbers

2010-02-04 Thread Bart Van Assche
On Wed, Feb 3, 2010 at 5:30 AM, Amerigo Wang  wrote:
>
> This patch introduces /proc/sys/net/ipv4/ip_local_reserved_ports,
> it can be used like ip_local_port_range, but this is used to
> reserve ports for third-party applications which use fixed
> port numbers within ip_local_port_range.
>
> This only affects the applications which call socket functions
> like bind(2) with port number 0, to prevent the kernel getting the ports
> within the specified range for them. For applications which use fixed
> port number, it will have no effects.
>
> Any comments are welcome.

Relying on fixed port numbers is generally considered as a shortcoming
in the application. It would be helpful if you could explain more in
detail why port number reservation is necessary. Maybe there exists
another solution that does not require modifying the bind() system
call.

A quote from the UNIX socket FAQ (http://www.faqs.org/faqs/unix-faq/socket/):

  4.10.  How should I choose a port number for my server?

  The list of registered port assignments can be found in STD 2 or RFC
  1700.  Choose one that isn't already registered, and isn't in
  /etc/services on your system.  It is also a good idea to let users
  customize the port number in case of conflicts with other un-
  registered port numbers in other servers.  The best way of doing this
  is hardcoding a service name, and using getservbyname() to lookup the
  actual port number.  This method allows users to change the port your
  server binds to by simply editing the /etc/services file.

Bart.
--
To unsubscribe from this list: send the line "unsubscribe linux-rdma" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [RFC Patch] net: reserve ports for applications using fixed port numbers

2010-02-04 Thread Cong Wang

Octavian Purdila wrote:

On Friday 05 February 2010 02:41:12 you wrote:

David Miller wrote:

Octavian Purdila wrote:

int inet_is_reserved_local_port(int port)
{
if (test_bit(port, reserved_ports))
return 1;
return 0;
}

Above check is exactly what I'm doing in the LSM hook.

But his version can be done inline in 2 or 3 instructions.

An LSM hook will result in an indirect function call,
all live registers spilled to the stack, then all of
those reloaded when the function returns.

It will be much more expensive.

If you can accept his version, I want to use his version (with an interface
 for updating above "reserved_ports" by not only root user's sysctl() but
 also MAC's policy configuration).



I think that simply using an interface to update the reserved_ports from MAC 
policy configuration module wouldn't work, as root will be able to modify the 
policy via sysctl.


I think that we might need to:

a) have a reserved_port updater

b) put a LSM hook into that

c) use the reserved_port updater from sysctl




Ideally, you'd provide an interface for port allocator to use, so
doing port reservation will be easier.

Thanks.


--
To unsubscribe from this list: send the line "unsubscribe linux-rdma" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [RFC Patch] net: reserve ports for applications using fixed port numbers

2010-02-04 Thread Cong Wang

Octavian Purdila wrote:

On Thursday 04 February 2010 19:41:10 you wrote:


From: Octavian Purdila 
Date: Thu, 4 Feb 2010 14:44:01 +0200


My concern is that we can have multiple applications that require a
fixed port and if those ports are significantly apart we will
decrease the port range available for connect. And that will hurt
the rate of which new connections can be opened.

I'm already uneasy about adding the simple check every time
we loop around in the bind port allocator.

Adding an LSM hook to this spot?  I absolutely refuse to allow
that, it will completely kill bind performance.



I think Tetsuo was proposing the LSM hook, so I'll leave him the daunting task 
of convincing you of the benefit of that :) - I have no opinion on this due to 
massive lack of knowledge.


I was just proposing to use a discrete set of ports instead of a range. The 
check in the current patch:


int inet_is_reserved_local_port(int port)
{
   int min, max;

   inet_get_local_reserved_ports(&min, &max);
   if (min && max)
   return (port >= min && port <= max);
   return 0;
}

would become:

int inet_is_reserved_local_port(int port)
{
if (test_bit(port, reserved_ports))
return 1;
return 0;
}

In theory it might be slower because of the reserved_ports bitmap will have a 
larger memory footprint than just a min/max, especially with random port 
allocation. But is this an issue in practice?


Again, using bitmap algorithm is not a problem and it's better, the
problem is sysctl interface, how would you plan to interact with users
via sysctl/proc if you use bitmap to handle this? I would like to hear
more details about this.

Thanks!

--
To unsubscribe from this list: send the line "unsubscribe linux-rdma" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [RFC Patch] net: reserve ports for applications using fixed port numbers

2010-02-04 Thread Octavian Purdila
On Friday 05 February 2010 02:41:12 you wrote:
> David Miller wrote:
> > > Octavian Purdila wrote:
> > >> int inet_is_reserved_local_port(int port)
> > >> {
> > >>  if (test_bit(port, reserved_ports))
> > >>  return 1;
> > >>  return 0;
> > >> }
> > >
> > > Above check is exactly what I'm doing in the LSM hook.
> >
> > But his version can be done inline in 2 or 3 instructions.
> >
> > An LSM hook will result in an indirect function call,
> > all live registers spilled to the stack, then all of
> > those reloaded when the function returns.
> >
> > It will be much more expensive.
> 
> If you can accept his version, I want to use his version (with an interface
>  for updating above "reserved_ports" by not only root user's sysctl() but
>  also MAC's policy configuration).
> 

I think that simply using an interface to update the reserved_ports from MAC 
policy configuration module wouldn't work, as root will be able to modify the 
policy via sysctl.

I think that we might need to:

a) have a reserved_port updater

b) put a LSM hook into that

c) use the reserved_port updater from sysctl



--
To unsubscribe from this list: send the line "unsubscribe linux-rdma" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [RFC Patch] net: reserve ports for applications using fixed port numbers

2010-02-04 Thread Tetsuo Handa
David Miller wrote:
> > Octavian Purdila wrote:
> >> 
> >> int inet_is_reserved_local_port(int port)
> >> {
> >>if (test_bit(port, reserved_ports))
> >>return 1;
> >>return 0;
> >> }
> >> 
> > Above check is exactly what I'm doing in the LSM hook.
> 
> But his version can be done inline in 2 or 3 instructions.
> 
> An LSM hook will result in an indirect function call,
> all live registers spilled to the stack, then all of
> those reloaded when the function returns.
> 
> It will be much more expensive.

If you can accept his version, I want to use his version (with an interface for
updating above "reserved_ports" by not only root user's sysctl() but also MAC's
policy configuration).
--
To unsubscribe from this list: send the line "unsubscribe linux-rdma" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [RFC Patch] net: reserve ports for applications using fixed port numbers

2010-02-04 Thread David Miller
From: Tetsuo Handa 
Date: Fri, 5 Feb 2010 06:45:28 +0900

> Octavian Purdila wrote:
>> 
>> int inet_is_reserved_local_port(int port)
>> {
>>  if (test_bit(port, reserved_ports))
>>  return 1;
>>  return 0;
>> }
>> 
> Above check is exactly what I'm doing in the LSM hook.

But his version can be done inline in 2 or 3 instructions.

An LSM hook will result in an indirect function call,
all live registers spilled to the stack, then all of
those reloaded when the function returns.

It will be much more expensive.
--
To unsubscribe from this list: send the line "unsubscribe linux-rdma" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [RFC Patch] net: reserve ports for applications using fixed port numbers

2010-02-04 Thread Tetsuo Handa
Octavian Purdila wrote:
> 
> int inet_is_reserved_local_port(int port)
> {
>   if (test_bit(port, reserved_ports))
>   return 1;
>   return 0;
> }
> 
Above check is exactly what I'm doing in the LSM hook.
--
To unsubscribe from this list: send the line "unsubscribe linux-rdma" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [RFC Patch] net: reserve ports for applications using fixed port numbers

2010-02-04 Thread David Miller
From: Octavian Purdila 
Date: Thu, 4 Feb 2010 20:15:51 +0200

> int inet_is_reserved_local_port(int port)
> {
>   if (test_bit(port, reserved_ports))
>   return 1;
>   return 0;
> }
> 
> In theory it might be slower because of the reserved_ports bitmap will have a 
> larger memory footprint than just a min/max, especially with random port 
> allocation. But is this an issue in practice?

No need to speculate, some simple benchmarks would confirm or deny
this.
--
To unsubscribe from this list: send the line "unsubscribe linux-rdma" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [RFC Patch] net: reserve ports for applications using fixed port numbers

2010-02-04 Thread Octavian Purdila
On Thursday 04 February 2010 19:41:10 you wrote:

> From: Octavian Purdila 
> Date: Thu, 4 Feb 2010 14:44:01 +0200
> 
> > My concern is that we can have multiple applications that require a
> > fixed port and if those ports are significantly apart we will
> > decrease the port range available for connect. And that will hurt
> > the rate of which new connections can be opened.
> 
> I'm already uneasy about adding the simple check every time
> we loop around in the bind port allocator.
> 
> Adding an LSM hook to this spot?  I absolutely refuse to allow
> that, it will completely kill bind performance.
> 

I think Tetsuo was proposing the LSM hook, so I'll leave him the daunting task 
of convincing you of the benefit of that :) - I have no opinion on this due to 
massive lack of knowledge.

I was just proposing to use a discrete set of ports instead of a range. The 
check in the current patch:

int inet_is_reserved_local_port(int port)
{
   int min, max;

   inet_get_local_reserved_ports(&min, &max);
   if (min && max)
   return (port >= min && port <= max);
   return 0;
}

would become:

int inet_is_reserved_local_port(int port)
{
if (test_bit(port, reserved_ports))
return 1;
return 0;
}

In theory it might be slower because of the reserved_ports bitmap will have a 
larger memory footprint than just a min/max, especially with random port 
allocation. But is this an issue in practice?
--
To unsubscribe from this list: send the line "unsubscribe linux-rdma" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [RFC Patch] net: reserve ports for applications using fixed port numbers

2010-02-04 Thread David Miller
From: Octavian Purdila 
Date: Thu, 4 Feb 2010 14:44:01 +0200

> My concern is that we can have multiple applications that require a
> fixed port and if those ports are significantly apart we will
> decrease the port range available for connect. And that will hurt
> the rate of which new connections can be opened.

I'm already uneasy about adding the simple check every time
we loop around in the bind port allocator.

Adding an LSM hook to this spot?  I absolutely refuse to allow
that, it will completely kill bind performance.
--
To unsubscribe from this list: send the line "unsubscribe linux-rdma" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [RFC Patch] net: reserve ports for applications using fixed port numbers

2010-02-04 Thread Octavian Purdila
On Thursday 04 February 2010 05:23:38 you wrote:

> > I think it might be useful to allow setting individual ports as reserved,
> > not only ranges, for example by using a bitmap.
> 
> This is a good idea, but I am not sure if this will be overkill? :-/
> Also, using bitmap is not friendly to sysctl interface, I am afraid.
> 

My concern is that we can have multiple applications that require a fixed port 
and if those ports are significantly apart we will decrease the port range 
available for connect. And that will hurt the rate of which new connections 
can be opened.

As for the sysctl interface I agree, I don't think it is even possible to  
cleanly use a bitmap through sysctl.

The options I see are either enhance sysctl to support bitmaps or use a 
dedicated /proc/net entry. 

I want to give this a try, which one do you people think is better?
--
To unsubscribe from this list: send the line "unsubscribe linux-rdma" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [RFC Patch] net: reserve ports for applications using fixed port numbers

2010-02-03 Thread Cong Wang

Octavian Purdila wrote:

On Wednesday 03 February 2010 06:30:07 you wrote:


This patch introduces /proc/sys/net/ipv4/ip_local_reserved_ports,
it can be used like ip_local_port_range, but this is used to
reserve ports for third-party applications which use fixed
port numbers within ip_local_port_range.

This only affects the applications which call socket functions
like bind(2) with port number 0, to prevent the kernel getting the ports
within the specified range for them. For applications which use fixed
port number, it will have no effects.


It also affects the case where applications do connect, without previously 
doing bind, right?



Yeah, I forgot to mention this, sorry.




Any comments are welcome.


I think it might be useful to allow setting individual ports as reserved, not 
only ranges, for example by using a bitmap. 



This is a good idea, but I am not sure if this will be overkill? :-/
Also, using bitmap is not friendly to sysctl interface, I am afraid.


Thanks!
--
To unsubscribe from this list: send the line "unsubscribe linux-rdma" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [RFC Patch] net: reserve ports for applications using fixed port numbers

2010-02-03 Thread Octavian Purdila
On Wednesday 03 February 2010 06:30:07 you wrote:

> This patch introduces /proc/sys/net/ipv4/ip_local_reserved_ports,
> it can be used like ip_local_port_range, but this is used to
> reserve ports for third-party applications which use fixed
> port numbers within ip_local_port_range.
> 
> This only affects the applications which call socket functions
> like bind(2) with port number 0, to prevent the kernel getting the ports
> within the specified range for them. For applications which use fixed
> port number, it will have no effects.

It also affects the case where applications do connect, without previously 
doing bind, right?

> 
> Any comments are welcome.

I think it might be useful to allow setting individual ports as reserved, not 
only ranges, for example by using a bitmap. 


--
To unsubscribe from this list: send the line "unsubscribe linux-rdma" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [RFC Patch] net: reserve ports for applications using fixed port numbers

2010-02-02 Thread Cong Wang

Eric Dumazet wrote:

Le mardi 02 février 2010 à 23:30 -0500, Amerigo Wang a écrit :

This patch introduces /proc/sys/net/ipv4/ip_local_reserved_ports,
it can be used like ip_local_port_range, but this is used to
reserve ports for third-party applications which use fixed
port numbers within ip_local_port_range.

This only affects the applications which call socket functions
like bind(2) with port number 0, to prevent the kernel getting the ports
within the specified range for them. For applications which use fixed
port number, it will have no effects.

Any comments are welcome.

Signed-off-by: WANG Cong 
Cc: David Miller 
Cc: Neil Horman 
Cc: Eric Dumazet 



.procname   = "igmp_max_memberships",
diff --git a/net/ipv4/udp.c b/net/ipv4/udp.c
index f0126fd..83045ca 100644
--- a/net/ipv4/udp.c
+++ b/net/ipv4/udp.c
@@ -210,8 +210,11 @@ int udp_lib_get_port(struct sock *sk, unsigned short snum,
inet_get_local_port_range(&low, &high);
remaining = (high - low) + 1;
 
+again:

rand = net_random();
first = (((u64)rand * remaining) >> 32) + low;
+   if (inet_is_reserved_local_port(first))
+   goto again;
/*
 * force rand to be an odd multiple of UDP_HTABLE_SIZE
 */


Unless I misread the patch, you are checking only the 'first' port that
udp_lib_get_port() chose.

I would use inet_get_local_reserved_ports(&min_res, &max_res);
and check every port that we chose in the loop to avoid it if necessary.



Hmm, right, 'first' is used to do iteration, but I did missed 'last'.
Thanks! I will fix this in the next update.

--
To unsubscribe from this list: send the line "unsubscribe linux-rdma" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [RFC Patch] net: reserve ports for applications using fixed port numbers

2010-02-02 Thread Eric Dumazet
Le mardi 02 février 2010 à 23:30 -0500, Amerigo Wang a écrit :
> This patch introduces /proc/sys/net/ipv4/ip_local_reserved_ports,
> it can be used like ip_local_port_range, but this is used to
> reserve ports for third-party applications which use fixed
> port numbers within ip_local_port_range.
> 
> This only affects the applications which call socket functions
> like bind(2) with port number 0, to prevent the kernel getting the ports
> within the specified range for them. For applications which use fixed
> port number, it will have no effects.
> 
> Any comments are welcome.
> 
> Signed-off-by: WANG Cong 
> Cc: David Miller 
> Cc: Neil Horman 
> Cc: Eric Dumazet 

>   .procname   = "igmp_max_memberships",
> diff --git a/net/ipv4/udp.c b/net/ipv4/udp.c
> index f0126fd..83045ca 100644
> --- a/net/ipv4/udp.c
> +++ b/net/ipv4/udp.c
> @@ -210,8 +210,11 @@ int udp_lib_get_port(struct sock *sk, unsigned short 
> snum,
>   inet_get_local_port_range(&low, &high);
>   remaining = (high - low) + 1;
>  
> +again:
>   rand = net_random();
>   first = (((u64)rand * remaining) >> 32) + low;
> + if (inet_is_reserved_local_port(first))
> + goto again;
>   /*
>* force rand to be an odd multiple of UDP_HTABLE_SIZE
>*/

Unless I misread the patch, you are checking only the 'first' port that
udp_lib_get_port() chose.

I would use inet_get_local_reserved_ports(&min_res, &max_res);
and check every port that we chose in the loop to avoid it if necessary.


--
To unsubscribe from this list: send the line "unsubscribe linux-rdma" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[RFC Patch] net: reserve ports for applications using fixed port numbers

2010-02-02 Thread Amerigo Wang

This patch introduces /proc/sys/net/ipv4/ip_local_reserved_ports,
it can be used like ip_local_port_range, but this is used to
reserve ports for third-party applications which use fixed
port numbers within ip_local_port_range.

This only affects the applications which call socket functions
like bind(2) with port number 0, to prevent the kernel getting the ports
within the specified range for them. For applications which use fixed
port number, it will have no effects.

Any comments are welcome.

Signed-off-by: WANG Cong 
Cc: David Miller 
Cc: Neil Horman 
Cc: Eric Dumazet 

---
diff --git a/drivers/infiniband/core/cma.c b/drivers/infiniband/core/cma.c
index cc9b594..8248fc6 100644
--- a/drivers/infiniband/core/cma.c
+++ b/drivers/infiniband/core/cma.c
@@ -1979,6 +1979,8 @@ retry:
/* FIXME: add proper port randomization per like inet_csk_get_port */
do {
ret = idr_get_new_above(ps, bind_list, next_port, &port);
+   if (inet_is_reserved_local_port(port))
+   ret = -EAGAIN;
} while ((ret == -EAGAIN) && idr_pre_get(ps, GFP_KERNEL));
 
if (ret)
@@ -2997,10 +2999,13 @@ static int __init cma_init(void)
 {
int ret, low, high, remaining;
 
-   get_random_bytes(&next_port, sizeof next_port);
inet_get_local_port_range(&low, &high);
+again:
+   get_random_bytes(&next_port, sizeof next_port);
remaining = (high - low) + 1;
next_port = ((unsigned int) next_port % remaining) + low;
+   if (inet_is_reserved_local_port(next_port))
+   goto again;
 
cma_wq = create_singlethread_workqueue("rdma_cm");
if (!cma_wq)
diff --git a/include/net/ip.h b/include/net/ip.h
index fb63371..f70acad 100644
--- a/include/net/ip.h
+++ b/include/net/ip.h
@@ -181,8 +181,10 @@ extern void snmp_mib_free(void *ptr[2]);
 extern struct local_ports {
seqlock_t   lock;
int range[2];
-} sysctl_local_ports;
+} sysctl_local_ports, sysctl_local_reserved_ports;
 extern void inet_get_local_port_range(int *low, int *high);
+extern void inet_get_local_reserved_ports(int *from, int *to);
+extern int inet_is_reserved_local_port(int port);
 
 extern int sysctl_ip_default_ttl;
 extern int sysctl_ip_nonlocal_bind;
diff --git a/net/ipv4/inet_connection_sock.c b/net/ipv4/inet_connection_sock.c
index ee16475..ee13e48 100644
--- a/net/ipv4/inet_connection_sock.c
+++ b/net/ipv4/inet_connection_sock.c
@@ -37,6 +37,11 @@ struct local_ports sysctl_local_ports __read_mostly = {
.range = { 32768, 61000 },
 };
 
+struct local_ports sysctl_local_reserved_ports __read_mostly = {
+   .lock = SEQLOCK_UNLOCKED,
+   .range = { 0, 0 },
+};
+
 void inet_get_local_port_range(int *low, int *high)
 {
unsigned seq;
@@ -49,6 +54,28 @@ void inet_get_local_port_range(int *low, int *high)
 }
 EXPORT_SYMBOL(inet_get_local_port_range);
 
+void inet_get_local_reserved_ports(int *from, int *to)
+{
+   unsigned int seq;
+   do {
+   seq = read_seqbegin(&sysctl_local_reserved_ports.lock);
+
+   *from = sysctl_local_reserved_ports.range[0];
+   *to = sysctl_local_reserved_ports.range[1];
+   } while (read_seqretry(&sysctl_local_reserved_ports.lock, seq));
+}
+
+int inet_is_reserved_local_port(int port)
+{
+   int min, max;
+
+   inet_get_local_reserved_ports(&min, &max);
+   if (min && max)
+   return (port >= min && port <= max);
+   return 0;
+}
+EXPORT_SYMBOL(inet_is_reserved_local_port);
+
 int inet_csk_bind_conflict(const struct sock *sk,
   const struct inet_bind_bucket *tb)
 {
@@ -105,6 +132,8 @@ again:
inet_get_local_port_range(&low, &high);
remaining = (high - low) + 1;
smallest_rover = rover = net_random() % remaining + low;
+   if (inet_is_reserved_local_port(rover))
+   goto again;
 
smallest_size = -1;
do {
diff --git a/net/ipv4/inet_hashtables.c b/net/ipv4/inet_hashtables.c
index 2b79377..d3e160a 100644
--- a/net/ipv4/inet_hashtables.c
+++ b/net/ipv4/inet_hashtables.c
@@ -456,6 +456,8 @@ int __inet_hash_connect(struct inet_timewait_death_row 
*death_row,
local_bh_disable();
for (i = 1; i <= remaining; i++) {
port = low + (i + offset) % remaining;
+   if (inet_is_reserved_local_port(port))
+   continue;
head = &hinfo->bhash[inet_bhashfn(net, port,
hinfo->bhash_size)];
spin_lock(&head->lock);
diff --git a/net/ipv4/sysctl_net_ipv4.c b/net/ipv4/sysctl_net_ipv4.c
index 7e3712c..9adf1a5 100644
--- a/net/ipv4/sysctl_net_ipv4.c
+++ b/net/ipv4/sysctl_net_ipv4.c
@@ -23,6 +23,7 @@
 
 static int zero;
 static int tcp_retr1_max = 255;
+static int ip_local_reserved_ports_min[] = {0, 0 };
 static in