Pablo Neira Ayuso says: ==================== netfilter/IPVS updates for net-next The following patchset contains Netfilter updates for your net-next tree, they are: * Add full port randomization support. Some crazy researchers found a way to reconstruct the secure ephemeral ports that are allocated in random mode by sending off-path bursts of UDP packets to overrun the socket buffer of the DNS resolver to trigger retransmissions, then if the timing for the DNS resolution done by a client is larger than usual, then they conclude that the port that received the burst of UDP packets is the one that was opened. It seems a bit aggressive method to me but it seems to work for them. As a result, Daniel Borkmann and Hannes Frederic Sowa came up with a new NAT mode to fully randomize ports using prandom. * Add a new classifier to x_tables based on the socket net_cls set via cgroups. These includes two patches to prepare the field as requested by Zefan Li. Also from Daniel Borkmann. * Use prandom instead of get_random_bytes in several locations of the netfilter code, from Florian Westphal. * Allow to use the CTA_MARK_MASK in ctnetlink when mangling the conntrack mark, also from Florian Westphal. * Fix compilation warning due to unused variable in IPVS, from Geert Uytterhoeven. * Add support for UID/GID via nfnetlink_queue, from Valentina Giusti. * Add IPComp extension to x_tables, from Fan Du. ====================
Unified · Split
| @@ -6,6 +6,8 @@ tag network packets with a class identifier (classid). · 5 unmodified lines | ||
| 6 | 6 | |
| 7 | 7 | The Traffic Controller (tc) can be used to assign |
| 8 | 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 | 12 | Creating a net_cls cgroups instance creates a net_cls.classid file. |
| 11 | 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 · 20 unmodified lines | ||
| 32 | 34 | - creating traffic class 10:1 |
| 33 | 35 | |
| 34 | 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 | |
| @@ -31,7 +31,7 @@ SUBSYS(devices) · 30 unmodified lines | ||
| 31 | 31 | SUBSYS(freezer) |
| 32 | 32 | #endif |
| 33 | 33 | |
| 34 | −#if IS_SUBSYS_ENABLED(CONFIG_NET_CLS_CGROUP) | |
| 34 | +#if IS_SUBSYS_ENABLED(CONFIG_CGROUP_NET_CLASSID) | |
| 35 | 35 | SUBSYS(net_cls) |
| 36 | 36 | #endif |
| 37 | 37 | |
| @@ -43,7 +43,7 @@ SUBSYS(blkio) · 5 unmodified lines | ||
| 43 | 43 | SUBSYS(perf) |
| 44 | 44 | #endif |
| 45 | 45 | |
| 46 | −#if IS_SUBSYS_ENABLED(CONFIG_NETPRIO_CGROUP) | |
| 46 | +#if IS_SUBSYS_ENABLED(CONFIG_CGROUP_NET_PRIO) | |
| 47 | 47 | SUBSYS(net_prio) |
| 48 | 48 | #endif |
| 49 | 49 | |
| @@ -1444,7 +1444,7 @@ struct net_device { · 1443 unmodified lines | ||
| 1444 | 1444 | /* max exchange id for FCoE LRO by ddp */ |
| 1445 | 1445 | unsigned int fcoe_ddp_xid; |
| 1446 | 1446 | #endif |
| 1447 | −#if IS_ENABLED(CONFIG_NETPRIO_CGROUP) | |
| 1447 | +#if IS_ENABLED(CONFIG_CGROUP_NET_PRIO) | |
| 1448 | 1448 | struct netprio_map __rcu *priomap; |
| 1449 | 1449 | #endif |
| 1450 | 1450 | /* phy device may attach itself for hardware timestamping */ |
| @@ -331,7 +331,6 @@ extern ip_set_id_t ip_set_get_byname(struct net *net, · 330 unmodified lines | ||
| 331 | 331 | const char *name, struct ip_set **set); |
| 332 | 332 | extern void ip_set_put_byindex(struct net *net, ip_set_id_t index); |
| 333 | 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 | 334 | extern ip_set_id_t ip_set_nfnl_get_byindex(struct net *net, ip_set_id_t index); |
| 336 | 335 | extern void ip_set_nfnl_put(struct net *net, ip_set_id_t index); |
| 337 | 336 | |
| @@ -16,17 +16,16 @@ · 15 unmodified lines | ||
| 16 | 16 | #include <linux/cgroup.h> |
| 17 | 17 | #include <linux/hardirq.h> |
| 18 | 18 | #include <linux/rcupdate.h> |
| 19 | +#include <net/sock.h> | |
| 19 | 20 | |
| 20 | −#if IS_ENABLED(CONFIG_NET_CLS_CGROUP) | |
| 21 | −struct cgroup_cls_state | |
| 22 | −{ | |
| 21 | +#ifdef CONFIG_CGROUP_NET_CLASSID | |
| 22 | +struct cgroup_cls_state { | |
| 23 | 23 | struct cgroup_subsys_state css; |
| 24 | 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 | 29 | static inline u32 task_cls_classid(struct task_struct *p) |
| 31 | 30 | { |
| 32 | 31 | u32 classid; |
| @@ -41,33 +40,18 @@ static inline u32 task_cls_classid(struct task_struct *p) · 8 unmodified lines | ||
| 41 | 40 | |
| 42 | 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 | 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 | 57 | #endif /* _NET_CLS_CGROUP_H */ |
| @@ -19,6 +19,4 @@ extern struct nf_conntrack_l4proto nf_conntrack_l4proto_icmp; · 18 unmodified lines | ||
| 19 | 19 | int nf_conntrack_ipv4_compat_init(void); |
| 20 | 20 | void nf_conntrack_ipv4_compat_fini(void); |
| 21 | 21 | |
| 22 | −void need_ipv4_conntrack(void); | |
| 23 | − | |
| 24 | 22 | #endif /*_NF_CONNTRACK_IPV4_H*/ |
| @@ -87,7 +87,6 @@ int nf_ct_l3proto_register(struct nf_conntrack_l3proto *proto); · 86 unmodified lines | ||
| 87 | 87 | void nf_ct_l3proto_unregister(struct nf_conntrack_l3proto *proto); |
| 88 | 88 | |
| 89 | 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 | 91 | /* Existing built-in protocols */ |
| 93 | 92 | extern struct nf_conntrack_l3proto nf_conntrack_l3proto_generic; |
| @@ -65,6 +65,23 @@ struct nf_ip_net { · 64 unmodified lines | ||
| 65 | 65 | struct netns_ct { |
| 66 | 66 | atomic_t count; |
| 67 | 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 | 85 | unsigned int htable_size; |
| 69 | 86 | struct kmem_cache *nf_conntrack_cachep; |
| 70 | 87 | struct hlist_nulls_head *hash; |
| @@ -75,14 +92,6 @@ struct netns_ct { · 4 unmodified lines | ||
| 75 | 92 | struct ip_conntrack_stat __percpu *stat; |
| 76 | 93 | struct nf_ct_event_notifier __rcu *nf_conntrack_event_cb; |
| 77 | 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 | 95 | struct nf_ip_net nf_ct_proto; |
| 87 | 96 | #if defined(CONFIG_NF_CONNTRACK_LABELS) |
| 88 | 97 | unsigned int labels_used; |
| @@ -92,13 +101,5 @@ struct netns_ct { · 3 unmodified lines | ||
| 92 | 101 | struct hlist_head *nat_bysource; |
| 93 | 102 | unsigned int nat_htable_size; |
| 94 | 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 | 105 | #endif |
| @@ -13,12 +13,12 @@ · 12 unmodified lines | ||
| 13 | 13 | |
| 14 | 14 | #ifndef _NETPRIO_CGROUP_H |
| 15 | 15 | #define _NETPRIO_CGROUP_H |
| 16 | + | |
| 16 | 17 | #include <linux/cgroup.h> |
| 17 | 18 | #include <linux/hardirq.h> |
| 18 | 19 | #include <linux/rcupdate.h> |
| 19 | 20 | |
| 20 | − | |
| 21 | −#if IS_ENABLED(CONFIG_NETPRIO_CGROUP) | |
| 21 | +#if IS_ENABLED(CONFIG_CGROUP_NET_PRIO) | |
| 22 | 22 | struct netprio_map { |
| 23 | 23 | struct rcu_head rcu; |
| 24 | 24 | u32 priomap_len; |
| @@ -27,8 +27,7 @@ struct netprio_map { · 2 unmodified lines | ||
| 27 | 27 | |
| 28 | 28 | void sock_update_netprioidx(struct sock *sk); |
| 29 | 29 | |
| 30 | −#if IS_BUILTIN(CONFIG_NETPRIO_CGROUP) | |
| 31 | − | |
| 30 | +#if IS_BUILTIN(CONFIG_CGROUP_NET_PRIO) | |
| 32 | 31 | static inline u32 task_netprioidx(struct task_struct *p) |
| 33 | 32 | { |
| 34 | 33 | struct cgroup_subsys_state *css; |
| @@ -40,9 +39,7 @@ static inline u32 task_netprioidx(struct task_struct *p) · 5 unmodified lines | ||
| 40 | 39 | rcu_read_unlock(); |
| 41 | 40 | return idx; |
| 42 | 41 | } |
| 43 | − | |
| 44 | −#elif IS_MODULE(CONFIG_NETPRIO_CGROUP) | |
| 45 | − | |
| 42 | +#elif IS_MODULE(CONFIG_CGROUP_NET_PRIO) | |
| 46 | 43 | static inline u32 task_netprioidx(struct task_struct *p) |
| 47 | 44 | { |
| 48 | 45 | struct cgroup_subsys_state *css; |
| @@ -56,9 +53,7 @@ static inline u32 task_netprioidx(struct task_struct *p) · 7 unmodified lines | ||
| 56 | 53 | return idx; |
| 57 | 54 | } |
| 58 | 55 | #endif |
| 59 | − | |
| 60 | −#else /* !CONFIG_NETPRIO_CGROUP */ | |
| 61 | − | |
| 56 | +#else /* !CONFIG_CGROUP_NET_PRIO */ | |
| 62 | 57 | static inline u32 task_netprioidx(struct task_struct *p) |
| 63 | 58 | { |
| 64 | 59 | return 0; |
| @@ -66,6 +61,5 @@ static inline u32 task_netprioidx(struct task_struct *p) · 1 unmodified line | ||
| 66 | 61 | |
| 67 | 62 | #define sock_update_netprioidx(sk) |
| 68 | 63 | |
| 69 | −#endif /* CONFIG_NETPRIO_CGROUP */ | |
| 70 | − | |
| 64 | +#endif /* CONFIG_CGROUP_NET_PRIO */ | |
| 71 | 65 | #endif /* _NET_CLS_CGROUP_H */ |
| @@ -395,7 +395,7 @@ struct sock { · 394 unmodified lines | ||
| 395 | 395 | unsigned short sk_ack_backlog; |
| 396 | 396 | unsigned short sk_max_ack_backlog; |
| 397 | 397 | __u32 sk_priority; |
| 398 | −#if IS_ENABLED(CONFIG_NETPRIO_CGROUP) | |
| 398 | +#if IS_ENABLED(CONFIG_CGROUP_NET_PRIO) | |
| 399 | 399 | __u32 sk_cgrp_prioidx; |
| 400 | 400 | #endif |
| 401 | 401 | struct pid *sk_peer_pid; |
| @@ -39,6 +39,7 @@ header-y += xt_TEE.h · 38 unmodified lines | ||
| 39 | 39 | header-y += xt_TPROXY.h |
| 40 | 40 | header-y += xt_addrtype.h |
| 41 | 41 | header-y += xt_bpf.h |
| 42 | +header-y += xt_cgroup.h | |
| 42 | 43 | header-y += xt_cluster.h |
| 43 | 44 | header-y += xt_comment.h |
| 44 | 45 | header-y += xt_connbytes.h |
| @@ -54,6 +55,7 @@ header-y += xt_ecn.h · 9 unmodified lines | ||
| 54 | 55 | header-y += xt_esp.h |
| 55 | 56 | header-y += xt_hashlimit.h |
| 56 | 57 | header-y += xt_helper.h |
| 58 | +header-y += xt_ipcomp.h | |
| 57 | 59 | header-y += xt_iprange.h |
| 58 | 60 | header-y += xt_ipvs.h |
| 59 | 61 | header-y += xt_length.h |
| @@ -4,10 +4,14 @@ · 3 unmodified lines | ||
| 4 | 4 | #include <linux/netfilter.h> |
| 5 | 5 | #include <linux/netfilter/nf_conntrack_tuple_common.h> |
| 6 | 6 | |
| 7 | −#define NF_NAT_RANGE_MAP_IPS 1 | |
| 8 | −#define NF_NAT_RANGE_PROTO_SPECIFIED 2 | |
| 9 | −#define NF_NAT_RANGE_PROTO_RANDOM 4 | |
| 10 | −#define NF_NAT_RANGE_PERSISTENT 8 | |
| 7 | +#define NF_NAT_RANGE_MAP_IPS (1 << 0) | |
| 8 | +#define NF_NAT_RANGE_PROTO_SPECIFIED (1 << 1) | |
| 9 | +#define NF_NAT_RANGE_PROTO_RANDOM (1 << 2) | |
| 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 | 16 | struct nf_nat_ipv4_range { |
| 13 | 17 | unsigned int flags; |
| @@ -47,6 +47,8 @@ enum nfqnl_attr_type { · 46 unmodified lines | ||
| 47 | 47 | NFQA_CAP_LEN, /* __u32 length of captured packet */ |
| 48 | 48 | NFQA_SKB_INFO, /* __u32 skb meta information */ |
| 49 | 49 | NFQA_EXP, /* nf_conntrack_netlink.h */ |
| 50 | + NFQA_UID, /* __u32 sk uid */ | |
| 51 | + NFQA_GID, /* __u32 sk gid */ | |
| 50 | 52 | |
| 51 | 53 | __NFQA_MAX |
| 52 | 54 | }; |
| @@ -99,7 +101,8 @@ enum nfqnl_attr_config { · 46 unmodified lines | ||
| 99 | 101 | #define NFQA_CFG_F_FAIL_OPEN (1 << 0) |
| 100 | 102 | #define NFQA_CFG_F_CONNTRACK (1 << 1) |
| 101 | 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 | 107 | /* flags for NFQA_SKB_INFO */ |
| 105 | 108 | /* packet appears to have wrong checksums, but they are ok */ |
| @@ -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 */ | |
| @@ -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*/ | |
| @@ -238,12 +238,19 @@ config XPS · 237 unmodified lines | ||
| 238 | 238 | depends on SMP |
| 239 | 239 | default y |
| 240 | 240 | |
| 241 | −config NETPRIO_CGROUP | |
| 241 | +config CGROUP_NET_PRIO | |
| 242 | 242 | tristate "Network priority cgroup" |
| 243 | 243 | depends on CGROUPS |
| 244 | 244 | ---help--- |
| 245 | 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 | 255 | config NET_RX_BUSY_POLL |
| 249 | 256 | boolean |
| @@ -21,4 +21,5 @@ obj-$(CONFIG_FIB_RULES) += fib_rules.o · 20 unmodified lines | ||
| 21 | 21 | obj-$(CONFIG_TRACEPOINTS) += net-traces.o |
| 22 | 22 | obj-$(CONFIG_NET_DROP_MONITOR) += drop_monitor.o |
| 23 | 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 | |
| @@ -2741,7 +2741,7 @@ static inline int __dev_xmit_skb(struct sk_buff *skb, struct Qdisc *q, · 2740 unmodified lines | ||
| 2741 | 2741 | return rc; |
| 2742 | 2742 | } |
| 2743 | 2743 | |
| 2744 | −#if IS_ENABLED(CONFIG_NETPRIO_CGROUP) | |
| 2744 | +#if IS_ENABLED(CONFIG_CGROUP_NET_PRIO) | |
| 2745 | 2745 | static void skb_update_prio(struct sk_buff *skb) |
| 2746 | 2746 | { |
| 2747 | 2747 | struct netprio_map *map = rcu_dereference_bh(skb->dev->priomap); |
| @@ -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); | |
| @@ -1307,19 +1307,7 @@ static void sk_prot_free(struct proto *prot, struct sock *sk) · 1306 unmodified lines | ||
| 1307 | 1307 | module_put(owner); |
| 1308 | 1308 | } |
| 1309 | 1309 | |
| 1310 | −#if IS_ENABLED(CONFIG_NET_CLS_CGROUP) | |
| 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) | |
| 1310 | +#if IS_ENABLED(CONFIG_CGROUP_NET_PRIO) | |
| 1323 | 1311 | void sock_update_netprioidx(struct sock *sk) |
| 1324 | 1312 | { |
| 1325 | 1313 | if (in_interrupt()) |
| @@ -548,9 +548,3 @@ static void __exit nf_conntrack_l3proto_ipv4_fini(void) · 547 unmodified lines | ||
| 548 | 548 | |
| 549 | 549 | module_init(nf_conntrack_l3proto_ipv4_init); |
| 550 | 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); | |
| @@ -858,6 +858,16 @@ config NETFILTER_XT_MATCH_BPF · 857 unmodified lines | ||
| 858 | 858 | |
| 859 | 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 | 871 | config NETFILTER_XT_MATCH_CLUSTER |
| 862 | 872 | tristate '"cluster" match support' |
| 863 | 873 | depends on NF_CONNTRACK |
| @@ -1035,6 +1045,15 @@ config NETFILTER_XT_MATCH_HL · 171 unmodified lines | ||
| 1035 | 1045 | in the IPv6 header, or the time-to-live field in the IPv4 |
| 1036 | 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 | 1057 | config NETFILTER_XT_MATCH_IPRANGE |
| 1039 | 1058 | tristate '"iprange" address range match support' |
| 1040 | 1059 | depends on NETFILTER_ADVANCED |
| @@ -133,6 +133,7 @@ obj-$(CONFIG_NETFILTER_XT_MATCH_ESP) += xt_esp.o · 132 unmodified lines | ||
| 133 | 133 | obj-$(CONFIG_NETFILTER_XT_MATCH_HASHLIMIT) += xt_hashlimit.o |
| 134 | 134 | obj-$(CONFIG_NETFILTER_XT_MATCH_HELPER) += xt_helper.o |
| 135 | 135 | obj-$(CONFIG_NETFILTER_XT_MATCH_HL) += xt_hl.o |
| 136 | +obj-$(CONFIG_NETFILTER_XT_MATCH_IPCOMP) += xt_ipcomp.o | |
| 136 | 137 | obj-$(CONFIG_NETFILTER_XT_MATCH_IPRANGE) += xt_iprange.o |
| 137 | 138 | obj-$(CONFIG_NETFILTER_XT_MATCH_IPVS) += xt_ipvs.o |
| 138 | 139 | obj-$(CONFIG_NETFILTER_XT_MATCH_LENGTH) += xt_length.o |
| @@ -142,6 +143,7 @@ obj-$(CONFIG_NETFILTER_XT_MATCH_MULTIPORT) += xt_multiport.o · 3 unmodified lines | ||
| 142 | 143 | obj-$(CONFIG_NETFILTER_XT_MATCH_NFACCT) += xt_nfacct.o |
| 143 | 144 | obj-$(CONFIG_NETFILTER_XT_MATCH_OSF) += xt_osf.o |
| 144 | 145 | obj-$(CONFIG_NETFILTER_XT_MATCH_OWNER) += xt_owner.o |
| 146 | +obj-$(CONFIG_NETFILTER_XT_MATCH_CGROUP) += xt_cgroup.o | |
| 145 | 147 | obj-$(CONFIG_NETFILTER_XT_MATCH_PHYSDEV) += xt_physdev.o |
| 146 | 148 | obj-$(CONFIG_NETFILTER_XT_MATCH_PKTTYPE) += xt_pkttype.o |
| 147 | 149 | obj-$(CONFIG_NETFILTER_XT_MATCH_POLICY) += xt_policy.o |
| @@ -624,34 +624,6 @@ EXPORT_SYMBOL_GPL(ip_set_name_byindex); · 623 unmodified lines | ||
| 624 | 624 | * call nfnl_lock for us. |
| 625 | 625 | */ |
| 626 | 626 | |
| 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 | 627 | /* |
| 656 | 628 | * Find set by index, reference it once. The reference makes sure the |
| 657 | 629 | * thing pointed to, does not go away under our feet. |
| @@ -1637,7 +1637,10 @@ static int sync_thread_master(void *data) · 1636 unmodified lines | ||
| 1637 | 1637 | continue; |
| 1638 | 1638 | } |
| 1639 | 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 | 1644 | sock_writeable(sk) || |
| 1642 | 1645 | kthread_should_stop()); |
| 1643 | 1646 | if (unlikely(kthread_should_stop())) |
| @@ -60,12 +60,6 @@ int (*nfnetlink_parse_nat_setup_hook)(struct nf_conn *ct, · 59 unmodified lines | ||
| 60 | 60 | const struct nlattr *attr) __read_mostly; |
| 61 | 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 | 63 | DEFINE_SPINLOCK(nf_conntrack_lock); |
| 70 | 64 | EXPORT_SYMBOL_GPL(nf_conntrack_lock); |
| 71 | 65 | |
| @@ -361,15 +355,6 @@ begin: · 289 unmodified lines | ||
| 361 | 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 | 358 | /* Find a connection corresponding to a tuple. */ |
| 374 | 359 | static struct nf_conntrack_tuple_hash * |
| 375 | 360 | __nf_conntrack_find_get(struct net *net, u16 zone, |
| @@ -2118,8 +2118,16 @@ ctnetlink_nfqueue_parse_ct(const struct nlattr *cda[], struct nf_conn *ct) · 2117 unmodified lines | ||
| 2118 | 2118 | return err; |
| 2119 | 2119 | } |
| 2120 | 2120 | #if defined(CONFIG_NF_CONNTRACK_MARK) |
| 2121 | − if (cda[CTA_MARK]) | |
| 2122 | − ct->mark = ntohl(nla_get_be32(cda[CTA_MARK])); | |
| 2121 | + if (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 | 2131 | #endif |
| 2124 | 2132 | return 0; |
| 2125 | 2133 | } |
| @@ -92,12 +92,6 @@ nf_ct_l3proto_find_get(u_int16_t l3proto) · 91 unmodified lines | ||
| 92 | 92 | } |
| 93 | 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 | 95 | int |
| 102 | 96 | nf_ct_l3proto_try_module_get(unsigned short l3proto) |
| 103 | 97 | { |
| @@ -315,7 +315,7 @@ get_unique_tuple(struct nf_conntrack_tuple *tuple, · 314 unmodified lines | ||
| 315 | 315 | * manips not an issue. |
| 316 | 316 | */ |
| 317 | 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 | 319 | /* try the original tuple first */ |
| 320 | 320 | if (in_range(l3proto, l4proto, orig_tuple, range)) { |
| 321 | 321 | if (!nf_nat_used_tuple(orig_tuple, ct)) { |
| @@ -339,7 +339,7 @@ get_unique_tuple(struct nf_conntrack_tuple *tuple, · 17 unmodified lines | ||
| 339 | 339 | */ |
| 340 | 340 | |
| 341 | 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 | 343 | if (range->flags & NF_NAT_RANGE_PROTO_SPECIFIED) { |
| 344 | 344 | if (l4proto->in_range(tuple, maniptype, |
| 345 | 345 | &range->min_proto, |
| @@ -74,22 +74,24 @@ void nf_nat_l4proto_unique_tuple(const struct nf_nat_l3proto *l3proto, · 73 unmodified lines | ||
| 74 | 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 | 78 | off = l3proto->secure_port(tuple, maniptype == NF_NAT_MANIP_SRC |
| 79 | 79 | ? tuple->dst.u.all |
| 80 | 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 | 84 | off = *rover; |
| 85 | + } | |
| 83 | 86 | |
| 84 | 87 | for (i = 0; ; ++off) { |
| 85 | 88 | *portptr = htons(min + off % range_size); |
| 86 | 89 | if (++i != range_size && nf_nat_used_tuple(tuple, ct)) |
| 87 | 90 | continue; |
| 88 | − if (!(range->flags & NF_NAT_RANGE_PROTO_RANDOM)) | |
| 91 | + if (!(range->flags & NF_NAT_RANGE_PROTO_RANDOM_ALL)) | |
| 89 | 92 | *rover = off; |
| 90 | 93 | return; |
| 91 | 94 | } |
| 92 | − return; | |
| 93 | 95 | } |
| 94 | 96 | EXPORT_SYMBOL_GPL(nf_nat_l4proto_unique_tuple); |
| 95 | 97 | |
| @@ -28,8 +28,6 @@ · 27 unmodified lines | ||
| 28 | 28 | #include <linux/proc_fs.h> |
| 29 | 29 | #include <linux/security.h> |
| 30 | 30 | #include <linux/list.h> |
| 31 | −#include <linux/jhash.h> | |
| 32 | −#include <linux/random.h> | |
| 33 | 31 | #include <linux/slab.h> |
| 34 | 32 | #include <net/sock.h> |
| 35 | 33 | #include <net/netfilter/nf_log.h> |
| @@ -75,7 +73,6 @@ struct nfulnl_instance { · 39 unmodified lines | ||
| 75 | 73 | }; |
| 76 | 74 | |
| 77 | 75 | #define INSTANCE_BUCKETS 16 |
| 78 | −static unsigned int hash_init; | |
| 79 | 76 | |
| 80 | 77 | static int nfnl_log_net_id __read_mostly; |
| 81 | 78 | |
| @@ -1066,11 +1063,6 @@ static int __init nfnetlink_log_init(void) · 984 unmodified lines | ||
| 1066 | 1063 | { |
| 1067 | 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 | 1066 | netlink_register_notifier(&nfulnl_rtnl_notifier); |
| 1075 | 1067 | status = nfnetlink_subsys_register(&nfulnl_subsys); |
| 1076 | 1068 | if (status < 0) { |
| @@ -297,6 +297,31 @@ nfqnl_put_packet_info(struct sk_buff *nlskb, struct sk_buff *packet, · 296 unmodified lines | ||
| 297 | 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 | 325 | static struct sk_buff * |
| 301 | 326 | nfqnl_build_packet_message(struct net *net, struct nfqnl_instance *queue, |
| 302 | 327 | struct nf_queue_entry *entry, |
| @@ -372,6 +397,11 @@ nfqnl_build_packet_message(struct net *net, struct nfqnl_instance *queue, · 69 unmodified lines | ||
| 372 | 397 | if (queue->flags & NFQA_CFG_F_CONNTRACK) |
| 373 | 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 | 405 | skb = nfnetlink_alloc_skb(net, size, queue->peer_portid, |
| 376 | 406 | GFP_ATOMIC); |
| 377 | 407 | if (!skb) |
| @@ -484,6 +514,10 @@ nfqnl_build_packet_message(struct net *net, struct nfqnl_instance *queue, · 106 unmodified lines | ||
| 484 | 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 | 521 | if (ct && nfqnl_ct_put(skb, ct, ctinfo) < 0) |
| 488 | 522 | goto nla_put_failure; |
| 489 | 523 | |
| @@ -164,7 +164,7 @@ static int nft_hash_init(const struct nft_set *set, · 163 unmodified lines | ||
| 164 | 164 | unsigned int cnt, i; |
| 165 | 165 | |
| 166 | 166 | if (unlikely(!nft_hash_rnd_initted)) { |
| 167 | − get_random_bytes(&nft_hash_rnd, 4); | |
| 167 | + nft_hash_rnd = prandom_u32(); | |
| 168 | 168 | nft_hash_rnd_initted = true; |
| 169 | 169 | } |
| 170 | 170 | |
| @@ -211,8 +211,10 @@ static int xt_ct_tg_check(const struct xt_tgchk_param *par, · 210 unmodified lines | ||
| 211 | 211 | ret = 0; |
| 212 | 212 | if ((info->ct_events || info->exp_events) && |
| 213 | 213 | !nf_ct_ecache_ext_add(ct, info->ct_events, info->exp_events, |
| 214 | − GFP_KERNEL)) | |
| 214 | + GFP_KERNEL)) { | |
| 215 | + ret = -EINVAL; | |
| 215 | 216 | goto err3; |
| 217 | + } | |
| 216 | 218 | |
| 217 | 219 | if (info->helper[0]) { |
| 218 | 220 | ret = xt_ct_set_helper(ct, info->helper, par); |
| @@ -100,7 +100,7 @@ static int xt_rateest_tg_checkentry(const struct xt_tgchk_param *par) · 99 unmodified lines | ||
| 100 | 100 | int ret; |
| 101 | 101 | |
| 102 | 102 | if (unlikely(!rnd_inited)) { |
| 103 | − get_random_bytes(&jhash_rnd, sizeof(jhash_rnd)); | |
| 103 | + jhash_rnd = prandom_u32(); | |
| 104 | 104 | rnd_inited = true; |
| 105 | 105 | } |
| 106 | 106 | |
| @@ -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); | |
| @@ -229,7 +229,7 @@ static int connlimit_mt_check(const struct xt_mtchk_param *par) · 228 unmodified lines | ||
| 229 | 229 | u_int32_t rand; |
| 230 | 230 | |
| 231 | 231 | do { |
| 232 | − get_random_bytes(&rand, sizeof(rand)); | |
| 232 | + rand = prandom_u32(); | |
| 233 | 233 | } while (!rand); |
| 234 | 234 | cmpxchg(&connlimit_rnd, 0, rand); |
| 235 | 235 | } |
| @@ -177,7 +177,7 @@ dsthash_alloc_init(struct xt_hashlimit_htable *ht, · 176 unmodified lines | ||
| 177 | 177 | /* initialize hash with random val at the time we allocate |
| 178 | 178 | * the first hashtable entry */ |
| 179 | 179 | if (unlikely(!ht->rnd_initialized)) { |
| 180 | − get_random_bytes(&ht->rnd, sizeof(ht->rnd)); | |
| 180 | + ht->rnd = prandom_u32(); | |
| 181 | 181 | ht->rnd_initialized = true; |
| 182 | 182 | } |
| 183 | 183 | |
| @@ -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); | |
| @@ -334,7 +334,7 @@ static int recent_mt_check(const struct xt_mtchk_param *par, · 333 unmodified lines | ||
| 334 | 334 | size_t sz; |
| 335 | 335 | |
| 336 | 336 | if (unlikely(!hash_rnd_inited)) { |
| 337 | − get_random_bytes(&hash_rnd, sizeof(hash_rnd)); | |
| 337 | + hash_rnd = prandom_u32(); | |
| 338 | 338 | hash_rnd_inited = true; |
| 339 | 339 | } |
| 340 | 340 | if (info->check_set & ~XT_RECENT_VALID_FLAGS) { |
| @@ -444,6 +444,7 @@ config NET_CLS_FLOW · 443 unmodified lines | ||
| 444 | 444 | config NET_CLS_CGROUP |
| 445 | 445 | tristate "Control Group Classifier" |
| 446 | 446 | select NET_CLS |
| 447 | + select CGROUP_NET_CLASSID | |
| 447 | 448 | depends on CGROUPS |
| 448 | 449 | ---help--- |
| 449 | 450 | Say Y here if you want to classify packets based on the control |
| @@ -11,109 +11,13 @@ · 10 unmodified lines | ||
| 11 | 11 | |
| 12 | 12 | #include <linux/module.h> |
| 13 | 13 | #include <linux/slab.h> |
| 14 | −#include <linux/types.h> | |
| 15 | −#include <linux/string.h> | |
| 16 | −#include <linux/errno.h> | |
| 17 | 14 | #include <linux/skbuff.h> |
| 18 | −#include <linux/cgroup.h> | |
| 19 | 15 | #include <linux/rcupdate.h> |
| 20 | −#include <linux/fdtable.h> | |
| 21 | 16 | #include <net/rtnetlink.h> |
| 22 | 17 | #include <net/pkt_cls.h> |
| 23 | 18 | #include <net/sock.h> |
| 24 | 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 | 21 | struct cls_cgroup_head { |
| 118 | 22 | u32 handle; |
| 119 | 23 | struct tcf_exts exts; |
| @@ -305,25 +209,12 @@ static struct tcf_proto_ops cls_cgroup_ops __read_mostly = { · 185 unmodified lines | ||
| 305 | 209 | |
| 306 | 210 | static int __init init_cgroup_cls(void) |
| 307 | 211 | { |
| 308 | − int ret; | |
| 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; | |
| 212 | + return register_tcf_proto_ops(&cls_cgroup_ops); | |
| 320 | 213 | } |
| 321 | 214 | |
| 322 | 215 | static void __exit exit_cgroup_cls(void) |
| 323 | 216 | { |
| 324 | 217 | unregister_tcf_proto_ops(&cls_cgroup_ops); |
| 325 | − | |
| 326 | − cgroup_unload_subsys(&net_cls_subsys); | |
| 327 | 218 | } |
| 328 | 219 | |
| 329 | 220 | module_init(init_cgroup_cls); |