diff options
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 | ||
| 7 | The Traffic Controller (tc) can be used to assign | 7 | The Traffic Controller (tc) can be used to assign |
| 8 | different priorities to packets from different cgroups. | 8 | different priorities to packets from different cgroups. |
| 9 | Also, Netfilter (iptables) can use this tag to perform | ||
| 10 | actions on such packets. | ||
| 9 | 11 | ||
| 10 | Creating a net_cls cgroups instance creates a net_cls.classid file. | 12 | Creating a net_cls cgroups instance creates a net_cls.classid file. |
| 11 | This net_cls.classid value is initialized to 0. | 13 | This 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 | ||
| 34 | tc filter add dev eth0 parent 10: protocol ip prio 10 handle 1: cgroup | 36 | tc filter add dev eth0 parent 10: protocol ip prio 10 handle 1: cgroup |
| 37 | |||
| 38 | configuring iptables, basic example: | ||
| 39 | iptables -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) | |||
| 31 | SUBSYS(freezer) | 31 | SUBSYS(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) |
| 35 | SUBSYS(net_cls) | 35 | SUBSYS(net_cls) |
| 36 | #endif | 36 | #endif |
| 37 | 37 | ||
| @@ -43,7 +43,7 @@ SUBSYS(blkio) | |||
| 43 | SUBSYS(perf) | 43 | SUBSYS(perf) |
| 44 | #endif | 44 | #endif |
| 45 | 45 | ||
| 46 | #if IS_SUBSYS_ENABLED(CONFIG_NETPRIO_CGROUP) | 46 | #if IS_SUBSYS_ENABLED(CONFIG_CGROUP_NET_PRIO) |
| 47 | SUBSYS(net_prio) | 47 | SUBSYS(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); |
| 332 | extern void ip_set_put_byindex(struct net *net, ip_set_id_t index); | 332 | extern void ip_set_put_byindex(struct net *net, ip_set_id_t index); |
| 333 | extern const char *ip_set_name_byindex(struct net *net, ip_set_id_t index); | 333 | extern const char *ip_set_name_byindex(struct net *net, ip_set_id_t index); |
| 334 | extern ip_set_id_t ip_set_nfnl_get(struct net *net, const char *name); | ||
| 335 | extern ip_set_id_t ip_set_nfnl_get_byindex(struct net *net, ip_set_id_t index); | 334 | extern ip_set_id_t ip_set_nfnl_get_byindex(struct net *net, ip_set_id_t index); |
| 336 | extern void ip_set_nfnl_put(struct net *net, ip_set_id_t index); | 335 | extern 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 |
| 21 | struct cgroup_cls_state | 22 | struct 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 | ||
| 27 | void sock_update_classid(struct sock *sk); | 27 | struct cgroup_cls_state *task_cls_state(struct task_struct *p); |
| 28 | 28 | ||
| 29 | #if IS_BUILTIN(CONFIG_NET_CLS_CGROUP) | ||
| 30 | static inline u32 task_cls_classid(struct task_struct *p) | 29 | static 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) | ||
| 45 | static 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 */ | ||
| 64 | static inline void sock_update_classid(struct sock *sk) | 44 | static inline void sock_update_classid(struct sock *sk) |
| 65 | { | 45 | { |
| 66 | } | 46 | u32 classid; |
| 67 | 47 | ||
| 68 | static 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 */ | ||
| 53 | static 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; | |||
| 19 | int nf_conntrack_ipv4_compat_init(void); | 19 | int nf_conntrack_ipv4_compat_init(void); |
| 20 | void nf_conntrack_ipv4_compat_fini(void); | 20 | void nf_conntrack_ipv4_compat_fini(void); |
| 21 | 21 | ||
| 22 | void 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); | |||
| 87 | void nf_ct_l3proto_unregister(struct nf_conntrack_l3proto *proto); | 87 | void nf_ct_l3proto_unregister(struct nf_conntrack_l3proto *proto); |
| 88 | 88 | ||
| 89 | struct nf_conntrack_l3proto *nf_ct_l3proto_find_get(u_int16_t l3proto); | 89 | struct nf_conntrack_l3proto *nf_ct_l3proto_find_get(u_int16_t l3proto); |
| 90 | void nf_ct_l3proto_put(struct nf_conntrack_l3proto *p); | ||
| 91 | 90 | ||
| 92 | /* Existing built-in protocols */ | 91 | /* Existing built-in protocols */ |
| 93 | extern struct nf_conntrack_l3proto nf_conntrack_l3proto_generic; | 92 | extern 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 { | |||
| 65 | struct netns_ct { | 65 | struct 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) | ||
| 22 | struct netprio_map { | 22 | struct 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 | ||
| 28 | void sock_update_netprioidx(struct sock *sk); | 28 | void sock_update_netprioidx(struct sock *sk); |
| 29 | 29 | ||
| 30 | #if IS_BUILTIN(CONFIG_NETPRIO_CGROUP) | 30 | #if IS_BUILTIN(CONFIG_CGROUP_NET_PRIO) |
| 31 | |||
| 32 | static inline u32 task_netprioidx(struct task_struct *p) | 31 | static 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 | |||
| 46 | static inline u32 task_netprioidx(struct task_struct *p) | 43 | static 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 | |||
| 62 | static inline u32 task_netprioidx(struct task_struct *p) | 57 | static 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 | |||
| 39 | header-y += xt_TPROXY.h | 39 | header-y += xt_TPROXY.h |
| 40 | header-y += xt_addrtype.h | 40 | header-y += xt_addrtype.h |
| 41 | header-y += xt_bpf.h | 41 | header-y += xt_bpf.h |
| 42 | header-y += xt_cgroup.h | ||
| 42 | header-y += xt_cluster.h | 43 | header-y += xt_cluster.h |
| 43 | header-y += xt_comment.h | 44 | header-y += xt_comment.h |
| 44 | header-y += xt_connbytes.h | 45 | header-y += xt_connbytes.h |
| @@ -54,6 +55,7 @@ header-y += xt_ecn.h | |||
| 54 | header-y += xt_esp.h | 55 | header-y += xt_esp.h |
| 55 | header-y += xt_hashlimit.h | 56 | header-y += xt_hashlimit.h |
| 56 | header-y += xt_helper.h | 57 | header-y += xt_helper.h |
| 58 | header-y += xt_ipcomp.h | ||
| 57 | header-y += xt_iprange.h | 59 | header-y += xt_iprange.h |
| 58 | header-y += xt_ipvs.h | 60 | header-y += xt_ipvs.h |
| 59 | header-y += xt_length.h | 61 | header-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 | ||
| 12 | struct nf_nat_ipv4_range { | 16 | struct 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 | |||
| 6 | struct 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 | |||
| 6 | struct 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 | ||
| 241 | config NETPRIO_CGROUP | 241 | config 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 | |||
| 248 | config 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 | ||
| 248 | config NET_RX_BUSY_POLL | 255 | config 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 | |||
| 21 | obj-$(CONFIG_TRACEPOINTS) += net-traces.o | 21 | obj-$(CONFIG_TRACEPOINTS) += net-traces.o |
| 22 | obj-$(CONFIG_NET_DROP_MONITOR) += drop_monitor.o | 22 | obj-$(CONFIG_NET_DROP_MONITOR) += drop_monitor.o |
| 23 | obj-$(CONFIG_NETWORK_PHY_TIMESTAMPING) += timestamping.o | 23 | obj-$(CONFIG_NETWORK_PHY_TIMESTAMPING) += timestamping.o |
| 24 | obj-$(CONFIG_NETPRIO_CGROUP) += netprio_cgroup.o | 24 | obj-$(CONFIG_CGROUP_NET_PRIO) += netprio_cgroup.o |
| 25 | obj-$(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) |
| 2745 | static void skb_update_prio(struct sk_buff *skb) | 2745 | static 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 | |||
| 19 | static 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 | |||
| 24 | struct cgroup_cls_state *task_cls_state(struct task_struct *p) | ||
| 25 | { | ||
| 26 | return css_cls_state(task_css(p, net_cls_subsys_id)); | ||
| 27 | } | ||
| 28 | EXPORT_SYMBOL_GPL(task_cls_state); | ||
| 29 | |||
| 30 | static struct cgroup_subsys_state * | ||
| 31 | cgrp_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 | |||
| 42 | static 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 | |||
| 53 | static void cgrp_css_free(struct cgroup_subsys_state *css) | ||
| 54 | { | ||
| 55 | kfree(css_cls_state(css)); | ||
| 56 | } | ||
| 57 | |||
| 58 | static 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 | |||
| 69 | static 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 | |||
| 83 | static u64 read_classid(struct cgroup_subsys_state *css, struct cftype *cft) | ||
| 84 | { | ||
| 85 | return css_cls_state(css)->classid; | ||
| 86 | } | ||
| 87 | |||
| 88 | static 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 | |||
| 96 | static struct cftype ss_files[] = { | ||
| 97 | { | ||
| 98 | .name = "classid", | ||
| 99 | .read_u64 = read_classid, | ||
| 100 | .write_u64 = write_classid, | ||
| 101 | }, | ||
| 102 | { } /* terminate */ | ||
| 103 | }; | ||
| 104 | |||
| 105 | struct 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 | |||
| 116 | static 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) |
| 1311 | void 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 | } | ||
| 1319 | EXPORT_SYMBOL(sock_update_classid); | ||
| 1320 | #endif | ||
| 1321 | |||
| 1322 | #if IS_ENABLED(CONFIG_NETPRIO_CGROUP) | ||
| 1323 | void sock_update_netprioidx(struct sock *sk) | 1311 | void 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 | ||
| 549 | module_init(nf_conntrack_l3proto_ipv4_init); | 549 | module_init(nf_conntrack_l3proto_ipv4_init); |
| 550 | module_exit(nf_conntrack_l3proto_ipv4_fini); | 550 | module_exit(nf_conntrack_l3proto_ipv4_fini); |
| 551 | |||
| 552 | void need_ipv4_conntrack(void) | ||
| 553 | { | ||
| 554 | return; | ||
| 555 | } | ||
| 556 | EXPORT_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 | ||
| 861 | config 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 | |||
| 861 | config NETFILTER_XT_MATCH_CLUSTER | 871 | config 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 | ||
| 1048 | config 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 | |||
| 1038 | config NETFILTER_XT_MATCH_IPRANGE | 1057 | config 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 | |||
| 133 | obj-$(CONFIG_NETFILTER_XT_MATCH_HASHLIMIT) += xt_hashlimit.o | 133 | obj-$(CONFIG_NETFILTER_XT_MATCH_HASHLIMIT) += xt_hashlimit.o |
| 134 | obj-$(CONFIG_NETFILTER_XT_MATCH_HELPER) += xt_helper.o | 134 | obj-$(CONFIG_NETFILTER_XT_MATCH_HELPER) += xt_helper.o |
| 135 | obj-$(CONFIG_NETFILTER_XT_MATCH_HL) += xt_hl.o | 135 | obj-$(CONFIG_NETFILTER_XT_MATCH_HL) += xt_hl.o |
| 136 | obj-$(CONFIG_NETFILTER_XT_MATCH_IPCOMP) += xt_ipcomp.o | ||
| 136 | obj-$(CONFIG_NETFILTER_XT_MATCH_IPRANGE) += xt_iprange.o | 137 | obj-$(CONFIG_NETFILTER_XT_MATCH_IPRANGE) += xt_iprange.o |
| 137 | obj-$(CONFIG_NETFILTER_XT_MATCH_IPVS) += xt_ipvs.o | 138 | obj-$(CONFIG_NETFILTER_XT_MATCH_IPVS) += xt_ipvs.o |
| 138 | obj-$(CONFIG_NETFILTER_XT_MATCH_LENGTH) += xt_length.o | 139 | obj-$(CONFIG_NETFILTER_XT_MATCH_LENGTH) += xt_length.o |
| @@ -142,6 +143,7 @@ obj-$(CONFIG_NETFILTER_XT_MATCH_MULTIPORT) += xt_multiport.o | |||
| 142 | obj-$(CONFIG_NETFILTER_XT_MATCH_NFACCT) += xt_nfacct.o | 143 | obj-$(CONFIG_NETFILTER_XT_MATCH_NFACCT) += xt_nfacct.o |
| 143 | obj-$(CONFIG_NETFILTER_XT_MATCH_OSF) += xt_osf.o | 144 | obj-$(CONFIG_NETFILTER_XT_MATCH_OSF) += xt_osf.o |
| 144 | obj-$(CONFIG_NETFILTER_XT_MATCH_OWNER) += xt_owner.o | 145 | obj-$(CONFIG_NETFILTER_XT_MATCH_OWNER) += xt_owner.o |
| 146 | obj-$(CONFIG_NETFILTER_XT_MATCH_CGROUP) += xt_cgroup.o | ||
| 145 | obj-$(CONFIG_NETFILTER_XT_MATCH_PHYSDEV) += xt_physdev.o | 147 | obj-$(CONFIG_NETFILTER_XT_MATCH_PHYSDEV) += xt_physdev.o |
| 146 | obj-$(CONFIG_NETFILTER_XT_MATCH_PKTTYPE) += xt_pkttype.o | 148 | obj-$(CONFIG_NETFILTER_XT_MATCH_PKTTYPE) += xt_pkttype.o |
| 147 | obj-$(CONFIG_NETFILTER_XT_MATCH_POLICY) += xt_policy.o | 149 | obj-$(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 | */ | ||
| 633 | ip_set_id_t | ||
| 634 | ip_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 | } | ||
| 653 | EXPORT_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; |
| 61 | EXPORT_SYMBOL_GPL(nfnetlink_parse_nat_setup_hook); | 61 | EXPORT_SYMBOL_GPL(nfnetlink_parse_nat_setup_hook); |
| 62 | 62 | ||
| 63 | int (*nf_nat_seq_adjust_hook)(struct sk_buff *skb, | ||
| 64 | struct nf_conn *ct, | ||
| 65 | enum ip_conntrack_info ctinfo, | ||
| 66 | unsigned int protoff); | ||
| 67 | EXPORT_SYMBOL_GPL(nf_nat_seq_adjust_hook); | ||
| 68 | |||
| 69 | DEFINE_SPINLOCK(nf_conntrack_lock); | 63 | DEFINE_SPINLOCK(nf_conntrack_lock); |
| 70 | EXPORT_SYMBOL_GPL(nf_conntrack_lock); | 64 | EXPORT_SYMBOL_GPL(nf_conntrack_lock); |
| 71 | 65 | ||
| @@ -361,15 +355,6 @@ begin: | |||
| 361 | return NULL; | 355 | return NULL; |
| 362 | } | 356 | } |
| 363 | 357 | ||
| 364 | struct 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 | } | ||
| 371 | EXPORT_SYMBOL_GPL(__nf_conntrack_find); | ||
| 372 | |||
| 373 | /* Find a connection corresponding to a tuple. */ | 358 | /* Find a connection corresponding to a tuple. */ |
| 374 | static struct nf_conntrack_tuple_hash * | 359 | static 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 | } |
| 93 | EXPORT_SYMBOL_GPL(nf_ct_l3proto_find_get); | 93 | EXPORT_SYMBOL_GPL(nf_ct_l3proto_find_get); |
| 94 | 94 | ||
| 95 | void nf_ct_l3proto_put(struct nf_conntrack_l3proto *p) | ||
| 96 | { | ||
| 97 | module_put(p->me); | ||
| 98 | } | ||
| 99 | EXPORT_SYMBOL_GPL(nf_ct_l3proto_put); | ||
| 100 | |||
| 101 | int | 95 | int |
| 102 | nf_ct_l3proto_try_module_get(unsigned short l3proto) | 96 | nf_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 | } |
| 94 | EXPORT_SYMBOL_GPL(nf_nat_l4proto_unique_tuple); | 96 | EXPORT_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 |
| 78 | static unsigned int hash_init; | ||
| 79 | 76 | ||
| 80 | static int nfnl_log_net_id __read_mostly; | 77 | static 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 | ||
| 300 | static 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 | |||
| 320 | nla_put_failure: | ||
| 321 | read_unlock_bh(&sk->sk_callback_lock); | ||
| 322 | return -1; | ||
| 323 | } | ||
| 324 | |||
| 300 | static struct sk_buff * | 325 | static struct sk_buff * |
| 301 | nfqnl_build_packet_message(struct net *net, struct nfqnl_instance *queue, | 326 | nfqnl_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 | |||
| 21 | MODULE_LICENSE("GPL"); | ||
| 22 | MODULE_AUTHOR("Daniel Borkmann <dborkman@redhat.com>"); | ||
| 23 | MODULE_DESCRIPTION("Xtables: process control group matching"); | ||
| 24 | MODULE_ALIAS("ipt_cgroup"); | ||
| 25 | MODULE_ALIAS("ip6t_cgroup"); | ||
| 26 | |||
| 27 | static 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 | |||
| 37 | static bool | ||
| 38 | cgroup_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 | |||
| 48 | static 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 | |||
| 60 | static int __init cgroup_mt_init(void) | ||
| 61 | { | ||
| 62 | return xt_register_match(&cgroup_mt_reg); | ||
| 63 | } | ||
| 64 | |||
| 65 | static void __exit cgroup_mt_exit(void) | ||
| 66 | { | ||
| 67 | xt_unregister_match(&cgroup_mt_reg); | ||
| 68 | } | ||
| 69 | |||
| 70 | module_init(cgroup_mt_init); | ||
| 71 | module_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 | |||
| 26 | MODULE_LICENSE("GPL"); | ||
| 27 | MODULE_AUTHOR("Fan Du <fan.du@windriver.com>"); | ||
| 28 | MODULE_DESCRIPTION("Xtables: IPv4/6 IPsec-IPComp SPI match"); | ||
| 29 | |||
| 30 | /* Returns 1 if the spi is matched by the range, 0 otherwise */ | ||
| 31 | static inline bool | ||
| 32 | spi_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 | |||
| 42 | static 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 | |||
| 67 | static 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 | |||
| 79 | static 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 | |||
| 100 | static int __init comp_mt_init(void) | ||
| 101 | { | ||
| 102 | return xt_register_matches(comp_mt_reg, ARRAY_SIZE(comp_mt_reg)); | ||
| 103 | } | ||
| 104 | |||
| 105 | static void __exit comp_mt_exit(void) | ||
| 106 | { | ||
| 107 | xt_unregister_matches(comp_mt_reg, ARRAY_SIZE(comp_mt_reg)); | ||
| 108 | } | ||
| 109 | |||
| 110 | module_init(comp_mt_init); | ||
| 111 | module_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 | |||
| 444 | config NET_CLS_CGROUP | 444 | config 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 | ||
| 26 | static 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 | |||
| 31 | static 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 | |||
| 36 | static struct cgroup_subsys_state * | ||
| 37 | cgrp_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 | |||
| 47 | static 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 | |||
| 57 | static void cgrp_css_free(struct cgroup_subsys_state *css) | ||
| 58 | { | ||
| 59 | kfree(css_cls_state(css)); | ||
| 60 | } | ||
| 61 | |||
| 62 | static 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 | |||
| 71 | static 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 | |||
| 85 | static u64 read_classid(struct cgroup_subsys_state *css, struct cftype *cft) | ||
| 86 | { | ||
| 87 | return css_cls_state(css)->classid; | ||
| 88 | } | ||
| 89 | |||
| 90 | static 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 | |||
| 97 | static struct cftype ss_files[] = { | ||
| 98 | { | ||
| 99 | .name = "classid", | ||
| 100 | .read_u64 = read_classid, | ||
| 101 | .write_u64 = write_classid, | ||
| 102 | }, | ||
| 103 | { } /* terminate */ | ||
| 104 | }; | ||
| 105 | |||
| 106 | struct 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 | |||
| 117 | struct cls_cgroup_head { | 21 | struct 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 | ||
| 306 | static int __init init_cgroup_cls(void) | 210 | static 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 | |||
| 318 | out: | ||
| 319 | return ret; | ||
| 320 | } | 213 | } |
| 321 | 214 | ||
| 322 | static void __exit exit_cgroup_cls(void) | 215 | static 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 | ||
| 329 | module_init(init_cgroup_cls); | 220 | module_init(init_cgroup_cls); |
