1、基本概念
1.1、wan lan
- LAN:Local Area Network 的英文简称,即局域网
我们计算机和路由连在一起就是接这个口 - WAN: Wide Area Network 的英文简称,即广域网
运营商拉进来的网线就是和这个口连在一起 - VLAN( Virtual Local Area Network)的中文名为"虚拟局域网"
VLAN通常是在局域网中逻辑地再划分为几个网段来构成VLAN。一个局域网中可以划分为N多个VLAN,使VLAN之间不可互相通信(通常这是为了安全起见)。LAN和WAN都属于VLAN - VLAN ID:每个VLAN都有一个ID,范围为0-4095之间,但是0和4095仅仅限于系统使用,用户不能查看和使用。所以我们可以使用的范围为1-4994
- ACCESS口:在OpenWRT里面为未标记,只属于一个VLAN通过
- TRUNK口:在OpenWRT里面为已标记,允许多个VLAN通过
- ethX.X:在大部分Linux发行版中,第一个X为实际的物理网卡ID,第二个X为VLAN ID
1.2、phy switch
- MAC(介质访问控制),可以理解成数据链路层即可
- PHY(物理性),简单理解层转成物理层的连接组件即可
- 控制接口(MDC/DMIO,I2C,SPI),数据接口(RGMII / GMII/MII)
- 网卡: 可以理解成phy 和mac 组成的一个芯片,直接可以通过各种接口和cpu对接
- PHY: 单纯的物理层芯片,通常是和SOC 或是MCU对接,部分soc和mcu 都会集成mac
- switch : 多网口设备,内部结构就是mac+phy,主要功能是将数据在不同端口之间转发。也会留有数据接口以便和SOC 等设备对接。
嵌入式设备的switch 以及PHY 芯片调试和选型
2、 openwrt官方配置swconfig
openwrt官方使用的是swconfig工具,它属于package下面的一个包
https://oldwiki.archive.openwrt.org/doc/techref/swconfig
- 可以使用swconfig命令来查看一些网卡的信息,如swconfig list 、swconfig dev eth0 show等。
swconfig 结构框架是应用层与内核驱动通信的一种框架,主要实通过应用层命令去配置交换机芯片的底层驱动,应用层与内核层采用netlink通信机制.
首先看到
- package/network/config/swconfig/cli.c文件,跳到main()函数,里面主要做了检查参数,根据传进来的参数操作底层驱动。
然后看到 - target/linux/generic/files/drivers/net/phy/swconfig.c
- target/linux/generic/files/include/linux/switch.h
这是内核层的代码,因为交换机芯片种类繁多,需要有统一接口去兼容所有交换机驱动接口,swconfig.c就是一套定义接口。应用层的命令首先会跳到swconig.c去选择底层驱动函数。
交换机芯片驱动位置
- target/linux/generic/files/drivers/net/phy/
交换机是总线设备驱动类型的,在swconfig.c已经注册了交换机设备register_switch,在驱动里面要注册交换机驱动,然后匹配设备和驱动,调用probe.
所以使用应用层swconfig的package包时,内核也需要有相应的CONFIG_SWCONFIG=y
配置开启。
然后就是 未标记 和 已标记 的意思:
在 VLAN 中说的很清楚了,不管是 未标记 还是 已标记,都是相对于将要到达某个口的network traffic而说的,而不是已经进到某个口的network traffic。
已标记:进入该口的network traffic必须是带tag的,以上图第一行(即vlan 1)为例,进入 CPU (eth0 设备) 的数据必须是带tag的
未标记:进入该口的network traffic必须是不带tag的(要是数据带tag,就会将该数据也就是 network traffic 丢弃掉),并且从该口出去的network traffic的tag会被remove掉。 注意 每一个口只能对一个vlan id设为 未标记(很容易理解嘛,如果一个口对 vlan1 设为 未标记,同时也对 vlan2 设为 未标记,那么它就不知道自己到底属于哪个vlan了,实际上 network traffic 进入该口之后是要打上对应的vlan tag的,它就不知道到底该打上哪个tag了)
关:带有该vlan id的数据无法到达这些口。
3、network启动配置switch过程
/etc/init.d/network start的时候会调用setup_switch函数,该函数位于/lib/network/switch.sh中
init_switch() {
setup_switch() { return 0; }
include /lib/network
setup_switch
}
start_service() {
init_switch
procd_open_instance
procd_set_param command /sbin/netifd
procd_set_param respawn
procd_set_param watch network.interface
[ -e /proc/sys/kern