aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv4
diff options
context:
space:
mode:
authorDavid S. Miller <davem@davemloft.net>2014-01-06 13:29:30 -0500
committerDavid S. Miller <davem@davemloft.net>2014-01-06 13:29:30 -0500
commit9aa28f2b71055d5ae17a2e1daee359d4174bb13e (patch)
treefbf4e0fd11eb924e0bece74a87f442bc54441b35 /net/ipv4
parent6a8c4796df74045088a916581c736432d08c53c0 (diff)
parentc9c8e485978a308c8a359140da187d55120f8fee (diff)
Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/pablo/nftables
Pablo Neira Ayuso says: <pablo@netfilter.org> ==================== nftables updates for net-next The following patchset contains nftables updates for your net-next tree, they are: * Add set operation to the meta expression by means of the select_ops() infrastructure, this allows us to set the packet mark among other things. From Arturo Borrero Gonzalez. * Fix wrong format in sscanf in nf_tables_set_alloc_name(), from Daniel Borkmann. * Add new queue expression to nf_tables. These comes with two previous patches to prepare this new feature, one to add mask in nf_tables_core to evaluate the queue verdict appropriately and another to refactor common code with xt_NFQUEUE, from Eric Leblond. * Do not hide nftables from Kconfig if nfnetlink is not enabled, also from Eric Leblond. * Add the reject expression to nf_tables, this adds the missing TCP RST support. It comes with an initial patch to refactor common code with xt_NFQUEUE, again from Eric Leblond. * Remove an unused variable assignment in nf_tables_dump_set(), from Michal Nazarewicz. * Remove the nft_meta_target code, now that Arturo added the set operation to the meta expression, from me. * Add help information for nf_tables to Kconfig, also from me. * Allow to dump all sets by specifying NFPROTO_UNSPEC, similar feature is available to other nf_tables objects, requested by Arturo, from me. * Expose the table usage counter, so we can know how many chains are using this table without dumping the list of chains, from Tomasz Bursztyka. ==================== Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/ipv4')
-rw-r--r--net/ipv4/netfilter/Kconfig18
-rw-r--r--net/ipv4/netfilter/Makefile1
-rw-r--r--net/ipv4/netfilter/ipt_REJECT.c140
-rw-r--r--net/ipv4/netfilter/nft_reject_ipv4.c123
4 files changed, 24 insertions, 258 deletions
diff --git a/net/ipv4/netfilter/Kconfig b/net/ipv4/netfilter/Kconfig
index 40d56073cd19..81c6910cfa92 100644
--- a/net/ipv4/netfilter/Kconfig
+++ b/net/ipv4/netfilter/Kconfig
@@ -39,23 +39,33 @@ config NF_CONNTRACK_PROC_COMPAT
39config NF_TABLES_IPV4 39config NF_TABLES_IPV4
40 depends on NF_TABLES 40 depends on NF_TABLES
41 tristate "IPv4 nf_tables support" 41 tristate "IPv4 nf_tables support"
42 42 help
43config NFT_REJECT_IPV4 43 This option enables the IPv4 support for nf_tables.
44 depends on NF_TABLES_IPV4
45 tristate "nf_tables IPv4 reject support"
46 44
47config NFT_CHAIN_ROUTE_IPV4 45config NFT_CHAIN_ROUTE_IPV4
48 depends on NF_TABLES_IPV4 46 depends on NF_TABLES_IPV4
49 tristate "IPv4 nf_tables route chain support" 47 tristate "IPv4 nf_tables route chain support"
48 help
49 This option enables the "route" chain for IPv4 in nf_tables. This
50 chain type is used to force packet re-routing after mangling header
51 fields such as the source, destination, type of service and
52 the packet mark.
50 53
51config NFT_CHAIN_NAT_IPV4 54config NFT_CHAIN_NAT_IPV4
52 depends on NF_TABLES_IPV4 55 depends on NF_TABLES_IPV4
53 depends on NF_NAT_IPV4 && NFT_NAT 56 depends on NF_NAT_IPV4 && NFT_NAT
54 tristate "IPv4 nf_tables nat chain support" 57 tristate "IPv4 nf_tables nat chain support"
58 help
59 This option enables the "nat" chain for IPv4 in nf_tables. This
60 chain type is used to perform Network Address Translation (NAT)
61 packet transformations such as the source, destination address and
62 source and destination ports.
55 63
56config NF_TABLES_ARP 64config NF_TABLES_ARP
57 depends on NF_TABLES 65 depends on NF_TABLES
58 tristate "ARP nf_tables support" 66 tristate "ARP nf_tables support"
67 help
68 This option enables the ARP support for nf_tables.
59 69
60config IP_NF_IPTABLES 70config IP_NF_IPTABLES
61 tristate "IP tables support (required for filtering/masq/NAT)" 71 tristate "IP tables support (required for filtering/masq/NAT)"
diff --git a/net/ipv4/netfilter/Makefile b/net/ipv4/netfilter/Makefile
index 19df72b7ba88..c16be9d58420 100644
--- a/net/ipv4/netfilter/Makefile
+++ b/net/ipv4/netfilter/Makefile
@@ -28,7 +28,6 @@ obj-$(CONFIG_NF_NAT_SNMP_BASIC) += nf_nat_snmp_basic.o
28obj-$(CONFIG_NF_NAT_PROTO_GRE) += nf_nat_proto_gre.o 28obj-$(CONFIG_NF_NAT_PROTO_GRE) += nf_nat_proto_gre.o
29 29
30obj-$(CONFIG_NF_TABLES_IPV4) += nf_tables_ipv4.o 30obj-$(CONFIG_NF_TABLES_IPV4) += nf_tables_ipv4.o
31obj-$(CONFIG_NFT_REJECT_IPV4) += nft_reject_ipv4.o
32obj-$(CONFIG_NFT_CHAIN_ROUTE_IPV4) += nft_chain_route_ipv4.o 31obj-$(CONFIG_NFT_CHAIN_ROUTE_IPV4) += nft_chain_route_ipv4.o
33obj-$(CONFIG_NFT_CHAIN_NAT_IPV4) += nft_chain_nat_ipv4.o 32obj-$(CONFIG_NFT_CHAIN_NAT_IPV4) += nft_chain_nat_ipv4.o
34obj-$(CONFIG_NF_TABLES_ARP) += nf_tables_arp.o 33obj-$(CONFIG_NF_TABLES_ARP) += nf_tables_arp.o
diff --git a/net/ipv4/netfilter/ipt_REJECT.c b/net/ipv4/netfilter/ipt_REJECT.c
index b969131ad1c1..5b6e0df4ccff 100644
--- a/net/ipv4/netfilter/ipt_REJECT.c
+++ b/net/ipv4/netfilter/ipt_REJECT.c
@@ -17,10 +17,6 @@
17#include <linux/udp.h> 17#include <linux/udp.h>
18#include <linux/icmp.h> 18#include <linux/icmp.h>
19#include <net/icmp.h> 19#include <net/icmp.h>
20#include <net/ip.h>
21#include <net/tcp.h>
22#include <net/route.h>
23#include <net/dst.h>
24#include <linux/netfilter/x_tables.h> 20#include <linux/netfilter/x_tables.h>
25#include <linux/netfilter_ipv4/ip_tables.h> 21#include <linux/netfilter_ipv4/ip_tables.h>
26#include <linux/netfilter_ipv4/ipt_REJECT.h> 22#include <linux/netfilter_ipv4/ipt_REJECT.h>
@@ -28,128 +24,12 @@
28#include <linux/netfilter_bridge.h> 24#include <linux/netfilter_bridge.h>
29#endif 25#endif
30 26
27#include <net/netfilter/ipv4/nf_reject.h>
28
31MODULE_LICENSE("GPL"); 29MODULE_LICENSE("GPL");
32MODULE_AUTHOR("Netfilter Core Team <coreteam@netfilter.org>"); 30MODULE_AUTHOR("Netfilter Core Team <coreteam@netfilter.org>");
33MODULE_DESCRIPTION("Xtables: packet \"rejection\" target for IPv4"); 31MODULE_DESCRIPTION("Xtables: packet \"rejection\" target for IPv4");
34 32
35/* Send RST reply */
36static void send_reset(struct sk_buff *oldskb, int hook)
37{
38 struct sk_buff *nskb;
39 const struct iphdr *oiph;
40 struct iphdr *niph;
41 const struct tcphdr *oth;
42 struct tcphdr _otcph, *tcph;
43
44 /* IP header checks: fragment. */
45 if (ip_hdr(oldskb)->frag_off & htons(IP_OFFSET))
46 return;
47
48 oth = skb_header_pointer(oldskb, ip_hdrlen(oldskb),
49 sizeof(_otcph), &_otcph);
50 if (oth == NULL)
51 return;
52
53 /* No RST for RST. */
54 if (oth->rst)
55 return;
56
57 if (skb_rtable(oldskb)->rt_flags & (RTCF_BROADCAST | RTCF_MULTICAST))
58 return;
59
60 /* Check checksum */
61 if (nf_ip_checksum(oldskb, hook, ip_hdrlen(oldskb), IPPROTO_TCP))
62 return;
63 oiph = ip_hdr(oldskb);
64
65 nskb = alloc_skb(sizeof(struct iphdr) + sizeof(struct tcphdr) +
66 LL_MAX_HEADER, GFP_ATOMIC);
67 if (!nskb)
68 return;
69
70 skb_reserve(nskb, LL_MAX_HEADER);
71
72 skb_reset_network_header(nskb);
73 niph = (struct iphdr *)skb_put(nskb, sizeof(struct iphdr));
74 niph->version = 4;
75 niph->ihl = sizeof(struct iphdr) / 4;
76 niph->tos = 0;
77 niph->id = 0;
78 niph->frag_off = htons(IP_DF);
79 niph->protocol = IPPROTO_TCP;
80 niph->check = 0;
81 niph->saddr = oiph->daddr;
82 niph->daddr = oiph->saddr;
83
84 skb_reset_transport_header(nskb);
85 tcph = (struct tcphdr *)skb_put(nskb, sizeof(struct tcphdr));
86 memset(tcph, 0, sizeof(*tcph));
87 tcph->source = oth->dest;
88 tcph->dest = oth->source;
89 tcph->doff = sizeof(struct tcphdr) / 4;
90
91 if (oth->ack)
92 tcph->seq = oth->ack_seq;
93 else {
94 tcph->ack_seq = htonl(ntohl(oth->seq) + oth->syn + oth->fin +
95 oldskb->len - ip_hdrlen(oldskb) -
96 (oth->doff << 2));
97 tcph->ack = 1;
98 }
99
100 tcph->rst = 1;
101 tcph->check = ~tcp_v4_check(sizeof(struct tcphdr), niph->saddr,
102 niph->daddr, 0);
103 nskb->ip_summed = CHECKSUM_PARTIAL;
104 nskb->csum_start = (unsigned char *)tcph - nskb->head;
105 nskb->csum_offset = offsetof(struct tcphdr, check);
106
107 /* ip_route_me_harder expects skb->dst to be set */
108 skb_dst_set_noref(nskb, skb_dst(oldskb));
109
110 nskb->protocol = htons(ETH_P_IP);
111 if (ip_route_me_harder(nskb, RTN_UNSPEC))
112 goto free_nskb;
113
114 niph->ttl = ip4_dst_hoplimit(skb_dst(nskb));
115
116 /* "Never happens" */
117 if (nskb->len > dst_mtu(skb_dst(nskb)))
118 goto free_nskb;
119
120 nf_ct_attach(nskb, oldskb);
121
122#ifdef CONFIG_BRIDGE_NETFILTER
123 /* If we use ip_local_out for bridged traffic, the MAC source on
124 * the RST will be ours, instead of the destination's. This confuses
125 * some routers/firewalls, and they drop the packet. So we need to
126 * build the eth header using the original destination's MAC as the
127 * source, and send the RST packet directly.
128 */
129 if (oldskb->nf_bridge) {
130 struct ethhdr *oeth = eth_hdr(oldskb);
131 nskb->dev = oldskb->nf_bridge->physindev;
132 niph->tot_len = htons(nskb->len);
133 ip_send_check(niph);
134 if (dev_hard_header(nskb, nskb->dev, ntohs(nskb->protocol),
135 oeth->h_source, oeth->h_dest, nskb->len) < 0)
136 goto free_nskb;
137 dev_queue_xmit(nskb);
138 } else
139#endif
140 ip_local_out(nskb);
141
142 return;
143
144 free_nskb:
145 kfree_skb(nskb);
146}
147
148static inline void send_unreach(struct sk_buff *skb_in, int code)
149{
150 icmp_send(skb_in, ICMP_DEST_UNREACH, code, 0);
151}
152
153static unsigned int 33static unsigned int
154reject_tg(struct sk_buff *skb, const struct xt_action_param *par) 34reject_tg(struct sk_buff *skb, const struct xt_action_param *par)
155{ 35{
@@ -157,28 +37,28 @@ reject_tg(struct sk_buff *skb, const struct xt_action_param *par)
157 37
158 switch (reject->with) { 38 switch (reject->with) {
159 case IPT_ICMP_NET_UNREACHABLE: 39 case IPT_ICMP_NET_UNREACHABLE:
160 send_unreach(skb, ICMP_NET_UNREACH); 40 nf_send_unreach(skb, ICMP_NET_UNREACH);
161 break; 41 break;
162 case IPT_ICMP_HOST_UNREACHABLE: 42 case IPT_ICMP_HOST_UNREACHABLE:
163 send_unreach(skb, ICMP_HOST_UNREACH); 43 nf_send_unreach(skb, ICMP_HOST_UNREACH);
164 break; 44 break;
165 case IPT_ICMP_PROT_UNREACHABLE: 45 case IPT_ICMP_PROT_UNREACHABLE:
166 send_unreach(skb, ICMP_PROT_UNREACH); 46 nf_send_unreach(skb, ICMP_PROT_UNREACH);
167 break; 47 break;
168 case IPT_ICMP_PORT_UNREACHABLE: 48 case IPT_ICMP_PORT_UNREACHABLE:
169 send_unreach(skb, ICMP_PORT_UNREACH); 49 nf_send_unreach(skb, ICMP_PORT_UNREACH);
170 break; 50 break;
171 case IPT_ICMP_NET_PROHIBITED: 51 case IPT_ICMP_NET_PROHIBITED:
172 send_unreach(skb, ICMP_NET_ANO); 52 nf_send_unreach(skb, ICMP_NET_ANO);
173 break; 53 break;
174 case IPT_ICMP_HOST_PROHIBITED: 54 case IPT_ICMP_HOST_PROHIBITED:
175 send_unreach(skb, ICMP_HOST_ANO); 55 nf_send_unreach(skb, ICMP_HOST_ANO);
176 break; 56 break;
177 case IPT_ICMP_ADMIN_PROHIBITED: 57 case IPT_ICMP_ADMIN_PROHIBITED:
178 send_unreach(skb, ICMP_PKT_FILTERED); 58 nf_send_unreach(skb, ICMP_PKT_FILTERED);
179 break; 59 break;
180 case IPT_TCP_RESET: 60 case IPT_TCP_RESET:
181 send_reset(skb, par->hooknum); 61 nf_send_reset(skb, par->hooknum);
182 case IPT_ICMP_ECHOREPLY: 62 case IPT_ICMP_ECHOREPLY:
183 /* Doesn't happen. */ 63 /* Doesn't happen. */
184 break; 64 break;
diff --git a/net/ipv4/netfilter/nft_reject_ipv4.c b/net/ipv4/netfilter/nft_reject_ipv4.c
deleted file mode 100644
index 4a5e94ac314a..000000000000
--- a/net/ipv4/netfilter/nft_reject_ipv4.c
+++ /dev/null
@@ -1,123 +0,0 @@
1/*
2 * Copyright (c) 2008-2009 Patrick McHardy <kaber@trash.net>
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 * Development of this code funded by Astaro AG (http://www.astaro.com/)
9 */
10
11#include <linux/kernel.h>
12#include <linux/init.h>
13#include <linux/module.h>
14#include <linux/netlink.h>
15#include <linux/netfilter.h>
16#include <linux/netfilter/nf_tables.h>
17#include <net/netfilter/nf_tables.h>
18#include <net/icmp.h>
19
20struct nft_reject {
21 enum nft_reject_types type:8;
22 u8 icmp_code;
23};
24
25static void nft_reject_eval(const struct nft_expr *expr,
26 struct nft_data data[NFT_REG_MAX + 1],
27 const struct nft_pktinfo *pkt)
28{
29 struct nft_reject *priv = nft_expr_priv(expr);
30
31 switch (priv->type) {
32 case NFT_REJECT_ICMP_UNREACH:
33 icmp_send(pkt->skb, ICMP_DEST_UNREACH, priv->icmp_code, 0);
34 break;
35 case NFT_REJECT_TCP_RST:
36 break;
37 }
38
39 data[NFT_REG_VERDICT].verdict = NF_DROP;
40}
41
42static const struct nla_policy nft_reject_policy[NFTA_REJECT_MAX + 1] = {
43 [NFTA_REJECT_TYPE] = { .type = NLA_U32 },
44 [NFTA_REJECT_ICMP_CODE] = { .type = NLA_U8 },
45};
46
47static int nft_reject_init(const struct nft_ctx *ctx,
48 const struct nft_expr *expr,
49 const struct nlattr * const tb[])
50{
51 struct nft_reject *priv = nft_expr_priv(expr);
52
53 if (tb[NFTA_REJECT_TYPE] == NULL)
54 return -EINVAL;
55
56 priv->type = ntohl(nla_get_be32(tb[NFTA_REJECT_TYPE]));
57 switch (priv->type) {
58 case NFT_REJECT_ICMP_UNREACH:
59 if (tb[NFTA_REJECT_ICMP_CODE] == NULL)
60 return -EINVAL;
61 priv->icmp_code = nla_get_u8(tb[NFTA_REJECT_ICMP_CODE]);
62 case NFT_REJECT_TCP_RST:
63 break;
64 default:
65 return -EINVAL;
66 }
67
68 return 0;
69}
70
71static int nft_reject_dump(struct sk_buff *skb, const struct nft_expr *expr)
72{
73 const struct nft_reject *priv = nft_expr_priv(expr);
74
75 if (nla_put_be32(skb, NFTA_REJECT_TYPE, htonl(priv->type)))
76 goto nla_put_failure;
77
78 switch (priv->type) {
79 case NFT_REJECT_ICMP_UNREACH:
80 if (nla_put_u8(skb, NFTA_REJECT_ICMP_CODE, priv->icmp_code))
81 goto nla_put_failure;
82 break;
83 }
84
85 return 0;
86
87nla_put_failure:
88 return -1;
89}
90
91static struct nft_expr_type nft_reject_type;
92static const struct nft_expr_ops nft_reject_ops = {
93 .type = &nft_reject_type,
94 .size = NFT_EXPR_SIZE(sizeof(struct nft_reject)),
95 .eval = nft_reject_eval,
96 .init = nft_reject_init,
97 .dump = nft_reject_dump,
98};
99
100static struct nft_expr_type nft_reject_type __read_mostly = {
101 .name = "reject",
102 .ops = &nft_reject_ops,
103 .policy = nft_reject_policy,
104 .maxattr = NFTA_REJECT_MAX,
105 .owner = THIS_MODULE,
106};
107
108static int __init nft_reject_module_init(void)
109{
110 return nft_register_expr(&nft_reject_type);
111}
112
113static void __exit nft_reject_module_exit(void)
114{
115 nft_unregister_expr(&nft_reject_type);
116}
117
118module_init(nft_reject_module_init);
119module_exit(nft_reject_module_exit);
120
121MODULE_LICENSE("GPL");
122MODULE_AUTHOR("Patrick McHardy <kaber@trash.net>");
123MODULE_ALIAS_NFT_EXPR("reject");