ip链接集上/下:如何调用脚本?

ip链接集上/下:如何调用脚本?

根据发行版,调用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

相关内容