[PATCH 4/5] net: add dscp ranges to net cgroup

2016-08-10 Thread Anoop Naravaram
dscp ranges
--
This property controls which dscp values the processes in a cgroup are
allowed to use. A process in a cgroup will receive an EACCES error if it
tries to do any of these things:
* set a socket's IP_TOS option to a value whose dscp field (bits 7:2) is
  outside the range
* use a socket to send a message in which the IP_TOS ancillary data is
  set to a value whose dscp field is outside the range

This property is exposed to userspace through the 'net.dscp_ranges' file,
similar to the bind and listen port ranges.

Tested: wrote python to attempt to setsockopt the IP_TOS option to a
value with an out-of-range dscp field, and expect a failure

Signed-off-by: Anoop Naravaram <anarava...@google.com>
---
 Documentation/cgroup-v1/net.txt | 14 ++
 include/net/net_cgroup.h|  6 ++
 net/core/net_cgroup.c   | 34 --
 net/ipv4/ip_sockglue.c  | 13 +
 net/ipv6/datagram.c |  9 +
 net/ipv6/ipv6_sockglue.c|  8 
 6 files changed, 82 insertions(+), 2 deletions(-)

diff --git a/Documentation/cgroup-v1/net.txt b/Documentation/cgroup-v1/net.txt
index a14fd1c..ea2f1db 100644
--- a/Documentation/cgroup-v1/net.txt
+++ b/Documentation/cgroup-v1/net.txt
@@ -30,6 +30,20 @@ This property is exposed to userspace through the 
'net.listen_port_ranges' file,
 as ranges of ports that the processes can listen on (as described in the HOW TO
 INTERACT WITH RANGES FILES section).
 
+dscp ranges
+---
+This property controls which dscp values the processes in a cgroup are
+allowed to use. A process in a cgroup will receive an EACCES error if it
+tries to do any of these things:
+* set a socket's IP_TOS option to a value whose dscp field (bits 7:2) is
+  outside the range
+* use a socket to send a message in which the IP_TOS ancillary data is
+  set to a value whose dscp field is outside the range
+
+This property is exposed to userspace through the 'net.dscp_ranges' file, as
+ranges of dscp values that the process can use (as described in the HOW TO
+INTERACT WITH RANGES FILES section).
+
 udp port usage and limit
 
 This property controls the limit of udp ports that can be used by the
diff --git a/include/net/net_cgroup.h b/include/net/net_cgroup.h
index 25a9def..d89e98d 100644
--- a/include/net/net_cgroup.h
+++ b/include/net/net_cgroup.h
@@ -23,6 +23,7 @@
 enum {
NETCG_LISTEN_RANGES,
NETCG_BIND_RANGES,
+   NETCG_DSCP_RANGES,
NETCG_NUM_RANGE_TYPES
 };
 
