When pfctl parses a pool it is aware of address family of each host,
at least when a host is an explicitly given IP address, not a pool or
interface. But kernel can't receive nor store this information in
struct pf_kpooladdr. Introduce pfctl_pooladdr and modify pf_kpooladdr
so that address family can be preserved. Struct pf_nl_pooladdr already
contains a variable for address family, but it was not used. Use it
to send address family with pool addresses when loading pools.
Another option would be to modify struct pf_pooladdr but that is used
in the old ioctls and those can't be modified without breaking
compatibility. Modify pfctl's print_pool to not recover address family
from rule but use the stored address family for each address.
Update source nodes to handle two address families: of the search
address and of the redirection address. Modify nat and route source
node creation to use pre-nat address family for search address and
pool address family for redirection address. Even without RFC5549 this
solves issues with source tracking for nat64 rules: it's the original
IPv6 source address which gets mapped on an IPv4 gateway or IPv4 SNAT
address.
When reading states using netlink introduce PF_ST_RT_AF, so that pfctl
does not need to recover route-to gateway's address family from the
rule.
Modify pf_map_addr() so that it is given a wanted adress family which
is then compared to address family of stored addresses. For RFC5549
operation in round-robin mode each address (which can be a table or
an interface) is evaluated twice: first for IPv6, then for IPv4.
For RFC5549 operation the found address family will overwrite
the requested wanted address family.
In pf_route() check rt_af, it is not guaranteed to be AF_INET anymore
because pf_map_addr() could have changed it. Construct appropriate
gateway using rt_addr.
- 8< ----
I still need to see how this works with pool types other than round-robin and single hosts, and there seems something wrong with source tracking for af-to.