如何实现本地ICMPv6邻居发现?自研IPv6栈该功能故障求助
Hey there, let's break down why your ICMPv6 Neighbor Discovery (ND) isn't playing nice with your custom IPv6 stack. Given your setup—capturing packets on an existing Ubuntu interface, using lxcbr0 for LXC containers—I’ve got targeted steps to diagnose and fix this:
1. Verify lxcbr0’s IPv6 Configuration
First, make sure your host’s bridge has proper IPv6 setup, since this is the backbone for LXC container communication:
- Run
ip -6 addr show lxcbr0to check if the bridge has a valid link-local or global unicast IPv6 address. Without this, ND packets (like Router Advertisements) won’t flow correctly. - Check if the bridge is configured to send Router Advertisements (RAs) (required for SLAAC address assignment in containers). You can verify this with
sysctl net.ipv6.conf.lxcbr0.accept_raandsysctl net.ipv6.conf.lxcbr0.autoconf—both should be set to1if using SLAAC.
2. Fix Packet Capture Filtering Logic
This is the most common pitfall with custom stacks: ND relies on multicast addresses, not just unicast. Your current filter only targets packets with your stack’s virtual unicast address, but:
- Neighbor Solicitation (NS) packets sent to your stack will target the Solicited-Node Multicast Address (format:
ff02::1:ffXX:XXXX, whereXX:XXXXis the last 24 bits of your virtual IPv6 address). For example, if your virtual address is2001:db8::abcd, the Solicited-Node address isff02::1:ffcd:abcd. - Update your capture logic to include these multicast addresses, otherwise NS packets will be completely missed, and your stack can’t respond with Neighbor Advertisements (NA).
3. Validate ND Response Packet Details
When your stack sends NA packets, double-check these critical fields:
- Source Address: Must be your stack’s virtual IPv6 address (not the host interface’s address).
- Target Address: Must match the source address of the incoming NS packet (the LXC container’s IPv6 address).
- Flags: Set the
S(Solicited) flag to1when responding to an NS packet—this tells the container the NA is a direct response to its request. - Link-Layer Address Option: If your stack uses a virtual MAC, include it here; if it reuses the host’s MAC, ensure the container accepts this (most do, but it’s worth verifying).
4. Check for Host-Side Interference
Ubuntu’s default network settings might be conflicting with your stack:
- ND Proxy: If the host is running ND proxy (via
sysctl net.ipv6.conf.lxcbr0.proxy_ndpset to1), it might be responding to NS packets on your stack’s behalf. Disable this temporarily to test:sudo sysctl -w net.ipv6.conf.lxcbr0.proxy_ndp=0. - Firewall Rules: UFW or nftables might be blocking ICMPv6 ND packets. Temporarily disable the firewall with
sudo ufw disableand retest, or add explicit allow rules for ICMPv6 types 135 (NS) and 136 (NA). - Packet Capture Validation: Use tcpdump to confirm packets are flowing:
- Capture NS packets:
tcpdump -i lxcbr0 icmp6 and ip6[40] = 135 - Capture NA packets:
tcpdump -i lxcbr0 icmp6 and ip6[40] = 136
This will show if NS packets reach the host, and if your stack is sending NA packets.
- Capture NS packets:
5. Inspect LXC Container’s ND State
On the LXC container, check if it’s receiving and processing your stack’s NA:
- Run
ip -6 neigh showto see if your stack’s virtual address has a corresponding neighbor entry (marked asREACHABLEorSTALE). - Verify container IPv6 settings with
sysctl net.ipv6.conf.eth0.accept_ra—if set to0, the container won’t accept RAs or process ND packets properly.
6. Validate ICMPv6 Checksum Calculation
ICMPv6 requires a checksum that includes the IPv6 pseudo-header (source address, destination address, payload length, next header). A miscalculated checksum will cause the container or host to drop your NA packets silently. Compare the checksum of your stack’s NA packet (via tcpdump) to a valid NA packet from the host to confirm it’s correct.
Start with the multicast filtering check—it’s the easiest fix and the most likely culprit. Let me know what you find from these tests!
内容的提问来源于stack exchange,提问作者Adam Lindberg