@@ -73,6 +74,7 @@ struct net_cgroup {
 
 bool net_cgroup_bind_allowed(u16 port);
 bool net_cgroup_listen_allowed(u16 port);
+bool net_cgroup_dscp_allowed(u8 dscp);
 bool net_cgroup_acquire_udp_port(void);
 void net_cgroup_release_udp_port(void);
 
@@ -85,6 +87,10 @@ static inline bool net_cgroup_listen_allowed(u16 port)
 {
return true;
 }
+static inline bool net_cgroup_dscp_allowed(u8 dscp)
+{
+   return true;
+}
 static inline bool net_cgroup_acquire_udp_port(void)
 {
return true;
diff --git a/net/core/net_cgroup.c b/net/core/net_cgroup.c
index 2f58e13..73dc5e7 100644
--- a/net/core/net_cgroup.c
+++ b/net/core/net_cgroup.c
@@ -21,6 +21,9 @@
 #define MIN_PORT_VALUE 0
 #define MAX_PORT_VALUE 65535
 
+#define MIN_DSCP_VALUE 0
+#define MAX_DSCP_VALUE 63
+
 /* Deriving MAX_ENTRIES from MAX_WRITE_SIZE as a rough estimate */
 #define MAX_ENTRIES ((MAX_WRITE_SIZE - offsetof(struct net_ranges, range)) /   
\
 BYTES_PER_ENTRY)
@@ -161,7 +164,10 @@ cgrp_css_alloc(struct cgroup_subsys_state *parent_css)
MIN_PORT_VALUE, MAX_PORT_VALUE) ||
alloc_init_net_ranges(
>whitelists[NETCG_LISTEN_RANGES],
-   MIN_PORT_VALUE, MAX_PORT_VALUE)) {
+   MIN_PORT_VALUE, MAX_PORT_VALUE) ||
+   alloc_init_net_ranges(
+   >whitelists[NETCG_DSCP_RANGES],
+   MIN_DSCP_VALUE, MAX_DSCP_VALUE)) {
free_net_cgroup(netcg);
/* if any of these cause an error, return ENOMEM */
return ERR_PTR(-ENOMEM);
@@ -178,7 +184,11 @@ cgrp_css_alloc(struct cgroup_subsys_state *parent_css)
alloc_copy_net_ranges(
>whitelists[NETCG_LISTEN_RANGES],
MIN_PORT_VALUE, MAX_PORT_VALUE,
-   
_netcg->whitelists[NETCG_LISTEN_RANGES])) {
+   _netcg->whitelists[NETCG_LISTEN_RANGES]) 
||
+   alloc_copy_net_ranges(
+   >whitelists[NETCG_DSCP_RANGES],
+   MIN_DSCP_VALUE, MAX_DSCP_VALUE,
+   _netcg->whitelists[NETCG_DSCP_RANGES])) {
  

[PATCH 1/5] net: create the networking cgroup controller

2016-08-10 Thread Anoop Naravaram
This is a skeleton implementation of a cgroup controller for networking
properties. It will be used for:
* limiting the specific ports that a process in a cgroup is allowed to bind
  to or listen on
* restricting which dscp values processes can use with their sockets
* limiting the total number of udp ports that can be used by a process

Also there is new documentation of this controller in
Documentation/cgroup-v1/net.txt.

Signed-off-by: Anoop Naravaram <anarava...@google.com>
---
 Documentation/cgroup-v1/net.txt |  9 ++
 include/linux/cgroup_subsys.h   |  4 +++
 include/net/net_cgroup.h| 27 ++
 net/Kconfig | 10 +++
 net/core/Makefile   |  1 +
 net/core/net_cgroup.c   | 62 +
 6 files changed, 113 insertions(+)
 create mode 100644 Documentation/cgroup-v1/net.txt
 create mode 100644 include/net/net_cgroup.h
 create mode 100644 net/core/net_cgroup.c

diff --git a/Documentation/cgroup-v1/net.txt b/Documentation/cgroup-v1/net.txt
new file mode 100644
index 000..580c214
--- /dev/null
+++ b/Documentation/cgroup-v1/net.txt
@@ -0,0 +1,9 @@
+Networking cgroup
+=
+
+The net cgroup controller keeps track of the following networking related
+properties for each process group:
+* bind port ranges
+* listen port ranges
+* dscp ranges
+* udp port usage and limit
diff --git a/include/linux/cgroup_subsys.h b/include/linux/cgroup_subsys.h
index 0df0336a..81ff75b 100644
--- a/include/linux/cgroup_subsys.h
+++ b/include/linux/cgroup_subsys.h
@@ -40,6 +40,10 @@ SUBSYS(freezer)
 SUBSYS(net_cls)
 #endif
 
+#if IS_ENABLED(CONFIG_CGROUP_NET)
+SUBSYS(net)
+#endif
+
 #if IS_ENABLED(CONFIG_CGROUP_PERF)
 SUBSYS(perf_event)
 #endif
diff --git a/include/net/net_cgroup.h b/include/net/net_cgroup.h
new file mode 100644
index 000..8e98803
--- /dev/null
+++ b/include/net/net_cgroup.h
@@ -0,0 +1,27 @@
+/*
+ * net_cgroup.hNetworking Control Group
+ *
+ * Copyright (C) 2016 Google, Inc.
+ *
+ * Authors:    Anoop Naravaram <anarava...@google.com>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option)
+ * any later version.
+ *
+ */
+
+#ifndef _NET_CGROUP_H
+#define _NET_CGROUP_H
+
+#include 
+
+#ifdef CONFIG_CGROUP_NET
+
+struct net_cgroup {
+   struct cgroup_subsys_state  css;
+};
+
+#endif /* CONFIG_CGROUP_NET */
+#endif  /* _NET_CGROUP_H */
diff --git a/net/Kconfig b/net/Kconfig
index c2cdbce..47f68bd 100644
--- a/net/Kconfig
+++ b/net/Kconfig
@@ -278,6 +278,16 @@ config CGROUP_NET_CLASSID
  Cgroup subsystem for use as general purpose socket classid marker 
that is
  being used in cls_cgroup and for netfilter matching.
 
+config CGROUP_NET
+   bool "Networking cgroup"
+   depends on CGROUPS
+   ---help---
+ Cgroup subsystem for use in managing several networking properties,
+ such as restricting which ports are available for processes to bind
+ and listen on, restricting which dscp values processes can use with
+ their sockets, and limiting the number of udp ports that can be
+ acquired by processes from the cgroup.
+
 config NET_RX_BUSY_POLL
bool
default y
diff --git a/net/core/Makefile b/net/core/Makefile
index d6508c2..9dbc8b6 100644
--- a/net/core/Makefile
+++ b/net/core/Makefile
@@ -23,6 +23,7 @@ obj-$(CONFIG_NETWORK_PHY_TIMESTAMPING) += timestamping.o
 obj-$(CONFIG_NET_PTP_CLASSIFY) += ptp_classifier.o
 obj-$(CONFIG_CGROUP_NET_PRIO) += netprio_cgroup.o
 obj-$(CONFIG_CGROUP_NET_CLASSID) += netclassid_cgroup.o
+obj-$(CONFIG_CGROUP_NET) += net_cgroup.o
 obj-$(CONFIG_LWTUNNEL) += lwtunnel.o
 obj-$(CONFIG_DST_CACHE) += dst_cache.o
 obj-$(CONFIG_HWBM) += hwbm.o
diff --git a/net/core/net_cgroup.c b/net/core/net_cgroup.c
new file mode 100644
index 000..3a46960
--- /dev/null
+++ b/net/core/net_cgroup.c
@@ -0,0 +1,62 @@
+/*
+ * net/core/net_cgroup.c   Networking Control Group
+ *
+ * Copyright (C) 2016 Google, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option)
+ * any later version.
+ *
+ * Authors:Anoop Naravaram <anarava...@google.com>
+ */
+
+#include 
+#include 
+
+static struct net_cgroup *css_to_net_cgroup(struct cgroup_subsys_state *css)
+{
+   return css ? container_of(css, struct net_cgroup, css) : NULL;
+}
+
+static struct net_cgroup *task_to_net_cgroup(struct task_struct *p)
+{
+   return css_to_net_cgroup(task_css(p, net_cgrp_id));
+}
+
+static struct net_cgroup *net_cgroup_to_parent(struct net_cgroup *netcg)
+{
+   return css_to_net_cgroup(netcg->css.parent);
+}

[PATCH 2/5] net: add bind/listen ranges to net cgroup

2016-08-10 Thread Anoop Naravaram
bind port ranges

This property controls which ports the processes in a cgroup are allowed
to bind to. If a process in a cgroup tries to bind a socket to a port
that is not within the range(s) permitted by the cgroup, it will receive an
EACCES error.

>From userspace, you can get or set the bind port ranges by accessing the
'net.bind_port_ranges' file. To set the ranges of a cgroup, write the
comma-separated ranges to the file, where each range could be either a
pair of ports separated by a hyphen (-), or just an individual port. For
example, say you want to allow all the processes in a cgroup to be allowed
to bind to ports 100 through 200 (inclusive), 300 through 320 (inclusive)
and 350. Then you can write the string "100-200,300-320,350" to the
'net.bind_port_ranges' file. When reading the file, any individual ports
will be read as a "start-end" range where the start and end are equal.
The example above would be read as "100-200,300-320,350-350".

The controller imposes the invariant that the ranges of any cgroup must
be a subset (or equal set) of the ranges of its parents (i.e., processes
in a cgroup cannot be allowed to bind to any port that is not allowed
by the parent cgroup). This constraint allows you to ensure that not
only do the processes in a cgroup follow the bind range, but so do the
processes in any of the cgroup's descendants. The way this is enforced
is because of two things: 1) when a cgroup is initialized, its ranges
are inherited from its parent, and 2) when attempting to set the ranges of
a cgroup, the kernel ensures that the condition is true for the current
cgroup and all its children, or otherwise fails to change the ranges
with error EINVAL.

