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'