ipv6 socket bind 失败 - accept_dad

本文介绍了IPv6的Duplicate Address Detection(DAD)机制,用于检测接口上的地址是否唯一。当DAD未完成或失败时,socket绑定该地址会失败。详细解析了ipv6_chk_addr函数,并描述了DAD的步骤,包括发送邻居请求、等待响应等。若要禁用DAD,可在INTERFACE语句上指定DUPADDRDET 0。
部署运行你感兴趣的模型镜像

file: /proc/sys/net/ipv6/conf/interface/accept_dad
variable: net.ipv6.conf.interface.accept_dad

Official reference

Whether to accept DAD (Duplicate Address Detection). 0: Disable DAD 1: Enable DAD (default) 2: Enable DAD, and disable IPv6 operation if MAC-based duplicate link-local address has been found.

DAD operation and mode on a given interface will be selected according to the maximum value of conf/{all,interface}/accept_dad.

Nb: per interface setting (where “interface” is the name of your network interface); “all” is a special interface: changes the settings for all interfaces.

 

file: /proc/sys/net/ipv6/conf/interface/dad_transmits
variable: net.ipv6.conf.interface.dad_transmits

Official reference

The amount of Duplicate Address Detection probes to send. Default: 1

Nb: per interface setting (where “interface” is the name of your network interface); “all” is a special interface: changes the settings for all interfaces.

也就是说默认是要发送发送一次NS来检查是否有地址冲突。等待retrans_time后,如果没有收到NS或者NA,就认为地址可用。

在DAD没有完成前或者DAD失败后,socket绑定这个地址是会失败的。参考内核代码inet6_bind中的ipv6_chk_addr函数

int ipv6_chk_addr(struct net *net, const struct in6_addr *addr,
          struct net_device *dev, int strict)
{
    struct inet6_ifaddr *ifp;
    struct hlist_node *node;
    unsigned int hash = ipv6_addr_hash(addr);

    rcu_read_lock_bh();
    hlist_for_each_entry_rcu(ifp, node, &inet6_addr_lst[hash], addr_lst) {
        if (!net_eq(dev_net(ifp->idev->dev), net))
            continue;
        if (ipv6_addr_equal(&ifp->addr, addr) &&
            !(ifp->flags&IFA_F_TENTATIVE) &&
            (dev == NULL || ifp->idev->dev == dev ||
             !(ifp->scope&(IFA_LINK|IFA_HOST) || strict))) {
            rcu_read_unlock_bh();
            return 1;
        }
    }

    rcu_read_unlock_bh();
    return 0;
}
如果地址状态时IFA_F_TENTATIVE,则inet6_bind会返回EADDRNOTAVAIL

DAD整个流程如下:

Duplicate address detection (DAD) is used to verify that an IPv6 home address is unique on the LAN before the address is assigned to a physical interface (for example, QDIO). z/OS® Communications Server responds to other nodes that are doing DAD for IP addresses assigned to the interface. DAD is not done for VIPAs or loopback addresses. DAD for local addresses is done for physical interfaces when one of the following situations occur:

  • The interface is started (the autoconfigured link-local address and manually configured addresses and /prefixes are checked).
  • A VARY TCPIP,,OBEYFILE command is issued for a profile data set containing an INTERFACE ADDADDR for an already active interface.
  • A router advertisement containing new prefix information and the autonomous bit set is received on an interface enabled for stateless autoconfiguration.
  • A temporary autoconfigured address is generated.

To disable DAD checking, specify DUPADDRDET 0 on the INTERFACE statement.

DAD processing involves the following steps:

  1. The host joins a link-local all-nodes multicast group at interface start processing.
  2. The host joins a solicited-node group for the local address.
  3. A neighbor solicitation is sent to the solicited-node multicast address with the tentative address for which DAD is being performed.
  4. The host waits for a neighbor response (neighbor advertisement or neighbor solicitation) on the interface.
  5. If no neighbor response is received within the specified retransmit time, the address is considered unique on the LAN.
  6. If a neighbor response is received within the specified time, the address is not unique. The host leaves the solicited-node multicast group, issues a duplicated address detected console message, and marks the address unavailable because of a duplicate address.

Unless DAD is disabled, the address is not considered assigned to an interface until DAD is successfully completed for the local address. Packets can be received for the all-nodes or solicited-node multicast groups, but there is no response because the address is not yet assigned to the interface. If the local address is a manually configured address, the addresses are displayed in a Netstat Home/-h report as Unavailable (if the interface has not been started or if DAD failed).

In situations where DAD is not done for the IPv6 home address (by specifying DUPADDRDET 0 on the INTERFACE statement or if it is a VIPA), the z/OS Communications Server host still responds if another node is doing DAD for an IPv6 address assigned to the interface or for IPv6 VIPAs when the interface is assigned to handle VIPAs; responses are not sent for loopback addresses.

您可能感兴趣的与本文相关的镜像

ACE-Step

ACE-Step

音乐合成
ACE-Step

ACE-Step是由中国团队阶跃星辰(StepFun)与ACE Studio联手打造的开源音乐生成模型。 它拥有3.5B参数量,支持快速高质量生成、强可控性和易于拓展的特点。 最厉害的是,它可以生成多种语言的歌曲,包括但不限于中文、英文、日文等19种语言