listen port ranges
--
This property controls which ports the processes in a cgroup are allowed
to listen on. If a process in a cgroup tries to listen using a socket
bound to a port that is not within the range(s) permitted by the cgroup,
it will receive an EACCES error.

Configuring this property works the same way as with bind port ranges,
except using the file 'net.listen_port_ranges' instead of
'net.bind_port_ranges'. The range subset invariant is imposed
independently for bind and listen port ranges. For now the kernel does
not enforce that the listen range must be a subset of the bind range.

Tested: Used a python unittest to set the range and try
binding/listening to ports inside and outside the range, and ensure
that an error occurred only when it should. Also, ensures that an error
occurs when trying to violate the subset condition.

Signed-off-by: Anoop Naravaram <anarava...@google.com>
---
 Documentation/cgroup-v1/net.txt |  46 ++
 include/net/net_cgroup.h|  41 +
 net/core/net_cgroup.c   | 341 
 net/ipv4/af_inet.c  |   8 +
 net/ipv4/inet_connection_sock.c |   7 +
 net/ipv6/af_inet6.c |   7 +
 6 files changed, 450 insertions(+)

diff --git a/Documentation/cgroup-v1/net.txt b/Documentation/cgroup-v1/net.txt
index 580c214..8c50c61 100644
--- a/Documentation/cgroup-v1/net.txt
+++ b/Documentation/cgroup-v1/net.txt
@@ -7,3 +7,49 @@ properties for each process group:
 * listen port ranges
 * dscp ranges
 * udp port usage and limit
