aboutsummaryrefslogtreecommitdiffstats
path: root/net/netfilter
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2014-12-11 17:27:06 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2014-12-11 17:27:06 -0500
commit70e71ca0af244f48a5dcf56dc435243792e3a495 (patch)
treef7d9c4c4d9a857a00043e9bf6aa2d6f533a34778 /net/netfilter
parentbae41e45b7400496b9bf0c70c6004419d9987819 (diff)
parent00c83b01d58068dfeb2e1351cca6fccf2a83fa8f (diff)
Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-next
Pull networking updates from David Miller: 1) New offloading infrastructure and example 'rocker' driver for offloading of switching and routing to hardware. This work was done by a large group of dedicated individuals, not limited to: Scott Feldman, Jiri Pirko, Thomas Graf, John Fastabend, Jamal Hadi Salim, Andy Gospodarek, Florian Fainelli, Roopa Prabhu 2) Start making the networking operate on IOV iterators instead of modifying iov objects in-situ during transfers. Thanks to Al Viro and Herbert Xu. 3) A set of new netlink interfaces for the TIPC stack, from Richard Alpe. 4) Remove unnecessary looping during ipv6 routing lookups, from Martin KaFai Lau. 5) Add PAUSE frame generation support to gianfar driver, from Matei Pavaluca. 6) Allow for larger reordering levels in TCP, which are easily achievable in the real world right now, from Eric Dumazet. 7) Add a variable of napi_schedule that doesn't need to disable cpu interrupts, from Eric Dumazet. 8) Use a doubly linked list to optimize neigh_parms_release(), from Nicolas Dichtel. 9) Various enhancements to the kernel BPF verifier, and allow eBPF programs to actually be attached to sockets. From Alexei Starovoitov. 10) Support TSO/LSO in sunvnet driver, from David L Stevens. 11) Allow controlling ECN usage via routing metrics, from Florian Westphal. 12) Remote checksum offload, from Tom Herbert. 13) Add split-header receive, BQL, and xmit_more support to amd-xgbe driver, from Thomas Lendacky. 14) Add MPLS support to openvswitch, from Simon Horman. 15) Support wildcard tunnel endpoints in ipv6 tunnels, from Steffen Klassert. 16) Do gro flushes on a per-device basis using a timer, from Eric Dumazet. This tries to resolve the conflicting goals between the desired handling of bulk vs. RPC-like traffic. 17) Allow userspace to ask for the CPU upon what a packet was received/steered, via SO_INCOMING_CPU. From Eric Dumazet. 18) Limit GSO packets to half the current congestion window, from Eric Dumazet. 19) Add a generic helper so that all drivers set their RSS keys in a consistent way, from Eric Dumazet. 20) Add xmit_more support to enic driver, from Govindarajulu Varadarajan. 21) Add VLAN packet scheduler action, from Jiri Pirko. 22) Support configurable RSS hash functions via ethtool, from Eyal Perry. * git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-next: (1820 commits) Fix race condition between vxlan_sock_add and vxlan_sock_release net/macb: fix compilation warning for print_hex_dump() called with skb->mac_header net/mlx4: Add support for A0 steering net/mlx4: Refactor QUERY_PORT net/mlx4_core: Add explicit error message when rule doesn't meet configuration net/mlx4: Add A0 hybrid steering net/mlx4: Add mlx4_bitmap zone allocator net/mlx4: Add a check if there are too many reserved QPs net/mlx4: Change QP allocation scheme net/mlx4_core: Use tasklet for user-space CQ completion events net/mlx4_core: Mask out host side virtualization features for guests net/mlx4_en: Set csum level for encapsulated packets be2net: Export tunnel offloads only when a VxLAN tunnel is created gianfar: Fix dma check map error when DMA_API_DEBUG is enabled cxgb4/csiostor: Don't use MASTER_MUST for fw_hello call net: fec: only enable mdio interrupt before phy device link up net: fec: clear all interrupt events to support i.MX6SX net: fec: reset fep link status in suspend function net: sock: fix access via invalid file descriptor net: introduce helper macro for_each_cmsghdr ...
Diffstat (limited to 'net/netfilter')
-rw-r--r--net/netfilter/Kconfig17
-rw-r--r--net/netfilter/Makefile2
-rw-r--r--net/netfilter/core.c1
-rw-r--r--net/netfilter/ipset/ip_set_hash_gen.h101
-rw-r--r--net/netfilter/ipset/ip_set_hash_netiface.c1
-rw-r--r--net/netfilter/ipset/ip_set_hash_netnet.c2
-rw-r--r--net/netfilter/ipset/ip_set_hash_netportnet.c2
-rw-r--r--net/netfilter/ipvs/ip_vs_ctl.c3
-rw-r--r--net/netfilter/ipvs/ip_vs_pe.c3
-rw-r--r--net/netfilter/ipvs/ip_vs_sched.c3
-rw-r--r--net/netfilter/ipvs/ip_vs_sync.c3
-rw-r--r--net/netfilter/ipvs/ip_vs_xmit.c5
-rw-r--r--net/netfilter/nf_conntrack_core.c11
-rw-r--r--net/netfilter/nf_conntrack_h323_main.c14
-rw-r--r--net/netfilter/nf_conntrack_helper.c2
-rw-r--r--net/netfilter/nf_log.c40
-rw-r--r--net/netfilter/nf_nat_redirect.c127
-rw-r--r--net/netfilter/nf_tables_api.c5
-rw-r--r--net/netfilter/nfnetlink_log.c18
-rw-r--r--net/netfilter/nft_hash.c10
-rw-r--r--net/netfilter/nft_meta.c7
-rw-r--r--net/netfilter/nft_redir.c99
-rw-r--r--net/netfilter/xt_DSCP.c6
-rw-r--r--net/netfilter/xt_REDIRECT.c83
-rw-r--r--net/netfilter/xt_connlimit.c25
-rw-r--r--net/netfilter/xt_recent.c64
-rw-r--r--net/netfilter/xt_set.c73
27 files changed, 502 insertions, 225 deletions
diff --git a/net/netfilter/Kconfig b/net/netfilter/Kconfig
index ae5096ab65eb..b02660fa9eb0 100644
--- a/net/netfilter/Kconfig
+++ b/net/netfilter/Kconfig
@@ -411,6 +411,13 @@ config NF_NAT_TFTP
411 depends on NF_CONNTRACK && NF_NAT 411 depends on NF_CONNTRACK && NF_NAT
412 default NF_NAT && NF_CONNTRACK_TFTP 412 default NF_NAT && NF_CONNTRACK_TFTP
413 413
414config NF_NAT_REDIRECT
415 tristate "IPv4/IPv6 redirect support"
416 depends on NF_NAT
417 help
418 This is the kernel functionality to redirect packets to local
419 machine through NAT.
420
414config NETFILTER_SYNPROXY 421config NETFILTER_SYNPROXY
415 tristate 422 tristate
416 423
@@ -505,6 +512,15 @@ config NFT_MASQ
505 This option adds the "masquerade" expression that you can use 512 This option adds the "masquerade" expression that you can use
506 to perform NAT in the masquerade flavour. 513 to perform NAT in the masquerade flavour.
507 514
515config NFT_REDIR
516 depends on NF_TABLES
517 depends on NF_CONNTRACK
518 depends on NF_NAT
519 tristate "Netfilter nf_tables redirect support"
520 help
521 This options adds the "redirect" expression that you can use
522 to perform NAT in the redirect flavour.
523
508config NFT_NAT 524config NFT_NAT
509 depends on NF_TABLES 525 depends on NF_TABLES
510 depends on NF_CONNTRACK 526 depends on NF_CONNTRACK
@@ -835,6 +851,7 @@ config NETFILTER_XT_TARGET_RATEEST
835config NETFILTER_XT_TARGET_REDIRECT 851config NETFILTER_XT_TARGET_REDIRECT
836 tristate "REDIRECT target support" 852 tristate "REDIRECT target support"
837 depends on NF_NAT 853 depends on NF_NAT
854 select NF_NAT_REDIRECT
838 ---help--- 855 ---help---
839 REDIRECT is a special case of NAT: all incoming connections are 856 REDIRECT is a special case of NAT: all incoming connections are
840 mapped onto the incoming interface's address, causing the packets to 857 mapped onto the incoming interface's address, causing the packets to
diff --git a/net/netfilter/Makefile b/net/netfilter/Makefile
index a9571be3f791..89f73a9e9874 100644
--- a/net/netfilter/Makefile
+++ b/net/netfilter/Makefile
@@ -51,6 +51,7 @@ nf_nat-y := nf_nat_core.o nf_nat_proto_unknown.o nf_nat_proto_common.o \
51obj-$(CONFIG_NF_LOG_COMMON) += nf_log_common.o 51obj-$(CONFIG_NF_LOG_COMMON) += nf_log_common.o
52 52
53obj-$(CONFIG_NF_NAT) += nf_nat.o 53obj-$(CONFIG_NF_NAT) += nf_nat.o
54obj-$(CONFIG_NF_NAT_REDIRECT) += nf_nat_redirect.o
54 55
55# NAT protocols (nf_nat) 56# NAT protocols (nf_nat)
56obj-$(CONFIG_NF_NAT_PROTO_DCCP) += nf_nat_proto_dccp.o 57obj-$(CONFIG_NF_NAT_PROTO_DCCP) += nf_nat_proto_dccp.o
@@ -88,6 +89,7 @@ obj-$(CONFIG_NFT_HASH) += nft_hash.o
88obj-$(CONFIG_NFT_COUNTER) += nft_counter.o 89obj-$(CONFIG_NFT_COUNTER) += nft_counter.o
89obj-$(CONFIG_NFT_LOG) += nft_log.o 90obj-$(CONFIG_NFT_LOG) += nft_log.o
90obj-$(CONFIG_NFT_MASQ) += nft_masq.o 91obj-$(CONFIG_NFT_MASQ) += nft_masq.o
92obj-$(CONFIG_NFT_REDIR) += nft_redir.o
91 93
92# generic X tables 94# generic X tables
93obj-$(CONFIG_NETFILTER_XTABLES) += x_tables.o xt_tcpudp.o 95obj-$(CONFIG_NETFILTER_XTABLES) += x_tables.o xt_tcpudp.o
diff --git a/net/netfilter/core.c b/net/netfilter/core.c
index 024a2e25c8a4..fea9ef566427 100644
--- a/net/netfilter/core.c
+++ b/net/netfilter/core.c
@@ -17,6 +17,7 @@
17#include <linux/interrupt.h> 17#include <linux/interrupt.h>
18#include <linux/if.h> 18#include <linux/if.h>
19#include <linux/netdevice.h> 19#include <linux/netdevice.h>
20#include <linux/netfilter_ipv6.h>
20#include <linux/inetdevice.h> 21#include <linux/inetdevice.h>
21#include <linux/proc_fs.h> 22#include <linux/proc_fs.h>
22#include <linux/mutex.h> 23#include <linux/mutex.h>
diff --git a/net/netfilter/ipset/ip_set_hash_gen.h b/net/netfilter/ipset/ip_set_hash_gen.h
index fee7c64e4dd1..974ff386db0f 100644
--- a/net/netfilter/ipset/ip_set_hash_gen.h
+++ b/net/netfilter/ipset/ip_set_hash_gen.h
@@ -147,16 +147,22 @@ hbucket_elem_add(struct hbucket *n, u8 ahash_max, size_t dsize)
147#else 147#else
148#define __CIDR(cidr, i) (cidr) 148#define __CIDR(cidr, i) (cidr)
149#endif 149#endif
150
151/* cidr + 1 is stored in net_prefixes to support /0 */
152#define SCIDR(cidr, i) (__CIDR(cidr, i) + 1)
153
150#ifdef IP_SET_HASH_WITH_NETS_PACKED 154#ifdef IP_SET_HASH_WITH_NETS_PACKED
151/* When cidr is packed with nomatch, cidr - 1 is stored in the entry */ 155/* When cidr is packed with nomatch, cidr - 1 is stored in the data entry */
152#define CIDR(cidr, i) (__CIDR(cidr, i) + 1) 156#define GCIDR(cidr, i) (__CIDR(cidr, i) + 1)
157#define NCIDR(cidr) (cidr)
153#else 158#else
154#define CIDR(cidr, i) (__CIDR(cidr, i)) 159#define GCIDR(cidr, i) (__CIDR(cidr, i))
160#define NCIDR(cidr) (cidr - 1)
155#endif 161#endif
156 162
157#define SET_HOST_MASK(family) (family == AF_INET ? 32 : 128) 163#define SET_HOST_MASK(family) (family == AF_INET ? 32 : 128)
158 164
159#ifdef IP_SET_HASH_WITH_MULTI 165#ifdef IP_SET_HASH_WITH_NET0
160#define NLEN(family) (SET_HOST_MASK(family) + 1) 166#define NLEN(family) (SET_HOST_MASK(family) + 1)
161#else 167#else
162#define NLEN(family) SET_HOST_MASK(family) 168#define NLEN(family) SET_HOST_MASK(family)
@@ -292,24 +298,22 @@ mtype_add_cidr(struct htype *h, u8 cidr, u8 nets_length, u8 n)
292 int i, j; 298 int i, j;
293 299
294 /* Add in increasing prefix order, so larger cidr first */ 300 /* Add in increasing prefix order, so larger cidr first */
295 for (i = 0, j = -1; i < nets_length && h->nets[i].nets[n]; i++) { 301 for (i = 0, j = -1; i < nets_length && h->nets[i].cidr[n]; i++) {
296 if (j != -1) 302 if (j != -1)
297 continue; 303 continue;
298 else if (h->nets[i].cidr[n] < cidr) 304 else if (h->nets[i].cidr[n] < cidr)
299 j = i; 305 j = i;
300 else if (h->nets[i].cidr[n] == cidr) { 306 else if (h->nets[i].cidr[n] == cidr) {
301 h->nets[i].nets[n]++; 307 h->nets[cidr - 1].nets[n]++;
302 return; 308 return;
303 } 309 }
304 } 310 }
305 if (j != -1) { 311 if (j != -1) {
306 for (; i > j; i--) { 312 for (; i > j; i--)
307 h->nets[i].cidr[n] = h->nets[i - 1].cidr[n]; 313 h->nets[i].cidr[n] = h->nets[i - 1].cidr[n];
308 h->nets[i].nets[n] = h->nets[i - 1].nets[n];
309 }
310 } 314 }
311 h->nets[i].cidr[n] = cidr; 315 h->nets[i].cidr[n] = cidr;
312 h->nets[i].nets[n] = 1; 316 h->nets[cidr - 1].nets[n] = 1;
313} 317}
314 318
315static void 319static void
@@ -320,16 +324,12 @@ mtype_del_cidr(struct htype *h, u8 cidr, u8 nets_length, u8 n)
320 for (i = 0; i < nets_length; i++) { 324 for (i = 0; i < nets_length; i++) {
321 if (h->nets[i].cidr[n] != cidr) 325 if (h->nets[i].cidr[n] != cidr)
322 continue; 326 continue;
323 if (h->nets[i].nets[n] > 1 || i == net_end || 327 h->nets[cidr -1].nets[n]--;
324 h->nets[i + 1].nets[n] == 0) { 328 if (h->nets[cidr -1].nets[n] > 0)
325 h->nets[i].nets[n]--;
326 return; 329 return;
327 } 330 for (j = i; j < net_end && h->nets[j].cidr[n]; j++)
328 for (j = i; j < net_end && h->nets[j].nets[n]; j++) {
329 h->nets[j].cidr[n] = h->nets[j + 1].cidr[n]; 331 h->nets[j].cidr[n] = h->nets[j + 1].cidr[n];
330 h->nets[j].nets[n] = h->nets[j + 1].nets[n]; 332 h->nets[j].cidr[n] = 0;
331 }
332 h->nets[j].nets[n] = 0;
333 return; 333 return;
334 } 334 }
335} 335}
@@ -486,7 +486,7 @@ mtype_expire(struct ip_set *set, struct htype *h, u8 nets_length, size_t dsize)
486 pr_debug("expired %u/%u\n", i, j); 486 pr_debug("expired %u/%u\n", i, j);
487#ifdef IP_SET_HASH_WITH_NETS 487#ifdef IP_SET_HASH_WITH_NETS
488 for (k = 0; k < IPSET_NET_COUNT; k++) 488 for (k = 0; k < IPSET_NET_COUNT; k++)
489 mtype_del_cidr(h, CIDR(data->cidr, k), 489 mtype_del_cidr(h, SCIDR(data->cidr, k),
490 nets_length, k); 490 nets_length, k);
491#endif 491#endif
492 ip_set_ext_destroy(set, data); 492 ip_set_ext_destroy(set, data);
@@ -633,29 +633,6 @@ mtype_add(struct ip_set *set, void *value, const struct ip_set_ext *ext,
633 bool flag_exist = flags & IPSET_FLAG_EXIST; 633 bool flag_exist = flags & IPSET_FLAG_EXIST;
634 u32 key, multi = 0; 634 u32 key, multi = 0;
635 635
636 if (h->elements >= h->maxelem && SET_WITH_FORCEADD(set)) {
637 rcu_read_lock_bh();
638 t = rcu_dereference_bh(h->table);
639 key = HKEY(value, h->initval, t->htable_bits);
640 n = hbucket(t,key);
641 if (n->pos) {
642 /* Choosing the first entry in the array to replace */
643 j = 0;
644 goto reuse_slot;
645 }
646 rcu_read_unlock_bh();
647 }
648 if (SET_WITH_TIMEOUT(set) && h->elements >= h->maxelem)
649 /* FIXME: when set is full, we slow down here */
650 mtype_expire(set, h, NLEN(set->family), set->dsize);
651
652 if (h->elements >= h->maxelem) {
653 if (net_ratelimit())
654 pr_warn("Set %s is full, maxelem %u reached\n",
655 set->name, h->maxelem);
656 return -IPSET_ERR_HASH_FULL;
657 }
658
659 rcu_read_lock_bh(); 636 rcu_read_lock_bh();
660 t = rcu_dereference_bh(h->table); 637 t = rcu_dereference_bh(h->table);
661 key = HKEY(value, h->initval, t->htable_bits); 638 key = HKEY(value, h->initval, t->htable_bits);
@@ -680,15 +657,32 @@ mtype_add(struct ip_set *set, void *value, const struct ip_set_ext *ext,
680 j != AHASH_MAX(h) + 1) 657 j != AHASH_MAX(h) + 1)
681 j = i; 658 j = i;
682 } 659 }
660 if (h->elements >= h->maxelem && SET_WITH_FORCEADD(set) && n->pos) {
661 /* Choosing the first entry in the array to replace */
662 j = 0;
663 goto reuse_slot;
664 }
665 if (SET_WITH_TIMEOUT(set) && h->elements >= h->maxelem)
666 /* FIXME: when set is full, we slow down here */
667 mtype_expire(set, h, NLEN(set->family), set->dsize);
668
669 if (h->elements >= h->maxelem) {
670 if (net_ratelimit())
671 pr_warn("Set %s is full, maxelem %u reached\n",
672 set->name, h->maxelem);
673 ret = -IPSET_ERR_HASH_FULL;
674 goto out;
675 }
676
683reuse_slot: 677reuse_slot:
684 if (j != AHASH_MAX(h) + 1) { 678 if (j != AHASH_MAX(h) + 1) {
685 /* Fill out reused slot */ 679 /* Fill out reused slot */
686 data = ahash_data(n, j, set->dsize); 680 data = ahash_data(n, j, set->dsize);
687#ifdef IP_SET_HASH_WITH_NETS 681#ifdef IP_SET_HASH_WITH_NETS
688 for (i = 0; i < IPSET_NET_COUNT; i++) { 682 for (i = 0; i < IPSET_NET_COUNT; i++) {
689 mtype_del_cidr(h, CIDR(data->cidr, i), 683 mtype_del_cidr(h, SCIDR(data->cidr, i),
690 NLEN(set->family), i); 684 NLEN(set->family), i);
691 mtype_add_cidr(h, CIDR(d->cidr, i), 685 mtype_add_cidr(h, SCIDR(d->cidr, i),
692 NLEN(set->family), i); 686 NLEN(set->family), i);
693 } 687 }
694#endif 688#endif
@@ -705,7 +699,7 @@ reuse_slot:
705 data = ahash_data(n, n->pos++, set->dsize); 699 data = ahash_data(n, n->pos++, set->dsize);
706#ifdef IP_SET_HASH_WITH_NETS 700#ifdef IP_SET_HASH_WITH_NETS
707 for (i = 0; i < IPSET_NET_COUNT; i++) 701 for (i = 0; i < IPSET_NET_COUNT; i++)
708 mtype_add_cidr(h, CIDR(d->cidr, i), NLEN(set->family), 702 mtype_add_cidr(h, SCIDR(d->cidr, i), NLEN(set->family),
709 i); 703 i);
710#endif 704#endif
711 h->elements++; 705 h->elements++;
@@ -766,7 +760,7 @@ mtype_del(struct ip_set *set, void *value, const struct ip_set_ext *ext,
766 h->elements--; 760 h->elements--;
767#ifdef IP_SET_HASH_WITH_NETS 761#ifdef IP_SET_HASH_WITH_NETS
768 for (j = 0; j < IPSET_NET_COUNT; j++) 762 for (j = 0; j < IPSET_NET_COUNT; j++)
769 mtype_del_cidr(h, CIDR(d->cidr, j), NLEN(set->family), 763 mtype_del_cidr(h, SCIDR(d->cidr, j), NLEN(set->family),
770 j); 764 j);
771#endif 765#endif
772 ip_set_ext_destroy(set, data); 766 ip_set_ext_destroy(set, data);
@@ -827,15 +821,15 @@ mtype_test_cidrs(struct ip_set *set, struct mtype_elem *d,
827 u8 nets_length = NLEN(set->family); 821 u8 nets_length = NLEN(set->family);
828 822
829 pr_debug("test by nets\n"); 823 pr_debug("test by nets\n");
830 for (; j < nets_length && h->nets[j].nets[0] && !multi; j++) { 824 for (; j < nets_length && h->nets[j].cidr[0] && !multi; j++) {
831#if IPSET_NET_COUNT == 2 825#if IPSET_NET_COUNT == 2
832 mtype_data_reset_elem(d, &orig); 826 mtype_data_reset_elem(d, &orig);
833 mtype_data_netmask(d, h->nets[j].cidr[0], false); 827 mtype_data_netmask(d, NCIDR(h->nets[j].cidr[0]), false);
834 for (k = 0; k < nets_length && h->nets[k].nets[1] && !multi; 828 for (k = 0; k < nets_length && h->nets[k].cidr[1] && !multi;
835 k++) { 829 k++) {
836 mtype_data_netmask(d, h->nets[k].cidr[1], true); 830 mtype_data_netmask(d, NCIDR(h->nets[k].cidr[1]), true);
837#else 831#else
838 mtype_data_netmask(d, h->nets[j].cidr[0]); 832 mtype_data_netmask(d, NCIDR(h->nets[j].cidr[0]));
839#endif 833#endif
840 key = HKEY(d, h->initval, t->htable_bits); 834 key = HKEY(d, h->initval, t->htable_bits);
841 n = hbucket(t, key); 835 n = hbucket(t, key);
@@ -883,7 +877,7 @@ mtype_test(struct ip_set *set, void *value, const struct ip_set_ext *ext,
883 /* If we test an IP address and not a network address, 877 /* If we test an IP address and not a network address,
884 * try all possible network sizes */ 878 * try all possible network sizes */
885 for (i = 0; i < IPSET_NET_COUNT; i++) 879 for (i = 0; i < IPSET_NET_COUNT; i++)
886 if (CIDR(d->cidr, i) != SET_HOST_MASK(set->family)) 880 if (GCIDR(d->cidr, i) != SET_HOST_MASK(set->family))
887 break; 881 break;
888 if (i == IPSET_NET_COUNT) { 882 if (i == IPSET_NET_COUNT) {
889 ret = mtype_test_cidrs(set, d, ext, mext, flags); 883 ret = mtype_test_cidrs(set, d, ext, mext, flags);
@@ -1107,8 +1101,7 @@ IPSET_TOKEN(HTYPE, _create)(struct net *net, struct ip_set *set,
1107 1101
1108 hsize = sizeof(*h); 1102 hsize = sizeof(*h);
1109#ifdef IP_SET_HASH_WITH_NETS 1103#ifdef IP_SET_HASH_WITH_NETS
1110 hsize += sizeof(struct net_prefixes) * 1104 hsize += sizeof(struct net_prefixes) * NLEN(set->family);
1111 (set->family == NFPROTO_IPV4 ? 32 : 128);
1112#endif 1105#endif
1113 h = kzalloc(hsize, GFP_KERNEL); 1106 h = kzalloc(hsize, GFP_KERNEL);
1114 if (!h) 1107 if (!h)
diff --git a/net/netfilter/ipset/ip_set_hash_netiface.c b/net/netfilter/ipset/ip_set_hash_netiface.c
index 35dd35873442..758b002130d9 100644
--- a/net/netfilter/ipset/ip_set_hash_netiface.c
+++ b/net/netfilter/ipset/ip_set_hash_netiface.c
@@ -115,6 +115,7 @@ iface_add(struct rb_root *root, const char **iface)
115#define IP_SET_HASH_WITH_NETS 115#define IP_SET_HASH_WITH_NETS
116#define IP_SET_HASH_WITH_RBTREE 116#define IP_SET_HASH_WITH_RBTREE
117#define IP_SET_HASH_WITH_MULTI 117#define IP_SET_HASH_WITH_MULTI
118#define IP_SET_HASH_WITH_NET0
118 119
119#define STREQ(a, b) (strcmp(a, b) == 0) 120#define STREQ(a, b) (strcmp(a, b) == 0)
120 121
diff --git a/net/netfilter/ipset/ip_set_hash_netnet.c b/net/netfilter/ipset/ip_set_hash_netnet.c
index da00284b3571..ea8772afb6e7 100644
--- a/net/netfilter/ipset/ip_set_hash_netnet.c
+++ b/net/netfilter/ipset/ip_set_hash_netnet.c
@@ -46,6 +46,7 @@ struct hash_netnet4_elem {
46 __be64 ipcmp; 46 __be64 ipcmp;
47 }; 47 };
48 u8 nomatch; 48 u8 nomatch;
49 u8 padding;
49 union { 50 union {
50 u8 cidr[2]; 51 u8 cidr[2];
51 u16 ccmp; 52 u16 ccmp;
@@ -271,6 +272,7 @@ hash_netnet4_uadt(struct ip_set *set, struct nlattr *tb[],
271struct hash_netnet6_elem { 272struct hash_netnet6_elem {
272 union nf_inet_addr ip[2]; 273 union nf_inet_addr ip[2];
273 u8 nomatch; 274 u8 nomatch;
275 u8 padding;
274 union { 276 union {
275 u8 cidr[2]; 277 u8 cidr[2];
276 u16 ccmp; 278 u16 ccmp;
diff --git a/net/netfilter/ipset/ip_set_hash_netportnet.c b/net/netfilter/ipset/ip_set_hash_netportnet.c
index b8053d675fc3..bfaa94c7baa7 100644
--- a/net/netfilter/ipset/ip_set_hash_netportnet.c
+++ b/net/netfilter/ipset/ip_set_hash_netportnet.c
@@ -53,6 +53,7 @@ struct hash_netportnet4_elem {
53 u8 cidr[2]; 53 u8 cidr[2];
54 u16 ccmp; 54 u16 ccmp;
55 }; 55 };
56 u16 padding;
56 u8 nomatch:1; 57 u8 nomatch:1;
57 u8 proto; 58 u8 proto;
58}; 59};
@@ -324,6 +325,7 @@ struct hash_netportnet6_elem {
324 u8 cidr[2]; 325 u8 cidr[2];
325 u16 ccmp; 326 u16 ccmp;
326 }; 327 };
328 u16 padding;
327 u8 nomatch:1; 329 u8 nomatch:1;
328 u8 proto; 330 u8 proto;
329}; 331};
diff --git a/net/netfilter/ipvs/ip_vs_ctl.c b/net/netfilter/ipvs/ip_vs_ctl.c
index ac7ba689efe7..b8295a430a56 100644
--- a/net/netfilter/ipvs/ip_vs_ctl.c
+++ b/net/netfilter/ipvs/ip_vs_ctl.c
@@ -465,8 +465,7 @@ __ip_vs_bind_svc(struct ip_vs_dest *dest, struct ip_vs_service *svc)
465 465
466static void ip_vs_service_free(struct ip_vs_service *svc) 466static void ip_vs_service_free(struct ip_vs_service *svc)
467{ 467{
468 if (svc->stats.cpustats) 468 free_percpu(svc->stats.cpustats);
469 free_percpu(svc->stats.cpustats);
470 kfree(svc); 469 kfree(svc);
471} 470}
472 471
diff --git a/net/netfilter/ipvs/ip_vs_pe.c b/net/netfilter/ipvs/ip_vs_pe.c
index 1a82b29ce8ea..0df17caa8af6 100644
--- a/net/netfilter/ipvs/ip_vs_pe.c
+++ b/net/netfilter/ipvs/ip_vs_pe.c
@@ -37,8 +37,7 @@ struct ip_vs_pe *__ip_vs_pe_getbyname(const char *pe_name)
37 rcu_read_unlock(); 37 rcu_read_unlock();
38 return pe; 38 return pe;
39 } 39 }
40 if (pe->module) 40 module_put(pe->module);
41 module_put(pe->module);
42 } 41 }
43 rcu_read_unlock(); 42 rcu_read_unlock();
44 43
diff --git a/net/netfilter/ipvs/ip_vs_sched.c b/net/netfilter/ipvs/ip_vs_sched.c
index 4dbcda6258bc..199760c71f39 100644
--- a/net/netfilter/ipvs/ip_vs_sched.c
+++ b/net/netfilter/ipvs/ip_vs_sched.c
@@ -104,8 +104,7 @@ static struct ip_vs_scheduler *ip_vs_sched_getbyname(const char *sched_name)
104 mutex_unlock(&ip_vs_sched_mutex); 104 mutex_unlock(&ip_vs_sched_mutex);
105 return sched; 105 return sched;
106 } 106 }
107 if (sched->module) 107 module_put(sched->module);
108 module_put(sched->module);
109 } 108 }
110 109
111 mutex_unlock(&ip_vs_sched_mutex); 110 mutex_unlock(&ip_vs_sched_mutex);
diff --git a/net/netfilter/ipvs/ip_vs_sync.c b/net/netfilter/ipvs/ip_vs_sync.c
index 7162c86fd50d..c47ffd7a0a70 100644
--- a/net/netfilter/ipvs/ip_vs_sync.c
+++ b/net/netfilter/ipvs/ip_vs_sync.c
@@ -820,8 +820,7 @@ ip_vs_conn_fill_param_sync(struct net *net, int af, union ip_vs_sync_conn *sc,
820 820
821 p->pe_data = kmemdup(pe_data, pe_data_len, GFP_ATOMIC); 821 p->pe_data = kmemdup(pe_data, pe_data_len, GFP_ATOMIC);
822 if (!p->pe_data) { 822 if (!p->pe_data) {
823 if (p->pe->module) 823 module_put(p->pe->module);
824 module_put(p->pe->module);
825 return -ENOMEM; 824 return -ENOMEM;
826 } 825 }
827 p->pe_data_len = pe_data_len; 826 p->pe_data_len = pe_data_len;
diff --git a/net/netfilter/ipvs/ip_vs_xmit.c b/net/netfilter/ipvs/ip_vs_xmit.c
index bd90bf8107da..3aedbda7658a 100644
--- a/net/netfilter/ipvs/ip_vs_xmit.c
+++ b/net/netfilter/ipvs/ip_vs_xmit.c
@@ -293,7 +293,6 @@ __ip_vs_get_out_rt(int skb_af, struct sk_buff *skb, struct ip_vs_dest *dest,
293 &dest->addr.ip, &dest_dst->dst_saddr.ip, 293 &dest->addr.ip, &dest_dst->dst_saddr.ip,
294 atomic_read(&rt->dst.__refcnt)); 294 atomic_read(&rt->dst.__refcnt));
295 } 295 }
296 daddr = dest->addr.ip;
297 if (ret_saddr) 296 if (ret_saddr)
298 *ret_saddr = dest_dst->dst_saddr.ip; 297 *ret_saddr = dest_dst->dst_saddr.ip;
299 } else { 298 } else {
@@ -344,7 +343,7 @@ __ip_vs_get_out_rt(int skb_af, struct sk_buff *skb, struct ip_vs_dest *dest,
344 skb_dst_drop(skb); 343 skb_dst_drop(skb);
345 if (noref) { 344 if (noref) {
346 if (!local) 345 if (!local)
347 skb_dst_set_noref_force(skb, &rt->dst); 346 skb_dst_set_noref(skb, &rt->dst);
348 else 347 else
349 skb_dst_set(skb, dst_clone(&rt->dst)); 348 skb_dst_set(skb, dst_clone(&rt->dst));
350 } else 349 } else
@@ -488,7 +487,7 @@ __ip_vs_get_out_rt_v6(int skb_af, struct sk_buff *skb, struct ip_vs_dest *dest,
488 skb_dst_drop(skb); 487 skb_dst_drop(skb);
489 if (noref) { 488 if (noref) {
490 if (!local) 489 if (!local)
491 skb_dst_set_noref_force(skb, &rt->dst); 490 skb_dst_set_noref(skb, &rt->dst);
492 else 491 else
493 skb_dst_set(skb, dst_clone(&rt->dst)); 492 skb_dst_set(skb, dst_clone(&rt->dst));
494 } else 493 } else
diff --git a/net/netfilter/nf_conntrack_core.c b/net/netfilter/nf_conntrack_core.c
index 5016a6929085..a11674806707 100644
--- a/net/netfilter/nf_conntrack_core.c
+++ b/net/netfilter/nf_conntrack_core.c
@@ -824,22 +824,19 @@ __nf_conntrack_alloc(struct net *net, u16 zone,
824 atomic_dec(&net->ct.count); 824 atomic_dec(&net->ct.count);
825 return ERR_PTR(-ENOMEM); 825 return ERR_PTR(-ENOMEM);
826 } 826 }
827 /*
828 * Let ct->tuplehash[IP_CT_DIR_ORIGINAL].hnnode.next
829 * and ct->tuplehash[IP_CT_DIR_REPLY].hnnode.next unchanged.
830 */
831 memset(&ct->tuplehash[IP_CT_DIR_MAX], 0,
832 offsetof(struct nf_conn, proto) -
833 offsetof(struct nf_conn, tuplehash[IP_CT_DIR_MAX]));
834 spin_lock_init(&ct->lock); 827 spin_lock_init(&ct->lock);
835 ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple = *orig; 828 ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple = *orig;
836 ct->tuplehash[IP_CT_DIR_ORIGINAL].hnnode.pprev = NULL; 829 ct->tuplehash[IP_CT_DIR_ORIGINAL].hnnode.pprev = NULL;
837 ct->tuplehash[IP_CT_DIR_REPLY].tuple = *repl; 830 ct->tuplehash[IP_CT_DIR_REPLY].tuple = *repl;
838 /* save hash for reusing when confirming */ 831 /* save hash for reusing when confirming */
839 *(unsigned long *)(&ct->tuplehash[IP_CT_DIR_REPLY].hnnode.pprev) = hash; 832 *(unsigned long *)(&ct->tuplehash[IP_CT_DIR_REPLY].hnnode.pprev) = hash;
833 ct->status = 0;
840 /* Don't set timer yet: wait for confirmation */ 834 /* Don't set timer yet: wait for confirmation */
841 setup_timer(&ct->timeout, death_by_timeout, (unsigned long)ct); 835 setup_timer(&ct->timeout, death_by_timeout, (unsigned long)ct);
842 write_pnet(&ct->ct_net, net); 836 write_pnet(&ct->ct_net, net);
837 memset(&ct->__nfct_init_offset[0], 0,
838 offsetof(struct nf_conn, proto) -
839 offsetof(struct nf_conn, __nfct_init_offset[0]));
843#ifdef CONFIG_NF_CONNTRACK_ZONES 840#ifdef CONFIG_NF_CONNTRACK_ZONES
844 if (zone) { 841 if (zone) {
845 struct nf_conntrack_zone *nf_ct_zone; 842 struct nf_conntrack_zone *nf_ct_zone;
diff --git a/net/netfilter/nf_conntrack_h323_main.c b/net/netfilter/nf_conntrack_h323_main.c
index 3a3a60b126e0..1d69f5b9748f 100644
--- a/net/netfilter/nf_conntrack_h323_main.c
+++ b/net/netfilter/nf_conntrack_h323_main.c
@@ -728,7 +728,8 @@ static int expect_h245(struct sk_buff *skb, struct nf_conn *ct,
728 728
729/* If the calling party is on the same side of the forward-to party, 729/* If the calling party is on the same side of the forward-to party,
730 * we don't need to track the second call */ 730 * we don't need to track the second call */
731static int callforward_do_filter(const union nf_inet_addr *src, 731static int callforward_do_filter(struct net *net,
732 const union nf_inet_addr *src,
732 const union nf_inet_addr *dst, 733 const union nf_inet_addr *dst,
733 u_int8_t family) 734 u_int8_t family)
734{ 735{
@@ -750,9 +751,9 @@ static int callforward_do_filter(const union nf_inet_addr *src,
750 751
751 memset(&fl2, 0, sizeof(fl2)); 752 memset(&fl2, 0, sizeof(fl2));
752 fl2.daddr = dst->ip; 753 fl2.daddr = dst->ip;
753 if (!afinfo->route(&init_net, (struct dst_entry **)&rt1, 754 if (!afinfo->route(net, (struct dst_entry **)&rt1,
754 flowi4_to_flowi(&fl1), false)) { 755 flowi4_to_flowi(&fl1), false)) {
755 if (!afinfo->route(&init_net, (struct dst_entry **)&rt2, 756 if (!afinfo->route(net, (struct dst_entry **)&rt2,
756 flowi4_to_flowi(&fl2), false)) { 757 flowi4_to_flowi(&fl2), false)) {
757 if (rt_nexthop(rt1, fl1.daddr) == 758 if (rt_nexthop(rt1, fl1.daddr) ==
758 rt_nexthop(rt2, fl2.daddr) && 759 rt_nexthop(rt2, fl2.daddr) &&
@@ -774,9 +775,9 @@ static int callforward_do_filter(const union nf_inet_addr *src,
774 775
775 memset(&fl2, 0, sizeof(fl2)); 776 memset(&fl2, 0, sizeof(fl2));
776 fl2.daddr = dst->in6; 777 fl2.daddr = dst->in6;
777 if (!afinfo->route(&init_net, (struct dst_entry **)&rt1, 778 if (!afinfo->route(net, (struct dst_entry **)&rt1,
778 flowi6_to_flowi(&fl1), false)) { 779 flowi6_to_flowi(&fl1), false)) {
779 if (!afinfo->route(&init_net, (struct dst_entry **)&rt2, 780 if (!afinfo->route(net, (struct dst_entry **)&rt2,
780 flowi6_to_flowi(&fl2), false)) { 781 flowi6_to_flowi(&fl2), false)) {
781 if (ipv6_addr_equal(rt6_nexthop(rt1), 782 if (ipv6_addr_equal(rt6_nexthop(rt1),
782 rt6_nexthop(rt2)) && 783 rt6_nexthop(rt2)) &&
@@ -807,6 +808,7 @@ static int expect_callforwarding(struct sk_buff *skb,
807 __be16 port; 808 __be16 port;
808 union nf_inet_addr addr; 809 union nf_inet_addr addr;
809 struct nf_conntrack_expect *exp; 810 struct nf_conntrack_expect *exp;
811 struct net *net = nf_ct_net(ct);
810 typeof(nat_callforwarding_hook) nat_callforwarding; 812 typeof(nat_callforwarding_hook) nat_callforwarding;
811 813
812 /* Read alternativeAddress */ 814 /* Read alternativeAddress */
@@ -816,7 +818,7 @@ static int expect_callforwarding(struct sk_buff *skb,
816 /* If the calling party is on the same side of the forward-to party, 818 /* If the calling party is on the same side of the forward-to party,
817 * we don't need to track the second call */ 819 * we don't need to track the second call */
818 if (callforward_filter && 820 if (callforward_filter &&
819 callforward_do_filter(&addr, &ct->tuplehash[!dir].tuple.src.u3, 821 callforward_do_filter(net, &addr, &ct->tuplehash[!dir].tuple.src.u3,
820 nf_ct_l3num(ct))) { 822 nf_ct_l3num(ct))) {
821 pr_debug("nf_ct_q931: Call Forwarding not tracked\n"); 823 pr_debug("nf_ct_q931: Call Forwarding not tracked\n");
822 return 0; 824 return 0;
diff --git a/net/netfilter/nf_conntrack_helper.c b/net/netfilter/nf_conntrack_helper.c
index 5b3eae7d4c9a..bd9d31537905 100644
--- a/net/netfilter/nf_conntrack_helper.c
+++ b/net/netfilter/nf_conntrack_helper.c
@@ -250,7 +250,7 @@ out:
250} 250}
251EXPORT_SYMBOL_GPL(__nf_ct_try_assign_helper); 251EXPORT_SYMBOL_GPL(__nf_ct_try_assign_helper);
252 252
253/* appropiate ct lock protecting must be taken by caller */ 253/* appropriate ct lock protecting must be taken by caller */
254static inline int unhelp(struct nf_conntrack_tuple_hash *i, 254static inline int unhelp(struct nf_conntrack_tuple_hash *i,
255 const struct nf_conntrack_helper *me) 255 const struct nf_conntrack_helper *me)
256{ 256{
diff --git a/net/netfilter/nf_log.c b/net/netfilter/nf_log.c
index 6e3b9117db1f..43c926cae9c0 100644
--- a/net/netfilter/nf_log.c
+++ b/net/netfilter/nf_log.c
@@ -19,6 +19,9 @@
19static struct nf_logger __rcu *loggers[NFPROTO_NUMPROTO][NF_LOG_TYPE_MAX] __read_mostly; 19static struct nf_logger __rcu *loggers[NFPROTO_NUMPROTO][NF_LOG_TYPE_MAX] __read_mostly;
20static DEFINE_MUTEX(nf_log_mutex); 20static DEFINE_MUTEX(nf_log_mutex);
21 21
22#define nft_log_dereference(logger) \
23 rcu_dereference_protected(logger, lockdep_is_held(&nf_log_mutex))
24
22static struct nf_logger *__find_logger(int pf, const char *str_logger) 25static struct nf_logger *__find_logger(int pf, const char *str_logger)
23{ 26{
24 struct nf_logger *log; 27 struct nf_logger *log;
@@ -28,8 +31,7 @@ static struct nf_logger *__find_logger(int pf, const char *str_logger)
28 if (loggers[pf][i] == NULL) 31 if (loggers[pf][i] == NULL)
29 continue; 32 continue;
30 33
31 log = rcu_dereference_protected(loggers[pf][i], 34 log = nft_log_dereference(loggers[pf][i]);
32 lockdep_is_held(&nf_log_mutex));
33 if (!strncasecmp(str_logger, log->name, strlen(log->name))) 35 if (!strncasecmp(str_logger, log->name, strlen(log->name)))
34 return log; 36 return log;
35 } 37 }
@@ -45,8 +47,7 @@ void nf_log_set(struct net *net, u_int8_t pf, const struct nf_logger *logger)
45 return; 47 return;
46 48
47 mutex_lock(&nf_log_mutex); 49 mutex_lock(&nf_log_mutex);
48 log = rcu_dereference_protected(net->nf.nf_loggers[pf], 50 log = nft_log_dereference(net->nf.nf_loggers[pf]);
49 lockdep_is_held(&nf_log_mutex));
50 if (log == NULL) 51 if (log == NULL)
51 rcu_assign_pointer(net->nf.nf_loggers[pf], logger); 52 rcu_assign_pointer(net->nf.nf_loggers[pf], logger);
52 53
@@ -61,8 +62,7 @@ void nf_log_unset(struct net *net, const struct nf_logger *logger)
61 62
62 mutex_lock(&nf_log_mutex); 63 mutex_lock(&nf_log_mutex);
63 for (i = 0; i < NFPROTO_NUMPROTO; i++) { 64 for (i = 0; i < NFPROTO_NUMPROTO; i++) {
64 log = rcu_dereference_protected(net->nf.nf_loggers[i], 65 log = nft_log_dereference(net->nf.nf_loggers[i]);
65 lockdep_is_held(&nf_log_mutex));
66 if (log == logger) 66 if (log == logger)
67 RCU_INIT_POINTER(net->nf.nf_loggers[i], NULL); 67 RCU_INIT_POINTER(net->nf.nf_loggers[i], NULL);
68 } 68 }
@@ -75,6 +75,7 @@ EXPORT_SYMBOL(nf_log_unset);
75int nf_log_register(u_int8_t pf, struct nf_logger *logger) 75int nf_log_register(u_int8_t pf, struct nf_logger *logger)
76{ 76{
77 int i; 77 int i;
78 int ret = 0;
78 79
79 if (pf >= ARRAY_SIZE(init_net.nf.nf_loggers)) 80 if (pf >= ARRAY_SIZE(init_net.nf.nf_loggers))
80 return -EINVAL; 81 return -EINVAL;
@@ -82,16 +83,25 @@ int nf_log_register(u_int8_t pf, struct nf_logger *logger)
82 mutex_lock(&nf_log_mutex); 83 mutex_lock(&nf_log_mutex);
83 84
84 if (pf == NFPROTO_UNSPEC) { 85 if (pf == NFPROTO_UNSPEC) {
86 for (i = NFPROTO_UNSPEC; i < NFPROTO_NUMPROTO; i++) {
87 if (rcu_access_pointer(loggers[i][logger->type])) {
88 ret = -EEXIST;
89 goto unlock;
90 }
91 }
85 for (i = NFPROTO_UNSPEC; i < NFPROTO_NUMPROTO; i++) 92 for (i = NFPROTO_UNSPEC; i < NFPROTO_NUMPROTO; i++)
86 rcu_assign_pointer(loggers[i][logger->type], logger); 93 rcu_assign_pointer(loggers[i][logger->type], logger);
87 } else { 94 } else {
88 /* register at end of list to honor first register win */ 95 if (rcu_access_pointer(loggers[pf][logger->type])) {
96 ret = -EEXIST;
97 goto unlock;
98 }
89 rcu_assign_pointer(loggers[pf][logger->type], logger); 99 rcu_assign_pointer(loggers[pf][logger->type], logger);
90 } 100 }
91 101
102unlock:
92 mutex_unlock(&nf_log_mutex); 103 mutex_unlock(&nf_log_mutex);
93 104 return ret;
94 return 0;
95} 105}
96EXPORT_SYMBOL(nf_log_register); 106EXPORT_SYMBOL(nf_log_register);
97 107
@@ -144,8 +154,7 @@ int nf_logger_find_get(int pf, enum nf_log_type type)
144 struct nf_logger *logger; 154 struct nf_logger *logger;
145 int ret = -ENOENT; 155 int ret = -ENOENT;
146 156
147 logger = loggers[pf][type]; 157 if (rcu_access_pointer(loggers[pf][type]) == NULL)
148 if (logger == NULL)
149 request_module("nf-logger-%u-%u", pf, type); 158 request_module("nf-logger-%u-%u", pf, type);
150 159
151 rcu_read_lock(); 160 rcu_read_lock();
@@ -297,8 +306,7 @@ static int seq_show(struct seq_file *s, void *v)
297 int i; 306 int i;
298 struct net *net = seq_file_net(s); 307 struct net *net = seq_file_net(s);
299 308
300 logger = rcu_dereference_protected(net->nf.nf_loggers[*pos], 309 logger = nft_log_dereference(net->nf.nf_loggers[*pos]);
301 lockdep_is_held(&nf_log_mutex));
302 310
303 if (!logger) 311 if (!logger)
304 seq_printf(s, "%2lld NONE (", *pos); 312 seq_printf(s, "%2lld NONE (", *pos);
@@ -312,8 +320,7 @@ static int seq_show(struct seq_file *s, void *v)
312 if (loggers[*pos][i] == NULL) 320 if (loggers[*pos][i] == NULL)
313 continue; 321 continue;
314 322
315 logger = rcu_dereference_protected(loggers[*pos][i], 323 logger = nft_log_dereference(loggers[*pos][i]);
316 lockdep_is_held(&nf_log_mutex));
317 seq_printf(s, "%s", logger->name); 324 seq_printf(s, "%s", logger->name);
318 if (i == 0 && loggers[*pos][i + 1] != NULL) 325 if (i == 0 && loggers[*pos][i + 1] != NULL)
319 seq_printf(s, ","); 326 seq_printf(s, ",");
@@ -387,8 +394,7 @@ static int nf_log_proc_dostring(struct ctl_table *table, int write,
387 mutex_unlock(&nf_log_mutex); 394 mutex_unlock(&nf_log_mutex);
388 } else { 395 } else {
389 mutex_lock(&nf_log_mutex); 396 mutex_lock(&nf_log_mutex);
390 logger = rcu_dereference_protected(net->nf.nf_loggers[tindex], 397 logger = nft_log_dereference(net->nf.nf_loggers[tindex]);
391 lockdep_is_held(&nf_log_mutex));
392 if (!logger) 398 if (!logger)
393 table->data = "NONE"; 399 table->data = "NONE";
394 else 400 else
diff --git a/net/netfilter/nf_nat_redirect.c b/net/netfilter/nf_nat_redirect.c
new file mode 100644
index 000000000000..97b75f9bfbcd
--- /dev/null
+++ b/net/netfilter/nf_nat_redirect.c
@@ -0,0 +1,127 @@
1/*
2 * (C) 1999-2001 Paul `Rusty' Russell
3 * (C) 2002-2006 Netfilter Core Team <coreteam@netfilter.org>
4 * Copyright (c) 2011 Patrick McHardy <kaber@trash.net>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
9 *
10 * Based on Rusty Russell's IPv4 REDIRECT target. Development of IPv6
11 * NAT funded by Astaro.
12 */
13
14#include <linux/if.h>
15#include <linux/inetdevice.h>
16#include <linux/ip.h>
17#include <linux/kernel.h>
18#include <linux/module.h>
19#include <linux/netdevice.h>
20#include <linux/netfilter.h>
21#include <linux/types.h>
22#include <linux/netfilter_ipv4.h>
23#include <linux/netfilter_ipv6.h>
24#include <linux/netfilter/x_tables.h>
25#include <net/addrconf.h>
26#include <net/checksum.h>
27#include <net/protocol.h>
28#include <net/netfilter/nf_nat.h>
29#include <net/netfilter/nf_nat_redirect.h>
30
31unsigned int
32nf_nat_redirect_ipv4(struct sk_buff *skb,
33 const struct nf_nat_ipv4_multi_range_compat *mr,
34 unsigned int hooknum)
35{
36 struct nf_conn *ct;
37 enum ip_conntrack_info ctinfo;
38 __be32 newdst;
39 struct nf_nat_range newrange;
40
41 NF_CT_ASSERT(hooknum == NF_INET_PRE_ROUTING ||
42 hooknum == NF_INET_LOCAL_OUT);
43
44 ct = nf_ct_get(skb, &ctinfo);
45 NF_CT_ASSERT(ct && (ctinfo == IP_CT_NEW || ctinfo == IP_CT_RELATED));
46
47 /* Local packets: make them go to loopback */
48 if (hooknum == NF_INET_LOCAL_OUT) {
49 newdst = htonl(0x7F000001);
50 } else {
51 struct in_device *indev;
52 struct in_ifaddr *ifa;
53
54 newdst = 0;
55
56 rcu_read_lock();
57 indev = __in_dev_get_rcu(skb->dev);
58 if (indev != NULL) {
59 ifa = indev->ifa_list;
60 newdst = ifa->ifa_local;
61 }
62 rcu_read_unlock();
63
64 if (!newdst)
65 return NF_DROP;
66 }
67
68 /* Transfer from original range. */
69 memset(&newrange.min_addr, 0, sizeof(newrange.min_addr));
70 memset(&newrange.max_addr, 0, sizeof(newrange.max_addr));
71 newrange.flags = mr->range[0].flags | NF_NAT_RANGE_MAP_IPS;
72 newrange.min_addr.ip = newdst;
73 newrange.max_addr.ip = newdst;
74 newrange.min_proto = mr->range[0].min;
75 newrange.max_proto = mr->range[0].max;
76
77 /* Hand modified range to generic setup. */
78 return nf_nat_setup_info(ct, &newrange, NF_NAT_MANIP_DST);
79}
80EXPORT_SYMBOL_GPL(nf_nat_redirect_ipv4);
81
82static const struct in6_addr loopback_addr = IN6ADDR_LOOPBACK_INIT;
83
84unsigned int
85nf_nat_redirect_ipv6(struct sk_buff *skb, const struct nf_nat_range *range,
86 unsigned int hooknum)
87{
88 struct nf_nat_range newrange;
89 struct in6_addr newdst;
90 enum ip_conntrack_info ctinfo;
91 struct nf_conn *ct;
92
93 ct = nf_ct_get(skb, &ctinfo);
94 if (hooknum == NF_INET_LOCAL_OUT) {
95 newdst = loopback_addr;
96 } else {
97 struct inet6_dev *idev;
98 struct inet6_ifaddr *ifa;
99 bool addr = false;
100
101 rcu_read_lock();
102 idev = __in6_dev_get(skb->dev);
103 if (idev != NULL) {
104 list_for_each_entry(ifa, &idev->addr_list, if_list) {
105 newdst = ifa->addr;
106 addr = true;
107 break;
108 }
109 }
110 rcu_read_unlock();
111
112 if (!addr)
113 return NF_DROP;
114 }
115
116 newrange.flags = range->flags | NF_NAT_RANGE_MAP_IPS;
117 newrange.min_addr.in6 = newdst;
118 newrange.max_addr.in6 = newdst;
119 newrange.min_proto = range->min_proto;
120 newrange.max_proto = range->max_proto;
121
122 return nf_nat_setup_info(ct, &newrange, NF_NAT_MANIP_DST);
123}
124EXPORT_SYMBOL_GPL(nf_nat_redirect_ipv6);
125
126MODULE_LICENSE("GPL");
127MODULE_AUTHOR("Patrick McHardy <kaber@trash.net>");
diff --git a/net/netfilter/nf_tables_api.c b/net/netfilter/nf_tables_api.c
index 66e8425dbfe7..129a8daa4abf 100644
--- a/net/netfilter/nf_tables_api.c
+++ b/net/netfilter/nf_tables_api.c
@@ -2477,7 +2477,7 @@ static int nf_tables_getset(struct sock *nlsk, struct sk_buff *skb,
2477 const struct nfgenmsg *nfmsg = nlmsg_data(nlh); 2477 const struct nfgenmsg *nfmsg = nlmsg_data(nlh);
2478 int err; 2478 int err;
2479 2479
2480 /* Verify existance before starting dump */ 2480 /* Verify existence before starting dump */
2481 err = nft_ctx_init_from_setattr(&ctx, skb, nlh, nla); 2481 err = nft_ctx_init_from_setattr(&ctx, skb, nlh, nla);
2482 if (err < 0) 2482 if (err < 0)
2483 return err; 2483 return err;
@@ -3665,8 +3665,7 @@ static int nf_tables_abort(struct sk_buff *skb)
3665 break; 3665 break;
3666 case NFT_MSG_NEWCHAIN: 3666 case NFT_MSG_NEWCHAIN:
3667 if (nft_trans_chain_update(trans)) { 3667 if (nft_trans_chain_update(trans)) {
3668 if (nft_trans_chain_stats(trans)) 3668 free_percpu(nft_trans_chain_stats(trans));
3669 free_percpu(nft_trans_chain_stats(trans));
3670 3669
3671 nft_trans_destroy(trans); 3670 nft_trans_destroy(trans);
3672 } else { 3671 } else {
diff --git a/net/netfilter/nfnetlink_log.c b/net/netfilter/nfnetlink_log.c
index 5f1be5ba3559..11d85b3813f2 100644
--- a/net/netfilter/nfnetlink_log.c
+++ b/net/netfilter/nfnetlink_log.c
@@ -12,6 +12,9 @@
12 * it under the terms of the GNU General Public License version 2 as 12 * it under the terms of the GNU General Public License version 2 as
13 * published by the Free Software Foundation. 13 * published by the Free Software Foundation.
14 */ 14 */
15
16#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
17
15#include <linux/module.h> 18#include <linux/module.h>
16#include <linux/skbuff.h> 19#include <linux/skbuff.h>
17#include <linux/if_arp.h> 20#include <linux/if_arp.h>
@@ -337,9 +340,6 @@ nfulnl_alloc_skb(struct net *net, u32 peer_portid, unsigned int inst_size,
337 340
338 skb = nfnetlink_alloc_skb(net, pkt_size, 341 skb = nfnetlink_alloc_skb(net, pkt_size,
339 peer_portid, GFP_ATOMIC); 342 peer_portid, GFP_ATOMIC);
340 if (!skb)
341 pr_err("nfnetlink_log: can't even alloc %u bytes\n",
342 pkt_size);
343 } 343 }
344 } 344 }
345 345
@@ -570,10 +570,8 @@ __build_packet_message(struct nfnl_log_net *log,
570 struct nlattr *nla; 570 struct nlattr *nla;
571 int size = nla_attr_size(data_len); 571 int size = nla_attr_size(data_len);
572 572
573 if (skb_tailroom(inst->skb) < nla_total_size(data_len)) { 573 if (skb_tailroom(inst->skb) < nla_total_size(data_len))
574 printk(KERN_WARNING "nfnetlink_log: no tailroom!\n"); 574 goto nla_put_failure;
575 return -1;
576 }
577 575
578 nla = (struct nlattr *)skb_put(inst->skb, nla_total_size(data_len)); 576 nla = (struct nlattr *)skb_put(inst->skb, nla_total_size(data_len));
579 nla->nla_type = NFULA_PAYLOAD; 577 nla->nla_type = NFULA_PAYLOAD;
@@ -1069,19 +1067,19 @@ static int __init nfnetlink_log_init(void)
1069 netlink_register_notifier(&nfulnl_rtnl_notifier); 1067 netlink_register_notifier(&nfulnl_rtnl_notifier);
1070 status = nfnetlink_subsys_register(&nfulnl_subsys); 1068 status = nfnetlink_subsys_register(&nfulnl_subsys);
1071 if (status < 0) { 1069 if (status < 0) {
1072 pr_err("log: failed to create netlink socket\n"); 1070 pr_err("failed to create netlink socket\n");
1073 goto cleanup_netlink_notifier; 1071 goto cleanup_netlink_notifier;
1074 } 1072 }
1075 1073
1076 status = nf_log_register(NFPROTO_UNSPEC, &nfulnl_logger); 1074 status = nf_log_register(NFPROTO_UNSPEC, &nfulnl_logger);
1077 if (status < 0) { 1075 if (status < 0) {
1078 pr_err("log: failed to register logger\n"); 1076 pr_err("failed to register logger\n");
1079 goto cleanup_subsys; 1077 goto cleanup_subsys;
1080 } 1078 }
1081 1079
1082 status = register_pernet_subsys(&nfnl_log_net_ops); 1080 status = register_pernet_subsys(&nfnl_log_net_ops);
1083 if (status < 0) { 1081 if (status < 0) {
1084 pr_err("log: failed to register pernet ops\n"); 1082 pr_err("failed to register pernet ops\n");
1085 goto cleanup_logger; 1083 goto cleanup_logger;
1086 } 1084 }
1087 return status; 1085 return status;
diff --git a/net/netfilter/nft_hash.c b/net/netfilter/nft_hash.c
index 8892b7b6184a..1e316ce4cb5d 100644
--- a/net/netfilter/nft_hash.c
+++ b/net/netfilter/nft_hash.c
@@ -65,7 +65,7 @@ static int nft_hash_insert(const struct nft_set *set,
65 if (set->flags & NFT_SET_MAP) 65 if (set->flags & NFT_SET_MAP)
66 nft_data_copy(he->data, &elem->data); 66 nft_data_copy(he->data, &elem->data);
67 67
68 rhashtable_insert(priv, &he->node, GFP_KERNEL); 68 rhashtable_insert(priv, &he->node);
69 69
70 return 0; 70 return 0;
71} 71}
@@ -88,7 +88,7 @@ static void nft_hash_remove(const struct nft_set *set,
88 pprev = elem->cookie; 88 pprev = elem->cookie;
89 he = rht_dereference((*pprev), priv); 89 he = rht_dereference((*pprev), priv);
90 90
91 rhashtable_remove_pprev(priv, he, pprev, GFP_KERNEL); 91 rhashtable_remove_pprev(priv, he, pprev);
92 92
93 synchronize_rcu(); 93 synchronize_rcu();
94 kfree(he); 94 kfree(he);
@@ -153,10 +153,12 @@ static unsigned int nft_hash_privsize(const struct nlattr * const nla[])
153 return sizeof(struct rhashtable); 153 return sizeof(struct rhashtable);
154} 154}
155 155
156static int lockdep_nfnl_lock_is_held(void) 156#ifdef CONFIG_PROVE_LOCKING
157static int lockdep_nfnl_lock_is_held(void *parent)
157{ 158{
158 return lockdep_nfnl_is_held(NFNL_SUBSYS_NFTABLES); 159 return lockdep_nfnl_is_held(NFNL_SUBSYS_NFTABLES);
159} 160}
161#endif
160 162
161static int nft_hash_init(const struct nft_set *set, 163static int nft_hash_init(const struct nft_set *set,
162 const struct nft_set_desc *desc, 164 const struct nft_set_desc *desc,
@@ -171,7 +173,9 @@ static int nft_hash_init(const struct nft_set *set,
171 .hashfn = jhash, 173 .hashfn = jhash,
172 .grow_decision = rht_grow_above_75, 174 .grow_decision = rht_grow_above_75,
173 .shrink_decision = rht_shrink_below_30, 175 .shrink_decision = rht_shrink_below_30,
176#ifdef CONFIG_PROVE_LOCKING
174 .mutex_is_held = lockdep_nfnl_lock_is_held, 177 .mutex_is_held = lockdep_nfnl_lock_is_held,
178#endif
175 }; 179 };
176 180
177 return rhashtable_init(priv, &params); 181 return rhashtable_init(priv, &params);
diff --git a/net/netfilter/nft_meta.c b/net/netfilter/nft_meta.c
index 1e7c076ca63a..e99911eda915 100644
--- a/net/netfilter/nft_meta.c
+++ b/net/netfilter/nft_meta.c
@@ -165,6 +165,12 @@ void nft_meta_get_eval(const struct nft_expr *expr,
165 goto err; 165 goto err;
166 dest->data[0] = out->group; 166 dest->data[0] = out->group;
167 break; 167 break;
168 case NFT_META_CGROUP:
169 if (skb->sk == NULL)
170 break;
171
172 dest->data[0] = skb->sk->sk_classid;
173 break;
168 default: 174 default:
169 WARN_ON(1); 175 WARN_ON(1);
170 goto err; 176 goto err;
@@ -240,6 +246,7 @@ int nft_meta_get_init(const struct nft_ctx *ctx,
240 case NFT_META_CPU: 246 case NFT_META_CPU:
241 case NFT_META_IIFGROUP: 247 case NFT_META_IIFGROUP:
242 case NFT_META_OIFGROUP: 248 case NFT_META_OIFGROUP:
249 case NFT_META_CGROUP:
243 break; 250 break;
244 default: 251 default:
245 return -EOPNOTSUPP; 252 return -EOPNOTSUPP;
diff --git a/net/netfilter/nft_redir.c b/net/netfilter/nft_redir.c
new file mode 100644
index 000000000000..9e8093f28311
--- /dev/null
+++ b/net/netfilter/nft_redir.c
@@ -0,0 +1,99 @@
1/*
2 * Copyright (c) 2014 Arturo Borrero Gonzalez <arturo.borrero.glez@gmail.com>
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 as
6 * published by the Free Software Foundation.
7 */
8
9#include <linux/kernel.h>
10#include <linux/init.h>
11#include <linux/module.h>
12#include <linux/netlink.h>
13#include <linux/netfilter.h>
14#include <linux/netfilter/nf_tables.h>
15#include <net/netfilter/nf_nat.h>
16#include <net/netfilter/nf_tables.h>
17#include <net/netfilter/nft_redir.h>
18
19const struct nla_policy nft_redir_policy[NFTA_REDIR_MAX + 1] = {
20 [NFTA_REDIR_REG_PROTO_MIN] = { .type = NLA_U32 },
21 [NFTA_REDIR_REG_PROTO_MAX] = { .type = NLA_U32 },
22 [NFTA_REDIR_FLAGS] = { .type = NLA_U32 },
23};
24EXPORT_SYMBOL_GPL(nft_redir_policy);
25
26int nft_redir_init(const struct nft_ctx *ctx,
27 const struct nft_expr *expr,
28 const struct nlattr * const tb[])
29{
30 struct nft_redir *priv = nft_expr_priv(expr);
31 int err;
32
33 err = nft_chain_validate_dependency(ctx->chain, NFT_CHAIN_T_NAT);
34 if (err < 0)
35 return err;
36
37 if (tb[NFTA_REDIR_REG_PROTO_MIN]) {
38 priv->sreg_proto_min =
39 ntohl(nla_get_be32(tb[NFTA_REDIR_REG_PROTO_MIN]));
40
41 err = nft_validate_input_register(priv->sreg_proto_min);
42 if (err < 0)
43 return err;
44
45 if (tb[NFTA_REDIR_REG_PROTO_MAX]) {
46 priv->sreg_proto_max =
47 ntohl(nla_get_be32(tb[NFTA_REDIR_REG_PROTO_MAX]));
48
49 err = nft_validate_input_register(priv->sreg_proto_max);
50 if (err < 0)
51 return err;
52 } else {
53 priv->sreg_proto_max = priv->sreg_proto_min;
54 }
55 }
56
57 if (tb[NFTA_REDIR_FLAGS]) {
58 priv->flags = ntohl(nla_get_be32(tb[NFTA_REDIR_FLAGS]));
59 if (priv->flags & ~NF_NAT_RANGE_MASK)
60 return -EINVAL;
61 }
62
63 return 0;
64}
65EXPORT_SYMBOL_GPL(nft_redir_init);
66
67int nft_redir_dump(struct sk_buff *skb, const struct nft_expr *expr)
68{
69 const struct nft_redir *priv = nft_expr_priv(expr);
70
71 if (priv->sreg_proto_min) {
72 if (nla_put_be32(skb, NFTA_REDIR_REG_PROTO_MIN,
73 htonl(priv->sreg_proto_min)))
74 goto nla_put_failure;
75 if (nla_put_be32(skb, NFTA_REDIR_REG_PROTO_MAX,
76 htonl(priv->sreg_proto_max)))
77 goto nla_put_failure;
78 }
79
80 if (priv->flags != 0 &&
81 nla_put_be32(skb, NFTA_REDIR_FLAGS, htonl(priv->flags)))
82 goto nla_put_failure;
83
84 return 0;
85
86nla_put_failure:
87 return -1;
88}
89EXPORT_SYMBOL_GPL(nft_redir_dump);
90
91int nft_redir_validate(const struct nft_ctx *ctx, const struct nft_expr *expr,
92 const struct nft_data **data)
93{
94 return nft_chain_validate_dependency(ctx->chain, NFT_CHAIN_T_NAT);
95}
96EXPORT_SYMBOL_GPL(nft_redir_validate);
97
98MODULE_LICENSE("GPL");
99MODULE_AUTHOR("Arturo Borrero Gonzalez <arturo.borrero.glez@gmail.com>");
diff --git a/net/netfilter/xt_DSCP.c b/net/netfilter/xt_DSCP.c
index ae8271652efa..3f83d38c4e5b 100644
--- a/net/netfilter/xt_DSCP.c
+++ b/net/netfilter/xt_DSCP.c
@@ -37,7 +37,8 @@ dscp_tg(struct sk_buff *skb, const struct xt_action_param *par)
37 if (!skb_make_writable(skb, sizeof(struct iphdr))) 37 if (!skb_make_writable(skb, sizeof(struct iphdr)))
38 return NF_DROP; 38 return NF_DROP;
39 39
40 ipv4_change_dsfield(ip_hdr(skb), (__u8)(~XT_DSCP_MASK), 40 ipv4_change_dsfield(ip_hdr(skb),
41 (__force __u8)(~XT_DSCP_MASK),
41 dinfo->dscp << XT_DSCP_SHIFT); 42 dinfo->dscp << XT_DSCP_SHIFT);
42 43
43 } 44 }
@@ -54,7 +55,8 @@ dscp_tg6(struct sk_buff *skb, const struct xt_action_param *par)
54 if (!skb_make_writable(skb, sizeof(struct ipv6hdr))) 55 if (!skb_make_writable(skb, sizeof(struct ipv6hdr)))
55 return NF_DROP; 56 return NF_DROP;
56 57
57 ipv6_change_dsfield(ipv6_hdr(skb), (__u8)(~XT_DSCP_MASK), 58 ipv6_change_dsfield(ipv6_hdr(skb),
59 (__force __u8)(~XT_DSCP_MASK),
58 dinfo->dscp << XT_DSCP_SHIFT); 60 dinfo->dscp << XT_DSCP_SHIFT);
59 } 61 }
60 return XT_CONTINUE; 62 return XT_CONTINUE;
diff --git a/net/netfilter/xt_REDIRECT.c b/net/netfilter/xt_REDIRECT.c
index 22a10309297c..03f0b370e178 100644
--- a/net/netfilter/xt_REDIRECT.c
+++ b/net/netfilter/xt_REDIRECT.c
@@ -26,48 +26,12 @@
26#include <net/checksum.h> 26#include <net/checksum.h>
27#include <net/protocol.h> 27#include <net/protocol.h>
28#include <net/netfilter/nf_nat.h> 28#include <net/netfilter/nf_nat.h>
29 29#include <net/netfilter/nf_nat_redirect.h>
30static const struct in6_addr loopback_addr = IN6ADDR_LOOPBACK_INIT;
31 30
32static unsigned int 31static unsigned int
33redirect_tg6(struct sk_buff *skb, const struct xt_action_param *par) 32redirect_tg6(struct sk_buff *skb, const struct xt_action_param *par)
34{ 33{
35 const struct nf_nat_range *range = par->targinfo; 34 return nf_nat_redirect_ipv6(skb, par->targinfo, par->hooknum);
36 struct nf_nat_range newrange;
37 struct in6_addr newdst;
38 enum ip_conntrack_info ctinfo;
39 struct nf_conn *ct;
40
41 ct = nf_ct_get(skb, &ctinfo);
42 if (par->hooknum == NF_INET_LOCAL_OUT)
43 newdst = loopback_addr;
44 else {
45 struct inet6_dev *idev;
46 struct inet6_ifaddr *ifa;
47 bool addr = false;
48
49 rcu_read_lock();
50 idev = __in6_dev_get(skb->dev);
51 if (idev != NULL) {
52 list_for_each_entry(ifa, &idev->addr_list, if_list) {
53 newdst = ifa->addr;
54 addr = true;
55 break;
56 }
57 }
58 rcu_read_unlock();
59
60 if (!addr)
61 return NF_DROP;
62 }
63
64 newrange.flags = range->flags | NF_NAT_RANGE_MAP_IPS;
65 newrange.min_addr.in6 = newdst;
66 newrange.max_addr.in6 = newdst;
67 newrange.min_proto = range->min_proto;
68 newrange.max_proto = range->max_proto;
69
70 return nf_nat_setup_info(ct, &newrange, NF_NAT_MANIP_DST);
71} 35}
72 36
73static int redirect_tg6_checkentry(const struct xt_tgchk_param *par) 37static int redirect_tg6_checkentry(const struct xt_tgchk_param *par)
@@ -98,48 +62,7 @@ static int redirect_tg4_check(const struct xt_tgchk_param *par)
98static unsigned int 62static unsigned int
99redirect_tg4(struct sk_buff *skb, const struct xt_action_param *par) 63redirect_tg4(struct sk_buff *skb, const struct xt_action_param *par)
100{ 64{
101 struct nf_conn *ct; 65 return nf_nat_redirect_ipv4(skb, par->targinfo, par->hooknum);
102 enum ip_conntrack_info ctinfo;
103 __be32 newdst;
104 const struct nf_nat_ipv4_multi_range_compat *mr = par->targinfo;
105 struct nf_nat_range newrange;
106
107 NF_CT_ASSERT(par->hooknum == NF_INET_PRE_ROUTING ||
108 par->hooknum == NF_INET_LOCAL_OUT);
109
110 ct = nf_ct_get(skb, &ctinfo);
111 NF_CT_ASSERT(ct && (ctinfo == IP_CT_NEW || ctinfo == IP_CT_RELATED));
112
113 /* Local packets: make them go to loopback */
114 if (par->hooknum == NF_INET_LOCAL_OUT)
115 newdst = htonl(0x7F000001);
116 else {
117 struct in_device *indev;
118 struct in_ifaddr *ifa;
119
120 newdst = 0;
121
122 rcu_read_lock();
123 indev = __in_dev_get_rcu(skb->dev);
124 if (indev && (ifa = indev->ifa_list))
125 newdst = ifa->ifa_local;
126 rcu_read_unlock();
127
128 if (!newdst)
129 return NF_DROP;
130 }
131
132 /* Transfer from original range. */
133 memset(&newrange.min_addr, 0, sizeof(newrange.min_addr));
134 memset(&newrange.max_addr, 0, sizeof(newrange.max_addr));
135 newrange.flags = mr->range[0].flags | NF_NAT_RANGE_MAP_IPS;
136 newrange.min_addr.ip = newdst;
137 newrange.max_addr.ip = newdst;
138 newrange.min_proto = mr->range[0].min;
139 newrange.max_proto = mr->range[0].max;
140
141 /* Hand modified range to generic setup. */
142 return nf_nat_setup_info(ct, &newrange, NF_NAT_MANIP_DST);
143} 66}
144 67
145static struct xt_target redirect_tg_reg[] __read_mostly = { 68static struct xt_target redirect_tg_reg[] __read_mostly = {
diff --git a/net/netfilter/xt_connlimit.c b/net/netfilter/xt_connlimit.c
index fbc66bb250d5..29ba6218a820 100644
--- a/net/netfilter/xt_connlimit.c
+++ b/net/netfilter/xt_connlimit.c
@@ -134,6 +134,7 @@ static bool add_hlist(struct hlist_head *head,
134static unsigned int check_hlist(struct net *net, 134static unsigned int check_hlist(struct net *net,
135 struct hlist_head *head, 135 struct hlist_head *head,
136 const struct nf_conntrack_tuple *tuple, 136 const struct nf_conntrack_tuple *tuple,
137 u16 zone,
137 bool *addit) 138 bool *addit)
138{ 139{
139 const struct nf_conntrack_tuple_hash *found; 140 const struct nf_conntrack_tuple_hash *found;
@@ -147,8 +148,7 @@ static unsigned int check_hlist(struct net *net,
147 148
148 /* check the saved connections */ 149 /* check the saved connections */
149 hlist_for_each_entry_safe(conn, n, head, node) { 150 hlist_for_each_entry_safe(conn, n, head, node) {
150 found = nf_conntrack_find_get(net, NF_CT_DEFAULT_ZONE, 151 found = nf_conntrack_find_get(net, zone, &conn->tuple);
151 &conn->tuple);
152 if (found == NULL) { 152 if (found == NULL) {
153 hlist_del(&conn->node); 153 hlist_del(&conn->node);
154 kmem_cache_free(connlimit_conn_cachep, conn); 154 kmem_cache_free(connlimit_conn_cachep, conn);
@@ -201,7 +201,7 @@ static unsigned int
201count_tree(struct net *net, struct rb_root *root, 201count_tree(struct net *net, struct rb_root *root,
202 const struct nf_conntrack_tuple *tuple, 202 const struct nf_conntrack_tuple *tuple,
203 const union nf_inet_addr *addr, const union nf_inet_addr *mask, 203 const union nf_inet_addr *addr, const union nf_inet_addr *mask,
204 u8 family) 204 u8 family, u16 zone)
205{ 205{
206 struct xt_connlimit_rb *gc_nodes[CONNLIMIT_GC_MAX_NODES]; 206 struct xt_connlimit_rb *gc_nodes[CONNLIMIT_GC_MAX_NODES];
207 struct rb_node **rbnode, *parent; 207 struct rb_node **rbnode, *parent;
@@ -229,7 +229,7 @@ count_tree(struct net *net, struct rb_root *root,
229 } else { 229 } else {
230 /* same source network -> be counted! */ 230 /* same source network -> be counted! */
231 unsigned int count; 231 unsigned int count;
232 count = check_hlist(net, &rbconn->hhead, tuple, &addit); 232 count = check_hlist(net, &rbconn->hhead, tuple, zone, &addit);
233 233
234 tree_nodes_free(root, gc_nodes, gc_count); 234 tree_nodes_free(root, gc_nodes, gc_count);
235 if (!addit) 235 if (!addit)
@@ -245,7 +245,7 @@ count_tree(struct net *net, struct rb_root *root,
245 continue; 245 continue;
246 246
247 /* only used for GC on hhead, retval and 'addit' ignored */ 247 /* only used for GC on hhead, retval and 'addit' ignored */
248 check_hlist(net, &rbconn->hhead, tuple, &addit); 248 check_hlist(net, &rbconn->hhead, tuple, zone, &addit);
249 if (hlist_empty(&rbconn->hhead)) 249 if (hlist_empty(&rbconn->hhead))
250 gc_nodes[gc_count++] = rbconn; 250 gc_nodes[gc_count++] = rbconn;
251 } 251 }
@@ -290,7 +290,7 @@ static int count_them(struct net *net,
290 const struct nf_conntrack_tuple *tuple, 290 const struct nf_conntrack_tuple *tuple,
291 const union nf_inet_addr *addr, 291 const union nf_inet_addr *addr,
292 const union nf_inet_addr *mask, 292 const union nf_inet_addr *mask,
293 u_int8_t family) 293 u_int8_t family, u16 zone)
294{ 294{
295 struct rb_root *root; 295 struct rb_root *root;
296 int count; 296 int count;
@@ -306,7 +306,7 @@ static int count_them(struct net *net,
306 306
307 spin_lock_bh(&xt_connlimit_locks[hash % CONNLIMIT_LOCK_SLOTS]); 307 spin_lock_bh(&xt_connlimit_locks[hash % CONNLIMIT_LOCK_SLOTS]);
308 308
309 count = count_tree(net, root, tuple, addr, mask, family); 309 count = count_tree(net, root, tuple, addr, mask, family, zone);
310 310
311 spin_unlock_bh(&xt_connlimit_locks[hash % CONNLIMIT_LOCK_SLOTS]); 311 spin_unlock_bh(&xt_connlimit_locks[hash % CONNLIMIT_LOCK_SLOTS]);
312 312
@@ -324,13 +324,16 @@ connlimit_mt(const struct sk_buff *skb, struct xt_action_param *par)
324 enum ip_conntrack_info ctinfo; 324 enum ip_conntrack_info ctinfo;
325 const struct nf_conn *ct; 325 const struct nf_conn *ct;
326 unsigned int connections; 326 unsigned int connections;
327 u16 zone = NF_CT_DEFAULT_ZONE;
327 328
328 ct = nf_ct_get(skb, &ctinfo); 329 ct = nf_ct_get(skb, &ctinfo);
329 if (ct != NULL) 330 if (ct != NULL) {
330 tuple_ptr = &ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple; 331 tuple_ptr = &ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple;
331 else if (!nf_ct_get_tuplepr(skb, skb_network_offset(skb), 332 zone = nf_ct_zone(ct);
332 par->family, &tuple)) 333 } else if (!nf_ct_get_tuplepr(skb, skb_network_offset(skb),
334 par->family, &tuple)) {
333 goto hotdrop; 335 goto hotdrop;
336 }
334 337
335 if (par->family == NFPROTO_IPV6) { 338 if (par->family == NFPROTO_IPV6) {
336 const struct ipv6hdr *iph = ipv6_hdr(skb); 339 const struct ipv6hdr *iph = ipv6_hdr(skb);
@@ -343,7 +346,7 @@ connlimit_mt(const struct sk_buff *skb, struct xt_action_param *par)
343 } 346 }
344 347
345 connections = count_them(net, info->data, tuple_ptr, &addr, 348 connections = count_them(net, info->data, tuple_ptr, &addr,
346 &info->mask, par->family); 349 &info->mask, par->family, zone);
347 if (connections == 0) 350 if (connections == 0)
348 /* kmalloc failed, drop it entirely */ 351 /* kmalloc failed, drop it entirely */
349 goto hotdrop; 352 goto hotdrop;
diff --git a/net/netfilter/xt_recent.c b/net/netfilter/xt_recent.c
index a9faae89f955..30dbe34915ae 100644
--- a/net/netfilter/xt_recent.c
+++ b/net/netfilter/xt_recent.c
@@ -43,25 +43,29 @@ MODULE_LICENSE("GPL");
43MODULE_ALIAS("ipt_recent"); 43MODULE_ALIAS("ipt_recent");
44MODULE_ALIAS("ip6t_recent"); 44MODULE_ALIAS("ip6t_recent");
45 45
46static unsigned int ip_list_tot = 100; 46static unsigned int ip_list_tot __read_mostly = 100;
47static unsigned int ip_pkt_list_tot = 20; 47static unsigned int ip_list_hash_size __read_mostly;
48static unsigned int ip_list_hash_size = 0; 48static unsigned int ip_list_perms __read_mostly = 0644;
49static unsigned int ip_list_perms = 0644; 49static unsigned int ip_list_uid __read_mostly;
50static unsigned int ip_list_uid = 0; 50static unsigned int ip_list_gid __read_mostly;
51static unsigned int ip_list_gid = 0;
52module_param(ip_list_tot, uint, 0400); 51module_param(ip_list_tot, uint, 0400);
53module_param(ip_pkt_list_tot, uint, 0400);
54module_param(ip_list_hash_size, uint, 0400); 52module_param(ip_list_hash_size, uint, 0400);
55module_param(ip_list_perms, uint, 0400); 53module_param(ip_list_perms, uint, 0400);
56module_param(ip_list_uid, uint, S_IRUGO | S_IWUSR); 54module_param(ip_list_uid, uint, S_IRUGO | S_IWUSR);
57module_param(ip_list_gid, uint, S_IRUGO | S_IWUSR); 55module_param(ip_list_gid, uint, S_IRUGO | S_IWUSR);
58MODULE_PARM_DESC(ip_list_tot, "number of IPs to remember per list"); 56MODULE_PARM_DESC(ip_list_tot, "number of IPs to remember per list");
59MODULE_PARM_DESC(ip_pkt_list_tot, "number of packets per IP address to remember (max. 255)");
60MODULE_PARM_DESC(ip_list_hash_size, "size of hash table used to look up IPs"); 57MODULE_PARM_DESC(ip_list_hash_size, "size of hash table used to look up IPs");
61MODULE_PARM_DESC(ip_list_perms, "permissions on /proc/net/xt_recent/* files"); 58MODULE_PARM_DESC(ip_list_perms, "permissions on /proc/net/xt_recent/* files");
62MODULE_PARM_DESC(ip_list_uid, "default owner of /proc/net/xt_recent/* files"); 59MODULE_PARM_DESC(ip_list_uid, "default owner of /proc/net/xt_recent/* files");
63MODULE_PARM_DESC(ip_list_gid, "default owning group of /proc/net/xt_recent/* files"); 60MODULE_PARM_DESC(ip_list_gid, "default owning group of /proc/net/xt_recent/* files");
64 61
62/* retained for backwards compatibility */
63static unsigned int ip_pkt_list_tot __read_mostly;
64module_param(ip_pkt_list_tot, uint, 0400);
65MODULE_PARM_DESC(ip_pkt_list_tot, "number of packets per IP address to remember (max. 255)");
66
67#define XT_RECENT_MAX_NSTAMPS 256
68
65struct recent_entry { 69struct recent_entry {
66 struct list_head list; 70 struct list_head list;
67 struct list_head lru_list; 71 struct list_head lru_list;
@@ -79,6 +83,7 @@ struct recent_table {
79 union nf_inet_addr mask; 83 union nf_inet_addr mask;
80 unsigned int refcnt; 84 unsigned int refcnt;
81 unsigned int entries; 85 unsigned int entries;
86 u8 nstamps_max_mask;
82 struct list_head lru_list; 87 struct list_head lru_list;
83 struct list_head iphash[0]; 88 struct list_head iphash[0];
84}; 89};
@@ -90,7 +95,8 @@ struct recent_net {
90#endif 95#endif
91}; 96};
92 97
93static int recent_net_id; 98static int recent_net_id __read_mostly;
99
94static inline struct recent_net *recent_pernet(struct net *net) 100static inline struct recent_net *recent_pernet(struct net *net)
95{ 101{
96 return net_generic(net, recent_net_id); 102 return net_generic(net, recent_net_id);
@@ -171,12 +177,15 @@ recent_entry_init(struct recent_table *t, const union nf_inet_addr *addr,
171 u_int16_t family, u_int8_t ttl) 177 u_int16_t family, u_int8_t ttl)
172{ 178{
173 struct recent_entry *e; 179 struct recent_entry *e;
180 unsigned int nstamps_max = t->nstamps_max_mask;
174 181
175 if (t->entries >= ip_list_tot) { 182 if (t->entries >= ip_list_tot) {
176 e = list_entry(t->lru_list.next, struct recent_entry, lru_list); 183 e = list_entry(t->lru_list.next, struct recent_entry, lru_list);
177 recent_entry_remove(t, e); 184 recent_entry_remove(t, e);
178 } 185 }
179 e = kmalloc(sizeof(*e) + sizeof(e->stamps[0]) * ip_pkt_list_tot, 186
187 nstamps_max += 1;
188 e = kmalloc(sizeof(*e) + sizeof(e->stamps[0]) * nstamps_max,
180 GFP_ATOMIC); 189 GFP_ATOMIC);
181 if (e == NULL) 190 if (e == NULL)
182 return NULL; 191 return NULL;
@@ -197,7 +206,7 @@ recent_entry_init(struct recent_table *t, const union nf_inet_addr *addr,
197 206
198static void recent_entry_update(struct recent_table *t, struct recent_entry *e) 207static void recent_entry_update(struct recent_table *t, struct recent_entry *e)
199{ 208{
200 e->index %= ip_pkt_list_tot; 209 e->index &= t->nstamps_max_mask;
201 e->stamps[e->index++] = jiffies; 210 e->stamps[e->index++] = jiffies;
202 if (e->index > e->nstamps) 211 if (e->index > e->nstamps)
203 e->nstamps = e->index; 212 e->nstamps = e->index;
@@ -326,6 +335,7 @@ static int recent_mt_check(const struct xt_mtchk_param *par,
326 kuid_t uid; 335 kuid_t uid;
327 kgid_t gid; 336 kgid_t gid;
328#endif 337#endif
338 unsigned int nstamp_mask;
329 unsigned int i; 339 unsigned int i;
330 int ret = -EINVAL; 340 int ret = -EINVAL;
331 size_t sz; 341 size_t sz;
@@ -349,19 +359,33 @@ static int recent_mt_check(const struct xt_mtchk_param *par,
349 return -EINVAL; 359 return -EINVAL;
350 if ((info->check_set & XT_RECENT_REAP) && !info->seconds) 360 if ((info->check_set & XT_RECENT_REAP) && !info->seconds)
351 return -EINVAL; 361 return -EINVAL;
352 if (info->hit_count > ip_pkt_list_tot) { 362 if (info->hit_count >= XT_RECENT_MAX_NSTAMPS) {
353 pr_info("hitcount (%u) is larger than " 363 pr_info("hitcount (%u) is larger than allowed maximum (%u)\n",
354 "packets to be remembered (%u)\n", 364 info->hit_count, XT_RECENT_MAX_NSTAMPS - 1);
355 info->hit_count, ip_pkt_list_tot);
356 return -EINVAL; 365 return -EINVAL;
357 } 366 }
358 if (info->name[0] == '\0' || 367 if (info->name[0] == '\0' ||
359 strnlen(info->name, XT_RECENT_NAME_LEN) == XT_RECENT_NAME_LEN) 368 strnlen(info->name, XT_RECENT_NAME_LEN) == XT_RECENT_NAME_LEN)
360 return -EINVAL; 369 return -EINVAL;
361 370
371 if (ip_pkt_list_tot && info->hit_count < ip_pkt_list_tot)
372 nstamp_mask = roundup_pow_of_two(ip_pkt_list_tot) - 1;
373 else if (info->hit_count)
374 nstamp_mask = roundup_pow_of_two(info->hit_count) - 1;
375 else
376 nstamp_mask = 32 - 1;
377
362 mutex_lock(&recent_mutex); 378 mutex_lock(&recent_mutex);
363 t = recent_table_lookup(recent_net, info->name); 379 t = recent_table_lookup(recent_net, info->name);
364 if (t != NULL) { 380 if (t != NULL) {
381 if (info->hit_count > t->nstamps_max_mask) {
382 pr_info("hitcount (%u) is larger than packets to be remembered (%u) for table %s\n",
383 info->hit_count, t->nstamps_max_mask + 1,
384 info->name);
385 ret = -EINVAL;
386 goto out;
387 }
388
365 t->refcnt++; 389 t->refcnt++;
366 ret = 0; 390 ret = 0;
367 goto out; 391 goto out;
@@ -377,6 +401,7 @@ static int recent_mt_check(const struct xt_mtchk_param *par,
377 goto out; 401 goto out;
378 } 402 }
379 t->refcnt = 1; 403 t->refcnt = 1;
404 t->nstamps_max_mask = nstamp_mask;
380 405
381 memcpy(&t->mask, &info->mask, sizeof(t->mask)); 406 memcpy(&t->mask, &info->mask, sizeof(t->mask));
382 strcpy(t->name, info->name); 407 strcpy(t->name, info->name);
@@ -497,9 +522,12 @@ static void recent_seq_stop(struct seq_file *s, void *v)
497static int recent_seq_show(struct seq_file *seq, void *v) 522static int recent_seq_show(struct seq_file *seq, void *v)
498{ 523{
499 const struct recent_entry *e = v; 524 const struct recent_entry *e = v;
525 struct recent_iter_state *st = seq->private;
526 const struct recent_table *t = st->table;
500 unsigned int i; 527 unsigned int i;
501 528
502 i = (e->index - 1) % ip_pkt_list_tot; 529 i = (e->index - 1) & t->nstamps_max_mask;
530
503 if (e->family == NFPROTO_IPV4) 531 if (e->family == NFPROTO_IPV4)
504 seq_printf(seq, "src=%pI4 ttl: %u last_seen: %lu oldest_pkt: %u", 532 seq_printf(seq, "src=%pI4 ttl: %u last_seen: %lu oldest_pkt: %u",
505 &e->addr.ip, e->ttl, e->stamps[i], e->index); 533 &e->addr.ip, e->ttl, e->stamps[i], e->index);
@@ -717,7 +745,9 @@ static int __init recent_mt_init(void)
717{ 745{
718 int err; 746 int err;
719 747
720 if (!ip_list_tot || !ip_pkt_list_tot || ip_pkt_list_tot > 255) 748 BUILD_BUG_ON_NOT_POWER_OF_2(XT_RECENT_MAX_NSTAMPS);
749
750 if (!ip_list_tot || ip_pkt_list_tot >= XT_RECENT_MAX_NSTAMPS)
721 return -EINVAL; 751 return -EINVAL;
722 ip_list_hash_size = 1 << fls(ip_list_tot); 752 ip_list_hash_size = 1 << fls(ip_list_tot);
723 753
diff --git a/net/netfilter/xt_set.c b/net/netfilter/xt_set.c
index 5732cd64acc0..0d47afea9682 100644
--- a/net/netfilter/xt_set.c
+++ b/net/netfilter/xt_set.c
@@ -157,7 +157,7 @@ set_match_v1_destroy(const struct xt_mtdtor_param *par)
157/* Revision 3 match */ 157/* Revision 3 match */
158 158
159static bool 159static bool
160match_counter(u64 counter, const struct ip_set_counter_match *info) 160match_counter0(u64 counter, const struct ip_set_counter_match0 *info)
161{ 161{
162 switch (info->op) { 162 switch (info->op) {
163 case IPSET_COUNTER_NONE: 163 case IPSET_COUNTER_NONE:
@@ -192,14 +192,60 @@ set_match_v3(const struct sk_buff *skb, struct xt_action_param *par)
192 if (!(ret && opt.cmdflags & IPSET_FLAG_MATCH_COUNTERS)) 192 if (!(ret && opt.cmdflags & IPSET_FLAG_MATCH_COUNTERS))
193 return ret; 193 return ret;
194 194
195 if (!match_counter(opt.ext.packets, &info->packets)) 195 if (!match_counter0(opt.ext.packets, &info->packets))
196 return 0; 196 return 0;
197 return match_counter(opt.ext.bytes, &info->bytes); 197 return match_counter0(opt.ext.bytes, &info->bytes);
198} 198}
199 199
200#define set_match_v3_checkentry set_match_v1_checkentry 200#define set_match_v3_checkentry set_match_v1_checkentry
201#define set_match_v3_destroy set_match_v1_destroy 201#define set_match_v3_destroy set_match_v1_destroy
202 202
203/* Revision 4 match */
204
205static bool
206match_counter(u64 counter, const struct ip_set_counter_match *info)
207{
208 switch (info->op) {
209 case IPSET_COUNTER_NONE:
210 return true;
211 case IPSET_COUNTER_EQ:
212 return counter == info->value;
213 case IPSET_COUNTER_NE:
214 return counter != info->value;
215 case IPSET_COUNTER_LT:
216 return counter < info->value;
217 case IPSET_COUNTER_GT:
218 return counter > info->value;
219 }
220 return false;
221}
222
223static bool
224set_match_v4(const struct sk_buff *skb, struct xt_action_param *par)
225{
226 const struct xt_set_info_match_v4 *info = par->matchinfo;
227 ADT_OPT(opt, par->family, info->match_set.dim,
228 info->match_set.flags, info->flags, UINT_MAX);
229 int ret;
230
231 if (info->packets.op != IPSET_COUNTER_NONE ||
232 info->bytes.op != IPSET_COUNTER_NONE)
233 opt.cmdflags |= IPSET_FLAG_MATCH_COUNTERS;
234
235 ret = match_set(info->match_set.index, skb, par, &opt,
236 info->match_set.flags & IPSET_INV_MATCH);
237
238 if (!(ret && opt.cmdflags & IPSET_FLAG_MATCH_COUNTERS))
239 return ret;
240
241 if (!match_counter(opt.ext.packets, &info->packets))
242 return 0;
243 return match_counter(opt.ext.bytes, &info->bytes);
244}
245
246#define set_match_v4_checkentry set_match_v1_checkentry
247#define set_match_v4_destroy set_match_v1_destroy
248
203/* Revision 0 interface: backward compatible with netfilter/iptables */ 249/* Revision 0 interface: backward compatible with netfilter/iptables */
204 250
205static unsigned int 251static unsigned int
@@ -573,6 +619,27 @@ static struct xt_match set_matches[] __read_mostly = {
573 .destroy = set_match_v3_destroy, 619 .destroy = set_match_v3_destroy,
574 .me = THIS_MODULE 620 .me = THIS_MODULE
575 }, 621 },
622 /* new revision for counters support: update, match */
623 {
624 .name = "set",
625 .family = NFPROTO_IPV4,
626 .revision = 4,
627 .match = set_match_v4,
628 .matchsize = sizeof(struct xt_set_info_match_v4),
629 .checkentry = set_match_v4_checkentry,
630 .destroy = set_match_v4_destroy,
631 .me = THIS_MODULE
632 },
633 {
634 .name = "set",
635 .family = NFPROTO_IPV6,
636 .revision = 4,
637 .match = set_match_v4,
638 .matchsize = sizeof(struct xt_set_info_match_v4),
639 .checkentry = set_match_v4_checkentry,
640 .destroy = set_match_v4_destroy,
641 .me = THIS_MODULE
642 },
576}; 643};
577 644
578static struct xt_target set_targets[] __read_mostly = { 645static struct xt_target set_targets[] __read_mostly = {