进一步阅读

进一步阅读

在某些时候,在我遇到的一些关于 Linux 的教材(来自 Linux Foundation)中,提到了以下内容:

ipifconfig命令比使用命令更通用、更高效网络链接套接字而不是读写控制系统调用。

谁能详细说明一下这一点,因为我无法理解幕后发生的事情?

PS我知道这个话题在这些工具上,但它没有解决它们操作方式上的具体差异

答案1

FreeBSD 和 OpenBSD 等操作系统上的命令ifconfig已根据操作系统的其余部分进行了更新。如今,它可以在这些操作系统上配置各种网络接口设置,并处理一系列网络协议。 BSDioctl()为这些事情提供支持。

这在 Linux 世界中并没有发生。今天有三个ifconfig命令:

  • ifconfigGNU inetutils
    jdebp % 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%
  • ifconfigNET-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- ifconfig3可以已进行调整以使用这个新的 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 的一体化工具,并且同样可以说它比单独的ifconfigroutearpndp命令“更通用”。

人们还可以为使用 netlink API 的 Linux编写routearp、 和命令。ndp

进一步阅读

答案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、多播和异步通信。

相关内容