+
+bind port ranges
+
+This property controls which ports the processes in a cgroup are allowed
+to bind to. If a process in a cgroup tries to bind a socket to a port
+that is not within the range(s) permitted by the cgroup, it will receive an
+EACCES error.
+
+This property is exposed to userspace through the 'net.bind_port_ranges' file,
+as ranges of ports that the processes can bind to (as described in the HOW TO
+INTERACT WITH RANGES FILES section).
+
+listen port ranges
+--
+This property controls which ports the processes in a cgroup are allowed
+to listen on. If a process in a cgroup tries to listen using a socket
+bound to a port that is not within the range(s) permitted by the cgroup,
+it will receive an EACCES error.
+
+This property is exposed to userspace through the 'net.listen_port_ranges' 
file,
+as ranges of ports that the processes can listen on (as described in the HOW TO
+INTERACT WITH RANGES FILES section).
+
+HOW TO INTERACT WITH RANGES FILES
+-
+Some cgroup properties can be expressed as ranges of allowed integers. From
+userspace, you can get or set them by accessing the cgroup file corresponding 
to
+the property you want to interact with. To set the ranges, write a list of
+comma-separated ranges to the file, where each range could be either a pair of
+integers separated by a hyphen (-), or just an individual integer. For example,
+say you want a cgroup to allow the integers 100 through 200 (inclusive), 300
+through 320 (inclusive) and 350. Then you can write the string
+"100-200,300-320,350" to the file. When reading the file, any individual
+integers wi

[PATCH 5/5] net: add test for net cgroup

2016-08-10 Thread Anoop Naravaram
Created a file scripts/cgroup/net_cgroup_test.py that tests the
functionality of the net cgroup as described in previous commit logs.

