#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/netdevice.h>
#include <linux/netlink.h>
#include <net/net_namespace.h>
#include <linux/if_arp.h>
#include <net/rtnetlink.h>
static netdev_tx_t nlmon_xmit(struct sk_buff *skb, struct net_device *dev)
struct pcpu_lstats *stats = this_cpu_ptr(dev->lstats);
u64_stats_update_begin(&stats->syncp);
u64_stats_update_end(&stats->syncp);
static int nlmon_dev_init(struct net_device *dev)
dev->lstats = netdev_alloc_pcpu_stats(struct pcpu_lstats);
return dev->lstats == NULL ? -ENOMEM : 0;
static void nlmon_dev_uninit(struct net_device *dev)
free_percpu(dev->lstats);
static int nlmon_open(struct net_device *dev)
struct nlmon *nlmon = netdev_priv(dev);
nlmon->nt.module = THIS_MODULE;
return netlink_add_tap(&nlmon->nt);
static int nlmon_close(struct net_device *dev)
struct nlmon *nlmon = netdev_priv(dev);
return netlink_remove_tap(&nlmon->nt);
nlmon_get_stats64(struct net_device *dev, struct rtnl_link_stats64 *stats)
u64 bytes = 0, packets = 0;
for_each_possible_cpu(i) {
const struct pcpu_lstats *nl_stats;