IMX257虚拟网卡vnet驱动程序

发布时间: 2024-08-13
来源: 电子工程世界

一、一个简单的虚拟网卡驱动

 1 static struct net_device *vnet_dev; //定义一个网络设备结构体

 2 

 3 

 4 static const struct net_device_ops virt_netdev_ops = {

 5     .ndo_start_xmit        = NULL,

 6 };

 7 

 8 

 9 static int virt_net_init(void){

10     

11     /* 1.分配一个net_device结构体 */

12     vnet_dev = alloc_netdev(0,'vnet%d',ether_setup); //私有数据为0,

13     /* 2.设置 */

14     vnet_dev->netdev_ops = &virt_netdev_ops;

15     /* 3.注册 */

16     //register_netdevice(vnet_dev);    //会报锁的错误

17     register_netdev(vnet_dev);   //rtnl_lock();

18     return 0;

19 }

20 

21 static void virt_net_exit(void){

22     if(vnet_dev){

23         unregister_netdev(vnet_dev);

24         free_netdev(vnet_dev);

25     }

26 }

27 

28 module_init(virt_net_init);

29 module_exit(virt_net_exit);

30 MODULE_AUTHOR('Lover雪儿');

31 MODULE_LICENSE('GPL');


如上面程序所示,定义分配一个net_device结构体,注册结构体,这样就实现了一个简单的虚拟网卡驱动。


实现效果:

3e2bbcbae45fb4ad0512a6a7234b6cef_191614256986085.png

如图所示,在/sys/class/net/目录下多生成了一个vnet0的文件夹


附驱动程序virt_net1.c


 1 #include

 2 #include

 3 #include

 4 #include

 5 #include

 6 #include

 7 #include

 8 #include

 9 #include

10 #include

11 #include

12 #include

13 #include

14 #include

15 #include

16 #include

17 

18 #include

19 #include

20 #include

21 

22 static struct net_device *vnet_dev; //定义一个网络设备结构体

23 

24 

25 static const struct net_device_ops virt_netdev_ops = {

26     .ndo_start_xmit        = NULL,

27 };

28 

29 

30 static int virt_net_init(void){

31     

32     /* 1.分配一个net_device结构体 */

33     vnet_dev = alloc_netdev(0,'vnet%d',ether_setup); //私有数据为0,

34     /* 2.设置 */

35     vnet_dev->netdev_ops = &virt_netdev_ops;

36     /* 3.注册 */

37     //register_netdevice(vnet_dev);    //会报锁的错误

38     register_netdev(vnet_dev);   //rtnl_lock();

39     return 0;

40 }

41 

42 static void virt_net_exit(void){

43     if(vnet_dev){

44         unregister_netdev(vnet_dev);

45         free_netdev(vnet_dev);

46     }

47 }

48 

49 module_init(virt_net_init);

50 module_exit(virt_net_exit);

51 MODULE_AUTHOR('Lover雪儿');

52 MODULE_LICENSE('GPL');

53 

54 

55 /*

56 

57 /////////////////////////////////////////////////////////////////////

58 网卡驱动程序框架:

59 app:  socket

60 --------------------------------------------------------------------

61         -----------------

62         ----------------- 若干层网络协议--纯软件

63         -----------------

64 hard_start_xmit() 用于发送数据包            ↑↑↑

65     ↓↓↓              sk_buff                netif_rx()用于上报数据包

66 调用硬件相关的驱动程序(要提供har_start_xmit,有数据时用netif_rx上报)

67 --------------------------------------------------------------------

68               硬件

69 //////////////////////////////////////////////////////////////////////

70               

71 网卡驱动编写:

72 1.分配一个net_device结构体

73 2.设置

74 2.1 发包函数:hard_start_xmit

75 2.2 收到到数据时,(在中断处理函数中)用netif_rx上报数据

76 2.3 其他设置

77 3.注册 register_netdevice              

78     

79 

80 一、测试1th

81 insmod virt_net.ko

82 ifconfig vnet0 3.3.3.3

83 ping 3.3.3.3

84 ping 3.3.3.4  看效果 

85 

86 

87 */


二、增加ping功能


下面是我画的一个网卡驱动程序框架。

1acf69b525aad1d069cef64c38353639_191614270893328.png

所以此处我们增加一个发送数据包的函数 hard_start_xmit用于转发数据包。


1.在net_device结构体下定义hard_start_xmit。


vnet_dev->hard_start_xmit = vir_net_send_packet;


2.实现vir_net_send_packet函数


此处我们的代码只是增加一些打印语句,以便确定当我们ping的时候,是否会调用该函数。


 1 //转发发送数据包

 2 static int virt_net_send_packet(struct sk_buff *skb, struct net_device *dev){

 3     static int cnt = 0;

 4     printk('vir_net_send_packet cnt = %dn',++cnt);

 5     return 0;

 6 }

 7 

 8 static const struct net_device_ops virt_netdev_ops = {

 9     .ndo_start_xmit        = virt_net_send_packet,

10 };

