mirror of
https://github.com/BobTheBlinker/android_kernel_motorola_sm6375.git
synced 2026-10-30 19:51:31 -04:00
net: reserve ports for applications using fixed port numbers
(Dropped the infiniband part, because Tetsuo modified the related code, I will send a separate patch for it once this is accepted.) This patch introduces /proc/sys/net/ipv4/ip_local_reserved_ports which allows users to reserve ports for third-party applications. The reserved ports will not be used by automatic port assignments (e.g. when calling connect() or bind() with port number 0). Explicit port allocation behavior is unchanged. Signed-off-by: Octavian Purdila <[email protected]> Signed-off-by: WANG Cong <[email protected]> Cc: Neil Horman <[email protected]> Cc: Eric Dumazet <[email protected]> Cc: Eric W. Biederman <[email protected]> Signed-off-by: David S. Miller <[email protected]>
This commit is contained in:
parent
9f977fb7ae
commit
e3826f1e94
8 changed files with 73 additions and 2 deletions
|
|
@ -1573,9 +1573,13 @@ static int __init inet_init(void)
|
|||
|
||||
BUILD_BUG_ON(sizeof(struct inet_skb_parm) > sizeof(dummy_skb->cb));
|
||||
|
||||
sysctl_local_reserved_ports = kzalloc(65536 / 8, GFP_KERNEL);
|
||||
if (!sysctl_local_reserved_ports)
|
||||
goto out;
|
||||
|
||||
rc = proto_register(&tcp_prot, 1);
|
||||
if (rc)
|
||||
goto out;
|
||||
goto out_free_reserved_ports;
|
||||
|
||||
rc = proto_register(&udp_prot, 1);
|
||||
if (rc)
|
||||
|
|
@ -1674,6 +1678,8 @@ out_unregister_udp_proto:
|
|||
proto_unregister(&udp_prot);
|
||||
out_unregister_tcp_proto:
|
||||
proto_unregister(&tcp_prot);
|
||||
out_free_reserved_ports:
|
||||
kfree(sysctl_local_reserved_ports);
|
||||
goto out;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -37,6 +37,9 @@ struct local_ports sysctl_local_ports __read_mostly = {
|
|||
.range = { 32768, 61000 },
|
||||
};
|
||||
|
||||
unsigned long *sysctl_local_reserved_ports;
|
||||
EXPORT_SYMBOL(sysctl_local_reserved_ports);
|
||||
|
||||
void inet_get_local_port_range(int *low, int *high)
|
||||
{
|
||||
unsigned seq;
|
||||
|
|
@ -108,6 +111,8 @@ again:
|
|||
|
||||
smallest_size = -1;
|
||||
do {
|
||||
if (inet_is_reserved_local_port(rover))
|
||||
goto next_nolock;
|
||||
head = &hashinfo->bhash[inet_bhashfn(net, rover,
|
||||
hashinfo->bhash_size)];
|
||||
spin_lock(&head->lock);
|
||||
|
|
@ -130,6 +135,7 @@ again:
|
|||
break;
|
||||
next:
|
||||
spin_unlock(&head->lock);
|
||||
next_nolock:
|
||||
if (++rover > high)
|
||||
rover = low;
|
||||
} while (--remaining > 0);
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -299,6 +299,13 @@ static struct ctl_table ipv4_table[] = {
|
|||
.mode = 0644,
|
||||
.proc_handler = ipv4_local_port_range,
|
||||
},
|
||||
{
|
||||
.procname = "ip_local_reserved_ports",
|
||||
.data = NULL, /* initialized in sysctl_ipv4_init */
|
||||
.maxlen = 65536,
|
||||
.mode = 0644,
|
||||
.proc_handler = proc_do_large_bitmap,
|
||||
},
|
||||
#ifdef CONFIG_IP_MULTICAST
|
||||
{
|
||||
.procname = "igmp_max_memberships",
|
||||
|
|
@ -736,6 +743,16 @@ static __net_initdata struct pernet_operations ipv4_sysctl_ops = {
|
|||
static __init int sysctl_ipv4_init(void)
|
||||
{
|
||||
struct ctl_table_header *hdr;
|
||||
struct ctl_table *i;
|
||||
|
||||
for (i = ipv4_table; i->procname; i++) {
|
||||
if (strcmp(i->procname, "ip_local_reserved_ports") == 0) {
|
||||
i->data = sysctl_local_reserved_ports;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!i->procname)
|
||||
return -EINVAL;
|
||||
|
||||
hdr = register_sysctl_paths(net_ipv4_ctl_path, ipv4_table);
|
||||
if (hdr == NULL)
|
||||
|
|
|
|||
|
|
@ -233,7 +233,8 @@ int udp_lib_get_port(struct sock *sk, unsigned short snum,
|
|||
*/
|
||||
do {
|
||||
if (low <= snum && snum <= high &&
|
||||
!test_bit(snum >> udptable->log, bitmap))
|
||||
!test_bit(snum >> udptable->log, bitmap) &&
|
||||
!inet_is_reserved_local_port(snum))
|
||||
goto found;
|
||||
snum += rand;
|
||||
} while (snum != first);
|
||||
|
|
|
|||
Loading…
Reference in a new issue