Signed-off-by: Anoop Naravaram <anarava...@google.com>
---
 scripts/cgroup/net_cgroup_test.py | 359 ++
 1 file changed, 359 insertions(+)
 create mode 100755 scripts/cgroup/net_cgroup_test.py

diff --git a/scripts/cgroup/net_cgroup_test.py 
b/scripts/cgroup/net_cgroup_test.py
new file mode 100755
index 000..604f662
--- /dev/null
+++ b/scripts/cgroup/net_cgroup_test.py
@@ -0,0 +1,359 @@
+#!/usr/grte/v4/bin/python2.7
+import unittest
+import os
+import socket
+import shutil
+import multiprocessing
+
+cgroup_net_root = '/dev/cgroup/net'
+
+def create_cgroup(name):
+'''
+Creates a cgroup with the given name. The name should also include the 
names
+of all ancestors separated by slashes, such as 'a/b/c'. Returns a path to
+the directory of the newly created cgroup.
+'''
+cgroup_dir = os.path.join(cgroup_net_root, name)
+while True:
+try:
+os.mkdir(cgroup_dir)
+break
+except OSError as e:
+# remove it if it already exists, then try to create again
+# there will be errors when rmtree tries to remove the cgroup 
files,
+# but these errors should be ignored because we only care about
+# rmdir'ing the directories, which will automatically get rid of 
the
+# files inside them
+shutil.rmtree(cgroup_dir, ignore_errors=True)
+
+return cgroup_dir
+
+
+def parse_ranges(ranges_str):
+'''
+Converts a range string like "100-200,300-400" into a set of 2-tuples like
+{(100,200),(300,400)}.
+'''
+return set(tuple(int(l) for l in r.strip().split('-'))
+   for r in ranges_str.split(','))
+
+def acquire_udp_ports(cgroup_dir, e2, n, addr, numfailq):
+'''
+Waits for the event e1, attempts to acquire n udp ports connected to addr,
+and then puts the number of failures on the queue and waits for e2. Then,
+all sockets are closed. (Intended to be called as a subprocess.)
+
+While waiting for e1, the parent process can set this process's cgroup.
+While waiting for e2, the parent process can read the udp statistics while
+this process is still alive.
+'''
+
+with open(os.path.join(cgroup_dir, 'tasks'), 'w') as f:
+# add proc1 to cgroup a/b
+f.write(str(os.getpid()))
+
+socketset = set()
+numfail = 0
+for _ in xrange(n):
+s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
+try:
+s.connect(addr)
+except socket.error as e:
+numfail += 1
+socketset.add(s)
+
+if numfailq is not None:
+numfailq.put(numfail)
+
+if e2 is not None:
+e2.wait()
+
+for s in socketset:
+s.close()
+
+
+class NetCgroupTest(unittest.TestCase):
+
+def test_port_range_check(self):
+'''
+Test that the kernel is correctly checking that a port is in the
+relevant range when a process in a net cgroup is trying to bind a 
socket
+to it, or trying to listen on a socket bound to it.
+'''
+
+# create a new cgroup a
+cgroup_a_dir = create_cgroup('a')
+
+# add current process to cgroup a
+with open(os.path.join(cgroup_a_dir, 'tasks'), 'w') as f:
+f.write(str(os.getpid()))
+
+# set bind and listen range of cgroup a
+with open(os.path.join(cgroup_a_dir, 'net.bind_port_ranges'), 'w') as 
f:
+f.write('300-400,500')
+with open(os.path.join(cgroup_a_dir, 'net.listen_port_ranges'), 'w') 
as f:
+f.write('350-400')
+
+# try binding and listening on various ports, and check if they succeed
+# or fail appropriately
+s = socket.socket()
+try:
+s.bind(('0.0.0.0', 350)) # should bind and listen successfully
+try:
+s.listen(5)
+except socket.error:
+self.fail('unexpectedly failed to listen')
+except socket.error:
+self.fail('unexpectedly failed to bind')
+s.close()
+
+s = socket.socket()
+try:
+s.bind(('0.0.0.0', 370)) # should bind and listen successfully
+try:
+s.listen(5)
+except socket.error:
+self.fail('unexpectedly failed to listen')
+except socket.error:
+self.fail('unexpectedly failed to bind')
+s.close()
+
+s = socket.socket()
+try:
+s.bind(('0.0.0.0', 320)) # should bind successfully but fail to 
listen
+with self.assertRaises(socket.error):
+s.listen(5)
+except socket.error:
+self.fail('unexpectedly failed to bind')
+s.close()
+
+s = socket.socket()
+try:
+s.bind(('0.0.0.0', 500)) # should b

