ip 与 ifconfig 命令的优缺点

pka*_*mol 36 linux networking ip ifconfig

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

ipcommand 比ifconfig因为它使用netlink套接字而不是ioctl系统调用更通用和更有效。

任何人都可以详细说明这一点,因为我无法理解引擎盖下发生了什么?

PS 我知道关于这些工具的这个主题,但它没有解决它们如何操作的具体差异

Jde*_*eBP 53

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

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

  • ifconfig来自GNU inetutils
    jdebp % inetutils-ifconfig -l
    enp14s0 enp15s0 lo
    jdebp % inetutils-ifconfig lo
    lo 链路封装:本地环回
          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
    jdebp %
  • 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 128 scopeid 0x10<host>
        inet6 ::2 prefixlen 128 scopeid 0x80<compat,global>
        inet6 fe80::prefixlen 10 scopeid 0x20<link>
        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
    jdebp %
  • ifconfig来自(版本 1.40)nosh 工具集
    jdebp % ifconfig -l
    enp14s0 enp15s0 lo
    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:: scope 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:: scope 1 prefixlen 10 
        inet6 地址 ::1 范围 0 prefixlen 128 
    jdebp % 

如您所见,GNU inetutils 和 NET-3 net-toolsifconfig在 IPv6、具有多个地址的接口以及诸如-l.

IPv6 问题的部分原因是工具本身缺少一些代码。但主要是因为 Linux 没有(像其他操作系统那样)通过ioctl()接口提供 IPv6 功能。它只允许程序通过网络查看和操作 IPv4 地址ioctl()

相反,Linux 通过不同的接口send()recv()特殊的、有点奇怪的套接字地址系列提供此功能,AF_NETLINK.

在GNU和NET-3ifconfig小号可能已经调整到使用这个新的API。反对这样做的论点是它不能移植到其他操作系统,但这些程序在实践中无论如何已经不可移植了,所以这没什么大不了的。

但它们并没有被调整,直到今天仍然如此。(多年来,有些人在不同的时间点对它们进行了研究,但遗憾的是,这些改进从未融入到程序中。例如: Bernd Eckenfels 从未接受向 NET-3 net-tools 添加一些 netlink API 功能的补丁ifconfig, 补丁编写 4 年后。)

取而代之的是,一些人将工具集彻底改造为一个ip命令,它使用了新的 Linux API,具有不同的语法,并在时尚风格的界面背后结合了其他几个功能。command subcommand

我需要一个ifconfig具有 FreeBSD 命令行语法和输出风格的文件ifconfig(GNU 和 NET-3ifconfig都没有,ip当然也没有)。所以我写了一篇。作为可以ifconfig在 Linux 上编写使用 netlink API 的证明,它确实如此。

因此ifconfig,诸如您引用的内容之类的已收到的智慧不再是真实的。现在说“ifconfig不使用netlink”是不真实的。盖二人的毯子不能盖三人。

一直是不真实的说法是“网络链路更有效。” 对于使用 完成的任务,ifconfig当涉及到 netlink API 和ioctl()API之间的效率时,实际上并没有太多内容。对于任何给定的任务,几乎相同数量的 API 调用。

实际上,在 netlink 情况下,每个 API 调用是两个系统调用,而不是ioctl()系统中的一个。可以说,netlink API 有一个缺点,即在一个频繁使用的系统上,它明确地包含了该工具永远不会收到通知它 API 调用结果的确认消息的可能性。

据,此外,不真实地说,ip是“更灵活”比GNU和NET-3ifconfig小号,因为它使用网络链路。它更通用,因为它可以完成更多的任务,在一个大程序中做一些事情,而除了 ifconfig. 仅仅依靠它在内部用于执行这些额外任务的 API,它并不是更通用。API 没有与此相关的任何内容。人们可以写的所有功能于一身的工具,它使用的FreeBSD的ioctl()API,例如,和同样出色的状态,这是“更灵活”不是个别ifconfigroutearp,和ndp命令。

也可以为使用 netlink API 的 Linux编写routearpndp命令。

进一步阅读

  • “netlink 使 ip 更通用”与“ip 更通用,因为它使用 netlink”相同,这在问题中_就在那里_。 (2认同)

Rui*_*iro 13

由于ifconfig多种原因,我们在许多发行版中使用的标准已被弃用。以一种过时且有限的方式与内核交谈,实际上,不再了解所有网络配置。您将无法操作某些网络配置,例如 ifconfig您可以使用ip. 此外,ifconfig对网络命名空间的支持是有限的。

作为一个轶事,我发现接口 IP 别名仅ip在 SuSE 中可见,而在 SuSE中不可见ifconfig

至于引擎盖下的差异:来自ifconfig vs ip: What's Difference and Comparing Network Configuration

虽然ip在第一个站点看起来有点复杂,但它的功能比 ifconfig 广泛得多。它在功能上组织在两层网络堆栈上,即第 2 层(链路层)、第 3 层(IP 层),并执行来自 net-tools 包的所有上述命令的工作。

虽然ifconfig主要显示或修改系统的接口,但此命令能够执行以下任务:

  • 显示或修改接口属性。

  • 添加、删除 ARP 缓存条目以及为主机创建新的静态 ARP 条目。

  • 显示与所有接口关联的 MAC 地址。

  • 显示和修改内核路由表。

将它与古老的 ifconfig 分开的主要亮点之一是后者使用 ioctl 进行网络配置,这是一种不太受欢迎的与内核交互的方式,而前者利用了 netlink 套接字机制,这是一个更灵活的继承者ioctl 使用 rtnetlink(它增加了网络环境操作能力)用于内核和用户空间之间的相互通信。

关于netlink的使用/优点:来自LJ - Kernel Korner - Why and How to Use Netlink Socket

Netlink 套接字是一种特殊的 IPC,用于在内核和用户空间进程之间传输信息。它通过用于用户空间进程的标准套接字 API 和用于内核模块的特殊内核 API 在两者之间提供全双工通信链接。Netlink 套接字使用地址族 AF_NETLINK。

.....

为什么上述功能使用 netlink 而不是系统调用、ioctls 或 proc 文件系统来进行用户和内核世界之间的通信?为新功能添加系统调用、ioctls 或 proc 文件是一项重要的任务;我们冒着污染内核和破坏系统稳定性的风险。不过,Netlink 套接字很简单:只需要​​向 netlink.h 添加一个常量,即协议类型。然后,内核模块和应用程序可以立即使用套接字样式的 API 进行对话。

....

Netlink 套接字是用于用户空间应用程序和内核模块之间通信的灵活接口。它为应用程序和内核提供了一个易于使用的套接字 API。它提供了其他内核/用户空间 IPC 所不具备的高级通信功能,例如全双工、缓冲 I/O、多播和异步通信。