aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Documentation/cgroups/net_cls.txt5
-rw-r--r--include/linux/cgroup_subsys.h4
-rw-r--r--include/linux/netdevice.h2
-rw-r--r--include/linux/netfilter/ipset/ip_set.h1
-rw-r--r--include/net/cls_cgroup.h40
-rw-r--r--include/net/netfilter/ipv4/nf_conntrack_ipv4.h2
-rw-r--r--include/net/netfilter/nf_conntrack_l3proto.h1
-rw-r--r--include/net/netns/conntrack.h33
-rw-r--r--include/net/netprio_cgroup.h18
-rw-r--r--include/net/sock.h2
-rw-r--r--include/uapi/linux/netfilter/Kbuild2
-rw-r--r--include/uapi/linux/netfilter/nf_nat.h12
-rw-r--r--include/uapi/linux/netfilter/nfnetlink_queue.h5
-rw-r--r--include/uapi/linux/netfilter/xt_cgroup.h11
-rw-r--r--include/uapi/linux/netfilter/xt_ipcomp.h16
-rw-r--r--net/Kconfig11
-rw-r--r--net/core/Makefile3
-rw-r--r--net/core/dev.c2
-rw-r--r--net/core/netclassid_cgroup.c120
-rw-r--r--net/core/sock.c14
-rw-r--r--net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c6
-rw-r--r--net/netfilter/Kconfig19
-rw-r--r--net/netfilter/Makefile2
-rw-r--r--net/netfilter/ipset/ip_set_core.c28
-rw-r--r--net/netfilter/ipvs/ip_vs_sync.c5
-rw-r--r--net/netfilter/nf_conntrack_core.c15
-rw-r--r--net/netfilter/nf_conntrack_netlink.c12
-rw-r--r--net/netfilter/nf_conntrack_proto.c6
-rw-r--r--net/netfilter/nf_nat_core.c4
-rw-r--r--net/netfilter/nf_nat_proto_common.c10
-rw-r--r--net/netfilter/nfnetlink_log.c8
-rw-r--r--net/netfilter/nfnetlink_queue_core.c34
-rw-r--r--net/netfilter/nft_hash.c2
-rw-r--r--net/netfilter/xt_CT.c4
-rw-r--r--net/netfilter/xt_RATEEST.c2
-rw-r--r--net/netfilter/xt_cgroup.c71
-rw-r--r--net/netfilter/xt_connlimit.c2
-rw-r--r--net/netfilter/xt_hashlimit.c2
-rw-r--r--net/netfilter/xt_ipcomp.c111
-rw-r--r--net/netfilter/xt_recent.c2
-rw-r--r--net/sched/Kconfig1
-rw-r--r--net/sched/cls_cgroup.c111
42 files changed, 487 insertions, 274 deletions
diff --git a/Documentation/cgroups/net_cls.txt b/Documentation/cgroups/net_cls.txt
index 9face6bb578a..ec182346dea2 100644
--- a/Documentation/cgroups/net_cls.txt
+++ b/Documentation/cgroups/net_cls.txt
@@ -6,6 +6,8 @@ tag network packets with a class identifier (classid).
6 6
7The Traffic Controller (tc) can be used to assign 7The Traffic Controller (tc) can be used to assign
8different priorities to packets from different cgroups. 8different priorities to packets from different cgroups.
9Also, Netfilter (iptables) can use this tag to perform
10actions on such packets.
9 11
10Creating a net_cls cgroups instance creates a net_cls.classid file. 12Creating a net_cls cgroups instance creates a net_cls.classid file.
11This net_cls.classid value is initialized to 0. 13This net_cls.classid value is initialized to 0.
@@ -32,3 +34,6 @@ tc class add dev eth0 parent 10: classid 10:1 htb rate 40mbit
32 - creating traffic class 10:1 34 - creating traffic class 10:1
33 35
34tc filter add dev eth0 parent 10: protocol ip prio 10 handle 1: cgroup 36tc filter add dev eth0 parent 10: protocol ip prio 10 handle 1: cgroup
37
38configuring iptables, basic example:
39iptables -A OUTPUT -m cgroup ! --cgroup 0x100001 -j DROP
diff --git a/include/linux/cgroup_subsys.h b/include/linux/cgroup_subsys.h
index b613ffd402d1..7b99d717411d 100644
--- a/include/linux/cgroup_subsys.h
+++ b/include/linux/cgroup_subsys.h
@@ -31,7 +31,7 @@ SUBSYS(devices)
31SUBSYS(freezer) 31SUBSYS(freezer)
32#endif 32#endif
33 33
34#if IS_SUBSYS_ENABLED(CONFIG_NET_CLS_CGROUP) 34#if IS_SUBSYS_ENABLED(CONFIG_CGROUP_NET_CLASSID)
35SUBSYS(net_cls) 35SUBSYS(net_cls)
36#endif 36#endif
37 37
@@ -43,7 +43,7 @@ SUBSYS(blkio)
43SUBSYS(perf) 43SUBSYS(perf)
44#endif 44#endif
45 45
46#if IS_SUBSYS_ENABLED(CONFIG_NETPRIO_CGROUP) 46#if IS_SUBSYS_ENABLED(CONFIG_CGROUP_NET_PRIO)
47SUBSYS(net_prio) 47SUBSYS(net_prio)
48#endif 48#endif
49 49
diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h
index 51c0fe258163..0c30af38be0d 100644
--- a/include/linux/netdevice.h
+++ b/include/linux/netdevice.h
@@ -1444,7 +1444,7 @@ struct net_device {
1444 /* max exchange id for FCoE LRO by ddp */ 1444 /* max exchange id for FCoE LRO by ddp */
1445 unsigned int fcoe_ddp_xid; 1445 unsigned int fcoe_ddp_xid;
1446#endif 1446#endif
1447#if IS_ENABLED(CONFIG_NETPRIO_CGROUP) 1447#if IS_ENABLED(CONFIG_CGROUP_NET_PRIO)
1448 struct netprio_map __rcu *priomap; 1448 struct netprio_map __rcu *priomap;
1449#endif 1449#endif
1450 /* phy device may attach itself for hardware timestamping */ 1450 /* phy device may attach itself for hardware timestamping */
diff --git a/include/linux/netfilter/ipset/ip_set.h b/include/linux/netfilter/ipset/ip_set.h
index c7174b816674..0c7d01eae56c 100644
--- a/include/linux/netfilter/ipset/ip_set.h
+++ b/include/linux/netfilter/ipset/ip_set.h
@@ -331,7 +331,6 @@ extern ip_set_id_t ip_set_get_byname(struct net *net,
331 const char *name, struct ip_set **set); 331 const char *name, struct ip_set **set);
332extern void ip_set_put_byindex(struct net *net, ip_set_id_t index); 332extern void ip_set_put_byindex(struct net *net, ip_set_id_t index);
333extern const char *ip_set_name_byindex(struct net *net, ip_set_id_t index); 333extern const char *ip_set_name_byindex(struct net *net, ip_set_id_t index);
334extern ip_set_id_t ip_set_nfnl_get(struct net *net, const char *name);
335extern ip_set_id_t ip_set_nfnl_get_byindex(struct net *net, ip_set_id_t index); 334extern ip_set_id_t ip_set_nfnl_get_byindex(struct net *net, ip_set_id_t index);
336extern void ip_set_nfnl_put(struct net *net, ip_set_id_t index); 335extern void ip_set_nfnl_put(struct net *net, ip_set_id_t index);
337 336
diff --git a/include/net/cls_cgroup.h b/include/net/cls_cgroup.h
index 33d03b648646..9cf2d5ef38d9 100644
--- a/include/net/cls_cgroup.h
+++ b/include/net/cls_cgroup.h
@@ -16,17 +16,16 @@
16#include <linux/cgroup.h> 16#include <linux/cgroup.h>
17#include <linux/hardirq.h> 17#include <linux/hardirq.h>
18#include <linux/rcupdate.h> 18#include <linux/rcupdate.h>
19#include <net/sock.h>
19 20
20#if IS_ENABLED(CONFIG_NET_CLS_CGROUP) 21#ifdef CONFIG_CGROUP_NET_CLASSID
21struct cgroup_cls_state 22struct cgroup_cls_state {
22{
23 struct cgroup_subsys_state css; 23 struct cgroup_subsys_state css;
24 u32 classid; 24 u32 classid;
25}; 25};
26 26
27void sock_update_classid(struct sock *sk); 27struct cgroup_cls_state *task_cls_state(struct task_struct *p);
28 28
29#if IS_BUILTIN(CONFIG_NET_CLS_CGROUP)
30static inline u32 task_cls_classid(struct task_struct *p) 29static inline u32 task_cls_classid(struct task_struct *p)
31{ 30{
32 u32 classid; 31 u32 classid;
@@ -41,33 +40,18 @@ static inline u32 task_cls_classid(struct task_struct *p)
41 40
42 return classid; 41 return classid;
43} 42}
44#elif IS_MODULE(CONFIG_NET_CLS_CGROUP)
45static inline u32 task_cls_classid(struct task_struct *p)
46{
47 struct cgroup_subsys_state *css;
48 u32 classid = 0;
49
50 if (in_interrupt())
51 return 0;
52
53 rcu_read_lock();
54 css = task_css(p, net_cls_subsys_id);
55 if (css)
56 classid = container_of(css,
57 struct cgroup_cls_state, css)->classid;
58 rcu_read_unlock();
59 43
60 return classid;
61}
62#endif
63#else /* !CGROUP_NET_CLS_CGROUP */
64static inline void sock_update_classid(struct sock *sk) 44static inline void sock_update_classid(struct sock *sk)
65{ 45{
66} 46 u32 classid;
67 47
68static inline u32 task_cls_classid(struct task_struct *p) 48 classid = task_cls_classid(current);
49 if (classid != sk->sk_classid)
50 sk->sk_classid = classid;
51}
52#else /* !CONFIG_CGROUP_NET_CLASSID */
53static inline void sock_update_classid(struct sock *sk)
69{ 54{
70 return 0;
71} 55}
72#endif /* CGROUP_NET_CLS_CGROUP */ 56#endif /* CONFIG_CGROUP_NET_CLASSID */
73#endif /* _NET_CLS_CGROUP_H */ 57#endif /* _NET_CLS_CGROUP_H */
diff --git a/include/net/netfilter/ipv4/nf_conntrack_ipv4.h b/include/net/netfilter/ipv4/nf_conntrack_ipv4.h
index 6c3d12e2949f..981c327374da 100644
--- a/include/net/netfilter/ipv4/nf_conntrack_ipv4.h
+++ b/include/net/netfilter/ipv4/nf_conntrack_ipv4.h
@@ -19,6 +19,4 @@ extern struct nf_conntrack_l4proto nf_conntrack_l4proto_icmp;
19int nf_conntrack_ipv4_compat_init(void); 19int nf_conntrack_ipv4_compat_init(void);
20void nf_conntrack_ipv4_compat_fini(void); 20void nf_conntrack_ipv4_compat_fini(void);
21 21
22void need_ipv4_conntrack(void);
23
24#endif /*_NF_CONNTRACK_IPV4_H*/ 22#endif /*_NF_CONNTRACK_IPV4_H*/
diff --git a/include/net/netfilter/nf_conntrack_l3proto.h b/include/net/netfilter/nf_conntrack_l3proto.h
index 3efab704b7eb..adc1fa3dd7ab 100644
--- a/include/net/netfilter/nf_conntrack_l3proto.h
+++ b/include/net/netfilter/nf_conntrack_l3proto.h
@@ -87,7 +87,6 @@ int nf_ct_l3proto_register(struct nf_conntrack_l3proto *proto);
87void nf_ct_l3proto_unregister(struct nf_conntrack_l3proto *proto); 87void nf_ct_l3proto_unregister(struct nf_conntrack_l3proto *proto);
88 88
89struct nf_conntrack_l3proto *nf_ct_l3proto_find_get(u_int16_t l3proto); 89struct nf_conntrack_l3proto *nf_ct_l3proto_find_get(u_int16_t l3proto);
90void nf_ct_l3proto_put(struct nf_conntrack_l3proto *p);
91 90
92/* Existing built-in protocols */ 91/* Existing built-in protocols */
93extern struct nf_conntrack_l3proto nf_conntrack_l3proto_generic; 92extern struct nf_conntrack_l3proto nf_conntrack_l3proto_generic;
diff --git a/include/net/netns/conntrack.h b/include/net/netns/conntrack.h
index c9c0c538b68b..fbcc7fa536dc 100644
--- a/include/net/netns/conntrack.h
+++ b/include/net/netns/conntrack.h
@@ -65,6 +65,23 @@ struct nf_ip_net {
65struct netns_ct { 65struct netns_ct {
66 atomic_t count; 66 atomic_t count;
67 unsigned int expect_count; 67 unsigned int expect_count;
68#ifdef CONFIG_SYSCTL
69 struct ctl_table_header *sysctl_header;
70 struct ctl_table_header *acct_sysctl_header;
71 struct ctl_table_header *tstamp_sysctl_header;
72 struct ctl_table_header *event_sysctl_header;
73 struct ctl_table_header *helper_sysctl_header;
74#endif
75 char *slabname;
76 unsigned int sysctl_log_invalid; /* Log invalid packets */
77 unsigned int sysctl_events_retry_timeout;
78 int sysctl_events;
79 int sysctl_acct;
80 int sysctl_auto_assign_helper;
81 bool auto_assign_helper_warned;
82 int sysctl_tstamp;
83 int sysctl_checksum;
84
68 unsigned int htable_size; 85 unsigned int htable_size;
69 struct kmem_cache *nf_conntrack_cachep; 86 struct kmem_cache *nf_conntrack_cachep;
70 struct hlist_nulls_head *hash; 87 struct hlist_nulls_head *hash;
@@ -75,14 +92,6 @@ struct netns_ct {
75 struct ip_conntrack_stat __percpu *stat; 92 struct ip_conntrack_stat __percpu *stat;
76 struct nf_ct_event_notifier __rcu *nf_conntrack_event_cb; 93 struct nf_ct_event_notifier __rcu *nf_conntrack_event_cb;
77 struct nf_exp_event_notifier __rcu *nf_expect_event_cb; 94 struct nf_exp_event_notifier __rcu *nf_expect_event_cb;
78 int sysctl_events;
79 unsigned int sysctl_events_retry_timeout;
80 int sysctl_acct;
81 int sysctl_tstamp;
82 int sysctl_checksum;
83 unsigned int sysctl_log_invalid; /* Log invalid packets */
84 int sysctl_auto_assign_helper;
85 bool auto_assign_helper_warned;
86 struct nf_ip_net nf_ct_proto; 95 struct nf_ip_net nf_ct_proto;
87#if defined(CONFIG_NF_CONNTRACK_LABELS) 96#if defined(CONFIG_NF_CONNTRACK_LABELS)
88 unsigned int labels_used; 97 unsigned int labels_used;
@@ -92,13 +101,5 @@ struct netns_ct {
92 struct hlist_head *nat_bysource; 101 struct hlist_head *nat_bysource;
93 unsigned int nat_htable_size; 102 unsigned int nat_htable_size;
94#endif 103#endif
95#ifdef CONFIG_SYSCTL
96 struct ctl_table_header *sysctl_header;
97 struct ctl_table_header *acct_sysctl_header;
98 struct ctl_table_header *tstamp_sysctl_header;
99 struct ctl_table_header *event_sysctl_header;
100 struct ctl_table_header *helper_sysctl_header;
101#endif
102 char *slabname;
103}; 104};
104#endif 105#endif
diff --git a/include/net/netprio_cgroup.h b/include/net/netprio_cgroup.h
index 099d02782e22..dafc09f0fdbc 100644
--- a/include/net/netprio_cgroup.h
+++ b/include/net/netprio_cgroup.h
@@ -13,12 +13,12 @@
13 13
14#ifndef _NETPRIO_CGROUP_H 14#ifndef _NETPRIO_CGROUP_H
15#define _NETPRIO_CGROUP_H 15#define _NETPRIO_CGROUP_H
16
16#include <linux/cgroup.h> 17#include <linux/cgroup.h>
17#include <linux/hardirq.h> 18#include <linux/hardirq.h>
18#include <linux/rcupdate.h> 19#include <linux/rcupdate.h>
19 20
20 21#if IS_ENABLED(CONFIG_CGROUP_NET_PRIO)
21#if IS_ENABLED(CONFIG_NETPRIO_CGROUP)
22struct netprio_map { 22struct netprio_map {
23 struct rcu_head rcu; 23 struct rcu_head rcu;
24 u32 priomap_len; 24 u32 priomap_len;
@@ -27,8 +27,7 @@ struct netprio_map {
27 27
28void sock_update_netprioidx(struct sock *sk); 28void sock_update_netprioidx(struct sock *sk);
29 29
30#if IS_BUILTIN(CONFIG_NETPRIO_CGROUP) 30#if IS_BUILTIN(CONFIG_CGROUP_NET_PRIO)
31
32static inline u32 task_netprioidx(struct task_struct *p) 31static inline u32 task_netprioidx(struct task_struct *p)
33{ 32{
34 struct cgroup_subsys_state *css; 33 struct cgroup_subsys_state *css;
@@ -40,9 +39,7 @@ static inline u32 task_netprioidx(struct task_struct *p)
40 rcu_read_unlock(); 39 rcu_read_unlock();
41 return idx; 40 return idx;
42} 41}
43 42#elif IS_MODULE(CONFIG_CGROUP_NET_PRIO)
44#elif IS_MODULE(CONFIG_NETPRIO_CGROUP)
45
46static inline u32 task_netprioidx(struct task_struct *p) 43static inline u32 task_netprioidx(struct task_struct *p)
47{ 44{
48 struct cgroup_subsys_state *css; 45 struct cgroup_subsys_state *css;
@@ -56,9 +53,7 @@ static inline u32 task_netprioidx(struct task_struct *p)
56 return idx; 53 return idx;
57} 54}
58#endif 55#endif
59 56#else /* !CONFIG_CGROUP_NET_PRIO */
60#else /* !CONFIG_NETPRIO_CGROUP */
61
62static inline u32 task_netprioidx(struct task_struct *p) 57static inline u32 task_netprioidx(struct task_struct *p)
63{ 58{
64 return 0; 59 return 0;
@@ -66,6 +61,5 @@ static inline u32 task_netprioidx(struct task_struct *p)
66 61
67#define sock_update_netprioidx(sk) 62#define sock_update_netprioidx(sk)
68 63
69#endif /* CONFIG_NETPRIO_CGROUP */ 64#endif /* CONFIG_CGROUP_NET_PRIO */
70
71#endif /* _NET_CLS_CGROUP_H */ 65#endif /* _NET_CLS_CGROUP_H */
diff --git a/include/net/sock.h b/include/net/sock.h
index 8d9af66ccf2c..5c3f7c3624aa 100644
--- a/include/net/sock.h
+++ b/include/net/sock.h
@@ -395,7 +395,7 @@ struct sock {
395 unsigned short sk_ack_backlog; 395 unsigned short sk_ack_backlog;
396 unsigned short sk_max_ack_backlog; 396 unsigned short sk_max_ack_backlog;
397 __u32 sk_priority; 397 __u32 sk_priority;
398#if IS_ENABLED(CONFIG_NETPRIO_CGROUP) 398#if IS_ENABLED(CONFIG_CGROUP_NET_PRIO)
399 __u32 sk_cgrp_prioidx; 399 __u32 sk_cgrp_prioidx;
400#endif 400#endif
401 struct pid *sk_peer_pid; 401 struct pid *sk_peer_pid;
diff --git a/include/uapi/linux/netfilter/Kbuild b/include/uapi/linux/netfilter/Kbuild
index 17c3af2c4bb9..2344f5a319fc 100644
--- a/include/uapi/linux/netfilter/Kbuild
+++ b/include/uapi/linux/netfilter/Kbuild
@@ -39,6 +39,7 @@ header-y += xt_TEE.h
39header-y += xt_TPROXY.h 39header-y += xt_TPROXY.h
40header-y += xt_addrtype.h 40header-y += xt_addrtype.h
41header-y += xt_bpf.h 41header-y += xt_bpf.h
42header-y += xt_cgroup.h
42header-y += xt_cluster.h 43header-y += xt_cluster.h
43header-y += xt_comment.h 44header-y += xt_comment.h
44header-y += xt_connbytes.h 45header-y += xt_connbytes.h
@@ -54,6 +55,7 @@ header-y += xt_ecn.h
54header-y += xt_esp.h 55header-y += xt_esp.h
55header-y += xt_hashlimit.h 56header-y += xt_hashlimit.h
56header-y += xt_helper.h 57header-y += xt_helper.h
58header-y += xt_ipcomp.h
57header-y += xt_iprange.h 59header-y += xt_iprange.h
58header-y += xt_ipvs.h 60header-y += xt_ipvs.h
59header-y += xt_length.h 61header-y += xt_length.h
diff --git a/include/uapi/linux/netfilter/nf_nat.h b/include/uapi/linux/netfilter/nf_nat.h
index bf0cc373ffb6..1ad3659102b6 100644
--- a/include/uapi/linux/netfilter/nf_nat.h
+++ b/include/uapi/linux/netfilter/nf_nat.h
@@ -4,10 +4,14 @@
4#include <linux/netfilter.h> 4#include <linux/netfilter.h>
5#include <linux/netfilter/nf_conntrack_tuple_common.h> 5#include <linux/netfilter/nf_conntrack_tuple_common.h>
6 6
7#define NF_NAT_RANGE_MAP_IPS 1 7#define NF_NAT_RANGE_MAP_IPS (1 << 0)
8#define NF_NAT_RANGE_PROTO_SPECIFIED 2 8#define NF_NAT_RANGE_PROTO_SPECIFIED (1 << 1)
9#define NF_NAT_RANGE_PROTO_RANDOM 4 9#define NF_NAT_RANGE_PROTO_RANDOM (1 << 2)
10#define NF_NAT_RANGE_PERSISTENT 8 10#define NF_NAT_RANGE_PERSISTENT (1 << 3)
11#define NF_NAT_RANGE_PROTO_RANDOM_FULLY (1 << 4)
12
13#define NF_NAT_RANGE_PROTO_RANDOM_ALL \
14 (NF_NAT_RANGE_PROTO_RANDOM | NF_NAT_RANGE_PROTO_RANDOM_FULLY)
11 15
12struct nf_nat_ipv4_range { 16struct nf_nat_ipv4_range {
13 unsigned int flags; 17 unsigned int flags;
diff --git a/include/uapi/linux/netfilter/nfnetlink_queue.h b/include/uapi/linux/netfilter/nfnetlink_queue.h
index 0132bad79de7..8dd819e2b5fe 100644
--- a/include/uapi/linux/netfilter/nfnetlink_queue.h
+++ b/include/uapi/linux/netfilter/nfnetlink_queue.h
@@ -47,6 +47,8 @@ enum nfqnl_attr_type {
47 NFQA_CAP_LEN, /* __u32 length of captured packet */ 47 NFQA_CAP_LEN, /* __u32 length of captured packet */
48 NFQA_SKB_INFO, /* __u32 skb meta information */ 48 NFQA_SKB_INFO, /* __u32 skb meta information */
49 NFQA_EXP, /* nf_conntrack_netlink.h */ 49 NFQA_EXP, /* nf_conntrack_netlink.h */
50 NFQA_UID, /* __u32 sk uid */
51 NFQA_GID, /* __u32 sk gid */
50 52
51 __NFQA_MAX 53 __NFQA_MAX
52}; 54};
@@ -99,7 +101,8 @@ enum nfqnl_attr_config {
99#define NFQA_CFG_F_FAIL_OPEN (1 << 0) 101#define NFQA_CFG_F_FAIL_OPEN (1 << 0)
100#define NFQA_CFG_F_CONNTRACK (1 << 1) 102#define NFQA_CFG_F_CONNTRACK (1 << 1)
101#define NFQA_CFG_F_GSO (1 << 2) 103#define NFQA_CFG_F_GSO (1 << 2)
102#define NFQA_CFG_F_MAX (1 << 3) 104#define NFQA_CFG_F_UID_GID (1 << 3)
105#define NFQA_CFG_F_MAX (1 << 4)
103 106
104/* flags for NFQA_SKB_INFO */ 107/* flags for NFQA_SKB_INFO */
105/* packet appears to have wrong checksums, but they are ok */ 108/* packet appears to have wrong checksums, but they are ok */
diff --git a/include/uapi/linux/netfilter/xt_cgroup.h b/include/uapi/linux/netfilter/xt_cgroup.h
new file mode 100644
index 000000000000..43acb7e175f6
--- /dev/null
+++ b/include/uapi/linux/netfilter/xt_cgroup.h
@@ -0,0 +1,11 @@
1#ifndef _UAPI_XT_CGROUP_H
2#define _UAPI_XT_CGROUP_H
3
4#include <linux/types.h>
5
6struct xt_cgroup_info {
7 __u32 id;
8 __u32 invert;
9};
10
11#endif /* _UAPI_XT_CGROUP_H */
diff --git a/include/uapi/linux/netfilter/xt_ipcomp.h b/include/uapi/linux/netfilter/xt_ipcomp.h
new file mode 100644
index 000000000000..45c7e40eb8e1
--- /dev/null
+++ b/include/uapi/linux/netfilter/xt_ipcomp.h
@@ -0,0 +1,16 @@
1#ifndef _XT_IPCOMP_H
2#define _XT_IPCOMP_H
3
4#include <linux/types.h>
5
6struct xt_ipcomp {
7 __u32 spis[2]; /* Security Parameter Index */
8 __u8 invflags; /* Inverse flags */
9 __u8 hdrres; /* Test of the Reserved Filed */
10};
11
12/* Values for "invflags" field in struct xt_ipcomp. */
13#define XT_IPCOMP_INV_SPI 0x01 /* Invert the sense of spi. */
14#define XT_IPCOMP_INV_MASK 0x01 /* All possible flags. */
15
16#endif /*_XT_IPCOMP_H*/
diff --git a/net/Kconfig b/net/Kconfig
index d334678c0bd8..e411046a62e3 100644
--- a/net/Kconfig
+++ b/net/Kconfig
@@ -238,12 +238,19 @@ config XPS
238 depends on SMP 238 depends on SMP
239 default y 239 default y
240 240
241config NETPRIO_CGROUP 241config CGROUP_NET_PRIO
242 tristate "Network priority cgroup" 242 tristate "Network priority cgroup"
243 depends on CGROUPS 243 depends on CGROUPS
244 ---help--- 244 ---help---
245 Cgroup subsystem for use in assigning processes to network priorities on 245 Cgroup subsystem for use in assigning processes to network priorities on
246 a per-interface basis 246 a per-interface basis.
247
248config CGROUP_NET_CLASSID
249 boolean "Network classid cgroup"
250 depends on CGROUPS
251 ---help---
252 Cgroup subsystem for use as general purpose socket classid marker that is
253 being used in cls_cgroup and for netfilter matching.
247 254
248config NET_RX_BUSY_POLL 255config NET_RX_BUSY_POLL
249 boolean 256 boolean
diff --git a/net/core/Makefile b/net/core/Makefile
index b33b996f5dd6..9628c20acff6 100644
--- a/net/core/Makefile
+++ b/net/core/Makefile
@@ -21,4 +21,5 @@ obj-$(CONFIG_FIB_RULES) += fib_rules.o
21obj-$(CONFIG_TRACEPOINTS) += net-traces.o 21obj-$(CONFIG_TRACEPOINTS) += net-traces.o
22obj-$(CONFIG_NET_DROP_MONITOR) += drop_monitor.o 22obj-$(CONFIG_NET_DROP_MONITOR) += drop_monitor.o
23obj-$(CONFIG_NETWORK_PHY_TIMESTAMPING) += timestamping.o 23obj-$(CONFIG_NETWORK_PHY_TIMESTAMPING) += timestamping.o
24obj-$(CONFIG_NETPRIO_CGROUP) += netprio_cgroup.o 24obj-$(CONFIG_CGROUP_NET_PRIO) += netprio_cgroup.o
25obj-$(CONFIG_CGROUP_NET_CLASSID) += netclassid_cgroup.o
diff --git a/net/core/dev.c b/net/core/dev.c
index 77f43aa373fe..153ee2f8c33e 100644
--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -2741,7 +2741,7 @@ static inline int __dev_xmit_skb(struct sk_buff *skb, struct Qdisc *q,
2741 return rc; 2741 return rc;
2742} 2742}
2743 2743
2744#if IS_ENABLED(CONFIG_NETPRIO_CGROUP) 2744#if IS_ENABLED(CONFIG_CGROUP_NET_PRIO)
2745static void skb_update_prio(struct sk_buff *skb) 2745static void skb_update_prio(struct sk_buff *skb)
2746{ 2746{
2747 struct netprio_map *map = rcu_dereference_bh(skb->dev->priomap); 2747 struct netprio_map *map = rcu_dereference_bh(skb->dev->priomap);
diff --git a/net/core/netclassid_cgroup.c b/net/core/netclassid_cgroup.c
new file mode 100644
index 000000000000..719efd541668
--- /dev/null
+++ b/net/core/netclassid_cgroup.c
@@ -0,0 +1,120 @@
1/*
2 * net/core/netclassid_cgroup.c Classid Cgroupfs Handling
3 *
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License
6 * as published by the Free Software Foundation; either version
7 * 2 of the License, or (at your option) any later version.
8 *
9 * Authors: Thomas Graf <tgraf@suug.ch>
10 */
11
12#include <linux/module.h>
13#include <linux/slab.h>
14#include <linux/cgroup.h>
15#include <linux/fdtable.h>
16#include <net/cls_cgroup.h>
17#include <net/sock.h>
18
19static inline struct cgroup_cls_state *css_cls_state(struct cgroup_subsys_state *css)
20{
21 return css ? container_of(css, struct cgroup_cls_state, css) : NULL;
22}
23
24struct cgroup_cls_state *task_cls_state(struct task_struct *p)
25{
26 return css_cls_state(task_css(p, net_cls_subsys_id));
27}
28EXPORT_SYMBOL_GPL(task_cls_state);
29
30static struct cgroup_subsys_state *
31cgrp_css_alloc(struct cgroup_subsys_state *parent_css)
32{
33 struct cgroup_cls_state *cs;
34
35 cs = kzalloc(sizeof(*cs), GFP_KERNEL);
36 if (!cs)
37 return ERR_PTR(-ENOMEM);
38
39 return &cs->css;
40}
41
42static int cgrp_css_online(struct cgroup_subsys_state *css)
43{
44 struct cgroup_cls_state *cs = css_cls_state(css);
45 struct cgroup_cls_state *parent = css_cls_state(css_parent(css));
46
47 if (parent)
48 cs->classid = parent->classid;
49
50 return 0;
51}
52
53static void cgrp_css_free(struct cgroup_subsys_state *css)
54{
55 kfree(css_cls_state(css));
56}
57
58static int update_classid(const void *v, struct file *file, unsigned n)
59{
60 int err;
61 struct socket *sock = sock_from_file(file, &err);
62
63 if (sock)
64 sock->sk->sk_classid = (u32)(unsigned long)v;
65
66 return 0;
67}
68
69static void cgrp_attach(struct cgroup_subsys_state *css,
70 struct cgroup_taskset *tset)
71{
72 struct cgroup_cls_state *cs = css_cls_state(css);
73 void *v = (void *)(unsigned long)cs->classid;
74 struct task_struct *p;
75
76 cgroup_taskset_for_each(p, css, tset) {
77 task_lock(p);
78 iterate_fd(p->files, 0, update_classid, v);
79 task_unlock(p);
80 }
81}
82
83static u64 read_classid(struct cgroup_subsys_state *css, struct cftype *cft)
84{
85 return css_cls_state(css)->classid;
86}
87
88static int write_classid(struct cgroup_subsys_state *css, struct cftype *cft,
89 u64 value)
90{
91 css_cls_state(css)->classid = (u32) value;
92
93 return 0;
94}
95
96static struct cftype ss_files[] = {
97 {
98 .name = "classid",
99 .read_u64 = read_classid,
100 .write_u64 = write_classid,
101 },
102 { } /* terminate */
103};
104
105struct cgroup_subsys net_cls_subsys = {
106 .name = "net_cls",
107 .css_alloc = cgrp_css_alloc,
108 .css_online = cgrp_css_online,
109 .css_free = cgrp_css_free,
110 .attach = cgrp_attach,
111 .subsys_id = net_cls_subsys_id,
112 .base_cftypes = ss_files,
113 .module = THIS_MODULE,
114};
115
116static int __init init_netclassid_cgroup(void)
117{
118 return cgroup_load_subsys(&net_cls_subsys);
119}
120__initcall(init_netclassid_cgroup);
diff --git a/net/core/sock.c b/net/core/sock.c
index 0358855576a8..85ad6f0d3898 100644
--- a/net/core/sock.c
+++ b/net/core/sock.c
@@ -1307,19 +1307,7 @@ static void sk_prot_free(struct proto *prot, struct sock *sk)
1307 module_put(owner); 1307 module_put(owner);
1308} 1308}
1309 1309
1310#if IS_ENABLED(CONFIG_NET_CLS_CGROUP) 1310#if IS_ENABLED(CONFIG_CGROUP_NET_PRIO)
1311void sock_update_classid(struct sock *sk)
1312{
1313 u32 classid;
1314
1315 classid = task_cls_classid(current);
1316 if (classid != sk->sk_classid)
1317 sk->sk_classid = classid;
1318}
1319EXPORT_SYMBOL(sock_update_classid);
1320#endif
1321
1322#if IS_ENABLED(CONFIG_NETPRIO_CGROUP)
1323void sock_update_netprioidx(struct sock *sk) 1311void sock_update_netprioidx(struct sock *sk)
1324{ 1312{
1325 if (in_interrupt()) 1313 if (in_interrupt())
diff --git a/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c b/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c
index ecd8bec411c9..8127dc802865 100644
--- a/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c
+++ b/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c
@@ -548,9 +548,3 @@ static void __exit nf_conntrack_l3proto_ipv4_fini(void)
548 548
549module_init(nf_conntrack_l3proto_ipv4_init); 549module_init(nf_conntrack_l3proto_ipv4_init);
550module_exit(nf_conntrack_l3proto_ipv4_fini); 550module_exit(nf_conntrack_l3proto_ipv4_fini);
551
552void need_ipv4_conntrack(void)
553{
554 return;
555}
556EXPORT_SYMBOL_GPL(need_ipv4_conntrack);
diff --git a/net/netfilter/Kconfig b/net/netfilter/Kconfig
index c3398cd99b94..c17902cb5df9 100644
--- a/net/netfilter/Kconfig
+++ b/net/netfilter/Kconfig
@@ -858,6 +858,16 @@ config NETFILTER_XT_MATCH_BPF
858 858
859 To compile it as a module, choose M here. If unsure, say N. 859 To compile it as a module, choose M here. If unsure, say N.
860 860
861config NETFILTER_XT_MATCH_CGROUP
862 tristate '"control group" match support'
863 depends on NETFILTER_ADVANCED
864 depends on CGROUPS
865 select CGROUP_NET_CLASSID
866 ---help---
867 Socket/process control group matching allows you to match locally
868 generated packets based on which net_cls control group processes
869 belong to.
870
861config NETFILTER_XT_MATCH_CLUSTER 871config NETFILTER_XT_MATCH_CLUSTER
862 tristate '"cluster" match support' 872 tristate '"cluster" match support'
863 depends on NF_CONNTRACK 873 depends on NF_CONNTRACK
@@ -1035,6 +1045,15 @@ config NETFILTER_XT_MATCH_HL
1035 in the IPv6 header, or the time-to-live field in the IPv4 1045 in the IPv6 header, or the time-to-live field in the IPv4
1036 header of the packet. 1046 header of the packet.
1037 1047
1048config NETFILTER_XT_MATCH_IPCOMP
1049 tristate '"ipcomp" match support'
1050 depends on NETFILTER_ADVANCED
1051 help
1052 This match extension allows you to match a range of CPIs(16 bits)
1053 inside IPComp header of IPSec packets.
1054
1055 To compile it as a module, choose M here. If unsure, say N.
1056
1038config NETFILTER_XT_MATCH_IPRANGE 1057config NETFILTER_XT_MATCH_IPRANGE
1039 tristate '"iprange" address range match support' 1058 tristate '"iprange" address range match support'
1040 depends on NETFILTER_ADVANCED 1059 depends on NETFILTER_ADVANCED
diff --git a/net/netfilter/Makefile b/net/netfilter/Makefile
index 394483b2c193..407fc232f625 100644
--- a/net/netfilter/Makefile
+++ b/net/netfilter/Makefile
@@ -133,6 +133,7 @@ obj-$(CONFIG_NETFILTER_XT_MATCH_ESP) += xt_esp.o
133obj-$(CONFIG_NETFILTER_XT_MATCH_HASHLIMIT) += xt_hashlimit.o 133obj-$(CONFIG_NETFILTER_XT_MATCH_HASHLIMIT) += xt_hashlimit.o
134obj-$(CONFIG_NETFILTER_XT_MATCH_HELPER) += xt_helper.o 134obj-$(CONFIG_NETFILTER_XT_MATCH_HELPER) += xt_helper.o
135obj-$(CONFIG_NETFILTER_XT_MATCH_HL) += xt_hl.o 135obj-$(CONFIG_NETFILTER_XT_MATCH_HL) += xt_hl.o
136obj-$(CONFIG_NETFILTER_XT_MATCH_IPCOMP) += xt_ipcomp.o
136obj-$(CONFIG_NETFILTER_XT_MATCH_IPRANGE) += xt_iprange.o 137obj-$(CONFIG_NETFILTER_XT_MATCH_IPRANGE) += xt_iprange.o
137obj-$(CONFIG_NETFILTER_XT_MATCH_IPVS) += xt_ipvs.o 138obj-$(CONFIG_NETFILTER_XT_MATCH_IPVS) += xt_ipvs.o
138obj-$(CONFIG_NETFILTER_XT_MATCH_LENGTH) += xt_length.o 139obj-$(CONFIG_NETFILTER_XT_MATCH_LENGTH) += xt_length.o
@@ -142,6 +143,7 @@ obj-$(CONFIG_NETFILTER_XT_MATCH_MULTIPORT) += xt_multiport.o
142obj-$(CONFIG_NETFILTER_XT_MATCH_NFACCT) += xt_nfacct.o 143obj-$(CONFIG_NETFILTER_XT_MATCH_NFACCT) += xt_nfacct.o
143obj-$(CONFIG_NETFILTER_XT_MATCH_OSF) += xt_osf.o 144obj-$(CONFIG_NETFILTER_XT_MATCH_OSF) += xt_osf.o
144obj-$(CONFIG_NETFILTER_XT_MATCH_OWNER) += xt_owner.o 145obj-$(CONFIG_NETFILTER_XT_MATCH_OWNER) += xt_owner.o
146obj-$(CONFIG_NETFILTER_XT_MATCH_CGROUP) += xt_cgroup.o
145obj-$(CONFIG_NETFILTER_XT_MATCH_PHYSDEV) += xt_physdev.o 147obj-$(CONFIG_NETFILTER_XT_MATCH_PHYSDEV) += xt_physdev.o
146obj-$(CONFIG_NETFILTER_XT_MATCH_PKTTYPE) += xt_pkttype.o 148obj-$(CONFIG_NETFILTER_XT_MATCH_PKTTYPE) += xt_pkttype.o
147obj-$(CONFIG_NETFILTER_XT_MATCH_POLICY) += xt_policy.o 149obj-$(CONFIG_NETFILTER_XT_MATCH_POLICY) += xt_policy.o
diff --git a/net/netfilter/ipset/ip_set_core.c b/net/netfilter/ipset/ip_set_core.c
index bac7e01df67f..de770ec39e51 100644
--- a/net/netfilter/ipset/ip_set_core.c
+++ b/net/netfilter/ipset/ip_set_core.c
@@ -625,34 +625,6 @@ EXPORT_SYMBOL_GPL(ip_set_name_byindex);
625 */ 625 */
626 626
627/* 627/*
628 * Find set by name, reference it once. The reference makes sure the
629 * thing pointed to, does not go away under our feet.
630 *
631 * The nfnl mutex is used in the function.
632 */
633ip_set_id_t
634ip_set_nfnl_get(struct net *net, const char *name)
635{
636 ip_set_id_t i, index = IPSET_INVALID_ID;
637 struct ip_set *s;
638 struct ip_set_net *inst = ip_set_pernet(net);
639
640 nfnl_lock(NFNL_SUBSYS_IPSET);
641 for (i = 0; i < inst->ip_set_max; i++) {
642 s = nfnl_set(inst, i);
643 if (s != NULL && STREQ(s->name, name)) {
644 __ip_set_get(s);
645 index = i;
646 break;
647 }
648 }
649 nfnl_unlock(NFNL_SUBSYS_IPSET);
650
651 return index;
652}
653EXPORT_SYMBOL_GPL(ip_set_nfnl_get);
654
655/*
656 * Find set by index, reference it once. The reference makes sure the 628 * Find set by index, reference it once. The reference makes sure the
657 * thing pointed to, does not go away under our feet. 629 * thing pointed to, does not go away under our feet.
658 * 630 *
diff --git a/net/netfilter/ipvs/ip_vs_sync.c b/net/netfilter/ipvs/ip_vs_sync.c
index f63c2388f38d..db801263ee9f 100644
--- a/net/netfilter/ipvs/ip_vs_sync.c
+++ b/net/netfilter/ipvs/ip_vs_sync.c
@@ -1637,7 +1637,10 @@ static int sync_thread_master(void *data)
1637 continue; 1637 continue;
1638 } 1638 }
1639 while (ip_vs_send_sync_msg(tinfo->sock, sb->mesg) < 0) { 1639 while (ip_vs_send_sync_msg(tinfo->sock, sb->mesg) < 0) {
1640 int ret = __wait_event_interruptible(*sk_sleep(sk), 1640 /* (Ab)use interruptible sleep to avoid increasing
1641 * the load avg.
1642 */
1643 __wait_event_interruptible(*sk_sleep(sk),
1641 sock_writeable(sk) || 1644 sock_writeable(sk) ||
1642 kthread_should_stop()); 1645 kthread_should_stop());
1643 if (unlikely(kthread_should_stop())) 1646 if (unlikely(kthread_should_stop()))
diff --git a/net/netfilter/nf_conntrack_core.c b/net/netfilter/nf_conntrack_core.c
index 43549eb7a7be..8824ed0ccc9c 100644
--- a/net/netfilter/nf_conntrack_core.c
+++ b/net/netfilter/nf_conntrack_core.c
@@ -60,12 +60,6 @@ int (*nfnetlink_parse_nat_setup_hook)(struct nf_conn *ct,
60 const struct nlattr *attr) __read_mostly; 60 const struct nlattr *attr) __read_mostly;
61EXPORT_SYMBOL_GPL(nfnetlink_parse_nat_setup_hook); 61EXPORT_SYMBOL_GPL(nfnetlink_parse_nat_setup_hook);
62 62
63int (*nf_nat_seq_adjust_hook)(struct sk_buff *skb,
64 struct nf_conn *ct,
65 enum ip_conntrack_info ctinfo,
66 unsigned int protoff);
67EXPORT_SYMBOL_GPL(nf_nat_seq_adjust_hook);
68
69DEFINE_SPINLOCK(nf_conntrack_lock); 63DEFINE_SPINLOCK(nf_conntrack_lock);
70EXPORT_SYMBOL_GPL(nf_conntrack_lock); 64EXPORT_SYMBOL_GPL(nf_conntrack_lock);
71 65
@@ -361,15 +355,6 @@ begin:
361 return NULL; 355 return NULL;
362} 356}
363 357
364struct nf_conntrack_tuple_hash *
365__nf_conntrack_find(struct net *net, u16 zone,
366 const struct nf_conntrack_tuple *tuple)
367{
368 return ____nf_conntrack_find(net, zone, tuple,
369 hash_conntrack_raw(tuple, zone));
370}
371EXPORT_SYMBOL_GPL(__nf_conntrack_find);
372
373/* Find a connection corresponding to a tuple. */ 358/* Find a connection corresponding to a tuple. */
374static struct nf_conntrack_tuple_hash * 359static struct nf_conntrack_tuple_hash *
375__nf_conntrack_find_get(struct net *net, u16 zone, 360__nf_conntrack_find_get(struct net *net, u16 zone,
diff --git a/net/netfilter/nf_conntrack_netlink.c b/net/netfilter/nf_conntrack_netlink.c
index 08870b859046..bb322d0beb48 100644
--- a/net/netfilter/nf_conntrack_netlink.c
+++ b/net/netfilter/nf_conntrack_netlink.c
@@ -2118,8 +2118,16 @@ ctnetlink_nfqueue_parse_ct(const struct nlattr *cda[], struct nf_conn *ct)
2118 return err; 2118 return err;
2119 } 2119 }
2120#if defined(CONFIG_NF_CONNTRACK_MARK) 2120#if defined(CONFIG_NF_CONNTRACK_MARK)
2121 if (cda[CTA_MARK]) 2121 if (cda[CTA_MARK]) {
2122 ct->mark = ntohl(nla_get_be32(cda[CTA_MARK])); 2122 u32 mask = 0, mark, newmark;
2123 if (cda[CTA_MARK_MASK])
2124 mask = ~ntohl(nla_get_be32(cda[CTA_MARK_MASK]));
2125
2126 mark = ntohl(nla_get_be32(cda[CTA_MARK]));
2127 newmark = (ct->mark & mask) ^ mark;
2128 if (newmark != ct->mark)
2129 ct->mark = newmark;
2130 }
2123#endif 2131#endif
2124 return 0; 2132 return 0;
2125} 2133}
diff --git a/net/netfilter/nf_conntrack_proto.c b/net/netfilter/nf_conntrack_proto.c
index ce3004156eeb..b65d5864b6d9 100644
--- a/net/netfilter/nf_conntrack_proto.c
+++ b/net/netfilter/nf_conntrack_proto.c
@@ -92,12 +92,6 @@ nf_ct_l3proto_find_get(u_int16_t l3proto)
92} 92}
93EXPORT_SYMBOL_GPL(nf_ct_l3proto_find_get); 93EXPORT_SYMBOL_GPL(nf_ct_l3proto_find_get);
94 94
95void nf_ct_l3proto_put(struct nf_conntrack_l3proto *p)
96{
97 module_put(p->me);
98}
99EXPORT_SYMBOL_GPL(nf_ct_l3proto_put);
100
101int 95int
102nf_ct_l3proto_try_module_get(unsigned short l3proto) 96nf_ct_l3proto_try_module_get(unsigned short l3proto)
103{ 97{
diff --git a/net/netfilter/nf_nat_core.c b/net/netfilter/nf_nat_core.c
index 63a815402211..d3f5cd6dd962 100644
--- a/net/netfilter/nf_nat_core.c
+++ b/net/netfilter/nf_nat_core.c
@@ -315,7 +315,7 @@ get_unique_tuple(struct nf_conntrack_tuple *tuple,
315 * manips not an issue. 315 * manips not an issue.
316 */ 316 */
317 if (maniptype == NF_NAT_MANIP_SRC && 317 if (maniptype == NF_NAT_MANIP_SRC &&
318 !(range->flags & NF_NAT_RANGE_PROTO_RANDOM)) { 318 !(range->flags & NF_NAT_RANGE_PROTO_RANDOM_ALL)) {
319 /* try the original tuple first */ 319 /* try the original tuple first */
320 if (in_range(l3proto, l4proto, orig_tuple, range)) { 320 if (in_range(l3proto, l4proto, orig_tuple, range)) {
321 if (!nf_nat_used_tuple(orig_tuple, ct)) { 321 if (!nf_nat_used_tuple(orig_tuple, ct)) {
@@ -339,7 +339,7 @@ get_unique_tuple(struct nf_conntrack_tuple *tuple,
339 */ 339 */
340 340
341 /* Only bother mapping if it's not already in range and unique */ 341 /* Only bother mapping if it's not already in range and unique */
342 if (!(range->flags & NF_NAT_RANGE_PROTO_RANDOM)) { 342 if (!(range->flags & NF_NAT_RANGE_PROTO_RANDOM_ALL)) {
343 if (range->flags & NF_NAT_RANGE_PROTO_SPECIFIED) { 343 if (range->flags & NF_NAT_RANGE_PROTO_SPECIFIED) {
344 if (l4proto->in_range(tuple, maniptype, 344 if (l4proto->in_range(tuple, maniptype,
345 &range->min_proto, 345 &range->min_proto,
diff --git a/net/netfilter/nf_nat_proto_common.c b/net/netfilter/nf_nat_proto_common.c
index 9baaf734c142..83a72a235cae 100644
--- a/net/netfilter/nf_nat_proto_common.c
+++ b/net/netfilter/nf_nat_proto_common.c
@@ -74,22 +74,24 @@ void nf_nat_l4proto_unique_tuple(const struct nf_nat_l3proto *l3proto,
74 range_size = ntohs(range->max_proto.all) - min + 1; 74 range_size = ntohs(range->max_proto.all) - min + 1;
75 } 75 }
76 76
77 if (range->flags & NF_NAT_RANGE_PROTO_RANDOM) 77 if (range->flags & NF_NAT_RANGE_PROTO_RANDOM) {
78 off = l3proto->secure_port(tuple, maniptype == NF_NAT_MANIP_SRC 78 off = l3proto->secure_port(tuple, maniptype == NF_NAT_MANIP_SRC
79 ? tuple->dst.u.all 79 ? tuple->dst.u.all
80 : tuple->src.u.all); 80 : tuple->src.u.all);
81 else 81 } else if (range->flags & NF_NAT_RANGE_PROTO_RANDOM_FULLY) {
82 off = prandom_u32();
83 } else {
82 off = *rover; 84 off = *rover;
85 }
83 86
84 for (i = 0; ; ++off) { 87 for (i = 0; ; ++off) {
85 *portptr = htons(min + off % range_size); 88 *portptr = htons(min + off % range_size);
86 if (++i != range_size && nf_nat_used_tuple(tuple, ct)) 89 if (++i != range_size && nf_nat_used_tuple(tuple, ct))
87 continue; 90 continue;
88 if (!(range->flags & NF_NAT_RANGE_PROTO_RANDOM)) 91 if (!(range->flags & NF_NAT_RANGE_PROTO_RANDOM_ALL))
89 *rover = off; 92 *rover = off;
90 return; 93 return;
91 } 94 }
92 return;
93} 95}
94EXPORT_SYMBOL_GPL(nf_nat_l4proto_unique_tuple); 96EXPORT_SYMBOL_GPL(nf_nat_l4proto_unique_tuple);
95 97
diff --git a/net/netfilter/nfnetlink_log.c b/net/netfilter/nfnetlink_log.c
index 3c4b69e5fe17..7d4254b0dc6b 100644
--- a/net/netfilter/nfnetlink_log.c
+++ b/net/netfilter/nfnetlink_log.c
@@ -28,8 +28,6 @@
28#include <linux/proc_fs.h> 28#include <linux/proc_fs.h>
29#include <linux/security.h> 29#include <linux/security.h>
30#include <linux/list.h> 30#include <linux/list.h>
31#include <linux/jhash.h>
32#include <linux/random.h>
33#include <linux/slab.h> 31#include <linux/slab.h>
34#include <net/sock.h> 32#include <net/sock.h>
35#include <net/netfilter/nf_log.h> 33#include <net/netfilter/nf_log.h>
@@ -75,7 +73,6 @@ struct nfulnl_instance {
75}; 73};
76 74
77#define INSTANCE_BUCKETS 16 75#define INSTANCE_BUCKETS 16
78static unsigned int hash_init;
79 76
80static int nfnl_log_net_id __read_mostly; 77static int nfnl_log_net_id __read_mostly;
81 78
@@ -1066,11 +1063,6 @@ static int __init nfnetlink_log_init(void)
1066{ 1063{
1067 int status = -ENOMEM; 1064 int status = -ENOMEM;
1068 1065
1069 /* it's not really all that important to have a random value, so
1070 * we can do this from the init function, even if there hasn't
1071 * been that much entropy yet */
1072 get_random_bytes(&hash_init, sizeof(hash_init));
1073
1074 netlink_register_notifier(&nfulnl_rtnl_notifier); 1066 netlink_register_notifier(&nfulnl_rtnl_notifier);
1075 status = nfnetlink_subsys_register(&nfulnl_subsys); 1067 status = nfnetlink_subsys_register(&nfulnl_subsys);
1076 if (status < 0) { 1068 if (status < 0) {
diff --git a/net/netfilter/nfnetlink_queue_core.c b/net/netfilter/nfnetlink_queue_core.c
index 21258cf70091..d3cf12b83174 100644
--- a/net/netfilter/nfnetlink_queue_core.c
+++ b/net/netfilter/nfnetlink_queue_core.c
@@ -297,6 +297,31 @@ nfqnl_put_packet_info(struct sk_buff *nlskb, struct sk_buff *packet,
297 return flags ? nla_put_be32(nlskb, NFQA_SKB_INFO, htonl(flags)) : 0; 297 return flags ? nla_put_be32(nlskb, NFQA_SKB_INFO, htonl(flags)) : 0;
298} 298}
299 299
300static int nfqnl_put_sk_uidgid(struct sk_buff *skb, struct sock *sk)
301{
302 const struct cred *cred;
303
304 if (sk->sk_state == TCP_TIME_WAIT)
305 return 0;
306
307 read_lock_bh(&sk->sk_callback_lock);
308 if (sk->sk_socket && sk->sk_socket->file) {
309 cred = sk->sk_socket->file->f_cred;
310 if (nla_put_be32(skb, NFQA_UID,
311 htonl(from_kuid_munged(&init_user_ns, cred->fsuid))))
312 goto nla_put_failure;
313 if (nla_put_be32(skb, NFQA_GID,
314 htonl(from_kgid_munged(&init_user_ns, cred->fsgid))))
315 goto nla_put_failure;
316 }
317 read_unlock_bh(&sk->sk_callback_lock);
318 return 0;
319
320nla_put_failure:
321 read_unlock_bh(&sk->sk_callback_lock);
322 return -1;
323}
324
300static struct sk_buff * 325static struct sk_buff *
301nfqnl_build_packet_message(struct net *net, struct nfqnl_instance *queue, 326nfqnl_build_packet_message(struct net *net, struct nfqnl_instance *queue,
302 struct nf_queue_entry *entry, 327 struct nf_queue_entry *entry,
@@ -372,6 +397,11 @@ nfqnl_build_packet_message(struct net *net, struct nfqnl_instance *queue,
372 if (queue->flags & NFQA_CFG_F_CONNTRACK) 397 if (queue->flags & NFQA_CFG_F_CONNTRACK)
373 ct = nfqnl_ct_get(entskb, &size, &ctinfo); 398 ct = nfqnl_ct_get(entskb, &size, &ctinfo);
374 399
400 if (queue->flags & NFQA_CFG_F_UID_GID) {
401 size += (nla_total_size(sizeof(u_int32_t)) /* uid */
402 + nla_total_size(sizeof(u_int32_t))); /* gid */
403 }
404
375 skb = nfnetlink_alloc_skb(net, size, queue->peer_portid, 405 skb = nfnetlink_alloc_skb(net, size, queue->peer_portid,
376 GFP_ATOMIC); 406 GFP_ATOMIC);
377 if (!skb) 407 if (!skb)
@@ -484,6 +514,10 @@ nfqnl_build_packet_message(struct net *net, struct nfqnl_instance *queue,
484 goto nla_put_failure; 514 goto nla_put_failure;
485 } 515 }
486 516
517 if ((queue->flags & NFQA_CFG_F_UID_GID) && entskb->sk &&
518 nfqnl_put_sk_uidgid(skb, entskb->sk) < 0)
519 goto nla_put_failure;
520
487 if (ct && nfqnl_ct_put(skb, ct, ctinfo) < 0) 521 if (ct && nfqnl_ct_put(skb, ct, ctinfo) < 0)
488 goto nla_put_failure; 522 goto nla_put_failure;
489 523
diff --git a/net/netfilter/nft_hash.c b/net/netfilter/nft_hash.c
index 3d3f8fce10a5..6aae699aeb46 100644
--- a/net/netfilter/nft_hash.c
+++ b/net/netfilter/nft_hash.c
@@ -164,7 +164,7 @@ static int nft_hash_init(const struct nft_set *set,
164 unsigned int cnt, i; 164 unsigned int cnt, i;
165 165
166 if (unlikely(!nft_hash_rnd_initted)) { 166 if (unlikely(!nft_hash_rnd_initted)) {
167 get_random_bytes(&nft_hash_rnd, 4); 167 nft_hash_rnd = prandom_u32();
168 nft_hash_rnd_initted = true; 168 nft_hash_rnd_initted = true;
169 } 169 }
170 170
diff --git a/net/netfilter/xt_CT.c b/net/netfilter/xt_CT.c
index da35ac06a975..5929be622c5c 100644
--- a/net/netfilter/xt_CT.c
+++ b/net/netfilter/xt_CT.c
@@ -211,8 +211,10 @@ static int xt_ct_tg_check(const struct xt_tgchk_param *par,
211 ret = 0; 211 ret = 0;
212 if ((info->ct_events || info->exp_events) && 212 if ((info->ct_events || info->exp_events) &&
213 !nf_ct_ecache_ext_add(ct, info->ct_events, info->exp_events, 213 !nf_ct_ecache_ext_add(ct, info->ct_events, info->exp_events,
214 GFP_KERNEL)) 214 GFP_KERNEL)) {
215 ret = -EINVAL;
215 goto err3; 216 goto err3;
217 }
216 218
217 if (info->helper[0]) { 219 if (info->helper[0]) {
218 ret = xt_ct_set_helper(ct, info->helper, par); 220 ret = xt_ct_set_helper(ct, info->helper, par);
diff --git a/net/netfilter/xt_RATEEST.c b/net/netfilter/xt_RATEEST.c
index 370adf622cef..190854be7629 100644
--- a/net/netfilter/xt_RATEEST.c
+++ b/net/netfilter/xt_RATEEST.c
@@ -100,7 +100,7 @@ static int xt_rateest_tg_checkentry(const struct xt_tgchk_param *par)
100 int ret; 100 int ret;
101 101
102 if (unlikely(!rnd_inited)) { 102 if (unlikely(!rnd_inited)) {
103 get_random_bytes(&jhash_rnd, sizeof(jhash_rnd)); 103 jhash_rnd = prandom_u32();
104 rnd_inited = true; 104 rnd_inited = true;
105 } 105 }
106 106
diff --git a/net/netfilter/xt_cgroup.c b/net/netfilter/xt_cgroup.c
new file mode 100644
index 000000000000..9a8e77e7f8d4
--- /dev/null
+++ b/net/netfilter/xt_cgroup.c
@@ -0,0 +1,71 @@
1/*
2 * Xtables module to match the process control group.
3 *
4 * Might be used to implement individual "per-application" firewall
5 * policies in contrast to global policies based on control groups.
6 * Matching is based upon processes tagged to net_cls' classid marker.
7 *
8 * (C) 2013 Daniel Borkmann <dborkman@redhat.com>
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License version 2 as
12 * published by the Free Software Foundation.
13 */
14
15#include <linux/skbuff.h>
16#include <linux/module.h>
17#include <linux/netfilter/x_tables.h>
18#include <linux/netfilter/xt_cgroup.h>
19#include <net/sock.h>
20
21MODULE_LICENSE("GPL");
22MODULE_AUTHOR("Daniel Borkmann <dborkman@redhat.com>");
23MODULE_DESCRIPTION("Xtables: process control group matching");
24MODULE_ALIAS("ipt_cgroup");
25MODULE_ALIAS("ip6t_cgroup");
26
27static int cgroup_mt_check(const struct xt_mtchk_param *par)
28{
29 struct xt_cgroup_info *info = par->matchinfo;
30
31 if (info->invert & ~1)
32 return -EINVAL;
33
34 return info->id ? 0 : -EINVAL;
35}
36
37static bool
38cgroup_mt(const struct sk_buff *skb, struct xt_action_param *par)
39{
40 const struct xt_cgroup_info *info = par->matchinfo;
41
42 if (skb->sk == NULL)
43 return false;
44
45 return (info->id == skb->sk->sk_classid) ^ info->invert;
46}
47
48static struct xt_match cgroup_mt_reg __read_mostly = {
49 .name = "cgroup",
50 .revision = 0,
51 .family = NFPROTO_UNSPEC,
52 .checkentry = cgroup_mt_check,
53 .match = cgroup_mt,
54 .matchsize = sizeof(struct xt_cgroup_info),
55 .me = THIS_MODULE,
56 .hooks = (1 << NF_INET_LOCAL_OUT) |
57 (1 << NF_INET_POST_ROUTING),
58};
59
60static int __init cgroup_mt_init(void)
61{
62 return xt_register_match(&cgroup_mt_reg);
63}
64
65static void __exit cgroup_mt_exit(void)
66{
67 xt_unregister_match(&cgroup_mt_reg);
68}
69
70module_init(cgroup_mt_init);
71module_exit(cgroup_mt_exit);
diff --git a/net/netfilter/xt_connlimit.c b/net/netfilter/xt_connlimit.c
index c40b2695633b..7671e8214919 100644
--- a/net/netfilter/xt_connlimit.c
+++ b/net/netfilter/xt_connlimit.c
@@ -229,7 +229,7 @@ static int connlimit_mt_check(const struct xt_mtchk_param *par)
229 u_int32_t rand; 229 u_int32_t rand;
230 230
231 do { 231 do {
232 get_random_bytes(&rand, sizeof(rand)); 232 rand = prandom_u32();
233 } while (!rand); 233 } while (!rand);
234 cmpxchg(&connlimit_rnd, 0, rand); 234 cmpxchg(&connlimit_rnd, 0, rand);
235 } 235 }
diff --git a/net/netfilter/xt_hashlimit.c b/net/netfilter/xt_hashlimit.c
index a3910fc2122b..d819f62b3b7c 100644
--- a/net/netfilter/xt_hashlimit.c
+++ b/net/netfilter/xt_hashlimit.c
@@ -177,7 +177,7 @@ dsthash_alloc_init(struct xt_hashlimit_htable *ht,
177 /* initialize hash with random val at the time we allocate 177 /* initialize hash with random val at the time we allocate
178 * the first hashtable entry */ 178 * the first hashtable entry */
179 if (unlikely(!ht->rnd_initialized)) { 179 if (unlikely(!ht->rnd_initialized)) {
180 get_random_bytes(&ht->rnd, sizeof(ht->rnd)); 180 ht->rnd = prandom_u32();
181 ht->rnd_initialized = true; 181 ht->rnd_initialized = true;
182 } 182 }
183 183
diff --git a/net/netfilter/xt_ipcomp.c b/net/netfilter/xt_ipcomp.c
new file mode 100644
index 000000000000..a4c7561698c5
--- /dev/null
+++ b/net/netfilter/xt_ipcomp.c
@@ -0,0 +1,111 @@
1/* Kernel module to match IPComp parameters for IPv4 and IPv6
2 *
3 * Copyright (C) 2013 WindRiver
4 *
5 * Author:
6 * Fan Du <fan.du@windriver.com>
7 *
8 * Based on:
9 * net/netfilter/xt_esp.c
10 *
11 * This program is free software; you can redistribute it and/or
12 * modify it under the terms of the GNU General Public License
13 * as published by the Free Software Foundation; either version
14 * 2 of the License, or (at your option) any later version.
15 */
16
17#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
18#include <linux/in.h>
19#include <linux/module.h>
20#include <linux/skbuff.h>
21#include <linux/ip.h>
22
23#include <linux/netfilter/xt_ipcomp.h>
24#include <linux/netfilter/x_tables.h>
25
26MODULE_LICENSE("GPL");
27MODULE_AUTHOR("Fan Du <fan.du@windriver.com>");
28MODULE_DESCRIPTION("Xtables: IPv4/6 IPsec-IPComp SPI match");
29
30/* Returns 1 if the spi is matched by the range, 0 otherwise */
31static inline bool
32spi_match(u_int32_t min, u_int32_t max, u_int32_t spi, bool invert)
33{
34 bool r;
35 pr_debug("spi_match:%c 0x%x <= 0x%x <= 0x%x\n",
36 invert ? '!' : ' ', min, spi, max);
37 r = (spi >= min && spi <= max) ^ invert;
38 pr_debug(" result %s\n", r ? "PASS" : "FAILED");
39 return r;
40}
41
42static bool comp_mt(const struct sk_buff *skb, struct xt_action_param *par)
43{
44 struct ip_comp_hdr _comphdr;
45 const struct ip_comp_hdr *chdr;
46 const struct xt_ipcomp *compinfo = par->matchinfo;
47
48 /* Must not be a fragment. */
49 if (par->fragoff != 0)
50 return false;
51
52 chdr = skb_header_pointer(skb, par->thoff, sizeof(_comphdr), &_comphdr);
53 if (chdr == NULL) {
54 /* We've been asked to examine this packet, and we
55 * can't. Hence, no choice but to drop.
56 */
57 pr_debug("Dropping evil IPComp tinygram.\n");
58 par->hotdrop = true;
59 return 0;
60 }
61
62 return spi_match(compinfo->spis[0], compinfo->spis[1],
63 ntohl(chdr->cpi << 16),
64 !!(compinfo->invflags & XT_IPCOMP_INV_SPI));
65}
66
67static int comp_mt_check(const struct xt_mtchk_param *par)
68{
69 const struct xt_ipcomp *compinfo = par->matchinfo;
70
71 /* Must specify no unknown invflags */
72 if (compinfo->invflags & ~XT_IPCOMP_INV_MASK) {
73 pr_err("unknown flags %X\n", compinfo->invflags);
74 return -EINVAL;
75 }
76 return 0;
77}
78
79static struct xt_match comp_mt_reg[] __read_mostly = {
80 {
81 .name = "ipcomp",
82 .family = NFPROTO_IPV4,
83 .match = comp_mt,
84 .matchsize = sizeof(struct xt_ipcomp),
85 .proto = IPPROTO_COMP,
86 .checkentry = comp_mt_check,
87 .me = THIS_MODULE,
88 },
89 {
90 .name = "ipcomp",
91 .family = NFPROTO_IPV6,
92 .match = comp_mt,
93 .matchsize = sizeof(struct xt_ipcomp),
94 .proto = IPPROTO_COMP,
95 .checkentry = comp_mt_check,
96 .me = THIS_MODULE,
97 },
98};
99
100static int __init comp_mt_init(void)
101{
102 return xt_register_matches(comp_mt_reg, ARRAY_SIZE(comp_mt_reg));
103}
104
105static void __exit comp_mt_exit(void)
106{
107 xt_unregister_matches(comp_mt_reg, ARRAY_SIZE(comp_mt_reg));
108}
109
110module_init(comp_mt_init);
111module_exit(comp_mt_exit);
diff --git a/net/netfilter/xt_recent.c b/net/netfilter/xt_recent.c
index 1e657cf715c4..bfdc29f1a04a 100644
--- a/net/netfilter/xt_recent.c
+++ b/net/netfilter/xt_recent.c
@@ -334,7 +334,7 @@ static int recent_mt_check(const struct xt_mtchk_param *par,
334 size_t sz; 334 size_t sz;
335 335
336 if (unlikely(!hash_rnd_inited)) { 336 if (unlikely(!hash_rnd_inited)) {
337 get_random_bytes(&hash_rnd, sizeof(hash_rnd)); 337 hash_rnd = prandom_u32();
338 hash_rnd_inited = true; 338 hash_rnd_inited = true;
339 } 339 }
340 if (info->check_set & ~XT_RECENT_VALID_FLAGS) { 340 if (info->check_set & ~XT_RECENT_VALID_FLAGS) {
diff --git a/net/sched/Kconfig b/net/sched/Kconfig
index 919847beec39..d3d7a0a66e28 100644
--- a/net/sched/Kconfig
+++ b/net/sched/Kconfig
@@ -444,6 +444,7 @@ config NET_CLS_FLOW
444config NET_CLS_CGROUP 444config NET_CLS_CGROUP
445 tristate "Control Group Classifier" 445 tristate "Control Group Classifier"
446 select NET_CLS 446 select NET_CLS
447 select CGROUP_NET_CLASSID
447 depends on CGROUPS 448 depends on CGROUPS
448 ---help--- 449 ---help---
449 Say Y here if you want to classify packets based on the control 450 Say Y here if you want to classify packets based on the control
diff --git a/net/sched/cls_cgroup.c b/net/sched/cls_cgroup.c
index f9d212583ea2..8349fcdc50f3 100644
--- a/net/sched/cls_cgroup.c
+++ b/net/sched/cls_cgroup.c
@@ -11,109 +11,13 @@
11 11
12#include <linux/module.h> 12#include <linux/module.h>
13#include <linux/slab.h> 13#include <linux/slab.h>
14#include <linux/types.h>
15#include <linux/string.h>
16#include <linux/errno.h>
17#include <linux/skbuff.h> 14#include <linux/skbuff.h>
18#include <linux/cgroup.h>
19#include <linux/rcupdate.h> 15#include <linux/rcupdate.h>
20#include <linux/fdtable.h>
21#include <net/rtnetlink.h> 16#include <net/rtnetlink.h>
22#include <net/pkt_cls.h> 17#include <net/pkt_cls.h>
23#include <net/sock.h> 18#include <net/sock.h>
24#include <net/cls_cgroup.h> 19#include <net/cls_cgroup.h>
25 20
26static inline struct cgroup_cls_state *css_cls_state(struct cgroup_subsys_state *css)
27{
28 return css ? container_of(css, struct cgroup_cls_state, css) : NULL;
29}
30
31static inline struct cgroup_cls_state *task_cls_state(struct task_struct *p)
32{
33 return css_cls_state(task_css(p, net_cls_subsys_id));
34}
35
36static struct cgroup_subsys_state *
37cgrp_css_alloc(struct cgroup_subsys_state *parent_css)
38{
39 struct cgroup_cls_state *cs;
40
41 cs = kzalloc(sizeof(*cs), GFP_KERNEL);
42 if (!cs)
43 return ERR_PTR(-ENOMEM);
44 return &cs->css;
45}
46
47static int cgrp_css_online(struct cgroup_subsys_state *css)
48{
49 struct cgroup_cls_state *cs = css_cls_state(css);
50 struct cgroup_cls_state *parent = css_cls_state(css_parent(css));
51
52 if (parent)
53 cs->classid = parent->classid;
54 return 0;
55}
56
57static void cgrp_css_free(struct cgroup_subsys_state *css)
58{
59 kfree(css_cls_state(css));
60}
61
62static int update_classid(const void *v, struct file *file, unsigned n)
63{
64 int err;
65 struct socket *sock = sock_from_file(file, &err);
66 if (sock)
67 sock->sk->sk_classid = (u32)(unsigned long)v;
68 return 0;
69}
70
71static void cgrp_attach(struct cgroup_subsys_state *css,
72 struct cgroup_taskset *tset)
73{
74 struct task_struct *p;
75 struct cgroup_cls_state *cs = css_cls_state(css);
76 void *v = (void *)(unsigned long)cs->classid;
77
78 cgroup_taskset_for_each(p, css, tset) {
79 task_lock(p);
80 iterate_fd(p->files, 0, update_classid, v);
81 task_unlock(p);
82 }
83}
84
85static u64 read_classid(struct cgroup_subsys_state *css, struct cftype *cft)
86{
87 return css_cls_state(css)->classid;
88}
89
90static int write_classid(struct cgroup_subsys_state *css, struct cftype *cft,
91 u64 value)
92{
93 css_cls_state(css)->classid = (u32) value;
94 return 0;
95}
96
97static struct cftype ss_files[] = {
98 {
99 .name = "classid",
100 .read_u64 = read_classid,
101 .write_u64 = write_classid,
102 },
103 { } /* terminate */
104};
105
106struct cgroup_subsys net_cls_subsys = {
107 .name = "net_cls",
108 .css_alloc = cgrp_css_alloc,
109 .css_online = cgrp_css_online,
110 .css_free = cgrp_css_free,
111 .attach = cgrp_attach,
112 .subsys_id = net_cls_subsys_id,
113 .base_cftypes = ss_files,
114 .module = THIS_MODULE,
115};
116
117struct cls_cgroup_head { 21struct cls_cgroup_head {
118 u32 handle; 22 u32 handle;
119 struct tcf_exts exts; 23 struct tcf_exts exts;
@@ -305,25 +209,12 @@ static struct tcf_proto_ops cls_cgroup_ops __read_mostly = {
305 209
306static int __init init_cgroup_cls(void) 210static int __init init_cgroup_cls(void)
307{ 211{
308 int ret; 212 return register_tcf_proto_ops(&cls_cgroup_ops);
309
310 ret = cgroup_load_subsys(&net_cls_subsys);
311 if (ret)
312 goto out;
313
314 ret = register_tcf_proto_ops(&cls_cgroup_ops);
315 if (ret)
316 cgroup_unload_subsys(&net_cls_subsys);
317
318out:
319 return ret;
320} 213}
321 214
322static void __exit exit_cgroup_cls(void) 215static void __exit exit_cgroup_cls(void)
323{ 216{
324 unregister_tcf_proto_ops(&cls_cgroup_ops); 217 unregister_tcf_proto_ops(&cls_cgroup_ops);
325
326 cgroup_unload_subsys(&net_cls_subsys);
327} 218}
328 219
329module_init(init_cgroup_cls); 220module_init(init_cgroup_cls);