OpenWRT(17):网络接口管理守护进程netifd
netifd是一个网络接口守护程序(daemon),它负责初始化网络设备、配置网络参数、处理网络事件以及维护网络连接。netifd通常在系统启动时启动,并在后台运行以监视和调整网络设置。
以下是netifd的一些关键特性和功能:
1.热插拔支持:netifd能够检测网络设备的变化,如USB网络适配器的连接和断开,并相应地更新网络配置。
2.无线支持:它支持无线网络的管理,包括扫描、连接、断开和无线安全设置。
3.多种网络设备支持:netifd支持多种类型的网络设备,包括Ethernet、无线、VPN、隧道等。
4.协议支持:它支持各种网络协议,如DHCP、PPPoE、静态IP配置等。
5.防火墙和路由规则管理:netifd可以配置iptables或nftables规则来控制数据包过滤和网络路由。
6.故障恢复:在网络连接失败时,netifd可以自动尝试重新连接或切换到备用网络连接。
7.配置管理:它使用UCI(UnifiedConfigurationInterface)系统来管理配置文件,这使得配置管理更加灵活和方便。
8.事件驱动:netifd基于事件驱动架构,能够响应网络状态变化和用户操作。
9.守护进程模式:netifd作为守护进程运行,它在后台执行,不占用前台终端。
10.脚本和插件支持:netifd允许使用脚本和插件来扩展其功能,例如,处理特定的网络设备或协议。
在OpenWrt和LEDE项目中,netifd是核心组件之一,它提供了一个稳定的网络环境,使得设备能够可靠地连接到网络。开发者可以通过修改netifd的配置脚本来添加新的网络功能或定制网络行为。
netifd的配置通常存储在/etc/config/network文件中,用户可以通过修改这个文件来改变网络设置,如指定静态IP地址、网关、子网掩码、DNS服务器等。此外,netifd还支持通过UCI配置文件来管理其他网络相关的服务和功能。
相关参考《[OpenWrt Wiki] netifd (Network Interface Daemon) – Technical Reference 》。
1 配置netifd
netifd被Base Files默认选中,用于配置网络接口:
Base system
->netifd.................... OpenWrt Network Interface Configuration Daemon
2 启动netifd
通过/etc/rc.d/S20network启动netifd:
#!/bin/sh /etc/rc.common START=20 STOP=90 USE_PROCD=1 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/kernel/core_pattern ] && { procd_set_param limits core="unlimited" } procd_close_instance } reload_service() { local rv=0 init_switch ubus call network reload || rv=1 /sbin/wifi reload_legacy return $rv } stop_service() { /sbin/wifi down ifdown -a sleep 1 } validate_atm_bridge_section() { uci_validate_section network "atm-bridge" "${1}" \ 'unit:uinteger:0' \ 'vci:range(32, 65535):35' \ 'vpi:range(0, 255):8' \ 'atmdev:uinteger:0' \ 'encaps:or("llc", "vc"):llc' \ 'payload:or("bridged", "routed"):bridged' } validate_route_section() { uci_validate_section network route "${1}" \ 'interface:string' \ 'target:cidr4' \ 'netmask:netmask4' \ 'gateway:ip4addr' \ 'metric:uinteger' \ 'mtu:uinteger' \ 'table:or(range(0,65535),string)' } validate_route6_section() { uci_validate_section network route6 "${1}" \ 'interface:string' \ 'target:cidr6' \ 'gateway:ip6addr' \ 'metric:uinteger' \ 'mtu:uinteger' \ 'table:or(range(0,65535),string)' } validate_rule_section() { uci_validate_section network rule "${1}" \ 'in:string' \ 'out:string' \ 'src:cidr4' \ 'dest:cidr4' \ 'tos:range(0,31)' \ 'mark:string' \ 'invert:bool' \ 'lookup:or(range(0,65535),string)' \ 'goto:range(0,65535)' \ 'action:or("prohibit", "unreachable", "blackhole", "throw")' } validate_rule6_section() { uci_validate_section network rule6 "${1}" \ 'in:string' \ 'out:string' \ 'src:cidr6' \ 'dest:cidr6' \ 'tos:range(0,31)' \ 'mark:string' \ 'invert:bool' \ 'lookup:or(range(0,65535),string)' \ 'goto:range(0,65535)' \ 'action:or("prohibit", "unreachable", "blackhole", "throw")' } validate_switch_section() { uci_validate_section network switch "${1}" \ 'name:string' \ 'enable:bool' \ 'enable_vlan:bool' \ 'reset:bool' \ 'ar8xxx_mib_poll_interval:uinteger' \ 'ar8xxx_mib_type:range(0,1)' } validate_switch_vlan() { uci_validate_section network switch_vlan "${1}" \ 'device:string' \ 'vlan:uinteger' \ 'ports:list(ports)' } service_triggers() { procd_add_reload_trigger network wireless procd_open_validate validate_atm_bridge_section validate_route_section [ -e /proc/sys/net/ipv6 ] && validate_route6_section validate_rule_section [ -e /proc/sys/net/ipv6 ] && validate_rule6_section validate_switch_section validate_switch_vlan procd_close_validate } shutdown() { ifdown -a sleep 1 }
3 netifd流程
netifd首先解析配置,然后执行解析的配置。
main
netifd_setup_signals
netifd_ubus_init
uloop_init
ubus_connect
netifd_ubus_add_fd
netifd_add_object
main_object--添加network ubus服务,处理netifd对象。
dev_object--添加network.device ubus服务,处理device对象。
wireless_object--添加network.wireless ubus服务,处理netifd_iface对象。
netifd_add_iface_object
proto_shell_init
netifd_init_script_handlers--添加一个新协议处理器shell,处理/lib/netifd/proto中的脚本。
proto_shell_add_handler
extdev_init--扫描/lib/netifd/extdev-config目录下的配置文件,并为每个找到的设备类型创建一个设备。
wireless_init--扫描/lib/netfifd/wireless目录下配置文件,进行无线网络接口初始化函数,它负责启动无线网络设备,扫描无线网络,连接无线网络等任务的初始化工作。
system_init
config_init_all
config_init_package--可以通过uci show network或者uci show wireless查看内容。
uci_load--获取network、wireless的UCI配置参数,存入uci_network、uci_wireless。
config_init_board
device_reset_config
config_init_devices--获取uci_network中支持Bridge的device配置,创建设备。
config_init_vlans--获取uci_network中关于bridge-vlan配置,获取设备,配置vlan。
config_init_devices--获取uci_network中不支持Bridge的device配置,创建设备。
config_init_interfaces--获取uci_network中interface配置。
config_parse_interface
config_init_ip--更新interfaces的IP,并解析route、route6、neighbor、neighbor6。
config_init_rules--解析rule、rule6。
config_init_globals--配置ula_prefix。
config_init_wireless
config_parse_wireless_device--根据解析的wifi-device配置创建无线设备。
wireless_device_create
config_parse_wireless_interface--根据解析的wifi-iface配置无线接口。
wireless_interface_create
config_parse_wireless_vlan--处理wifi-vlan。
config_parse_wireless_station--处理wifi-station。
device_reset_old
device_init_pending
interface_refresh_assignments
interface_start_pending--启动interfaces上autostart属性的设备。
wireless_start_pending--启动wireless_devices设备。
uloop_run
netifd_kill_processes
netifd_ubus_done
协议相关处理脚本:
lib/netifd/proto/ ├── dhcp.sh ├── dhcpv6.sh └── ppp.sh
3.1 netifd提供的ubus服务
'network' @e48923aa "restart":{} "reload":{} "add_host_route":{"target":"String","v6":"Boolean","interface":"String","exclude":"Boolean"} "get_proto_handlers":{} "add_dynamic":{"name":"String"} "netns_updown":{"jail":"String","start":"Boolean"} 'network.device' @7bc915cc "status":{"name":"String"} "set_alias":{"alias":"Array","device":"String"} "set_state":{"name":"String","defer":"Boolean","auth_status":"Boolean"} "stp_init":{} 'network.interface' @d6254176 "up":{} "down":{} "renew":{} "status":{} "prepare":{} "dump":{} "add_device":{"name":"String","link-ext":"Boolean","vlan":"Array"} "remove_device":{"name":"String","link-ext":"Boolean","vlan":"Array"} "notify_proto":{} "remove":{} "set_data":{} 'network.interface.lan' @62b7e274 "up":{} "down":{} "renew":{} "status":{} "prepare":{} "dump":{} "add_device":{"name":"String","link-ext":"Boolean","vlan":"Array"} "remove_device":{"name":"String","link-ext":"Boolean","vlan":"Array"} "notify_proto":{} "remove":{} "set_data":{} 'network.interface.loopback' @e469cb75 "up":{} "down":{} "renew":{} "status":{} "prepare":{} "dump":{} "add_device":{"name":"String","link-ext":"Boolean","vlan":"Array"} "remove_device":{"name":"String","link-ext":"Boolean","vlan":"Array"} "notify_proto":{} "remove":{} "set_data":{} 'network.rrdns' @5412c564 "lookup":{"addrs":"Array","timeout":"Integer","server":"String","port":"(unknown)","limit":"Integer"} 'network.wireless' @5ca467ed "up":{} "down":{} "reconf":{} "status":{} "notify":{} "get_validate":{}
3.2 netifd相关的uci配置
network.loopback=interface network.loopback.device='lo' network.loopback.proto='static' network.loopback.ipaddr='127.0.0.1' network.loopback.netmask='255.0.0.0' network.globals=globals network.globals.ula_prefix='fd97:9986:d46c::/48' network.@device[0]=device network.@device[0].name='br-lan' network.@device[0].type='bridge' network.@device[0].ports='eth0' network.lan=interface network.lan.device='br-lan' network.lan.proto='static' network.lan.ipaddr='192.168.1.1' network.lan.netmask='255.255.255.0'