1 // SPDX-License-Identifier: GPL-2.0-or-later
3 * IP6 tables REJECT target module
4 * Linux INET6 implementation
6 * Copyright (C)2003 USAGI/WIDE Project
9 * Yasuyuki Kozakai <yasuyuki.kozakai@toshiba.co.jp>
11 * Copyright (c) 2005-2007 Patrick McHardy <kaber@trash.net>
13 * Based on net/ipv4/netfilter/ipt_REJECT.c
15 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
17 #include <linux/gfp.h>
18 #include <linux/module.h>
19 #include <linux/skbuff.h>
20 #include <linux/icmpv6.h>
21 #include <linux/netdevice.h>
24 #include <linux/netfilter/x_tables.h>
25 #include <linux/netfilter_ipv6/ip6_tables.h>
26 #include <linux/netfilter_ipv6/ip6t_REJECT.h>
28 #include <net/netfilter/ipv6/nf_reject.h>
30 MODULE_AUTHOR("Yasuyuki KOZAKAI <yasuyuki.kozakai@toshiba.co.jp>");
31 MODULE_DESCRIPTION("Xtables: packet \"rejection\" target for IPv6");
32 MODULE_LICENSE("GPL");
35 reject_tg6(struct sk_buff
*skb
, const struct xt_action_param
*par
)
37 const struct ip6t_reject_info
*reject
= par
->targinfo
;
38 struct net
*net
= xt_net(par
);
40 switch (reject
->with
) {
41 case IP6T_ICMP6_NO_ROUTE
:
42 nf_send_unreach6(net
, skb
, ICMPV6_NOROUTE
, xt_hooknum(par
));
44 case IP6T_ICMP6_ADM_PROHIBITED
:
45 nf_send_unreach6(net
, skb
, ICMPV6_ADM_PROHIBITED
,
48 case IP6T_ICMP6_NOT_NEIGHBOUR
:
49 nf_send_unreach6(net
, skb
, ICMPV6_NOT_NEIGHBOUR
,
52 case IP6T_ICMP6_ADDR_UNREACH
:
53 nf_send_unreach6(net
, skb
, ICMPV6_ADDR_UNREACH
,
56 case IP6T_ICMP6_PORT_UNREACH
:
57 nf_send_unreach6(net
, skb
, ICMPV6_PORT_UNREACH
,
60 case IP6T_ICMP6_ECHOREPLY
:
64 nf_send_reset6(net
, par
->state
->sk
, skb
, xt_hooknum(par
));
66 case IP6T_ICMP6_POLICY_FAIL
:
67 nf_send_unreach6(net
, skb
, ICMPV6_POLICY_FAIL
, xt_hooknum(par
));
69 case IP6T_ICMP6_REJECT_ROUTE
:
70 nf_send_unreach6(net
, skb
, ICMPV6_REJECT_ROUTE
,
78 static int reject_tg6_check(const struct xt_tgchk_param
*par
)
80 const struct ip6t_reject_info
*rejinfo
= par
->targinfo
;
81 const struct ip6t_entry
*e
= par
->entryinfo
;
83 if (rejinfo
->with
== IP6T_ICMP6_ECHOREPLY
) {
84 pr_info_ratelimited("ECHOREPLY is not supported\n");
86 } else if (rejinfo
->with
== IP6T_TCP_RESET
) {
87 /* Must specify that it's a TCP packet */
88 if (!(e
->ipv6
.flags
& IP6T_F_PROTO
) ||
89 e
->ipv6
.proto
!= IPPROTO_TCP
||
90 (e
->ipv6
.invflags
& XT_INV_PROTO
)) {
91 pr_info_ratelimited("TCP_RESET illegal for non-tcp\n");
98 static struct xt_target reject_tg6_reg __read_mostly
= {
100 .family
= NFPROTO_IPV6
,
101 .target
= reject_tg6
,
102 .targetsize
= sizeof(struct ip6t_reject_info
),
104 .hooks
= (1 << NF_INET_LOCAL_IN
) | (1 << NF_INET_FORWARD
) |
105 (1 << NF_INET_LOCAL_OUT
),
106 .checkentry
= reject_tg6_check
,
110 static int __init
reject_tg6_init(void)
112 return xt_register_target(&reject_tg6_reg
);
115 static void __exit
reject_tg6_exit(void)
117 xt_unregister_target(&reject_tg6_reg
);
120 module_init(reject_tg6_init
);
121 module_exit(reject_tg6_exit
);