This article explains the behavior of IPv6 NDP neighbor resolution process when firewall filter is configured on the interface. A firewall filter term matching IPv6 solicited-node multicast address for IPV6 NDP resolution is needed over that interface.
2a00:79e0:1c:978::0/64 R1---------------------------------------------------------------------------R2 2a00:79e0:1c:978::3/64 2a00:79e0:1c:978::2/64
IPv6 Neighborship will be stuck in incomplete/unreachable state in the absence of ‘all-nodes multicast address’ or ‘all-routers multicast address’ or super-net covering these multicast address range in the matching criteria in the filter.
‘all-nodes multicast address’
‘all-routers multicast address’
As documented in RFC2461 Section 4.3 , in case of resolving the IPv6 neighbors for the 1st time, the NS packets are always destined to an ‘ all-nodes multicast address - FF02::1 ’ or ‘ all-routers multicast address - FF02::2 ’. This scenario would appear in case of a router reboot, interface flap, new interface creation along with the filter configuration in same commit – or for that matter any other event which would make the IPv6 neighbor unreachable. The Neighbor advertisement and subsequent reachability verification between IPv6 neighbors would be a unicast communication over the link local/Global IPv6 address.
Packet capture taken on R1:
No. Time Source Destination Protocol Length Info 15 25.584667 2a00:79e0:1c:978::3 ff02::1:ff00:2 ICMPv6 118 Neighbor Solicitation for 2a00:79e0:1c:978::2 from a8:d0:e5:5b:39:d9 . . . Ethernet II, Src: JuniperN_5b:39:d9 (a8:d0:e5:5b:39:d9), Dst: IPv6mcast_ff:00:00:02 (33:33:ff:00:00:02) Destination: IPv6mcast_ff:00:00:02 (33:33:ff:00:00:02) Address: IPv6mcast_ff:00:00:02 (33:33:ff:00:00:02) .... ..1. .... .... .... .... = LG bit: Locally administered address (this is NOT the factory default) .... ...1 .... .... .... .... = IG bit: Group address (multicast/broadcast) Source: JuniperN_5b:39:d9 (a8:d0:e5:5b:39:d9) Address: JuniperN_5b:39:d9 (a8:d0:e5:5b:39:d9) .... ..0. .... .... .... .... = LG bit: Globally unique address (factory default) .... ...0 .... .... .... .... = IG bit: Individual address (unicast) Type: 802.1Q Virtual LAN (0x8100) 802.1Q Virtual LAN, PRI: 6, DEI: 0, ID: 708 110. .... .... .... = Priority: Internetwork Control (6) ...0 .... .... .... = DEI: Ineligible .... 0010 1100 0100 = ID: 708 Type: IPv6 (0x86dd) Internet Protocol Version 6, Src: 2a00:79e0:1c:978::3, Dst: ff02::1:ff00:2 0110 .... = Version: 6 .... 1000 0000 .... .... .... .... .... = Traffic Class: 0x80 (DSCP: CS4, ECN: Not-ECT) .... 1000 00.. .... .... .... .... .... = Differentiated Services Codepoint: Class Selector 4 (32) .... .... ..00 .... .... .... .... .... = Explicit Congestion Notification: Not ECN-Capable Transport (0) .... .... .... 0000 0000 0000 0000 0000 = Flow Label: 0x00000 Payload Length: 32 Next Header: ICMPv6 (58) Hop Limit: 255 Source Address: 2a00:79e0:1c:978::3 Destination Address: ff02::1:ff00:2 Internet Control Message Protocol v6 Type: Neighbor Solicitation (135) Code: 0 Checksum: 0x56a9 [correct] [Checksum Status: Good] Reserved: 00000000 Target Address: 2a00:79e0:1c:978::2 ICMPv6 Option (Source link-layer address : a8:d0:e5:5b:39:d9) Type: Source link-layer address (1) Length: 1 (8 bytes) Link-layer address: JuniperN_5b:39:d9 (a8:d0:e5:5b:39:d9)
Once the neighbors are seen, any subsequent keepalives are sent as unicast:
No. Time Source Destination Protocol Length Info 1 0.000000 2a00:79e0:1c:978::3 2a00:79e0:1c:978::2 ICMPv6 118 Neighbor Solicitation for 2a00:79e0:1c:978::2 from a8:d0:e5:5b:39:d9
With the firewall filter configuration missing match statements for all-nodes multicast address, below is the output for how NDP neighbor would appear if the IPv6 neighbors cannot see each other. Below is the firewall filter configuration during a problem state where it only has match conditions for the unicast IPv6 address. Since the IPv6 neighbors cannot see each other, the neighbor state would be shown as incomplete for such a peer.
firewall { family inet6 { filter IPv6_filter { term ICMPv6 { from { source-address { 2a00:79e0:1c:978::/64; } destination-address { 2a00:79e0:1c:978::/64 } next-header icmpv6; <--- If you are looking for more specific match icmp-type [ 1 2 3 4 128 129 130 131 132 133 134 135 136 141 142 143 148 149 151 152 153 ]; } then accept; } } } }
router-R1> show ipv6 neighbors IPv6 Address Linklayer Address State Exp Rtr Secure Interface 2a00:79e0:1c:978::1 none incomplete 0 no no ae3.708
If you are using IPv6 firewall filters on the interface (on both input and output direction) and matching the ‘destination address’, then this term should contain a match for the IPV6 solicited-node multicast address (ff02::1/104 and ff02::2/104) as well, which is needed for seeing through NDP neighbors.
Example of filter term:
firewall { family inet6 { filter IPv6_filter { term ICMPv6 { from { source-address { 2a00:79e0:1c:978::/64; } destination-address { 2a00:79e0:1c:978::/64; ff02::1:ff00:0/104; <-- This is the solicited-node multicast address prefix for this link } next-header icmpv6; <-- If you are looking for more specific match icmp-type [ 1 2 3 4 128 129 130 131 132 133 134 135 136 141 142 143 148 149 151 152 153 ]; } then accept; } } } }
The match condition for destination address can also match a generic super net covering the solicitated-node multicast address:
firewall { family inet6 { filter IPv6_filter { term ICMPv6 { from { destination-address { 2a00:79e0:1c:978::/64; 0::0/128; } } } } } }
firewall { family inet6 { filter IPv6_filter { term ICMPv6 { from { destination-address { 2a00:79e0:1c:978::/64; ff02::/12; } } } } } }
In case if a filter blocking IPv6 Multicast address is not applied before the IPv6 neighbors are seen and is added later to the interface, the IPv6 NDP neighbors will still see each other because once the NDP neighbors are formed, the reachability check is unicast. However, if the NDP neighbor goes down because of some reason (say interface flap), the NDP neighbors will not be formed because of incorrect firewall filter
Note: As per RFC4291 , solicited-node multicast address is formed by taking the low-order 24 bits of the address (unicast or anycast) and appending those bits to the prefix FF02:0:0:0:0:1:FF00::/104.