Linux回环网卡驱动设计(2)

/* detailed rx_errors: */
      __u64    rx_length_errors;
      __u64    rx_over_errors;          /* receiver ring buff overflow    */
      __u64    rx_crc_errors;          /* recved pkt with crc error    */
      __u64    rx_frame_errors;    /* recv'd frame alignment error */
      __u64    rx_fifo_errors;          /* recv'r fifo overrun          */
      __u64    rx_missed_errors;    /* receiver missed packet    */

/* detailed tx_errors */
      __u64    tx_aborted_errors;
      __u64    tx_carrier_errors;
      __u64    tx_fifo_errors;
      __u64    tx_heartbeat_errors;
      __u64    tx_window_errors;

/* for cslip etc */
      __u64    rx_compressed;
      __u64    tx_compressed;
 };
主要是这四个成员
   stats->rx_packets = packets;
      stats->tx_packets = packets;
      stats->rx_bytes  = bytes;
      stats->tx_bytes  = bytes;
。实际上自己可以重写这个获取状态的函数,因为struct net_device *dev有一个成员就是struct net_device_stats    stats;所以可以在重写的时候定义一个struct net_device_stats    stats指向形参传递进来的回环网卡结构体的stats成员,同样只需要注意stats成员的上述四个成员即可。

9.在退出该驱动的时候就是取消注册结构体。达到注销网卡的目的。

static __net_exit void loopback_net_exit(struct net *net)
{
 struct net_device *dev = net->loopback_dev;

unregister_netdev(dev);
}

下面为范例代码

#include <linux/kernel.h>
#include <linux/jiffies.h>
#include <linux/module.h>
#include <linux/interrupt.h>
#include <linux/fs.h>
#include <linux/types.h>
#include <linux/string.h>
#include <linux/socket.h>
#include <linux/errno.h>
#include <linux/fcntl.h>
#include <linux/in.h>
#include <linux/init.h>

#include <asm/system.h>
#include <asm/uaccess.h>
#include <asm/io.h>

#include <linux/inet.h>
#include <linux/netdevice.h>
#include <linux/etherdevice.h>
#include <linux/skbuff.h>
#include <linux/ethtool.h>
#include <net/sock.h>
#include <net/checksum.h>
#include <linux/if_ether.h> /* For the statistics structure. */
#include <linux/if_arp.h> /* For ARPHRD_ETHER */
#include <linux/ip.h>
#include <linux/tcp.h>
#include <linux/percpu.h>
#include <net/net_namespace.h>
#include <linux/u64_stats_sync.h>

unsigned long packets = 0;
unsigned long bytes = 0;

//struct net_device *dev;

static __net_exit void loopback_net_exit(struct net *net)
{
 struct net_device *dev = net->loopback_dev;

unregister_netdev(dev);
}


static int loopback_net_xmit(struct sk_buff *skb,struct net_device *dev)
{
 skb->protocol = eth_type_trans(skb,dev);

packets++;
 bytes += skb->len;

netif_rx(skb);

return 0;
}


static struct net_device_stats *loopback_get_stats(struct net_device *dev)
{
 struct net_device_stats *stats = &dev->stats;

stats->rx_packets = packets;
 stats->tx_packets = packets;
 stats->rx_bytes = bytes;
 stats->tx_bytes = bytes;

return stats;
}


static const struct net_device_ops loopback_ops =
{
 .ndo_start_xmit = loopback_net_xmit,
 .ndo_get_stats = loopback_get_stats,
};

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/5d25e3fcd9a3bbd6302557d90330c674.html