IPv6 routing with multiple interfaces

I guess Network Prefix Translation is one solution if you get a large IPv6 prefix from the VPN provider. You need a /64 for a LAN.
With fewer addresses you probably need to use NAT66 instead.

It may also be possible to let the clients select the correct source address. Linux has the "ip addrlabel" which allows that and which I use myself.

There also is a dhcpv6 option for distributing the policy, but I don't know if it's supported by any OS.



Thank you for the link. Can prefix be either source or target prefix or would it only work for source prefixes?

It's used when selecting source address according to RFC 3484. The target address should already be selected and it will be used when selecting the source address.
BTW ip addrlabel on the router will only affect locally generated traffic and not forwarded traffic.


the main issue with ipv6 as I see it is that a multi-homed network will cause clients to have addresses on several prefixes. when the client wants to talk to the internet it chooses an IP address to use as its source address for its packets. once it does this, the WAN connection must be the one from which the prefix comes, (barring any high end business class contract where the ISP allows traffic from various sources).

So basically the router has no choice... the only way the router can affect this is to do network prefix translation, or God forbid NAT66.

so the question is, what should VPR do with packets from the LAN?


For widest VPN service compatibility it seems both NPT and NAT66 need to be supported.

1 Like

firewall3: missing targets with IPv6 NAT

IMHO any VPN that assigns less than a /60 is broken and you should go elsewhere (this is likely ALL of them). if they assign a /60 then at most you need NPT.

If I wanted a VPN type service I would rent a digital ocean droplet or the like and install wireguard to roll my own, for various reasons including security.


Are you sure anyone can give you a /60 prefix for free?
If not then it's just a lame excuse to not fix the bug.

Based on the feedback I've received so far, VPR should:

  1. Figure out of NAT6 is configured for all IPv6-capable connections on the router.
  2. If #1 is true, figure out the gateways (is there an IPv6 gateway)?
  3. Set up policies to direct IPv6 traffic thru gateways as per policies set by user.

Does it look plausible?

If anyone can contribute any code or provide feedback on gw6-related functions here: https://github.com/stangri/openwrt_packages/blob/master/vpn-policy-routing/files/vpn-policy-routing.init#L95-L99 I'd be much obliged.

1 Like

anyone running a VPN service can get a /32 which gives them 2^28 =268 million /60 networks to hand out, so, yes.

1 Like

Technically it's not true, because to run a service you don't need a /32.
A /64 or even a /128 is enough to run a service.

It should be clarified that NAT6 aka NAT66 is enabled/disabled globally.
Currently NAT6 is broken on the level of fw3 service.
While IPv6 masquerading, which relies on NAT6, may be enabled per firewall zone.

1 Like

it is true, anyone CAN, the fact that people don't just goes to show how little people understand ipv6 even VPN providers

1 Like

The service is not required to be a public provider and the server location may be critical to the client.

How can I check if the IPv6 masquerading is enabled?

In theory it should be the same way as for IPv4:

uci get firewall.@zone[x].masq6

Although fw3 currently ignores this option, there are workarounds.

Regarding the VPR code:

  • ifconfig is deprecated, so consider replacing it with ip.
  • from is a mandatory selector for ip -6 route to fetch the correct IPv6 gateway.

There's an example of code which may help you in some way:

net_addr() {
    local PROTO="${1}"
    local NET_IF="${2}"
    local NET_ADDR="$(${IPR} ${PROTO} addr show dev ${NET_IF} \
        | sed -n -e "/\sinet6*\s/{s/^\s*\w*\s//;s/\/.*$//p}" \
        | sed -n -e "1p")"
    echo "${NET_ADDR}"

net_gw() {
    local PROTO="${1}"
    local NET_IF="${2}"
    case "${PROTO}" in
        "-4") local NET_GLOBAL="1" ;;
        "-6") local NET_GLOBAL="1::" ;;
    local NET_ADDR="$(net_addr ${PROTO} ${NET_IF})"
    local NET_GW="$(${IPR} ${PROTO} route get ${NET_GLOBAL} from ${NET_ADDR} dev ${NET_IF} \
        | sed -n -e "/\svia\s/{s/^.*\svia\s//;s/\s.*$//p}")"
    echo "${NET_GW}"

NET_ADDR="$(net_addr -4 ${NET_IF})"
NET_ADDR6="$(net_addr -6 ${NET_IF6})"
NET_GW="$(net_gw -4 ${NET_IF})"
NET_GW6="$(net_gw -6 ${NET_IF6})"
echo "${NET_ADDR} - ${NET_GW}"
echo "${NET_ADDR6} - ${NET_GW6}"

This doesn't seem to work for neither -4 nor -6 with the wireguard tunnel which is not default routing (route_allowed_ips '0').

For WireGuard I can see only the peer's own IP address/netmask.
I used these utilities for testing:

ip address show
ip route show table all

It doesn't matter whether I enable route_allowed_ips or not.
Are you sure it is possible get anything else?
Please, provide an example configuration so we can find common ground.

Perhaps my system is a bit too old:

# uname -a
Linux vgrouter 4.14.63 #0 Thu Aug 16 07:51:15 2018 mips GNU/Linux
# opkg list-installed wireguard
wireguard - 0.0.20190601-1

I'll reply again after I test a new build.

1 Like

This is what bugs me. That's why I suppose that NPTv6 - and not NAT6 - is the solution for multi-homing. It lets clients handle only 1 IP address while also lets router do load balancing with any rule we'd like.

I don't see why this would be bad. Having clients with 2 or more GUA + ULA and handling routing with no way of customizing it is anything from good.

1 Like

Thank you for bring it back up.

I now have accounts issued to me by a few commercial VPN providers and for IPv6 they allot the unique-local addresses only, not global ones.

Can anyone comment if it's a usual practice?


I usually receive: /128, /64 or a /48 from IPv6 tunnel providers.