<think> 我们正在分析一个Makefile中的COPTS赋值语句: COPTS = -DHAVE_UBUS -DHAVE_POLL_H $(if $(CONFIG_IPV6),,-DNO_IPV6) 这个语句定义了一个变量COPTS,它用于设置编译选项(通常是C/C++编译器的选项)。下面我们逐步分解: 1. **固定选项**: - `-DHAVE_UBUS`:定义一个名为`HAVE_UBUS`的宏,通常表示代码将支持UBus(OpenWrt中的进程间通信机制)。 - `-DHAVE_POLL_H`:定义一个名为`HAVE_POLL_H`的宏,表示系统存在`<poll.h>`头文件,代码可以使用`poll()`系统调用。 2. **条件选项**: - `$(if $(CONFIG_IPV6),,-DNO_IPV6)`:这是一个Make的条件函数。它的语法是`$(if condition, then-part, else-part)`。 - 条件部分:`$(CONFIG_IPV6)`,如果变量`CONFIG_IPV6`被定义且非空,则条件为真,否则为假。 - 当条件为真(即`CONFIG_IPV6`有定义且非空)时,返回`then-part`(这里为空,所以不添加任何选项)。 - 当条件为假(即`CONFIG_IPV6`未定义或为空)时,返回`else-part`(即`-DNO_IPV6`),这样就会添加一个宏定义`NO_IPV6`,表示不支持IPv6。 因此,整个语句的含义是: - 始终定义`HAVE_UBUS`和`HAVE_POLL_H`宏。 - 如果`CONFIG_IPV6`没有被设置(即没有启用IPv6),则额外定义`NO_IPV6`宏。 在代码中,这些宏可能被用于条件编译,例如: ```c #ifdef HAVE_UBUS // 包含UBus相关的代码 #endif #ifdef NO_IPV6 // 在没有IPv6支持的情况下,使用替代代码或禁用某些功能 #else // 支持IPv6的代码 #endif ``` **总结**:该COPTS变量用于根据配置(特别是IPv6的启用状态)来设置预处理器宏,从而控制代码的编译选项。 --- §§相关问题§§ 1. Makefile中的条件函数`$(if ...)`还有哪些常见用法? 2. 在OpenWrt的Makefile中,`CONFIG_IPV6`变量通常是如何设置的? 3. 如何查看编译时实际使用的COPTS值? </think> ### Makefile 语句解析:`COPTS = -DHAVE_UBUS -DHAVE_POLL_H $(if $(CONFIG_IPV6),,-DNO_IPV6)` 此语句定义了编译选项变量 `COPTS`,用于控制 C/C++ 代码的预处理器宏定义。下面逐步分析其含义: #### 1. **基础结构** ```makefile COPTS = [固定选项] [条件选项] ``` - `COPTS`:编译选项变量(Compiler Options),通常传递给 `gcc`/`clang` 的 `CFLAGS` - `-D`:预处理器宏定义标志(类似代码中的 `#define`) --- #### 2. **固定选项分析** ```makefile -DHAVE_UBUS -DHAVE_POLL_H ``` | 宏定义 | 作用 | |---------------------|----------------------------------------------------------------------| | `-DHAVE_UBUS` | 启用 **UBus 支持**(OpenWrt 的进程间通信总线)[^1] | | `-DHAVE_POLL_H` | 声明系统提供 **`<poll.h>` 头文件**,支持 `poll()` 网络事件监听机制 | 代码中可能存在的条件编译: ```c #ifdef HAVE_UBUS ubus_register_service(); // 注册 UBus 服务 #endif #ifdef HAVE_POLL_H #include <poll.h> // 使用 poll() 代替 select() #endif ``` --- #### 3. **条件选项分析** ```makefile $(if $(CONFIG_IPV6), , -DNO_IPV6) ``` - **Makefile 条件函数**:`$(if condition, then-part, else-part)` - **逻辑解析**: ```makefile 如果 $(CONFIG_IPV6) 已定义且非空 → 返回空字符串(不添加选项) 否则 → 返回 -DNO_IPV6 ``` - **实际效果**: - 当 `CONFIG_IPV6=y`(启用 IPv6)时:**不定义 `NO_IPV6`**,代码保留 IPv6 功能 - 当 `CONFIG_IPV6` 未设置时:**定义 `NO_IPV6`**,禁用 IPv6 相关代码 代码中的典型应用: ```c #ifndef NO_IPV6 bind_ipv6_socket(); // 启用 IPv6 套接字 #else log("IPv6 support disabled"); #endif ``` --- #### 4. **完整逻辑总结** | 配置状态 | 最终宏定义 | 代码行为 | |-------------------|-------------------------------------|----------------------------| | `CONFIG_IPV6=y` | `-DHAVE_UBUS -DHAVE_POLL_H` | 启用 UBus/poll/IPv6 | | `CONFIG_IPV6`未设置 | `-DHAVE_UBUS -DHAVE_POLL_H -DNO_IPV6` | 启用 UBus/poll,**禁用 IPv6** | --- #### 5. **在 OpenWrt 中的意义** 1. **模块化控制** 通过 `CONFIG_IPV6` 实现 **IPv6 功能的按需编译**,减少固件体积(对资源受限的路由器设备关键) 2. **平台兼容性** `-DHAVE_POLL_H` 确保代码适配不同 libc 实现(如 uClibc/musl) 3. **服务集成** `-DHAVE_UBUS` 支持 OpenWrt 服务管理总线,例如 DHCP 服务通过 UBus 暴露 API: ```bash ubus call dhcp get_leases # 查询 DHCP 租约 ``` ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值