2 changed files with 165 additions and 16 deletions
@ -0,0 +1,116 @@
|
||||
## 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 { |
||||
^^^^^ |
||||
``` |
||||
|
||||
### 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) |
||||
|
||||
- Have to investigate |
Loading…
Reference in new issue