## What I want to do: NAT64 static mapping

I want to use different mapped IPv4 networks for (possibly) the same
destination IPv6 network.

In other words:

* Network A, 2001:db8::/64, sends to an address in 64:ff9b::/96
* The 8 bit sub network ("range") of 2001:db8::/64, 2001:db8::/120
  should be mapped to 10.1.0.0/24
* Network B, 2001:db8:1::/64, sends to an address in 64:ff9b::/96
* The 8 bit sub network ("range") of 2001:db8:1::/64, 2001:db8:1::/120
  should be mapped to 10.1.1.0/24

## What I tried to do
### 2 LPM keys

I tried to use one table with two LPM keys, which I would like to
match "in order":

```
    table nat64 {
        key = {
            hdr.ipv6.src_addr: lpm;
            hdr.ipv6.dst_addr: lpm;
        }
        actions = {
            controller_debug;
            nat64_static;
            NoAction;
        }
        size = NAT64_TABLE_SIZE;
        default_action = controller_debug;
    }
```

So matching hdr.ipv6.src_addr first and then if the destination packet
is in 64:ff9b::/96, then do NAT64.

This results into the compiler problem

```
../p4src/static-mapping.p4(121): error: MyIngress.nat64, Multiple LPM keys in table
    table nat64 {
          ^^^^^
```

## How it could be solved

### 2 tables (recommendation of Nate)

It does not work, when matching the source address first:

```
    table nat64_src {
        key = {
            hdr.ipv6.src_addr: lpm;
        }
        actions = {
            NoAction;
        }
        size = NAT64_TABLE_SIZE;
        default_action = NoAction;
    }


    table nat64_dst {
        key = {
            hdr.ipv6.dst_addr: lpm;
        }
        actions = {
            controller_debug;
            nat64_static;
            NoAction;
        }
        size = NAT64_TABLE_SIZE;
        default_action = controller_debug;
    }

    ...

    apply {
        if (nat64_src.apply().hit) {
            nat64_dst.apply();
        }
    }

```

The entries of nat64_dst.apply() will be all the same, i.e. there will
be many 64:ff9b::/96 entries and thus this approach does not work.

Trying to match the destination address first:

```
    ...

    apply {
        if (nat64_dst.apply().hit) {
            nat64_src.apply();
        }
    }

```

This way repeating destination addresses will still not be set, but
this is not a problem as one is enough to proceed into the nat64_src
table.

Disadvantage of this approach is that entries from the nat64_dst table
cannot be deleted safely anymore, as repeating destination addresses
of other networks might be deleted. So while this approach works for
testing / development, it does not work for a production setup.

### Ternary matching (recommendation of Andy)

Could be a solution, because it offers priorities. Is not exactly what
I want to achieve, because I want to do LPM matching, but it could be
misused for it.

### Double table with using ID of first match (Andy + Nate ideas)

Use the handle of the source network to match again on exact in the
2nd table. This might be a very reasonable approach.
