Linux网络设备驱动模块——虚拟网卡virnet

环境

系统:Ubuntu16.04
kernel:4.10.0-28-generic

新建目录和文件

~$ mkdir virnet
~$ cd virnet
~/virnet$ touch virnet.c
~/virnet$ touch Makefile

添加以下内容到virnet.c文件

#include <linux/module.h>
#include <linux/errno.h>
#include <linux/netdevice.h>

MODULE_LICENSE("GPL");

// 网络设备对象
static struct net_device *sg_dev;

// 有数据帧要发送时,kernel会调用该函数
static int virnet_send_packet(struct sk_buff *skb,struct net_device *dev)
{
    // 统计已发送的数据包
    dev->stats.tx_packets++;
    // 统计已发送的字节
    dev->stats.tx_bytes+=skb->len;
    // 释放数据帧
    dev_kfree_skb(skb);
    return 0;
}

// 驱动程序支持的操作
static struct net_device_ops sg_ops=
{
    // 发送数据帧
    .ndo_start_xmit=virnet_send_packet,
};

// 驱动程序初始化
static int virnet_init(void)
{
    // 创建一个网络设备,名为“virnet%d",kernel会自动填写%d为网卡编号
    //sg_dev=alloc_netdev(0,"virnet%d",ether_setup);
    // kernel 4.4.0-97上需要四个参数如下
    sg_dev=alloc_netdev(0,"virnet%d", NET_NAME_UNKNOWN, ether_setup);
    // 该网络设备的操作集
    sg_dev->netdev_ops=&sg_ops;
    // MAC地址是01:02:03:04:05:06
    memcpy(sg_dev->dev_addr,"\x01\x02\x03\x04\x05\x06",6);
    // 注册网络设备
    register_netdev(sg_dev);
    return 0;
}

// 驱动程序销毁
static void virnet_exit(void)
{
    // 注销网络设备
    unregister_netdev(sg_dev);
    // 释放对象
    free_netdev(sg_dev);
}

module_init(virnet_init);
module_exit(virnet_exit);

添加以下内容到Makefile文件

obj-m := virnet.o
KERNEL_DIR := /lib/modules/$(shell uname -r)/build
PWD := $(shell pwd)
all:
	make -C $(KERNEL_DIR) SUBDIRS=$(PWD) modules
clean:
	rm *.o *.ko *.mod.c
.PHONY:clean

编译和测试

~/virnet$ make
~/virnet$ sudo insmod virnet.ko
~/virnet$ ifconfig -a
~/virnet$ sudo rmmod virnet

参考

第一个Linux网络设备驱动——最简虚拟网卡virnet

猜你喜欢

转载自blog.csdn.net/kingwan560/article/details/84324982