[PATCH 3/5] net: add udp limit to net cgroup

2016-08-10 Thread Anoop Naravaram
udp port limit
--
This property controls the limit of udp ports that can be used by the
processes in a cgroup. The controller manages udp statistics (usage,
limit, etc) for each cgroup. Every cgroup also keeps track of the udp
ports acquired by its descendants. If a process tries to acquire a port
when its cgroup has already reached its limit, it will fail with error
EACCES. It will also fail if one of the cgroup's ancestors has reached its
limit. There are 5 files exposed to userspace to configure this property:

* 'net.udp_usage': Reading this file gives the number of udp ports used by
processes in this cgroup and all its descendants.
* 'net.udp_limit': Writing this file sets the total number of udp ports
that can be used by processes in this cgroup and all
its descendants. This file can also be read.
* 'net.udp_maxusage': Reading this file gives the highest value of
net.udp_usage that has been seen for this cgroup.
* 'net.udp_failcnt': Reading this file gives the number of times a
process in this cgroup or one of its descendants has attempted to acquire
a udp port but failed because the limit of this cgroup was reached.
* 'net.udp_underflowcnt': Reading this file gives the number of times a
process in this cgroup or one of its descendants released a udp port when
the usage value of this cgroup was 0.

When a new cgroup is created, its udp limit is copied from its parent.

Tested: Set the udp limit, then used python to use several udp ports,
ensuring that it is successful up until the limit, after which there
should be an error. Also tried different limits at different levels of the
hierarchy.

Signed-off-by: Anoop Naravaram <anarava...@google.com>
---
 Documentation/cgroup-v1/net.txt |  26 
 include/net/net_cgroup.h|  29 +
 net/core/net_cgroup.c   | 273 
 net/ipv4/udp.c  |   8 ++
 4 files changed, 336 insertions(+)

diff --git a/Documentation/cgroup-v1/net.txt b/Documentation/cgroup-v1/net.txt
index 8c50c61..a14fd1c 100644
--- a/Documentation/cgroup-v1/net.txt
+++ b/Documentation/cgroup-v1/net.txt
@@ -30,6 +30,32 @@ This property is exposed to userspace through the 
'net.listen_port_ranges' file,
 as ranges of ports that the processes can listen on (as described in the HOW TO
 INTERACT WITH RANGES FILES section).
 
+udp port usage and limit
+
+This property controls the limit of udp ports that can be used by the
+processes in a cgroup. The controller manages udp statistics (usage, limit, 
etc)
+for each cgroup. Every cgroup also keeps track of the udp ports acquired by its
+descendants. If a process tries to acquire a port when its cgroup has
+already reached its limit, it will fail with error EACCES. It will also fail if
+one of the cgroup's ancestors has reached its limit. There are 5 files
+exposed to userspace to configure this property:
+
+* 'net.udp_usage': Reading this file gives the number of udp ports used by
+processes in this cgroup and all its descendants.
+* 'net.udp_limit': Writing this file sets the total number of udp ports
+that can be used by processes in this cgroup and all
+its descendants. This file can also be read.
+* 'net.udp_maxusage': Reading this file gives the highest value of
+net.udp_usage that has been seen for this cgroup.
+* 'net.udp_failcnt': Reading this file gives the number of times a
+process in this cgroup or one of its descendants has attempted to acquire a
+udp port but failed because the limit of this cgroup was reached.
+* 'net.udp_underflowcnt': Reading this file gives the number of times a
+process in this cgroup or one of its descendants released a udp port when the
+usage value of this cgroup was 0.
+
+When a new cgroup is created, its udp limit is copied from its parent.
+
 HOW TO INTERACT WITH RANGES FILES
 -
 Some cgroup properties can be expressed as ranges of allowed integers. From