11 //接着在入口函数中增加net_device_ops

12 

13 vnet_dev->netdev_ops = &virt_netdev_ops;


实现效果:

485dc2ff3054900190bb1080665aeebe_191614308854466.png

ping 测试:

58d4db37122925f48af3f5f64ea0c0d2_191614319175752.png

附驱动程序virt_net2.c


 1 #include

 2 #include

 3 #include

 4 #include

 5 #include

 6 #include

 7 #include

 8 #include

 9 #include

10 #include

11 #include

12 #include

13 #include

14 #include

15 #include

16 #include

17 

18 #include

19 #include

20 #include

21 

22 static struct net_device *vnet_dev; //定义一个网络设备结构体

23 

24 //转发发送数据包

25 static int virt_net_send_packet(struct sk_buff *skb, struct net_device *dev){

26     static int cnt = 0;

27     printk('vir_net_send_packet cnt = %dn',++cnt);

28     return 0;

29 }

30 

31 static const struct net_device_ops virt_netdev_ops = {

32     .ndo_start_xmit        = virt_net_send_packet,

33 };

34 

35 

36 static int virt_net_init(void){

37     

38     /* 1.分配一个net_device结构体 */

39     vnet_dev = alloc_netdev(0,'vnet%d',ether_setup); //私有数据为0,

40     /* 2.设置 */

41     vnet_dev->netdev_ops = &virt_netdev_ops;

42     /* 3.注册 */

43     //register_netdevice(vnet_dev);    //会报锁的错误

44     register_netdev(vnet_dev);   //rtnl_lock();

45     return 0;

46 }

47 

48 static void virt_net_exit(void){

49     if(vnet_dev){

50         unregister_netdev(vnet_dev);

51         free_netdev(vnet_dev);

52     }

53 }

54 

55 module_init(virt_net_init);

56 module_exit(virt_net_exit);

57 MODULE_AUTHOR('Lover雪儿');

58 MODULE_LICENSE('GPL');

59 

60 

61 /*

62 

63 /////////////////////////////////////////////////////////////////////

64 网卡驱动程序框架:

65 app:  socket

66 --------------------------------------------------------------------

67         -----------------

68         ----------------- 若干层网络协议--纯软件

69         -----------------

70 hard_start_xmit() 用于发送数据包            ↑↑↑

71     ↓↓↓              sk_buff                netif_rx()用于上报数据包

72 调用硬件相关的驱动程序(要提供har_start_xmit,有数据时用netif_rx上报)

73 --------------------------------------------------------------------

74               硬件

75 //////////////////////////////////////////////////////////////////////

76               

77 网卡驱动编写:

78 1.分配一个net_device结构体

79 2.设置

80 2.1 发包函数:hard_start_xmit

81 2.2 收到到数据时,(在中断处理函数中)用netif_rx上报数据

82 2.3 其他设置

83 3.注册 register_netdevice              

84     

85 

86 一、测试1th

87 insmod virt_net.ko

88 ifconfig vnet0 3.3.3.3

89 ping 3.3.3.3

90 ping 3.3.3.4  看效果 

91 

92 */


三、增加数据包的统计,设置MAC地址


有关于数据包的统计信息定义在net_device结构体的stats结构体下,主要是定义了收发数据包的个数,字节数,时间等。此处,我们就增加一个统计发送数据包的个数,以及字节数。


stats结构体如下:


发送数据包的统计

struct net_device_stats

{

    unsigned long rx_packets; / * total packets received * /

    unsigned long tx_packets; / * total packets transmitted * /

    unsigned long rx_bytes; / * total bytes received * /

    unsigned long tx_bytes; / * total bytes transmitted * /

    unsigned long rx_errors; / * bad packets received * /

    unsigned long tx_errors; / * packet transmit probls * /

    unsigned long rx_dropped; / * no space in linux buffers * /

    unsigned long tx_dropped; / * no space available in linux * /

    unsigned long multicast; / * multicast packets received * /

    unsigned long collisions;


    / * detailed rx_errors: * /

    unsigned long rx_length_errors;

    unsigned long rx_over_errors; / * receiver ring buff overflow * /

    unsigned long rx_crc_errors; / * recved pkt with crc error * /

    unsigned long rx_frame_errors; / * recv'd frame alignment error * /

    unsigned long rx_fifo_errors; / * recv'r fifo overrun * /

    unsigned long rx_missed_errors; / * receiver missed packet * /

 

    / * detailed tx_errors * /

    unsigned long tx_aborted_errors;

    unsigned long tx_carrier_errors;

    unsigned long tx_fifo_errors;

    unsigned long tx_heartbeat_errors;

    unsigned long tx_window_errors;

 

    / * for cslip etc * /

    unsigned long rx_compressed;

    unsigned long tx_compressed;

};

文章来源于: 电子工程世界 原文链接

本站所有转载文章系出于传递更多信息之目的,且明确注明来源,不希望被转载的媒体或个人可与我们联系,我们将立即进行删除处理。