aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv4
diff options
context:
space:
mode:
authorDavid S. Miller <davem@davemloft.net>2014-10-05 21:32:37 -0400
committerDavid S. Miller <davem@davemloft.net>2014-10-05 21:32:37 -0400
commit61b37d2f54961b336a47a501e797a05df20c3b30 (patch)
treed2b629be3e30ba71ba86573a72a4036b777e106f /net/ipv4
parentad9eef52085c5c6047e44705806a1b5b14b7f476 (diff)
parent8da4cc1b10c1aeba090d1d862b17174e4dbd50a4 (diff)
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 another batch with Netfilter/IPVS updates for net-next, they are: 1) Add abstracted ICMP codes to the nf_tables reject expression. We introduce four reasons to reject using ICMP that overlap in IPv4 and IPv6 from the semantic point of view. This should simplify the maintainance of dual stack rule-sets through the inet table. 2) Move nf_send_reset() functions from header files to per-family nf_reject modules, suggested by Patrick McHardy. 3) We have to use IS_ENABLED(CONFIG_BRIDGE_NETFILTER) everywhere in the code now that br_netfilter can be modularized. Convert remaining spots in the network stack code. 4) Use rcu_barrier() in the nf_tables module removal path to ensure that we don't leave object that are still pending to be released via call_rcu (that may likely result in a crash). 5) Remove incomplete arch 32/64 compat from nft_compat. The original (bad) idea was to probe the word size based on the xtables match/target info size, but this assumption is wrong when you have to dump the information back to userspace. 6) Allow to filter from prerouting and postrouting in the nf_tables bridge. In order to emulate the ebtables NAT chains (which are actually simple filter chains with no special semantics), we have support filtering from this hooks too. 7) Add explicit module dependency between xt_physdev and br_netfilter. This provides a way to detect if the user needs br_netfilter from the configuration path. This should reduce the breakage of the br_netfilter modularization. 8) Cleanup coding style in ip_vs.h, from Simon Horman. 9) Fix crash in the recently added nf_tables masq expression. We have to register/unregister the notifiers to clean up the conntrack table entries from the module init/exit path, not from the rule addition / deletion path. From Arturo Borrero. ==================== Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/ipv4')
-rw-r--r--net/ipv4/ip_output.c2
-rw-r--r--net/ipv4/netfilter/Kconfig6
-rw-r--r--net/ipv4/netfilter/Makefile3
-rw-r--r--net/ipv4/netfilter/ipt_REJECT.c2
-rw-r--r--net/ipv4/netfilter/nf_defrag_ipv4.c2
-rw-r--r--net/ipv4/netfilter/nf_reject_ipv4.c127
-rw-r--r--net/ipv4/netfilter/nft_masq_ipv4.c34
-rw-r--r--net/ipv4/netfilter/nft_reject_ipv4.c1
8 files changed, 150 insertions, 27 deletions
diff --git a/net/ipv4/ip_output.c b/net/ipv4/ip_output.c
index c8fa62476461..e35b71289156 100644
--- a/net/ipv4/ip_output.c
+++ b/net/ipv4/ip_output.c
@@ -516,7 +516,7 @@ int ip_fragment(struct sk_buff *skb, int (*output)(struct sk_buff *))
516 516
517 hlen = iph->ihl * 4; 517 hlen = iph->ihl * 4;
518 mtu = mtu - hlen; /* Size of data space */ 518 mtu = mtu - hlen; /* Size of data space */
519#ifdef CONFIG_BRIDGE_NETFILTER 519#if IS_ENABLED(CONFIG_BRIDGE_NETFILTER)
520 if (skb->nf_bridge) 520 if (skb->nf_bridge)
521 mtu -= nf_bridge_mtu_reduction(skb); 521 mtu -= nf_bridge_mtu_reduction(skb);
522#endif 522#endif
diff --git a/net/ipv4/netfilter/Kconfig b/net/ipv4/netfilter/Kconfig
index 345242a79db6..4c019d5c3f57 100644
--- a/net/ipv4/netfilter/Kconfig
+++ b/net/ipv4/netfilter/Kconfig
@@ -61,8 +61,13 @@ config NFT_CHAIN_ROUTE_IPV4
61 fields such as the source, destination, type of service and 61 fields such as the source, destination, type of service and
62 the packet mark. 62 the packet mark.
63 63
64config NF_REJECT_IPV4
65 tristate "IPv4 packet rejection"
66 default m if NETFILTER_ADVANCED=n
67
64config NFT_REJECT_IPV4 68config NFT_REJECT_IPV4
65 depends on NF_TABLES_IPV4 69 depends on NF_TABLES_IPV4
70 select NF_REJECT_IPV4
66 default NFT_REJECT 71 default NFT_REJECT
67 tristate 72 tristate
68 73
@@ -208,6 +213,7 @@ config IP_NF_FILTER
208config IP_NF_TARGET_REJECT 213config IP_NF_TARGET_REJECT
209 tristate "REJECT target support" 214 tristate "REJECT target support"
210 depends on IP_NF_FILTER 215 depends on IP_NF_FILTER
216 select NF_REJECT_IPV4
211 default m if NETFILTER_ADVANCED=n 217 default m if NETFILTER_ADVANCED=n
212 help 218 help
213 The REJECT target allows a filtering rule to specify that an ICMP 219 The REJECT target allows a filtering rule to specify that an ICMP
diff --git a/net/ipv4/netfilter/Makefile b/net/ipv4/netfilter/Makefile
index 14488cc5fd2c..f4cef5af0969 100644
--- a/net/ipv4/netfilter/Makefile
+++ b/net/ipv4/netfilter/Makefile
@@ -23,6 +23,9 @@ obj-$(CONFIG_NF_DEFRAG_IPV4) += nf_defrag_ipv4.o
23obj-$(CONFIG_NF_LOG_ARP) += nf_log_arp.o 23obj-$(CONFIG_NF_LOG_ARP) += nf_log_arp.o
24obj-$(CONFIG_NF_LOG_IPV4) += nf_log_ipv4.o 24obj-$(CONFIG_NF_LOG_IPV4) += nf_log_ipv4.o
25 25
26# reject
27obj-$(CONFIG_NF_REJECT_IPV4) += nf_reject_ipv4.o
28
26# NAT helpers (nf_conntrack) 29# NAT helpers (nf_conntrack)
27obj-$(CONFIG_NF_NAT_H323) += nf_nat_h323.o 30obj-$(CONFIG_NF_NAT_H323) += nf_nat_h323.o
28obj-$(CONFIG_NF_NAT_PPTP) += nf_nat_pptp.o 31obj-$(CONFIG_NF_NAT_PPTP) += nf_nat_pptp.o
diff --git a/net/ipv4/netfilter/ipt_REJECT.c b/net/ipv4/netfilter/ipt_REJECT.c
index 5b6e0df4ccff..8f48f5517e33 100644
--- a/net/ipv4/netfilter/ipt_REJECT.c
+++ b/net/ipv4/netfilter/ipt_REJECT.c
@@ -20,7 +20,7 @@
20#include <linux/netfilter/x_tables.h> 20#include <linux/netfilter/x_tables.h>
21#include <linux/netfilter_ipv4/ip_tables.h> 21#include <linux/netfilter_ipv4/ip_tables.h>
22#include <linux/netfilter_ipv4/ipt_REJECT.h> 22#include <linux/netfilter_ipv4/ipt_REJECT.h>
23#ifdef CONFIG_BRIDGE_NETFILTER 23#if IS_ENABLED(CONFIG_BRIDGE_NETFILTER)
24#include <linux/netfilter_bridge.h> 24#include <linux/netfilter_bridge.h>
25#endif 25#endif
26 26
diff --git a/net/ipv4/netfilter/nf_defrag_ipv4.c b/net/ipv4/netfilter/nf_defrag_ipv4.c
index 76bd1aef257f..7e5ca6f2d0cd 100644
--- a/net/ipv4/netfilter/nf_defrag_ipv4.c
+++ b/net/ipv4/netfilter/nf_defrag_ipv4.c
@@ -50,7 +50,7 @@ static enum ip_defrag_users nf_ct_defrag_user(unsigned int hooknum,
50 zone = nf_ct_zone((struct nf_conn *)skb->nfct); 50 zone = nf_ct_zone((struct nf_conn *)skb->nfct);
51#endif 51#endif
52 52
53#ifdef CONFIG_BRIDGE_NETFILTER 53#if IS_ENABLED(CONFIG_BRIDGE_NETFILTER)
54 if (skb->nf_bridge && 54 if (skb->nf_bridge &&
55 skb->nf_bridge->mask & BRNF_NF_BRIDGE_PREROUTING) 55 skb->nf_bridge->mask & BRNF_NF_BRIDGE_PREROUTING)
56 return IP_DEFRAG_CONNTRACK_BRIDGE_IN + zone; 56 return IP_DEFRAG_CONNTRACK_BRIDGE_IN + zone;
diff --git a/net/ipv4/netfilter/nf_reject_ipv4.c b/net/ipv4/netfilter/nf_reject_ipv4.c
new file mode 100644
index 000000000000..b023b4eb1a96
--- /dev/null
+++ b/net/ipv4/netfilter/nf_reject_ipv4.c
@@ -0,0 +1,127 @@
1/* (C) 1999-2001 Paul `Rusty' Russell
2 * (C) 2002-2004 Netfilter Core Team <coreteam@netfilter.org>
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 <net/ip.h>
10#include <net/tcp.h>
11#include <net/route.h>
12#include <net/dst.h>
13#include <linux/netfilter_ipv4.h>
14
15/* Send RST reply */
16void nf_send_reset(struct sk_buff *oldskb, int hook)
17{
18 struct sk_buff *nskb;
19 const struct iphdr *oiph;
20 struct iphdr *niph;
21 const struct tcphdr *oth;
22 struct tcphdr _otcph, *tcph;
23
24 /* IP header checks: fragment. */
25 if (ip_hdr(oldskb)->frag_off & htons(IP_OFFSET))
26 return;
27
28 oth = skb_header_pointer(oldskb, ip_hdrlen(oldskb),
29 sizeof(_otcph), &_otcph);
30 if (oth == NULL)
31 return;
32
33 /* No RST for RST. */
34 if (oth->rst)
35 return;
36
37 if (skb_rtable(oldskb)->rt_flags & (RTCF_BROADCAST | RTCF_MULTICAST))
38 return;
39
40 /* Check checksum */
41 if (nf_ip_checksum(oldskb, hook, ip_hdrlen(oldskb), IPPROTO_TCP))
42 return;
43 oiph = ip_hdr(oldskb);
44
45 nskb = alloc_skb(sizeof(struct iphdr) + sizeof(struct tcphdr) +
46 LL_MAX_HEADER, GFP_ATOMIC);
47 if (!nskb)
48 return;
49
50 skb_reserve(nskb, LL_MAX_HEADER);
51
52 skb_reset_network_header(nskb);
53 niph = (struct iphdr *)skb_put(nskb, sizeof(struct iphdr));
54 niph->version = 4;
55 niph->ihl = sizeof(struct iphdr) / 4;
56 niph->tos = 0;
57 niph->id = 0;
58 niph->frag_off = htons(IP_DF);
59 niph->protocol = IPPROTO_TCP;
60 niph->check = 0;
61 niph->saddr = oiph->daddr;
62 niph->daddr = oiph->saddr;
63
64 skb_reset_transport_header(nskb);
65 tcph = (struct tcphdr *)skb_put(nskb, sizeof(struct tcphdr));
66 memset(tcph, 0, sizeof(*tcph));
67 tcph->source = oth->dest;
68 tcph->dest = oth->source;
69 tcph->doff = sizeof(struct tcphdr) / 4;
70
71 if (oth->ack)
72 tcph->seq = oth->ack_seq;
73 else {
74 tcph->ack_seq = htonl(ntohl(oth->seq) + oth->syn + oth->fin +
75 oldskb->len - ip_hdrlen(oldskb) -
76 (oth->doff << 2));
77 tcph->ack = 1;
78 }
79
80 tcph->rst = 1;
81 tcph->check = ~tcp_v4_check(sizeof(struct tcphdr), niph->saddr,
82 niph->daddr, 0);
83 nskb->ip_summed = CHECKSUM_PARTIAL;
84 nskb->csum_start = (unsigned char *)tcph - nskb->head;
85 nskb->csum_offset = offsetof(struct tcphdr, check);
86
87 /* ip_route_me_harder expects skb->dst to be set */
88 skb_dst_set_noref(nskb, skb_dst(oldskb));
89
90 nskb->protocol = htons(ETH_P_IP);
91 if (ip_route_me_harder(nskb, RTN_UNSPEC))
92 goto free_nskb;
93
94 niph->ttl = ip4_dst_hoplimit(skb_dst(nskb));
95
96 /* "Never happens" */
97 if (nskb->len > dst_mtu(skb_dst(nskb)))
98 goto free_nskb;
99
100 nf_ct_attach(nskb, oldskb);
101
102#if IS_ENABLED(CONFIG_BRIDGE_NETFILTER)
103 /* If we use ip_local_out for bridged traffic, the MAC source on
104 * the RST will be ours, instead of the destination's. This confuses
105 * some routers/firewalls, and they drop the packet. So we need to
106 * build the eth header using the original destination's MAC as the
107 * source, and send the RST packet directly.
108 */
109 if (oldskb->nf_bridge) {
110 struct ethhdr *oeth = eth_hdr(oldskb);
111 nskb->dev = oldskb->nf_bridge->physindev;
112 niph->tot_len = htons(nskb->len);
113 ip_send_check(niph);
114 if (dev_hard_header(nskb, nskb->dev, ntohs(nskb->protocol),
115 oeth->h_source, oeth->h_dest, nskb->len) < 0)
116 goto free_nskb;
117 dev_queue_xmit(nskb);
118 } else
119#endif
120 ip_local_out(nskb);
121
122 return;
123
124 free_nskb:
125 kfree_skb(nskb);
126}
127EXPORT_SYMBOL_GPL(nf_send_reset);
diff --git a/net/ipv4/netfilter/nft_masq_ipv4.c b/net/ipv4/netfilter/nft_masq_ipv4.c
index 6ea1d207b6a5..1c636d6b5b50 100644
--- a/net/ipv4/netfilter/nft_masq_ipv4.c
+++ b/net/ipv4/netfilter/nft_masq_ipv4.c
@@ -32,33 +32,12 @@ static void nft_masq_ipv4_eval(const struct nft_expr *expr,
32 data[NFT_REG_VERDICT].verdict = verdict; 32 data[NFT_REG_VERDICT].verdict = verdict;
33} 33}
34 34
35static int nft_masq_ipv4_init(const struct nft_ctx *ctx,
36 const struct nft_expr *expr,
37 const struct nlattr * const tb[])
38{
39 int err;
40
41 err = nft_masq_init(ctx, expr, tb);
42 if (err < 0)
43 return err;
44
45 nf_nat_masquerade_ipv4_register_notifier();
46 return 0;
47}
48
49static void nft_masq_ipv4_destroy(const struct nft_ctx *ctx,
50 const struct nft_expr *expr)
51{
52 nf_nat_masquerade_ipv4_unregister_notifier();
53}
54
55static struct nft_expr_type nft_masq_ipv4_type; 35static struct nft_expr_type nft_masq_ipv4_type;
56static const struct nft_expr_ops nft_masq_ipv4_ops = { 36static const struct nft_expr_ops nft_masq_ipv4_ops = {
57 .type = &nft_masq_ipv4_type, 37 .type = &nft_masq_ipv4_type,
58 .size = NFT_EXPR_SIZE(sizeof(struct nft_masq)), 38 .size = NFT_EXPR_SIZE(sizeof(struct nft_masq)),
59 .eval = nft_masq_ipv4_eval, 39 .eval = nft_masq_ipv4_eval,
60 .init = nft_masq_ipv4_init, 40 .init = nft_masq_init,
61 .destroy = nft_masq_ipv4_destroy,
62 .dump = nft_masq_dump, 41 .dump = nft_masq_dump,
63}; 42};
64 43
@@ -73,12 +52,21 @@ static struct nft_expr_type nft_masq_ipv4_type __read_mostly = {
73 52
74static int __init nft_masq_ipv4_module_init(void) 53static int __init nft_masq_ipv4_module_init(void)
75{ 54{
76 return nft_register_expr(&nft_masq_ipv4_type); 55 int ret;
56
57 ret = nft_register_expr(&nft_masq_ipv4_type);
58 if (ret < 0)
59 return ret;
60
61 nf_nat_masquerade_ipv4_register_notifier();
62
63 return ret;
77} 64}
78 65
79static void __exit nft_masq_ipv4_module_exit(void) 66static void __exit nft_masq_ipv4_module_exit(void)
80{ 67{
81 nft_unregister_expr(&nft_masq_ipv4_type); 68 nft_unregister_expr(&nft_masq_ipv4_type);
69 nf_nat_masquerade_ipv4_unregister_notifier();
82} 70}
83 71
84module_init(nft_masq_ipv4_module_init); 72module_init(nft_masq_ipv4_module_init);
diff --git a/net/ipv4/netfilter/nft_reject_ipv4.c b/net/ipv4/netfilter/nft_reject_ipv4.c
index e79718a382f2..ed33299c56d1 100644
--- a/net/ipv4/netfilter/nft_reject_ipv4.c
+++ b/net/ipv4/netfilter/nft_reject_ipv4.c
@@ -16,7 +16,6 @@
16#include <linux/netfilter.h> 16#include <linux/netfilter.h>
17#include <linux/netfilter/nf_tables.h> 17#include <linux/netfilter/nf_tables.h>
18#include <net/netfilter/nf_tables.h> 18#include <net/netfilter/nf_tables.h>
19#include <net/icmp.h>
20#include <net/netfilter/ipv4/nf_reject.h> 19#include <net/netfilter/ipv4/nf_reject.h>
21#include <net/netfilter/nft_reject.h> 20#include <net/netfilter/nft_reject.h>
22 21