Project

General

Profile

IPv6 and the Neighbor Discovery Protocol (NDP)

When using IPv6 a potential pitfall is that traffic selectors of established tunnels might also cover packets used by the Neighbor Discovery Protocol (NDP), in particular, if all traffic is tunneled (traffic selector is ::/0). So looking up link layer addresses of peers and routers might fail, or locally assigned IP addresses might disappear.

To allow NDP traffic when tunnels are established bypass policies have to be installed.

Either for all ICMPv6 traffic or only for certain types (depending on the setup and traffic selectors not all will have to be bypassed, refer to RFC 4861 for details on the message types):

  • Router Solicitation (RS): 133
    Used to locate routers. Source address is a local address or :: (if none is known yet), the destination address is typically the all-routers multicast address.
  • Router Advertisement (RA): 134
    Sent by routers periodically or in response to RS messages (from a link-local address to either the address from which RS messages were received or the all-nodes multicast address). If these (or RS messages, if used) are blocked, locally assigned addresses might disappear after establishing the tunnel.
  • Neighbor Solicitation (NS): 135
    Similar to ARP for IPv4 these are used to determine the link layer address of a host. Typically sent from a locally assigned address to the solicited-node multicast address corresponding to the target address.
  • Neighbor Advertisement (NA): 136
    Sent as response to NS messages (from a local address to the address from which the NS messages were received). If these or NS messages are blocked, peers might not be able to reach each other or a router after establishing the tunnel (could take a while if link local addresses are cached).
  • Redirect (R): 137
    Could be used by routers to send hosts a better first hop router for a destination (from a link-local address to the source address of the packet that triggered the redirect).

Examples

swanctl.conf ipsec.conf
To bypass all ICMPv6 messages
connections {
  ...
  ndp {
    children {
      icmpv6 {
        local_ts = ::/0[ipv6-icmp/%any]
        remote_ts = ::/0[ipv6-icmp/%any]
        mode = pass
        start_action = trap
      }
    }
  }
}
conn icmpv6
    right=::1 # so this connection does not get used for other purposes
    leftsubnet=::/0[ipv6-icmp/%any]
    rightsubnet=::/0[ipv6-icmp/%any]
    type=passthrough
    auto=route
To bypass only NS and NA messages
connections {
  ...
  ndp {
    children {
      ns {
        local_ts = ::/0[ipv6-icmp/135]
        remote_ts = ::/0[ipv6-icmp/135]
        mode = pass
        start_action = trap
      }
      na {
        local_ts = ::/0[ipv6-icmp/136]
        remote_ts = ::/0[ipv6-icmp/136]
        mode = pass
        start_action = trap
      }
    }
  }
}
conn ndp-ns
    right=::1 # so this connection does not get used for other purposes
    leftsubnet=::/0[ipv6-icmp/135]
    rightsubnet=::/0[ipv6-icmp/135]
    type=passthrough
    auto=route

conn ndp-na
    right=::1 # so this connection does not get used for other purposes
    leftsubnet=::/0[ipv6-icmp/136]
    rightsubnet=::/0[ipv6-icmp/136]
    type=passthrough
    auto=route
Note: Instead of ipv6-icmp the numeric protocol identifier 58 might have to be used if it can't be resolved.