File Index
Files and directories
Sign in
FILE

nft_dup_ipv6.c

File preview with syntax highlighting.

linux-6.19.14/net/ipv6/netfilter/nft_dup_ipv6.c C
  1// SPDX-License-Identifier: GPL-2.0-only
  2/*
  3 * Copyright (c) 2015 Pablo Neira Ayuso <pablo@netfilter.org>
  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/ipv6/nf_dup_ipv6.h>
 14
 15struct nft_dup_ipv6 {
 16	u8	sreg_addr;
 17	u8	sreg_dev;
 18};
 19
 20static void nft_dup_ipv6_eval(const struct nft_expr *expr,
 21			      struct nft_regs *regs,
 22			      const struct nft_pktinfo *pkt)
 23{
 24	struct nft_dup_ipv6 *priv = nft_expr_priv(expr);
 25	struct in6_addr *gw = (struct in6_addr *)&regs->data[priv->sreg_addr];
 26	int oif = priv->sreg_dev ? regs->data[priv->sreg_dev] : -1;
 27
 28	nf_dup_ipv6(nft_net(pkt), pkt->skb, nft_hook(pkt), gw, oif);
 29}
 30
 31static int nft_dup_ipv6_init(const struct nft_ctx *ctx,
 32			     const struct nft_expr *expr,
 33			     const struct nlattr * const tb[])
 34{
 35	struct nft_dup_ipv6 *priv = nft_expr_priv(expr);
 36	int err;
 37
 38	if (tb[NFTA_DUP_SREG_ADDR] == NULL)
 39		return -EINVAL;
 40
 41	err = nft_parse_register_load(ctx, tb[NFTA_DUP_SREG_ADDR], &priv->sreg_addr,
 42				      sizeof(struct in6_addr));
 43	if (err < 0)
 44		return err;
 45
 46	if (tb[NFTA_DUP_SREG_DEV])
 47		err = nft_parse_register_load(ctx, tb[NFTA_DUP_SREG_DEV],
 48					      &priv->sreg_dev, sizeof(int));
 49
 50	return err;
 51}
 52
 53static int nft_dup_ipv6_dump(struct sk_buff *skb,
 54			     const struct nft_expr *expr, bool reset)
 55{
 56	struct nft_dup_ipv6 *priv = nft_expr_priv(expr);
 57
 58	if (nft_dump_register(skb, NFTA_DUP_SREG_ADDR, priv->sreg_addr))
 59		goto nla_put_failure;
 60	if (priv->sreg_dev &&
 61	    nft_dump_register(skb, NFTA_DUP_SREG_DEV, priv->sreg_dev))
 62		goto nla_put_failure;
 63
 64	return 0;
 65
 66nla_put_failure:
 67	return -1;
 68}
 69
 70static struct nft_expr_type nft_dup_ipv6_type;
 71static const struct nft_expr_ops nft_dup_ipv6_ops = {
 72	.type		= &nft_dup_ipv6_type,
 73	.size		= NFT_EXPR_SIZE(sizeof(struct nft_dup_ipv6)),
 74	.eval		= nft_dup_ipv6_eval,
 75	.init		= nft_dup_ipv6_init,
 76	.dump		= nft_dup_ipv6_dump,
 77	.reduce		= NFT_REDUCE_READONLY,
 78};
 79
 80static const struct nla_policy nft_dup_ipv6_policy[NFTA_DUP_MAX + 1] = {
 81	[NFTA_DUP_SREG_ADDR]	= { .type = NLA_U32 },
 82	[NFTA_DUP_SREG_DEV]	= { .type = NLA_U32 },
 83};
 84
 85static struct nft_expr_type nft_dup_ipv6_type __read_mostly = {
 86	.family		= NFPROTO_IPV6,
 87	.name		= "dup",
 88	.ops		= &nft_dup_ipv6_ops,
 89	.policy		= nft_dup_ipv6_policy,
 90	.maxattr	= NFTA_DUP_MAX,
 91	.owner		= THIS_MODULE,
 92};
 93
 94static int __init nft_dup_ipv6_module_init(void)
 95{
 96	return nft_register_expr(&nft_dup_ipv6_type);
 97}
 98
 99static void __exit nft_dup_ipv6_module_exit(void)
100{
101	nft_unregister_expr(&nft_dup_ipv6_type);
102}
103
104module_init(nft_dup_ipv6_module_init);
105module_exit(nft_dup_ipv6_module_exit);
106
107MODULE_LICENSE("GPL");
108MODULE_AUTHOR("Pablo Neira Ayuso <pablo@netfilter.org>");
109MODULE_ALIAS_NFT_AF_EXPR(AF_INET6, "dup");
110MODULE_DESCRIPTION("IPv6 nftables packet duplication support");
~/ Read-only file preview.