2 * Copyright (c) 2014 Pablo Neira Ayuso <pablo@netfilter.org>
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.
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_tables.h>
16 #include <net/netfilter/nft_reject.h>
17 #include <net/netfilter/ipv4/nf_reject.h>
18 #include <net/netfilter/ipv6/nf_reject.h>
21 #include <net/ip6_checksum.h>
22 #include <linux/netfilter_bridge.h>
23 #include "../br_private.h"
25 static void nft_reject_br_push_etherhdr(struct sk_buff
*oldskb
,
30 eth
= (struct ethhdr
*)skb_push(nskb
, ETH_HLEN
);
31 skb_reset_mac_header(nskb
);
32 ether_addr_copy(eth
->h_source
, eth_hdr(oldskb
)->h_dest
);
33 ether_addr_copy(eth
->h_dest
, eth_hdr(oldskb
)->h_source
);
34 eth
->h_proto
= eth_hdr(oldskb
)->h_proto
;
35 skb_pull(nskb
, ETH_HLEN
);
38 static int nft_reject_iphdr_validate(struct sk_buff
*oldskb
)
43 if (!pskb_may_pull(oldskb
, sizeof(struct iphdr
)))
47 if (iph
->ihl
< 5 || iph
->version
!= 4)
50 len
= ntohs(iph
->tot_len
);
51 if (oldskb
->len
< len
)
53 else if (len
< (iph
->ihl
*4))
56 if (!pskb_may_pull(oldskb
, iph
->ihl
*4))
62 static void nft_reject_br_send_v4_tcp_reset(struct sk_buff
*oldskb
, int hook
)
66 const struct tcphdr
*oth
;
69 if (!nft_reject_iphdr_validate(oldskb
))
72 oth
= nf_reject_ip_tcphdr_get(oldskb
, &_oth
, hook
);
76 nskb
= alloc_skb(sizeof(struct iphdr
) + sizeof(struct tcphdr
) +
77 LL_MAX_HEADER
, GFP_ATOMIC
);
81 skb_reserve(nskb
, LL_MAX_HEADER
);
82 niph
= nf_reject_iphdr_put(nskb
, oldskb
, IPPROTO_TCP
,
83 sysctl_ip_default_ttl
);
84 nf_reject_ip_tcphdr_put(nskb
, oldskb
, oth
);
85 niph
->ttl
= sysctl_ip_default_ttl
;
86 niph
->tot_len
= htons(nskb
->len
);
89 nft_reject_br_push_etherhdr(oldskb
, nskb
);
91 br_deliver(br_port_get_rcu(oldskb
->dev
), nskb
);
94 static void nft_reject_br_send_v4_unreach(struct sk_buff
*oldskb
, int hook
,
99 struct icmphdr
*icmph
;
104 if (!nft_reject_iphdr_validate(oldskb
))
107 /* IP header checks: fragment. */
108 if (ip_hdr(oldskb
)->frag_off
& htons(IP_OFFSET
))
111 /* RFC says return as much as we can without exceeding 576 bytes. */
112 len
= min_t(unsigned int, 536, oldskb
->len
);
114 if (!pskb_may_pull(oldskb
, len
))
117 if (nf_ip_checksum(oldskb
, hook
, ip_hdrlen(oldskb
), 0))
120 nskb
= alloc_skb(sizeof(struct iphdr
) + sizeof(struct icmphdr
) +
121 LL_MAX_HEADER
+ len
, GFP_ATOMIC
);
125 skb_reserve(nskb
, LL_MAX_HEADER
);
126 niph
= nf_reject_iphdr_put(nskb
, oldskb
, IPPROTO_ICMP
,
127 sysctl_ip_default_ttl
);
129 skb_reset_transport_header(nskb
);
130 icmph
= (struct icmphdr
*)skb_put(nskb
, sizeof(struct icmphdr
));
131 memset(icmph
, 0, sizeof(*icmph
));
132 icmph
->type
= ICMP_DEST_UNREACH
;
135 payload
= skb_put(nskb
, len
);
136 memcpy(payload
, skb_network_header(oldskb
), len
);
138 csum
= csum_partial((void *)icmph
, len
+ sizeof(struct icmphdr
), 0);
139 icmph
->checksum
= csum_fold(csum
);
141 niph
->tot_len
= htons(nskb
->len
);
144 nft_reject_br_push_etherhdr(oldskb
, nskb
);
146 br_deliver(br_port_get_rcu(oldskb
->dev
), nskb
);
149 static int nft_reject_ip6hdr_validate(struct sk_buff
*oldskb
)
154 if (!pskb_may_pull(oldskb
, sizeof(struct ipv6hdr
)))
157 hdr
= ipv6_hdr(oldskb
);
158 if (hdr
->version
!= 6)
161 pkt_len
= ntohs(hdr
->payload_len
);
162 if (pkt_len
+ sizeof(struct ipv6hdr
) > oldskb
->len
)
168 static void nft_reject_br_send_v6_tcp_reset(struct net
*net
,
169 struct sk_buff
*oldskb
, int hook
)
171 struct sk_buff
*nskb
;
172 const struct tcphdr
*oth
;
174 unsigned int otcplen
;
175 struct ipv6hdr
*nip6h
;
177 if (!nft_reject_ip6hdr_validate(oldskb
))
180 oth
= nf_reject_ip6_tcphdr_get(oldskb
, &_oth
, &otcplen
, hook
);
184 nskb
= alloc_skb(sizeof(struct ipv6hdr
) + sizeof(struct tcphdr
) +
185 LL_MAX_HEADER
, GFP_ATOMIC
);
189 skb_reserve(nskb
, LL_MAX_HEADER
);
190 nip6h
= nf_reject_ip6hdr_put(nskb
, oldskb
, IPPROTO_TCP
,
191 net
->ipv6
.devconf_all
->hop_limit
);
192 nf_reject_ip6_tcphdr_put(nskb
, oldskb
, oth
, otcplen
);
193 nip6h
->payload_len
= htons(nskb
->len
- sizeof(struct ipv6hdr
));
195 nft_reject_br_push_etherhdr(oldskb
, nskb
);
197 br_deliver(br_port_get_rcu(oldskb
->dev
), nskb
);
200 static void nft_reject_br_send_v6_unreach(struct net
*net
,
201 struct sk_buff
*oldskb
, int hook
,
204 struct sk_buff
*nskb
;
205 struct ipv6hdr
*nip6h
;
206 struct icmp6hdr
*icmp6h
;
210 if (!nft_reject_ip6hdr_validate(oldskb
))
213 /* Include "As much of invoking packet as possible without the ICMPv6
214 * packet exceeding the minimum IPv6 MTU" in the ICMP payload.
216 len
= min_t(unsigned int, 1220, oldskb
->len
);
218 if (!pskb_may_pull(oldskb
, len
))
221 nskb
= alloc_skb(sizeof(struct iphdr
) + sizeof(struct icmp6hdr
) +
222 LL_MAX_HEADER
+ len
, GFP_ATOMIC
);
226 skb_reserve(nskb
, LL_MAX_HEADER
);
227 nip6h
= nf_reject_ip6hdr_put(nskb
, oldskb
, IPPROTO_ICMPV6
,
228 net
->ipv6
.devconf_all
->hop_limit
);
230 skb_reset_transport_header(nskb
);
231 icmp6h
= (struct icmp6hdr
*)skb_put(nskb
, sizeof(struct icmp6hdr
));
232 memset(icmp6h
, 0, sizeof(*icmp6h
));
233 icmp6h
->icmp6_type
= ICMPV6_DEST_UNREACH
;
234 icmp6h
->icmp6_code
= code
;
236 payload
= skb_put(nskb
, len
);
237 memcpy(payload
, skb_network_header(oldskb
), len
);
238 nip6h
->payload_len
= htons(nskb
->len
- sizeof(struct ipv6hdr
));
240 icmp6h
->icmp6_cksum
=
241 csum_ipv6_magic(&nip6h
->saddr
, &nip6h
->daddr
,
242 nskb
->len
- sizeof(struct ipv6hdr
),
245 nskb
->len
- sizeof(struct ipv6hdr
),
248 nft_reject_br_push_etherhdr(oldskb
, nskb
);
250 br_deliver(br_port_get_rcu(oldskb
->dev
), nskb
);
253 static void nft_reject_bridge_eval(const struct nft_expr
*expr
,
254 struct nft_data data
[NFT_REG_MAX
+ 1],
255 const struct nft_pktinfo
*pkt
)
257 struct nft_reject
*priv
= nft_expr_priv(expr
);
258 struct net
*net
= dev_net((pkt
->in
!= NULL
) ? pkt
->in
: pkt
->out
);
259 const unsigned char *dest
= eth_hdr(pkt
->skb
)->h_dest
;
261 if (is_broadcast_ether_addr(dest
) ||
262 is_multicast_ether_addr(dest
))
265 switch (eth_hdr(pkt
->skb
)->h_proto
) {
266 case htons(ETH_P_IP
):
267 switch (priv
->type
) {
268 case NFT_REJECT_ICMP_UNREACH
:
269 nft_reject_br_send_v4_unreach(pkt
->skb
,
273 case NFT_REJECT_TCP_RST
:
274 nft_reject_br_send_v4_tcp_reset(pkt
->skb
,
277 case NFT_REJECT_ICMPX_UNREACH
:
278 nft_reject_br_send_v4_unreach(pkt
->skb
,
280 nft_reject_icmp_code(priv
->icmp_code
));
284 case htons(ETH_P_IPV6
):
285 switch (priv
->type
) {
286 case NFT_REJECT_ICMP_UNREACH
:
287 nft_reject_br_send_v6_unreach(net
, pkt
->skb
,
291 case NFT_REJECT_TCP_RST
:
292 nft_reject_br_send_v6_tcp_reset(net
, pkt
->skb
,
295 case NFT_REJECT_ICMPX_UNREACH
:
296 nft_reject_br_send_v6_unreach(net
, pkt
->skb
,
298 nft_reject_icmpv6_code(priv
->icmp_code
));
303 /* No explicit way to reject this protocol, drop it. */
307 data
[NFT_REG_VERDICT
].verdict
= NF_DROP
;
310 static int nft_reject_bridge_validate_hooks(const struct nft_chain
*chain
)
312 struct nft_base_chain
*basechain
;
314 if (chain
->flags
& NFT_BASE_CHAIN
) {
315 basechain
= nft_base_chain(chain
);
317 switch (basechain
->ops
[0].hooknum
) {
318 case NF_BR_PRE_ROUTING
:
328 static int nft_reject_bridge_init(const struct nft_ctx
*ctx
,
329 const struct nft_expr
*expr
,
330 const struct nlattr
* const tb
[])
332 struct nft_reject
*priv
= nft_expr_priv(expr
);
335 err
= nft_reject_bridge_validate_hooks(ctx
->chain
);
339 if (tb
[NFTA_REJECT_TYPE
] == NULL
)
342 priv
->type
= ntohl(nla_get_be32(tb
[NFTA_REJECT_TYPE
]));
343 switch (priv
->type
) {
344 case NFT_REJECT_ICMP_UNREACH
:
345 case NFT_REJECT_ICMPX_UNREACH
:
346 if (tb
[NFTA_REJECT_ICMP_CODE
] == NULL
)
349 icmp_code
= nla_get_u8(tb
[NFTA_REJECT_ICMP_CODE
]);
350 if (priv
->type
== NFT_REJECT_ICMPX_UNREACH
&&
351 icmp_code
> NFT_REJECT_ICMPX_MAX
)
354 priv
->icmp_code
= icmp_code
;
356 case NFT_REJECT_TCP_RST
:
364 static int nft_reject_bridge_dump(struct sk_buff
*skb
,
365 const struct nft_expr
*expr
)
367 const struct nft_reject
*priv
= nft_expr_priv(expr
);
369 if (nla_put_be32(skb
, NFTA_REJECT_TYPE
, htonl(priv
->type
)))
370 goto nla_put_failure
;
372 switch (priv
->type
) {
373 case NFT_REJECT_ICMP_UNREACH
:
374 case NFT_REJECT_ICMPX_UNREACH
:
375 if (nla_put_u8(skb
, NFTA_REJECT_ICMP_CODE
, priv
->icmp_code
))
376 goto nla_put_failure
;
386 static int nft_reject_bridge_validate(const struct nft_ctx
*ctx
,
387 const struct nft_expr
*expr
,
388 const struct nft_data
**data
)
390 return nft_reject_bridge_validate_hooks(ctx
->chain
);
393 static struct nft_expr_type nft_reject_bridge_type
;
394 static const struct nft_expr_ops nft_reject_bridge_ops
= {
395 .type
= &nft_reject_bridge_type
,
396 .size
= NFT_EXPR_SIZE(sizeof(struct nft_reject
)),
397 .eval
= nft_reject_bridge_eval
,
398 .init
= nft_reject_bridge_init
,
399 .dump
= nft_reject_bridge_dump
,
400 .validate
= nft_reject_bridge_validate
,
403 static struct nft_expr_type nft_reject_bridge_type __read_mostly
= {
404 .family
= NFPROTO_BRIDGE
,
406 .ops
= &nft_reject_bridge_ops
,
407 .policy
= nft_reject_policy
,
408 .maxattr
= NFTA_REJECT_MAX
,
409 .owner
= THIS_MODULE
,
412 static int __init
nft_reject_bridge_module_init(void)
414 return nft_register_expr(&nft_reject_bridge_type
);
417 static void __exit
nft_reject_bridge_module_exit(void)
419 nft_unregister_expr(&nft_reject_bridge_type
);
422 module_init(nft_reject_bridge_module_init
);
423 module_exit(nft_reject_bridge_module_exit
);
425 MODULE_LICENSE("GPL");
426 MODULE_AUTHOR("Pablo Neira Ayuso <pablo@netfilter.org>");
427 MODULE_ALIAS_NFT_AF_EXPR(AF_BRIDGE
, "reject");