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 基础理解
-
Linux 为什么把网络设备抽象为 net_device?
-
sk_buff 表示什么?
16.2 数据路径
-
发送数据路径是什么?
-
接收数据路径是什么?
16.3 驱动结构
-
nod_start_xmit 的作用是什么?
-
register_netdev 做了什么?