【问题标题】:Ipv6 Source Address selection in linuxlinux中的IPv6源地址选择
【发布时间】:2014-05-07 05:20:52
【问题描述】:

要从主机名获取目标或应用目标地址选择算法(根据 RFC 3484),我们有一个库 api getaddrinfo()。如果您在网上搜索,您会发现相同的 API 可用于源地址选择。但是当我实际测试它时,它并没有发生。

当我对其进行一些功课时发现,在 linux 中,内核本身通过应用这些规则(根据 RFC 3484)根据目标地址决定适当的源地址。这是由内核在fib6_rule_action() 方法中完成的,这是在发送数据时完成的(例如在sendto() 中)。

我的问题是在发送数据之前的早期阶段,是否有任何库 API 或系统调用可以为我执行此操作。

【问题讨论】:

  • 为了确保我明白这一点:你想向某人发送一个 UDP 数据包,并指定源地址?
  • 不清楚你真正想要什么,但如果你 connect() 套接字,你会用getsockname() 得到源地址。 (如果将来内核路由表发生变化,源地址也可能会发生变化——至少对于 UDP)。
  • 是的,这就是我想要的,但由于我有多个 ipv6 地址,我将如何决定应该从哪个源 ip 发送数据。是否有任何库 API 可以根据目标 IP 地址实际给我排序的源 IP 列表。

标签: c linux ipv6


【解决方案1】:

您可以通过linux routing sockets aka rtnetlink 获取该信息。具体来说,就是您要查找的 RTA_SRC。

提醒一句,(rt)netlink 套接字不是最容易使用的协议,除了源代码之外没有太多最新的文档。 netlink 的wikipedia page 可能会帮助您入门。一些外部链接看起来不错,链接的论文包含更多参考。

如果你能找到一个库,并且你的 netlink 相关代码比单一源地址查询长,我建议使用一个库。 Libnllibmnl 可能很好。前者还有一个关于routing sockets的不错的页面。

作为测试,您可以使用用户空间命令ip -6 route get <dst_addr> 例如ip -6 route get 2a00:1450:4010:c04::63 获得相同的功能。

【讨论】:

  • 我在提到我猜的问题时并不太清楚。如果您看到我对 jonathon-reinhart 回复的评论,那么您将得到我想要的。为了澄清一点,我希望从多个 IPv6 地址 IP(我有)系统中应该给我最喜欢的地址,具体取决于我想要发送数据的目标地址。有什么机制可以解决这个问题。我最喜欢的地址是指应用 RFC3484 中定义的那些规则。 (同样我想要的是源地址而不是目标地址,因为对于目标我们有 getaddrinfo)
  • 我的回答指出了一种完全按照您的要求进行操作的方法。虽然它本身不是一个 API,而是一个协议。
  • @thouvila ip 是一个实用程序,但我认为它可以达到路由级别。我从这个链接 (linux-hacks.blogspot.in/2008/07/…) 了解到,源地址选择是在路由算法之后出现的。这是真的还是我走错了方向???
  • ip 只是一个实用程序,是的。我将命令放在答案中,以帮助您了解 rtnetlink 套接字返回的信息类型。我不建议直接从您的程序中调用 ip。使用 netlink 套接字获取相同的信息。给 rtnetlink 的消息将返回将在 linux FIB 中选择的源地址,即与您的链接描述的逻辑相同。
  • 我用 rtnetlink 试过了。现在我已经到了可以看到整个路由表的阶段。但是,当我将目标地址作为 netlink 消息的属性时,我仍然卡住了。你能帮我解决这个问题吗?如果我们能在内部了解 ip route get 的工作原理,那也可以解决。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-06-21
  • 2012-08-26
  • 1970-01-01
  • 2014-01-11
相关资源
最近更新 更多