zoukankan      html  css  js  c++  java
  • IMX257虚拟网卡vnet驱动程序

    20150419 IMX257虚拟网卡vnet驱动程序

    2015-04-19 Lover雪儿

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

     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结构体,注册结构体,这样就实现了一个简单的虚拟网卡驱动。

    实现效果:

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

    附驱动程序virt_net1.c

     1 #include <linux/errno.h>
     2 #include <linux/netdevice.h>
     3 #include <linux/etherdevice.h>
     4 #include <linux/kernel.h>
     5 #include <linux/types.h>
     6 #include <linux/fcntl.h>
     7 #include <linux/interrupt.h>
     8 #include <linux/ioport.h>
     9 #include <linux/in.h>
    10 #include <linux/skbuff.h>
    11 #include <linux/slab.h>
    12 #include <linux/spinlock.h>
    13 #include <linux/string.h>
    14 #include <linux/init.h>
    15 #include <linux/bitops.h>
    16 #include <linux/delay.h>
    17 
    18 #include <asm/system.h>
    19 #include <asm/io.h>
    20 #include <asm/irq.h>
    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 */
    virt_net1.c

    二、增加ping功能

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

    所以此处我们增加一个发送数据包的函数 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 = %d
    ",++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;

     实现效果:

    ping 测试:

    附驱动程序virt_net2.c

     1 #include <linux/errno.h>
     2 #include <linux/netdevice.h>
     3 #include <linux/etherdevice.h>
     4 #include <linux/kernel.h>
     5 #include <linux/types.h>
     6 #include <linux/fcntl.h>
     7 #include <linux/interrupt.h>
     8 #include <linux/ioport.h>
     9 #include <linux/in.h>
    10 #include <linux/skbuff.h>
    11 #include <linux/slab.h>
    12 #include <linux/spinlock.h>
    13 #include <linux/string.h>
    14 #include <linux/init.h>
    15 #include <linux/bitops.h>
    16 #include <linux/delay.h>
    17 
    18 #include <asm/system.h>
    19 #include <asm/io.h>
    20 #include <asm/irq.h>
    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 = %d
    ",++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 */
    virt_net2.c

    三、增加数据包的统计,设置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;
    };

    接下来就是在virt_net_send_packet实现数据包的自加。

     1 static int virt_net_send_packet(struct sk_buff *skb, struct net_device *dev)
     2 {
     3     static int cnt = 0;
     4     printk("virt_net_send_packet cnt = %d
    ", ++cnt);
     5 
     6     /* 更新统计信息 */
     7     dev->stats.tx_packets++;
     8     dev->stats.tx_bytes += skb->len;
     9     
    10     return 0;
    11 }

    设置mac地址

     1 static int virt_net_init(void)
     2 {
     3     /* 1. 分配一个net_device结构体 */
     4     vnet_dev = alloc_netdev(0, "vnet%d", ether_setup);;  /* alloc_etherdev */
     5 
     6     /* 2. 设置 */
     7     vnet_dev->netdev_ops    = &virt_netdev_ops;
     8 
     9     /* 设置MAC地址 */
    10     vnet_dev->dev_addr[0] = 0x08;
    11     vnet_dev->dev_addr[1] = 0x89;
    12     vnet_dev->dev_addr[2] = 0x89;
    13     vnet_dev->dev_addr[3] = 0x89;
    14     vnet_dev->dev_addr[4] = 0x89;
    15     vnet_dev->dev_addr[5] = 0x11;
    16 
    17     /* 设置下面两项才能ping通 */
    18     //vnet_dev->flags           |= IFF_NOARP;
    19     //vnet_dev->features        |= NETIF_F_NO_CSUM;    
    20 
    21     /* 3. 注册 */
    22     //register_netdevice(vnet_dev);
    23     register_netdev(vnet_dev);
    24     
    25     return 0;
    26 }

     实现效果:

    附驱动程序virt_net3.c

      1 #include <linux/module.h>
      2 #include <linux/errno.h>
      3 #include <linux/netdevice.h>
      4 #include <linux/etherdevice.h>
      5 #include <linux/kernel.h>
      6 #include <linux/types.h>
      7 #include <linux/fcntl.h>
      8 #include <linux/interrupt.h>
      9 #include <linux/ioport.h>
     10 #include <linux/in.h>
     11 #include <linux/skbuff.h>
     12 #include <linux/slab.h>
     13 #include <linux/spinlock.h>
     14 #include <linux/string.h>
     15 #include <linux/init.h>
     16 #include <linux/bitops.h>
     17 #include <linux/delay.h>
     18 #include <linux/ip.h>
     19 
     20 #include <asm/system.h>
     21 #include <asm/io.h>
     22 #include <asm/irq.h>
     23 
     24 static struct net_device *vnet_dev;
     25 
     26 
     27 static int virt_net_send_packet(struct sk_buff *skb, struct net_device *dev)
     28 {
     29     static int cnt = 0;
     30     printk("virt_net_send_packet cnt = %d
    ", ++cnt);
     31 
     32     /* 更新统计信息 */
     33     dev->stats.tx_packets++;
     34     dev->stats.tx_bytes += skb->len;
     35     
     36     return 0;
     37 }
     38 
     39 static const struct net_device_ops virt_netdev_ops = {
     40     .ndo_start_xmit        = virt_net_send_packet,
     41 };
     42 
     43 static int virt_net_init(void)
     44 {
     45     /* 1. 分配一个net_device结构体 */
     46     vnet_dev = alloc_netdev(0, "vnet%d", ether_setup);;  /* alloc_etherdev */
     47 
     48     /* 2. 设置 */
     49     vnet_dev->netdev_ops    = &virt_netdev_ops;
     50 
     51     /* 设置MAC地址 */
     52     vnet_dev->dev_addr[0] = 0x08;
     53     vnet_dev->dev_addr[1] = 0x89;
     54     vnet_dev->dev_addr[2] = 0x89;
     55     vnet_dev->dev_addr[3] = 0x89;
     56     vnet_dev->dev_addr[4] = 0x89;
     57     vnet_dev->dev_addr[5] = 0x11;
     58 
     59     /* 设置下面两项才能ping通 */
     60     //vnet_dev->flags           |= IFF_NOARP;
     61     //vnet_dev->features        |= NETIF_F_NO_CSUM;    
     62 
     63     /* 3. 注册 */
     64     //register_netdevice(vnet_dev);
     65     register_netdev(vnet_dev);
     66     
     67     return 0;
     68 }
     69 
     70 static void virt_net_exit(void)
     71 {
     72     unregister_netdev(vnet_dev);
     73     free_netdev(vnet_dev);
     74 }
     75 
     76 module_init(virt_net_init);
     77 module_exit(virt_net_exit);
     78 MODULE_AUTHOR("Lover雪儿");
     79 MODULE_LICENSE("GPL");
     80 
     81 
     82 /*
     83 
     84 /////////////////////////////////////////////////////////////////////
     85 网卡驱动程序框架:
     86 app:  socket
     87 --------------------------------------------------------------------
     88         -----------------
     89         ----------------- 若干层网络协议--纯软件
     90         -----------------
     91 hard_start_xmit() 用于发送数据包            ↑↑↑
     92     ↓↓↓              sk_buff                netif_rx()用于上报数据包
     93 调用硬件相关的驱动程序(要提供har_start_xmit,有数据时用netif_rx上报)
     94 --------------------------------------------------------------------
     95               硬件
     96 //////////////////////////////////////////////////////////////////////
     97               
     98 网卡驱动编写:
     99 1.分配一个net_device结构体
    100 2.设置
    101 2.1 发包函数:hard_start_xmit
    102 2.2 收到到数据时,(在中断处理函数中)用netif_rx上报数据
    103 2.3 其他设置
    104 3.注册 register_netdevice              
    105     
    106 
    107 一、测试1th
    108 insmod virt_net.ko
    109 ifconfig vnet0 3.3.3.3
    110 ping 3.3.3.3
    111 ping 3.3.3.4  看效果 
    112 
    113 */
    virt_net3.c

    四、模拟回环网卡程序,实现数据包的收发过程

    前面我们已经实现了转发数据包的功能,此处我们增加一个接受数据包的功能。

    如程序中所示,主要就是交换数据包中的源目的MAC头信息,源目的IP信息等功能。

     1 static void emulator_rx_packet(struct sk_buff *skb, struct net_device *dev)
     2 {
     3     /* 参考LDD3 */
     4     unsigned char *type;
     5     struct iphdr *ih;
     6     __be32 *saddr, *daddr, tmp;
     7     unsigned char    tmp_dev_addr[ETH_ALEN];
     8     struct ethhdr *ethhdr;
     9     
    10     struct sk_buff *rx_skb;
    11         
    12     // 从硬件读出/保存数据
    13     /* 对调"源/目的"的mac地址 */
    14     ethhdr = (struct ethhdr *)skb->data;
    15     memcpy(tmp_dev_addr, ethhdr->h_dest, ETH_ALEN);
    16     memcpy(ethhdr->h_dest, ethhdr->h_source, ETH_ALEN);
    17     memcpy(ethhdr->h_source, tmp_dev_addr, ETH_ALEN);
    18 
    19     /* 对调"源/目的"的ip地址 */    
    20     ih = (struct iphdr *)(skb->data + sizeof(struct ethhdr));
    21     saddr = &ih->saddr;
    22     daddr = &ih->daddr;
    23 
    24     tmp = *saddr;
    25     *saddr = *daddr;
    26     *daddr = tmp;
    27     
    28     //((u8 *)saddr)[2] ^= 1; /* change the third octet (class C) */
    29     //((u8 *)daddr)[2] ^= 1;
    30     type = skb->data + sizeof(struct ethhdr) + sizeof(struct iphdr);
    31     //printk("tx package type = %02x
    ", *type);
    32     // 修改类型, 原来0x8表示ping
    33     *type = 0; /* 0表示reply */
    34     
    35     ih->check = 0;           /* and rebuild the checksum (ip needs it) */
    36     ih->check = ip_fast_csum((unsigned char *)ih,ih->ihl);
    37     
    38     // 构造一个sk_buff
    39     rx_skb = dev_alloc_skb(skb->len + 2);
    40     skb_reserve(rx_skb, 2); /* align IP on 16B boundary */    
    41     memcpy(skb_put(rx_skb, skb->len), skb->data, skb->len);
    42 
    43     /* Write metadata, and then pass to the receive level */
    44     rx_skb->dev = dev;
    45     rx_skb->protocol = eth_type_trans(rx_skb, dev);
    46     rx_skb->ip_summed = CHECKSUM_UNNECESSARY; /* don't check it */
    47     dev->stats.rx_packets++;
    48     dev->stats.rx_bytes += skb->len;
    49 
    50     // 提交sk_buff
    51     netif_rx(rx_skb);
    52 }

     接着在发送数据包函数中:

     1 static int virt_net_send_packet(struct sk_buff *skb, struct net_device *dev)
     2 {
     3     static int cnt = 0;
     4     //printk("virt_net_send_packet cnt = %d
    ", ++cnt);
     5 
     6     /* 对于真实的网卡, 把skb里的数据通过网卡发送出去 */
     7     netif_stop_queue(dev); /* 停止该网卡的队列 */
     8     /* ...... */           /* 把skb的数据写入网卡 */
     9 
    10     /* 构造一个假的sk_buff,上报 */
    11     emulator_rx_packet(skb, dev);
    12 
    13     dev_kfree_skb (skb);   /* 释放skb */
    14     netif_wake_queue(dev); /* 数据全部发送出去后,唤醒网卡的队列 */
    15 
    16     /* 更新统计信息 */
    17     dev->stats.tx_packets++;
    18     dev->stats.tx_bytes += skb->len;
    19     
    20     return 0;
    21 }

    实现效果:

    附驱动程序virt_net4.c

      1 #include <linux/module.h>
      2 #include <linux/errno.h>
      3 #include <linux/netdevice.h>
      4 #include <linux/etherdevice.h>
      5 #include <linux/kernel.h>
      6 #include <linux/types.h>
      7 #include <linux/fcntl.h>
      8 #include <linux/interrupt.h>
      9 #include <linux/ioport.h>
     10 #include <linux/in.h>
     11 #include <linux/skbuff.h>
     12 #include <linux/slab.h>
     13 #include <linux/spinlock.h>
     14 #include <linux/string.h>
     15 #include <linux/init.h>
     16 #include <linux/bitops.h>
     17 #include <linux/delay.h>
     18 #include <linux/ip.h>
     19 
     20 #include <asm/system.h>
     21 #include <asm/io.h>
     22 #include <asm/irq.h>
     23 
     24 static struct net_device *vnet_dev;
     25 
     26 static void emulator_rx_packet(struct sk_buff *skb, struct net_device *dev)
     27 {
     28     /* 参考LDD3 */
     29     unsigned char *type;
     30     struct iphdr *ih;
     31     __be32 *saddr, *daddr, tmp;
     32     unsigned char    tmp_dev_addr[ETH_ALEN];
     33     struct ethhdr *ethhdr;
     34     
     35     struct sk_buff *rx_skb;
     36         
     37     // 从硬件读出/保存数据
     38     /* 对调"源/目的"的mac地址 */
     39     ethhdr = (struct ethhdr *)skb->data;
     40     memcpy(tmp_dev_addr, ethhdr->h_dest, ETH_ALEN);
     41     memcpy(ethhdr->h_dest, ethhdr->h_source, ETH_ALEN);
     42     memcpy(ethhdr->h_source, tmp_dev_addr, ETH_ALEN);
     43 
     44     /* 对调"源/目的"的ip地址 */    
     45     ih = (struct iphdr *)(skb->data + sizeof(struct ethhdr));
     46     saddr = &ih->saddr;
     47     daddr = &ih->daddr;
     48 
     49     tmp = *saddr;
     50     *saddr = *daddr;
     51     *daddr = tmp;
     52     
     53     //((u8 *)saddr)[2] ^= 1; /* change the third octet (class C) */
     54     //((u8 *)daddr)[2] ^= 1;
     55     type = skb->data + sizeof(struct ethhdr) + sizeof(struct iphdr);
     56     //printk("tx package type = %02x
    ", *type);
     57     // 修改类型, 原来0x8表示ping
     58     *type = 0; /* 0表示reply */
     59     
     60     ih->check = 0;           /* and rebuild the checksum (ip needs it) */
     61     ih->check = ip_fast_csum((unsigned char *)ih,ih->ihl);
     62     
     63     // 构造一个sk_buff
     64     rx_skb = dev_alloc_skb(skb->len + 2);
     65     skb_reserve(rx_skb, 2); /* align IP on 16B boundary */    
     66     memcpy(skb_put(rx_skb, skb->len), skb->data, skb->len);
     67 
     68     /* Write metadata, and then pass to the receive level */
     69     rx_skb->dev = dev;
     70     rx_skb->protocol = eth_type_trans(rx_skb, dev);
     71     rx_skb->ip_summed = CHECKSUM_UNNECESSARY; /* don't check it */
     72     dev->stats.rx_packets++;
     73     dev->stats.rx_bytes += skb->len;
     74 
     75     // 提交sk_buff
     76     netif_rx(rx_skb);
     77 }
     78 
     79 static int virt_net_send_packet(struct sk_buff *skb, struct net_device *dev)
     80 {
     81     static int cnt = 0;
     82     //printk("virt_net_send_packet cnt = %d
    ", ++cnt);
     83 
     84     /* 对于真实的网卡, 把skb里的数据通过网卡发送出去 */
     85     netif_stop_queue(dev); /* 停止该网卡的队列 */
     86     /* ...... */           /* 把skb的数据写入网卡 */
     87 
     88     /* 构造一个假的sk_buff,上报 */
     89     emulator_rx_packet(skb, dev);
     90 
     91     dev_kfree_skb (skb);   /* 释放skb */
     92     netif_wake_queue(dev); /* 数据全部发送出去后,唤醒网卡的队列 */
     93 
     94     /* 更新统计信息 */
     95     dev->stats.tx_packets++;
     96     dev->stats.tx_bytes += skb->len;
     97     
     98     return 0;
     99 }
    100 
    101 static const struct net_device_ops virt_netdev_ops = {
    102     .ndo_start_xmit        = virt_net_send_packet,
    103 };
    104 
    105 static int virt_net_init(void)
    106 {
    107     /* 1. 分配一个net_device结构体 */
    108     vnet_dev = alloc_netdev(0, "vnet%d", ether_setup);;  /* alloc_etherdev */
    109 
    110     /* 2. 设置 */
    111     vnet_dev->netdev_ops    = &virt_netdev_ops;
    112 
    113     /* 设置MAC地址 */
    114     vnet_dev->dev_addr[0] = 0x08;
    115     vnet_dev->dev_addr[1] = 0x89;
    116     vnet_dev->dev_addr[2] = 0x89;
    117     vnet_dev->dev_addr[3] = 0x89;
    118     vnet_dev->dev_addr[4] = 0x89;
    119     vnet_dev->dev_addr[5] = 0x11;
    120 
    121     /* 设置下面两项才能ping通 */
    122     vnet_dev->flags           |= IFF_NOARP;
    123     vnet_dev->features        |= NETIF_F_NO_CSUM;    
    124 
    125     /* 3. 注册 */
    126     //register_netdevice(vnet_dev);
    127     register_netdev(vnet_dev);
    128     
    129     return 0;
    130 }
    131 
    132 static void virt_net_exit(void)
    133 {
    134     unregister_netdev(vnet_dev);
    135     free_netdev(vnet_dev);
    136 }
    137 
    138 module_init(virt_net_init);
    139 module_exit(virt_net_exit);
    140 MODULE_AUTHOR("Lover雪儿");
    141 MODULE_LICENSE("GPL");
    142 
    143 
    144 /*
    145 
    146 /////////////////////////////////////////////////////////////////////
    147 网卡驱动程序框架:
    148 app:  socket
    149 --------------------------------------------------------------------
    150         -----------------
    151         ----------------- 若干层网络协议--纯软件
    152         -----------------
    153 hard_start_xmit() 用于发送数据包            ↑↑↑
    154     ↓↓↓              sk_buff                netif_rx()用于上报数据包
    155 调用硬件相关的驱动程序(要提供har_start_xmit,有数据时用netif_rx上报)
    156 --------------------------------------------------------------------
    157               硬件
    158 //////////////////////////////////////////////////////////////////////
    159               
    160 网卡驱动编写:
    161 1.分配一个net_device结构体
    162 2.设置
    163 2.1 发包函数:hard_start_xmit
    164 2.2 收到到数据时,(在中断处理函数中)用netif_rx上报数据
    165 2.3 其他设置
    166 3.注册 register_netdevice              
    167     
    168 
    169 一、测试1th
    170 insmod virt_net.ko
    171 ifconfig vnet0 3.3.3.3
    172 ping 3.3.3.3
    173 ping 3.3.3.4  看效果 
    174 
    175     
    176 */
    virt_net4.c
  • 相关阅读:
    eCryptfs文件系统测试
    体验企业级网络管理软件(图片加视频)
    基于Linux2.6内核的加密容器法保护文件方法
    Orion Network Performance Monitor 软件在网络管理中的应用
    两款硬件代理服务器产品之比较
    3Com Network Supervisor与IBM Tivoli NetView两款网管软件操作视频
    成为IBM精英讲师-一分耕耘 一份收获 同时也多了一份责任!
    Hp Open View安装使用视频
    在Fedora 14 alpha 下测试Kvm情况(视频)
    ACM模板——分数类
  • 原文地址:https://www.cnblogs.com/lihaiyan/p/4439337.html
Copyright © 2011-2022 走看看