根据发行版,调用ip link set <iface> up
(或 down;还有 ifup / ifdown)将查看各种配置文件(Debian 上的 /etc/network/interfaces 我认为,Gentoo 有 /etc/conf.d/net...),并进行更改(例如与 DHCP 交互等)
据我所见strace
,该ip
命令直接与内核对话(是这样吗?)。但最终,有人启动这些 shell 脚本/读取配置。这背后的机制是什么? init 系统是否在某些内核接口上侦听 up/down 状态更改并启动这些脚本?或者有什么不同吗?
答案1
正如您所描述的那样,调用ip link set <iface> up
只是通过内核与内核进行最少的通信rtnetlink应用程序编程接口(这不仅与路由有关,还与链接、地址等有关。这里是RTM_NEWLINK
)以管理方式启动接口。较旧的ifconfig
工具使用已弃用的(针对网络)ioctl API(此处为SIOCGIFFLAGS
)向内核提出相同的要求。
这些命令是低级命令,仅执行所要求的操作,仅此而已。
ifup
是(在 Debian 上)的一部分如果向上向下(或替代的如果上下2)套件,并且在不同的 Linux 发行版上有不同的实现。它们只是一套脚本,可能会调用ip link set ...
自身,也许其中一些也会直接使用其他可用的工具(例如网络管理器)。所以你绝对不能把它们放在同一水平上:ip link set ... up
根本不是ifup ...
。
现在其他网络工具会怎么样网络管理器互动并知道发生了什么?因为他们在询问内核,通过rtnetlink,获得他们感兴趣的一些网络事件的通知。网络链接API 实现支持多播:这意味着多个感兴趣方(属于用户空间或内核)可以有效地接收单个消息,因此这简化了事件实现。
通常,当某些东西(此处ip link set ... up
)向内核发送消息时,内核会回复一条消息,该消息被多播给感兴趣的各方:该ip link
命令收到此消息,而且所有等待的工具现在都知道“刚刚启动了一个接口” “(我将忽略管理状态启动与操作状态启动之间的差异)。
可以使用由命令输出驱动的事件循环在脚本中执行相同的操作ip monitor
它正在等待来自内核的网络事件。当然,真正可解析的输出会更好,遗憾的是,而许多其他输出ip路由2子命令支持 JSON 输出(使用-json
),但ip monitor
.
这是一个基本的shell 示例基于ip monitor link
每当对该接口进行更改时显示该接口的操作状态(即使它与其操作状态无关..基本的例子)。由于它正在解析不可靠的输出,因此预计它在某些情况下会失败:
#!/bin/sh
ip -o monitor link | while read -r index interface status remaining; do
iface=$(printf '%s\n' "$interface" | sed -E 's/(@.*)?:$//')
operstate=$(printf '%s\n' "$remaining" | grep -Eo ' state [^ ]+' | sed 's/^ state //')
printf '%s %s\n' "$iface" "$operstate"
done
当上面的脚本运行时,在其他地方尝试这些命令:
# ip link add test1 type veth peer name test2
# ip link set test1 up
# ip link set test2 up
# ip link delete test1 # script doesn't handle correctly lines starting with Deleted
地址、路线等也同样如此。这就是网络管理器正在对命令做出反应ip link set <iface> up
。