DHCPv6 Prefix Delegation bug allows routing loop



  • When getting DHCPv6 leases with both IA_ADDR and IA_PD-prefix a rule is added to pf to prevent a routing loop in filter.inc. The rule looks like:

    pass out route-to (igb5 fe80::xxxx:xxxx:xxxx:xxxx) inet6 from 2600:8802:7f20:500:yyyy:yyyy:yyyy:yyyy to ! 2600:8802:7f20:500::/56 flags S/SA keep state allow-opts label "let out anything from firewall host itself"

    The prefix in the "!" part should be from the IA_PD-prefix, but is actually from the IA_ADDR. At least it gets the prefix length right (in my case /56). So, it's blocking the wrong packets. This allows a routing loop if some of the prefixes that have been allocated are not being used.



  • That's correct if your interface IP's a /56 mask. That's not for preventing routing loops, it's so traffic initiated from the host's IP on that interface is routed out via that WAN in multi-WAN environments, only where the traffic isn't destined to the local subnet directly connected to that interface.



  • Then why is the PDlen being used? The WAN interface is on a /128 "network". Nowhere in the WAN config, other than the PD used BEHIND it, is on a /56 network - if anything, it should just be a /64, but that will still block access to important services line (potentially) DNS at the ISP which could be on the same network as a WAN interface.

    And, then a followup, how can I prevent the routing loops? There doesn't appear to be any way to create a firewall rule that included the PD-prefix.



  • It won't block anything either. Looks like that is using the wrong mask there, but that doesn't actually hurt anything in most circumstances (if you have multiple dynamic IPv6 WANs, it might).

    What routing loop are you trying to prevent?

    The interface aliases, like "LAN net", include your PD-assigned subnet on that interface.



  • I'm trying to avoid the loops discussed in RFC 7084:

    WPD-5:  Any packet received by the CE router with a destination
              address in the prefix(es) delegated to the CE router but not
              in the set of prefixes assigned by the CE router to the LAN
              must be dropped.  In other words, the next hop for the
              prefix(es) delegated to the CE router should be the null
              destination.  This is necessary to prevent forwarding loops
              when some addresses covered by the aggregate are not
              reachable [RFC4632].

    I have a /56 allocated by my ISP, but I'm only currently using a few of the /64 networks out of it. So, there are a lot of unused ones that will cause loops between my pfSense gateway and the ISP's router. These packets loop because the outbound packet setups the state in the firewall and then the inbound is allowed and loops. From my perspective, it would be better to add an outbound anti-spoofing rule that blocks anything in the PD that isn't being used.

    For example:

    Ping command on internal host:

    $ ping6 -c 1  2600:8802:1500:a01::1
    PING6(56=40+8+8 bytes) 2600:8802:1500:a00:571:870b:ca12:2b3b –> 2600:8802:1500:a01::1

    --- 2600:8802:1500:a01::1 ping6 statistics ---
    1 packets transmitted, 0 packets received, 100.0% packet loss

    Results in the one packet looping between by pfSense gateway and the ISP's router:

    : tcpdump -i igb5 -s 0 -n -l -vvv host 2600:8802:1500:a01::1
    tcpdump: listening on igb5, link-type EN10MB (Ethernet), capture size 65535 bytes
    18:06:40.836650 IP6 (flowlabel 0x03823, hlim 63, next-header ICMPv6 (58) payload length: 16) 2600:8802:1500:a00:571:870b:ca12:2b3b > 2600:8802:1500:a01::1: [icmp6 sum ok] ICMP6, echo request, seq 0
    18:06:40.843484 IP6 (flowlabel 0x03823, hlim 62, next-header ICMPv6 (58) payload length: 16) 2600:8802:1500:a00:571:870b:ca12:2b3b > 2600:8802:1500:a01::1: [icmp6 sum ok] ICMP6, echo request, seq 0
    18:06:40.843500 IP6 (flowlabel 0x03823, hlim 61, next-header ICMPv6 (58) payload length: 16) 2600:8802:1500:a00:571:870b:ca12:2b3b > 2600:8802:1500:a01::1: [icmp6 sum ok] ICMP6, echo request, seq 0
    18:06:40.852037 IP6 (flowlabel 0x03823, hlim 60, next-header ICMPv6 (58) payload length: 16) 2600:8802:1500:a00:571:870b:ca12:2b3b > 2600:8802:1500:a01::1: [icmp6 sum ok] ICMP6, echo request, seq 0
    18:06:40.852053 IP6 (flowlabel 0x03823, hlim 59, next-header ICMPv6 (58) payload length: 16) 2600:8802:1500:a00:571:870b:ca12:2b3b > 2600:8802:1500:a01::1: [icmp6 sum ok] ICMP6, echo request, seq 0
    18:06:40.859665 IP6 (flowlabel 0x03823, hlim 58, next-header ICMPv6 (58) payload length: 16) 2600:8802:1500:a00:571:870b:ca12:2b3b > 2600:8802:1500:a01::1: [icmp6 sum ok] ICMP6, echo request, seq 0
    18:06:40.859681 IP6 (flowlabel 0x03823, hlim 57, next-header ICMPv6 (58) payload length: 16) 2600:8802:1500:a00:571:870b:ca12:2b3b > 2600:8802:1500:a01::1: [icmp6 sum ok] ICMP6, echo request, seq 0
    18:06:40.867918 IP6 (flowlabel 0x03823, hlim 56, next-header ICMPv6 (58) payload length: 16) 2600:8802:1500:a00:571:870b:ca12:2b3b > 2600:8802:1500:a01::1: [icmp6 sum ok] ICMP6, echo request, seq 0
    18:06:40.867933 IP6 (flowlabel 0x03823, hlim 55, next-header ICMPv6 (58) payload length: 16) 2600:8802:1500:a00:571:870b:ca12:2b3b > 2600:8802:1500:a01::1: [icmp6 sum ok] ICMP6, echo request, seq 0
    18:06:40.875496 IP6 (flowlabel 0x03823, hlim 54, next-header ICMPv6 (58) payload length: 16) 2600:8802:1500:a00:571:870b:ca12:2b3b > 2600:8802:1500:a01::1: [icmp6 sum ok] ICMP6, echo request, seq 0
    18:06:40.875511 IP6 (flowlabel 0x03823, hlim 53, next-header ICMPv6 (58) payload length: 16) 2600:8802:1500:a00:571:870b:ca12:2b3b > 2600:8802:1500:a01::1: [icmp6 sum ok] ICMP6, echo request, seq 0
    18:06:40.883474 IP6 (flowlabel 0x03823, hlim 52, next-header ICMPv6 (58) payload length: 16) 2600:8802:1500:a00:571:870b:ca12:2b3b > 2600:8802:1500:a01::1: [icmp6 sum ok] ICMP6, echo request, seq 0
    18:06:40.883490 IP6 (flowlabel 0x03823, hlim 51, next-header ICMPv6 (58) payload length: 16) 2600:8802:1500:a00:571:870b:ca12:2b3b > 2600:8802:1500:a01::1: [icmp6 sum ok] ICMP6, echo request, seq 0
    18:06:40.899281 IP6 (flowlabel 0x03823, hlim 50, next-header ICMPv6 (58) payload length: 16) 2600:8802:1500:a00:571:870b:ca12:2b3b > 2600:8802:1500:a01::1: [icmp6 sum ok] ICMP6, echo request, seq 0
    18:06:40.899296 IP6 (flowlabel 0x03823, hlim 49, next-header ICMPv6 (58) payload length: 16) 2600:8802:1500:a00:571:870b:ca12:2b3b > 2600:8802:1500:a01::1: [icmp6 sum ok] ICMP6, echo request, seq 0
    18:06:40.907684 IP6 (flowlabel 0x03823, hlim 48, next-header ICMPv6 (58) payload length: 16) 2600:8802:1500:a00:571:870b:ca12:2b3b > 2600:8802:1500:a01::1: [icmp6 sum ok] ICMP6, echo request, seq 0
    18:06:40.907699 IP6 (flowlabel 0x03823, hlim 47, next-header ICMPv6 (58) payload length: 16) 2600:8802:1500:a00:571:870b:ca12:2b3b > 2600:8802:1500:a01::1: [icmp6 sum ok] ICMP6, echo request, seq 0
    18:06:40.915511 IP6 (flowlabel 0x03823, hlim 46, next-header ICMPv6 (58) payload length: 16) 2600:8802:1500:a00:571:870b:ca12:2b3b > 2600:8802:1500:a01::1: [icmp6 sum ok] ICMP6, echo request, seq 0
    18:06:40.915523 IP6 (flowlabel 0x03823, hlim 45, next-header ICMPv6 (58) payload length: 16) 2600:8802:1500:a00:571:870b:ca12:2b3b > 2600:8802:1500:a01::1: [icmp6 sum ok] ICMP6, echo request, seq 0
    18:06:40.923691 IP6 (flowlabel 0x03823, hlim 44, next-header ICMPv6 (58) payload length: 16) 2600:8802:1500:a00:571:870b:ca12:2b3b > 2600:8802:1500:a01::1: [icmp6 sum ok] ICMP6, echo request, seq 0
    18:06:40.923707 IP6 (flowlabel 0x03823, hlim 43, next-header ICMPv6 (58) payload length: 16) 2600:8802:1500:a00:571:870b:ca12:2b3b > 2600:8802:1500:a01::1: [icmp6 sum ok] ICMP6, echo request, seq 0
    18:06:40.934520 IP6 (flowlabel 0x03823, hlim 42, next-header ICMPv6 (58) payload length: 16) 2600:8802:1500:a00:571:870b:ca12:2b3b > 2600:8802:1500:a01::1: [icmp6 sum ok] ICMP6, echo request, seq 0
    18:06:40.934536 IP6 (flowlabel 0x03823, hlim 41, next-header ICMPv6 (58) payload length: 16) 2600:8802:1500:a00:571:870b:ca12:2b3b > 2600:8802:1500:a01::1: [icmp6 sum ok] ICMP6, echo request, seq 0
    18:06:40.941499 IP6 (flowlabel 0x03823, hlim 40, next-header ICMPv6 (58) payload length: 16) 2600:8802:1500:a00:571:870b:ca12:2b3b > 2600:8802:1500:a01::1: [icmp6 sum ok] ICMP6, echo request, seq 0
    18:06:40.941515 IP6 (flowlabel 0x03823, hlim 39, next-header ICMPv6 (58) payload length: 16) 2600:8802:1500:a00:571:870b:ca12:2b3b > 2600:8802:1500:a01::1: [icmp6 sum ok] ICMP6, echo request, seq 0
    18:06:40.949452 IP6 (flowlabel 0x03823, hlim 38, next-header ICMPv6 (58) payload length: 16) 2600:8802:1500:a00:571:870b:ca12:2b3b > 2600:8802:1500:a01::1: [icmp6 sum ok] ICMP6, echo request, seq 0
    18:06:40.949467 IP6 (flowlabel 0x03823, hlim 37, next-header ICMPv6 (58) payload length: 16) 2600:8802:1500:a00:571:870b:ca12:2b3b > 2600:8802:1500:a01::1: [icmp6 sum ok] ICMP6, echo request, seq 0
    18:06:40.957736 IP6 (flowlabel 0x03823, hlim 36, next-header ICMPv6 (58) payload length: 16) 2600:8802:1500:a00:571:870b:ca12:2b3b > 2600:8802:1500:a01::1: [icmp6 sum ok] ICMP6, echo request, seq 0
    18:06:40.957754 IP6 (flowlabel 0x03823, hlim 35, next-header ICMPv6 (58) payload length: 16) 2600:8802:1500:a00:571:870b:ca12:2b3b > 2600:8802:1500:a01::1: [icmp6 sum ok] ICMP6, echo request, seq 0
    18:06:40.965534 IP6 (flowlabel 0x03823, hlim 34, next-header ICMPv6 (58) payload length: 16) 2600:8802:1500:a00:571:870b:ca12:2b3b > 2600:8802:1500:a01::1: [icmp6 sum ok] ICMP6, echo request, seq 0
    18:06:40.965551 IP6 (flowlabel 0x03823, hlim 33, next-header ICMPv6 (58) payload length: 16) 2600:8802:1500:a00:571:870b:ca12:2b3b > 2600:8802:1500:a01::1: [icmp6 sum ok] ICMP6, echo request, seq 0
    18:06:40.973687 IP6 (flowlabel 0x03823, hlim 32, next-header ICMPv6 (58) payload length: 16) 2600:8802:1500:a00:571:870b:ca12:2b3b > 2600:8802:1500:a01::1: [icmp6 sum ok] ICMP6, echo request, seq 0
    18:06:40.973704 IP6 (flowlabel 0x03823, hlim 31, next-header ICMPv6 (58) payload length: 16) 2600:8802:1500:a00:571:870b:ca12:2b3b > 2600:8802:1500:a01::1: [icmp6 sum ok] ICMP6, echo request, seq 0
    18:06:40.981715 IP6 (flowlabel 0x03823, hlim 30, next-header ICMPv6 (58) payload length: 16) 2600:8802:1500:a00:571:870b:ca12:2b3b > 2600:8802:1500:a01::1: [icmp6 sum ok] ICMP6, echo request, seq 0
    18:06:40.981731 IP6 (flowlabel 0x03823, hlim 29, next-header ICMPv6 (58) payload length: 16) 2600:8802:1500:a00:571:870b:ca12:2b3b > 2600:8802:1500:a01::1: [icmp6 sum ok] ICMP6, echo request, seq 0
    18:06:40.989493 IP6 (flowlabel 0x03823, hlim 28, next-header ICMPv6 (58) payload length: 16) 2600:8802:1500:a00:571:870b:ca12:2b3b > 2600:8802:1500:a01::1: [icmp6 sum ok] ICMP6, echo request, seq 0
    18:06:40.989509 IP6 (flowlabel 0x03823, hlim 27, next-header ICMPv6 (58) payload length: 16) 2600:8802:1500:a00:571:870b:ca12:2b3b > 2600:8802:1500:a01::1: [icmp6 sum ok] ICMP6, echo request, seq 0
    18:06:40.997521 IP6 (flowlabel 0x03823, hlim 26, next-header ICMPv6 (58) payload length: 16) 2600:8802:1500:a00:571:870b:ca12:2b3b > 2600:8802:1500:a01::1: [icmp6 sum ok] ICMP6, echo request, seq 0
    18:06:40.997537 IP6 (flowlabel 0x03823, hlim 25, next-header ICMPv6 (58) payload length: 16) 2600:8802:1500:a00:571:870b:ca12:2b3b > 2600:8802:1500:a01::1: [icmp6 sum ok] ICMP6, echo request, seq 0
    18:06:41.006725 IP6 (flowlabel 0x03823, hlim 24, next-header ICMPv6 (58) payload length: 16) 2600:8802:1500:a00:571:870b:ca12:2b3b > 2600:8802:1500:a01::1: [icmp6 sum ok] ICMP6, echo request, seq 0
    18:06:41.006741 IP6 (flowlabel 0x03823, hlim 23, next-header ICMPv6 (58) payload length: 16) 2600:8802:1500:a00:571:870b:ca12:2b3b > 2600:8802:1500:a01::1: [icmp6 sum ok] ICMP6, echo request, seq 0
    18:06:41.023707 IP6 (flowlabel 0x03823, hlim 22, next-header ICMPv6 (58) payload length: 16) 2600:8802:1500:a00:571:870b:ca12:2b3b > 2600:8802:1500:a01::1: [icmp6 sum ok] ICMP6, echo request, seq 0
    18:06:41.023723 IP6 (flowlabel 0x03823, hlim 21, next-header ICMPv6 (58) payload length: 16) 2600:8802:1500:a00:571:870b:ca12:2b3b > 2600:8802:1500:a01::1: [icmp6 sum ok] ICMP6, echo request, seq 0
    18:06:41.031711 IP6 (flowlabel 0x03823, hlim 20, next-header ICMPv6 (58) payload length: 16) 2600:8802:1500:a00:571:870b:ca12:2b3b > 2600:8802:1500:a01::1: [icmp6 sum ok] ICMP6, echo request, seq 0
    18:06:41.031726 IP6 (flowlabel 0x03823, hlim 19, next-header ICMPv6 (58) payload length: 16) 2600:8802:1500:a00:571:870b:ca12:2b3b > 2600:8802:1500:a01::1: [icmp6 sum ok] ICMP6, echo request, seq 0
    18:06:41.039713 IP6 (flowlabel 0x03823, hlim 18, next-header ICMPv6 (58) payload length: 16) 2600:8802:1500:a00:571:870b:ca12:2b3b > 2600:8802:1500:a01::1: [icmp6 sum ok] ICMP6, echo request, seq 0
    18:06:41.039729 IP6 (flowlabel 0x03823, hlim 17, next-header ICMPv6 (58) payload length: 16) 2600:8802:1500:a00:571:870b:ca12:2b3b > 2600:8802:1500:a01::1: [icmp6 sum ok] ICMP6, echo request, seq 0
    18:06:41.047692 IP6 (flowlabel 0x03823, hlim 16, next-header ICMPv6 (58) payload length: 16) 2600:8802:1500:a00:571:870b:ca12:2b3b > 2600:8802:1500:a01::1: [icmp6 sum ok] ICMP6, echo request, seq 0
    18:06:41.047708 IP6 (flowlabel 0x03823, hlim 15, next-header ICMPv6 (58) payload length: 16) 2600:8802:1500:a00:571:870b:ca12:2b3b > 2600:8802:1500:a01::1: [icmp6 sum ok] ICMP6, echo request, seq 0
    18:06:41.055771 IP6 (flowlabel 0x03823, hlim 14, next-header ICMPv6 (58) payload length: 16) 2600:8802:1500:a00:571:870b:ca12:2b3b > 2600:8802:1500:a01::1: [icmp6 sum ok] ICMP6, echo request, seq 0
    18:06:41.055787 IP6 (flowlabel 0x03823, hlim 13, next-header ICMPv6 (58) payload length: 16) 2600:8802:1500:a00:571:870b:ca12:2b3b > 2600:8802:1500:a01::1: [icmp6 sum ok] ICMP6, echo request, seq 0
    18:06:41.063524 IP6 (flowlabel 0x03823, hlim 12, next-header ICMPv6 (58) payload length: 16) 2600:8802:1500:a00:571:870b:ca12:2b3b > 2600:8802:1500:a01::1: [icmp6 sum ok] ICMP6, echo request, seq 0
    18:06:41.063539 IP6 (flowlabel 0x03823, hlim 11, next-header ICMPv6 (58) payload length: 16) 2600:8802:1500:a00:571:870b:ca12:2b3b > 2600:8802:1500:a01::1: [icmp6 sum ok] ICMP6, echo request, seq 0
    18:06:41.077736 IP6 (flowlabel 0x03823, hlim 10, next-header ICMPv6 (58) payload length: 16) 2600:8802:1500:a00:571:870b:ca12:2b3b > 2600:8802:1500:a01::1: [icmp6 sum ok] ICMP6, echo request, seq 0
    18:06:41.077752 IP6 (flowlabel 0x03823, hlim 9, next-header ICMPv6 (58) payload length: 16) 2600:8802:1500:a00:571:870b:ca12:2b3b > 2600:8802:1500:a01::1: [icmp6 sum ok] ICMP6, echo request, seq 0
    18:06:41.085533 IP6 (flowlabel 0x03823, hlim 8, next-header ICMPv6 (58) payload length: 16) 2600:8802:1500:a00:571:870b:ca12:2b3b > 2600:8802:1500:a01::1: [icmp6 sum ok] ICMP6, echo request, seq 0
    18:06:41.085548 IP6 (flowlabel 0x03823, hlim 7, next-header ICMPv6 (58) payload length: 16) 2600:8802:1500:a00:571:870b:ca12:2b3b > 2600:8802:1500:a01::1: [icmp6 sum ok] ICMP6, echo request, seq 0
    18:06:41.093536 IP6 (flowlabel 0x03823, hlim 6, next-header ICMPv6 (58) payload length: 16) 2600:8802:1500:a00:571:870b:ca12:2b3b > 2600:8802:1500:a01::1: [icmp6 sum ok] ICMP6, echo request, seq 0
    18:06:41.093551 IP6 (flowlabel 0x03823, hlim 5, next-header ICMPv6 (58) payload length: 16) 2600:8802:1500:a00:571:870b:ca12:2b3b > 2600:8802:1500:a01::1: [icmp6 sum ok] ICMP6, echo request, seq 0
    18:06:41.102690 IP6 (flowlabel 0x03823, hlim 4, next-header ICMPv6 (58) payload length: 16) 2600:8802:1500:a00:571:870b:ca12:2b3b > 2600:8802:1500:a01::1: [icmp6 sum ok] ICMP6, echo request, seq 0
    18:06:41.102705 IP6 (flowlabel 0x03823, hlim 3, next-header ICMPv6 (58) payload length: 16) 2600:8802:1500:a00:571:870b:ca12:2b3b > 2600:8802:1500:a01::1: [icmp6 sum ok] ICMP6, echo request, seq 0
    18:06:41.109742 IP6 (flowlabel 0x03823, hlim 2, next-header ICMPv6 (58) payload length: 16) 2600:8802:1500:a00:571:870b:ca12:2b3b > 2600:8802:1500:a01::1: [icmp6 sum ok] ICMP6, echo request, seq 0
    18:06:41.109758 IP6 (flowlabel 0x03823, hlim 1, next-header ICMPv6 (58) payload length: 16) 2600:8802:1500:a00:571:870b:ca12:2b3b > 2600:8802:1500:a01::1: [icmp6 sum ok] ICMP6, echo request, seq 0