Same happens in Ubuntu 14.04 with kernel 4.4.0-36-generic. Also
reproduced on the above 16.04 distribution.

DHCPv6 server: isc-dhcp-server in IPv6 mode (isc-dhcp-server6)

Wireshark captures indicate that the solicit is sent from the client,
arrives to the server's network interface, then lost in the kernel
before arriving to dhcpd.

Cleared ip6tables and tc completely, so no firewall nor QoS could
block/redirect the packet.

Running dhcpd under strace in the foreground confirms that no broadcast
packet is received in user space.

Traced kernel function calls:

#!/bin/bash
mkdir -p /debug
mount -t debugfs nodev /debug
mount -t debugfs nodev /sys/kernel/debug
echo '*' >/debug/tracing/set_ftrace_filter
echo function_graph >/debug/tracing/current_tracer
echo 1 >/debug/tracing/tracing_on
sleep 10
echo 0 >/debug/tracing/tracing_on
cat /debug/tracing/trace > tracing.$$.out

Found the following fragment, where the packet is dropped:

ipv6_rcv() {
  ...
  ip6_rcv_finish() {
    ...
    ip6_mc_input() {
      ipv6_chk_mcast_addr() {
        _raw_read_lock_bh();
        _raw_read_unlock_bh() {
          __local_bh_enable_ip();
        }
      }
      kfree_skb() {
        ...
      }
    }
  }
}

(Timing information removed and irrelevant fragments replaced by
ellipsis.)

Relevant kernel source code:

Function discards the packet: ip6_mc_input
http://lxr.free-electrons.com/source/net/ipv6/ip6_input.c?v=4.4#L285

Decision is based on false value returned here:
deliver = ipv6_chk_mcast_addr(skb->dev, &hdr->daddr, NULL);

I verified that deliver is false by instrumenting the kernel with printk
here.

(The long conditional block after the above code line does nothing,
since it is not an MLD packet.)

Packet is discarded at the end of function by calling the kfree_skb
function.

So the ultimate decision is made by this function: ipv6_chk_mcast_addr
http://lxr.free-electrons.com/source/net/ipv6/mcast.c?v=4.4#L955

Please note that src_addr = NULL. (See the function call above.)

I verified by kernel logging that idev is not NULL, so the device is
found here.

Since src_addr is NULL rv can only be true if the for loop finds the
destination address of the packet (variable: group) in the list of
registered broadcast addresses.

Listing registered broadcast groups: netstat -g

I verified that dhcpd is indeed registered to ff02::1:2

Registration is also visible in the strace output.

I can get an address with the server (from itself) by adding a new
virtual network adapter and connecting it to the same network. So it
works if the packet remains inside the VM and does not go through the
virtual switch.

I have spent days on this problem so far. Any ideas?

-- 
You received this bug notification because you are a member of Ubuntu
Bugs, which is subscribed to Ubuntu.
https://bugs.launchpad.net/bugs/1624722

Title:
  DHCPv6 does not work in Hyper-V

To manage notifications about this bug go to:
https://bugs.launchpad.net/ubuntu/+source/linux/+bug/1624722/+subscriptions

-- 
ubuntu-bugs mailing list
ubuntu-bugs@lists.ubuntu.com
https://lists.ubuntu.com/mailman/listinfo/ubuntu-bugs

Reply via email to