diff --git a/include/net/net_cgroup.h b/include/net/net_cgroup.h
index 6ee79d5..25a9def 100644
--- a/include/net/net_cgroup.h
+++ b/include/net/net_cgroup.h
@@ -26,6 +26,16 @@ enum {
NETCG_NUM_RANGE_TYPES
 };
 
+/* udp statistic type */
+enum {
+   NETCG_LIMIT_UDP,
+   NETCG_USAGE_UDP,
+   NETCG_MAXUSAGE_UDP,
+   NETCG_FAILCNT_UDP,
+   NETCG_UNDERFLOWCNT_UDP,
+   NETCG_NUM_UDP_STATS
+};
+
 struct net_range {
u16 min_value;
u16 max_value;
@@ -43,9 +53,19 @@ struct net_range_types {
u16 upper_limit;
 };
 
+struct cgroup_udp_stats {
+   /* Use atomics to protect against multiple writers */
+   atomic64_t  udp_limitandusage; /* 32MSB => limit, 32LSB => usage */
+   atomic_tudp_maxusage;
+   atomic_tudp_failcnt;
+   atomic_tudp_underflowcnt;
+};
+
 struct net_cgroup {
struct cgroup_subsys_state  css;
 
+   struct cgroup_udp_stats udp_stats;
+
/* these fields are requi

[PATCH 0/5] Networking cgroup controller

2016-08-10 Thread Anoop Naravaram
This patchset introduces a cgroup controller for the networking subsystem as a
whole. As of now, this controller will be used for:

* Limiting the specific ports that a process in a cgroup is allowed to bind
  to or listen on. For example, you can say that all the processes in a
  cgroup can only bind to ports 1000-2000, and listen on ports 1000-1100, which
  guarantees that the remaining ports will be available for other processes.

* Restricting which DSCP values processes can use with their sockets. For
  example, you can say that all the processes in a cgroup can only send
  packets with a DSCP tag between 48 and 63 (corresponding to TOS values of
  192 to 255).

* Limiting the total number of udp ports that can be used by a process in a
  cgroup. For example, you can say that all the processes in one cgroup are
  allowed to use a total of up to 100 udp ports. Since the total number of udp
  ports that can be used by all processes is limited, this is useful for
  rationing out the ports to different process groups.

In the future, more networking-related properties may be added to this
controller.

Anoop Naravaram (5):
  net: create the networking cgroup controller
  net: add bind/listen ranges to net cgroup
  net: add udp limit to net cgroup
  net: add dscp ranges to net cgroup
  net: add test for net cgroup

 Documentation/cgroup-v1/net.txt   |  95 +
 include/linux/cgroup_subsys.h |   4 +
 include/net/net_cgroup.h  | 103 ++
 net/Kconfig   |  10 +
 net/core/Makefile |   1 +
 net/core/net_cgroup.c | 706 ++
 net/ipv4/af_inet.c|   8 +
 net/ipv4/inet_connection_sock.c   |   7 +
 net/ipv4/ip_sockglue.c|  13 +
 net/ipv4/udp.c|   8 +
 net/ipv6/af_inet6.c   |   7 +
 net/ipv6/datagram.c   |   9 +
 net/ipv6/ipv6_sockglue.c  |   8 +
 scripts/cgroup/net_cgroup_test.py | 359 +++
 14 files changed, 1338 insertions(+)
 create mode 100644 Documentation/cgroup-v1/net.txt
 create mode 100644 include/net/net_cgroup.h
 create mode 100644 net/core/net_cgroup.c
 create mode 100755 scripts/cgroup/net_cgroup_test.py

-- 
2.8.0.rc3.226.g39d4020