linux/net/netfilter/nft_immediate.c
<<
>>
Prefs
   1/*
   2 * Copyright (c) 2008-2009 Patrick McHardy <kaber@trash.net>
   3 *
   4 * This program is free software; you can redistribute it and/or modify
   5 * it under the terms of the GNU General Public License version 2 as
   6 * published by the Free Software Foundation.
   7 *
   8 * Development of this code funded by Astaro AG (http://www.astaro.com/)
   9 */
  10
  11#include <linux/kernel.h>
  12#include <linux/init.h>
  13#include <linux/module.h>
  14#include <linux/netlink.h>
  15#include <linux/netfilter.h>
  16#include <linux/netfilter/nf_tables.h>
  17#include <net/netfilter/nf_tables_core.h>
  18#include <net/netfilter/nf_tables.h>
  19
  20struct nft_immediate_expr {
  21        struct nft_data         data;
  22        enum nft_registers      dreg:8;
  23        u8                      dlen;
  24};
  25
  26static void nft_immediate_eval(const struct nft_expr *expr,
  27                               struct nft_regs *regs,
  28                               const struct nft_pktinfo *pkt)
  29{
  30        const struct nft_immediate_expr *priv = nft_expr_priv(expr);
  31
  32        nft_data_copy(&regs->data[priv->dreg], &priv->data, priv->dlen);
  33}
  34
  35static const struct nla_policy nft_immediate_policy[NFTA_IMMEDIATE_MAX + 1] = {
  36        [NFTA_IMMEDIATE_DREG]   = { .type = NLA_U32 },
  37        [NFTA_IMMEDIATE_DATA]   = { .type = NLA_NESTED },
  38};
  39
  40static int nft_immediate_init(const struct nft_ctx *ctx,
  41                              const struct nft_expr *expr,
  42                              const struct nlattr * const tb[])
  43{
  44        struct nft_immediate_expr *priv = nft_expr_priv(expr);
  45        struct nft_data_desc desc;
  46        int err;
  47
  48        if (tb[NFTA_IMMEDIATE_DREG] == NULL ||
  49            tb[NFTA_IMMEDIATE_DATA] == NULL)
  50                return -EINVAL;
  51
  52        err = nft_data_init(ctx, &priv->data, sizeof(priv->data), &desc,
  53                            tb[NFTA_IMMEDIATE_DATA]);
  54        if (err < 0)
  55                return err;
  56        priv->dlen = desc.len;
  57
  58        priv->dreg = nft_parse_register(tb[NFTA_IMMEDIATE_DREG]);
  59        err = nft_validate_register_store(ctx, priv->dreg, &priv->data,
  60                                          desc.type, desc.len);
  61        if (err < 0)
  62                goto err1;
  63
  64        return 0;
  65
  66err1:
  67        nft_data_uninit(&priv->data, desc.type);
  68        return err;
  69}
  70
  71static void nft_immediate_destroy(const struct nft_ctx *ctx,
  72                                  const struct nft_expr *expr)
  73{
  74        const struct nft_immediate_expr *priv = nft_expr_priv(expr);
  75        return nft_data_uninit(&priv->data, nft_dreg_to_type(priv->dreg));
  76}
  77
  78static int nft_immediate_dump(struct sk_buff *skb, const struct nft_expr *expr)
  79{
  80        const struct nft_immediate_expr *priv = nft_expr_priv(expr);
  81
  82        if (nft_dump_register(skb, NFTA_IMMEDIATE_DREG, priv->dreg))
  83                goto nla_put_failure;
  84
  85        return nft_data_dump(skb, NFTA_IMMEDIATE_DATA, &priv->data,
  86                             nft_dreg_to_type(priv->dreg), priv->dlen);
  87
  88nla_put_failure:
  89        return -1;
  90}
  91
  92static int nft_immediate_validate(const struct nft_ctx *ctx,
  93                                  const struct nft_expr *expr,
  94                                  const struct nft_data **data)
  95{
  96        const struct nft_immediate_expr *priv = nft_expr_priv(expr);
  97
  98        if (priv->dreg == NFT_REG_VERDICT)
  99                *data = &priv->data;
 100
 101        return 0;
 102}
 103
 104static struct nft_expr_type nft_imm_type;
 105static const struct nft_expr_ops nft_imm_ops = {
 106        .type           = &nft_imm_type,
 107        .size           = NFT_EXPR_SIZE(sizeof(struct nft_immediate_expr)),
 108        .eval           = nft_immediate_eval,
 109        .init           = nft_immediate_init,
 110        .destroy        = nft_immediate_destroy,
 111        .dump           = nft_immediate_dump,
 112        .validate       = nft_immediate_validate,
 113};
 114
 115static struct nft_expr_type nft_imm_type __read_mostly = {
 116        .name           = "immediate",
 117        .ops            = &nft_imm_ops,
 118        .policy         = nft_immediate_policy,
 119        .maxattr        = NFTA_IMMEDIATE_MAX,
 120        .owner          = THIS_MODULE,
 121};
 122
 123int __init nft_immediate_module_init(void)
 124{
 125        return nft_register_expr(&nft_imm_type);
 126}
 127
 128void nft_immediate_module_exit(void)
 129{
 130        nft_unregister_expr(&nft_imm_type);
 131}
 132