linux/net/netfilter/nft_reject_inet.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0-only
   2/*
   3 * Copyright (c) 2014 Patrick McHardy <kaber@trash.net>
   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>
  14#include <net/netfilter/ipv4/nf_reject.h>
  15#include <net/netfilter/ipv6/nf_reject.h>
  16
  17static void nft_reject_inet_eval(const struct nft_expr *expr,
  18                                 struct nft_regs *regs,
  19                                 const struct nft_pktinfo *pkt)
  20{
  21        struct nft_reject *priv = nft_expr_priv(expr);
  22
  23        switch (nft_pf(pkt)) {
  24        case NFPROTO_IPV4:
  25                switch (priv->type) {
  26                case NFT_REJECT_ICMP_UNREACH:
  27                        nf_send_unreach(pkt->skb, priv->icmp_code,
  28                                        nft_hook(pkt));
  29                        break;
  30                case NFT_REJECT_TCP_RST:
  31                        nf_send_reset(nft_net(pkt), nft_sk(pkt),
  32                                      pkt->skb, nft_hook(pkt));
  33                        break;
  34                case NFT_REJECT_ICMPX_UNREACH:
  35                        nf_send_unreach(pkt->skb,
  36                                        nft_reject_icmp_code(priv->icmp_code),
  37                                        nft_hook(pkt));
  38                        break;
  39                }
  40                break;
  41        case NFPROTO_IPV6:
  42                switch (priv->type) {
  43                case NFT_REJECT_ICMP_UNREACH:
  44                        nf_send_unreach6(nft_net(pkt), pkt->skb,
  45                                         priv->icmp_code, nft_hook(pkt));
  46                        break;
  47                case NFT_REJECT_TCP_RST:
  48                        nf_send_reset6(nft_net(pkt), nft_sk(pkt),
  49                                       pkt->skb, nft_hook(pkt));
  50                        break;
  51                case NFT_REJECT_ICMPX_UNREACH:
  52                        nf_send_unreach6(nft_net(pkt), pkt->skb,
  53                                         nft_reject_icmpv6_code(priv->icmp_code),
  54                                         nft_hook(pkt));
  55                        break;
  56                }
  57                break;
  58        }
  59
  60        regs->verdict.code = NF_DROP;
  61}
  62
  63static 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
  75static struct nft_expr_type nft_reject_inet_type;
  76static 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,
  80        .init           = nft_reject_init,
  81        .dump           = nft_reject_dump,
  82        .validate       = nft_reject_inet_validate,
  83        .reduce         = NFT_REDUCE_READONLY,
  84};
  85
  86static 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
  95static int __init nft_reject_inet_module_init(void)
  96{
  97        return nft_register_expr(&nft_reject_inet_type);
  98}
  99
 100static void __exit nft_reject_inet_module_exit(void)
 101{
 102        nft_unregister_expr(&nft_reject_inet_type);
 103}
 104
 105module_init(nft_reject_inet_module_init);
 106module_exit(nft_reject_inet_module_exit);
 107
 108MODULE_LICENSE("GPL");
 109MODULE_AUTHOR("Patrick McHardy <kaber@trash.net>");
 110MODULE_ALIAS_NFT_AF_EXPR(1, "reject");
 111MODULE_DESCRIPTION("Netfilter nftables reject inet support");
 112