Skip to content

IPv6 notes

mdavidsaver edited this page Oct 12, 2021 · 5 revisions

Terminology

rfc7346 talks about "interface-local" scope. In Linux source this is referred to as "node-local". Both refer to scope 1. cf. IPV6_ADDR_SCOPE_NODELOCAL in kernel source.

Gotchas...

IPv4 multicast address can't be mapped to IPv6.

Sending to ::ffff:224.0.1.1 with an IPv6 socket is not equivalent to sending to 224.0.1.1 with an IPv4 socket.

So it isn't possible to use a single socket to send both IPv4 and IPv6 multicasts...

bind() limitations

On Linux it is possible to bind() to a multicast address to create a socket which receives only multicasts. This socket can also be used to sendto() replies.

On OSX, bind() to multicast works, but sendto() does not.

On Windows, bind() to multicast is not supported.

Destination address/interface

So there is no portable way for a socket to receive only multicasts via a specific interface without binding to 0.0.0.0 and/or ::1 and also receiving unicasts and broadcasts via any interface.

These can be distinguish with access to the packet destination address and destination network interface, which is available through recvmsg() from the RFC2292 extended socket API.

Specific control message types are OS specific. However, as of 2021 all major OSs support either IP_PKTINFO or IP_ORIGDSTADDR and IP_RECVIF for IPv4, as well as IPV6_PKTINFO/IPV6_RECVPKTINFO for IPv6.

Magic link-local address

With Linux, the automatic link-local address (fe80::...) doesn't appear until the link becomes RUNNING for the first time. eg. for a TAP interface, after something open()s it.

mcast on loopback

Trying to send to ff01::1:ff00:1 or ff02::1:ff00:1 via the loopback interface. Set interface index 1 via IPV6_MULTICAST_IF and/or sin6_scope_id.

Does not seem to be possible with defaults. Roadblocks...

  • IPV6_ADD_MEMBERSHIP fails unless lo has IFF_MULTICAST. workaround:
# ip link show dev lo
1: lo: <LOOPBACK,MULTICAST,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN mode DEFAULT group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
# ip link set dev lo multicast on
  • sendto() fails with EHOSTUNREACH

There is no default entry for lo in the multicast routing table. workaround?

# ip route show type multicast table all
multicast ff00::/8 dev br0 table local proto kernel metric 256 pref medium
multicast ff00::/8 dev wlan0 table local proto kernel metric 256 pref medium
# ip route add multicast ff00::/8 dev lo table local
  • sendto() succeeds, but no packet is sent. stuck here...

Based on investigation of sendto() call chain with systemtap, looks like a blackhole route is selected? (call to ip6_pkt_discard_out() instead of ip6_output())

Maybe unable to select a source address? Send with IPV6_PKTINFO?