在底层,可以使用rtnetlink 套接字捕获这些事件,无需任何轮询。旁注:如果你使用 rtnetlink,你必须和 udev 一起工作,否则你的程序可能会在 udev 重命名一个新的网络接口时出现混乱。
使用 shell 脚本进行网络配置的问题是 shell 脚本对于事件处理很糟糕(例如插入和拔出网线)。如果您需要更强大的功能,请查看我的 NCD programming language,这是一种专为网络配置而设计的编程语言。
例如,一个简单的 NCD 脚本,它将“cable in”和“cable out”打印到 stdout(假设接口已经启动):
process foo {
# Wait for device to appear and be configured by udev.
net.backend.waitdevice("eth0");
# Wait for cable to be plugged in.
net.backend.waitlink("eth0");
# Print "cable in" when we reach this point, and "cable out"
# when we regress.
println("cable in"); # or pop_bubble("Network cable in.");
rprintln("cable out"); # or rpop_bubble("Network cable out!");
# just joking, there's no pop_bubble() in NCD yet :)
}
(在内部,net.backend.waitlink() 使用 rtnetlink,net.backend.waitdevice() 使用 udev)
NCD 的想法是你只用它来配置网络,所以通常配置命令会介于两者之间,例如:
process foo {
# Wait for device to appear and be configured by udev.
net.backend.waitdevice("eth0");
# Set device up.
net.up("eth0");
# Wait for cable to be plugged in.
net.backend.waitlink("eth0");
# Add IP address to device.
net.ipv4.addr("eth0", "192.168.1.61", "24");
}
需要注意的重要部分是允许执行回归;在第二个例子中,例如,如果电缆被拔出,IP地址将自动删除。