在某些时候,在我遇到的一些关于 Linux 的教材(来自 Linux Foundation)中,提到了以下内容:
ip
ifconfig
命令比使用命令更通用、更高效网络链接套接字而不是读写控制系统调用。
谁能详细说明一下这一点,因为我无法理解幕后发生的事情?
PS我知道这个话题在这些工具上,但它没有解决它们操作方式上的具体差异
答案1
FreeBSD 和 OpenBSD 等操作系统上的命令ifconfig
已根据操作系统的其余部分进行了更新。如今,它可以在这些操作系统上配置各种网络接口设置,并处理一系列网络协议。 BSDioctl()
为这些事情提供支持。
这在 Linux 世界中并没有发生。今天有三个ifconfig
命令:
ifconfig
从GNU inetutilsjdebp % inetutils-ifconfig -l enp14s0 enp15s0 罗 jdebp % inetutils-ifconfig lo lo 链接 encap:本地环回 inet 地址:127.0.0.1 广播:0.0.0.0 掩码:255.0.0.0 上环回运行 MTU:65536 公制:1 RX 数据包:9087 错误:0 丢弃:0 溢出:0 帧:0 TX 数据包:9087 错误:0 丢弃:0 溢出:0 运营商:0 碰撞:0 txqueuelen:1000 RX 字节:51214341 TX 字节:51214341 杰德BP%
ifconfig
从NET-3 网络工具jdebp % ifconfig -l ifconfig: 选项--help' 提供使用信息。
-l' not recognised. ifconfig:
jdebp % ifconfig lo lo:flags=73<UP、LOOPBACK、RUNNING> mtu 65536 inet 127.0.0.1 网络掩码 255.0.0.0 inet6 ::1 prefixlen 128scopeid 0x10<主机> inet6 ::2 prefixlen 128scopeid 0x80<兼容,全局> inet6 fe80:: prefixlen 10scopeid 0x20<链接> Loop txqueuelen 1000(本地环回) RX 数据包 9087 字节 51214341 (48.8 MiB) RX 错误 0 丢弃 0 溢出 0 帧 0 TX 数据包 9087 字节 51214341 (48.8 MiB) TX 错误 0 丢弃 0 溢出 0 载波 0 冲突 0 杰德BP%ifconfig
来自(版本 1.40)诺什工具集jdebp % ifconfig -l enp14s0 enp15s0 罗 jdebp % ifconfig lo 罗 链接环回运行 链接地址 00:00:00:00:00:00 bdaddr 00:00:00:00:00:00 inet4 地址 127.0.0.1 prefixlen 8 bdaddr 127.0.0.1 inet4 地址 127.53.0.1 prefixlen 8 bdaddr 127.255.255.255 inet6 地址 ::2 范围 0 prefixlen 128 inet6 地址 fe80:: 范围 1 prefixlen 10 inet6 地址 ::1 范围 0 prefixlen 128 jdebp % sudo ifconfig lo inet4 127.1.0.2 别名 jdebp % sudo ifconfig lo inet6 ::3/128 别名 jdebp % ifconfig lo 罗 链接环回运行 链接地址 00:00:00:00:00:00 bdaddr 00:00:00:00:00:00 inet4 地址 127.0.0.1 prefixlen 8 bdaddr 127.0.0.1 inet4 地址 127.1.0.2 prefixlen 32 bdaddr 127.1.0.2 inet4 地址 127.53.0.1 prefixlen 8 bdaddr 127.255.255.255 inet6 地址 ::3 范围 0 prefixlen 128 inet6 地址 ::2 范围 0 prefixlen 128 inet6 地址 fe80:: 范围 1 prefixlen 10 inet6 地址 ::1 范围 0 prefixlen 128 杰德BP%
正如您所看到的,GNU inetutils 和 NET-3 网络工具ifconfig
在 IPv6、具有多个地址的接口以及-l
.
IPv6 问题的部分原因是工具本身缺少一些代码。但主要是由于 Linux 没有(像其他操作系统那样)通过ioctl()
接口提供 IPv6 功能。它只允许程序通过网络查看和操作 IPv4 地址ioctl()
。
相反,Linux 通过不同的接口send()
并recv()
在特殊且有些奇怪的套接字地址族上提供此功能AF_NETLINK
。
GNU 和 NET- ifconfig
3可以已进行调整以使用这个新的 API。反对这样做的理由是它不能移植到其他操作系统,但这些程序在实践中是可行的已经不便携反正所以这没什么争议。
但它们没有进行调整,并且至今仍如上述。 (多年来,有些人在不同的时间点对它们进行了研究,但遗憾的是,这些改进从未纳入程序中。例如: Bernd Eckenfels 从未接受过补丁ifconfig
在补丁编写 4 年后,为 NET-3 net-tools 添加了一些 netlink API 功能。)
相反,有些人将工具集完全重新发明为ip
命令,它使用新的 Linux API,具有不同的语法,并在时尚风格的界面后面结合了其他几个功能。command subcommand
我需要一个ifconfig
具有 FreeBSD 的命令行语法和输出风格的东西ifconfig
(GNU 和 NET-3 都ifconfig
没有,而且ip
肯定也没有)。所以我写了一篇。作为人们可以ifconfig
在 Linux 上编写使用 netlink API 的证明,它确实做到了。
因此,关于 的公认智慧ifconfig
,例如您引用的内容,不再是真正的事实。这是现在不真实说“ifconfig
不使用netlink。”。盖住两个人的毯子盖不住三个人。
它一直以来说“netlink 更高效”是不真实的。对于使用 执行的任务ifconfig
,netlink API 和 API 之间的效率并没有多大区别ioctl()
。对于任何给定的任务,人们都会进行几乎相同数量的 API 调用。
事实上,每个 API 调用都是二netlink 情况下的系统调用,而不是ioctl()
系统中的系统调用。可以说,netlink API 的缺点是,在频繁使用的系统上,它明确地包含了该工具永远不会收到通知其 API 调用结果的确认消息的可能性。
此外,说它ip
比 GNU 和 NET-3“更通用”也是ifconfig
不真实的。因为它使用netlink。它更通用,因为它可以完成更多任务,可以在一个大程序中完成需要单独程序完成的任务以外 ifconfig
。它并不能仅仅通过内部使用的 API 来执行这些额外的任务而变得更加通用。 API 对此没有任何固有的内容。ioctl()
例如,人们可以编写一个使用 FreeBSD API 的一体化工具,并且同样可以说它比单独的ifconfig
、route
、arp
和ndp
命令“更通用”。
人们还可以为使用 netlink API 的 Linux编写route
、arp
、 和命令。ndp
进一步阅读
- 乔纳森·德博因·波拉德 (2019)。
ifconfig
。 小吃指南。软件。 - 爱德华多·费罗 (2009-04-16)。ifconfig:报告错误的 IP 地址/初始补丁。 Debian 错误 #359676。
答案2
ifconfig
由于多种原因,我们在许多发行版中使用的标准已被弃用。以过时且有限的方式与内核进行对话,事实上,不再了解所有网络配置。您将无法操作某些网络配置,例如 ifconfig
您可以使用ip
.此外,ifconfig
对网络命名空间的支持也是有限的。
作为一个轶事,我发现接口 IP 别名仅在 SuSE 中可见,ip
而在 SuSE 中不可见ifconfig
。
至于背后的差异:ifconfig 与 ip:有什么区别和比较网络配置
虽然
ip
乍一看可能有点复杂,但它的功能比 ifconfig 广泛得多。它在功能上组织在网络堆栈的两层上,即第 2 层(链路层)、第 3 层(IP 层),并执行 net-tools 包中所有上述命令的工作。虽然
ifconfig
主要显示或修改系统的界面,但该命令能够执行以下任务:
显示或修改界面属性。
添加、删除 ARP 缓存条目以及为主机创建新的静态 ARP 条目。
显示与所有接口关联的 MAC 地址。
显示和修改内核路由表。
它与古老版本 ifconfig 的主要区别之一是后者使用 ioctl 进行网络配置,这是一种不太受欢迎的与内核交互的方式,而前者利用 netlink 套接字机制进行网络配置,这是一种更灵活的后继者使用 rtnetlink (增加了网络环境操作能力)在内核和用户空间之间进行相互通信的 ioctl。
关于netlink的使用/优点:来自LJ - Kernel Korner - 为什么以及如何使用 Netlink Socket
Netlink套接字是一种特殊的IPC,用于在内核和用户空间进程之间传输信息。它通过用户空间进程的标准套接字 API 和内核模块的特殊内核 API 为两者之间提供全双工通信链路。 Netlink 套接字使用地址族 AF_NETLINK。
……
为什么上述功能使用 netlink 而不是系统调用、ioctls 或 proc 文件系统来实现用户和内核之间的通信?为新功能添加系统调用、ioctls 或 proc 文件并非易事;我们冒着污染内核和破坏系统稳定性的风险。但是,Netlink 套接字很简单:只需要将一个常量(即协议类型)添加到 netlink.h 中。然后,内核模块和应用程序就可以立即使用套接字样式的 API 进行通信。
....
Netlink套接字是一个灵活的接口,用于用户空间应用程序和内核模块之间的通信。它为应用程序和内核提供了易于使用的套接字 API。它提供了其他内核/用户空间 IPC 所不具备的高级通信功能,例如全双工、缓冲 I/O、多播和异步通信。