root/net/netfilter/nft_reject_inet.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. nft_reject_inet_eval
  2. nft_reject_inet_init
  3. nft_reject_inet_dump
  4. nft_reject_inet_module_init
  5. nft_reject_inet_module_exit

   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 
  17 static 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), pkt->skb, nft_hook(pkt));
  32                         break;
  33                 case NFT_REJECT_ICMPX_UNREACH:
  34                         nf_send_unreach(pkt->skb,
  35                                         nft_reject_icmp_code(priv->icmp_code),
  36                                         nft_hook(pkt));
  37                         break;
  38                 }
  39                 break;
  40         case NFPROTO_IPV6:
  41                 switch (priv->type) {
  42                 case NFT_REJECT_ICMP_UNREACH:
  43                         nf_send_unreach6(nft_net(pkt), pkt->skb,
  44                                          priv->icmp_code, nft_hook(pkt));
  45                         break;
  46                 case NFT_REJECT_TCP_RST:
  47                         nf_send_reset6(nft_net(pkt), pkt->skb, nft_hook(pkt));
  48                         break;
  49                 case NFT_REJECT_ICMPX_UNREACH:
  50                         nf_send_unreach6(nft_net(pkt), pkt->skb,
  51                                          nft_reject_icmpv6_code(priv->icmp_code),
  52                                          nft_hook(pkt));
  53                         break;
  54                 }
  55                 break;
  56         }
  57 
  58         regs->verdict.code = NF_DROP;
  59 }
  60 
  61 static int nft_reject_inet_init(const struct nft_ctx *ctx,
  62                                 const struct nft_expr *expr,
  63                                 const struct nlattr * const tb[])
  64 {
  65         struct nft_reject *priv = nft_expr_priv(expr);
  66         int icmp_code;
  67 
  68         if (tb[NFTA_REJECT_TYPE] == NULL)
  69                 return -EINVAL;
  70 
  71         priv->type = ntohl(nla_get_be32(tb[NFTA_REJECT_TYPE]));
  72         switch (priv->type) {
  73         case NFT_REJECT_ICMP_UNREACH:
  74         case NFT_REJECT_ICMPX_UNREACH:
  75                 if (tb[NFTA_REJECT_ICMP_CODE] == NULL)
  76                         return -EINVAL;
  77 
  78                 icmp_code = nla_get_u8(tb[NFTA_REJECT_ICMP_CODE]);
  79                 if (priv->type == NFT_REJECT_ICMPX_UNREACH &&
  80                     icmp_code > NFT_REJECT_ICMPX_MAX)
  81                         return -EINVAL;
  82 
  83                 priv->icmp_code = icmp_code;
  84                 break;
  85         case NFT_REJECT_TCP_RST:
  86                 break;
  87         default:
  88                 return -EINVAL;
  89         }
  90         return 0;
  91 }
  92 
  93 static int nft_reject_inet_dump(struct sk_buff *skb,
  94                                 const struct nft_expr *expr)
  95 {
  96         const struct nft_reject *priv = nft_expr_priv(expr);
  97 
  98         if (nla_put_be32(skb, NFTA_REJECT_TYPE, htonl(priv->type)))
  99                 goto nla_put_failure;
 100 
 101         switch (priv->type) {
 102         case NFT_REJECT_ICMP_UNREACH:
 103         case NFT_REJECT_ICMPX_UNREACH:
 104                 if (nla_put_u8(skb, NFTA_REJECT_ICMP_CODE, priv->icmp_code))
 105                         goto nla_put_failure;
 106                 break;
 107         default:
 108                 break;
 109         }
 110 
 111         return 0;
 112 
 113 nla_put_failure:
 114         return -1;
 115 }
 116 
 117 static struct nft_expr_type nft_reject_inet_type;
 118 static const struct nft_expr_ops nft_reject_inet_ops = {
 119         .type           = &nft_reject_inet_type,
 120         .size           = NFT_EXPR_SIZE(sizeof(struct nft_reject)),
 121         .eval           = nft_reject_inet_eval,
 122         .init           = nft_reject_inet_init,
 123         .dump           = nft_reject_inet_dump,
 124         .validate       = nft_reject_validate,
 125 };
 126 
 127 static struct nft_expr_type nft_reject_inet_type __read_mostly = {
 128         .family         = NFPROTO_INET,
 129         .name           = "reject",
 130         .ops            = &nft_reject_inet_ops,
 131         .policy         = nft_reject_policy,
 132         .maxattr        = NFTA_REJECT_MAX,
 133         .owner          = THIS_MODULE,
 134 };
 135 
 136 static int __init nft_reject_inet_module_init(void)
 137 {
 138         return nft_register_expr(&nft_reject_inet_type);
 139 }
 140 
 141 static void __exit nft_reject_inet_module_exit(void)
 142 {
 143         nft_unregister_expr(&nft_reject_inet_type);
 144 }
 145 
 146 module_init(nft_reject_inet_module_init);
 147 module_exit(nft_reject_inet_module_exit);
 148 
 149 MODULE_LICENSE("GPL");
 150 MODULE_AUTHOR("Patrick McHardy <kaber@trash.net>");
 151 MODULE_ALIAS_NFT_AF_EXPR(1, "reject");

/* [<][>][^][v][top][bottom][index][help] */