Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-only
0002 /*
0003  * Copyright (c) 2014 Patrick McHardy <kaber@trash.net>
0004  */
0005 
0006 #include <linux/kernel.h>
0007 #include <linux/init.h>
0008 #include <linux/module.h>
0009 #include <linux/netlink.h>
0010 #include <linux/netfilter.h>
0011 #include <linux/netfilter/nf_tables.h>
0012 #include <net/netfilter/nf_tables.h>
0013 #include <net/netfilter/nft_reject.h>
0014 #include <net/netfilter/ipv4/nf_reject.h>
0015 #include <net/netfilter/ipv6/nf_reject.h>
0016 
0017 static void nft_reject_inet_eval(const struct nft_expr *expr,
0018                  struct nft_regs *regs,
0019                  const struct nft_pktinfo *pkt)
0020 {
0021     struct nft_reject *priv = nft_expr_priv(expr);
0022 
0023     switch (nft_pf(pkt)) {
0024     case NFPROTO_IPV4:
0025         switch (priv->type) {
0026         case NFT_REJECT_ICMP_UNREACH:
0027             nf_send_unreach(pkt->skb, priv->icmp_code,
0028                     nft_hook(pkt));
0029             break;
0030         case NFT_REJECT_TCP_RST:
0031             nf_send_reset(nft_net(pkt), nft_sk(pkt),
0032                       pkt->skb, nft_hook(pkt));
0033             break;
0034         case NFT_REJECT_ICMPX_UNREACH:
0035             nf_send_unreach(pkt->skb,
0036                     nft_reject_icmp_code(priv->icmp_code),
0037                     nft_hook(pkt));
0038             break;
0039         }
0040         break;
0041     case NFPROTO_IPV6:
0042         switch (priv->type) {
0043         case NFT_REJECT_ICMP_UNREACH:
0044             nf_send_unreach6(nft_net(pkt), pkt->skb,
0045                      priv->icmp_code, nft_hook(pkt));
0046             break;
0047         case NFT_REJECT_TCP_RST:
0048             nf_send_reset6(nft_net(pkt), nft_sk(pkt),
0049                        pkt->skb, nft_hook(pkt));
0050             break;
0051         case NFT_REJECT_ICMPX_UNREACH:
0052             nf_send_unreach6(nft_net(pkt), pkt->skb,
0053                      nft_reject_icmpv6_code(priv->icmp_code),
0054                      nft_hook(pkt));
0055             break;
0056         }
0057         break;
0058     }
0059 
0060     regs->verdict.code = NF_DROP;
0061 }
0062 
0063 static int nft_reject_inet_validate(const struct nft_ctx *ctx,
0064                     const struct nft_expr *expr,
0065                     const struct nft_data **data)
0066 {
0067     return nft_chain_validate_hooks(ctx->chain,
0068                     (1 << NF_INET_LOCAL_IN) |
0069                     (1 << NF_INET_FORWARD) |
0070                     (1 << NF_INET_LOCAL_OUT) |
0071                     (1 << NF_INET_PRE_ROUTING) |
0072                     (1 << NF_INET_INGRESS));
0073 }
0074 
0075 static struct nft_expr_type nft_reject_inet_type;
0076 static const struct nft_expr_ops nft_reject_inet_ops = {
0077     .type       = &nft_reject_inet_type,
0078     .size       = NFT_EXPR_SIZE(sizeof(struct nft_reject)),
0079     .eval       = nft_reject_inet_eval,
0080     .init       = nft_reject_init,
0081     .dump       = nft_reject_dump,
0082     .validate   = nft_reject_inet_validate,
0083     .reduce     = NFT_REDUCE_READONLY,
0084 };
0085 
0086 static struct nft_expr_type nft_reject_inet_type __read_mostly = {
0087     .family     = NFPROTO_INET,
0088     .name       = "reject",
0089     .ops        = &nft_reject_inet_ops,
0090     .policy     = nft_reject_policy,
0091     .maxattr    = NFTA_REJECT_MAX,
0092     .owner      = THIS_MODULE,
0093 };
0094 
0095 static int __init nft_reject_inet_module_init(void)
0096 {
0097     return nft_register_expr(&nft_reject_inet_type);
0098 }
0099 
0100 static void __exit nft_reject_inet_module_exit(void)
0101 {
0102     nft_unregister_expr(&nft_reject_inet_type);
0103 }
0104 
0105 module_init(nft_reject_inet_module_init);
0106 module_exit(nft_reject_inet_module_exit);
0107 
0108 MODULE_LICENSE("GPL");
0109 MODULE_AUTHOR("Patrick McHardy <kaber@trash.net>");
0110 MODULE_ALIAS_NFT_AF_EXPR(1, "reject");
0111 MODULE_DESCRIPTION("Netfilter nftables reject inet support");