1. 学习目标

  1. 理解 Linux 网络设备架构

理解 Linux 网络通信结构:

User Space
   │
   ▼
Socket API
   │
   ▼
TCP/IP Stack
   │
   ▼
Network Driver
   │
   ▼
Network Hardware

  • 理解 Linux 网络设备模型

理解 Linux 网络设备核心结构:

net_device
net_device_ops
sk_buff

  • 理解网络数据收发流程

掌握:

发送路径
接收路径
  • 能编写基础网络驱动

掌握核心 API:

alloc_netdev
register_netdev
unregister_netdev

  • 能调试网络设备

掌握工具

ip
ifconfig
tcpdump

2. Linux 网络子系统简介

Linux 网络系统结构:

User Application
       │
       ▼
Socket API
       │
       ▼
TCP/IP Protocol Stack
       │
       ▼
Network Device Driver
       │
       ▼
Network Hardware

例如:

Ethernet
WiFi
CAN

3. Linux 网络设备

Linux 将网络设备表示为:

net_device

系统中的设备:

eth0
wlan0
can0
lo

查看设备:

ip link

4. net_device 结构

net_device 表示:

网络设备

结构:

struct net_device
{
    char name[IFNAMSIZ];
    const struct net_device_ops *netdev_ops;
};

关键成员:

name
netdev_ops

5. net_device_ops

net_device_ops 表示:

网络设备操作接口

结构:

struct net_device_ops
{
    int (*ndo_open)(struct net_device *);
    int (*ndo_stop)(struct net_device *);
    netdev_tx_t (*ndo_start_xmit)(struct sk_buff *,
                                  struct net_device *);
};

主要函数:

open
stop
transmit

6. sk_buff

Linux 网络数据使用:

sk_buff

结构:

struct sk_buff
{
    unsigned char *data;
    unsigned int len;
};

作用:

表示网络数据包

例如:

Ethernet frame
IP packet
TCP segment

7. Netdev 驱动注册流程

网络驱动基本流程:

分配 net_device
      │
设置 net_device_ops
      │
register_netdev
      │
生成网络接口

流程图:

Network Driver
       │
       ▼
alloc_netdev
       │
       ▼
register_netdev
       │
       ▼
eth0

8. 发送数据流程

发送流程:

User Space
    │
send()
    │
TCP/IP Stack
    │
ndo_start_xmit
    │
Network Driver
    │
Hardware

驱动函数:

ndo_start_xmit

示例:

static netdev_tx_t my_xmit(struct sk_buff *skb,
                           struct net_device *dev)
{
    printk("send packet\n");

    dev_kfree_skb(skb);

    return NETDEV_TX_OK;
}

9. 接收数据流程

接收流程:

Network Hardware
      │
      ▼
IRQ
      │
      ▼
Driver
      │
      ▼
netif_rx
      │
      ▼
TCP/IP Stack
      │
      ▼
User Space

10. 网络驱动示例

简单网络驱动结构:

static int my_net_open(struct net_device *dev)
{
    printk("net open\n");
    return 0;
}

static int my_net_stop(struct net_device *dev)
{
    printk("net stop\n");
    return 0;
}

static netdev_tx_t my_xmit(struct sk_buff *skb,
                           struct net_device *dev)
{
    printk("send packet\n");

    dev_kfree_skb(skb);

    return NETDEV_TX_OK;
}

static const struct net_device_ops my_netdev_ops =
{
    .ndo_open = my_net_open,
    .ndo_stop = my_net_stop,
    .ndo_start_xmit = my_xmit,
};

11. 驱动注册

分配设备:

struct net_device *dev;

dev = alloc_netdev(0,"eth%d",NET_NAME_UNKNOWN,ether_setup);

注册设备:

register_netdev(dev);

12. 用户空间管理网络

Linux 网络管理工具:

ip
ifconfig

查看接口:

ip link

启动接口:

ip link set eth0 up

配置 IP:

ip addr add 192.168.1.10/24 dev eth0

13. Netdev 子系统结构总结

Linux 网络驱动结构:

User Space
   │
   ▼
Socket API
   │
   ▼
TCP/IP Stack
   │
   ▼
Network Driver
   │
   ▼
Hardware

核心结构:

net_device
net_device_ops
sk_buff

14. 驱动常见问题

网络接口不存在

原因:

register_netdev 没调用

发送失败

原因:

ndo_start_xmit 未实现

无法接收数据

原因:

IRQ 未注册

15. 总结

Linux 网络驱动核心结构:

net_device
net_device_ops
sk_buff

关系:

Network Stack
      │
      ▼
Network Driver
      │
      ▼
Hardware

最重要原则:

网络驱动 = TCP/IP Stack + net_device

16. Q&A

16.1 基础理解

  1. Linux 为什么把网络设备抽象为 net_device?

  2. sk_buff 表示什么?

16.2 数据路径

  1. 发送数据路径是什么?

  2. 接收数据路径是什么?

16.3 驱动结构

  1. nod_start_xmit 的作用是什么?

  2. register_netdev 做了什么?