I just stumbled upon bind() returning -1 with errno set to ENODEV and noticed that this value for errno is not documented in bind.2. I was trying to bind to an IPv6 address. I just checked the kernel code we are using, and then the one in 2.6.23 and noticed this in inet6_bind(): # # if (addr_type & IPV6_ADDR_LINKLOCAL) { # if (addr_len >= sizeof(struct sockaddr_in6) && # addr->sin6_scope_id) { # /* Override any existing binding, if another one # * is supplied by user. # */ # sk->sk_bound_dev_if = addr->sin6_scope_id; # } # # /* Binding to link-local address requires an interface */ # if (!sk->sk_bound_dev_if) { # err = -EINVAL; # goto out; # } # dev = dev_get_by_index(sk->sk_bound_dev_if); # if (!dev) { # err = -ENODEV; # goto out; # } # } Notice the err = -ENODEV because the value set in sin6_scope_id isn't something we expect. We are indeed setting that in our code, and using a link-local address. Now, 'man ipv6' says: sin6_scope_id is an ID of depending of on the scope of the address. It is new in Linux 2.4. Linux only supports it for link scope addresses, in that case sin6_scope_id contains the interface index (see netdevice(7)) So ENODEV is returned for IPv6 when using a link-local address and a sin6_scope_id that doesn't include a valid interface index. Not sure if this needs to go in bind.2 or in ipv6.7 - I guess you would know better. I've attached a suggested patch.
Attachment:
bind.2.patch
Description: Binary data