首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >标识适配器的首选IPv6源地址

标识适配器的首选IPv6源地址
EN

Stack Overflow用户
提问于 2011-08-26 16:59:17
回答 1查看 2.8K关注 0票数 17

如果启用了IPv6的主机具有多个全局作用域地址,如何通过编程方式确定bind()的首选地址

示例地址列表:

代码语言:javascript
复制
eth0      Link encap:Ethernet  HWaddr 00:14:5e:bd:6d:da  
          inet addr:10.6.28.31  Bcast:10.6.28.255  Mask:255.255.255.0
          inet6 addr: 2002:dce8:d28e:0:214:5eff:febd:6dda/64 Scope:Global
          inet6 addr: fe80::214:5eff:febd:6dda/64 Scope:Link
          inet6 addr: 2002:dce8:d28e::31/64 Scope:Global
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1

在Solaris上,您可以使用接口标志来指示首选地址,并且可以通过SIOCGLIFCONF以编程方式使用该地址

代码语言:javascript
复制
/usr/include/net/if.h:
#define   IFF_PREFERRED   0x0400000000    /* Prefer as source address */

如接口列表所示:

代码语言:javascript
复制
eri0: flags=2104841<UP,RUNNING,MULTICAST,DHCP,ROUTER,IPv6> mtu 1500 index 2
        inet6 fe80::203:baff:fe4e:6cc8/10 
eri0:1: flags=402100841<UP,RUNNING,MULTICAST,ROUTER,IPv6,PREFERRED> mtu 1500 index 2
        inet6 2002:dce8:d28e::36/64 

不过,这不能移植到OSX、Linux、FreeBSD或Windows上。不过,从管理员的角度来看,基于UUID的适配器名称(取决于Windows版本)完全没有用,因此Windows很容易被释放。

For Linux this article详细介绍了如何通过修改参数preferred_lft (其中lft是“生命周期”的缩写)来加权内核的选择过程。但是,在SIOCGIFCONFgetifaddrs()的结果中,这个设置看起来并不方便。

因此,我希望绑定到eth0eri0或任何可用的接口名称。选择有点严酷:

  1. 无法将适配器名称解析到多个接口。我采用这种方法来处理多播传输(OpenPGM),因为该协议必须只有一个-只向所有内容发送address.
  2. Bind。这是一种回避,对用户来说是意外的。
  3. 使用SO_BINDTODEVICE绑定到适配器。这需要Linux上的CAP_NET_RAW系统功能,对于适配器上的第一个IPv6接口的administrators.
  4. Bind来说,这可能是一个相当麻烦的开销。排序往往完全是假的。
  5. 绑定到最后一个接口。David Croft的文章暗示Linux做到了这一点,但在每个接口上也有一点bogus.
  6. Enumerate,并显式地为每个接口创建一个新的套接字。

对于选项#6,我希望您通常更聪明,并采取这样的方法:如果只有链路本地作用域地址可用,则绑定到该地址,否则只绑定到可用的全局链接作用域地址。

当连接到另一台主机时,可以使用RFC 3484,但如您所见,所有选择都取决于与目的地址的匹配:

  1. 首选相同的地址。(例如,目标是本地machine)
  2. Prefer适当的作用域。(即与destination)
  3. Avoid不推荐使用的addresses.
  4. Prefer主地址共享的最小范围。首选传出接口。(例如,优先使用我们发送出去的接口上的地址)公共前缀首选匹配label.
  5. Prefer addresses.
  6. Use
  7. 最长匹配前缀。

在某些情况下,我们可以在这里使用#7,但在上面的接口示例中,两个全局范围的接口都有64位前缀长度。

RFC 3484有以下相关行:

IPv6寻址体系结构5允许多个单播

要分配给接口的地址。这些地址可能具有

不同的可达性范围(本地链路、本地站点或全局)。

这些地址也可能是“首选”或“不推荐”的6

链接是到RFC 2462的,类似地展开:

首选地址-分配给接口的地址,其使用不受上层协议的限制。优选地址可以用作从接口发送(或发往)的分组的源(或目的)地址。

但是没有以编程方式获取此详细信息的方法。

Props to RFC,它公开了一个Win32 SIO_ADDRESS_LIST_SORT,允许开发人员不仅使用RFC3484排序,而且考虑到任何系统管理员覆盖。Linux在getaddrinfo()中有用于RFC3484排序的/etc/gai.conf,但没有用于直接访问排序的API。Solaris有ipaddrsel命令。OSX在10.7版本中加入了ip6addrctl来效仿FreeBSD。

edit:在这个附加的IETF草案文档中列出并引用了与RFC3484排序有关的一些问题:

https://datatracker.ietf.org/doc/html/draft-axu-addr-sel-01

例如,

Solaris会为每个新的

分配给物理接口的地址。所以if_index也可以是

用于唯一标识特定于源地址的路由表

那个平台。其他操作系统的工作方式并不相同。

作者喜欢Solaris的方法,即为每个额外的IPv6接口赋予一个新的别名,这样eri0将成为链路本地作用域地址,并且必须指定eri0:1eri0:2等才能使用全局作用域地址。

显然,虽然这是一个很好的想法,但在相当长的一段时间内,人们不能指望看到其他操作系统发生变化。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2013-08-04 15:22:02

我不确定这是不是你要找的方向,但是...

仔细查看linux下的iproute包的ip代码(ip/ipaddress.c),可以发现ip命令从struct ifaddrmsg、成员ifa_flags中挖掘出诸如primarysecondary之类的接口标志。ifaddmsg似乎是通过man 7 netlink中记录的struct nlmsghdr获得的,并通过sendmsgrecvmsg与内核的交互使用,总体上听起来像是王室的痛苦,但至少是编程上的。主要的和次要的是否足够有用是另一个问题。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/7202316

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档