History

Merge git://git.kernel.org/pub/scm/linux/kernel/git/pablo/nf-next

Pablo Neira Ayuso says: ==================== Netfilter/IPVS updates for net-next The following patchset contains a large Netfilter update for net-next, to summarise: 1) Add support for stateful objects. This series provides a nf_tables native alternative to the extended accounting infrastructure for nf_tables. Two initial stateful objects are supported: counters and quotas. Objects are identified by a user-defined name, you can fetch and reset them anytime. You can also use a maps to allow fast lookups using any arbitrary key combination. More info at: http://marc.info/?l=netfilter-devel&m=148029128323837&w=2 2) On-demand registration of nf_conntrack and defrag hooks per netns. Register nf_conntrack hooks if we have a stateful ruleset, ie. state-based filtering or NAT. The new nf_conntrack_default_on sysctl enables this from newly created netnamespaces. Default behaviour is not modified. Patches from Florian Westphal. 3) Allocate 4k chunks and then use these for x_tables counter allocation requests, this improves ruleset load time and also datapath ruleset evaluation, patches from Florian Westphal. 4) Add support for ebpf to the existing x_tables bpf extension. From Willem de Bruijn. 5) Update layer 4 checksum if any of the pseudoheader fields is updated. This provides a limited form of 1:1 stateless NAT that make sense in specific scenario, eg. load balancing. 6) Add support to flush sets in nf_tables. This series comes with a new set->ops->deactivate_one() indirection given that we have to walk over the list of set elements, then deactivate them one by one. The existing set->ops->deactivate() performs an element lookup that we don't need. 7) Two patches to avoid cloning packets, thus speed up packet forwarding via nft_fwd from ingress. From Florian Westphal. 8) Two IPVS patches via Simon Horman: Decrement ttl in all modes to prevent infinite loops, patch from Dwip Banerjee. And one minor refactoring from Gao feng. 9) Revisit recent log support for nf_tables netdev families: One patch to ensure that we correctly handle non-ethernet packets. Another patch to add missing logger definition for netdev. Patches from Liping Zhang. 10) Three patches for nft_fib, one to address insufficient register initialization and another to solve incorrect (although harmless) byteswap operation. Moreover update xt_rpfilter and nft_fib to match lbcast packets with zeronet as source, eg. DHCP Discover packets (0.0.0.0 -> 255.255.255.255). Also from Liping Zhang. 11) Built-in DCCP, SCTP and UDPlite conntrack and NAT support, from Davide Caratti. While DCCP is rather hopeless lately, and UDPlite has been broken in many-cast mode for some little time, let's give them a chance by placing them at the same level as other existing protocols. Thus, users don't explicitly have to modprobe support for this and NAT rules work for them. Some people point to the lack of support in SOHO Linux-based routers that make deployment of new protocols harder. I guess other middleboxes outthere on the Internet are also to blame. Anyway, let's see if this has any impact in the midrun. 12) Skip software SCTP software checksum calculation if the NIC comes with SCTP checksum offload support. From Davide Caratti. 13) Initial core factoring to prepare conversion to hook array. Three patches from Aaron Conole. 14) Gao Feng made a wrong conversion to switch in the xt_multiport extension in a patch coming in the previous batch. Fix it in this batch. 15) Get vmalloc call in sync with kmalloc flags to avoid a warning and likely OOM killer intervention from x_tables. From Marcelo Ricardo Leitner. 16) Update Arturo Borrero's email address in all source code headers. ====================

David S. Miller committed 9 years ago

Commit 5fccd642 parents 63c36c4 73c25fb90 files · +2513 −661Browse files

Unified · Split

90 files
  1. Documentation/networking/nf_conntrack-sysctl.txt +11 −0
  2. include/linux/netfilter.h +30 −1
  3. include/linux/netfilter/nf_conntrack_dccp.h +1 −1
  4. include/linux/netfilter/x_tables.h +7 −31
  5. include/linux/netfilter_ingress.h +6 −1
  6. include/net/netfilter/ipv4/nf_conntrack_ipv4.h +9 −0
  7. include/net/netfilter/ipv4/nf_defrag_ipv4.h +2 −1
  8. include/net/netfilter/ipv6/nf_conntrack_ipv6.h +9 −0
  9. include/net/netfilter/ipv6/nf_defrag_ipv6.h +2 −1
  10. include/net/netfilter/nf_conntrack.h +4 −0
  11. include/net/netfilter/nf_conntrack_l3proto.h +13 −3
  12. include/net/netfilter/nf_dup_netdev.h +1 −0
  13. include/net/netfilter/nf_log.h +3 −1
  14. include/net/netfilter/nf_nat_l4proto.h +9 −0
  15. include/net/netfilter/nf_tables.h +100 −1
  16. include/net/netfilter/nf_tables_core.h +1 −0
  17. include/net/netns/conntrack.h +43 −0
  18. include/net/netns/netfilter.h +6 −0
  19. include/uapi/linux/netfilter/nf_conntrack_tuple_common.h +3 −0
  20. include/uapi/linux/netfilter/nf_tables.h +70 −0
  21. include/uapi/linux/netfilter/xt_bpf.h +21 −0
  22. net/bridge/br_netfilter_hooks.c +4 −4
  23. net/bridge/netfilter/nf_log_bridge.c +2 −1
  24. net/ipv4/netfilter/arp_tables.c +8 −8
  25. net/ipv4/netfilter/ip_tables.c +8 −8
  26. net/ipv4/netfilter/ipt_CLUSTERIP.c +2 −2
  27. net/ipv4/netfilter/ipt_MASQUERADE.c +7 −1
  28. net/ipv4/netfilter/ipt_SYNPROXY.c +2 −2
  29. net/ipv4/netfilter/ipt_rpfilter.c +5 −3
  30. net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c +56 −15
  31. net/ipv4/netfilter/nf_defrag_ipv4.c +38 −3
  32. net/ipv4/netfilter/nft_fib_ipv4.c +10 −7
  33. net/ipv4/netfilter/nft_masq_ipv4.c +9 −2
  34. net/ipv4/netfilter/nft_redir_ipv4.c +9 −2
  35. net/ipv6/netfilter/ip6_tables.c +8 −9
  36. net/ipv6/netfilter/ip6t_SYNPROXY.c +2 −2
  37. net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c +57 −13
  38. net/ipv6/netfilter/nf_defrag_ipv6_hooks.c +38 −4
  39. net/ipv6/netfilter/nft_fib_ipv6.c +1 −1
  40. net/ipv6/netfilter/nft_masq_ipv6.c +9 −2
  41. net/ipv6/netfilter/nft_redir_ipv6.c +9 −2
  42. net/netfilter/Kconfig +18 −12
  43. net/netfilter/Makefile +9 −9
  44. net/netfilter/core.c +6 −10
  45. net/netfilter/ipvs/ip_vs_ctl.c +1 −1
  46. net/netfilter/ipvs/ip_vs_xmit.c +54 −0
  47. net/netfilter/nf_conntrack_proto.c +65 −8
  48. net/netfilter/nf_conntrack_proto_dccp.c +10 −69
  49. net/netfilter/nf_conntrack_proto_sctp.c +9 −67
  50. net/netfilter/nf_conntrack_proto_udplite.c +9 −70
  51. net/netfilter/nf_conntrack_standalone.c +10 −0
  52. net/netfilter/nf_dup_netdev.c +25 −8
  53. net/netfilter/nf_log_common.c +2 −1
  54. net/netfilter/nf_log_netdev.c +2 −1
  55. net/netfilter/nf_nat_core.c +12 −0
  56. net/netfilter/nf_nat_proto_dccp.c +1 −35
  57. net/netfilter/nf_nat_proto_sctp.c +5 −35
  58. net/netfilter/nf_nat_proto_udplite.c +1 −34
  59. net/netfilter/nf_queue.c +2 −3
  60. net/netfilter/nf_tables_api.c +702 −16
  61. net/netfilter/nfnetlink_log.c +1 −0
  62. net/netfilter/nft_counter.c +156 −30
  63. net/netfilter/nft_ct.c +13 −13
  64. net/netfilter/nft_fib.c +1 −1
  65. net/netfilter/nft_fwd_netdev.c +2 −2
  66. net/netfilter/nft_masq.c +3 −3
  67. net/netfilter/nft_nat.c +10 −1
  68. net/netfilter/nft_objref.c +226 −0
  69. net/netfilter/nft_payload.c +102 −5
  70. net/netfilter/nft_quota.c +136 −22
  71. net/netfilter/nft_redir.c +3 −3
  72. net/netfilter/nft_set_hash.c +18 −7
  73. net/netfilter/nft_set_rbtree.c +11 −1
  74. net/netfilter/x_tables.c +57 −1
  75. net/netfilter/xt_CONNSECMARK.c +2 −2
  76. net/netfilter/xt_CT.c +3 −3
  77. net/netfilter/xt_NETMAP.c +9 −2
  78. net/netfilter/xt_REDIRECT.c +10 −2
  79. net/netfilter/xt_TPROXY.c +10 −5
  80. net/netfilter/xt_bpf.c +80 −16
  81. net/netfilter/xt_connbytes.c +2 −2
  82. net/netfilter/xt_connlabel.c +3 −3
  83. net/netfilter/xt_connlimit.c +3 −3
  84. net/netfilter/xt_connmark.c +4 −4
  85. net/netfilter/xt_conntrack.c +2 −2
  86. net/netfilter/xt_helper.c +2 −2
  87. net/netfilter/xt_multiport.c +19 −7
  88. net/netfilter/xt_nat.c +17 −1
  89. net/netfilter/xt_socket.c +28 −5
  90. net/netfilter/xt_state.c +2 −2
