linux/net/netfilter/nft_reject.c
<<
>>
Prefs
   1/*
   2 * Copyright (c) 2008-2009 Patrick McHardy <kaber@trash.net>
   3 * Copyright (c) 2013 Eric Leblond <eric@regit.org>
   4 *
   5 * This program is free software; you can redistribute it and/or modify
   6 * it under the terms of the GNU General Public License version 2 as
   7 * published by the Free Software Foundation.
   8 *
   9 * Development of this code funded by Astaro AG (http://www.astaro.com/)
  10 */
  11
  12#include <linux/kernel.h>
  13#include <linux/init.h>
  14#include <linux/module.h>
  15#include <linux/netlink.h>
  16#include <linux/netfilter.h>
  17#include <linux/netfilter/nf_tables.h>
  18#include <net/netfilter/nf_tables.h>
  19#include <net/netfilter/nft_reject.h>
  20#include <linux/icmp.h>
  21#include <linux/icmpv6.h>
  22
  23const struct nla_policy nft_reject_policy[NFTA_REJECT_MAX + 1] = {
  24        [NFTA_REJECT_TYPE]              = { .type = NLA_U32 },
  25        [NFTA_REJECT_ICMP_CODE]         = { .type = NLA_U8 },
  26};
  27EXPORT_SYMBOL_GPL(nft_reject_policy);
  28
  29int nft_reject_validate(const struct nft_ctx *ctx,
  30                        const struct nft_expr *expr,
  31                        const struct nft_data **data)
  32{
  33        return nft_chain_validate_hooks(ctx->chain,
  34                                        (1 << NF_INET_LOCAL_IN) |
  35                                        (1 << NF_INET_FORWARD) |
  36                                        (1 << NF_INET_LOCAL_OUT));
  37}
  38EXPORT_SYMBOL_GPL(nft_reject_validate);
  39
  40int nft_reject_init(const struct nft_ctx *ctx,
  41                    const struct nft_expr *expr,
  42                    const struct nlattr * const tb[])
  43{
  44        struct nft_reject *priv = nft_expr_priv(expr);
  45        int err;
  46
  47        err = nft_reject_validate(ctx, expr, NULL);
  48        if (err < 0)
  49                return err;
  50
  51        if (tb[NFTA_REJECT_TYPE] == NULL)
  52                return -EINVAL;
  53
  54        priv->type = ntohl(nla_get_be32(tb[NFTA_REJECT_TYPE]));
  55        switch (priv->type) {
  56        case NFT_REJECT_ICMP_UNREACH:
  57                if (tb[NFTA_REJECT_ICMP_CODE] == NULL)
  58                        return -EINVAL;
  59                priv->icmp_code = nla_get_u8(tb[NFTA_REJECT_ICMP_CODE]);
  60        case NFT_REJECT_TCP_RST:
  61                break;
  62        default:
  63                return -EINVAL;
  64        }
  65
  66        return 0;
  67}
  68EXPORT_SYMBOL_GPL(nft_reject_init);
  69
  70int nft_reject_dump(struct sk_buff *skb, const struct nft_expr *expr)
  71{
  72        const struct nft_reject *priv = nft_expr_priv(expr);
  73
  74        if (nla_put_be32(skb, NFTA_REJECT_TYPE, htonl(priv->type)))
  75                goto nla_put_failure;
  76
  77        switch (priv->type) {
  78        case NFT_REJECT_ICMP_UNREACH:
  79                if (nla_put_u8(skb, NFTA_REJECT_ICMP_CODE, priv->icmp_code))
  80                        goto nla_put_failure;
  81                break;
  82        default:
  83                break;
  84        }
  85
  86        return 0;
  87
  88nla_put_failure:
  89        return -1;
  90}
  91EXPORT_SYMBOL_GPL(nft_reject_dump);
  92
  93static u8 icmp_code_v4[NFT_REJECT_ICMPX_MAX + 1] = {
  94        [NFT_REJECT_ICMPX_NO_ROUTE]             = ICMP_NET_UNREACH,
  95        [NFT_REJECT_ICMPX_PORT_UNREACH]         = ICMP_PORT_UNREACH,
  96        [NFT_REJECT_ICMPX_HOST_UNREACH]         = ICMP_HOST_UNREACH,
  97        [NFT_REJECT_ICMPX_ADMIN_PROHIBITED]     = ICMP_PKT_FILTERED,
  98};
  99
 100int nft_reject_icmp_code(u8 code)
 101{
 102        BUG_ON(code > NFT_REJECT_ICMPX_MAX);
 103
 104        return icmp_code_v4[code];
 105}
 106
 107EXPORT_SYMBOL_GPL(nft_reject_icmp_code);
 108
 109
 110static u8 icmp_code_v6[NFT_REJECT_ICMPX_MAX + 1] = {
 111        [NFT_REJECT_ICMPX_NO_ROUTE]             = ICMPV6_NOROUTE,
 112        [NFT_REJECT_ICMPX_PORT_UNREACH]         = ICMPV6_PORT_UNREACH,
 113        [NFT_REJECT_ICMPX_HOST_UNREACH]         = ICMPV6_ADDR_UNREACH,
 114        [NFT_REJECT_ICMPX_ADMIN_PROHIBITED]     = ICMPV6_ADM_PROHIBITED,
 115};
 116
 117int nft_reject_icmpv6_code(u8 code)
 118{
 119        BUG_ON(code > NFT_REJECT_ICMPX_MAX);
 120
 121        return icmp_code_v6[code];
 122}
 123
 124EXPORT_SYMBOL_GPL(nft_reject_icmpv6_code);
 125
 126MODULE_LICENSE("GPL");
 127MODULE_AUTHOR("Patrick McHardy <kaber@trash.net>");
 128