Commit | Line | Data |
---|---|---|
d2912cb1 | 1 | // SPDX-License-Identifier: GPL-2.0-only |
05513e9e PM |
2 | /* |
3 | * Copyright (c) 2014 Patrick McHardy <kaber@trash.net> | |
05513e9e PM |
4 | */ |
5 | ||
6 | #include <linux/kernel.h> | |
7 | #include <linux/init.h> | |
8 | #include <linux/module.h> | |
9 | #include <linux/netlink.h> | |
10 | #include <linux/netfilter.h> | |
11 | #include <linux/netfilter/nf_tables.h> | |
12 | #include <net/netfilter/nf_tables.h> | |
13 | #include <net/netfilter/nft_reject.h> | |
51b0a5d8 PNA |
14 | #include <net/netfilter/ipv4/nf_reject.h> |
15 | #include <net/netfilter/ipv6/nf_reject.h> | |
05513e9e PM |
16 | |
17 | static void nft_reject_inet_eval(const struct nft_expr *expr, | |
a55e22e9 | 18 | struct nft_regs *regs, |
05513e9e PM |
19 | const struct nft_pktinfo *pkt) |
20 | { | |
51b0a5d8 | 21 | struct nft_reject *priv = nft_expr_priv(expr); |
51b0a5d8 | 22 | |
0e5a1c7e | 23 | switch (nft_pf(pkt)) { |
05513e9e | 24 | case NFPROTO_IPV4: |
51b0a5d8 PNA |
25 | switch (priv->type) { |
26 | case NFT_REJECT_ICMP_UNREACH: | |
ee586bbc | 27 | nf_send_unreach(pkt->skb, priv->icmp_code, |
0e5a1c7e | 28 | nft_hook(pkt)); |
51b0a5d8 PNA |
29 | break; |
30 | case NFT_REJECT_TCP_RST: | |
85554eb9 | 31 | nf_send_reset(nft_net(pkt), nft_sk(pkt), |
04295878 | 32 | pkt->skb, nft_hook(pkt)); |
51b0a5d8 PNA |
33 | break; |
34 | case NFT_REJECT_ICMPX_UNREACH: | |
35 | nf_send_unreach(pkt->skb, | |
ee586bbc | 36 | nft_reject_icmp_code(priv->icmp_code), |
0e5a1c7e | 37 | nft_hook(pkt)); |
51b0a5d8 PNA |
38 | break; |
39 | } | |
40 | break; | |
05513e9e | 41 | case NFPROTO_IPV6: |
51b0a5d8 PNA |
42 | switch (priv->type) { |
43 | case NFT_REJECT_ICMP_UNREACH: | |
0e5a1c7e PNA |
44 | nf_send_unreach6(nft_net(pkt), pkt->skb, |
45 | priv->icmp_code, nft_hook(pkt)); | |
51b0a5d8 PNA |
46 | break; |
47 | case NFT_REJECT_TCP_RST: | |
85554eb9 | 48 | nf_send_reset6(nft_net(pkt), nft_sk(pkt), |
04295878 | 49 | pkt->skb, nft_hook(pkt)); |
51b0a5d8 PNA |
50 | break; |
51 | case NFT_REJECT_ICMPX_UNREACH: | |
0e5a1c7e | 52 | nf_send_unreach6(nft_net(pkt), pkt->skb, |
51b0a5d8 | 53 | nft_reject_icmpv6_code(priv->icmp_code), |
0e5a1c7e | 54 | nft_hook(pkt)); |
51b0a5d8 PNA |
55 | break; |
56 | } | |
57 | break; | |
58 | } | |
a55e22e9 PM |
59 | |
60 | regs->verdict.code = NF_DROP; | |
51b0a5d8 PNA |
61 | } |
62 | ||
117ca1f8 PNA |
63 | static int nft_reject_inet_validate(const struct nft_ctx *ctx, |
64 | const struct nft_expr *expr, | |
65 | const struct nft_data **data) | |
66 | { | |
67 | return nft_chain_validate_hooks(ctx->chain, | |
68 | (1 << NF_INET_LOCAL_IN) | | |
69 | (1 << NF_INET_FORWARD) | | |
70 | (1 << NF_INET_LOCAL_OUT) | | |
71 | (1 << NF_INET_PRE_ROUTING) | | |
72 | (1 << NF_INET_INGRESS)); | |
73 | } | |
74 | ||
05513e9e PM |
75 | static struct nft_expr_type nft_reject_inet_type; |
76 | static const struct nft_expr_ops nft_reject_inet_ops = { | |
77 | .type = &nft_reject_inet_type, | |
78 | .size = NFT_EXPR_SIZE(sizeof(struct nft_reject)), | |
79 | .eval = nft_reject_inet_eval, | |
312ca575 JGG |
80 | .init = nft_reject_init, |
81 | .dump = nft_reject_dump, | |
117ca1f8 | 82 | .validate = nft_reject_inet_validate, |
b2d30654 | 83 | .reduce = NFT_REDUCE_READONLY, |
05513e9e PM |
84 | }; |
85 | ||
86 | static struct nft_expr_type nft_reject_inet_type __read_mostly = { | |
87 | .family = NFPROTO_INET, | |
88 | .name = "reject", | |
89 | .ops = &nft_reject_inet_ops, | |
90 | .policy = nft_reject_policy, | |
91 | .maxattr = NFTA_REJECT_MAX, | |
92 | .owner = THIS_MODULE, | |
93 | }; | |
94 | ||
95 | static int __init nft_reject_inet_module_init(void) | |
96 | { | |
97 | return nft_register_expr(&nft_reject_inet_type); | |
98 | } | |
99 | ||
100 | static void __exit nft_reject_inet_module_exit(void) | |
101 | { | |
102 | nft_unregister_expr(&nft_reject_inet_type); | |
103 | } | |
104 | ||
105 | module_init(nft_reject_inet_module_init); | |
106 | module_exit(nft_reject_inet_module_exit); | |
107 | ||
108 | MODULE_LICENSE("GPL"); | |
109 | MODULE_AUTHOR("Patrick McHardy <kaber@trash.net>"); | |
110 | MODULE_ALIAS_NFT_AF_EXPR(1, "reject"); | |
4cacc395 | 111 | MODULE_DESCRIPTION("Netfilter nftables reject inet support"); |