Documentation/networking/nf_conntrack-sysctl.txt+11−0
@@ -96,6 +96,17 @@ nf_conntrack_max - INTEGER · 95 unmodified lines
9696 Size of connection tracking table. Default value is
9797 nf_conntrack_buckets value * 4.
9898
99+nf_conntrack_default_on - BOOLEAN
100+ 0 - don't register conntrack in new net namespaces
101+ 1 - register conntrack in new net namespaces (default)
102+
103+ This controls wheter newly created network namespaces have connection
104+ tracking enabled by default. It will be enabled automatically
105+ regardless of this setting if the new net namespace requires
106+ connection tracking, e.g. when NAT rules are created.
107+ This setting is only visible in initial user namespace, it has no
108+ effect on existing namespaces.
109+
99110 nf_conntrack_tcp_be_liberal - BOOLEAN
100111 0 - disabled (default)
101112 not 0 - enabled
include/linux/netfilter.h+30−1
@@ -75,10 +75,39 @@ struct nf_hook_ops { · 74 unmodified lines
7575
7676 struct nf_hook_entry {
7777 struct nf_hook_entry __rcu *next;
78− struct nf_hook_ops ops;
78+ nf_hookfn *hook;
79+ void *priv;
7980 const struct nf_hook_ops *orig_ops;
8081 };
8182
83+static inline void
84+nf_hook_entry_init(struct nf_hook_entry *entry, const struct nf_hook_ops *ops)
85+{
86+ entry->next = NULL;
87+ entry->hook = ops->hook;
88+ entry->priv = ops->priv;
89+ entry->orig_ops = ops;
90+}
91+
92+static inline int
93+nf_hook_entry_priority(const struct nf_hook_entry *entry)
94+{
95+ return entry->orig_ops->priority;
96+}
97+
98+static inline int
99+nf_hook_entry_hookfn(const struct nf_hook_entry *entry, struct sk_buff *skb,
100+ struct nf_hook_state *state)
101+{
102+ return entry->hook(entry->priv, skb, state);
103+}
104+
105+static inline const struct nf_hook_ops *
106+nf_hook_entry_ops(const struct nf_hook_entry *entry)
107+{
108+ return entry->orig_ops;
109+}
110+
82111 static inline void nf_hook_state_init(struct nf_hook_state *p,
83112 unsigned int hook,
84113 u_int8_t pf,
include/linux/netfilter/nf_conntrack_dccp.h+1−1
@@ -25,7 +25,7 @@ enum ct_dccp_roles { · 24 unmodified lines
2525 #define CT_DCCP_ROLE_MAX (__CT_DCCP_ROLE_MAX - 1)
2626
2727 #ifdef __KERNEL__
28−#include <net/netfilter/nf_conntrack_tuple.h>
28+#include <linux/netfilter/nf_conntrack_tuple_common.h>
2929
3030 struct nf_ct_dccp {
3131 u_int8_t role[IP_CT_DIR_MAX];
include/linux/netfilter/x_tables.h+7−31
@@ -403,38 +403,14 @@ static inline unsigned long ifname_compare_aligned(const char *_a, · 402 unmodified lines
403403 return ret;
404404 }
405405
406+struct xt_percpu_counter_alloc_state {
407+ unsigned int off;
408+ const char __percpu *mem;
409+};
406410
407−/* On SMP, ip(6)t_entry->counters.pcnt holds address of the
408− * real (percpu) counter. On !SMP, its just the packet count,
409− * so nothing needs to be done there.
410− *
411− * xt_percpu_counter_alloc returns the address of the percpu
412− * counter, or 0 on !SMP. We force an alignment of 16 bytes
413− * so that bytes/packets share a common cache line.
414− *
415− * Hence caller must use IS_ERR_VALUE to check for error, this
416− * allows us to return 0 for single core systems without forcing
417− * callers to deal with SMP vs. NONSMP issues.
418− */
419−static inline unsigned long xt_percpu_counter_alloc(void)
420−{
421− if (nr_cpu_ids > 1) {
422− void __percpu *res = __alloc_percpu(sizeof(struct xt_counters),
423− sizeof(struct xt_counters));
424−
425− if (res == NULL)
426− return -ENOMEM;
427−
428− return (__force unsigned long) res;
429− }
430−
431− return 0;
432−}
433−static inline void xt_percpu_counter_free(u64 pcnt)
434−{
435− if (nr_cpu_ids > 1)
436− free_percpu((void __percpu *) (unsigned long) pcnt);
437−}
411+bool xt_percpu_counter_alloc(struct xt_percpu_counter_alloc_state *state,
412+ struct xt_counters *counter);
413+void xt_percpu_counter_free(struct xt_counters *cnt);
438414
439415 static inline struct xt_counters *
440416 xt_get_this_cpu_counter(struct xt_counters *cnt)
include/linux/netfilter_ingress.h+6−1
@@ -19,6 +19,7 @@ static inline int nf_hook_ingress(struct sk_buff *skb) · 18 unmodified lines
1919 {
2020 struct nf_hook_entry *e = rcu_dereference(skb->dev->nf_hooks_ingress);
2121 struct nf_hook_state state;
22+ int ret;
2223
2324 /* Must recheck the ingress hook head, in the event it became NULL
2425 * after the check in nf_hook_ingress_active evaluated to true.
@@ -29,7 +30,11 @@ static inline int nf_hook_ingress(struct sk_buff *skb) · 4 unmodified lines
2930 nf_hook_state_init(&state, NF_NETDEV_INGRESS,
3031 NFPROTO_NETDEV, skb->dev, NULL, NULL,
3132 dev_net(skb->dev), NULL);
32− return nf_hook_slow(skb, &state, e);
33+ ret = nf_hook_slow(skb, &state, e);
34+ if (ret == 0)
35+ return -1;
36+
37+ return ret;
3338 }
3439
3540 static inline void nf_hook_ingress_init(struct net_device *dev)
include/net/netfilter/ipv4/nf_conntrack_ipv4.h+9−0
@@ -15,6 +15,15 @@ extern struct nf_conntrack_l3proto nf_conntrack_l3proto_ipv4; · 14 unmodified lines
1515 extern struct nf_conntrack_l4proto nf_conntrack_l4proto_tcp4;
1616 extern struct nf_conntrack_l4proto nf_conntrack_l4proto_udp4;
1717 extern struct nf_conntrack_l4proto nf_conntrack_l4proto_icmp;
18+#ifdef CONFIG_NF_CT_PROTO_DCCP
19+extern struct nf_conntrack_l4proto nf_conntrack_l4proto_dccp4;
20+#endif
21+#ifdef CONFIG_NF_CT_PROTO_SCTP
22+extern struct nf_conntrack_l4proto nf_conntrack_l4proto_sctp4;
23+#endif
24+#ifdef CONFIG_NF_CT_PROTO_UDPLITE
25+extern struct nf_conntrack_l4proto nf_conntrack_l4proto_udplite4;
26+#endif
1827
1928 int nf_conntrack_ipv4_compat_init(void);
2029 void nf_conntrack_ipv4_compat_fini(void);
include/net/netfilter/ipv4/nf_defrag_ipv4.h+2−1
@@ -1,6 +1,7 @@
11 #ifndef _NF_DEFRAG_IPV4_H
22 #define _NF_DEFRAG_IPV4_H
33
4−void nf_defrag_ipv4_enable(void);
4+struct net;
5+int nf_defrag_ipv4_enable(struct net *);
56
67 #endif /* _NF_DEFRAG_IPV4_H */
include/net/netfilter/ipv6/nf_conntrack_ipv6.h+9−0
@@ -6,6 +6,15 @@ extern struct nf_conntrack_l3proto nf_conntrack_l3proto_ipv6; · 5 unmodified lines
66 extern struct nf_conntrack_l4proto nf_conntrack_l4proto_tcp6;
77 extern struct nf_conntrack_l4proto nf_conntrack_l4proto_udp6;
88 extern struct nf_conntrack_l4proto nf_conntrack_l4proto_icmpv6;
9+#ifdef CONFIG_NF_CT_PROTO_DCCP
10+extern struct nf_conntrack_l4proto nf_conntrack_l4proto_dccp6;
11+#endif
12+#ifdef CONFIG_NF_CT_PROTO_SCTP
13+extern struct nf_conntrack_l4proto nf_conntrack_l4proto_sctp6;
14+#endif
15+#ifdef CONFIG_NF_CT_PROTO_UDPLITE
16+extern struct nf_conntrack_l4proto nf_conntrack_l4proto_udplite6;
17+#endif
918
1019 #include <linux/sysctl.h>
1120 extern struct ctl_table nf_ct_ipv6_sysctl_table[];
include/net/netfilter/ipv6/nf_defrag_ipv6.h+2−1
@@ -1,7 +1,8 @@
11 #ifndef _NF_DEFRAG_IPV6_H
22 #define _NF_DEFRAG_IPV6_H
33
4−void nf_defrag_ipv6_enable(void);
4+struct net;
5+int nf_defrag_ipv6_enable(struct net *);
56
67 int nf_ct_frag6_init(void);
78 void nf_ct_frag6_cleanup(void);
include/net/netfilter/nf_conntrack.h+4−0
@@ -181,6 +181,10 @@ static inline void nf_ct_put(struct nf_conn *ct) · 180 unmodified lines
181181 int nf_ct_l3proto_try_module_get(unsigned short l3proto);
182182 void nf_ct_l3proto_module_put(unsigned short l3proto);
183183
184+/* load module; enable/disable conntrack in this namespace */
185+int nf_ct_netns_get(struct net *net, u8 nfproto);
186+void nf_ct_netns_put(struct net *net, u8 nfproto);
187+
184188 /*
185189 * Allocate a hashtable of hlist_head (if nulls == 0),
186190 * or hlist_nulls_head (if nulls == 1)
include/net/netfilter/nf_conntrack_l3proto.h+13−3
@@ -52,6 +52,10 @@ struct nf_conntrack_l3proto { · 51 unmodified lines
5252 int (*tuple_to_nlattr)(struct sk_buff *skb,
5353 const struct nf_conntrack_tuple *t);
5454
55+ /* Called when netns wants to use connection tracking */
56+ int (*net_ns_get)(struct net *);
57+ void (*net_ns_put)(struct net *);
58+
5559 /*
5660 * Calculate size of tuple nlattr
5761 */
@@ -63,18 +67,24 @@ struct nf_conntrack_l3proto { · 5 unmodified lines
6367
6468 size_t nla_size;
6569
66− /* Init l3proto pernet data */
67− int (*init_net)(struct net *net);
68−
6970 /* Module (if any) which this is connected to. */
7071 struct module *me;
7172 };
7273
7374 extern struct nf_conntrack_l3proto __rcu *nf_ct_l3protos[AF_MAX];
7475
76+#ifdef CONFIG_SYSCTL
7577 /* Protocol pernet registration. */
7678 int nf_ct_l3proto_pernet_register(struct net *net,
7779 struct nf_conntrack_l3proto *proto);
80+#else
81+static inline int nf_ct_l3proto_pernet_register(struct net *n,
82+ struct nf_conntrack_l3proto *p)
83+{
84+ return 0;
85+}
86+#endif
87+
7888 void nf_ct_l3proto_pernet_unregister(struct net *net,
7989 struct nf_conntrack_l3proto *proto);
8090
include/net/netfilter/nf_dup_netdev.h+1−0
@@ -2,5 +2,6 @@ · 1 unmodified line
22 #define _NF_DUP_NETDEV_H_
33
44 void nf_dup_netdev_egress(const struct nft_pktinfo *pkt, int oif);
5+void nf_fwd_netdev_egress(const struct nft_pktinfo *pkt, int oif);
56
67 #endif
include/net/netfilter/nf_log.h+3−1
@@ -109,7 +109,9 @@ void nf_log_dump_packet_common(struct nf_log_buf *m, u_int8_t pf, · 108 unmodified lines
109109 const struct net_device *out,
110110 const struct nf_loginfo *loginfo,
111111 const char *prefix);
112−void nf_log_l2packet(struct net *net, u_int8_t pf, unsigned int hooknum,
112+void nf_log_l2packet(struct net *net, u_int8_t pf,
113+ __be16 protocol,
114+ unsigned int hooknum,
113115 const struct sk_buff *skb,
114116 const struct net_device *in,
115117 const struct net_device *out,
include/net/netfilter/nf_nat_l4proto.h+9−0
@@ -54,6 +54,15 @@ extern const struct nf_nat_l4proto nf_nat_l4proto_udp; · 53 unmodified lines
5454 extern const struct nf_nat_l4proto nf_nat_l4proto_icmp;
5555 extern const struct nf_nat_l4proto nf_nat_l4proto_icmpv6;
5656 extern const struct nf_nat_l4proto nf_nat_l4proto_unknown;
57+#ifdef CONFIG_NF_NAT_PROTO_DCCP
58+extern const struct nf_nat_l4proto nf_nat_l4proto_dccp;
59+#endif
60+#ifdef CONFIG_NF_NAT_PROTO_SCTP
61+extern const struct nf_nat_l4proto nf_nat_l4proto_sctp;
62+#endif
63+#ifdef CONFIG_NF_NAT_PROTO_UDPLITE
64+extern const struct nf_nat_l4proto nf_nat_l4proto_udplite;
65+#endif
5766
5867 bool nf_nat_l4proto_in_range(const struct nf_conntrack_tuple *tuple,
5968 enum nf_nat_manip_type maniptype,
include/net/netfilter/nf_tables.h+100−1
@@ -259,7 +259,8 @@ struct nft_expr; · 258 unmodified lines
259259 * @lookup: look up an element within the set
260260 * @insert: insert new element into set
261261 * @activate: activate new element in the next generation
262− * @deactivate: deactivate element in the next generation
262+ * @deactivate: lookup for element and deactivate it in the next generation
263+ * @deactivate_one: deactivate element in the next generation
263264 * @remove: remove element from set
264265 * @walk: iterate over all set elemeennts
265266 * @privsize: function to return size of set private data
@@ -294,6 +295,9 @@ struct nft_set_ops { · 28 unmodified lines
294295 void * (*deactivate)(const struct net *net,
295296 const struct nft_set *set,
296297 const struct nft_set_elem *elem);
298+ bool (*deactivate_one)(const struct net *net,
299+ const struct nft_set *set,
300+ void *priv);
297301 void (*remove)(const struct nft_set *set,
298302 const struct nft_set_elem *elem);
299303 void (*walk)(const struct nft_ctx *ctx,
@@ -326,6 +330,7 @@ void nft_unregister_set(struct nft_set_ops *ops); · 26 unmodified lines
326330 * @name: name of the set
327331 * @ktype: key type (numeric type defined by userspace, not used in the kernel)
328332 * @dtype: data type (verdict or numeric type defined by userspace)
333+ * @objtype: object type (see NFT_OBJECT_* definitions)
329334 * @size: maximum set size
330335 * @nelems: number of elements
331336 * @ndeact: number of deactivated elements queued for removal
@@ -347,6 +352,7 @@ struct nft_set { · 15 unmodified lines
347352 char name[NFT_SET_MAXNAMELEN];
348353 u32 ktype;
349354 u32 dtype;
355+ u32 objtype;
350356 u32 size;
351357 atomic_t nelems;
352358 u32 ndeact;
@@ -416,6 +422,7 @@ void nf_tables_unbind_set(const struct nft_ctx *ctx, struct nft_set *set, · 63 unmodified lines
416422 * @NFT_SET_EXT_EXPIRATION: element expiration time
417423 * @NFT_SET_EXT_USERDATA: user data associated with the element
418424 * @NFT_SET_EXT_EXPR: expression assiociated with the element
425+ * @NFT_SET_EXT_OBJREF: stateful object reference associated with element
419426 * @NFT_SET_EXT_NUM: number of extension types
420427 */
421428 enum nft_set_extensions {
@@ -426,6 +433,7 @@ enum nft_set_extensions { · 4 unmodified lines
426433 NFT_SET_EXT_EXPIRATION,
427434 NFT_SET_EXT_USERDATA,
428435 NFT_SET_EXT_EXPR,
436+ NFT_SET_EXT_OBJREF,
429437 NFT_SET_EXT_NUM
430438 };
431439
@@ -554,6 +562,11 @@ static inline struct nft_set_ext *nft_set_elem_ext(const struct nft_set *set, · 122 unmodified lines
554562 return elem + set->ops->elemsize;
555563 }
556564
565+static inline struct nft_object **nft_set_ext_obj(const struct nft_set_ext *ext)
566+{
567+ return nft_set_ext(ext, NFT_SET_EXT_OBJREF);
568+}
569+
557570 void *nft_set_elem_init(const struct nft_set *set,
558571 const struct nft_set_ext_tmpl *tmpl,
559572 const u32 *key, const u32 *data,
@@ -875,6 +888,7 @@ unsigned int nft_do_chain(struct nft_pktinfo *pkt, void *priv); · 315 unmodified lines
875888 * @list: used internally
876889 * @chains: chains in the table
877890 * @sets: sets in the table
891+ * @objects: stateful objects in the table
878892 * @hgenerator: handle generator state
879893 * @use: number of chain references to this table
880894 * @flags: table flag (see enum nft_table_flags)
@@ -885,6 +899,7 @@ struct nft_table { · 4 unmodified lines
885899 struct list_head list;
886900 struct list_head chains;
887901 struct list_head sets;
902+ struct list_head objects;
888903 u64 hgenerator;
889904 u32 use;
890905 u16 flags:14,
@@ -934,6 +949,80 @@ void nft_unregister_expr(struct nft_expr_type *); · 43 unmodified lines
934949 int nft_verdict_dump(struct sk_buff *skb, int type,
935950 const struct nft_verdict *v);
936951
952+/**
953+ * struct nft_object - nf_tables stateful object
954+ *
955+ * @list: table stateful object list node
956+ * @table: table this object belongs to
957+ * @type: pointer to object type
958+ * @data: pointer to object data
959+ * @name: name of this stateful object
960+ * @genmask: generation mask
961+ * @use: number of references to this stateful object
962+ * @data: object data, layout depends on type
963+ */
964+struct nft_object {
965+ struct list_head list;
966+ char name[NFT_OBJ_MAXNAMELEN];
967+ struct nft_table *table;
968+ u32 genmask:2,
969+ use:30;
970+ /* runtime data below here */
971+ const struct nft_object_type *type ____cacheline_aligned;
972+ unsigned char data[]
973+ __attribute__((aligned(__alignof__(u64))));
974+};
975+
976+static inline void *nft_obj_data(const struct nft_object *obj)
977+{
978+ return (void *)obj->data;
979+}
980+
981+#define nft_expr_obj(expr) *((struct nft_object **)nft_expr_priv(expr))
982+
983+struct nft_object *nf_tables_obj_lookup(const struct nft_table *table,
984+ const struct nlattr *nla, u32 objtype,
985+ u8 genmask);
986+
987+int nft_obj_notify(struct net *net, struct nft_table *table,
988+ struct nft_object *obj, u32 portid, u32 seq,
989+ int event, int family, int report, gfp_t gfp);
990+
991+/**
992+ * struct nft_object_type - stateful object type
993+ *
994+ * @eval: stateful object evaluation function
995+ * @list: list node in list of object types
996+ * @type: stateful object numeric type
997+ * @size: stateful object size
998+ * @owner: module owner
999+ * @maxattr: maximum netlink attribute
1000+ * @policy: netlink attribute policy
1001+ * @init: initialize object from netlink attributes
1002+ * @destroy: release existing stateful object
1003+ * @dump: netlink dump stateful object
1004+ */
1005+struct nft_object_type {
1006+ void (*eval)(struct nft_object *obj,
1007+ struct nft_regs *regs,
1008+ const struct nft_pktinfo *pkt);
1009+ struct list_head list;
1010+ u32 type;
1011+ unsigned int size;
1012+ unsigned int maxattr;
1013+ struct module *owner;
1014+ const struct nla_policy *policy;
1015+ int (*init)(const struct nlattr * const tb[],
1016+ struct nft_object *obj);
1017+ void (*destroy)(struct nft_object *obj);
1018+ int (*dump)(struct sk_buff *skb,
1019+ struct nft_object *obj,
1020+ bool reset);
1021+};
1022+
1023+int nft_register_obj(struct nft_object_type *obj_type);
1024+void nft_unregister_obj(struct nft_object_type *obj_type);
1025+
9371026 /**
9381027 * struct nft_traceinfo - nft tracing information and state
9391028 *
@@ -981,6 +1070,9 @@ void nft_trace_notify(struct nft_traceinfo *info); · 41 unmodified lines
9811070 #define MODULE_ALIAS_NFT_SET() \
9821071 MODULE_ALIAS("nft-set")
9831072
1073+#define MODULE_ALIAS_NFT_OBJ(type) \
1074+ MODULE_ALIAS("nft-obj-" __stringify(type))
1075+
9841076 /*
9851077 * The gencursor defines two generations, the currently active and the
9861078 * next one. Objects contain a bitmask of 2 bits specifying the generations
@@ -1157,4 +1249,11 @@ struct nft_trans_elem { · 170 unmodified lines
11571249 #define nft_trans_elem(trans) \
11581250 (((struct nft_trans_elem *)trans->data)->elem)
11591251
1252+struct nft_trans_obj {
1253+ struct nft_object *obj;
1254+};
1255+
1256+#define nft_trans_obj(trans) \
1257+ (((struct nft_trans_obj *)trans->data)->obj)
1258+
11601259 #endif /* _NET_NF_TABLES_H */
include/net/netfilter/nf_tables_core.h+1−0
@@ -45,6 +45,7 @@ struct nft_payload_set { · 44 unmodified lines
4545 enum nft_registers sreg:8;
4646 u8 csum_type;
4747 u8 csum_offset;
48+ u8 csum_flags;
4849 };
4950
5051 extern const struct nft_expr_ops nft_payload_fast_ops;
include/net/netns/conntrack.h+43−0
@@ -6,6 +6,12 @@ · 5 unmodified lines
66 #include <linux/atomic.h>
77 #include <linux/workqueue.h>
88 #include <linux/netfilter/nf_conntrack_tcp.h>
9+#ifdef CONFIG_NF_CT_PROTO_DCCP
10+#include <linux/netfilter/nf_conntrack_dccp.h>
11+#endif
12+#ifdef CONFIG_NF_CT_PROTO_SCTP
13+#include <linux/netfilter/nf_conntrack_sctp.h>
14+#endif
915 #include <linux/seqlock.h>
1016
1117 struct ctl_table_header;
@@ -48,12 +54,49 @@ struct nf_icmp_net { · 36 unmodified lines
4854 unsigned int timeout;
4955 };
5056
57+#ifdef CONFIG_NF_CT_PROTO_DCCP
58+struct nf_dccp_net {
59+ struct nf_proto_net pn;
60+ int dccp_loose;
61+ unsigned int dccp_timeout[CT_DCCP_MAX + 1];
62+};
63+#endif
64+
65+#ifdef CONFIG_NF_CT_PROTO_SCTP
66+struct nf_sctp_net {
67+ struct nf_proto_net pn;
68+ unsigned int timeouts[SCTP_CONNTRACK_MAX];
69+};
70+#endif
71+
72+#ifdef CONFIG_NF_CT_PROTO_UDPLITE
73+enum udplite_conntrack {
74+ UDPLITE_CT_UNREPLIED,
75+ UDPLITE_CT_REPLIED,
76+ UDPLITE_CT_MAX
77+};
78+
79+struct nf_udplite_net {
80+ struct nf_proto_net pn;
81+ unsigned int timeouts[UDPLITE_CT_MAX];
82+};
83+#endif
84+
5185 struct nf_ip_net {
5286 struct nf_generic_net generic;
5387 struct nf_tcp_net tcp;
5488 struct nf_udp_net udp;
5589 struct nf_icmp_net icmp;
5690 struct nf_icmp_net icmpv6;
91+#ifdef CONFIG_NF_CT_PROTO_DCCP
92+ struct nf_dccp_net dccp;
93+#endif
94+#ifdef CONFIG_NF_CT_PROTO_SCTP
95+ struct nf_sctp_net sctp;
96+#endif
97+#ifdef CONFIG_NF_CT_PROTO_UDPLITE
98+ struct nf_udplite_net udplite;
99+#endif
57100 };
58101
59102 struct ct_pcpu {
include/net/netns/netfilter.h+6−0
@@ -17,5 +17,11 @@ struct netns_nf { · 16 unmodified lines
1717 struct ctl_table_header *nf_log_dir_header;
1818 #endif
1919 struct nf_hook_entry __rcu *hooks[NFPROTO_NUMPROTO][NF_MAX_HOOKS];
20+#if IS_ENABLED(CONFIG_NF_DEFRAG_IPV4)
21+ bool defrag_ipv4;
22+#endif
23+#if IS_ENABLED(CONFIG_NF_DEFRAG_IPV6)
24+ bool defrag_ipv6;
25+#endif
2026 };
2127 #endif
include/uapi/linux/netfilter/nf_conntrack_tuple_common.h+3−0
@@ -2,7 +2,10 @@ · 1 unmodified line
22 #define _NF_CONNTRACK_TUPLE_COMMON_H
33
44 #include <linux/types.h>
5+#ifndef __KERNEL__
56 #include <linux/netfilter.h>
7+#endif
8+#include <linux/netfilter/nf_conntrack_common.h> /* IP_CT_IS_REPLY */
69
710 enum ip_conntrack_dir {
811 IP_CT_DIR_ORIGINAL,
include/uapi/linux/netfilter/nf_tables.h+70−0
@@ -4,6 +4,7 @@ · 3 unmodified lines
44 #define NFT_TABLE_MAXNAMELEN 32
55 #define NFT_CHAIN_MAXNAMELEN 32
66 #define NFT_SET_MAXNAMELEN 32
7+#define NFT_OBJ_MAXNAMELEN 32
78 #define NFT_USERDATA_MAXLEN 256
89
910 /**
@@ -85,6 +86,10 @@ enum nft_verdicts { · 75 unmodified lines
8586 * @NFT_MSG_NEWGEN: announce a new generation, only for events (enum nft_gen_attributes)
8687 * @NFT_MSG_GETGEN: get the rule-set generation (enum nft_gen_attributes)
8788 * @NFT_MSG_TRACE: trace event (enum nft_trace_attributes)
89+ * @NFT_MSG_NEWOBJ: create a stateful object (enum nft_obj_attributes)
90+ * @NFT_MSG_GETOBJ: get a stateful object (enum nft_obj_attributes)
91+ * @NFT_MSG_DELOBJ: delete a stateful object (enum nft_obj_attributes)
92+ * @NFT_MSG_GETOBJ_RESET: get and reset a stateful object (enum nft_obj_attributes)
8893 */
8994 enum nf_tables_msg_types {
9095 NFT_MSG_NEWTABLE,
@@ -105,6 +110,10 @@ enum nf_tables_msg_types { · 14 unmodified lines
105110 NFT_MSG_NEWGEN,
106111 NFT_MSG_GETGEN,
107112 NFT_MSG_TRACE,
113+ NFT_MSG_NEWOBJ,
114+ NFT_MSG_GETOBJ,
115+ NFT_MSG_DELOBJ,
116+ NFT_MSG_GETOBJ_RESET,
108117 NFT_MSG_MAX,
109118 };
110119
@@ -246,6 +255,7 @@ enum nft_rule_compat_attributes { · 135 unmodified lines
246255 * @NFT_SET_MAP: set is used as a dictionary
247256 * @NFT_SET_TIMEOUT: set uses timeouts
248257 * @NFT_SET_EVAL: set contains expressions for evaluation
258+ * @NFT_SET_OBJECT: set contains stateful objects
249259 */
250260 enum nft_set_flags {
251261 NFT_SET_ANONYMOUS = 0x1,
@@ -254,6 +264,7 @@ enum nft_set_flags { · 2 unmodified lines
254264 NFT_SET_MAP = 0x8,
255265 NFT_SET_TIMEOUT = 0x10,
256266 NFT_SET_EVAL = 0x20,
267+ NFT_SET_OBJECT = 0x40,
257268 };
258269
259270 /**
@@ -295,6 +306,7 @@ enum nft_set_desc_attributes { · 35 unmodified lines
295306 * @NFTA_SET_TIMEOUT: default timeout value (NLA_U64)
296307 * @NFTA_SET_GC_INTERVAL: garbage collection interval (NLA_U32)
297308 * @NFTA_SET_USERDATA: user data (NLA_BINARY)
309+ * @NFTA_SET_OBJ_TYPE: stateful object type (NLA_U32: NFT_OBJECT_*)
298310 */
299311 enum nft_set_attributes {
300312 NFTA_SET_UNSPEC,
@@ -312,6 +324,7 @@ enum nft_set_attributes { · 11 unmodified lines
312324 NFTA_SET_GC_INTERVAL,
313325 NFTA_SET_USERDATA,
314326 NFTA_SET_PAD,
327+ NFTA_SET_OBJ_TYPE,
315328 __NFTA_SET_MAX
316329 };
317330 #define NFTA_SET_MAX (__NFTA_SET_MAX - 1)
@@ -335,6 +348,7 @@ enum nft_set_elem_flags { · 17 unmodified lines
335348 * @NFTA_SET_ELEM_EXPIRATION: expiration time (NLA_U64)
336349 * @NFTA_SET_ELEM_USERDATA: user data (NLA_BINARY)
337350 * @NFTA_SET_ELEM_EXPR: expression (NLA_NESTED: nft_expr_attributes)
351+ * @NFTA_SET_ELEM_OBJREF: stateful object reference (NLA_STRING)
338352 */
339353 enum nft_set_elem_attributes {
340354 NFTA_SET_ELEM_UNSPEC,
@@ -346,6 +360,7 @@ enum nft_set_elem_attributes { · 5 unmodified lines
346360 NFTA_SET_ELEM_USERDATA,
347361 NFTA_SET_ELEM_EXPR,
348362 NFTA_SET_ELEM_PAD,
363+ NFTA_SET_ELEM_OBJREF,
349364 __NFTA_SET_ELEM_MAX
350365 };
351366 #define NFTA_SET_ELEM_MAX (__NFTA_SET_ELEM_MAX - 1)
@@ -659,6 +674,10 @@ enum nft_payload_csum_types { · 307 unmodified lines
659674 NFT_PAYLOAD_CSUM_INET,
660675 };
661676
677+enum nft_payload_csum_flags {
678+ NFT_PAYLOAD_L4CSUM_PSEUDOHDR = (1 << 0),
679+};
680+
662681 /**
663682 * enum nft_payload_attributes - nf_tables payload expression netlink attributes
664683 *
@@ -669,6 +688,7 @@ enum nft_payload_csum_types { · 4 unmodified lines
669688 * @NFTA_PAYLOAD_SREG: source register to load data from (NLA_U32: nft_registers)
670689 * @NFTA_PAYLOAD_CSUM_TYPE: checksum type (NLA_U32)
671690 * @NFTA_PAYLOAD_CSUM_OFFSET: checksum offset relative to base (NLA_U32)
691+ * @NFTA_PAYLOAD_CSUM_FLAGS: checksum flags (NLA_U32)
672692 */
673693 enum nft_payload_attributes {
674694 NFTA_PAYLOAD_UNSPEC,
@@ -679,6 +699,7 @@ enum nft_payload_attributes { · 4 unmodified lines
679699 NFTA_PAYLOAD_SREG,
680700 NFTA_PAYLOAD_CSUM_TYPE,
681701 NFTA_PAYLOAD_CSUM_OFFSET,
702+ NFTA_PAYLOAD_CSUM_FLAGS,
682703 __NFTA_PAYLOAD_MAX
683704 };
684705 #define NFTA_PAYLOAD_MAX (__NFTA_PAYLOAD_MAX - 1)
@@ -968,6 +989,7 @@ enum nft_queue_attributes { · 283 unmodified lines
968989
969990 enum nft_quota_flags {
970991 NFT_QUOTA_F_INV = (1 << 0),
992+ NFT_QUOTA_F_DEPLETED = (1 << 1),
971993 };
972994
973995 /**
@@ -975,12 +997,14 @@ enum nft_quota_flags { · 1 unmodified line
975997 *
976998 * @NFTA_QUOTA_BYTES: quota in bytes (NLA_U16)
977999 * @NFTA_QUOTA_FLAGS: flags (NLA_U32)
1000+ * @NFTA_QUOTA_CONSUMED: quota already consumed in bytes (NLA_U64)
9781001 */
9791002 enum nft_quota_attributes {
9801003 NFTA_QUOTA_UNSPEC,
9811004 NFTA_QUOTA_BYTES,
9821005 NFTA_QUOTA_FLAGS,
9831006 NFTA_QUOTA_PAD,
1007+ NFTA_QUOTA_CONSUMED,
9841008 __NFTA_QUOTA_MAX
9851009 };
9861010 #define NFTA_QUOTA_MAX (__NFTA_QUOTA_MAX - 1)
@@ -1124,6 +1148,26 @@ enum nft_fwd_attributes { · 137 unmodified lines
11241148 };
11251149 #define NFTA_FWD_MAX (__NFTA_FWD_MAX - 1)
11261150
1151+/**
1152+ * enum nft_objref_attributes - nf_tables stateful object expression netlink attributes
1153+ *
1154+ * @NFTA_OBJREF_IMM_TYPE: object type for immediate reference (NLA_U32: nft_register)
1155+ * @NFTA_OBJREF_IMM_NAME: object name for immediate reference (NLA_STRING)
1156+ * @NFTA_OBJREF_SET_SREG: source register of the data to look for (NLA_U32: nft_registers)
1157+ * @NFTA_OBJREF_SET_NAME: name of the set where to look for (NLA_STRING)
1158+ * @NFTA_OBJREF_SET_ID: id of the set where to look for in this transaction (NLA_U32)
1159+ */
1160+enum nft_objref_attributes {
1161+ NFTA_OBJREF_UNSPEC,
1162+ NFTA_OBJREF_IMM_TYPE,
1163+ NFTA_OBJREF_IMM_NAME,
1164+ NFTA_OBJREF_SET_SREG,
1165+ NFTA_OBJREF_SET_NAME,
1166+ NFTA_OBJREF_SET_ID,
1167+ __NFTA_OBJREF_MAX
1168+};
1169+#define NFTA_OBJREF_MAX (__NFTA_OBJREF_MAX - 1)
1170+
11271171 /**
11281172 * enum nft_gen_attributes - nf_tables ruleset generation attributes
11291173 *
@@ -1172,6 +1216,32 @@ enum nft_fib_flags { · 42 unmodified lines
11721216 NFTA_FIB_F_OIF = 1 << 4, /* restrict to oif */
11731217 };
11741218
1219+#define NFT_OBJECT_UNSPEC 0
1220+#define NFT_OBJECT_COUNTER 1
1221+#define NFT_OBJECT_QUOTA 2
1222+#define __NFT_OBJECT_MAX 3
1223+#define NFT_OBJECT_MAX (__NFT_OBJECT_MAX - 1)
1224+
1225+/**
1226+ * enum nft_object_attributes - nf_tables stateful object netlink attributes
1227+ *
1228+ * @NFTA_OBJ_TABLE: name of the table containing the expression (NLA_STRING)
1229+ * @NFTA_OBJ_NAME: name of this expression type (NLA_STRING)
1230+ * @NFTA_OBJ_TYPE: stateful object type (NLA_U32)
1231+ * @NFTA_OBJ_DATA: stateful object data (NLA_NESTED)
1232+ * @NFTA_OBJ_USE: number of references to this expression (NLA_U32)
1233+ */
1234+enum nft_object_attributes {
1235+ NFTA_OBJ_UNSPEC,
1236+ NFTA_OBJ_TABLE,
1237+ NFTA_OBJ_NAME,
1238+ NFTA_OBJ_TYPE,
1239+ NFTA_OBJ_DATA,
1240+ NFTA_OBJ_USE,
1241+ __NFTA_OBJ_MAX
1242+};
1243+#define NFTA_OBJ_MAX (__NFTA_OBJ_MAX - 1)
1244+
11751245 /**
11761246 * enum nft_trace_attributes - nf_tables trace netlink attributes
11771247 *
include/uapi/linux/netfilter/xt_bpf.h+21−0
@@ -2,9 +2,11 @@ · 1 unmodified line
22 #define _XT_BPF_H
33
44 #include <linux/filter.h>
5+#include <linux/limits.h>
56 #include <linux/types.h>
67
78 #define XT_BPF_MAX_NUM_INSTR 64
9+#define XT_BPF_PATH_MAX (XT_BPF_MAX_NUM_INSTR * sizeof(struct sock_filter))
810
911 struct bpf_prog;
1012
@@ -16,4 +18,23 @@ struct xt_bpf_info { · 5 unmodified lines
1618 struct bpf_prog *filter __attribute__((aligned(8)));
1719 };
1820
21+enum xt_bpf_modes {
22+ XT_BPF_MODE_BYTECODE,
23+ XT_BPF_MODE_FD_PINNED,
24+ XT_BPF_MODE_FD_ELF,
25+};
26+
27+struct xt_bpf_info_v1 {
28+ __u16 mode;
29+ __u16 bpf_program_num_elem;
30+ __s32 fd;
31+ union {
32+ struct sock_filter bpf_program[XT_BPF_MAX_NUM_INSTR];
33+ char path[XT_BPF_PATH_MAX];
34+ };
35+
36+ /* only used in the kernel */
37+ struct bpf_prog *filter __attribute__((aligned(8)));
38+};
39+
1940 #endif /*_XT_BPF_H */
net/bridge/br_netfilter_hooks.c+4−4
@@ -1008,10 +1008,10 @@ int br_nf_hook_thresh(unsigned int hook, struct net *net, · 1007 unmodified lines
10081008 struct nf_hook_state state;
10091009 int ret;
10101010
1011− elem = rcu_dereference(net->nf.hooks[NFPROTO_BRIDGE][hook]);
1012−
1013− while (elem && (elem->ops.priority <= NF_BR_PRI_BRNF))
1014− elem = rcu_dereference(elem->next);
1011+ for (elem = rcu_dereference(net->nf.hooks[NFPROTO_BRIDGE][hook]);
1012+ elem && nf_hook_entry_priority(elem) <= NF_BR_PRI_BRNF;
1013+ elem = rcu_dereference(elem->next))
1014+ ;
10151015
10161016 if (!elem)
10171017 return okfn(net, sk, skb);
net/bridge/netfilter/nf_log_bridge.c+2−1
@@ -24,7 +24,8 @@ static void nf_log_bridge_packet(struct net *net, u_int8_t pf, · 23 unmodified lines
2424 const struct nf_loginfo *loginfo,
2525 const char *prefix)
2626 {
27− nf_log_l2packet(net, pf, hooknum, skb, in, out, loginfo, prefix);
27+ nf_log_l2packet(net, pf, eth_hdr(skb)->h_proto, hooknum, skb,
28+ in, out, loginfo, prefix);
2829 }
2930
3031 static struct nf_logger nf_bridge_logger __read_mostly = {
net/ipv4/netfilter/arp_tables.c+8−8
@@ -411,17 +411,15 @@ static inline int check_target(struct arpt_entry *e, const char *name) · 410 unmodified lines
411411 }
412412
413413 static inline int
414−find_check_entry(struct arpt_entry *e, const char *name, unsigned int size)
414+find_check_entry(struct arpt_entry *e, const char *name, unsigned int size,
415+ struct xt_percpu_counter_alloc_state *alloc_state)
415416 {
416417 struct xt_entry_target *t;
417418 struct xt_target *target;
418− unsigned long pcnt;
419419 int ret;
420420
421− pcnt = xt_percpu_counter_alloc();
422− if (IS_ERR_VALUE(pcnt))
421+ if (!xt_percpu_counter_alloc(alloc_state, &e->counters))
423422 return -ENOMEM;
424− e->counters.pcnt = pcnt;
425423
426424 t = arpt_get_target(e);
427425 target = xt_request_find_target(NFPROTO_ARP, t->u.user.name,
@@ -439,7 +437,7 @@ find_check_entry(struct arpt_entry *e, const char *name, unsigned int size) · 11 unmodified lines
439437 err:
440438 module_put(t->u.kernel.target->me);
441439 out:
442− xt_percpu_counter_free(e->counters.pcnt);
440+ xt_percpu_counter_free(&e->counters);
443441
444442 return ret;
445443 }
@@ -519,7 +517,7 @@ static inline void cleanup_entry(struct arpt_entry *e) · 73 unmodified lines
519517 if (par.target->destroy != NULL)
520518 par.target->destroy(&par);
521519 module_put(par.target->me);
522− xt_percpu_counter_free(e->counters.pcnt);
520+ xt_percpu_counter_free(&e->counters);
523521 }
524522
525523 /* Checks and translates the user-supplied table segment (held in
@@ -528,6 +526,7 @@ static inline void cleanup_entry(struct arpt_entry *e) · 2 unmodified lines
528526 static int translate_table(struct xt_table_info *newinfo, void *entry0,
529527 const struct arpt_replace *repl)
530528 {
529+ struct xt_percpu_counter_alloc_state alloc_state = { 0 };
531530 struct arpt_entry *iter;
532531 unsigned int *offsets;
533532 unsigned int i;
@@ -590,7 +589,8 @@ static int translate_table(struct xt_table_info *newinfo, void *entry0, · 56 unmodified lines
590589 /* Finally, each sanity check must pass */
591590 i = 0;
592591 xt_entry_foreach(iter, entry0, newinfo->size) {
593− ret = find_check_entry(iter, repl->name, repl->size);
592+ ret = find_check_entry(iter, repl->name, repl->size,
593+ &alloc_state);
594594 if (ret != 0)
595595 break;
596596 ++i;
net/ipv4/netfilter/ip_tables.c+8−8
@@ -531,7 +531,8 @@ static int check_target(struct ipt_entry *e, struct net *net, const char *name) · 530 unmodified lines
531531
532532 static int
533533 find_check_entry(struct ipt_entry *e, struct net *net, const char *name,
534− unsigned int size)
534+ unsigned int size,
535+ struct xt_percpu_counter_alloc_state *alloc_state)
535536 {
536537 struct xt_entry_target *t;
537538 struct xt_target *target;
@@ -539,12 +540,9 @@ find_check_entry(struct ipt_entry *e, struct net *net, const char *name, · 1 unmodified line
539540 unsigned int j;
540541 struct xt_mtchk_param mtpar;
541542 struct xt_entry_match *ematch;
542− unsigned long pcnt;
543543
544− pcnt = xt_percpu_counter_alloc();
545− if (IS_ERR_VALUE(pcnt))
544+ if (!xt_percpu_counter_alloc(alloc_state, &e->counters))
546545 return -ENOMEM;
547− e->counters.pcnt = pcnt;
548546
549547 j = 0;
550548 mtpar.net = net;
@@ -582,7 +580,7 @@ find_check_entry(struct ipt_entry *e, struct net *net, const char *name, · 31 unmodified lines
582580 cleanup_match(ematch, net);
583581 }
584582
585− xt_percpu_counter_free(e->counters.pcnt);
583+ xt_percpu_counter_free(&e->counters);
586584
587585 return ret;
588586 }
@@ -670,7 +668,7 @@ cleanup_entry(struct ipt_entry *e, struct net *net) · 81 unmodified lines
670668 if (par.target->destroy != NULL)
671669 par.target->destroy(&par);
672670 module_put(par.target->me);
673− xt_percpu_counter_free(e->counters.pcnt);
671+ xt_percpu_counter_free(&e->counters);
674672 }
675673
676674 /* Checks and translates the user-supplied table segment (held in
@@ -679,6 +677,7 @@ static int · 2 unmodified lines
679677 translate_table(struct net *net, struct xt_table_info *newinfo, void *entry0,
680678 const struct ipt_replace *repl)
681679 {
680+ struct xt_percpu_counter_alloc_state alloc_state = { 0 };
682681 struct ipt_entry *iter;
683682 unsigned int *offsets;
684683 unsigned int i;
@@ -738,7 +737,8 @@ translate_table(struct net *net, struct xt_table_info *newinfo, void *entry0, · 53 unmodified lines
738737 /* Finally, each sanity check must pass */
739738 i = 0;
740739 xt_entry_foreach(iter, entry0, newinfo->size) {
741− ret = find_check_entry(iter, net, repl->name, repl->size);
740+ ret = find_check_entry(iter, net, repl->name, repl->size,
741+ &alloc_state);
742742 if (ret != 0)
743743 break;
744744 ++i;
net/ipv4/netfilter/ipt_CLUSTERIP.c+2−2
@@ -419,7 +419,7 @@ static int clusterip_tg_check(const struct xt_tgchk_param *par) · 418 unmodified lines
419419 }
420420 cipinfo->config = config;
421421
422− ret = nf_ct_l3proto_try_module_get(par->family);
422+ ret = nf_ct_netns_get(par->net, par->family);
423423 if (ret < 0)
424424 pr_info("cannot load conntrack support for proto=%u\n",
425425 par->family);
@@ -444,7 +444,7 @@ static void clusterip_tg_destroy(const struct xt_tgdtor_param *par) · 18 unmodified lines
444444
445445 clusterip_config_put(cipinfo->config);
446446
447− nf_ct_l3proto_module_put(par->family);
447+ nf_ct_netns_get(par->net, par->family);
448448 }
449449
450450 #ifdef CONFIG_COMPAT
net/ipv4/netfilter/ipt_MASQUERADE.c+7−1
@@ -41,7 +41,7 @@ static int masquerade_tg_check(const struct xt_tgchk_param *par) · 40 unmodified lines
4141 pr_debug("bad rangesize %u\n", mr->rangesize);
4242 return -EINVAL;
4343 }
44− return 0;
44+ return nf_ct_netns_get(par->net, par->family);
4545 }
4646
4747 static unsigned int
@@ -59,6 +59,11 @@ masquerade_tg(struct sk_buff *skb, const struct xt_action_param *par) · 11 unmodified lines
5959 xt_out(par));
6060 }
6161
62+static void masquerade_tg_destroy(const struct xt_tgdtor_param *par)
63+{
64+ nf_ct_netns_put(par->net, par->family);
65+}
66+
6267 static struct xt_target masquerade_tg_reg __read_mostly = {
6368 .name = "MASQUERADE",
6469 .family = NFPROTO_IPV4,
@@ -67,6 +72,7 @@ static struct xt_target masquerade_tg_reg __read_mostly = { · 2 unmodified lines
6772 .table = "nat",
6873 .hooks = 1 << NF_INET_POST_ROUTING,
6974 .checkentry = masquerade_tg_check,
75+ .destroy = masquerade_tg_destroy,
7076 .me = THIS_MODULE,
7177 };
7278
net/ipv4/netfilter/ipt_SYNPROXY.c+2−2
@@ -418,12 +418,12 @@ static int synproxy_tg4_check(const struct xt_tgchk_param *par) · 417 unmodified lines
418418 e->ip.invflags & XT_INV_PROTO)
419419 return -EINVAL;
420420
421− return nf_ct_l3proto_try_module_get(par->family);
421+ return nf_ct_netns_get(par->net, par->family);
422422 }
423423
424424 static void synproxy_tg4_destroy(const struct xt_tgdtor_param *par)
425425 {
426− nf_ct_l3proto_module_put(par->family);
426+ nf_ct_netns_put(par->net, par->family);
427427 }
428428
429429 static struct xt_target synproxy_tg4_reg __read_mostly = {
net/ipv4/netfilter/ipt_rpfilter.c+5−3
@@ -83,10 +83,12 @@ static bool rpfilter_mt(const struct sk_buff *skb, struct xt_action_param *par) · 82 unmodified lines
8383 return true ^ invert;
8484
8585 iph = ip_hdr(skb);
86− if (ipv4_is_multicast(iph->daddr)) {
87− if (ipv4_is_zeronet(iph->saddr))
88− return ipv4_is_local_multicast(iph->daddr) ^ invert;
86+ if (ipv4_is_zeronet(iph->saddr)) {
87+ if (ipv4_is_lbcast(iph->daddr) ||
88+ ipv4_is_local_multicast(iph->daddr))
89+ return true ^ invert;
8990 }
91+
9092 flow.flowi4_iif = LOOPBACK_IFINDEX;
9193 flow.daddr = iph->saddr;
9294 flow.saddr = rpfilter_get_saddr(iph->daddr);
net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c+56−15
@@ -31,6 +31,13 @@ · 30 unmodified lines
3131 #include <net/netfilter/ipv4/nf_defrag_ipv4.h>
3232 #include <net/netfilter/nf_log.h>
3333
34+static int conntrack4_net_id __read_mostly;
35+static DEFINE_MUTEX(register_ipv4_hooks);
36+
37+struct conntrack4_net {
38+ unsigned int users;
39+};
40+
3441 static bool ipv4_pkt_to_tuple(const struct sk_buff *skb, unsigned int nhoff,
3542 struct nf_conntrack_tuple *tuple)
3643 {
@@ -307,9 +314,42 @@ static struct nf_sockopt_ops so_getorigdst = { · 270 unmodified lines
307314 .owner = THIS_MODULE,
308315 };
309316
310−static int ipv4_init_net(struct net *net)
317+static int ipv4_hooks_register(struct net *net)
311318 {
312− return 0;
319+ struct conntrack4_net *cnet = net_generic(net, conntrack4_net_id);
320+ int err = 0;
321+
322+ mutex_lock(&register_ipv4_hooks);
323+
324+ cnet->users++;
325+ if (cnet->users > 1)
326+ goto out_unlock;
327+
328+ err = nf_defrag_ipv4_enable(net);
329+ if (err) {
330+ cnet->users = 0;
331+ goto out_unlock;
332+ }
333+
334+ err = nf_register_net_hooks(net, ipv4_conntrack_ops,
335+ ARRAY_SIZE(ipv4_conntrack_ops));
336+
337+ if (err)
338+ cnet->users = 0;
339+ out_unlock:
340+ mutex_unlock(&register_ipv4_hooks);
341+ return err;
342+}
343+
344+static void ipv4_hooks_unregister(struct net *net)
345+{
346+ struct conntrack4_net *cnet = net_generic(net, conntrack4_net_id);
347+
348+ mutex_lock(&register_ipv4_hooks);
349+ if (cnet->users && (--cnet->users == 0))
350+ nf_unregister_net_hooks(net, ipv4_conntrack_ops,
351+ ARRAY_SIZE(ipv4_conntrack_ops));
352+ mutex_unlock(&register_ipv4_hooks);
313353 }
314354
315355 struct nf_conntrack_l3proto nf_conntrack_l3proto_ipv4 __read_mostly = {
@@ -325,7 +365,8 @@ struct nf_conntrack_l3proto nf_conntrack_l3proto_ipv4 __read_mostly = { · 9 unmodified lines
325365 .nlattr_to_tuple = ipv4_nlattr_to_tuple,
326366 .nla_policy = ipv4_nla_policy,
327367 #endif
328− .init_net = ipv4_init_net,
368+ .net_ns_get = ipv4_hooks_register,
369+ .net_ns_put = ipv4_hooks_unregister,
329370 .me = THIS_MODULE,
330371 };
331372
@@ -340,6 +381,15 @@ static struct nf_conntrack_l4proto *builtin_l4proto4[] = { · 8 unmodified lines
340381 &nf_conntrack_l4proto_tcp4,
341382 &nf_conntrack_l4proto_udp4,
342383 &nf_conntrack_l4proto_icmp,
384+#ifdef CONFIG_NF_CT_PROTO_DCCP
385+ &nf_conntrack_l4proto_dccp4,
386+#endif
387+#ifdef CONFIG_NF_CT_PROTO_SCTP
388+ &nf_conntrack_l4proto_sctp4,
389+#endif
390+#ifdef CONFIG_NF_CT_PROTO_UDPLITE
391+ &nf_conntrack_l4proto_udplite4,
392+#endif
343393 };
344394
345395 static int ipv4_net_init(struct net *net)
@@ -369,6 +419,8 @@ static void ipv4_net_exit(struct net *net) · 23 unmodified lines
369419 static struct pernet_operations ipv4_net_ops = {
370420 .init = ipv4_net_init,
371421 .exit = ipv4_net_exit,
422+ .id = &conntrack4_net_id,
423+ .size = sizeof(struct conntrack4_net),
372424 };
373425
374426 static int __init nf_conntrack_l3proto_ipv4_init(void)
@@ -376,7 +428,6 @@ static int __init nf_conntrack_l3proto_ipv4_init(void) · 1 unmodified line
376428 int ret = 0;
377429
378430 need_conntrack();
379− nf_defrag_ipv4_enable();
380431
381432 ret = nf_register_sockopt(&so_getorigdst);
382433 if (ret < 0) {
@@ -390,17 +441,10 @@ static int __init nf_conntrack_l3proto_ipv4_init(void) · 7 unmodified lines
390441 goto cleanup_sockopt;
391442 }
392443
393− ret = nf_register_hooks(ipv4_conntrack_ops,
394− ARRAY_SIZE(ipv4_conntrack_ops));
395− if (ret < 0) {
396− pr_err("nf_conntrack_ipv4: can't register hooks.\n");
397− goto cleanup_pernet;
398− }
399−
400444 ret = nf_ct_l4proto_register(builtin_l4proto4,
401445 ARRAY_SIZE(builtin_l4proto4));
402446 if (ret < 0)
403− goto cleanup_hooks;
447+ goto cleanup_pernet;
404448
405449 ret = nf_ct_l3proto_register(&nf_conntrack_l3proto_ipv4);
406450 if (ret < 0) {
@@ -412,8 +456,6 @@ static int __init nf_conntrack_l3proto_ipv4_init(void) · 5 unmodified lines
412456 cleanup_l4proto:
413457 nf_ct_l4proto_unregister(builtin_l4proto4,
414458 ARRAY_SIZE(builtin_l4proto4));
415− cleanup_hooks:
416− nf_unregister_hooks(ipv4_conntrack_ops, ARRAY_SIZE(ipv4_conntrack_ops));
417459 cleanup_pernet:
418460 unregister_pernet_subsys(&ipv4_net_ops);
419461 cleanup_sockopt:
@@ -427,7 +469,6 @@ static void __exit nf_conntrack_l3proto_ipv4_fini(void) · 7 unmodified lines
427469 nf_ct_l3proto_unregister(&nf_conntrack_l3proto_ipv4);
428470 nf_ct_l4proto_unregister(builtin_l4proto4,
429471 ARRAY_SIZE(builtin_l4proto4));
430− nf_unregister_hooks(ipv4_conntrack_ops, ARRAY_SIZE(ipv4_conntrack_ops));
431472 unregister_pernet_subsys(&ipv4_net_ops);
432473 nf_unregister_sockopt(&so_getorigdst);
433474 }
net/ipv4/netfilter/nf_defrag_ipv4.c+38−3
@@ -11,6 +11,7 @@ · 10 unmodified lines
1111 #include <linux/netfilter.h>
1212 #include <linux/module.h>
1313 #include <linux/skbuff.h>
14+#include <net/netns/generic.h>
1415 #include <net/route.h>
1516 #include <net/ip.h>
1617
@@ -22,6 +23,8 @@ · 5 unmodified lines
2223 #endif
2324 #include <net/netfilter/nf_conntrack_zones.h>
2425
26+static DEFINE_MUTEX(defrag4_mutex);
27+
2528 static int nf_ct_ipv4_gather_frags(struct net *net, struct sk_buff *skb,
2629 u_int32_t user)
2730 {
@@ -102,18 +105,50 @@ static struct nf_hook_ops ipv4_defrag_ops[] = { · 74 unmodified lines
102105 },
103106 };
104107
108+static void __net_exit defrag4_net_exit(struct net *net)
109+{
110+ if (net->nf.defrag_ipv4) {
111+ nf_unregister_net_hooks(net, ipv4_defrag_ops,
112+ ARRAY_SIZE(ipv4_defrag_ops));
113+ net->nf.defrag_ipv4 = false;
114+ }
115+}
116+
117+static struct pernet_operations defrag4_net_ops = {
118+ .exit = defrag4_net_exit,
119+};
120+
105121 static int __init nf_defrag_init(void)
106122 {
107− return nf_register_hooks(ipv4_defrag_ops, ARRAY_SIZE(ipv4_defrag_ops));
123+ return register_pernet_subsys(&defrag4_net_ops);
108124 }
109125
110126 static void __exit nf_defrag_fini(void)
111127 {
112− nf_unregister_hooks(ipv4_defrag_ops, ARRAY_SIZE(ipv4_defrag_ops));
128+ unregister_pernet_subsys(&defrag4_net_ops);
113129 }
114130
115−void nf_defrag_ipv4_enable(void)
131+int nf_defrag_ipv4_enable(struct net *net)
116132 {
133+ int err = 0;
134+
135+ might_sleep();
136+
137+ if (net->nf.defrag_ipv4)
138+ return 0;
139+
140+ mutex_lock(&defrag4_mutex);
141+ if (net->nf.defrag_ipv4)
142+ goto out_unlock;
143+
144+ err = nf_register_net_hooks(net, ipv4_defrag_ops,
145+ ARRAY_SIZE(ipv4_defrag_ops));
146+ if (err == 0)
147+ net->nf.defrag_ipv4 = true;
148+
149+ out_unlock:
150+ mutex_unlock(&defrag4_mutex);
151+ return err;
117152 }
118153 EXPORT_SYMBOL_GPL(nf_defrag_ipv4_enable);
119154
net/ipv4/netfilter/nft_fib_ipv4.c+10−7
@@ -101,12 +101,13 @@ void nft_fib4_eval(const struct nft_expr *expr, struct nft_regs *regs, · 100 unmodified lines
101101 }
102102
103103 iph = ip_hdr(pkt->skb);
104− if (ipv4_is_multicast(iph->daddr) &&
105− ipv4_is_zeronet(iph->saddr) &&
106− ipv4_is_local_multicast(iph->daddr)) {
107− nft_fib_store_result(dest, priv->result, pkt,
108− get_ifindex(pkt->skb->dev));
109− return;
104+ if (ipv4_is_zeronet(iph->saddr)) {
105+ if (ipv4_is_lbcast(iph->daddr) ||
106+ ipv4_is_local_multicast(iph->daddr)) {
107+ nft_fib_store_result(dest, priv->result, pkt,
108+ get_ifindex(pkt->skb->dev));
109+ return;
110+ }
110111 }
111112
112113 if (priv->flags & NFTA_FIB_F_MARK)
@@ -122,6 +123,8 @@ void nft_fib4_eval(const struct nft_expr *expr, struct nft_regs *regs, · 9 unmodified lines
122123 fl4.saddr = get_saddr(iph->daddr);
123124 }
124125
126+ *dest = 0;
127+
125128 if (fib_lookup(nft_net(pkt), &fl4, &res, FIB_LOOKUP_IGNORE_LINKSTATE))
126129 return;
127130
@@ -198,7 +201,7 @@ nft_fib4_select_ops(const struct nft_ctx *ctx, · 70 unmodified lines
198201 if (!tb[NFTA_FIB_RESULT])
199202 return ERR_PTR(-EINVAL);
200203
201− result = htonl(nla_get_be32(tb[NFTA_FIB_RESULT]));
204+ result = ntohl(nla_get_be32(tb[NFTA_FIB_RESULT]));
202205
203206 switch (result) {
204207 case NFT_FIB_RESULT_OIF:
net/ipv4/netfilter/nft_masq_ipv4.c+9−2
@@ -1,5 +1,5 @@
11 /*
2− * Copyright (c) 2014 Arturo Borrero Gonzalez <arturo.borrero.glez@gmail.com>
2+ * Copyright (c) 2014 Arturo Borrero Gonzalez <arturo@debian.org>
33 *
44 * This program is free software; you can redistribute it and/or modify
55 * it under the terms of the GNU General Public License version 2 as
@@ -35,12 +35,19 @@ static void nft_masq_ipv4_eval(const struct nft_expr *expr, · 29 unmodified lines
3535 &range, nft_out(pkt));
3636 }
3737
38+static void
39+nft_masq_ipv4_destroy(const struct nft_ctx *ctx, const struct nft_expr *expr)
40+{
41+ nf_ct_netns_put(ctx->net, NFPROTO_IPV4);
42+}
43+
3844 static struct nft_expr_type nft_masq_ipv4_type;
3945 static const struct nft_expr_ops nft_masq_ipv4_ops = {
4046 .type = &nft_masq_ipv4_type,
4147 .size = NFT_EXPR_SIZE(sizeof(struct nft_masq)),
4248 .eval = nft_masq_ipv4_eval,
4349 .init = nft_masq_init,
50+ .destroy = nft_masq_ipv4_destroy,
4451 .dump = nft_masq_dump,
4552 .validate = nft_masq_validate,
4653 };
@@ -77,5 +84,5 @@ module_init(nft_masq_ipv4_module_init); · 30 unmodified lines
7784 module_exit(nft_masq_ipv4_module_exit);
7885
7986 MODULE_LICENSE("GPL");
80−MODULE_AUTHOR("Arturo Borrero Gonzalez <arturo.borrero.glez@gmail.com>");
87+MODULE_AUTHOR("Arturo Borrero Gonzalez <arturo@debian.org");
8188 MODULE_ALIAS_NFT_AF_EXPR(AF_INET, "masq");
net/ipv4/netfilter/nft_redir_ipv4.c+9−2
@@ -1,5 +1,5 @@
11 /*
2− * Copyright (c) 2014 Arturo Borrero Gonzalez <arturo.borrero.glez@gmail.com>
2+ * Copyright (c) 2014 Arturo Borrero Gonzalez <arturo@debian.org>
33 *
44 * This program is free software; you can redistribute it and/or modify
55 * it under the terms of the GNU General Public License version 2 as
@@ -38,12 +38,19 @@ static void nft_redir_ipv4_eval(const struct nft_expr *expr, · 32 unmodified lines
3838 regs->verdict.code = nf_nat_redirect_ipv4(pkt->skb, &mr, nft_hook(pkt));
3939 }
4040
41+static void
42+nft_redir_ipv4_destroy(const struct nft_ctx *ctx, const struct nft_expr *expr)
43+{
44+ nf_ct_netns_put(ctx->net, NFPROTO_IPV4);
45+}
46+
4147 static struct nft_expr_type nft_redir_ipv4_type;
4248 static const struct nft_expr_ops nft_redir_ipv4_ops = {
4349 .type = &nft_redir_ipv4_type,
4450 .size = NFT_EXPR_SIZE(sizeof(struct nft_redir)),
4551 .eval = nft_redir_ipv4_eval,
4652 .init = nft_redir_init,
53+ .destroy = nft_redir_ipv4_destroy,
4754 .dump = nft_redir_dump,
4855 .validate = nft_redir_validate,
4956 };
@@ -71,5 +78,5 @@ module_init(nft_redir_ipv4_module_init); · 21 unmodified lines
7178 module_exit(nft_redir_ipv4_module_exit);
7279
7380 MODULE_LICENSE("GPL");
74−MODULE_AUTHOR("Arturo Borrero Gonzalez <arturo.borrero.glez@gmail.com>");
81+MODULE_AUTHOR("Arturo Borrero Gonzalez <arturo@debian.org>");
7582 MODULE_ALIAS_NFT_AF_EXPR(AF_INET, "redir");
net/ipv6/netfilter/ip6_tables.c+8−9
@@ -562,7 +562,8 @@ static int check_target(struct ip6t_entry *e, struct net *net, const char *name) · 561 unmodified lines
562562
563563 static int
564564 find_check_entry(struct ip6t_entry *e, struct net *net, const char *name,
565− unsigned int size)
565+ unsigned int size,
566+ struct xt_percpu_counter_alloc_state *alloc_state)
566567 {
567568 struct xt_entry_target *t;
568569 struct xt_target *target;
@@ -570,12 +571,9 @@ find_check_entry(struct ip6t_entry *e, struct net *net, const char *name, · 1 unmodified line
570571 unsigned int j;
571572 struct xt_mtchk_param mtpar;
572573 struct xt_entry_match *ematch;
573− unsigned long pcnt;
574574
575− pcnt = xt_percpu_counter_alloc();
576− if (IS_ERR_VALUE(pcnt))
575+ if (!xt_percpu_counter_alloc(alloc_state, &e->counters))
577576 return -ENOMEM;
578− e->counters.pcnt = pcnt;
579577
580578 j = 0;
581579 mtpar.net = net;
@@ -612,7 +610,7 @@ find_check_entry(struct ip6t_entry *e, struct net *net, const char *name, · 30 unmodified lines
612610 cleanup_match(ematch, net);
613611 }
614612
615− xt_percpu_counter_free(e->counters.pcnt);
613+ xt_percpu_counter_free(&e->counters);
616614
617615 return ret;
618616 }
@@ -699,8 +697,7 @@ static void cleanup_entry(struct ip6t_entry *e, struct net *net) · 80 unmodified lines
699697 if (par.target->destroy != NULL)
700698 par.target->destroy(&par);
701699 module_put(par.target->me);
702−
703− xt_percpu_counter_free(e->counters.pcnt);
700+ xt_percpu_counter_free(&e->counters);
704701 }
705702
706703 /* Checks and translates the user-supplied table segment (held in
@@ -709,6 +706,7 @@ static int · 2 unmodified lines
709706 translate_table(struct net *net, struct xt_table_info *newinfo, void *entry0,
710707 const struct ip6t_replace *repl)
711708 {
709+ struct xt_percpu_counter_alloc_state alloc_state = { 0 };
712710 struct ip6t_entry *iter;
713711 unsigned int *offsets;
714712 unsigned int i;
@@ -768,7 +766,8 @@ translate_table(struct net *net, struct xt_table_info *newinfo, void *entry0, · 53 unmodified lines
768766 /* Finally, each sanity check must pass */
769767 i = 0;
770768 xt_entry_foreach(iter, entry0, newinfo->size) {
771− ret = find_check_entry(iter, net, repl->name, repl->size);
769+ ret = find_check_entry(iter, net, repl->name, repl->size,
770+ &alloc_state);
772771 if (ret != 0)
773772 break;
774773 ++i;
net/ipv6/netfilter/ip6t_SYNPROXY.c+2−2
@@ -440,12 +440,12 @@ static int synproxy_tg6_check(const struct xt_tgchk_param *par) · 439 unmodified lines
440440 e->ipv6.invflags & XT_INV_PROTO)
441441 return -EINVAL;
442442
443− return nf_ct_l3proto_try_module_get(par->family);
443+ return nf_ct_netns_get(par->net, par->family);
444444 }
445445
446446 static void synproxy_tg6_destroy(const struct xt_tgdtor_param *par)
447447 {
448− nf_ct_l3proto_module_put(par->family);
448+ nf_ct_netns_put(par->net, par->family);
449449 }
450450
451451 static struct xt_target synproxy_tg6_reg __read_mostly = {
net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c+57−13
@@ -34,6 +34,13 @@ · 33 unmodified lines
3434 #include <net/netfilter/ipv6/nf_defrag_ipv6.h>
3535 #include <net/netfilter/nf_log.h>
3636
37+static int conntrack6_net_id;
38+static DEFINE_MUTEX(register_ipv6_hooks);
39+
40+struct conntrack6_net {
41+ unsigned int users;
42+};
43+
3744 static bool ipv6_pkt_to_tuple(const struct sk_buff *skb, unsigned int nhoff,
3845 struct nf_conntrack_tuple *tuple)
3946 {
@@ -308,6 +315,42 @@ static int ipv6_nlattr_tuple_size(void) · 268 unmodified lines
308315 }
309316 #endif
310317
318+static int ipv6_hooks_register(struct net *net)
319+{
320+ struct conntrack6_net *cnet = net_generic(net, conntrack6_net_id);
321+ int err = 0;
322+
323+ mutex_lock(&register_ipv6_hooks);
324+ cnet->users++;
325+ if (cnet->users > 1)
326+ goto out_unlock;
327+
328+ err = nf_defrag_ipv6_enable(net);
329+ if (err < 0) {
330+ cnet->users = 0;
331+ goto out_unlock;
332+ }
333+
334+ err = nf_register_net_hooks(net, ipv6_conntrack_ops,
335+ ARRAY_SIZE(ipv6_conntrack_ops));
336+ if (err)
337+ cnet->users = 0;
338+ out_unlock:
339+ mutex_unlock(&register_ipv6_hooks);
340+ return err;
341+}
342+
343+static void ipv6_hooks_unregister(struct net *net)
344+{
345+ struct conntrack6_net *cnet = net_generic(net, conntrack6_net_id);
346+
347+ mutex_lock(&register_ipv6_hooks);
348+ if (cnet->users && (--cnet->users == 0))
349+ nf_unregister_net_hooks(net, ipv6_conntrack_ops,
350+ ARRAY_SIZE(ipv6_conntrack_ops));
351+ mutex_unlock(&register_ipv6_hooks);
352+}
353+
311354 struct nf_conntrack_l3proto nf_conntrack_l3proto_ipv6 __read_mostly = {
312355 .l3proto = PF_INET6,
313356 .name = "ipv6",
@@ -321,6 +364,8 @@ struct nf_conntrack_l3proto nf_conntrack_l3proto_ipv6 __read_mostly = { · 7 unmodified lines
321364 .nlattr_to_tuple = ipv6_nlattr_to_tuple,
322365 .nla_policy = ipv6_nla_policy,
323366 #endif
367+ .net_ns_get = ipv6_hooks_register,
368+ .net_ns_put = ipv6_hooks_unregister,
324369 .me = THIS_MODULE,
325370 };
326371
@@ -340,6 +385,15 @@ static struct nf_conntrack_l4proto *builtin_l4proto6[] = { · 13 unmodified lines
340385 &nf_conntrack_l4proto_tcp6,
341386 &nf_conntrack_l4proto_udp6,
342387 &nf_conntrack_l4proto_icmpv6,
388+#ifdef CONFIG_NF_CT_PROTO_DCCP
389+ &nf_conntrack_l4proto_dccp6,
390+#endif
391+#ifdef CONFIG_NF_CT_PROTO_SCTP
392+ &nf_conntrack_l4proto_sctp6,
393+#endif
394+#ifdef CONFIG_NF_CT_PROTO_UDPLITE
395+ &nf_conntrack_l4proto_udplite6,
396+#endif
343397 };
344398
345399 static int ipv6_net_init(struct net *net)
@@ -370,6 +424,8 @@ static void ipv6_net_exit(struct net *net) · 24 unmodified lines
370424 static struct pernet_operations ipv6_net_ops = {
371425 .init = ipv6_net_init,
372426 .exit = ipv6_net_exit,
427+ .id = &conntrack6_net_id,
428+ .size = sizeof(struct conntrack6_net),
373429 };
374430
375431 static int __init nf_conntrack_l3proto_ipv6_init(void)
@@ -377,7 +433,6 @@ static int __init nf_conntrack_l3proto_ipv6_init(void) · 1 unmodified line
377433 int ret = 0;
378434
379435 need_conntrack();
380− nf_defrag_ipv6_enable();
381436
382437 ret = nf_register_sockopt(&so_getorigdst6);
383438 if (ret < 0) {
@@ -389,18 +444,10 @@ static int __init nf_conntrack_l3proto_ipv6_init(void) · 5 unmodified lines
389444 if (ret < 0)
390445 goto cleanup_sockopt;
391446
392− ret = nf_register_hooks(ipv6_conntrack_ops,
393− ARRAY_SIZE(ipv6_conntrack_ops));
394− if (ret < 0) {
395− pr_err("nf_conntrack_ipv6: can't register pre-routing defrag "
396− "hook.\n");
397− goto cleanup_pernet;
398− }
399−
400447 ret = nf_ct_l4proto_register(builtin_l4proto6,
401448 ARRAY_SIZE(builtin_l4proto6));
402449 if (ret < 0)
403− goto cleanup_hooks;
450+ goto cleanup_pernet;
404451
405452 ret = nf_ct_l3proto_register(&nf_conntrack_l3proto_ipv6);
406453 if (ret < 0) {
@@ -411,8 +458,6 @@ static int __init nf_conntrack_l3proto_ipv6_init(void) · 4 unmodified lines
411458 cleanup_l4proto:
412459 nf_ct_l4proto_unregister(builtin_l4proto6,
413460 ARRAY_SIZE(builtin_l4proto6));
414− cleanup_hooks:
415− nf_unregister_hooks(ipv6_conntrack_ops, ARRAY_SIZE(ipv6_conntrack_ops));
416461 cleanup_pernet:
417462 unregister_pernet_subsys(&ipv6_net_ops);
418463 cleanup_sockopt:
@@ -426,7 +471,6 @@ static void __exit nf_conntrack_l3proto_ipv6_fini(void) · 7 unmodified lines
426471 nf_ct_l3proto_unregister(&nf_conntrack_l3proto_ipv6);
427472 nf_ct_l4proto_unregister(builtin_l4proto6,
428473 ARRAY_SIZE(builtin_l4proto6));
429− nf_unregister_hooks(ipv6_conntrack_ops, ARRAY_SIZE(ipv6_conntrack_ops));
430474 unregister_pernet_subsys(&ipv6_net_ops);
431475 nf_unregister_sockopt(&so_getorigdst6);
432476 }
net/ipv6/netfilter/nf_defrag_ipv6_hooks.c+38−4
@@ -30,6 +30,8 @@ · 29 unmodified lines
3030 #include <net/netfilter/nf_conntrack_zones.h>
3131 #include <net/netfilter/ipv6/nf_defrag_ipv6.h>
3232
33+static DEFINE_MUTEX(defrag6_mutex);
34+
3335 static enum ip6_defrag_users nf_ct6_defrag_user(unsigned int hooknum,
3436 struct sk_buff *skb)
3537 {
@@ -87,6 +89,19 @@ static struct nf_hook_ops ipv6_defrag_ops[] = { · 51 unmodified lines
8789 },
8890 };
8991
92+static void __net_exit defrag6_net_exit(struct net *net)
93+{
94+ if (net->nf.defrag_ipv6) {
95+ nf_unregister_net_hooks(net, ipv6_defrag_ops,
96+ ARRAY_SIZE(ipv6_defrag_ops));
97+ net->nf.defrag_ipv6 = false;
98+ }
99+}
100+
101+static struct pernet_operations defrag6_net_ops = {
102+ .exit = defrag6_net_exit,
103+};
104+
90105 static int __init nf_defrag_init(void)
91106 {
92107 int ret = 0;
@@ -96,9 +111,9 @@ static int __init nf_defrag_init(void) · 3 unmodified lines
96111 pr_err("nf_defrag_ipv6: can't initialize frag6.\n");
97112 return ret;
98113 }
99− ret = nf_register_hooks(ipv6_defrag_ops, ARRAY_SIZE(ipv6_defrag_ops));
114+ ret = register_pernet_subsys(&defrag6_net_ops);
100115 if (ret < 0) {
101− pr_err("nf_defrag_ipv6: can't register hooks\n");
116+ pr_err("nf_defrag_ipv6: can't register pernet ops\n");
102117 goto cleanup_frag6;
103118 }
104119 return ret;
@@ -111,12 +126,31 @@ cleanup_frag6: · 6 unmodified lines
111126
112127 static void __exit nf_defrag_fini(void)
113128 {
114− nf_unregister_hooks(ipv6_defrag_ops, ARRAY_SIZE(ipv6_defrag_ops));
129+ unregister_pernet_subsys(&defrag6_net_ops);
115130 nf_ct_frag6_cleanup();
116131 }
117132
118−void nf_defrag_ipv6_enable(void)
133+int nf_defrag_ipv6_enable(struct net *net)
119134 {
135+ int err = 0;
136+
137+ might_sleep();
138+
139+ if (net->nf.defrag_ipv6)
140+ return 0;
141+
142+ mutex_lock(&defrag6_mutex);
143+ if (net->nf.defrag_ipv6)
144+ goto out_unlock;
145+
146+ err = nf_register_net_hooks(net, ipv6_defrag_ops,
147+ ARRAY_SIZE(ipv6_defrag_ops));
148+ if (err == 0)
149+ net->nf.defrag_ipv6 = true;
150+
151+ out_unlock:
152+ mutex_unlock(&defrag6_mutex);
153+ return err;
120154 }
121155 EXPORT_SYMBOL_GPL(nf_defrag_ipv6_enable);
122156
net/ipv6/netfilter/nft_fib_ipv6.c+1−1
@@ -235,7 +235,7 @@ nft_fib6_select_ops(const struct nft_ctx *ctx, · 234 unmodified lines
235235 if (!tb[NFTA_FIB_RESULT])
236236 return ERR_PTR(-EINVAL);
237237
238− result = htonl(nla_get_be32(tb[NFTA_FIB_RESULT]));
238+ result = ntohl(nla_get_be32(tb[NFTA_FIB_RESULT]));
239239
240240 switch (result) {
241241 case NFT_FIB_RESULT_OIF:
net/ipv6/netfilter/nft_masq_ipv6.c+9−2
@@ -1,5 +1,5 @@
11 /*
2− * Copyright (c) 2014 Arturo Borrero Gonzalez <arturo.borrero.glez@gmail.com>
2+ * Copyright (c) 2014 Arturo Borrero Gonzalez <arturo@debian.org>
33 *
44 * This program is free software; you can redistribute it and/or modify
55 * it under the terms of the GNU General Public License version 2 as
@@ -36,12 +36,19 @@ static void nft_masq_ipv6_eval(const struct nft_expr *expr, · 30 unmodified lines
3636 nft_out(pkt));
3737 }
3838
39+static void
40+nft_masq_ipv6_destroy(const struct nft_ctx *ctx, const struct nft_expr *expr)
41+{
42+ nf_ct_netns_put(ctx->net, NFPROTO_IPV6);
43+}
44+
3945 static struct nft_expr_type nft_masq_ipv6_type;
4046 static const struct nft_expr_ops nft_masq_ipv6_ops = {
4147 .type = &nft_masq_ipv6_type,
4248 .size = NFT_EXPR_SIZE(sizeof(struct nft_masq)),
4349 .eval = nft_masq_ipv6_eval,
4450 .init = nft_masq_init,
51+ .destroy = nft_masq_ipv6_destroy,
4552 .dump = nft_masq_dump,
4653 .validate = nft_masq_validate,
4754 };
@@ -78,5 +85,5 @@ module_init(nft_masq_ipv6_module_init); · 30 unmodified lines
7885 module_exit(nft_masq_ipv6_module_exit);
7986
8087 MODULE_LICENSE("GPL");
81−MODULE_AUTHOR("Arturo Borrero Gonzalez <arturo.borrero.glez@gmail.com>");
88+MODULE_AUTHOR("Arturo Borrero Gonzalez <arturo@debian.org>");
8289 MODULE_ALIAS_NFT_AF_EXPR(AF_INET6, "masq");
net/ipv6/netfilter/nft_redir_ipv6.c+9−2
@@ -1,5 +1,5 @@
11 /*
2− * Copyright (c) 2014 Arturo Borrero Gonzalez <arturo.borrero.glez@gmail.com>
2+ * Copyright (c) 2014 Arturo Borrero Gonzalez <arturo@debian.org>
33 *
44 * This program is free software; you can redistribute it and/or modify
55 * it under the terms of the GNU General Public License version 2 as
@@ -39,12 +39,19 @@ static void nft_redir_ipv6_eval(const struct nft_expr *expr, · 33 unmodified lines
3939 nf_nat_redirect_ipv6(pkt->skb, &range, nft_hook(pkt));
4040 }
4141
42+static void
43+nft_redir_ipv6_destroy(const struct nft_ctx *ctx, const struct nft_expr *expr)
44+{
45+ nf_ct_netns_put(ctx->net, NFPROTO_IPV6);
46+}
47+
4248 static struct nft_expr_type nft_redir_ipv6_type;
4349 static const struct nft_expr_ops nft_redir_ipv6_ops = {
4450 .type = &nft_redir_ipv6_type,
4551 .size = NFT_EXPR_SIZE(sizeof(struct nft_redir)),
4652 .eval = nft_redir_ipv6_eval,
4753 .init = nft_redir_init,
54+ .destroy = nft_redir_ipv6_destroy,
4855 .dump = nft_redir_dump,
4956 .validate = nft_redir_validate,
5057 };
@@ -72,5 +79,5 @@ module_init(nft_redir_ipv6_module_init); · 21 unmodified lines
7279 module_exit(nft_redir_ipv6_module_exit);
7380
7481 MODULE_LICENSE("GPL");
75−MODULE_AUTHOR("Arturo Borrero Gonzalez <arturo.borrero.glez@gmail.com>");
82+MODULE_AUTHOR("Arturo Borrero Gonzalez <arturo@debian.org>");
7683 MODULE_ALIAS_NFT_AF_EXPR(AF_INET6, "redir");
net/netfilter/Kconfig+18−12
@@ -146,38 +146,38 @@ config NF_CONNTRACK_LABELS · 145 unmodified lines
146146 to connection tracking entries. It selected by the connlabel match.
147147
148148 config NF_CT_PROTO_DCCP
149− tristate 'DCCP protocol connection tracking support'
149+ bool 'DCCP protocol connection tracking support'
150150 depends on NETFILTER_ADVANCED
151− default IP_DCCP
151+ default y
152152 help
153153 With this option enabled, the layer 3 independent connection
154154 tracking code will be able to do state tracking on DCCP connections.
155155
156− If unsure, say 'N'.
156+ If unsure, say Y.
157157
158158 config NF_CT_PROTO_GRE
159159 tristate
160160
161161 config NF_CT_PROTO_SCTP
162− tristate 'SCTP protocol connection tracking support'
162+ bool 'SCTP protocol connection tracking support'
163163 depends on NETFILTER_ADVANCED
164− default IP_SCTP
164+ default y
165165 help
166166 With this option enabled, the layer 3 independent connection
167167 tracking code will be able to do state tracking on SCTP connections.
168168
169− If you want to compile it as a module, say M here and read
170− <file:Documentation/kbuild/modules.txt>. If unsure, say `N'.
169+ If unsure, say Y.
171170
172171 config NF_CT_PROTO_UDPLITE
173− tristate 'UDP-Lite protocol connection tracking support'
172+ bool 'UDP-Lite protocol connection tracking support'
174173 depends on NETFILTER_ADVANCED
174+ default y
175175 help
176176 With this option enabled, the layer 3 independent connection
177177 tracking code will be able to do state tracking on UDP-Lite
178178 connections.
179179
180− To compile it as a module, choose M here. If unsure, say N.
180+ If unsure, say Y.
181181
182182 config NF_CONNTRACK_AMANDA
183183 tristate "Amanda backup protocol support"
@@ -384,17 +384,17 @@ config NF_NAT_NEEDED · 200 unmodified lines
384384 default y
385385
386386 config NF_NAT_PROTO_DCCP
387− tristate
387+ bool
388388 depends on NF_NAT && NF_CT_PROTO_DCCP
389389 default NF_NAT && NF_CT_PROTO_DCCP
390390
391391 config NF_NAT_PROTO_UDPLITE
392− tristate
392+ bool
393393 depends on NF_NAT && NF_CT_PROTO_UDPLITE
394394 default NF_NAT && NF_CT_PROTO_UDPLITE
395395
396396 config NF_NAT_PROTO_SCTP
397− tristate
397+ bool
398398 default NF_NAT && NF_CT_PROTO_SCTP
399399 depends on NF_NAT && NF_CT_PROTO_SCTP
400400 select LIBCRC32C
@@ -551,6 +551,12 @@ config NFT_NAT · 150 unmodified lines
551551 This option adds the "nat" expression that you can use to perform
552552 typical Network Address Translation (NAT) packet transformations.
553553
554+config NFT_OBJREF
555+ tristate "Netfilter nf_tables stateful object reference module"
556+ help
557+ This option adds the "objref" expression that allows you to refer to
558+ stateful objects, such as counters and quotas.
559+
554560 config NFT_QUEUE
555561 depends on NETFILTER_NETLINK_QUEUE
556562 tristate "Netfilter nf_tables queue module"
net/netfilter/Makefile+9−9
@@ -5,6 +5,9 @@ nf_conntrack-$(CONFIG_NF_CONNTRACK_TIMEOUT) += nf_conntrack_timeout.o · 4 unmodified lines
55 nf_conntrack-$(CONFIG_NF_CONNTRACK_TIMESTAMP) += nf_conntrack_timestamp.o
66 nf_conntrack-$(CONFIG_NF_CONNTRACK_EVENTS) += nf_conntrack_ecache.o
77 nf_conntrack-$(CONFIG_NF_CONNTRACK_LABELS) += nf_conntrack_labels.o
8+nf_conntrack-$(CONFIG_NF_CT_PROTO_DCCP) += nf_conntrack_proto_dccp.o
9+nf_conntrack-$(CONFIG_NF_CT_PROTO_SCTP) += nf_conntrack_proto_sctp.o
10+nf_conntrack-$(CONFIG_NF_CT_PROTO_UDPLITE) += nf_conntrack_proto_udplite.o
811
912 obj-$(CONFIG_NETFILTER) = netfilter.o
1013
@@ -16,11 +19,7 @@ obj-$(CONFIG_NETFILTER_NETLINK_LOG) += nfnetlink_log.o · 5 unmodified lines
1619 # connection tracking
1720 obj-$(CONFIG_NF_CONNTRACK) += nf_conntrack.o
1821
19−# SCTP protocol connection tracking
20−obj-$(CONFIG_NF_CT_PROTO_DCCP) += nf_conntrack_proto_dccp.o
2122 obj-$(CONFIG_NF_CT_PROTO_GRE) += nf_conntrack_proto_gre.o
22−obj-$(CONFIG_NF_CT_PROTO_SCTP) += nf_conntrack_proto_sctp.o
23−obj-$(CONFIG_NF_CT_PROTO_UDPLITE) += nf_conntrack_proto_udplite.o
2423
2524 # netlink interface for nf_conntrack
2625 obj-$(CONFIG_NF_CT_NETLINK) += nf_conntrack_netlink.o
@@ -45,6 +44,11 @@ obj-$(CONFIG_NF_CONNTRACK_TFTP) += nf_conntrack_tftp.o · 18 unmodified lines
4544 nf_nat-y := nf_nat_core.o nf_nat_proto_unknown.o nf_nat_proto_common.o \
4645 nf_nat_proto_udp.o nf_nat_proto_tcp.o nf_nat_helper.o
4746
47+# NAT protocols (nf_nat)
48+nf_nat-$(CONFIG_NF_NAT_PROTO_DCCP) += nf_nat_proto_dccp.o
49+nf_nat-$(CONFIG_NF_NAT_PROTO_SCTP) += nf_nat_proto_sctp.o
50+nf_nat-$(CONFIG_NF_NAT_PROTO_UDPLITE) += nf_nat_proto_udplite.o
51+
4852 # generic transport layer logging
4953 obj-$(CONFIG_NF_LOG_COMMON) += nf_log_common.o
5054
@@ -54,11 +58,6 @@ obj-$(CONFIG_NF_LOG_NETDEV) += nf_log_netdev.o · 3 unmodified lines
5458 obj-$(CONFIG_NF_NAT) += nf_nat.o
5559 obj-$(CONFIG_NF_NAT_REDIRECT) += nf_nat_redirect.o
5660
57−# NAT protocols (nf_nat)
58−obj-$(CONFIG_NF_NAT_PROTO_DCCP) += nf_nat_proto_dccp.o
59−obj-$(CONFIG_NF_NAT_PROTO_UDPLITE) += nf_nat_proto_udplite.o
60−obj-$(CONFIG_NF_NAT_PROTO_SCTP) += nf_nat_proto_sctp.o
61−
6261 # NAT helpers
6362 obj-$(CONFIG_NF_NAT_AMANDA) += nf_nat_amanda.o
6463 obj-$(CONFIG_NF_NAT_FTP) += nf_nat_ftp.o
@@ -89,6 +88,7 @@ obj-$(CONFIG_NFT_NUMGEN) += nft_numgen.o · 24 unmodified lines
8988 obj-$(CONFIG_NFT_CT) += nft_ct.o
9089 obj-$(CONFIG_NFT_LIMIT) += nft_limit.o
9190 obj-$(CONFIG_NFT_NAT) += nft_nat.o
91+obj-$(CONFIG_NFT_OBJREF) += nft_objref.o
9292 obj-$(CONFIG_NFT_QUEUE) += nft_queue.o
9393 obj-$(CONFIG_NFT_QUOTA) += nft_quota.o
9494 obj-$(CONFIG_NFT_REJECT) += nft_reject.o
net/netfilter/core.c+6−10
@@ -102,17 +102,14 @@ int nf_register_net_hook(struct net *net, const struct nf_hook_ops *reg) · 101 unmodified lines
102102 if (!entry)
103103 return -ENOMEM;
104104
105− entry->orig_ops = reg;
106− entry->ops = *reg;
107− entry->next = NULL;
105+ nf_hook_entry_init(entry, reg);
108106
109107 mutex_lock(&nf_hook_mutex);
110108
111109 /* Find the spot in the list */
112− while ((p = nf_entry_dereference(*pp)) != NULL) {
113− if (reg->priority < p->orig_ops->priority)
110+ for (; (p = nf_entry_dereference(*pp)) != NULL; pp = &p->next) {
111+ if (reg->priority < nf_hook_entry_priority(p))
114112 break;
115− pp = &p->next;
116113 }
117114 rcu_assign_pointer(entry->next, p);
118115 rcu_assign_pointer(*pp, entry);
@@ -139,12 +136,11 @@ void nf_unregister_net_hook(struct net *net, const struct nf_hook_ops *reg) · 20 unmodified lines
139136 return;
140137
141138 mutex_lock(&nf_hook_mutex);
142− while ((p = nf_entry_dereference(*pp)) != NULL) {
143− if (p->orig_ops == reg) {
139+ for (; (p = nf_entry_dereference(*pp)) != NULL; pp = &p->next) {
140+ if (nf_hook_entry_ops(p) == reg) {
144141 rcu_assign_pointer(*pp, p->next);
145142 break;
146143 }
147− pp = &p->next;
148144 }
149145 mutex_unlock(&nf_hook_mutex);
150146 if (!p) {
@@ -311,7 +307,7 @@ int nf_hook_slow(struct sk_buff *skb, struct nf_hook_state *state, · 160 unmodified lines
311307 int ret;
312308
313309 do {
314− verdict = entry->ops.hook(entry->ops.priv, skb, state);
310+ verdict = nf_hook_entry_hookfn(entry, skb, state);
315311 switch (verdict & NF_VERDICT_MASK) {
316312 case NF_ACCEPT:
317313 entry = rcu_dereference(entry->next);
net/netfilter/ipvs/ip_vs_ctl.c+1−1
@@ -3260,7 +3260,7 @@ static int ip_vs_genl_dump_dests(struct sk_buff *skb, · 3259 unmodified lines
32603260
32613261
32623262 svc = ip_vs_genl_find_service(ipvs, attrs[IPVS_CMD_ATTR_SERVICE]);
3263− if (IS_ERR(svc) || svc == NULL)
3263+ if (IS_ERR_OR_NULL(svc))
32643264 goto out_err;
32653265
32663266 /* Dump the destinations */
net/netfilter/ipvs/ip_vs_xmit.c+54−0
@@ -254,6 +254,54 @@ static inline bool ensure_mtu_is_adequate(struct netns_ipvs *ipvs, int skb_af, · 253 unmodified lines
254254 return true;
255255 }
256256
257+static inline bool decrement_ttl(struct netns_ipvs *ipvs,
258+ int skb_af,
259+ struct sk_buff *skb)
260+{
261+ struct net *net = ipvs->net;
262+
263+#ifdef CONFIG_IP_VS_IPV6
264+ if (skb_af == AF_INET6) {
265+ struct dst_entry *dst = skb_dst(skb);
266+
267+ /* check and decrement ttl */
268+ if (ipv6_hdr(skb)->hop_limit <= 1) {
269+ /* Force OUTPUT device used as source address */
270+ skb->dev = dst->dev;
271+ icmpv6_send(skb, ICMPV6_TIME_EXCEED,
272+ ICMPV6_EXC_HOPLIMIT, 0);
273+ __IP6_INC_STATS(net, ip6_dst_idev(dst),
274+ IPSTATS_MIB_INHDRERRORS);
275+
276+ return false;
277+ }
278+
279+ /* don't propagate ttl change to cloned packets */
280+ if (!skb_make_writable(skb, sizeof(struct ipv6hdr)))
281+ return false;
282+
283+ ipv6_hdr(skb)->hop_limit--;
284+ } else
285+#endif
286+ {
287+ if (ip_hdr(skb)->ttl <= 1) {
288+ /* Tell the sender its packet died... */
289+ __IP_INC_STATS(net, IPSTATS_MIB_INHDRERRORS);
290+ icmp_send(skb, ICMP_TIME_EXCEEDED, ICMP_EXC_TTL, 0);
291+ return false;
292+ }
293+
294+ /* don't propagate ttl change to cloned packets */
295+ if (!skb_make_writable(skb, sizeof(struct iphdr)))
296+ return false;
297+
298+ /* Decrease ttl */
299+ ip_decrease_ttl(ip_hdr(skb));
300+ }
301+
302+ return true;
303+}
304+
257305 /* Get route to destination or remote server */
258306 static int
259307 __ip_vs_get_out_rt(struct netns_ipvs *ipvs, int skb_af, struct sk_buff *skb,
@@ -326,6 +374,9 @@ __ip_vs_get_out_rt(struct netns_ipvs *ipvs, int skb_af, struct sk_buff *skb, · 66 unmodified lines
326374 return local;
327375 }
328376
377+ if (!decrement_ttl(ipvs, skb_af, skb))
378+ goto err_put;
379+
329380 if (likely(!(rt_mode & IP_VS_RT_MODE_TUNNEL))) {
330381 mtu = dst_mtu(&rt->dst);
331382 } else {
@@ -473,6 +524,9 @@ __ip_vs_get_out_rt_v6(struct netns_ipvs *ipvs, int skb_af, struct sk_buff *skb, · 141 unmodified lines
473524 return local;
474525 }
475526
527+ if (!decrement_ttl(ipvs, skb_af, skb))
528+ goto err_put;
529+
476530 /* MTU checking */
477531 if (likely(!(rt_mode & IP_VS_RT_MODE_TUNNEL)))
478532 mtu = dst_mtu(&rt->dst);
net/netfilter/nf_conntrack_proto.c+65−8
@@ -125,6 +125,54 @@ void nf_ct_l3proto_module_put(unsigned short l3proto) · 124 unmodified lines
125125 }
126126 EXPORT_SYMBOL_GPL(nf_ct_l3proto_module_put);
127127
128+int nf_ct_netns_get(struct net *net, u8 nfproto)
129+{
130+ const struct nf_conntrack_l3proto *l3proto;
131+ int ret;
132+
133+ might_sleep();
134+
135+ ret = nf_ct_l3proto_try_module_get(nfproto);
136+ if (ret < 0)
137+ return ret;
138+
139+ /* we already have a reference, can't fail */
140+ rcu_read_lock();
141+ l3proto = __nf_ct_l3proto_find(nfproto);
142+ rcu_read_unlock();
143+
144+ if (!l3proto->net_ns_get)
145+ return 0;
146+
147+ ret = l3proto->net_ns_get(net);
148+ if (ret < 0)
149+ nf_ct_l3proto_module_put(nfproto);
150+
151+ return ret;
152+}
153+EXPORT_SYMBOL_GPL(nf_ct_netns_get);
154+
155+void nf_ct_netns_put(struct net *net, u8 nfproto)
156+{
157+ const struct nf_conntrack_l3proto *l3proto;
158+
159+ might_sleep();
160+
161+ /* same as nf_conntrack_netns_get(), reference assumed */
162+ rcu_read_lock();
163+ l3proto = __nf_ct_l3proto_find(nfproto);
164+ rcu_read_unlock();
165+
166+ if (WARN_ON(!l3proto))
167+ return;
168+
169+ if (l3proto->net_ns_put)
170+ l3proto->net_ns_put(net);
171+
172+ nf_ct_l3proto_module_put(nfproto);
173+}
174+EXPORT_SYMBOL_GPL(nf_ct_netns_put);
175+
128176 struct nf_conntrack_l4proto *
129177 nf_ct_l4proto_find_get(u_int16_t l3num, u_int8_t l4num)
130178 {
@@ -190,20 +238,19 @@ out_unlock: · 59 unmodified lines
190238 }
191239 EXPORT_SYMBOL_GPL(nf_ct_l3proto_register);
192240
241+#ifdef CONFIG_SYSCTL
242+extern unsigned int nf_conntrack_default_on;
243+
193244 int nf_ct_l3proto_pernet_register(struct net *net,
194245 struct nf_conntrack_l3proto *proto)
195246 {
196− int ret;
197−
198− if (proto->init_net) {
199− ret = proto->init_net(net);
200− if (ret < 0)
201− return ret;
202− }
247+ if (nf_conntrack_default_on == 0)
248+ return 0;
203249
204− return 0;
250+ return proto->net_ns_get ? proto->net_ns_get(net) : 0;
205251 }
206252 EXPORT_SYMBOL_GPL(nf_ct_l3proto_pernet_register);
253+#endif
207254
208255 void nf_ct_l3proto_unregister(struct nf_conntrack_l3proto *proto)
209256 {
@@ -224,6 +271,16 @@ EXPORT_SYMBOL_GPL(nf_ct_l3proto_unregister); · 14 unmodified lines
224271 void nf_ct_l3proto_pernet_unregister(struct net *net,
225272 struct nf_conntrack_l3proto *proto)
226273 {
274+ /*
275+ * nf_conntrack_default_on *might* have registered hooks.
276+ * ->net_ns_put must cope with more puts() than get(), i.e.
277+ * if nf_conntrack_default_on was 0 at time of
278+ * nf_ct_l3proto_pernet_register invocation this net_ns_put()
279+ * should be a noop.
280+ */
281+ if (proto->net_ns_put)
282+ proto->net_ns_put(net);
283+
227284 /* Remove all contrack entries for this protocol */
228285 nf_ct_iterate_cleanup(net, kill_l3proto, proto, 0, 0);
229286 }
net/netfilter/nf_conntrack_proto_dccp.c+10−69
@@ -9,7 +9,6 @@ · 8 unmodified lines
99 *
1010 */
1111 #include <linux/kernel.h>
12−#include <linux/module.h>
1312 #include <linux/init.h>
1413 #include <linux/sysctl.h>
1514 #include <linux/spinlock.h>
@@ -384,17 +383,9 @@ dccp_state_table[CT_DCCP_ROLE_MAX + 1][DCCP_PKT_SYNCACK + 1][CT_DCCP_MAX + 1] = · 368 unmodified lines
384383 },
385384 };
386385
387−/* this module per-net specifics */
388−static unsigned int dccp_net_id __read_mostly;
389−struct dccp_net {
390− struct nf_proto_net pn;
391− int dccp_loose;
392− unsigned int dccp_timeout[CT_DCCP_MAX + 1];
393−};
394−
395−static inline struct dccp_net *dccp_pernet(struct net *net)
386+static inline struct nf_dccp_net *dccp_pernet(struct net *net)
396387 {
397− return net_generic(net, dccp_net_id);
388+ return &net->ct.nf_ct_proto.dccp;
398389 }
399390
400391 static bool dccp_pkt_to_tuple(const struct sk_buff *skb, unsigned int dataoff,
@@ -424,7 +415,7 @@ static bool dccp_new(struct nf_conn *ct, const struct sk_buff *skb, · 23 unmodified lines
424415 unsigned int dataoff, unsigned int *timeouts)
425416 {
426417 struct net *net = nf_ct_net(ct);
427− struct dccp_net *dn;
418+ struct nf_dccp_net *dn;
428419 struct dccp_hdr _dh, *dh;
429420 const char *msg;
430421 u_int8_t state;
@@ -719,7 +710,7 @@ static int dccp_nlattr_size(void) · 288 unmodified lines
719710 static int dccp_timeout_nlattr_to_obj(struct nlattr *tb[],
720711 struct net *net, void *data)
721712 {
722− struct dccp_net *dn = dccp_pernet(net);
713+ struct nf_dccp_net *dn = dccp_pernet(net);
723714 unsigned int *timeouts = data;
724715 int i;
725716
@@ -820,7 +811,7 @@ static struct ctl_table dccp_sysctl_table[] = { · 94 unmodified lines
820811 #endif /* CONFIG_SYSCTL */
821812
822813 static int dccp_kmemdup_sysctl_table(struct net *net, struct nf_proto_net *pn,
823− struct dccp_net *dn)
814+ struct nf_dccp_net *dn)
824815 {
825816 #ifdef CONFIG_SYSCTL
826817 if (pn->ctl_table)
@@ -850,7 +841,7 @@ static int dccp_kmemdup_sysctl_table(struct net *net, struct nf_proto_net *pn, · 23 unmodified lines
850841
851842 static int dccp_init_net(struct net *net, u_int16_t proto)
852843 {
853− struct dccp_net *dn = dccp_pernet(net);
844+ struct nf_dccp_net *dn = dccp_pernet(net);
854845 struct nf_proto_net *pn = &dn->pn;
855846
856847 if (!pn->users) {
@@ -868,7 +859,7 @@ static int dccp_init_net(struct net *net, u_int16_t proto) · 11 unmodified lines
868859 return dccp_kmemdup_sysctl_table(net, pn, dn);
869860 }
870861
871−static struct nf_conntrack_l4proto dccp_proto4 __read_mostly = {
862+struct nf_conntrack_l4proto nf_conntrack_l4proto_dccp4 __read_mostly = {
872863 .l3proto = AF_INET,
873864 .l4proto = IPPROTO_DCCP,
874865 .name = "dccp",
@@ -898,11 +889,11 @@ static struct nf_conntrack_l4proto dccp_proto4 __read_mostly = { · 23 unmodified lines
898889 .nla_policy = dccp_timeout_nla_policy,
899890 },
900891 #endif /* CONFIG_NF_CT_NETLINK_TIMEOUT */
901− .net_id = &dccp_net_id,
902892 .init_net = dccp_init_net,
903893 };
894+EXPORT_SYMBOL_GPL(nf_conntrack_l4proto_dccp4);
904895
905−static struct nf_conntrack_l4proto dccp_proto6 __read_mostly = {
896+struct nf_conntrack_l4proto nf_conntrack_l4proto_dccp6 __read_mostly = {
906897 .l3proto = AF_INET6,
907898 .l4proto = IPPROTO_DCCP,
908899 .name = "dccp",
@@ -932,56 +923,6 @@ static struct nf_conntrack_l4proto dccp_proto6 __read_mostly = { · 23 unmodified lines
932923 .nla_policy = dccp_timeout_nla_policy,
933924 },
934925 #endif /* CONFIG_NF_CT_NETLINK_TIMEOUT */
935− .net_id = &dccp_net_id,
936926 .init_net = dccp_init_net,
937927 };
938−
939−static struct nf_conntrack_l4proto *dccp_proto[] = {
940− &dccp_proto4,
941− &dccp_proto6,
942−};
943−
944−static __net_init int dccp_net_init(struct net *net)
945−{
946− return nf_ct_l4proto_pernet_register(net, dccp_proto,
947− ARRAY_SIZE(dccp_proto));
948−}
949−
950−static __net_exit void dccp_net_exit(struct net *net)
951−{
952− nf_ct_l4proto_pernet_unregister(net, dccp_proto,
953− ARRAY_SIZE(dccp_proto));
954−}
955−
956−static struct pernet_operations dccp_net_ops = {
957− .init = dccp_net_init,
958− .exit = dccp_net_exit,
959− .id = &dccp_net_id,
960− .size = sizeof(struct dccp_net),
961−};
962−
963−static int __init nf_conntrack_proto_dccp_init(void)
964−{
965− int ret;
966−
967− ret = register_pernet_subsys(&dccp_net_ops);
968− if (ret < 0)
969− return ret;
970− ret = nf_ct_l4proto_register(dccp_proto, ARRAY_SIZE(dccp_proto));
971− if (ret < 0)
972− unregister_pernet_subsys(&dccp_net_ops);
973− return ret;
974−}
975−
976−static void __exit nf_conntrack_proto_dccp_fini(void)
977−{
978− nf_ct_l4proto_unregister(dccp_proto, ARRAY_SIZE(dccp_proto));
979− unregister_pernet_subsys(&dccp_net_ops);
980−}
981−
982−module_init(nf_conntrack_proto_dccp_init);
983−module_exit(nf_conntrack_proto_dccp_fini);
984−
985−MODULE_AUTHOR("Patrick McHardy <kaber@trash.net>");
986−MODULE_DESCRIPTION("DCCP connection tracking protocol helper");
987−MODULE_LICENSE("GPL");
928+EXPORT_SYMBOL_GPL(nf_conntrack_l4proto_dccp6);
net/netfilter/nf_conntrack_proto_sctp.c+9−67
@@ -15,7 +15,6 @@ · 14 unmodified lines
1515 #include <linux/types.h>
1616 #include <linux/timer.h>
1717 #include <linux/netfilter.h>
18−#include <linux/module.h>
1918 #include <linux/in.h>
2019 #include <linux/ip.h>
2120 #include <linux/sctp.h>
@@ -144,15 +143,9 @@ static const u8 sctp_conntracks[2][11][SCTP_CONNTRACK_MAX] = { · 122 unmodified lines
144143 }
145144 };
146145
147−static unsigned int sctp_net_id __read_mostly;
148−struct sctp_net {
149− struct nf_proto_net pn;
150− unsigned int timeouts[SCTP_CONNTRACK_MAX];
151−};
152−
153−static inline struct sctp_net *sctp_pernet(struct net *net)
146+static inline struct nf_sctp_net *sctp_pernet(struct net *net)
154147 {
155− return net_generic(net, sctp_net_id);
148+ return &net->ct.nf_ct_proto.sctp;
156149 }
157150
158151 static bool sctp_pkt_to_tuple(const struct sk_buff *skb, unsigned int dataoff,
@@ -600,7 +593,7 @@ static int sctp_timeout_nlattr_to_obj(struct nlattr *tb[], · 441 unmodified lines
600593 struct net *net, void *data)
601594 {
602595 unsigned int *timeouts = data;
603− struct sctp_net *sn = sctp_pernet(net);
596+ struct nf_sctp_net *sn = sctp_pernet(net);
604597 int i;
605598
606599 /* set default SCTP timeouts. */
@@ -708,7 +701,7 @@ static struct ctl_table sctp_sysctl_table[] = { · 101 unmodified lines
708701 #endif
709702
710703 static int sctp_kmemdup_sysctl_table(struct nf_proto_net *pn,
711− struct sctp_net *sn)
704+ struct nf_sctp_net *sn)
712705 {
713706 #ifdef CONFIG_SYSCTL
714707 if (pn->ctl_table)
@@ -735,7 +728,7 @@ static int sctp_kmemdup_sysctl_table(struct nf_proto_net *pn, · 20 unmodified lines
735728
736729 static int sctp_init_net(struct net *net, u_int16_t proto)
737730 {
738− struct sctp_net *sn = sctp_pernet(net);
731+ struct nf_sctp_net *sn = sctp_pernet(net);
739732 struct nf_proto_net *pn = &sn->pn;
740733
741734 if (!pn->users) {
@@ -748,7 +741,7 @@ static int sctp_init_net(struct net *net, u_int16_t proto) · 6 unmodified lines
748741 return sctp_kmemdup_sysctl_table(pn, sn);
749742 }
750743
751−static struct nf_conntrack_l4proto nf_conntrack_l4proto_sctp4 __read_mostly = {
744+struct nf_conntrack_l4proto nf_conntrack_l4proto_sctp4 __read_mostly = {
752745 .l3proto = PF_INET,
753746 .l4proto = IPPROTO_SCTP,
754747 .name = "sctp",
@@ -778,11 +771,11 @@ static struct nf_conntrack_l4proto nf_conntrack_l4proto_sctp4 __read_mostly = { · 23 unmodified lines
778771 .nla_policy = sctp_timeout_nla_policy,
779772 },
780773 #endif /* CONFIG_NF_CT_NETLINK_TIMEOUT */
781− .net_id = &sctp_net_id,
782774 .init_net = sctp_init_net,
783775 };
776+EXPORT_SYMBOL_GPL(nf_conntrack_l4proto_sctp4);
784777
785−static struct nf_conntrack_l4proto nf_conntrack_l4proto_sctp6 __read_mostly = {
778+struct nf_conntrack_l4proto nf_conntrack_l4proto_sctp6 __read_mostly = {
786779 .l3proto = PF_INET6,
787780 .l4proto = IPPROTO_SCTP,
788781 .name = "sctp",
@@ -812,57 +805,6 @@ static struct nf_conntrack_l4proto nf_conntrack_l4proto_sctp6 __read_mostly = { · 23 unmodified lines
812805 },
813806 #endif /* CONFIG_NF_CT_NETLINK_TIMEOUT */
814807 #endif
815− .net_id = &sctp_net_id,
816808 .init_net = sctp_init_net,
817809 };
818−
819−static struct nf_conntrack_l4proto *sctp_proto[] = {
820− &nf_conntrack_l4proto_sctp4,
821− &nf_conntrack_l4proto_sctp6,
822−};
823−
824−static int sctp_net_init(struct net *net)
825−{
826− return nf_ct_l4proto_pernet_register(net, sctp_proto,
827− ARRAY_SIZE(sctp_proto));
828−}
829−
830−static void sctp_net_exit(struct net *net)
831−{
832− nf_ct_l4proto_pernet_unregister(net, sctp_proto,
833− ARRAY_SIZE(sctp_proto));
834−}
835−
836−static struct pernet_operations sctp_net_ops = {
837− .init = sctp_net_init,
838− .exit = sctp_net_exit,
839− .id = &sctp_net_id,
840− .size = sizeof(struct sctp_net),
841−};
842−
843−static int __init nf_conntrack_proto_sctp_init(void)
844−{
845− int ret;
846−
847− ret = register_pernet_subsys(&sctp_net_ops);
848− if (ret < 0)
849− return ret;
850− ret = nf_ct_l4proto_register(sctp_proto, ARRAY_SIZE(sctp_proto));
851− if (ret < 0)
852− unregister_pernet_subsys(&sctp_net_ops);
853− return ret;
854−}
855−
856−static void __exit nf_conntrack_proto_sctp_fini(void)
857−{
858− nf_ct_l4proto_unregister(sctp_proto, ARRAY_SIZE(sctp_proto));
859− unregister_pernet_subsys(&sctp_net_ops);
860−}
861−
862−module_init(nf_conntrack_proto_sctp_init);
863−module_exit(nf_conntrack_proto_sctp_fini);
864−
865−MODULE_LICENSE("GPL");
866−MODULE_AUTHOR("Kiran Kumar Immidi");
867−MODULE_DESCRIPTION("Netfilter connection tracking protocol helper for SCTP");
868−MODULE_ALIAS("ip_conntrack_proto_sctp");
810+EXPORT_SYMBOL_GPL(nf_conntrack_l4proto_sctp6);
net/netfilter/nf_conntrack_proto_udplite.c+9−70
@@ -9,7 +9,6 @@ · 8 unmodified lines
99
1010 #include <linux/types.h>
1111 #include <linux/timer.h>
12−#include <linux/module.h>
1312 #include <linux/udp.h>
1413 #include <linux/seq_file.h>
1514 #include <linux/skbuff.h>
@@ -24,26 +23,14 @@ · 8 unmodified lines
2423 #include <net/netfilter/nf_conntrack_ecache.h>
2524 #include <net/netfilter/nf_log.h>
2625
27−enum udplite_conntrack {
28− UDPLITE_CT_UNREPLIED,
29− UDPLITE_CT_REPLIED,
30− UDPLITE_CT_MAX
31−};
32−
3326 static unsigned int udplite_timeouts[UDPLITE_CT_MAX] = {
3427 [UDPLITE_CT_UNREPLIED] = 30*HZ,
3528 [UDPLITE_CT_REPLIED] = 180*HZ,
3629 };
3730
38−static unsigned int udplite_net_id __read_mostly;
39−struct udplite_net {
40− struct nf_proto_net pn;
41− unsigned int timeouts[UDPLITE_CT_MAX];
42−};
43−
44−static inline struct udplite_net *udplite_pernet(struct net *net)
31+static inline struct nf_udplite_net *udplite_pernet(struct net *net)
4532 {
46− return net_generic(net, udplite_net_id);
33+ return &net->ct.nf_ct_proto.udplite;
4734 }
4835
4936 static bool udplite_pkt_to_tuple(const struct sk_buff *skb,
@@ -178,7 +165,7 @@ static int udplite_timeout_nlattr_to_obj(struct nlattr *tb[], · 128 unmodified lines
178165 struct net *net, void *data)
179166 {
180167 unsigned int *timeouts = data;
181− struct udplite_net *un = udplite_pernet(net);
168+ struct nf_udplite_net *un = udplite_pernet(net);
182169
183170 /* set default timeouts for UDPlite. */
184171 timeouts[UDPLITE_CT_UNREPLIED] = un->timeouts[UDPLITE_CT_UNREPLIED];
@@ -237,7 +224,7 @@ static struct ctl_table udplite_sysctl_table[] = { · 52 unmodified lines
237224 #endif /* CONFIG_SYSCTL */
238225
239226 static int udplite_kmemdup_sysctl_table(struct nf_proto_net *pn,
240− struct udplite_net *un)
227+ struct nf_udplite_net *un)
241228 {
242229 #ifdef CONFIG_SYSCTL
243230 if (pn->ctl_table)
@@ -257,7 +244,7 @@ static int udplite_kmemdup_sysctl_table(struct nf_proto_net *pn, · 13 unmodified lines
257244
258245 static int udplite_init_net(struct net *net, u_int16_t proto)
259246 {
260− struct udplite_net *un = udplite_pernet(net);
247+ struct nf_udplite_net *un = udplite_pernet(net);
261248 struct nf_proto_net *pn = &un->pn;
262249
263250 if (!pn->users) {
@@ -270,7 +257,7 @@ static int udplite_init_net(struct net *net, u_int16_t proto) · 6 unmodified lines
270257 return udplite_kmemdup_sysctl_table(pn, un);
271258 }
272259
273−static struct nf_conntrack_l4proto nf_conntrack_l4proto_udplite4 __read_mostly =
260+struct nf_conntrack_l4proto nf_conntrack_l4proto_udplite4 __read_mostly =
274261 {
275262 .l3proto = PF_INET,
276263 .l4proto = IPPROTO_UDPLITE,
@@ -299,11 +286,11 @@ static struct nf_conntrack_l4proto nf_conntrack_l4proto_udplite4 __read_mostly = · 22 unmodified lines
299286 .nla_policy = udplite_timeout_nla_policy,
300287 },
301288 #endif /* CONFIG_NF_CT_NETLINK_TIMEOUT */
302− .net_id = &udplite_net_id,
303289 .init_net = udplite_init_net,
304290 };
291+EXPORT_SYMBOL_GPL(nf_conntrack_l4proto_udplite4);
305292
306−static struct nf_conntrack_l4proto nf_conntrack_l4proto_udplite6 __read_mostly =
293+struct nf_conntrack_l4proto nf_conntrack_l4proto_udplite6 __read_mostly =
307294 {
308295 .l3proto = PF_INET6,
309296 .l4proto = IPPROTO_UDPLITE,
@@ -332,54 +319,6 @@ static struct nf_conntrack_l4proto nf_conntrack_l4proto_udplite6 __read_mostly = · 22 unmodified lines
332319 .nla_policy = udplite_timeout_nla_policy,
333320 },
334321 #endif /* CONFIG_NF_CT_NETLINK_TIMEOUT */
335− .net_id = &udplite_net_id,
336322 .init_net = udplite_init_net,
337323 };
338−
339−static struct nf_conntrack_l4proto *udplite_proto[] = {
340− &nf_conntrack_l4proto_udplite4,
341− &nf_conntrack_l4proto_udplite6,
342−};
343−
344−static int udplite_net_init(struct net *net)
345−{
346− return nf_ct_l4proto_pernet_register(net, udplite_proto,
347− ARRAY_SIZE(udplite_proto));
348−}
349−
350−static void udplite_net_exit(struct net *net)
351−{
352− nf_ct_l4proto_pernet_unregister(net, udplite_proto,
353− ARRAY_SIZE(udplite_proto));
354−}
355−
356−static struct pernet_operations udplite_net_ops = {
357− .init = udplite_net_init,
358− .exit = udplite_net_exit,
359− .id = &udplite_net_id,
360− .size = sizeof(struct udplite_net),
361−};
362−
363−static int __init nf_conntrack_proto_udplite_init(void)
364−{
365− int ret;
366−
367− ret = register_pernet_subsys(&udplite_net_ops);
368− if (ret < 0)
369− return ret;
370− ret = nf_ct_l4proto_register(udplite_proto, ARRAY_SIZE(udplite_proto));
371− if (ret < 0)
372− unregister_pernet_subsys(&udplite_net_ops);
373− return ret;
374−}
375−
376−static void __exit nf_conntrack_proto_udplite_exit(void)
377−{
378− nf_ct_l4proto_unregister(udplite_proto, ARRAY_SIZE(udplite_proto));
379− unregister_pernet_subsys(&udplite_net_ops);
380−}
381−
382−module_init(nf_conntrack_proto_udplite_init);
383−module_exit(nf_conntrack_proto_udplite_exit);
384−
385−MODULE_LICENSE("GPL");
324+EXPORT_SYMBOL_GPL(nf_conntrack_l4proto_udplite6);
net/netfilter/nf_conntrack_standalone.c+10−0
@@ -452,6 +452,9 @@ static int log_invalid_proto_max __read_mostly = 255; · 451 unmodified lines
452452 /* size the user *wants to set */
453453 static unsigned int nf_conntrack_htable_size_user __read_mostly;
454454
455+extern unsigned int nf_conntrack_default_on;
456+unsigned int nf_conntrack_default_on __read_mostly = 1;
457+
455458 static int
456459 nf_conntrack_hash_sysctl(struct ctl_table *table, int write,
457460 void __user *buffer, size_t *lenp, loff_t *ppos)
@@ -517,6 +520,13 @@ static struct ctl_table nf_ct_sysctl_table[] = { · 59 unmodified lines
517520 .mode = 0644,
518521 .proc_handler = proc_dointvec,
519522 },
523+ {
524+ .procname = "nf_conntrack_default_on",
525+ .data = &nf_conntrack_default_on,
526+ .maxlen = sizeof(unsigned int),
527+ .mode = 0644,
528+ .proc_handler = proc_dointvec,
529+ },
520530 { }
521531 };
522532
net/netfilter/nf_dup_netdev.c+25−8
@@ -14,6 +14,29 @@ · 13 unmodified lines
1414 #include <linux/netfilter/nf_tables.h>
1515 #include <net/netfilter/nf_tables.h>
1616
17+static void nf_do_netdev_egress(struct sk_buff *skb, struct net_device *dev)
18+{
19+ if (skb_mac_header_was_set(skb))
20+ skb_push(skb, skb->mac_len);
21+
22+ skb->dev = dev;
23+ dev_queue_xmit(skb);
24+}
25+
26+void nf_fwd_netdev_egress(const struct nft_pktinfo *pkt, int oif)
27+{
28+ struct net_device *dev;
29+
30+ dev = dev_get_by_index_rcu(nft_net(pkt), oif);
31+ if (!dev) {
32+ kfree_skb(pkt->skb);
33+ return;
34+ }
35+
36+ nf_do_netdev_egress(pkt->skb, dev);
37+}
38+EXPORT_SYMBOL_GPL(nf_fwd_netdev_egress);
39+
1740 void nf_dup_netdev_egress(const struct nft_pktinfo *pkt, int oif)
1841 {
1942 struct net_device *dev;
@@ -24,14 +47,8 @@ void nf_dup_netdev_egress(const struct nft_pktinfo *pkt, int oif) · 4 unmodified lines
2447 return;
2548
2649 skb = skb_clone(pkt->skb, GFP_ATOMIC);
27− if (skb == NULL)
28− return;
29−
30− if (skb_mac_header_was_set(skb))
31− skb_push(skb, skb->mac_len);
32−
33− skb->dev = dev;
34− dev_queue_xmit(skb);
50+ if (skb)
51+ nf_do_netdev_egress(skb, dev);
3552 }
3653 EXPORT_SYMBOL_GPL(nf_dup_netdev_egress);
3754
net/netfilter/nf_log_common.c+2−1
@@ -177,6 +177,7 @@ EXPORT_SYMBOL_GPL(nf_log_dump_packet_common); · 176 unmodified lines
177177
178178 /* bridge and netdev logging families share this code. */
179179 void nf_log_l2packet(struct net *net, u_int8_t pf,
180+ __be16 protocol,
180181 unsigned int hooknum,
181182 const struct sk_buff *skb,
182183 const struct net_device *in,
@@ -184,7 +185,7 @@ void nf_log_l2packet(struct net *net, u_int8_t pf, · 1 unmodified line
184185 const struct nf_loginfo *loginfo,
185186 const char *prefix)
186187 {
187− switch (eth_hdr(skb)->h_proto) {
188+ switch (protocol) {
188189 case htons(ETH_P_IP):
189190 nf_log_packet(net, NFPROTO_IPV4, hooknum, skb, in, out,
190191 loginfo, "%s", prefix);
net/netfilter/nf_log_netdev.c+2−1
@@ -23,7 +23,8 @@ static void nf_log_netdev_packet(struct net *net, u_int8_t pf, · 22 unmodified lines
2323 const struct nf_loginfo *loginfo,
2424 const char *prefix)
2525 {
26− nf_log_l2packet(net, pf, hooknum, skb, in, out, loginfo, prefix);
26+ nf_log_l2packet(net, pf, skb->protocol, hooknum, skb, in, out,
27+ loginfo, prefix);
2728 }
2829
2930 static struct nf_logger nf_netdev_logger __read_mostly = {
net/netfilter/nf_nat_core.c+12−0
@@ -682,6 +682,18 @@ int nf_nat_l3proto_register(const struct nf_nat_l3proto *l3proto) · 681 unmodified lines
682682 &nf_nat_l4proto_tcp);
683683 RCU_INIT_POINTER(nf_nat_l4protos[l3proto->l3proto][IPPROTO_UDP],
684684 &nf_nat_l4proto_udp);
685+#ifdef CONFIG_NF_NAT_PROTO_DCCP
686+ RCU_INIT_POINTER(nf_nat_l4protos[l3proto->l3proto][IPPROTO_DCCP],
687+ &nf_nat_l4proto_dccp);
688+#endif
689+#ifdef CONFIG_NF_NAT_PROTO_SCTP
690+ RCU_INIT_POINTER(nf_nat_l4protos[l3proto->l3proto][IPPROTO_SCTP],
691+ &nf_nat_l4proto_sctp);
692+#endif
693+#ifdef CONFIG_NF_NAT_PROTO_UDPLITE
694+ RCU_INIT_POINTER(nf_nat_l4protos[l3proto->l3proto][IPPROTO_UDPLITE],
695+ &nf_nat_l4proto_udplite);
696+#endif
685697 mutex_unlock(&nf_nat_proto_mutex);
686698
687699 RCU_INIT_POINTER(nf_nat_l3protos[l3proto->l3proto], l3proto);
net/netfilter/nf_nat_proto_dccp.c+1−35
@@ -10,8 +10,6 @@ · 9 unmodified lines
1010 */
1111
1212 #include <linux/kernel.h>
13−#include <linux/module.h>
14−#include <linux/init.h>
1513 #include <linux/skbuff.h>
1614 #include <linux/dccp.h>
1715
@@ -73,7 +71,7 @@ dccp_manip_pkt(struct sk_buff *skb, · 55 unmodified lines
7371 return true;
7472 }
7573
76−static const struct nf_nat_l4proto nf_nat_l4proto_dccp = {
74+const struct nf_nat_l4proto nf_nat_l4proto_dccp = {
7775 .l4proto = IPPROTO_DCCP,
7876 .manip_pkt = dccp_manip_pkt,
7977 .in_range = nf_nat_l4proto_in_range,
@@ -82,35 +80,3 @@ static const struct nf_nat_l4proto nf_nat_l4proto_dccp = { · 2 unmodified lines
8280 .nlattr_to_range = nf_nat_l4proto_nlattr_to_range,
8381 #endif
8482 };
85−
86−static int __init nf_nat_proto_dccp_init(void)
87−{
88− int err;
89−
90− err = nf_nat_l4proto_register(NFPROTO_IPV4, &nf_nat_l4proto_dccp);
91− if (err < 0)
92− goto err1;
93− err = nf_nat_l4proto_register(NFPROTO_IPV6, &nf_nat_l4proto_dccp);
94− if (err < 0)
95− goto err2;
96− return 0;
97−
98−err2:
99− nf_nat_l4proto_unregister(NFPROTO_IPV4, &nf_nat_l4proto_dccp);
100−err1:
101− return err;
102−}
103−
104−static void __exit nf_nat_proto_dccp_fini(void)
105−{
106− nf_nat_l4proto_unregister(NFPROTO_IPV6, &nf_nat_l4proto_dccp);
107− nf_nat_l4proto_unregister(NFPROTO_IPV4, &nf_nat_l4proto_dccp);
108−
109−}
110−
111−module_init(nf_nat_proto_dccp_init);
112−module_exit(nf_nat_proto_dccp_fini);
113−
114−MODULE_AUTHOR("Patrick McHardy <kaber@trash.net>");
115−MODULE_DESCRIPTION("DCCP NAT protocol helper");
116−MODULE_LICENSE("GPL");
net/netfilter/nf_nat_proto_sctp.c+5−35
@@ -7,9 +7,7 @@ · 6 unmodified lines
77 */
88
99 #include <linux/types.h>
10−#include <linux/init.h>
1110 #include <linux/sctp.h>
12−#include <linux/module.h>
1311 #include <net/sctp/checksum.h>
1412
1513 #include <net/netfilter/nf_nat_l4proto.h>
@@ -49,12 +47,15 @@ sctp_manip_pkt(struct sk_buff *skb, · 33 unmodified lines
4947 hdr->dest = tuple->dst.u.sctp.port;
5048 }
5149
52− hdr->checksum = sctp_compute_cksum(skb, hdroff);
50+ if (skb->ip_summed != CHECKSUM_PARTIAL) {
51+ hdr->checksum = sctp_compute_cksum(skb, hdroff);
52+ skb->ip_summed = CHECKSUM_NONE;
53+ }
5354
5455 return true;
5556 }
5657
57−static const struct nf_nat_l4proto nf_nat_l4proto_sctp = {
58+const struct nf_nat_l4proto nf_nat_l4proto_sctp = {
5859 .l4proto = IPPROTO_SCTP,
5960 .manip_pkt = sctp_manip_pkt,
6061 .in_range = nf_nat_l4proto_in_range,
@@ -63,34 +64,3 @@ static const struct nf_nat_l4proto nf_nat_l4proto_sctp = { · 2 unmodified lines
6364 .nlattr_to_range = nf_nat_l4proto_nlattr_to_range,
6465 #endif
6566 };
66−
67−static int __init nf_nat_proto_sctp_init(void)
68−{
69− int err;
70−
71− err = nf_nat_l4proto_register(NFPROTO_IPV4, &nf_nat_l4proto_sctp);
72− if (err < 0)
73− goto err1;
74− err = nf_nat_l4proto_register(NFPROTO_IPV6, &nf_nat_l4proto_sctp);
75− if (err < 0)
76− goto err2;
77− return 0;
78−
79−err2:
80− nf_nat_l4proto_unregister(NFPROTO_IPV4, &nf_nat_l4proto_sctp);
81−err1:
82− return err;
83−}
84−
85−static void __exit nf_nat_proto_sctp_exit(void)
86−{
87− nf_nat_l4proto_unregister(NFPROTO_IPV6, &nf_nat_l4proto_sctp);
88− nf_nat_l4proto_unregister(NFPROTO_IPV4, &nf_nat_l4proto_sctp);
89−}
90−
91−module_init(nf_nat_proto_sctp_init);
92−module_exit(nf_nat_proto_sctp_exit);
93−
94−MODULE_LICENSE("GPL");
95−MODULE_DESCRIPTION("SCTP NAT protocol helper");
96−MODULE_AUTHOR("Patrick McHardy <kaber@trash.net>");
net/netfilter/nf_nat_proto_udplite.c+1−34
@@ -8,11 +8,9 @@ · 7 unmodified lines
88 */
99
1010 #include <linux/types.h>
11−#include <linux/init.h>
1211 #include <linux/udp.h>
1312
1413 #include <linux/netfilter.h>
15−#include <linux/module.h>
1614 #include <net/netfilter/nf_nat.h>
1715 #include <net/netfilter/nf_nat_l3proto.h>
1816 #include <net/netfilter/nf_nat_l4proto.h>
@@ -64,7 +62,7 @@ udplite_manip_pkt(struct sk_buff *skb, · 45 unmodified lines
6462 return true;
6563 }
6664
67−static const struct nf_nat_l4proto nf_nat_l4proto_udplite = {
65+const struct nf_nat_l4proto nf_nat_l4proto_udplite = {
6866 .l4proto = IPPROTO_UDPLITE,
6967 .manip_pkt = udplite_manip_pkt,
7068 .in_range = nf_nat_l4proto_in_range,
@@ -73,34 +71,3 @@ static const struct nf_nat_l4proto nf_nat_l4proto_udplite = { · 2 unmodified lines
7371 .nlattr_to_range = nf_nat_l4proto_nlattr_to_range,
7472 #endif
7573 };
76−
77−static int __init nf_nat_proto_udplite_init(void)
78−{
79− int err;
80−
81− err = nf_nat_l4proto_register(NFPROTO_IPV4, &nf_nat_l4proto_udplite);
82− if (err < 0)
83− goto err1;
84− err = nf_nat_l4proto_register(NFPROTO_IPV6, &nf_nat_l4proto_udplite);
85− if (err < 0)
86− goto err2;
87− return 0;
88−
89−err2:
90− nf_nat_l4proto_unregister(NFPROTO_IPV4, &nf_nat_l4proto_udplite);
91−err1:
92− return err;
93−}
94−
95−static void __exit nf_nat_proto_udplite_fini(void)
96−{
97− nf_nat_l4proto_unregister(NFPROTO_IPV6, &nf_nat_l4proto_udplite);
98− nf_nat_l4proto_unregister(NFPROTO_IPV4, &nf_nat_l4proto_udplite);
99−}
100−
101−module_init(nf_nat_proto_udplite_init);
102−module_exit(nf_nat_proto_udplite_fini);
103−
104−MODULE_LICENSE("GPL");
105−MODULE_DESCRIPTION("UDP-Lite NAT protocol helper");
106−MODULE_AUTHOR("Patrick McHardy <kaber@trash.net>");
net/netfilter/nf_queue.c+2−3
@@ -185,7 +185,7 @@ static unsigned int nf_iterate(struct sk_buff *skb, · 184 unmodified lines
185185
186186 do {
187187 repeat:
188− verdict = (*entryp)->ops.hook((*entryp)->ops.priv, skb, state);
188+ verdict = nf_hook_entry_hookfn((*entryp), skb, state);
189189 if (verdict != NF_ACCEPT) {
190190 if (verdict != NF_REPEAT)
191191 return verdict;
@@ -200,7 +200,6 @@ repeat: · 8 unmodified lines
200200 void nf_reinject(struct nf_queue_entry *entry, unsigned int verdict)
201201 {
202202 struct nf_hook_entry *hook_entry = entry->hook;
203− struct nf_hook_ops *elem = &hook_entry->ops;
204203 struct sk_buff *skb = entry->skb;
205204 const struct nf_afinfo *afinfo;
206205 int err;
@@ -209,7 +208,7 @@ void nf_reinject(struct nf_queue_entry *entry, unsigned int verdict) · 2 unmodified lines
209208
210209 /* Continue traversal iff userspace said ok... */
211210 if (verdict == NF_REPEAT)
212− verdict = elem->hook(elem->priv, skb, &entry->state);
211+ verdict = nf_hook_entry_hookfn(hook_entry, skb, &entry->state);
213212
214213 if (verdict == NF_ACCEPT) {
215214 afinfo = nf_get_afinfo(entry->state.pf);
net/netfilter/nf_tables_api.c+702−16
@@ -22,6 +22,7 @@ · 21 unmodified lines
2222 #include <net/sock.h>
2323
2424 static LIST_HEAD(nf_tables_expressions);
25+static LIST_HEAD(nf_tables_objects);
2526
2627 /**
2728 * nft_register_afinfo - register nf_tables address family info
@@ -110,12 +111,12 @@ static void nft_ctx_init(struct nft_ctx *ctx, · 82 unmodified lines
110111 ctx->seq = nlh->nlmsg_seq;
111112 }
112113
113−static struct nft_trans *nft_trans_alloc(struct nft_ctx *ctx, int msg_type,
114− u32 size)
114+static struct nft_trans *nft_trans_alloc_gfp(const struct nft_ctx *ctx,
115+ int msg_type, u32 size, gfp_t gfp)
115116 {
116117 struct nft_trans *trans;
117118
118− trans = kzalloc(sizeof(struct nft_trans) + size, GFP_KERNEL);
119+ trans = kzalloc(sizeof(struct nft_trans) + size, gfp);
119120 if (trans == NULL)
120121 return NULL;
121122
@@ -125,6 +126,12 @@ static struct nft_trans *nft_trans_alloc(struct nft_ctx *ctx, int msg_type, · 3 unmodified lines
125126 return trans;
126127 }
127128
129+static struct nft_trans *nft_trans_alloc(const struct nft_ctx *ctx,
130+ int msg_type, u32 size)
131+{
132+ return nft_trans_alloc_gfp(ctx, msg_type, size, GFP_KERNEL);
133+}
134+
128135 static void nft_trans_destroy(struct nft_trans *trans)
129136 {
130137 list_del(&trans->list);
@@ -304,6 +311,38 @@ static int nft_delset(struct nft_ctx *ctx, struct nft_set *set) · 173 unmodified lines
304311 return err;
305312 }
306313
314+static int nft_trans_obj_add(struct nft_ctx *ctx, int msg_type,
315+ struct nft_object *obj)
316+{
317+ struct nft_trans *trans;
318+
319+ trans = nft_trans_alloc(ctx, msg_type, sizeof(struct nft_trans_obj));
320+ if (trans == NULL)
321+ return -ENOMEM;
322+
323+ if (msg_type == NFT_MSG_NEWOBJ)
324+ nft_activate_next(ctx->net, obj);
325+
326+ nft_trans_obj(trans) = obj;
327+ list_add_tail(&trans->list, &ctx->net->nft.commit_list);
328+
329+ return 0;
330+}
331+
332+static int nft_delobj(struct nft_ctx *ctx, struct nft_object *obj)
333+{
334+ int err;
335+
336+ err = nft_trans_obj_add(ctx, NFT_MSG_DELOBJ, obj);
337+ if (err < 0)
338+ return err;
339+
340+ nft_deactivate_next(ctx->net, obj);
341+ ctx->table->use--;
342+
343+ return err;
344+}
345+
307346 /*
308347 * Tables
309348 */
@@ -688,6 +727,7 @@ static int nf_tables_newtable(struct net *net, struct sock *nlsk, · 378 unmodified lines
688727 nla_strlcpy(table->name, name, NFT_TABLE_MAXNAMELEN);
689728 INIT_LIST_HEAD(&table->chains);
690729 INIT_LIST_HEAD(&table->sets);
730+ INIT_LIST_HEAD(&table->objects);
691731 table->flags = flags;
692732
693733 nft_ctx_init(&ctx, net, skb, nlh, afi, table, NULL, nla);
@@ -709,6 +749,7 @@ static int nft_flush_table(struct nft_ctx *ctx) · 15 unmodified lines
709749 {
710750 int err;
711751 struct nft_chain *chain, *nc;
752+ struct nft_object *obj, *ne;
712753 struct nft_set *set, *ns;
713754
714755 list_for_each_entry(chain, &ctx->table->chains, list) {
@@ -735,6 +776,12 @@ static int nft_flush_table(struct nft_ctx *ctx) · 20 unmodified lines
735776 goto out;
736777 }
737778
779+ list_for_each_entry_safe(obj, ne, &ctx->table->objects, list) {
780+ err = nft_delobj(ctx, obj);
781+ if (err < 0)
782+ goto out;
783+ }
784+
738785 list_for_each_entry_safe(chain, nc, &ctx->table->chains, list) {
739786 if (!nft_is_active_next(ctx->net, chain))
740787 continue;
@@ -2411,6 +2458,7 @@ static const struct nla_policy nft_set_policy[NFTA_SET_MAX + 1] = { · 1670 unmodified lines
24112458 [NFTA_SET_GC_INTERVAL] = { .type = NLA_U32 },
24122459 [NFTA_SET_USERDATA] = { .type = NLA_BINARY,
24132460 .len = NFT_USERDATA_MAXLEN },
2461+ [NFTA_SET_OBJ_TYPE] = { .type = NLA_U32 },
24142462 };
24152463
24162464 static const struct nla_policy nft_set_desc_policy[NFTA_SET_DESC_MAX + 1] = {
@@ -2462,6 +2510,7 @@ struct nft_set *nf_tables_set_lookup(const struct nft_table *table, · 45 unmodified lines
24622510 }
24632511 return ERR_PTR(-ENOENT);
24642512 }
2513+EXPORT_SYMBOL_GPL(nf_tables_set_lookup);
24652514
24662515 struct nft_set *nf_tables_set_lookup_byid(const struct net *net,
24672516 const struct nlattr *nla,
@@ -2480,6 +2529,7 @@ struct nft_set *nf_tables_set_lookup_byid(const struct net *net, · 12 unmodified lines
24802529 }
24812530 return ERR_PTR(-ENOENT);
24822531 }
2532+EXPORT_SYMBOL_GPL(nf_tables_set_lookup_byid);
24832533
24842534 static int nf_tables_set_alloc_name(struct nft_ctx *ctx, struct nft_set *set,
24852535 const char *name)
@@ -2568,6 +2618,9 @@ static int nf_tables_fill_set(struct sk_buff *skb, const struct nft_ctx *ctx, · 82 unmodified lines
25682618 if (nla_put_be32(skb, NFTA_SET_DATA_LEN, htonl(set->dlen)))
25692619 goto nla_put_failure;
25702620 }
2621+ if (set->flags & NFT_SET_OBJECT &&
2622+ nla_put_be32(skb, NFTA_SET_OBJ_TYPE, htonl(set->objtype)))
2623+ goto nla_put_failure;
25712624
25722625 if (set->timeout &&
25732626 nla_put_be64(skb, NFTA_SET_TIMEOUT,
@@ -2797,7 +2850,7 @@ static int nf_tables_newset(struct net *net, struct sock *nlsk, · 223 unmodified lines
27972850 unsigned int size;
27982851 bool create;
27992852 u64 timeout;
2800− u32 ktype, dtype, flags, policy, gc_int;
2853+ u32 ktype, dtype, flags, policy, gc_int, objtype;
28012854 struct nft_set_desc desc;
28022855 unsigned char *udata;
28032856 u16 udlen;
@@ -2827,11 +2880,12 @@ static int nf_tables_newset(struct net *net, struct sock *nlsk, · 23 unmodified lines
28272880 flags = ntohl(nla_get_be32(nla[NFTA_SET_FLAGS]));
28282881 if (flags & ~(NFT_SET_ANONYMOUS | NFT_SET_CONSTANT |
28292882 NFT_SET_INTERVAL | NFT_SET_TIMEOUT |
2830− NFT_SET_MAP | NFT_SET_EVAL))
2883+ NFT_SET_MAP | NFT_SET_EVAL |
2884+ NFT_SET_OBJECT))
28312885 return -EINVAL;
2832− /* Only one of both operations is supported */
2833− if ((flags & (NFT_SET_MAP | NFT_SET_EVAL)) ==
2834− (NFT_SET_MAP | NFT_SET_EVAL))
2886+ /* Only one of these operations is supported */
2887+ if ((flags & (NFT_SET_MAP | NFT_SET_EVAL | NFT_SET_OBJECT)) ==
2888+ (NFT_SET_MAP | NFT_SET_EVAL | NFT_SET_OBJECT))
28352889 return -EOPNOTSUPP;
28362890 }
28372891
@@ -2856,6 +2910,19 @@ static int nf_tables_newset(struct net *net, struct sock *nlsk, · 18 unmodified lines
28562910 } else if (flags & NFT_SET_MAP)
28572911 return -EINVAL;
28582912
2913+ if (nla[NFTA_SET_OBJ_TYPE] != NULL) {
2914+ if (!(flags & NFT_SET_OBJECT))
2915+ return -EINVAL;
2916+
2917+ objtype = ntohl(nla_get_be32(nla[NFTA_SET_OBJ_TYPE]));
2918+ if (objtype == NFT_OBJECT_UNSPEC ||
2919+ objtype > NFT_OBJECT_MAX)
2920+ return -EINVAL;
2921+ } else if (flags & NFT_SET_OBJECT)
2922+ return -EINVAL;
2923+ else
2924+ objtype = NFT_OBJECT_UNSPEC;
2925+
28592926 timeout = 0;
28602927 if (nla[NFTA_SET_TIMEOUT] != NULL) {
28612928 if (!(flags & NFT_SET_TIMEOUT))
@@ -2943,6 +3010,7 @@ static int nf_tables_newset(struct net *net, struct sock *nlsk, · 81 unmodified lines
29433010 set->ktype = ktype;
29443011 set->klen = desc.klen;
29453012 set->dtype = dtype;
3013+ set->objtype = objtype;
29463014 set->dlen = desc.dlen;
29473015 set->flags = flags;
29483016 set->size = desc.size;
@@ -3064,6 +3132,7 @@ bind: · 115 unmodified lines
30643132 list_add_tail_rcu(&binding->list, &set->bindings);
30653133 return 0;
30663134 }
3135+EXPORT_SYMBOL_GPL(nf_tables_bind_set);
30673136
30683137 void nf_tables_unbind_set(const struct nft_ctx *ctx, struct nft_set *set,
30693138 struct nft_set_binding *binding)
@@ -3074,6 +3143,7 @@ void nf_tables_unbind_set(const struct nft_ctx *ctx, struct nft_set *set, · 4 unmodified lines
30743143 nft_is_active(ctx->net, set))
30753144 nf_tables_set_destroy(ctx, set);
30763145 }
3146+EXPORT_SYMBOL_GPL(nf_tables_unbind_set);
30773147
30783148 const struct nft_set_ext_type nft_set_ext_types[] = {
30793149 [NFT_SET_EXT_KEY] = {
@@ -3085,6 +3155,10 @@ const struct nft_set_ext_type nft_set_ext_types[] = { · 5 unmodified lines
30853155 [NFT_SET_EXT_EXPR] = {
30863156 .align = __alignof__(struct nft_expr),
30873157 },
3158+ [NFT_SET_EXT_OBJREF] = {
3159+ .len = sizeof(struct nft_object *),
3160+ .align = __alignof__(struct nft_object *),
3161+ },
30883162 [NFT_SET_EXT_FLAGS] = {
30893163 .len = sizeof(u8),
30903164 .align = __alignof__(u8),
@@ -3173,6 +3247,11 @@ static int nf_tables_fill_setelem(struct sk_buff *skb, · 82 unmodified lines
31733247 nft_expr_dump(skb, NFTA_SET_ELEM_EXPR, nft_set_ext_expr(ext)) < 0)
31743248 goto nla_put_failure;
31753249
3250+ if (nft_set_ext_exists(ext, NFT_SET_EXT_OBJREF) &&
3251+ nla_put_string(skb, NFTA_SET_ELEM_OBJREF,
3252+ (*nft_set_ext_obj(ext))->name) < 0)
3253+ goto nla_put_failure;
3254+
31763255 if (nft_set_ext_exists(ext, NFT_SET_EXT_FLAGS) &&
31773256 nla_put_be32(skb, NFTA_SET_ELEM_FLAGS,
31783257 htonl(*nft_set_ext_flags(ext))))
@@ -3467,7 +3546,8 @@ void nft_set_elem_destroy(const struct nft_set *set, void *elem, · 288 unmodified lines
34673546 nft_data_uninit(nft_set_ext_data(ext), set->dtype);
34683547 if (destroy_expr && nft_set_ext_exists(ext, NFT_SET_EXT_EXPR))
34693548 nf_tables_expr_destroy(NULL, nft_set_ext_expr(ext));
3470−
3549+ if (nft_set_ext_exists(ext, NFT_SET_EXT_OBJREF))
3550+ (*nft_set_ext_obj(ext))->use--;
34713551 kfree(elem);
34723552 }
34733553 EXPORT_SYMBOL_GPL(nft_set_elem_destroy);
@@ -3492,11 +3572,13 @@ static int nft_add_set_elem(struct nft_ctx *ctx, struct nft_set *set, · 18 unmodified lines
34923572 const struct nlattr *attr, u32 nlmsg_flags)
34933573 {
34943574 struct nlattr *nla[NFTA_SET_ELEM_MAX + 1];
3575+ u8 genmask = nft_genmask_next(ctx->net);
34953576 struct nft_data_desc d1, d2;
34963577 struct nft_set_ext_tmpl tmpl;
34973578 struct nft_set_ext *ext, *ext2;
34983579 struct nft_set_elem elem;
34993580 struct nft_set_binding *binding;
3581+ struct nft_object *obj = NULL;
35003582 struct nft_userdata *udata;
35013583 struct nft_data data;
35023584 enum nft_registers dreg;
@@ -3559,6 +3641,20 @@ static int nft_add_set_elem(struct nft_ctx *ctx, struct nft_set *set, · 56 unmodified lines
35593641 nft_set_ext_add(&tmpl, NFT_SET_EXT_TIMEOUT);
35603642 }
35613643
3644+ if (nla[NFTA_SET_ELEM_OBJREF] != NULL) {
3645+ if (!(set->flags & NFT_SET_OBJECT)) {
3646+ err = -EINVAL;
3647+ goto err2;
3648+ }
3649+ obj = nf_tables_obj_lookup(ctx->table, nla[NFTA_SET_ELEM_OBJREF],
3650+ set->objtype, genmask);
3651+ if (IS_ERR(obj)) {
3652+ err = PTR_ERR(obj);
3653+ goto err2;
3654+ }
3655+ nft_set_ext_add(&tmpl, NFT_SET_EXT_OBJREF);
3656+ }
3657+
35623658 if (nla[NFTA_SET_ELEM_DATA] != NULL) {
35633659 err = nft_data_init(ctx, &data, sizeof(data), &d2,
35643660 nla[NFTA_SET_ELEM_DATA]);
@@ -3617,6 +3713,10 @@ static int nft_add_set_elem(struct nft_ctx *ctx, struct nft_set *set, · 52 unmodified lines
36173713 udata->len = ulen - 1;
36183714 nla_memcpy(&udata->data, nla[NFTA_SET_ELEM_USERDATA], ulen);
36193715 }
3716+ if (obj) {
3717+ *nft_set_ext_obj(ext) = obj;
3718+ obj->use++;
3719+ }
36203720
36213721 trans = nft_trans_elem_alloc(ctx, NFT_MSG_NEWSETELEM, set);
36223722 if (trans == NULL)
@@ -3626,10 +3726,13 @@ static int nft_add_set_elem(struct nft_ctx *ctx, struct nft_set *set, · 3 unmodified lines
36263726 err = set->ops->insert(ctx->net, set, &elem, &ext2);
36273727 if (err) {
36283728 if (err == -EEXIST) {
3629− if (nft_set_ext_exists(ext, NFT_SET_EXT_DATA) &&
3630− nft_set_ext_exists(ext2, NFT_SET_EXT_DATA) &&
3631− memcmp(nft_set_ext_data(ext),
3632− nft_set_ext_data(ext2), set->dlen) != 0)
3729+ if ((nft_set_ext_exists(ext, NFT_SET_EXT_DATA) &&
3730+ nft_set_ext_exists(ext2, NFT_SET_EXT_DATA) &&
3731+ memcmp(nft_set_ext_data(ext),
3732+ nft_set_ext_data(ext2), set->dlen) != 0) ||
3733+ (nft_set_ext_exists(ext, NFT_SET_EXT_OBJREF) &&
3734+ nft_set_ext_exists(ext2, NFT_SET_EXT_OBJREF) &&
3735+ *nft_set_ext_obj(ext) != *nft_set_ext_obj(ext2)))
36333736 err = -EBUSY;
36343737 else if (!(nlmsg_flags & NLM_F_EXCL))
36353738 err = 0;
@@ -3779,6 +3882,34 @@ err1: · 143 unmodified lines
37793882 return err;
37803883 }
37813884
3885+static int nft_flush_set(const struct nft_ctx *ctx,
3886+ const struct nft_set *set,
3887+ const struct nft_set_iter *iter,
3888+ const struct nft_set_elem *elem)
3889+{
3890+ struct nft_trans *trans;
3891+ int err;
3892+
3893+ trans = nft_trans_alloc_gfp(ctx, NFT_MSG_DELSETELEM,
3894+ sizeof(struct nft_trans_elem), GFP_ATOMIC);
3895+ if (!trans)
3896+ return -ENOMEM;
3897+
3898+ if (!set->ops->deactivate_one(ctx->net, set, elem->priv)) {
3899+ err = -ENOENT;
3900+ goto err1;
3901+ }
3902+
3903+ nft_trans_elem_set(trans) = (struct nft_set *)set;
3904+ nft_trans_elem(trans) = *((struct nft_set_elem *)elem);
3905+ list_add_tail(&trans->list, &ctx->net->nft.commit_list);
3906+
3907+ return 0;
3908+err1:
3909+ kfree(trans);
3910+ return err;
3911+}
3912+
37823913 static int nf_tables_delsetelem(struct net *net, struct sock *nlsk,
37833914 struct sk_buff *skb, const struct nlmsghdr *nlh,
37843915 const struct nlattr * const nla[])
@@ -3789,9 +3920,6 @@ static int nf_tables_delsetelem(struct net *net, struct sock *nlsk, · 4 unmodified lines
37893920 struct nft_ctx ctx;
37903921 int rem, err = 0;
37913922
3792− if (nla[NFTA_SET_ELEM_LIST_ELEMENTS] == NULL)
3793− return -EINVAL;
3794−
37953923 err = nft_ctx_init_from_elemattr(&ctx, net, skb, nlh, nla, genmask);
37963924 if (err < 0)
37973925 return err;
@@ -3803,6 +3931,18 @@ static int nf_tables_delsetelem(struct net *net, struct sock *nlsk, · 5 unmodified lines
38033931 if (!list_empty(&set->bindings) && set->flags & NFT_SET_CONSTANT)
38043932 return -EBUSY;
38053933
3934+ if (nla[NFTA_SET_ELEM_LIST_ELEMENTS] == NULL) {
3935+ struct nft_set_dump_args args = {
3936+ .iter = {
3937+ .genmask = genmask,
3938+ .fn = nft_flush_set,
3939+ },
3940+ };
3941+ set->ops->walk(&ctx, set, &args.iter);
3942+
3943+ return args.iter.err;
3944+ }
3945+
38063946 nla_for_each_nested(attr, nla[NFTA_SET_ELEM_LIST_ELEMENTS], rem) {
38073947 err = nft_del_setelem(&ctx, set, attr);
38083948 if (err < 0)
@@ -3838,6 +3978,500 @@ struct nft_set_gc_batch *nft_set_gc_batch_alloc(const struct nft_set *set, · 29 unmodified lines
38383978 }
38393979 EXPORT_SYMBOL_GPL(nft_set_gc_batch_alloc);
38403980
3981+/*
3982+ * Stateful objects
3983+ */
3984+
3985+/**
3986+ * nft_register_obj- register nf_tables stateful object type
3987+ * @obj: object type
3988+ *
3989+ * Registers the object type for use with nf_tables. Returns zero on
3990+ * success or a negative errno code otherwise.
3991+ */
3992+int nft_register_obj(struct nft_object_type *obj_type)
3993+{
3994+ if (obj_type->type == NFT_OBJECT_UNSPEC)
3995+ return -EINVAL;
3996+
3997+ nfnl_lock(NFNL_SUBSYS_NFTABLES);
3998+ list_add_rcu(&obj_type->list, &nf_tables_objects);
3999+ nfnl_unlock(NFNL_SUBSYS_NFTABLES);
4000+ return 0;
4001+}
4002+EXPORT_SYMBOL_GPL(nft_register_obj);
4003+
4004+/**
4005+ * nft_unregister_obj - unregister nf_tables object type
4006+ * @obj: object type
4007+ *
4008+ * Unregisters the object type for use with nf_tables.
4009+ */
4010+void nft_unregister_obj(struct nft_object_type *obj_type)
4011+{
4012+ nfnl_lock(NFNL_SUBSYS_NFTABLES);
4013+ list_del_rcu(&obj_type->list);
4014+ nfnl_unlock(NFNL_SUBSYS_NFTABLES);
4015+}
4016+EXPORT_SYMBOL_GPL(nft_unregister_obj);
4017+
4018+struct nft_object *nf_tables_obj_lookup(const struct nft_table *table,
4019+ const struct nlattr *nla,
4020+ u32 objtype, u8 genmask)
4021+{
4022+ struct nft_object *obj;
4023+
4024+ list_for_each_entry(obj, &table->objects, list) {
4025+ if (!nla_strcmp(nla, obj->name) &&
4026+ objtype == obj->type->type &&
4027+ nft_active_genmask(obj, genmask))
4028+ return obj;
4029+ }
4030+ return ERR_PTR(-ENOENT);
4031+}
4032+EXPORT_SYMBOL_GPL(nf_tables_obj_lookup);
4033+
4034+static const struct nla_policy nft_obj_policy[NFTA_OBJ_MAX + 1] = {
4035+ [NFTA_OBJ_TABLE] = { .type = NLA_STRING },
4036+ [NFTA_OBJ_NAME] = { .type = NLA_STRING },
4037+ [NFTA_OBJ_TYPE] = { .type = NLA_U32 },
4038+ [NFTA_OBJ_DATA] = { .type = NLA_NESTED },
4039+};
4040+
4041+static struct nft_object *nft_obj_init(const struct nft_object_type *type,
4042+ const struct nlattr *attr)
4043+{
4044+ struct nlattr *tb[type->maxattr + 1];
4045+ struct nft_object *obj;
4046+ int err;
4047+
4048+ if (attr) {
4049+ err = nla_parse_nested(tb, type->maxattr, attr, type->policy);
4050+ if (err < 0)
4051+ goto err1;
4052+ } else {
4053+ memset(tb, 0, sizeof(tb[0]) * (type->maxattr + 1));
4054+ }
4055+
4056+ err = -ENOMEM;
4057+ obj = kzalloc(sizeof(struct nft_object) + type->size, GFP_KERNEL);
4058+ if (obj == NULL)
4059+ goto err1;
4060+
4061+ err = type->init((const struct nlattr * const *)tb, obj);
4062+ if (err < 0)
4063+ goto err2;
4064+
4065+ obj->type = type;
4066+ return obj;
4067+err2:
4068+ kfree(obj);
4069+err1:
4070+ return ERR_PTR(err);
4071+}
4072+
4073+static int nft_object_dump(struct sk_buff *skb, unsigned int attr,
4074+ struct nft_object *obj, bool reset)
4075+{
4076+ struct nlattr *nest;
4077+
4078+ nest = nla_nest_start(skb, attr);
4079+ if (!nest)
4080+ goto nla_put_failure;
4081+ if (obj->type->dump(skb, obj, reset) < 0)
4082+ goto nla_put_failure;
4083+ nla_nest_end(skb, nest);
4084+ return 0;
4085+
4086+nla_put_failure:
4087+ return -1;
4088+}
4089+
4090+static const struct nft_object_type *__nft_obj_type_get(u32 objtype)
4091+{
4092+ const struct nft_object_type *type;
4093+
4094+ list_for_each_entry(type, &nf_tables_objects, list) {
4095+ if (objtype == type->type)
4096+ return type;
4097+ }
4098+ return NULL;
4099+}
4100+
4101+static const struct nft_object_type *nft_obj_type_get(u32 objtype)
4102+{
4103+ const struct nft_object_type *type;
4104+
4105+ type = __nft_obj_type_get(objtype);
4106+ if (type != NULL && try_module_get(type->owner))
4107+ return type;
4108+
4109+#ifdef CONFIG_MODULES
4110+ if (type == NULL) {
4111+ nfnl_unlock(NFNL_SUBSYS_NFTABLES);
4112+ request_module("nft-obj-%u", objtype);
4113+ nfnl_lock(NFNL_SUBSYS_NFTABLES);
4114+ if (__nft_obj_type_get(objtype))
4115+ return ERR_PTR(-EAGAIN);
4116+ }
4117+#endif
4118+ return ERR_PTR(-ENOENT);
4119+}
4120+
4121+static int nf_tables_newobj(struct net *net, struct sock *nlsk,
4122+ struct sk_buff *skb, const struct nlmsghdr *nlh,
4123+ const struct nlattr * const nla[])
4124+{
4125+ const struct nfgenmsg *nfmsg = nlmsg_data(nlh);
4126+ const struct nft_object_type *type;
4127+ u8 genmask = nft_genmask_next(net);
4128+ int family = nfmsg->nfgen_family;
4129+ struct nft_af_info *afi;
4130+ struct nft_table *table;
4131+ struct nft_object *obj;
4132+ struct nft_ctx ctx;
4133+ u32 objtype;
4134+ int err;
4135+
4136+ if (!nla[NFTA_OBJ_TYPE] ||
4137+ !nla[NFTA_OBJ_NAME] ||
4138+ !nla[NFTA_OBJ_DATA])
4139+ return -EINVAL;
4140+
4141+ afi = nf_tables_afinfo_lookup(net, family, true);
4142+ if (IS_ERR(afi))
4143+ return PTR_ERR(afi);
4144+
4145+ table = nf_tables_table_lookup(afi, nla[NFTA_OBJ_TABLE], genmask);
4146+ if (IS_ERR(table))
4147+ return PTR_ERR(table);
4148+
4149+ objtype = ntohl(nla_get_be32(nla[NFTA_OBJ_TYPE]));
4150+ obj = nf_tables_obj_lookup(table, nla[NFTA_OBJ_NAME], objtype, genmask);
4151+ if (IS_ERR(obj)) {
4152+ err = PTR_ERR(obj);
4153+ if (err != -ENOENT)
4154+ return err;
4155+
4156+ obj = NULL;
4157+ }
4158+
4159+ if (obj != NULL) {
4160+ if (nlh->nlmsg_flags & NLM_F_EXCL)
4161+ return -EEXIST;
4162+
4163+ return 0;
4164+ }
4165+
4166+ nft_ctx_init(&ctx, net, skb, nlh, afi, table, NULL, nla);
4167+
4168+ type = nft_obj_type_get(objtype);
4169+ if (IS_ERR(type))
4170+ return PTR_ERR(type);
4171+
4172+ obj = nft_obj_init(type, nla[NFTA_OBJ_DATA]);
4173+ if (IS_ERR(obj)) {
4174+ err = PTR_ERR(obj);
4175+ goto err1;
4176+ }
4177+ obj->table = table;
4178+ nla_strlcpy(obj->name, nla[NFTA_OBJ_NAME], NFT_OBJ_MAXNAMELEN);
4179+
4180+ err = nft_trans_obj_add(&ctx, NFT_MSG_NEWOBJ, obj);
4181+ if (err < 0)
4182+ goto err2;
4183+
4184+ list_add_tail_rcu(&obj->list, &table->objects);
4185+ table->use++;
4186+ return 0;
4187+err2:
4188+ if (obj->type->destroy)
4189+ obj->type->destroy(obj);
4190+ kfree(obj);
4191+err1:
4192+ module_put(type->owner);
4193+ return err;
4194+}
4195+
4196+static int nf_tables_fill_obj_info(struct sk_buff *skb, struct net *net,
4197+ u32 portid, u32 seq, int event, u32 flags,
4198+ int family, const struct nft_table *table,
4199+ struct nft_object *obj, bool reset)
4200+{
4201+ struct nfgenmsg *nfmsg;
4202+ struct nlmsghdr *nlh;
4203+
4204+ event |= NFNL_SUBSYS_NFTABLES << 8;
4205+ nlh = nlmsg_put(skb, portid, seq, event, sizeof(struct nfgenmsg), flags);
4206+ if (nlh == NULL)
4207+ goto nla_put_failure;
4208+
4209+ nfmsg = nlmsg_data(nlh);
4210+ nfmsg->nfgen_family = family;
4211+ nfmsg->version = NFNETLINK_V0;
4212+ nfmsg->res_id = htons(net->nft.base_seq & 0xffff);
4213+
4214+ if (nla_put_string(skb, NFTA_OBJ_TABLE, table->name) ||
4215+ nla_put_string(skb, NFTA_OBJ_NAME, obj->name) ||
4216+ nla_put_be32(skb, NFTA_OBJ_TYPE, htonl(obj->type->type)) ||
4217+ nla_put_be32(skb, NFTA_OBJ_USE, htonl(obj->use)) ||
4218+ nft_object_dump(skb, NFTA_OBJ_DATA, obj, reset))
4219+ goto nla_put_failure;
4220+
4221+ nlmsg_end(skb, nlh);
4222+ return 0;
4223+
4224+nla_put_failure:
4225+ nlmsg_trim(skb, nlh);
4226+ return -1;
4227+}
4228+
4229+struct nft_obj_filter {
4230+ char table[NFT_OBJ_MAXNAMELEN];
4231+ u32 type;
4232+};
4233+
4234+static int nf_tables_dump_obj(struct sk_buff *skb, struct netlink_callback *cb)
4235+{
4236+ const struct nfgenmsg *nfmsg = nlmsg_data(cb->nlh);
4237+ const struct nft_af_info *afi;
4238+ const struct nft_table *table;
4239+ unsigned int idx = 0, s_idx = cb->args[0];
4240+ struct nft_obj_filter *filter = cb->data;
4241+ struct net *net = sock_net(skb->sk);
4242+ int family = nfmsg->nfgen_family;
4243+ struct nft_object *obj;
4244+ bool reset = false;
4245+
4246+ if (NFNL_MSG_TYPE(cb->nlh->nlmsg_type) == NFT_MSG_GETOBJ_RESET)
4247+ reset = true;
4248+
4249+ rcu_read_lock();
4250+ cb->seq = net->nft.base_seq;
4251+
4252+ list_for_each_entry_rcu(afi, &net->nft.af_info, list) {
4253+ if (family != NFPROTO_UNSPEC && family != afi->family)
4254+ continue;
4255+
4256+ list_for_each_entry_rcu(table, &afi->tables, list) {
4257+ list_for_each_entry_rcu(obj, &table->objects, list) {
4258+ if (!nft_is_active(net, obj))
4259+ goto cont;
4260+ if (idx < s_idx)
4261+ goto cont;
4262+ if (idx > s_idx)
4263+ memset(&cb->args[1], 0,
4264+ sizeof(cb->args) - sizeof(cb->args[0]));
4265+ if (filter->table[0] &&
4266+ strcmp(filter->table, table->name))
4267+ goto cont;
4268+ if (filter->type != NFT_OBJECT_UNSPEC &&
4269+ obj->type->type != filter->type)
4270+ goto cont;
4271+
4272+ if (nf_tables_fill_obj_info(skb, net, NETLINK_CB(cb->skb).portid,
4273+ cb->nlh->nlmsg_seq,
4274+ NFT_MSG_NEWOBJ,
4275+ NLM_F_MULTI | NLM_F_APPEND,
4276+ afi->family, table, obj, reset) < 0)
4277+ goto done;
4278+
4279+ nl_dump_check_consistent(cb, nlmsg_hdr(skb));
4280+cont:
4281+ idx++;
4282+ }
4283+ }
4284+ }
4285+done:
4286+ rcu_read_unlock();
4287+
4288+ cb->args[0] = idx;
4289+ return skb->len;
4290+}
4291+
4292+static int nf_tables_dump_obj_done(struct netlink_callback *cb)
4293+{
4294+ kfree(cb->data);
4295+
4296+ return 0;
4297+}
4298+
4299+static struct nft_obj_filter *
4300+nft_obj_filter_alloc(const struct nlattr * const nla[])
4301+{
4302+ struct nft_obj_filter *filter;
4303+
4304+ filter = kzalloc(sizeof(*filter), GFP_KERNEL);
4305+ if (!filter)
4306+ return ERR_PTR(-ENOMEM);
4307+
4308+ if (nla[NFTA_OBJ_TABLE])
4309+ nla_strlcpy(filter->table, nla[NFTA_OBJ_TABLE],
4310+ NFT_TABLE_MAXNAMELEN);
4311+ if (nla[NFTA_OBJ_TYPE])
4312+ filter->type = ntohl(nla_get_be32(nla[NFTA_OBJ_TYPE]));
4313+
4314+ return filter;
4315+}
4316+
4317+static int nf_tables_getobj(struct net *net, struct sock *nlsk,
4318+ struct sk_buff *skb, const struct nlmsghdr *nlh,
4319+ const struct nlattr * const nla[])
4320+{
4321+ const struct nfgenmsg *nfmsg = nlmsg_data(nlh);
4322+ u8 genmask = nft_genmask_cur(net);
4323+ int family = nfmsg->nfgen_family;
4324+ const struct nft_af_info *afi;
4325+ const struct nft_table *table;
4326+ struct nft_object *obj;
4327+ struct sk_buff *skb2;
4328+ bool reset = false;
4329+ u32 objtype;
4330+ int err;
4331+
4332+ if (nlh->nlmsg_flags & NLM_F_DUMP) {
4333+ struct netlink_dump_control c = {
4334+ .dump = nf_tables_dump_obj,
4335+ .done = nf_tables_dump_obj_done,
4336+ };
4337+
4338+ if (nla[NFTA_OBJ_TABLE] ||
4339+ nla[NFTA_OBJ_TYPE]) {
4340+ struct nft_obj_filter *filter;
4341+
4342+ filter = nft_obj_filter_alloc(nla);
4343+ if (IS_ERR(filter))
4344+ return -ENOMEM;
4345+
4346+ c.data = filter;
4347+ }
4348+ return netlink_dump_start(nlsk, skb, nlh, &c);
4349+ }
4350+
4351+ if (!nla[NFTA_OBJ_NAME] ||
4352+ !nla[NFTA_OBJ_TYPE])
4353+ return -EINVAL;
4354+
4355+ afi = nf_tables_afinfo_lookup(net, family, false);
4356+ if (IS_ERR(afi))
4357+ return PTR_ERR(afi);
4358+
4359+ table = nf_tables_table_lookup(afi, nla[NFTA_OBJ_TABLE], genmask);
4360+ if (IS_ERR(table))
4361+ return PTR_ERR(table);
4362+
4363+ objtype = ntohl(nla_get_be32(nla[NFTA_OBJ_TYPE]));
4364+ obj = nf_tables_obj_lookup(table, nla[NFTA_OBJ_NAME], objtype, genmask);
4365+ if (IS_ERR(obj))
4366+ return PTR_ERR(obj);
4367+
4368+ skb2 = alloc_skb(NLMSG_GOODSIZE, GFP_KERNEL);
4369+ if (!skb2)
4370+ return -ENOMEM;
4371+
4372+ if (NFNL_MSG_TYPE(nlh->nlmsg_type) == NFT_MSG_GETOBJ_RESET)
4373+ reset = true;
4374+
4375+ err = nf_tables_fill_obj_info(skb2, net, NETLINK_CB(skb).portid,
4376+ nlh->nlmsg_seq, NFT_MSG_NEWOBJ, 0,
4377+ family, table, obj, reset);
4378+ if (err < 0)
4379+ goto err;
4380+
4381+ return nlmsg_unicast(nlsk, skb2, NETLINK_CB(skb).portid);
4382+err:
4383+ kfree_skb(skb2);
4384+ return err;
4385+
4386+ return 0;
4387+}
4388+
4389+static void nft_obj_destroy(struct nft_object *obj)
4390+{
4391+ if (obj->type->destroy)
4392+ obj->type->destroy(obj);
4393+
4394+ module_put(obj->type->owner);
4395+ kfree(obj);
4396+}
4397+
4398+static int nf_tables_delobj(struct net *net, struct sock *nlsk,
4399+ struct sk_buff *skb, const struct nlmsghdr *nlh,
4400+ const struct nlattr * const nla[])
4401+{
4402+ const struct nfgenmsg *nfmsg = nlmsg_data(nlh);
4403+ u8 genmask = nft_genmask_next(net);
4404+ int family = nfmsg->nfgen_family;
4405+ struct nft_af_info *afi;
4406+ struct nft_table *table;
4407+ struct nft_object *obj;
4408+ struct nft_ctx ctx;
4409+ u32 objtype;
4410+
4411+ if (!nla[NFTA_OBJ_TYPE] ||
4412+ !nla[NFTA_OBJ_NAME])
4413+ return -EINVAL;
4414+
4415+ afi = nf_tables_afinfo_lookup(net, family, true);
4416+ if (IS_ERR(afi))
4417+ return PTR_ERR(afi);
4418+
4419+ table = nf_tables_table_lookup(afi, nla[NFTA_OBJ_TABLE], genmask);
4420+ if (IS_ERR(table))
4421+ return PTR_ERR(table);
4422+
4423+ objtype = ntohl(nla_get_be32(nla[NFTA_OBJ_TYPE]));
4424+ obj = nf_tables_obj_lookup(table, nla[NFTA_OBJ_NAME], objtype, genmask);
4425+ if (IS_ERR(obj))
4426+ return PTR_ERR(obj);
4427+ if (obj->use > 0)
4428+ return -EBUSY;
4429+
4430+ nft_ctx_init(&ctx, net, skb, nlh, afi, table, NULL, nla);
4431+
4432+ return nft_delobj(&ctx, obj);
4433+}
4434+
4435+int nft_obj_notify(struct net *net, struct nft_table *table,
4436+ struct nft_object *obj, u32 portid, u32 seq, int event,
4437+ int family, int report, gfp_t gfp)
4438+{
4439+ struct sk_buff *skb;
4440+ int err;
4441+
4442+ if (!report &&
4443+ !nfnetlink_has_listeners(net, NFNLGRP_NFTABLES))
4444+ return 0;
4445+
4446+ err = -ENOBUFS;
4447+ skb = nlmsg_new(NLMSG_GOODSIZE, gfp);
4448+ if (skb == NULL)
4449+ goto err;
4450+
4451+ err = nf_tables_fill_obj_info(skb, net, portid, seq, event, 0, family,
4452+ table, obj, false);
4453+ if (err < 0) {
4454+ kfree_skb(skb);
4455+ goto err;
4456+ }
4457+
4458+ err = nfnetlink_send(skb, net, portid, NFNLGRP_NFTABLES, report, gfp);
4459+err:
4460+ if (err < 0) {
4461+ nfnetlink_set_err(net, portid, NFNLGRP_NFTABLES, err);
4462+ }
4463+ return err;
4464+}
4465+EXPORT_SYMBOL_GPL(nft_obj_notify);
4466+
4467+static int nf_tables_obj_notify(const struct nft_ctx *ctx,
4468+ struct nft_object *obj, int event)
4469+{
4470+ return nft_obj_notify(ctx->net, ctx->table, obj, ctx->portid,
4471+ ctx->seq, event, ctx->afi->family, ctx->report,
4472+ GFP_KERNEL);
4473+}
4474+
38414475 static int nf_tables_fill_gen_info(struct sk_buff *skb, struct net *net,
38424476 u32 portid, u32 seq)
38434477 {
@@ -3998,6 +4632,26 @@ static const struct nfnl_callback nf_tables_cb[NFT_MSG_MAX] = { · 154 unmodified lines
39984632 [NFT_MSG_GETGEN] = {
39994633 .call = nf_tables_getgen,
40004634 },
4635+ [NFT_MSG_NEWOBJ] = {
4636+ .call_batch = nf_tables_newobj,
4637+ .attr_count = NFTA_OBJ_MAX,
4638+ .policy = nft_obj_policy,
4639+ },
4640+ [NFT_MSG_GETOBJ] = {
4641+ .call = nf_tables_getobj,
4642+ .attr_count = NFTA_OBJ_MAX,
4643+ .policy = nft_obj_policy,
4644+ },
4645+ [NFT_MSG_DELOBJ] = {
4646+ .call_batch = nf_tables_delobj,
4647+ .attr_count = NFTA_OBJ_MAX,
4648+ .policy = nft_obj_policy,
4649+ },
4650+ [NFT_MSG_GETOBJ_RESET] = {
4651+ .call = nf_tables_getobj,
4652+ .attr_count = NFTA_OBJ_MAX,
4653+ .policy = nft_obj_policy,
4654+ },
40014655 };
40024656
40034657 static void nft_chain_commit_update(struct nft_trans *trans)
@@ -4040,6 +4694,9 @@ static void nf_tables_commit_release(struct nft_trans *trans) · 36 unmodified lines
40404694 nft_set_elem_destroy(nft_trans_elem_set(trans),
40414695 nft_trans_elem(trans).priv, true);
40424696 break;
4697+ case NFT_MSG_DELOBJ:
4698+ nft_obj_destroy(nft_trans_obj(trans));
4699+ break;
40434700 }
40444701 kfree(trans);
40454702 }
@@ -4147,6 +4804,17 @@ static int nf_tables_commit(struct net *net, struct sk_buff *skb) · 101 unmodified lines
41474804 atomic_dec(&te->set->nelems);
41484805 te->set->ndeact--;
41494806 break;
4807+ case NFT_MSG_NEWOBJ:
4808+ nft_clear(net, nft_trans_obj(trans));
4809+ nf_tables_obj_notify(&trans->ctx, nft_trans_obj(trans),
4810+ NFT_MSG_NEWOBJ);
4811+ nft_trans_destroy(trans);
4812+ break;
4813+ case NFT_MSG_DELOBJ:
4814+ list_del_rcu(&nft_trans_obj(trans)->list);
4815+ nf_tables_obj_notify(&trans->ctx, nft_trans_obj(trans),
4816+ NFT_MSG_DELOBJ);
4817+ break;
41504818 }
41514819 }
41524820
@@ -4181,6 +4849,9 @@ static void nf_tables_abort_release(struct nft_trans *trans) · 28 unmodified lines
41814849 nft_set_elem_destroy(nft_trans_elem_set(trans),
41824850 nft_trans_elem(trans).priv, true);
41834851 break;
4852+ case NFT_MSG_NEWOBJ:
4853+ nft_obj_destroy(nft_trans_obj(trans));
4854+ break;
41844855 }
41854856 kfree(trans);
41864857 }
@@ -4259,6 +4930,15 @@ static int nf_tables_abort(struct net *net, struct sk_buff *skb) · 72 unmodified lines
42594930 te->set->ops->activate(net, te->set, &te->elem);
42604931 te->set->ndeact--;
42614932
4933+ nft_trans_destroy(trans);
4934+ break;
4935+ case NFT_MSG_NEWOBJ:
4936+ trans->ctx.table->use--;
4937+ list_del_rcu(&nft_trans_obj(trans)->list);
4938+ break;
4939+ case NFT_MSG_DELOBJ:
4940+ trans->ctx.table->use++;
4941+ nft_clear(trans->ctx.net, nft_trans_obj(trans));
42624942 nft_trans_destroy(trans);
42634943 break;
42644944 }
@@ -4807,6 +5487,7 @@ static void __nft_release_afinfo(struct net *net, struct nft_af_info *afi) · 542 unmodified lines
48075487 {
48085488 struct nft_table *table, *nt;
48095489 struct nft_chain *chain, *nc;
5490+ struct nft_object *obj, *ne;
48105491 struct nft_rule *rule, *nr;
48115492 struct nft_set *set, *ns;
48125493 struct nft_ctx ctx = {
@@ -4833,6 +5514,11 @@ static void __nft_release_afinfo(struct net *net, struct nft_af_info *afi) · 20 unmodified lines
48335514 table->use--;
48345515 nft_set_destroy(set);
48355516 }
5517+ list_for_each_entry_safe(obj, ne, &table->objects, list) {
5518+ list_del(&obj->list);
5519+ table->use--;
5520+ nft_obj_destroy(obj);
5521+ }
48365522 list_for_each_entry_safe(chain, nc, &table->chains, list) {
48375523 list_del(&chain->list);
48385524 table->use--;
net/netfilter/nfnetlink_log.c+1−0
@@ -1152,6 +1152,7 @@ MODULE_ALIAS_NF_LOGGER(AF_INET, 1); · 1151 unmodified lines
11521152 MODULE_ALIAS_NF_LOGGER(AF_INET6, 1);
11531153 MODULE_ALIAS_NF_LOGGER(AF_BRIDGE, 1);
11541154 MODULE_ALIAS_NF_LOGGER(3, 1); /* NFPROTO_ARP */
1155+MODULE_ALIAS_NF_LOGGER(5, 1); /* NFPROTO_NETDEV */
11551156
11561157 module_init(nfnetlink_log_init);
11571158 module_exit(nfnetlink_log_fini);
net/netfilter/nft_counter.c+156−30
@@ -31,11 +31,10 @@ struct nft_counter_percpu_priv { · 30 unmodified lines
3131 struct nft_counter_percpu __percpu *counter;
3232 };
3333
34−static void nft_counter_eval(const struct nft_expr *expr,
35− struct nft_regs *regs,
36− const struct nft_pktinfo *pkt)
34+static inline void nft_counter_do_eval(struct nft_counter_percpu_priv *priv,
35+ struct nft_regs *regs,
36+ const struct nft_pktinfo *pkt)
3737 {
38− struct nft_counter_percpu_priv *priv = nft_expr_priv(expr);
3938 struct nft_counter_percpu *this_cpu;
4039
4140 local_bh_disable();
@@ -47,10 +46,64 @@ static void nft_counter_eval(const struct nft_expr *expr, · 5 unmodified lines
4746 local_bh_enable();
4847 }
4948
50−static void nft_counter_fetch(const struct nft_counter_percpu __percpu *counter,
49+static inline void nft_counter_obj_eval(struct nft_object *obj,
50+ struct nft_regs *regs,
51+ const struct nft_pktinfo *pkt)
52+{
53+ struct nft_counter_percpu_priv *priv = nft_obj_data(obj);
54+
55+ nft_counter_do_eval(priv, regs, pkt);
56+}
57+
58+static int nft_counter_do_init(const struct nlattr * const tb[],
59+ struct nft_counter_percpu_priv *priv)
60+{
61+ struct nft_counter_percpu __percpu *cpu_stats;
62+ struct nft_counter_percpu *this_cpu;
63+
64+ cpu_stats = netdev_alloc_pcpu_stats(struct nft_counter_percpu);
65+ if (cpu_stats == NULL)
66+ return -ENOMEM;
67+
68+ preempt_disable();
69+ this_cpu = this_cpu_ptr(cpu_stats);
70+ if (tb[NFTA_COUNTER_PACKETS]) {
71+ this_cpu->counter.packets =
72+ be64_to_cpu(nla_get_be64(tb[NFTA_COUNTER_PACKETS]));
73+ }
74+ if (tb[NFTA_COUNTER_BYTES]) {
75+ this_cpu->counter.bytes =
76+ be64_to_cpu(nla_get_be64(tb[NFTA_COUNTER_BYTES]));
77+ }
78+ preempt_enable();
79+ priv->counter = cpu_stats;
80+ return 0;
81+}
82+
83+static int nft_counter_obj_init(const struct nlattr * const tb[],
84+ struct nft_object *obj)
85+{
86+ struct nft_counter_percpu_priv *priv = nft_obj_data(obj);
87+
88+ return nft_counter_do_init(tb, priv);
89+}
90+
91+static void nft_counter_do_destroy(struct nft_counter_percpu_priv *priv)
92+{
93+ free_percpu(priv->counter);
94+}
95+
96+static void nft_counter_obj_destroy(struct nft_object *obj)
97+{
98+ struct nft_counter_percpu_priv *priv = nft_obj_data(obj);
99+
100+ nft_counter_do_destroy(priv);
101+}
102+
103+static void nft_counter_fetch(struct nft_counter_percpu __percpu *counter,
51104 struct nft_counter *total)
52105 {
53− const struct nft_counter_percpu *cpu_stats;
106+ struct nft_counter_percpu *cpu_stats;
54107 u64 bytes, packets;
55108 unsigned int seq;
56109 int cpu;
@@ -69,12 +122,52 @@ static void nft_counter_fetch(const struct nft_counter_percpu __percpu *counter, · 12 unmodified lines
69122 }
70123 }
71124
72−static int nft_counter_dump(struct sk_buff *skb, const struct nft_expr *expr)
125+static u64 __nft_counter_reset(u64 *counter)
126+{
127+ u64 ret, old;
128+
129+ do {
130+ old = *counter;
131+ ret = cmpxchg64(counter, old, 0);
132+ } while (ret != old);
133+
134+ return ret;
135+}
136+
137+static void nft_counter_reset(struct nft_counter_percpu __percpu *counter,
138+ struct nft_counter *total)
139+{
140+ struct nft_counter_percpu *cpu_stats;
141+ u64 bytes, packets;
142+ unsigned int seq;
143+ int cpu;
144+
145+ memset(total, 0, sizeof(*total));
146+ for_each_possible_cpu(cpu) {
147+ bytes = packets = 0;
148+
149+ cpu_stats = per_cpu_ptr(counter, cpu);
150+ do {
151+ seq = u64_stats_fetch_begin_irq(&cpu_stats->syncp);
152+ packets += __nft_counter_reset(&cpu_stats->counter.packets);
153+ bytes += __nft_counter_reset(&cpu_stats->counter.bytes);
154+ } while (u64_stats_fetch_retry_irq(&cpu_stats->syncp, seq));
155+
156+ total->packets += packets;
157+ total->bytes += bytes;
158+ }
159+}
160+
161+static int nft_counter_do_dump(struct sk_buff *skb,
162+ const struct nft_counter_percpu_priv *priv,
163+ bool reset)
73164 {
74− struct nft_counter_percpu_priv *priv = nft_expr_priv(expr);
75165 struct nft_counter total;
76166
77− nft_counter_fetch(priv->counter, &total);
167+ if (reset)
168+ nft_counter_reset(priv->counter, &total);
169+ else
170+ nft_counter_fetch(priv->counter, &total);
78171
79172 if (nla_put_be64(skb, NFTA_COUNTER_BYTES, cpu_to_be64(total.bytes),
80173 NFTA_COUNTER_PAD) ||
@@ -87,36 +180,54 @@ nla_put_failure: · 6 unmodified lines
87180 return -1;
88181 }
89182
183+static int nft_counter_obj_dump(struct sk_buff *skb,
184+ struct nft_object *obj, bool reset)
185+{
186+ struct nft_counter_percpu_priv *priv = nft_obj_data(obj);
187+
188+ return nft_counter_do_dump(skb, priv, reset);
189+}
190+
90191 static const struct nla_policy nft_counter_policy[NFTA_COUNTER_MAX + 1] = {
91192 [NFTA_COUNTER_PACKETS] = { .type = NLA_U64 },
92193 [NFTA_COUNTER_BYTES] = { .type = NLA_U64 },
93194 };
94195
196+static struct nft_object_type nft_counter_obj __read_mostly = {
197+ .type = NFT_OBJECT_COUNTER,
198+ .size = sizeof(struct nft_counter_percpu_priv),
199+ .maxattr = NFTA_COUNTER_MAX,
200+ .policy = nft_counter_policy,
201+ .eval = nft_counter_obj_eval,
202+ .init = nft_counter_obj_init,
203+ .destroy = nft_counter_obj_destroy,
204+ .dump = nft_counter_obj_dump,
205+ .owner = THIS_MODULE,
206+};
207+
208+static void nft_counter_eval(const struct nft_expr *expr,
209+ struct nft_regs *regs,
210+ const struct nft_pktinfo *pkt)
211+{
212+ struct nft_counter_percpu_priv *priv = nft_expr_priv(expr);
213+
214+ nft_counter_do_eval(priv, regs, pkt);
215+}
216+
217+static int nft_counter_dump(struct sk_buff *skb, const struct nft_expr *expr)
218+{
219+ const struct nft_counter_percpu_priv *priv = nft_expr_priv(expr);
220+
221+ return nft_counter_do_dump(skb, priv, false);
222+}
223+
95224 static int nft_counter_init(const struct nft_ctx *ctx,
96225 const struct nft_expr *expr,
97226 const struct nlattr * const tb[])
98227 {
99228 struct nft_counter_percpu_priv *priv = nft_expr_priv(expr);
100− struct nft_counter_percpu __percpu *cpu_stats;
101− struct nft_counter_percpu *this_cpu;
102229
103− cpu_stats = netdev_alloc_pcpu_stats(struct nft_counter_percpu);
104− if (cpu_stats == NULL)
105− return -ENOMEM;
106−
107− preempt_disable();
108− this_cpu = this_cpu_ptr(cpu_stats);
109− if (tb[NFTA_COUNTER_PACKETS]) {
110− this_cpu->counter.packets =
111− be64_to_cpu(nla_get_be64(tb[NFTA_COUNTER_PACKETS]));
112− }
113− if (tb[NFTA_COUNTER_BYTES]) {
114− this_cpu->counter.bytes =
115− be64_to_cpu(nla_get_be64(tb[NFTA_COUNTER_BYTES]));
116− }
117− preempt_enable();
118− priv->counter = cpu_stats;
119− return 0;
230+ return nft_counter_do_init(tb, priv);
120231 }
121232
122233 static void nft_counter_destroy(const struct nft_ctx *ctx,
@@ -124,7 +235,7 @@ static void nft_counter_destroy(const struct nft_ctx *ctx, · 1 unmodified line
124235 {
125236 struct nft_counter_percpu_priv *priv = nft_expr_priv(expr);
126237
127− free_percpu(priv->counter);
238+ nft_counter_do_destroy(priv);
128239 }
129240
130241 static int nft_counter_clone(struct nft_expr *dst, const struct nft_expr *src)
@@ -174,12 +285,26 @@ static struct nft_expr_type nft_counter_type __read_mostly = { · 43 unmodified lines
174285
175286 static int __init nft_counter_module_init(void)
176287 {
177− return nft_register_expr(&nft_counter_type);
288+ int err;
289+
290+ err = nft_register_obj(&nft_counter_obj);
291+ if (err < 0)
292+ return err;
293+
294+ err = nft_register_expr(&nft_counter_type);
295+ if (err < 0)
296+ goto err1;
297+
298+ return 0;
299+err1:
300+ nft_unregister_obj(&nft_counter_obj);
301+ return err;
178302 }
179303
180304 static void __exit nft_counter_module_exit(void)
181305 {
182306 nft_unregister_expr(&nft_counter_type);
307+ nft_unregister_obj(&nft_counter_obj);
183308 }
184309
185310 module_init(nft_counter_module_init);
@@ -188,3 +313,4 @@ module_exit(nft_counter_module_exit); · 2 unmodified lines
188313 MODULE_LICENSE("GPL");
189314 MODULE_AUTHOR("Patrick McHardy <kaber@trash.net>");
190315 MODULE_ALIAS_NFT_EXPR("counter");
316+MODULE_ALIAS_NFT_OBJ(NFT_OBJECT_COUNTER);
net/netfilter/nft_ct.c+13−13
@@ -208,37 +208,37 @@ static const struct nla_policy nft_ct_policy[NFTA_CT_MAX + 1] = { · 207 unmodified lines
208208 [NFTA_CT_SREG] = { .type = NLA_U32 },
209209 };
210210
211−static int nft_ct_l3proto_try_module_get(uint8_t family)
211+static int nft_ct_netns_get(struct net *net, uint8_t family)
212212 {
213213 int err;
214214
215215 if (family == NFPROTO_INET) {
216− err = nf_ct_l3proto_try_module_get(NFPROTO_IPV4);
216+ err = nf_ct_netns_get(net, NFPROTO_IPV4);
217217 if (err < 0)
218218 goto err1;
219− err = nf_ct_l3proto_try_module_get(NFPROTO_IPV6);
219+ err = nf_ct_netns_get(net, NFPROTO_IPV6);
220220 if (err < 0)
221221 goto err2;
222222 } else {
223− err = nf_ct_l3proto_try_module_get(family);
223+ err = nf_ct_netns_get(net, family);
224224 if (err < 0)
225225 goto err1;
226226 }
227227 return 0;
228228
229229 err2:
230− nf_ct_l3proto_module_put(NFPROTO_IPV4);
230+ nf_ct_netns_put(net, NFPROTO_IPV4);
231231 err1:
232232 return err;
233233 }
234234
235−static void nft_ct_l3proto_module_put(uint8_t family)
235+static void nft_ct_netns_put(struct net *net, uint8_t family)
236236 {
237237 if (family == NFPROTO_INET) {
238− nf_ct_l3proto_module_put(NFPROTO_IPV4);
239− nf_ct_l3proto_module_put(NFPROTO_IPV6);
238+ nf_ct_netns_put(net, NFPROTO_IPV4);
239+ nf_ct_netns_put(net, NFPROTO_IPV6);
240240 } else
241− nf_ct_l3proto_module_put(family);
241+ nf_ct_netns_put(net, family);
242242 }
243243
244244 static int nft_ct_get_init(const struct nft_ctx *ctx,
@@ -342,7 +342,7 @@ static int nft_ct_get_init(const struct nft_ctx *ctx, · 97 unmodified lines
342342 if (err < 0)
343343 return err;
344344
345− err = nft_ct_l3proto_try_module_get(ctx->afi->family);
345+ err = nft_ct_netns_get(ctx->net, ctx->afi->family);
346346 if (err < 0)
347347 return err;
348348
@@ -390,7 +390,7 @@ static int nft_ct_set_init(const struct nft_ctx *ctx, · 41 unmodified lines
390390 if (err < 0)
391391 goto err1;
392392
393− err = nft_ct_l3proto_try_module_get(ctx->afi->family);
393+ err = nft_ct_netns_get(ctx->net, ctx->afi->family);
394394 if (err < 0)
395395 goto err1;
396396
@@ -405,7 +405,7 @@ err1: · 8 unmodified lines
405405 static void nft_ct_get_destroy(const struct nft_ctx *ctx,
406406 const struct nft_expr *expr)
407407 {
408− nft_ct_l3proto_module_put(ctx->afi->family);
408+ nf_ct_netns_put(ctx->net, ctx->afi->family);
409409 }
410410
411411 static void nft_ct_set_destroy(const struct nft_ctx *ctx,
@@ -423,7 +423,7 @@ static void nft_ct_set_destroy(const struct nft_ctx *ctx, · 11 unmodified lines
423423 break;
424424 }
425425
426− nft_ct_l3proto_module_put(ctx->afi->family);
426+ nft_ct_netns_put(ctx->net, ctx->afi->family);
427427 }
428428
429429 static int nft_ct_get_dump(struct sk_buff *skb, const struct nft_expr *expr)
net/netfilter/nft_fib.c+1−1
@@ -86,7 +86,7 @@ int nft_fib_init(const struct nft_ctx *ctx, const struct nft_expr *expr, · 85 unmodified lines
8686 if ((priv->flags & (NFTA_FIB_F_SADDR | NFTA_FIB_F_DADDR)) == 0)
8787 return -EINVAL;
8888
89− priv->result = htonl(nla_get_be32(tb[NFTA_FIB_RESULT]));
89+ priv->result = ntohl(nla_get_be32(tb[NFTA_FIB_RESULT]));
9090 priv->dreg = nft_parse_register(tb[NFTA_FIB_DREG]);
9191
9292 switch (priv->result) {
net/netfilter/nft_fwd_netdev.c+2−2
@@ -26,8 +26,8 @@ static void nft_fwd_netdev_eval(const struct nft_expr *expr, · 25 unmodified lines
2626 struct nft_fwd_netdev *priv = nft_expr_priv(expr);
2727 int oif = regs->data[priv->sreg_dev];
2828
29− nf_dup_netdev_egress(pkt, oif);
30− regs->verdict.code = NF_DROP;
29+ nf_fwd_netdev_egress(pkt, oif);
30+ regs->verdict.code = NF_STOLEN;
3131 }
3232
3333 static const struct nla_policy nft_fwd_netdev_policy[NFTA_FWD_MAX + 1] = {
net/netfilter/nft_masq.c+3−3
@@ -1,5 +1,5 @@
11 /*
2− * Copyright (c) 2014 Arturo Borrero Gonzalez <arturo.borrero.glez@gmail.com>
2+ * Copyright (c) 2014 Arturo Borrero Gonzalez <arturo@debian.org>
33 *
44 * This program is free software; you can redistribute it and/or modify
55 * it under the terms of the GNU General Public License version 2 as
@@ -77,7 +77,7 @@ int nft_masq_init(const struct nft_ctx *ctx, · 71 unmodified lines
7777 }
7878 }
7979
80− return 0;
80+ return nf_ct_netns_get(ctx->net, ctx->afi->family);
8181 }
8282 EXPORT_SYMBOL_GPL(nft_masq_init);
8383
@@ -105,4 +105,4 @@ nla_put_failure: · 21 unmodified lines
105105 EXPORT_SYMBOL_GPL(nft_masq_dump);
106106
107107 MODULE_LICENSE("GPL");
108−MODULE_AUTHOR("Arturo Borrero Gonzalez <arturo.borrero.glez@gmail.com>");
108+MODULE_AUTHOR("Arturo Borrero Gonzalez <arturo@debian.org>");
net/netfilter/nft_nat.c+10−1
@@ -209,7 +209,7 @@ static int nft_nat_init(const struct nft_ctx *ctx, const struct nft_expr *expr, · 208 unmodified lines
209209 return -EINVAL;
210210 }
211211
212− return 0;
212+ return nf_ct_netns_get(ctx->net, family);
213213 }
214214
215215 static int nft_nat_dump(struct sk_buff *skb, const struct nft_expr *expr)
@@ -257,12 +257,21 @@ nla_put_failure: · 41 unmodified lines
257257 return -1;
258258 }
259259
260+static void
261+nft_nat_destroy(const struct nft_ctx *ctx, const struct nft_expr *expr)
262+{
263+ const struct nft_nat *priv = nft_expr_priv(expr);
264+
265+ nf_ct_netns_put(ctx->net, priv->family);
266+}
267+
260268 static struct nft_expr_type nft_nat_type;
261269 static const struct nft_expr_ops nft_nat_ops = {
262270 .type = &nft_nat_type,
263271 .size = NFT_EXPR_SIZE(sizeof(struct nft_nat)),
264272 .eval = nft_nat_eval,
265273 .init = nft_nat_init,
274+ .destroy = nft_nat_destroy,
266275 .dump = nft_nat_dump,
267276 .validate = nft_nat_validate,
268277 };
net/netfilter/nft_objref.c+226−0
@@ -0,0 +1,226 @@
1+/*
2+ * Copyright (c) 2012-2016 Pablo Neira Ayuso <pablo@netfilter.org>
3+ *
4+ * This program is free software; you can redistribute it and/or modify it
5+ * under the terms and conditions of the GNU General Public License,
6+ * version 2, as published by the Free Software Foundation.
7+ */
8+
9+#include <linux/init.h>
10+#include <linux/module.h>
11+#include <linux/skbuff.h>
12+#include <linux/netlink.h>
13+#include <linux/netfilter.h>
14+#include <linux/netfilter/nf_tables.h>
15+#include <net/netfilter/nf_tables.h>
16+
17+#define nft_objref_priv(expr) *((struct nft_object **)nft_expr_priv(expr))
18+
19+static void nft_objref_eval(const struct nft_expr *expr,
20+ struct nft_regs *regs,
21+ const struct nft_pktinfo *pkt)
22+{
23+ struct nft_object *obj = nft_objref_priv(expr);
24+
25+ obj->type->eval(obj, regs, pkt);
26+}
27+
28+static int nft_objref_init(const struct nft_ctx *ctx,
29+ const struct nft_expr *expr,
30+ const struct nlattr * const tb[])
31+{
32+ struct nft_object *obj = nft_objref_priv(expr);
33+ u8 genmask = nft_genmask_next(ctx->net);
34+ u32 objtype;
35+
36+ if (!tb[NFTA_OBJREF_IMM_NAME] ||
37+ !tb[NFTA_OBJREF_IMM_TYPE])
38+ return -EINVAL;
39+
40+ objtype = ntohl(nla_get_be32(tb[NFTA_OBJREF_IMM_TYPE]));
41+ obj = nf_tables_obj_lookup(ctx->table, tb[NFTA_OBJREF_IMM_NAME], objtype,
42+ genmask);
43+ if (IS_ERR(obj))
44+ return -ENOENT;
45+
46+ nft_objref_priv(expr) = obj;
47+ obj->use++;
48+
49+ return 0;
50+}
51+
52+static int nft_objref_dump(struct sk_buff *skb, const struct nft_expr *expr)
53+{
54+ const struct nft_object *obj = nft_objref_priv(expr);
55+
56+ if (nla_put_string(skb, NFTA_OBJREF_IMM_NAME, obj->name) ||
57+ nla_put_be32(skb, NFTA_OBJREF_IMM_TYPE, htonl(obj->type->type)))
58+ goto nla_put_failure;
59+
60+ return 0;
61+
62+nla_put_failure:
63+ return -1;
64+}
65+
66+static void nft_objref_destroy(const struct nft_ctx *ctx,
67+ const struct nft_expr *expr)
68+{
69+ struct nft_object *obj = nft_objref_priv(expr);
70+
71+ obj->use--;
72+}
73+
74+static struct nft_expr_type nft_objref_type;
75+static const struct nft_expr_ops nft_objref_ops = {
76+ .type = &nft_objref_type,
77+ .size = NFT_EXPR_SIZE(sizeof(struct nft_object *)),
78+ .eval = nft_objref_eval,
79+ .init = nft_objref_init,
80+ .destroy = nft_objref_destroy,
81+ .dump = nft_objref_dump,
82+};
83+
84+struct nft_objref_map {
85+ struct nft_set *set;
86+ enum nft_registers sreg:8;
87+ struct nft_set_binding binding;
88+};
89+
90+static void nft_objref_map_eval(const struct nft_expr *expr,
91+ struct nft_regs *regs,
92+ const struct nft_pktinfo *pkt)
93+{
94+ struct nft_objref_map *priv = nft_expr_priv(expr);
95+ const struct nft_set *set = priv->set;
96+ const struct nft_set_ext *ext;
97+ struct nft_object *obj;
98+ bool found;
99+
100+ found = set->ops->lookup(nft_net(pkt), set, &regs->data[priv->sreg],
101+ &ext);
102+ if (!found) {
103+ regs->verdict.code = NFT_BREAK;
104+ return;
105+ }
106+ obj = *nft_set_ext_obj(ext);
107+ obj->type->eval(obj, regs, pkt);
108+}
109+
110+static int nft_objref_map_init(const struct nft_ctx *ctx,
111+ const struct nft_expr *expr,
112+ const struct nlattr * const tb[])
113+{
114+ struct nft_objref_map *priv = nft_expr_priv(expr);
115+ u8 genmask = nft_genmask_next(ctx->net);
116+ struct nft_set *set;
117+ int err;
118+
119+ set = nf_tables_set_lookup(ctx->table, tb[NFTA_OBJREF_SET_NAME], genmask);
120+ if (IS_ERR(set)) {
121+ if (tb[NFTA_OBJREF_SET_ID]) {
122+ set = nf_tables_set_lookup_byid(ctx->net,
123+ tb[NFTA_OBJREF_SET_ID],
124+ genmask);
125+ }
126+ if (IS_ERR(set))
127+ return PTR_ERR(set);
128+ }
129+
130+ if (!(set->flags & NFT_SET_OBJECT))
131+ return -EINVAL;
132+
133+ priv->sreg = nft_parse_register(tb[NFTA_OBJREF_SET_SREG]);
134+ err = nft_validate_register_load(priv->sreg, set->klen);
135+ if (err < 0)
136+ return err;
137+
138+ priv->binding.flags = set->flags & NFT_SET_OBJECT;
139+
140+ err = nf_tables_bind_set(ctx, set, &priv->binding);
141+ if (err < 0)
142+ return err;
143+
144+ priv->set = set;
145+ return 0;
146+}
147+
148+static int nft_objref_map_dump(struct sk_buff *skb, const struct nft_expr *expr)
149+{
150+ const struct nft_objref_map *priv = nft_expr_priv(expr);
151+
152+ if (nft_dump_register(skb, NFTA_OBJREF_SET_SREG, priv->sreg) ||
153+ nla_put_string(skb, NFTA_OBJREF_SET_NAME, priv->set->name))
154+ goto nla_put_failure;
155+
156+ return 0;
157+
158+nla_put_failure:
159+ return -1;
160+}
161+
162+static void nft_objref_map_destroy(const struct nft_ctx *ctx,
163+ const struct nft_expr *expr)
164+{
165+ struct nft_objref_map *priv = nft_expr_priv(expr);
166+
167+ nf_tables_unbind_set(ctx, priv->set, &priv->binding);
168+}
169+
170+static struct nft_expr_type nft_objref_type;
171+static const struct nft_expr_ops nft_objref_map_ops = {
172+ .type = &nft_objref_type,
173+ .size = NFT_EXPR_SIZE(sizeof(struct nft_objref_map)),
174+ .eval = nft_objref_map_eval,
175+ .init = nft_objref_map_init,
176+ .destroy = nft_objref_map_destroy,
177+ .dump = nft_objref_map_dump,
178+};
179+
180+static const struct nft_expr_ops *
181+nft_objref_select_ops(const struct nft_ctx *ctx,
182+ const struct nlattr * const tb[])
183+{
184+ if (tb[NFTA_OBJREF_SET_SREG] &&
185+ (tb[NFTA_OBJREF_SET_NAME] ||
186+ tb[NFTA_OBJREF_SET_ID]))
187+ return &nft_objref_map_ops;
188+ else if (tb[NFTA_OBJREF_IMM_NAME] &&
189+ tb[NFTA_OBJREF_IMM_TYPE])
190+ return &nft_objref_ops;
191+
192+ return ERR_PTR(-EOPNOTSUPP);
193+}
194+
195+static const struct nla_policy nft_objref_policy[NFTA_OBJREF_MAX + 1] = {
196+ [NFTA_OBJREF_IMM_NAME] = { .type = NLA_STRING },
197+ [NFTA_OBJREF_IMM_TYPE] = { .type = NLA_U32 },
198+ [NFTA_OBJREF_SET_SREG] = { .type = NLA_U32 },
199+ [NFTA_OBJREF_SET_NAME] = { .type = NLA_STRING },
200+ [NFTA_OBJREF_SET_ID] = { .type = NLA_U32 },
201+};
202+
203+static struct nft_expr_type nft_objref_type __read_mostly = {
204+ .name = "objref",
205+ .select_ops = nft_objref_select_ops,
206+ .policy = nft_objref_policy,
207+ .maxattr = NFTA_OBJREF_MAX,
208+ .owner = THIS_MODULE,
209+};
210+
211+static int __init nft_objref_module_init(void)
212+{
213+ return nft_register_expr(&nft_objref_type);
214+}
215+
216+static void __exit nft_objref_module_exit(void)
217+{
218+ nft_unregister_expr(&nft_objref_type);
219+}
220+
221+module_init(nft_objref_module_init);
222+module_exit(nft_objref_module_exit);
223+
224+MODULE_LICENSE("GPL");
225+MODULE_AUTHOR("Pablo Neira Ayuso <pablo@netfilter.org>");
226+MODULE_ALIAS_NFT_EXPR("objref");
net/netfilter/nft_payload.c+102−5
@@ -1,5 +1,6 @@
11 /*
22 * Copyright (c) 2008-2009 Patrick McHardy <kaber@trash.net>
3+ * Copyright (c) 2016 Pablo Neira Ayuso <pablo@netfilter.org>
34 *
45 * This program is free software; you can redistribute it and/or modify
56 * it under the terms of the GNU General Public License version 2 as
@@ -17,6 +18,10 @@ · 11 unmodified lines
1718 #include <linux/netfilter/nf_tables.h>
1819 #include <net/netfilter/nf_tables_core.h>
1920 #include <net/netfilter/nf_tables.h>
21+/* For layer 4 checksum field offset. */
22+#include <linux/tcp.h>
23+#include <linux/udp.h>
24+#include <linux/icmpv6.h>
2025
2126 /* add vlan header into the user buffer for if tag was removed by offloads */
2227 static bool
@@ -164,6 +169,87 @@ const struct nft_expr_ops nft_payload_fast_ops = { · 141 unmodified lines
164169 .dump = nft_payload_dump,
165170 };
166171
172+static inline void nft_csum_replace(__sum16 *sum, __wsum fsum, __wsum tsum)
173+{
174+ *sum = csum_fold(csum_add(csum_sub(~csum_unfold(*sum), fsum), tsum));
175+ if (*sum == 0)
176+ *sum = CSUM_MANGLED_0;
177+}
178+
179+static bool nft_payload_udp_checksum(struct sk_buff *skb, unsigned int thoff)
180+{
181+ struct udphdr *uh, _uh;
182+
183+ uh = skb_header_pointer(skb, thoff, sizeof(_uh), &_uh);
184+ if (!uh)
185+ return false;
186+
187+ return uh->check;
188+}
189+
190+static int nft_payload_l4csum_offset(const struct nft_pktinfo *pkt,
191+ struct sk_buff *skb,
192+ unsigned int *l4csum_offset)
193+{
194+ switch (pkt->tprot) {
195+ case IPPROTO_TCP:
196+ *l4csum_offset = offsetof(struct tcphdr, check);
197+ break;
198+ case IPPROTO_UDP:
199+ if (!nft_payload_udp_checksum(skb, pkt->xt.thoff))
200+ return -1;
201+ /* Fall through. */
202+ case IPPROTO_UDPLITE:
203+ *l4csum_offset = offsetof(struct udphdr, check);
204+ break;
205+ case IPPROTO_ICMPV6:
206+ *l4csum_offset = offsetof(struct icmp6hdr, icmp6_cksum);
207+ break;
208+ default:
209+ return -1;
210+ }
211+
212+ *l4csum_offset += pkt->xt.thoff;
213+ return 0;
214+}
215+
216+static int nft_payload_l4csum_update(const struct nft_pktinfo *pkt,
217+ struct sk_buff *skb,
218+ __wsum fsum, __wsum tsum)
219+{
220+ int l4csum_offset;
221+ __sum16 sum;
222+
223+ /* If we cannot determine layer 4 checksum offset or this packet doesn't
224+ * require layer 4 checksum recalculation, skip this packet.
225+ */
226+ if (nft_payload_l4csum_offset(pkt, skb, &l4csum_offset) < 0)
227+ return 0;
228+
229+ if (skb_copy_bits(skb, l4csum_offset, &sum, sizeof(sum)) < 0)
230+ return -1;
231+
232+ /* Checksum mangling for an arbitrary amount of bytes, based on
233+ * inet_proto_csum_replace*() functions.
234+ */
235+ if (skb->ip_summed != CHECKSUM_PARTIAL) {
236+ nft_csum_replace(&sum, fsum, tsum);
237+ if (skb->ip_summed == CHECKSUM_COMPLETE) {
238+ skb->csum = ~csum_add(csum_sub(~(skb->csum), fsum),
239+ tsum);
240+ }
241+ } else {
242+ sum = ~csum_fold(csum_add(csum_sub(csum_unfold(sum), fsum),
243+ tsum));
244+ }
245+
246+ if (!skb_make_writable(skb, l4csum_offset + sizeof(sum)) ||
247+ skb_store_bits(skb, l4csum_offset, &sum, sizeof(sum)) < 0)
248+ return -1;
249+
250+ return 0;
251+}
252+
167253 static void nft_payload_set_eval(const struct nft_expr *expr,
168254 struct nft_regs *regs,
169255 const struct nft_pktinfo *pkt)
@@ -204,14 +290,15 @@ static void nft_payload_set_eval(const struct nft_expr *expr, · 34 unmodified lines
204290
205291 fsum = skb_checksum(skb, offset, priv->len, 0);
206292 tsum = csum_partial(src, priv->len, 0);
207− sum = csum_fold(csum_add(csum_sub(~csum_unfold(sum), fsum),
208− tsum));
209− if (sum == 0)
210− sum = CSUM_MANGLED_0;
293+ nft_csum_replace(&sum, fsum, tsum);
211294
212295 if (!skb_make_writable(skb, csum_offset + sizeof(sum)) ||
213296 skb_store_bits(skb, csum_offset, &sum, sizeof(sum)) < 0)
214297 goto err;
298+
299+ if (priv->csum_flags &&
300+ nft_payload_l4csum_update(pkt, skb, fsum, tsum) < 0)
301+ goto err;
215302 }
216303
217304 if (!skb_make_writable(skb, max(offset + priv->len, 0)) ||
@@ -240,6 +327,15 @@ static int nft_payload_set_init(const struct nft_ctx *ctx, · 22 unmodified lines
240327 if (tb[NFTA_PAYLOAD_CSUM_OFFSET])
241328 priv->csum_offset =
242329 ntohl(nla_get_be32(tb[NFTA_PAYLOAD_CSUM_OFFSET]));
330+ if (tb[NFTA_PAYLOAD_CSUM_FLAGS]) {
331+ u32 flags;
332+
333+ flags = ntohl(nla_get_be32(tb[NFTA_PAYLOAD_CSUM_FLAGS]));
334+ if (flags & ~NFT_PAYLOAD_L4CSUM_PSEUDOHDR)
335+ return -EINVAL;
336+
337+ priv->csum_flags = flags;
338+ }
243339
244340 switch (priv->csum_type) {
245341 case NFT_PAYLOAD_CSUM_NONE:
@@ -262,7 +358,8 @@ static int nft_payload_set_dump(struct sk_buff *skb, const struct nft_expr *expr · 16 unmodified lines
262358 nla_put_be32(skb, NFTA_PAYLOAD_LEN, htonl(priv->len)) ||
263359 nla_put_be32(skb, NFTA_PAYLOAD_CSUM_TYPE, htonl(priv->csum_type)) ||
264360 nla_put_be32(skb, NFTA_PAYLOAD_CSUM_OFFSET,
265− htonl(priv->csum_offset)))
361+ htonl(priv->csum_offset)) ||
362+ nla_put_be32(skb, NFTA_PAYLOAD_CSUM_FLAGS, htonl(priv->csum_flags)))
266363 goto nla_put_failure;
267364 return 0;
268365
net/netfilter/nft_quota.c+136−22
@@ -17,38 +17,59 @@ · 16 unmodified lines
1717
1818 struct nft_quota {
1919 u64 quota;
20− bool invert;
21− atomic64_t remain;
20+ unsigned long flags;
21+ atomic64_t consumed;
2222 };
2323
2424 static inline bool nft_overquota(struct nft_quota *priv,
25− const struct nft_pktinfo *pkt)
25+ const struct sk_buff *skb)
2626 {
27− return atomic64_sub_return(pkt->skb->len, &priv->remain) < 0;
27+ return atomic64_add_return(skb->len, &priv->consumed) >= priv->quota;
2828 }
2929
30−static void nft_quota_eval(const struct nft_expr *expr,
31− struct nft_regs *regs,
32− const struct nft_pktinfo *pkt)
30+static inline bool nft_quota_invert(struct nft_quota *priv)
3331 {
34− struct nft_quota *priv = nft_expr_priv(expr);
32+ return priv->flags & NFT_QUOTA_F_INV;
33+}
3534
36− if (nft_overquota(priv, pkt) ^ priv->invert)
35+static inline void nft_quota_do_eval(struct nft_quota *priv,
36+ struct nft_regs *regs,
37+ const struct nft_pktinfo *pkt)
38+{
39+ if (nft_overquota(priv, pkt->skb) ^ nft_quota_invert(priv))
3740 regs->verdict.code = NFT_BREAK;
3841 }
3942
4043 static const struct nla_policy nft_quota_policy[NFTA_QUOTA_MAX + 1] = {
4144 [NFTA_QUOTA_BYTES] = { .type = NLA_U64 },
4245 [NFTA_QUOTA_FLAGS] = { .type = NLA_U32 },
46+ [NFTA_QUOTA_CONSUMED] = { .type = NLA_U64 },
4347 };
4448
45−static int nft_quota_init(const struct nft_ctx *ctx,
46− const struct nft_expr *expr,
47− const struct nlattr * const tb[])
49+#define NFT_QUOTA_DEPLETED_BIT 1 /* From NFT_QUOTA_F_DEPLETED. */
50+
51+static void nft_quota_obj_eval(struct nft_object *obj,
52+ struct nft_regs *regs,
53+ const struct nft_pktinfo *pkt)
4854 {
49− struct nft_quota *priv = nft_expr_priv(expr);
50− u32 flags = 0;
51− u64 quota;
55+ struct nft_quota *priv = nft_obj_data(obj);
56+ bool overquota;
57+
58+ overquota = nft_overquota(priv, pkt->skb);
59+ if (overquota ^ nft_quota_invert(priv))
60+ regs->verdict.code = NFT_BREAK;
61+
62+ if (overquota &&
63+ !test_and_set_bit(NFT_QUOTA_DEPLETED_BIT, &priv->flags))
64+ nft_obj_notify(nft_net(pkt), obj->table, obj, 0, 0,
65+ NFT_MSG_NEWOBJ, nft_pf(pkt), 0, GFP_ATOMIC);
66+}
67+
68+static int nft_quota_do_init(const struct nlattr * const tb[],
69+ struct nft_quota *priv)
70+{
71+ unsigned long flags = 0;
72+ u64 quota, consumed = 0;
5273
5374 if (!tb[NFTA_QUOTA_BYTES])
5475 return -EINVAL;
@@ -57,26 +78,60 @@ static int nft_quota_init(const struct nft_ctx *ctx, · 2 unmodified lines
5778 if (quota > S64_MAX)
5879 return -EOVERFLOW;
5980
81+ if (tb[NFTA_QUOTA_CONSUMED]) {
82+ consumed = be64_to_cpu(nla_get_be64(tb[NFTA_QUOTA_CONSUMED]));
83+ if (consumed > quota)
84+ return -EINVAL;
85+ }
86+
6087 if (tb[NFTA_QUOTA_FLAGS]) {
6188 flags = ntohl(nla_get_be32(tb[NFTA_QUOTA_FLAGS]));
6289 if (flags & ~NFT_QUOTA_F_INV)
6390 return -EINVAL;
91+ if (flags & NFT_QUOTA_F_DEPLETED)
92+ return -EOPNOTSUPP;
6493 }
6594
6695 priv->quota = quota;
67− priv->invert = (flags & NFT_QUOTA_F_INV) ? true : false;
68− atomic64_set(&priv->remain, quota);
96+ priv->flags = flags;
97+ atomic64_set(&priv->consumed, consumed);
6998
7099 return 0;
71100 }
72101
73−static int nft_quota_dump(struct sk_buff *skb, const struct nft_expr *expr)
102+static int nft_quota_obj_init(const struct nlattr * const tb[],
103+ struct nft_object *obj)
104+{
105+ struct nft_quota *priv = nft_obj_data(obj);
106+
107+ return nft_quota_do_init(tb, priv);
108+}
109+
110+static int nft_quota_do_dump(struct sk_buff *skb, struct nft_quota *priv,
111+ bool reset)
74112 {
75− const struct nft_quota *priv = nft_expr_priv(expr);
76− u32 flags = priv->invert ? NFT_QUOTA_F_INV : 0;
113+ u32 flags = priv->flags;
114+ u64 consumed;
115+
116+ if (reset) {
117+ consumed = atomic64_xchg(&priv->consumed, 0);
118+ if (test_and_clear_bit(NFT_QUOTA_DEPLETED_BIT, &priv->flags))
119+ flags |= NFT_QUOTA_F_DEPLETED;
120+ } else {
121+ consumed = atomic64_read(&priv->consumed);
122+ }
123+
124+ /* Since we inconditionally increment consumed quota for each packet
125+ * that we see, don't go over the quota boundary in what we send to
126+ * userspace.
127+ */
128+ if (consumed > priv->quota)
129+ consumed = priv->quota;
77130
78131 if (nla_put_be64(skb, NFTA_QUOTA_BYTES, cpu_to_be64(priv->quota),
79132 NFTA_QUOTA_PAD) ||
133+ nla_put_be64(skb, NFTA_QUOTA_CONSUMED, cpu_to_be64(consumed),
134+ NFTA_QUOTA_PAD) ||
80135 nla_put_be32(skb, NFTA_QUOTA_FLAGS, htonl(flags)))
81136 goto nla_put_failure;
82137 return 0;
@@ -85,6 +140,50 @@ nla_put_failure: · 2 unmodified lines
85140 return -1;
86141 }
87142
143+static int nft_quota_obj_dump(struct sk_buff *skb, struct nft_object *obj,
144+ bool reset)
145+{
146+ struct nft_quota *priv = nft_obj_data(obj);
147+
148+ return nft_quota_do_dump(skb, priv, reset);
149+}
150+
151+static struct nft_object_type nft_quota_obj __read_mostly = {
152+ .type = NFT_OBJECT_QUOTA,
153+ .size = sizeof(struct nft_quota),
154+ .maxattr = NFTA_QUOTA_MAX,
155+ .policy = nft_quota_policy,
156+ .init = nft_quota_obj_init,
157+ .eval = nft_quota_obj_eval,
158+ .dump = nft_quota_obj_dump,
159+ .owner = THIS_MODULE,
160+};
161+
162+static void nft_quota_eval(const struct nft_expr *expr,
163+ struct nft_regs *regs,
164+ const struct nft_pktinfo *pkt)
165+{
166+ struct nft_quota *priv = nft_expr_priv(expr);
167+
168+ nft_quota_do_eval(priv, regs, pkt);
169+}
170+
171+static int nft_quota_init(const struct nft_ctx *ctx,
172+ const struct nft_expr *expr,
173+ const struct nlattr * const tb[])
174+{
175+ struct nft_quota *priv = nft_expr_priv(expr);
176+
177+ return nft_quota_do_init(tb, priv);
178+}
179+
180+static int nft_quota_dump(struct sk_buff *skb, const struct nft_expr *expr)
181+{
182+ struct nft_quota *priv = nft_expr_priv(expr);
183+
184+ return nft_quota_do_dump(skb, priv, false);
185+}
186+
88187 static struct nft_expr_type nft_quota_type;
89188 static const struct nft_expr_ops nft_quota_ops = {
90189 .type = &nft_quota_type,
@@ -105,12 +204,26 @@ static struct nft_expr_type nft_quota_type __read_mostly = { · 14 unmodified lines
105204
106205 static int __init nft_quota_module_init(void)
107206 {
108− return nft_register_expr(&nft_quota_type);
207+ int err;
208+
209+ err = nft_register_obj(&nft_quota_obj);
210+ if (err < 0)
211+ return err;
212+
213+ err = nft_register_expr(&nft_quota_type);
214+ if (err < 0)
215+ goto err1;
216+
217+ return 0;
218+err1:
219+ nft_unregister_obj(&nft_quota_obj);
220+ return err;
109221 }
110222
111223 static void __exit nft_quota_module_exit(void)
112224 {
113− nft_unregister_expr(&nft_quota_type);
225+ nft_unregister_expr(&nft_quota_type);
226+ nft_unregister_obj(&nft_quota_obj);
114227 }
115228
116229 module_init(nft_quota_module_init);
@@ -119,3 +232,4 @@ module_exit(nft_quota_module_exit); · 2 unmodified lines
119232 MODULE_LICENSE("GPL");
120233 MODULE_AUTHOR("Pablo Neira Ayuso <pablo@netfilter.org>");
121234 MODULE_ALIAS_NFT_EXPR("quota");
235+MODULE_ALIAS_NFT_OBJ(NFT_OBJECT_QUOTA);
net/netfilter/nft_redir.c+3−3
@@ -1,5 +1,5 @@
11 /*
2− * Copyright (c) 2014 Arturo Borrero Gonzalez <arturo.borrero.glez@gmail.com>
2+ * Copyright (c) 2014 Arturo Borrero Gonzalez <arturo@debian.org>
33 *
44 * This program is free software; you can redistribute it and/or modify
55 * it under the terms of the GNU General Public License version 2 as
@@ -79,7 +79,7 @@ int nft_redir_init(const struct nft_ctx *ctx, · 73 unmodified lines
7979 return -EINVAL;
8080 }
8181
82− return 0;
82+ return nf_ct_netns_get(ctx->net, ctx->afi->family);
8383 }
8484 EXPORT_SYMBOL_GPL(nft_redir_init);
8585
@@ -108,4 +108,4 @@ nla_put_failure: · 22 unmodified lines
108108 EXPORT_SYMBOL_GPL(nft_redir_dump);
109109
110110 MODULE_LICENSE("GPL");
111−MODULE_AUTHOR("Arturo Borrero Gonzalez <arturo.borrero.glez@gmail.com>");
111+MODULE_AUTHOR("Arturo Borrero Gonzalez <arturo@debian.org>");
net/netfilter/nft_set_hash.c+18−7
@@ -167,6 +167,19 @@ static void nft_hash_activate(const struct net *net, const struct nft_set *set, · 166 unmodified lines
167167 nft_set_elem_clear_busy(&he->ext);
168168 }
169169
170+static bool nft_hash_deactivate_one(const struct net *net,
171+ const struct nft_set *set, void *priv)
172+{
173+ struct nft_hash_elem *he = priv;
174+
175+ if (!nft_set_elem_mark_busy(&he->ext) ||
176+ !nft_is_active(net, &he->ext)) {
177+ nft_set_elem_change_active(net, set, &he->ext);
178+ return true;
179+ }
180+ return false;
181+}
182+
170183 static void *nft_hash_deactivate(const struct net *net,
171184 const struct nft_set *set,
172185 const struct nft_set_elem *elem)
@@ -181,13 +194,10 @@ static void *nft_hash_deactivate(const struct net *net, · 8 unmodified lines
181194
182195 rcu_read_lock();
183196 he = rhashtable_lookup_fast(&priv->ht, &arg, nft_hash_params);
184− if (he != NULL) {
185− if (!nft_set_elem_mark_busy(&he->ext) ||
186− !nft_is_active(net, &he->ext))
187− nft_set_elem_change_active(net, set, &he->ext);
188− else
189− he = NULL;
190− }
197+ if (he != NULL &&
198+ !nft_hash_deactivate_one(net, set, he))
199+ he = NULL;
200+
191201 rcu_read_unlock();
192202
193203 return he;
@@ -387,6 +397,7 @@ static struct nft_set_ops nft_hash_ops __read_mostly = { · 193 unmodified lines
387397 .insert = nft_hash_insert,
388398 .activate = nft_hash_activate,
389399 .deactivate = nft_hash_deactivate,
400+ .deactivate_one = nft_hash_deactivate_one,
390401 .remove = nft_hash_remove,
391402 .lookup = nft_hash_lookup,
392403 .update = nft_hash_update,
net/netfilter/nft_set_rbtree.c+11−1
@@ -171,6 +171,15 @@ static void nft_rbtree_activate(const struct net *net, · 170 unmodified lines
171171 nft_set_elem_change_active(net, set, &rbe->ext);
172172 }
173173
174+static bool nft_rbtree_deactivate_one(const struct net *net,
175+ const struct nft_set *set, void *priv)
176+{
177+ struct nft_rbtree_elem *rbe = priv;
178+
179+ nft_set_elem_change_active(net, set, &rbe->ext);
180+ return true;
181+}
182+
174183 static void *nft_rbtree_deactivate(const struct net *net,
175184 const struct nft_set *set,
176185 const struct nft_set_elem *elem)
@@ -204,7 +213,7 @@ static void *nft_rbtree_deactivate(const struct net *net, · 27 unmodified lines
204213 parent = parent->rb_right;
205214 continue;
206215 }
207− nft_set_elem_change_active(net, set, &rbe->ext);
216+ nft_rbtree_deactivate_one(net, set, rbe);
208217 return rbe;
209218 }
210219 }
@@ -295,6 +304,7 @@ static struct nft_set_ops nft_rbtree_ops __read_mostly = { · 84 unmodified lines
295304 .insert = nft_rbtree_insert,
296305 .remove = nft_rbtree_remove,
297306 .deactivate = nft_rbtree_deactivate,
307+ .deactivate_one = nft_rbtree_deactivate_one,
298308 .activate = nft_rbtree_activate,
299309 .lookup = nft_rbtree_lookup,
300310 .walk = nft_rbtree_walk,
net/netfilter/x_tables.c+57−1
@@ -40,6 +40,7 @@ MODULE_AUTHOR("Harald Welte <laforge@netfilter.org>"); · 39 unmodified lines
4040 MODULE_DESCRIPTION("{ip,ip6,arp,eb}_tables backend module");
4141
4242 #define SMP_ALIGN(x) (((x) + SMP_CACHE_BYTES-1) & ~(SMP_CACHE_BYTES-1))
43+#define XT_PCPU_BLOCK_SIZE 4096
4344
4445 struct compat_delta {
4546 unsigned int offset; /* offset in kernel */
@@ -958,7 +959,9 @@ struct xt_table_info *xt_alloc_table_info(unsigned int size) · 912 unmodified lines
958959 if (sz <= (PAGE_SIZE << PAGE_ALLOC_COSTLY_ORDER))
959960 info = kmalloc(sz, GFP_KERNEL | __GFP_NOWARN | __GFP_NORETRY);
960961 if (!info) {
961− info = vmalloc(sz);
962+ info = __vmalloc(sz, GFP_KERNEL | __GFP_NOWARN |
963+ __GFP_NORETRY | __GFP_HIGHMEM,
964+ PAGE_KERNEL);
962965 if (!info)
963966 return NULL;
964967 }
@@ -1615,6 +1618,59 @@ void xt_proto_fini(struct net *net, u_int8_t af) · 650 unmodified lines
16151618 }
16161619 EXPORT_SYMBOL_GPL(xt_proto_fini);
16171620
1621+/**
1622+ * xt_percpu_counter_alloc - allocate x_tables rule counter
1623+ *
1624+ * @state: pointer to xt_percpu allocation state
1625+ * @counter: pointer to counter struct inside the ip(6)/arpt_entry struct
1626+ *
1627+ * On SMP, the packet counter [ ip(6)t_entry->counters.pcnt ] will then
1628+ * contain the address of the real (percpu) counter.
1629+ *
1630+ * Rule evaluation needs to use xt_get_this_cpu_counter() helper
1631+ * to fetch the real percpu counter.
1632+ *
1633+ * To speed up allocation and improve data locality, a 4kb block is
1634+ * allocated.
1635+ *
1636+ * xt_percpu_counter_alloc_state contains the base address of the
1637+ * allocated page and the current sub-offset.
1638+ *
1639+ * returns false on error.
1640+ */
1641+bool xt_percpu_counter_alloc(struct xt_percpu_counter_alloc_state *state,
1642+ struct xt_counters *counter)
1643+{
1644+ BUILD_BUG_ON(XT_PCPU_BLOCK_SIZE < (sizeof(*counter) * 2));
1645+
1646+ if (nr_cpu_ids <= 1)
1647+ return true;
1648+
1649+ if (!state->mem) {
1650+ state->mem = __alloc_percpu(XT_PCPU_BLOCK_SIZE,
1651+ XT_PCPU_BLOCK_SIZE);
1652+ if (!state->mem)
1653+ return false;
1654+ }
1655+ counter->pcnt = (__force unsigned long)(state->mem + state->off);
1656+ state->off += sizeof(*counter);
1657+ if (state->off > (XT_PCPU_BLOCK_SIZE - sizeof(*counter))) {
1658+ state->mem = NULL;
1659+ state->off = 0;
1660+ }
1661+ return true;
1662+}
1663+EXPORT_SYMBOL_GPL(xt_percpu_counter_alloc);
1664+
1665+void xt_percpu_counter_free(struct xt_counters *counters)
1666+{
1667+ unsigned long pcnt = counters->pcnt;
1668+
1669+ if (nr_cpu_ids > 1 && (pcnt & (XT_PCPU_BLOCK_SIZE - 1)) == 0)
1670+ free_percpu((void __percpu *)pcnt);
1671+}
1672+EXPORT_SYMBOL_GPL(xt_percpu_counter_free);
1673+
16181674 static int __net_init xt_net_init(struct net *net)
16191675 {
16201676 int i;
net/netfilter/xt_CONNSECMARK.c+2−2
@@ -106,7 +106,7 @@ static int connsecmark_tg_check(const struct xt_tgchk_param *par) · 105 unmodified lines
106106 return -EINVAL;
107107 }
108108
109− ret = nf_ct_l3proto_try_module_get(par->family);
109+ ret = nf_ct_netns_get(par->net, par->family);
110110 if (ret < 0)
111111 pr_info("cannot load conntrack support for proto=%u\n",
112112 par->family);
@@ -115,7 +115,7 @@ static int connsecmark_tg_check(const struct xt_tgchk_param *par) · 2 unmodified lines
115115
116116 static void connsecmark_tg_destroy(const struct xt_tgdtor_param *par)
117117 {
118− nf_ct_l3proto_module_put(par->family);
118+ nf_ct_netns_put(par->net, par->family);
119119 }
120120
121121 static struct xt_target connsecmark_tg_reg __read_mostly = {
net/netfilter/xt_CT.c+3−3
@@ -216,7 +216,7 @@ static int xt_ct_tg_check(const struct xt_tgchk_param *par, · 215 unmodified lines
216216 goto err1;
217217 #endif
218218
219− ret = nf_ct_l3proto_try_module_get(par->family);
219+ ret = nf_ct_netns_get(par->net, par->family);
220220 if (ret < 0)
221221 goto err1;
222222
@@ -260,7 +260,7 @@ out: · 37 unmodified lines
260260 err3:
261261 nf_ct_tmpl_free(ct);
262262 err2:
263− nf_ct_l3proto_module_put(par->family);
263+ nf_ct_netns_put(par->net, par->family);
264264 err1:
265265 return ret;
266266 }
@@ -341,7 +341,7 @@ static void xt_ct_tg_destroy(const struct xt_tgdtor_param *par, · 74 unmodified lines
341341 if (help)
342342 module_put(help->helper->me);
343343
344− nf_ct_l3proto_module_put(par->family);
344+ nf_ct_netns_put(par->net, par->family);
345345
346346 xt_ct_destroy_timeout(ct);
347347 nf_ct_put(info->ct);
net/netfilter/xt_NETMAP.c+9−2
@@ -60,7 +60,12 @@ static int netmap_tg6_checkentry(const struct xt_tgchk_param *par) · 59 unmodified lines
6060
6161 if (!(range->flags & NF_NAT_RANGE_MAP_IPS))
6262 return -EINVAL;
63− return 0;
63+ return nf_ct_netns_get(par->net, par->family);
64+}
65+
66+static void netmap_tg_destroy(const struct xt_tgdtor_param *par)
67+{
68+ nf_ct_netns_put(par->net, par->family);
6469 }
6570
6671 static unsigned int
@@ -111,7 +116,7 @@ static int netmap_tg4_check(const struct xt_tgchk_param *par) · 44 unmodified lines
111116 pr_debug("bad rangesize %u.\n", mr->rangesize);
112117 return -EINVAL;
113118 }
114− return 0;
119+ return nf_ct_netns_get(par->net, par->family);
115120 }
116121
117122 static struct xt_target netmap_tg_reg[] __read_mostly = {
@@ -127,6 +132,7 @@ static struct xt_target netmap_tg_reg[] __read_mostly = { · 9 unmodified lines
127132 (1 << NF_INET_LOCAL_OUT) |
128133 (1 << NF_INET_LOCAL_IN),
129134 .checkentry = netmap_tg6_checkentry,
135+ .destroy = netmap_tg_destroy,
130136 .me = THIS_MODULE,
131137 },
132138 {
@@ -141,6 +147,7 @@ static struct xt_target netmap_tg_reg[] __read_mostly = { · 8 unmodified lines
141147 (1 << NF_INET_LOCAL_OUT) |
142148 (1 << NF_INET_LOCAL_IN),
143149 .checkentry = netmap_tg4_check,
150+ .destroy = netmap_tg_destroy,
144151 .me = THIS_MODULE,
145152 },
146153 };
net/netfilter/xt_REDIRECT.c+10−2
@@ -40,7 +40,13 @@ static int redirect_tg6_checkentry(const struct xt_tgchk_param *par) · 39 unmodified lines
4040
4141 if (range->flags & NF_NAT_RANGE_MAP_IPS)
4242 return -EINVAL;
43− return 0;
43+
44+ return nf_ct_netns_get(par->net, par->family);
45+}
46+
47+static void redirect_tg_destroy(const struct xt_tgdtor_param *par)
48+{
49+ nf_ct_netns_put(par->net, par->family);
4450 }
4551
4652 /* FIXME: Take multiple ranges --RR */
@@ -56,7 +62,7 @@ static int redirect_tg4_check(const struct xt_tgchk_param *par) · 9 unmodified lines
5662 pr_debug("bad rangesize %u.\n", mr->rangesize);
5763 return -EINVAL;
5864 }
59− return 0;
65+ return nf_ct_netns_get(par->net, par->family);
6066 }
6167
6268 static unsigned int
@@ -72,6 +78,7 @@ static struct xt_target redirect_tg_reg[] __read_mostly = { · 9 unmodified lines
7278 .revision = 0,
7379 .table = "nat",
7480 .checkentry = redirect_tg6_checkentry,
81+ .destroy = redirect_tg_destroy,
7582 .target = redirect_tg6,
7683 .targetsize = sizeof(struct nf_nat_range),
7784 .hooks = (1 << NF_INET_PRE_ROUTING) |
@@ -85,6 +92,7 @@ static struct xt_target redirect_tg_reg[] __read_mostly = { · 7 unmodified lines
8592 .table = "nat",
8693 .target = redirect_tg4,
8794 .checkentry = redirect_tg4_check,
95+ .destroy = redirect_tg_destroy,
8896 .targetsize = sizeof(struct nf_nat_ipv4_multi_range_compat),
8997 .hooks = (1 << NF_INET_PRE_ROUTING) |
9098 (1 << NF_INET_LOCAL_OUT),
net/netfilter/xt_TPROXY.c+10−5
@@ -531,6 +531,11 @@ tproxy_tg6_v1(struct sk_buff *skb, const struct xt_action_param *par) · 530 unmodified lines
531531 static int tproxy_tg6_check(const struct xt_tgchk_param *par)
532532 {
533533 const struct ip6t_ip6 *i = par->entryinfo;
534+ int err;
535+
536+ err = nf_defrag_ipv6_enable(par->net);
537+ if (err)
538+ return err;
534539
535540 if ((i->proto == IPPROTO_TCP || i->proto == IPPROTO_UDP) &&
536541 !(i->invflags & IP6T_INV_PROTO))
@@ -545,6 +550,11 @@ static int tproxy_tg6_check(const struct xt_tgchk_param *par) · 8 unmodified lines
545550 static int tproxy_tg4_check(const struct xt_tgchk_param *par)
546551 {
547552 const struct ipt_ip *i = par->entryinfo;
553+ int err;
554+
555+ err = nf_defrag_ipv4_enable(par->net);
556+ if (err)
557+ return err;
548558
549559 if ((i->proto == IPPROTO_TCP || i->proto == IPPROTO_UDP)
550560 && !(i->invflags & IPT_INV_PROTO))
@@ -596,11 +606,6 @@ static struct xt_target tproxy_tg_reg[] __read_mostly = { · 45 unmodified lines
596606
597607 static int __init tproxy_tg_init(void)
598608 {
599− nf_defrag_ipv4_enable();
600−#ifdef XT_TPROXY_HAVE_IPV6
601− nf_defrag_ipv6_enable();
602−#endif
603−
604609 return xt_register_targets(tproxy_tg_reg, ARRAY_SIZE(tproxy_tg_reg));
605610 }
606611
net/netfilter/xt_bpf.c+80−16
@@ -10,6 +10,7 @@ · 9 unmodified lines
1010 #include <linux/module.h>
1111 #include <linux/skbuff.h>
1212 #include <linux/filter.h>
13+#include <linux/bpf.h>
1314
1415 #include <linux/netfilter/xt_bpf.h>
1516 #include <linux/netfilter/x_tables.h>
@@ -20,15 +21,15 @@ MODULE_LICENSE("GPL"); · 4 unmodified lines
2021 MODULE_ALIAS("ipt_bpf");
2122 MODULE_ALIAS("ip6t_bpf");
2223
23−static int bpf_mt_check(const struct xt_mtchk_param *par)
24+static int __bpf_mt_check_bytecode(struct sock_filter *insns, __u16 len,
25+ struct bpf_prog **ret)
2426 {
25− struct xt_bpf_info *info = par->matchinfo;
2627 struct sock_fprog_kern program;
2728
28− program.len = info->bpf_program_num_elem;
29− program.filter = info->bpf_program;
29+ program.len = len;
30+ program.filter = insns;
3031
31− if (bpf_prog_create(&info->filter, &program)) {
32+ if (bpf_prog_create(ret, &program)) {
3233 pr_info("bpf: check failed: parse error\n");
3334 return -EINVAL;
3435 }
@@ -36,6 +37,42 @@ static int bpf_mt_check(const struct xt_mtchk_param *par) · 1 unmodified line
3637 return 0;
3738 }
3839
40+static int __bpf_mt_check_fd(int fd, struct bpf_prog **ret)
41+{
42+ struct bpf_prog *prog;
43+
44+ prog = bpf_prog_get_type(fd, BPF_PROG_TYPE_SOCKET_FILTER);
45+ if (IS_ERR(prog))
46+ return PTR_ERR(prog);
47+
48+ *ret = prog;
49+ return 0;
50+}
51+
52+static int bpf_mt_check(const struct xt_mtchk_param *par)
53+{
54+ struct xt_bpf_info *info = par->matchinfo;
55+
56+ return __bpf_mt_check_bytecode(info->bpf_program,
57+ info->bpf_program_num_elem,
58+ &info->filter);
59+}
60+
61+static int bpf_mt_check_v1(const struct xt_mtchk_param *par)
62+{
63+ struct xt_bpf_info_v1 *info = par->matchinfo;
64+
65+ if (info->mode == XT_BPF_MODE_BYTECODE)
66+ return __bpf_mt_check_bytecode(info->bpf_program,
67+ info->bpf_program_num_elem,
68+ &info->filter);
69+ else if (info->mode == XT_BPF_MODE_FD_PINNED ||
70+ info->mode == XT_BPF_MODE_FD_ELF)
71+ return __bpf_mt_check_fd(info->fd, &info->filter);
72+ else
73+ return -EINVAL;
74+}
75+
3976 static bool bpf_mt(const struct sk_buff *skb, struct xt_action_param *par)
4077 {
4178 const struct xt_bpf_info *info = par->matchinfo;
@@ -43,31 +80,58 @@ static bool bpf_mt(const struct sk_buff *skb, struct xt_action_param *par) · 1 unmodified line
4380 return BPF_PROG_RUN(info->filter, skb);
4481 }
4582
83+static bool bpf_mt_v1(const struct sk_buff *skb, struct xt_action_param *par)
84+{
85+ const struct xt_bpf_info_v1 *info = par->matchinfo;
86+
87+ return !!bpf_prog_run_save_cb(info->filter, (struct sk_buff *) skb);
88+}
89+
4690 static void bpf_mt_destroy(const struct xt_mtdtor_param *par)
4791 {
4892 const struct xt_bpf_info *info = par->matchinfo;
93+
94+ bpf_prog_destroy(info->filter);
95+}
96+
97+static void bpf_mt_destroy_v1(const struct xt_mtdtor_param *par)
98+{
99+ const struct xt_bpf_info_v1 *info = par->matchinfo;
100+
49101 bpf_prog_destroy(info->filter);
50102 }
51103
52−static struct xt_match bpf_mt_reg __read_mostly = {
53− .name = "bpf",
54− .revision = 0,
55− .family = NFPROTO_UNSPEC,
56− .checkentry = bpf_mt_check,
57− .match = bpf_mt,
58− .destroy = bpf_mt_destroy,
59− .matchsize = sizeof(struct xt_bpf_info),
60− .me = THIS_MODULE,
104+static struct xt_match bpf_mt_reg[] __read_mostly = {
105+ {
106+ .name = "bpf",
107+ .revision = 0,
108+ .family = NFPROTO_UNSPEC,
109+ .checkentry = bpf_mt_check,
110+ .match = bpf_mt,
111+ .destroy = bpf_mt_destroy,
112+ .matchsize = sizeof(struct xt_bpf_info),
113+ .me = THIS_MODULE,
114+ },
115+ {
116+ .name = "bpf",
117+ .revision = 1,
118+ .family = NFPROTO_UNSPEC,
119+ .checkentry = bpf_mt_check_v1,
120+ .match = bpf_mt_v1,
121+ .destroy = bpf_mt_destroy_v1,
122+ .matchsize = sizeof(struct xt_bpf_info_v1),
123+ .me = THIS_MODULE,
124+ },
61125 };
62126
63127 static int __init bpf_mt_init(void)
64128 {
65− return xt_register_match(&bpf_mt_reg);
129+ return xt_register_matches(bpf_mt_reg, ARRAY_SIZE(bpf_mt_reg));
66130 }
67131
68132 static void __exit bpf_mt_exit(void)
69133 {
70− xt_unregister_match(&bpf_mt_reg);
134+ xt_unregister_matches(bpf_mt_reg, ARRAY_SIZE(bpf_mt_reg));
71135 }
72136
73137 module_init(bpf_mt_init);
net/netfilter/xt_connbytes.c+2−2
@@ -110,7 +110,7 @@ static int connbytes_mt_check(const struct xt_mtchk_param *par) · 109 unmodified lines
110110 sinfo->direction != XT_CONNBYTES_DIR_BOTH)
111111 return -EINVAL;
112112
113− ret = nf_ct_l3proto_try_module_get(par->family);
113+ ret = nf_ct_netns_get(par->net, par->family);
114114 if (ret < 0)
115115 pr_info("cannot load conntrack support for proto=%u\n",
116116 par->family);
@@ -129,7 +129,7 @@ static int connbytes_mt_check(const struct xt_mtchk_param *par) · 12 unmodified lines
129129
130130 static void connbytes_mt_destroy(const struct xt_mtdtor_param *par)
131131 {
132− nf_ct_l3proto_module_put(par->family);
132+ nf_ct_netns_put(par->net, par->family);
133133 }
134134
135135 static struct xt_match connbytes_mt_reg __read_mostly = {
net/netfilter/xt_connlabel.c+3−3
@@ -61,7 +61,7 @@ static int connlabel_mt_check(const struct xt_mtchk_param *par) · 60 unmodified lines
6161 return -EINVAL;
6262 }
6363
64− ret = nf_ct_l3proto_try_module_get(par->family);
64+ ret = nf_ct_netns_get(par->net, par->family);
6565 if (ret < 0) {
6666 pr_info("cannot load conntrack support for proto=%u\n",
6767 par->family);
@@ -70,14 +70,14 @@ static int connlabel_mt_check(const struct xt_mtchk_param *par) · 2 unmodified lines
7070
7171 ret = nf_connlabels_get(par->net, info->bit);
7272 if (ret < 0)
73− nf_ct_l3proto_module_put(par->family);
73+ nf_ct_netns_put(par->net, par->family);
7474 return ret;
7575 }
7676
7777 static void connlabel_mt_destroy(const struct xt_mtdtor_param *par)
7878 {
7979 nf_connlabels_put(par->net);
80− nf_ct_l3proto_module_put(par->family);
80+ nf_ct_netns_put(par->net, par->family);
8181 }
8282
8383 static struct xt_match connlabels_mt_reg __read_mostly = {
net/netfilter/xt_connlimit.c+3−3
@@ -368,7 +368,7 @@ static int connlimit_mt_check(const struct xt_mtchk_param *par) · 367 unmodified lines
368368
369369 net_get_random_once(&connlimit_rnd, sizeof(connlimit_rnd));
370370
371− ret = nf_ct_l3proto_try_module_get(par->family);
371+ ret = nf_ct_netns_get(par->net, par->family);
372372 if (ret < 0) {
373373 pr_info("cannot load conntrack support for "
374374 "address family %u\n", par->family);
@@ -378,7 +378,7 @@ static int connlimit_mt_check(const struct xt_mtchk_param *par) · 3 unmodified lines
378378 /* init private data */
379379 info->data = kmalloc(sizeof(struct xt_connlimit_data), GFP_KERNEL);
380380 if (info->data == NULL) {
381− nf_ct_l3proto_module_put(par->family);
381+ nf_ct_netns_put(par->net, par->family);
382382 return -ENOMEM;
383383 }
384384
@@ -414,7 +414,7 @@ static void connlimit_mt_destroy(const struct xt_mtdtor_param *par) · 29 unmodified lines
414414 const struct xt_connlimit_info *info = par->matchinfo;
415415 unsigned int i;
416416
417− nf_ct_l3proto_module_put(par->family);
417+ nf_ct_netns_put(par->net, par->family);
418418
419419 for (i = 0; i < ARRAY_SIZE(info->data->climit_root4); ++i)
420420 destroy_tree(&info->data->climit_root4[i]);
net/netfilter/xt_connmark.c+4−4
@@ -77,7 +77,7 @@ static int connmark_tg_check(const struct xt_tgchk_param *par) · 76 unmodified lines
7777 {
7878 int ret;
7979
80− ret = nf_ct_l3proto_try_module_get(par->family);
80+ ret = nf_ct_netns_get(par->net, par->family);
8181 if (ret < 0)
8282 pr_info("cannot load conntrack support for proto=%u\n",
8383 par->family);
@@ -86,7 +86,7 @@ static int connmark_tg_check(const struct xt_tgchk_param *par) · 2 unmodified lines
8686
8787 static void connmark_tg_destroy(const struct xt_tgdtor_param *par)
8888 {
89− nf_ct_l3proto_module_put(par->family);
89+ nf_ct_netns_put(par->net, par->family);
9090 }
9191
9292 static bool
@@ -107,7 +107,7 @@ static int connmark_mt_check(const struct xt_mtchk_param *par) · 14 unmodified lines
107107 {
108108 int ret;
109109
110− ret = nf_ct_l3proto_try_module_get(par->family);
110+ ret = nf_ct_netns_get(par->net, par->family);
111111 if (ret < 0)
112112 pr_info("cannot load conntrack support for proto=%u\n",
113113 par->family);
@@ -116,7 +116,7 @@ static int connmark_mt_check(const struct xt_mtchk_param *par) · 2 unmodified lines
116116
117117 static void connmark_mt_destroy(const struct xt_mtdtor_param *par)
118118 {
119− nf_ct_l3proto_module_put(par->family);
119+ nf_ct_netns_put(par->net, par->family);
120120 }
121121
122122 static struct xt_target connmark_tg_reg __read_mostly = {
net/netfilter/xt_conntrack.c+2−2
@@ -271,7 +271,7 @@ static int conntrack_mt_check(const struct xt_mtchk_param *par) · 270 unmodified lines
271271 {
272272 int ret;
273273
274− ret = nf_ct_l3proto_try_module_get(par->family);
274+ ret = nf_ct_netns_get(par->net, par->family);
275275 if (ret < 0)
276276 pr_info("cannot load conntrack support for proto=%u\n",
277277 par->family);
@@ -280,7 +280,7 @@ static int conntrack_mt_check(const struct xt_mtchk_param *par) · 2 unmodified lines
280280
281281 static void conntrack_mt_destroy(const struct xt_mtdtor_param *par)
282282 {
283− nf_ct_l3proto_module_put(par->family);
283+ nf_ct_netns_put(par->net, par->family);
284284 }
285285
286286 static struct xt_match conntrack_mt_reg[] __read_mostly = {
net/netfilter/xt_helper.c+2−2
@@ -59,7 +59,7 @@ static int helper_mt_check(const struct xt_mtchk_param *par) · 58 unmodified lines
5959 struct xt_helper_info *info = par->matchinfo;
6060 int ret;
6161
62− ret = nf_ct_l3proto_try_module_get(par->family);
62+ ret = nf_ct_netns_get(par->net, par->family);
6363 if (ret < 0) {
6464 pr_info("cannot load conntrack support for proto=%u\n",
6565 par->family);
@@ -71,7 +71,7 @@ static int helper_mt_check(const struct xt_mtchk_param *par) · 5 unmodified lines
7171
7272 static void helper_mt_destroy(const struct xt_mtdtor_param *par)
7373 {
74− nf_ct_l3proto_module_put(par->family);
74+ nf_ct_netns_put(par->net, par->family);
7575 }
7676
7777 static struct xt_match helper_mt_reg __read_mostly = {
net/netfilter/xt_multiport.c+19−7
@@ -44,12 +44,18 @@ ports_match_v1(const struct xt_multiport_v1 *minfo, · 43 unmodified lines
4444
4545 switch (minfo->flags) {
4646 case XT_MULTIPORT_SOURCE:
47− return (src >= s && src <= e) ^ minfo->invert;
47+ if (src >= s && src <= e)
48+ return true ^ minfo->invert;
49+ break;
4850 case XT_MULTIPORT_DESTINATION:
49− return (dst >= s && dst <= e) ^ minfo->invert;
51+ if (dst >= s && dst <= e)
52+ return true ^ minfo->invert;
53+ break;
5054 case XT_MULTIPORT_EITHER:
51− return ((dst >= s && dst <= e) ||
52− (src >= s && src <= e)) ^ minfo->invert;
55+ if ((dst >= s && dst <= e) ||
56+ (src >= s && src <= e))
57+ return true ^ minfo->invert;
58+ break;
5359 default:
5460 break;
5561 }
@@ -59,11 +65,17 @@ ports_match_v1(const struct xt_multiport_v1 *minfo, · 3 unmodified lines
5965
6066 switch (minfo->flags) {
6167 case XT_MULTIPORT_SOURCE:
62− return (src == s) ^ minfo->invert;
68+ if (src == s)
69+ return true ^ minfo->invert;
70+ break;
6371 case XT_MULTIPORT_DESTINATION:
64− return (dst == s) ^ minfo->invert;
72+ if (dst == s)
73+ return true ^ minfo->invert;
74+ break;
6575 case XT_MULTIPORT_EITHER:
66− return (src == s || dst == s) ^ minfo->invert;
76+ if (src == s || dst == s)
77+ return true ^ minfo->invert;
78+ break;
6779 default:
6880 break;
6981 }
net/netfilter/xt_nat.c+17−1
@@ -23,7 +23,17 @@ static int xt_nat_checkentry_v0(const struct xt_tgchk_param *par) · 22 unmodified lines
2323 par->target->name);
2424 return -EINVAL;
2525 }
26− return 0;
26+ return nf_ct_netns_get(par->net, par->family);
27+}
28+
29+static int xt_nat_checkentry(const struct xt_tgchk_param *par)
30+{
31+ return nf_ct_netns_get(par->net, par->family);
32+}
33+
34+static void xt_nat_destroy(const struct xt_tgdtor_param *par)
35+{
36+ nf_ct_netns_put(par->net, par->family);
2737 }
2838
2939 static void xt_nat_convert_range(struct nf_nat_range *dst,
@@ -106,6 +116,7 @@ static struct xt_target xt_nat_target_reg[] __read_mostly = { · 76 unmodified lines
106116 .name = "SNAT",
107117 .revision = 0,
108118 .checkentry = xt_nat_checkentry_v0,
119+ .destroy = xt_nat_destroy,
109120 .target = xt_snat_target_v0,
110121 .targetsize = sizeof(struct nf_nat_ipv4_multi_range_compat),
111122 .family = NFPROTO_IPV4,
@@ -118,6 +129,7 @@ static struct xt_target xt_nat_target_reg[] __read_mostly = { · 6 unmodified lines
118129 .name = "DNAT",
119130 .revision = 0,
120131 .checkentry = xt_nat_checkentry_v0,
132+ .destroy = xt_nat_destroy,
121133 .target = xt_dnat_target_v0,
122134 .targetsize = sizeof(struct nf_nat_ipv4_multi_range_compat),
123135 .family = NFPROTO_IPV4,
@@ -129,6 +141,8 @@ static struct xt_target xt_nat_target_reg[] __read_mostly = { · 5 unmodified lines
129141 {
130142 .name = "SNAT",
131143 .revision = 1,
144+ .checkentry = xt_nat_checkentry,
145+ .destroy = xt_nat_destroy,
132146 .target = xt_snat_target_v1,
133147 .targetsize = sizeof(struct nf_nat_range),
134148 .table = "nat",
@@ -139,6 +153,8 @@ static struct xt_target xt_nat_target_reg[] __read_mostly = { · 4 unmodified lines
139153 {
140154 .name = "DNAT",
141155 .revision = 1,
156+ .checkentry = xt_nat_checkentry,
157+ .destroy = xt_nat_destroy,
142158 .target = xt_dnat_target_v1,
143159 .targetsize = sizeof(struct nf_nat_range),
144160 .table = "nat",
net/netfilter/xt_socket.c+28−5
@@ -147,9 +147,28 @@ socket_mt6_v1_v2_v3(const struct sk_buff *skb, struct xt_action_param *par) · 146 unmodified lines
147147 }
148148 #endif
149149
150+static int socket_mt_enable_defrag(struct net *net, int family)
151+{
152+ switch (family) {
153+ case NFPROTO_IPV4:
154+ return nf_defrag_ipv4_enable(net);
155+#ifdef XT_SOCKET_HAVE_IPV6
156+ case NFPROTO_IPV6:
157+ return nf_defrag_ipv6_enable(net);
158+#endif
159+ }
160+ WARN_ONCE(1, "Unknown family %d\n", family);
161+ return 0;
162+}
163+
150164 static int socket_mt_v1_check(const struct xt_mtchk_param *par)
151165 {
152166 const struct xt_socket_mtinfo1 *info = (struct xt_socket_mtinfo1 *) par->matchinfo;
167+ int err;
168+
169+ err = socket_mt_enable_defrag(par->net, par->family);
170+ if (err)
171+ return err;
153172
154173 if (info->flags & ~XT_SOCKET_FLAGS_V1) {
155174 pr_info("unknown flags 0x%x\n", info->flags & ~XT_SOCKET_FLAGS_V1);
@@ -161,6 +180,11 @@ static int socket_mt_v1_check(const struct xt_mtchk_param *par) · 5 unmodified lines
161180 static int socket_mt_v2_check(const struct xt_mtchk_param *par)
162181 {
163182 const struct xt_socket_mtinfo2 *info = (struct xt_socket_mtinfo2 *) par->matchinfo;
183+ int err;
184+
185+ err = socket_mt_enable_defrag(par->net, par->family);
186+ if (err)
187+ return err;
164188
165189 if (info->flags & ~XT_SOCKET_FLAGS_V2) {
166190 pr_info("unknown flags 0x%x\n", info->flags & ~XT_SOCKET_FLAGS_V2);
@@ -173,7 +197,11 @@ static int socket_mt_v3_check(const struct xt_mtchk_param *par) · 6 unmodified lines
173197 {
174198 const struct xt_socket_mtinfo3 *info =
175199 (struct xt_socket_mtinfo3 *)par->matchinfo;
200+ int err;
176201
202+ err = socket_mt_enable_defrag(par->net, par->family);
203+ if (err)
204+ return err;
177205 if (info->flags & ~XT_SOCKET_FLAGS_V3) {
178206 pr_info("unknown flags 0x%x\n",
179207 info->flags & ~XT_SOCKET_FLAGS_V3);
@@ -268,11 +296,6 @@ static struct xt_match socket_mt_reg[] __read_mostly = { · 88 unmodified lines
268296
269297 static int __init socket_mt_init(void)
270298 {
271− nf_defrag_ipv4_enable();
272−#if IS_ENABLED(CONFIG_IP6_NF_IPTABLES)
273− nf_defrag_ipv6_enable();
274−#endif
275−
276299 return xt_register_matches(socket_mt_reg, ARRAY_SIZE(socket_mt_reg));
277300 }
278301
net/netfilter/xt_state.c+2−2
@@ -43,7 +43,7 @@ static int state_mt_check(const struct xt_mtchk_param *par) · 42 unmodified lines
4343 {
4444 int ret;
4545
46− ret = nf_ct_l3proto_try_module_get(par->family);
46+ ret = nf_ct_netns_get(par->net, par->family);
4747 if (ret < 0)
4848 pr_info("cannot load conntrack support for proto=%u\n",
4949 par->family);
@@ -52,7 +52,7 @@ static int state_mt_check(const struct xt_mtchk_param *par) · 2 unmodified lines
5252
5353 static void state_mt_destroy(const struct xt_mtdtor_param *par)
5454 {
55− nf_ct_l3proto_module_put(par->family);
55+ nf_ct_netns_put(par->net, par->family);
5656 }
5757
5858 static struct xt_match state_mt_reg __read_mostly = {

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t