OpenWrt network 启动过程

OpenWrt network 启动过程

/etc/config/network

networt 配置文件为 /etc/config/network

关于/etc/config/network 的生成可以看我的上一篇博文:OpenWrt /etc/config/network 的生成过程

config interface 'loopback'
        option ifname 'lo'
        option proto 'static'
        option ipaddr '127.0.0.1'
        option netmask '255.0.0.0'

config globals ‘globals’
option ula_prefix ‘fd20:4754:ca54::/48’

config interface ‘lan’
option ifname ‘eth0.1’
option force_link ‘1’
option macaddr ‘ff:ff:ff:ff:ff:ff’
option type ‘bridge’
option proto ‘dhcp’
option ipaddr ‘192.168.1.1’
option netmask ‘255.255.255.0’
option ip6assign ‘60’

config interface ‘wan’
option force_link ‘1’
option macaddr ‘ff:ff:ff:ff:ff:ff’
option proto ‘dhcp’
option ifname ‘apcli0’

config interface ‘wan6’
option ifname ‘eth0.2’
option proto ‘dhcpv6’

config switch
option name ‘switch0’
option reset ‘1’
option enable_vlan ‘1’

config switch_vlan
option device ‘switch0’
option vlan ‘1’
option ports ‘0 6t’

config switch_vlan
option device ‘switch0’
option vlan ‘2’
option ports ‘1 6t’

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43

/etc/init.d/network

openWrt 网络启动脚本为/etc/init.d/network, 以MT7688 为例内容如下:

#!/bin/sh /etc/rc.common

START=20
STOP=90

USE_PROCD=1 # 表示由 procd 进程管理
# 更多说明:https://openwrt.org/start?id=docs/guide-developer/procd-init-scripts

init_switch() {
setup_switch() { return 0; }

    include /lib/network  
    setup_switch    # 调用的是 /lib/network 里定义的 setup_switch

}

start_service() {
init_switch
#初始化 switch
procd_open_instance
# 创建一个实例
# ubus call service list 可以查看实例
procd_set_param command /sbin/netifd
# 执行的命令是 /sbin/netifd
procd_set_param respawn
# 定义respawn参数,告知procd当程序退出后尝试进行重启
procd_set_param watch network.interface
# 监控的ubs 名字
[ -e /proc/sys/kernel/core_pattern ] && {
procd_set_param limits core=“unlimited”
echo ‘/tmp/%e.%p.%s.%t.core’ > /proc/sys/kernel/core_pattern
}
procd_close_instance
# 关闭一个实例
}

reload_service() {
init_switch
ubus call network reload
/sbin/wifi reload_legacy
}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42

start_service 中主要做了两件事情:

  • init_switch
  • /sbin/netifd

init_switch

init_switch -> setup_switch ,找到 setup_switch 的定义在 /lib/network/switch.sh

/lib/network 下有两个文件

config.sh
switch.sh

   
   
   
   
  • 1
  • 2
#!/bin/sh
# Copyright (C) 2009 OpenWrt.org

setup_switch_dev() {
local name
config_get name 1 " < / s p a n > n a m e n a m e < s p a n c l a s s = " t o k e n o p e r a t o r " > = < / s p a n > < s p a n c l a s s = " t o k e n s t r i n g " > " 1" name name=" 1"</span>namename<spanclass="tokenoperator">=</span><spanclass="tokenstring">"{name:-KaTeX parse error: Expected 'EOF', got '}' at position 2: 1}̲" name” ] && ifconfig n a m e " < / s p a n > u p s w c o n f i g d e v < s p a n c l a s s = " t o k e n s t r i n g " > " name" up swconfig dev " name"</span>upswconfigdev<spanclass="tokenstring">"name” load network
}

setup_switch() {
config_load network # 读取 /etc/config/network ,config_load 在/lib/functions.sh 中定义
config_foreach setup_switch_dev switch
}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16

config_foreach setup_switch_dev switch 最终执行 swconfig dev switch0 load network

swconfig

swconfig 是 openWrt 下用于配置 switch 的 工具,工具是基于 genl (Generic Netlink)接口与内核通信实现的。usage 如下。

~# swconfig --help
swconfig list
swconfig dev  [port |vlan ] (help|set  |get |load |show)

   
   
   
   
  • 1
  • 2
  • 3

swconfig dev switch0 load network 会读取 /etc/config/network ,根据里面的配置信息对swicth 进行配置。所涉及的配置有:

  • vlan 的使能
  • port 的划分,如上,有port0 和port1 两个端口,port0 归valn1 ,port1 归vlan2

netifd

netifd是openWrt中用于进行网络配置的守护进程。netifd 读取 /etc/config/network 和/etc/config/wireless并在ubus 上创建如下对象:

# ubus list network*
network
network.device
network.interface
network.interface.lan
network.interface.loopback
network.interface.wan
network.interface.wan6
network.wireless

   
   
   
   
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

同时可看到 /sys/class/net 下面创建了虚拟网卡,也可以 ifconfig 查看到

ls -l /sys/class/net/*
lrwxrwxrwx    1 root     root             0 May 11 15:52 /sys/class/net/apcli0 -> ../../devices/virtual/net/apcli0
lrwxrwxrwx    1 root     root             0 May 12 09:29 /sys/class/net/apcli1 -> ../../devices/virtual/net/apcli1
lrwxrwxrwx    1 root     root             0 May 11 15:52 /sys/class/net/br-lan -> ../../devices/virtual/net/br-lan
lrwxrwxrwx    1 root     root             0 Jan  1  1970 /sys/class/net/eth0 -> ../../devices/10100000.ethernet/net/eth0
lrwxrwxrwx    1 root     root             0 May 12 09:29 /sys/class/net/eth0.1 -> ../../devices/virtual/net/eth0.1
lrwxrwxrwx    1 root     root             0 May 12 09:29 /sys/class/net/eth0.2 -> ../../devices/virtual/net/eth0.2
lrwxrwxrwx    1 root     root             0 Jan  1  1970 /sys/class/net/lo -> ../../devices/virtual/net/lo
lrwxrwxrwx    1 root     root             0 May 11 15:52 /sys/class/net/ra0 -> ../../devices/virtual/net/ra0

   
   
   
   
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

netifd 如何通知内核创建虚拟网卡的?

netifd

main 
 config_init_all
  config_init_interfaces
   config_parse_interface
    interface_add
     __interface_add
      vlist_add(&interfaces, &iface->node, iface->name);
       tree->update  // = interfaces.update
         interface_update
          interface_claim_device
           device_get
            get_vlan_device_chain
             get_vlan_device
              vldev->dev.set_state = vlan_set_device_state   // 设置set_state 方法            
           interface_set_device_config(iface, dev)
            device_apply_config
             dev->set_state()                                // 调用set_state 方法
               vlan_set_device_state
                system_vlan_add
                 system_vlan
                  ioctl(sock_ioctl, SIOCSIFVLAN, &ifr);      // 通过socket 给内核发消息 ifr.cmd = ADD_VLAN_CMD

   
   
   
   
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21

kernel

// linux-3.18.21\net\8021q\vlan.c
vlan_ioctl_handler
  case ADD_VLAN_CMD:		
		err = register_vlan_device(dev, args.u.VID);
		break;

   
   
   
   
  • 1
  • 2
  • 3
  • 4
  • 5

小结

  • 网络配置文件 /etc/config/network
  • 网络初始化脚本/etc/init.d/network
  • swconfig 用于配置 switch
  • netifd 进行更复杂的网络管理,创建虚拟网卡,dhcp 等
                                

你可能感兴趣的:(Openwrt)