linux/net/netfilter/nf_dup_netdev.c
<<
>>
Prefs
   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/nf_tables_offload.h>
  14#include <net/netfilter/nf_dup_netdev.h>
  15
  16static void nf_do_netdev_egress(struct sk_buff *skb, struct net_device *dev)
  17{
  18        if (skb_mac_header_was_set(skb))
  19                skb_push(skb, skb->mac_len);
  20
  21        skb->dev = dev;
  22        skb->tstamp = 0;
  23        dev_queue_xmit(skb);
  24}
  25
  26void nf_fwd_netdev_egress(const struct nft_pktinfo *pkt, int oif)
  27{
  28        struct net_device *dev;
  29
  30        dev = dev_get_by_index_rcu(nft_net(pkt), oif);
  31        if (!dev) {
  32                kfree_skb(pkt->skb);
  33                return;
  34        }
  35
  36        nf_do_netdev_egress(pkt->skb, dev);
  37}
  38EXPORT_SYMBOL_GPL(nf_fwd_netdev_egress);
  39
  40void nf_dup_netdev_egress(const struct nft_pktinfo *pkt, int oif)
  41{
  42        struct net_device *dev;
  43        struct sk_buff *skb;
  44
  45        dev = dev_get_by_index_rcu(nft_net(pkt), oif);
  46        if (dev == NULL)
  47                return;
  48
  49        skb = skb_clone(pkt->skb, GFP_ATOMIC);
  50        if (skb)
  51                nf_do_netdev_egress(skb, dev);
  52}
  53EXPORT_SYMBOL_GPL(nf_dup_netdev_egress);
  54
  55int nft_fwd_dup_netdev_offload(struct nft_offload_ctx *ctx,
  56                               struct nft_flow_rule *flow,
  57                               enum flow_action_id id, int oif)
  58{
  59        struct flow_action_entry *entry;
  60        struct net_device *dev;
  61
  62        /* nft_flow_rule_destroy() releases the reference on this device. */
  63        dev = dev_get_by_index(ctx->net, oif);
  64        if (!dev)
  65                return -EOPNOTSUPP;
  66
  67        entry = &flow->rule->action.entries[ctx->num_actions++];
  68        entry->id = id;
  69        entry->dev = dev;
  70
  71        return 0;
  72}
  73EXPORT_SYMBOL_GPL(nft_fwd_dup_netdev_offload);
  74
  75MODULE_LICENSE("GPL");
  76MODULE_AUTHOR("Pablo Neira Ayuso <pablo@netfilter.org>");
  77MODULE_DESCRIPTION("Netfilter packet duplication support");
  78