++ nat64 update, discussion update
This commit is contained in:
parent
b5cd3aeb0e
commit
7c8f019b2a
3 changed files with 71 additions and 9 deletions
60
doc/plan.org
60
doc/plan.org
|
@ -106,7 +106,7 @@
|
||||||
| 2019-03-14 | NAT64 static rewrite | |
|
| 2019-03-14 | NAT64 static rewrite | |
|
||||||
| | - table support | |
|
| | - table support | |
|
||||||
| | - checksum not yet ported for translations | |
|
| | - checksum not yet ported for translations | |
|
||||||
| | - how to get mask from lpm table match? | |
|
| | - how to get mask from lpm table match? | |
|
||||||
| | - how to get network from lpm match? | |
|
| | - how to get network from lpm match? | |
|
||||||
| | | |
|
| | | |
|
||||||
| | | |
|
| | | |
|
||||||
|
@ -1053,6 +1053,64 @@ DEBUG:main:INCOMING: <Ether dst=33:33:ff:00:00:42 src=00:00:0a:00:00:01 type=0x
|
||||||
**** Requirements
|
**** Requirements
|
||||||
*** Performance comparison
|
*** Performance comparison
|
||||||
*** Feature/Functionality difference / overview / Challenges / limitations in P4
|
*** Feature/Functionality difference / overview / Challenges / limitations in P4
|
||||||
|
**** P4: cannot read key from table
|
||||||
|
Key and mask for matching destination is in table. We need this
|
||||||
|
information in the action. However this information is not exposed, so
|
||||||
|
we need to specify another parameter with the same information as in
|
||||||
|
the key(s).
|
||||||
|
|
||||||
|
Log from slack: (2019-03-14)
|
||||||
|
|
||||||
|
nico [1:55 PM]
|
||||||
|
If I use LPM for matching, can I easily get the network address from P4 or do I have to use a bitmask myself? In the latter case it is not exactly clear how to get the mask from the table
|
||||||
|
|
||||||
|
Nate Foster [1:58 PM]
|
||||||
|
You want to retrieve the address in the packet? In a table?
|
||||||
|
And do you want to do the retrieving from the data plane or the control plane? (edited)
|
||||||
|
|
||||||
|
nico [2:00 PM]
|
||||||
|
If I have a match in a table that matches on LPM, it can be any IP address in a network
|
||||||
|
For calculating the NAT64/NAT46 translation, I will need the base address, i.e. network address to do subtractions/additions
|
||||||
|
So it is fully data plane, what I would like to do
|
||||||
|
I'll commit sample code to show the use case more clearly
|
||||||
|
https://gitlab.ethz.ch/nicosc/master-thesis/blob/master/p4src/static-mapping.p4#L73
|
||||||
|
GitLab
|
||||||
|
p4src/static-mapping.p4 · master · nicosc / master-thesis
|
||||||
|
gitlab.ethz.ch
|
||||||
|
So the action nat64_static() is used in the table v6_networks.
|
||||||
|
In v6_networks I use a match on `hdr.ipv6.dst_addr: lpm;`
|
||||||
|
What I would like to be able is to get the network address ; I can do that manually, if I have the mask
|
||||||
|
I can also re-inject this parameter by another action argument, but I'd assume that I can somewhere read this out from the table / match
|
||||||
|
|
||||||
|
Nate Foster [2:15 PM]
|
||||||
|
To make sure I understand, in the data plane, you want to retrieve the address in the lpm pattern? (edited)
|
||||||
|
|
||||||
|
nico [2:16 PM]
|
||||||
|
I want to retrieve the key
|
||||||
|
|
||||||
|
Nate Foster [2:16 PM]
|
||||||
|
Wait. The value `hdr.ipv6.dst_addr` is the thing used in the match.
|
||||||
|
So you have that.
|
||||||
|
What you don’t have is the IPv6 address and mask put into the table by the control plane.
|
||||||
|
I assume you want the latter, right?
|
||||||
|
|
||||||
|
nico [2:17 PM]
|
||||||
|
For example, if my matching key is 2001:db8::/32 and the real address is 2001:db8::f00, then I would like to retrieve 2001:db8:: and 32 from the table
|
||||||
|
exactly :slightly_smiling_face:
|
||||||
|
I can "fix" this by adding another argument, but it feels somewhat wrong to do that
|
||||||
|
Because the table already knows this information
|
||||||
|
|
||||||
|
Nate Foster [2:26 PM]
|
||||||
|
I can’t think of a way other than the action parameter hack.
|
||||||
|
|
||||||
|
nico [2:26 PM]
|
||||||
|
Oh, ok
|
||||||
|
Is it because the information is "lost in hardware"?
|
||||||
|
|
||||||
|
Nate Foster [2:31 PM]
|
||||||
|
No you’re right that most implementations have the value in memory. And one can imagine a different table API that allowed one to retrieve it in the data plane.
|
||||||
|
But unless I am missing something obvious, P4 hides it…
|
||||||
|
|
||||||
**** ICMP6: checksum over payload
|
**** ICMP6: checksum over payload
|
||||||
- variable length, up to 65k
|
- variable length, up to 65k
|
||||||
**** Synchronisation with the controller
|
**** Synchronisation with the controller
|
||||||
|
|
|
@ -117,7 +117,7 @@ class L2Controller(object):
|
||||||
self.nat64_map[mode].append({
|
self.nat64_map[mode].append({
|
||||||
"v6_network": v6_net,
|
"v6_network": v6_net,
|
||||||
"v4_network": v4_net,
|
"v4_network": v4_net,
|
||||||
"v6_nat64_prefix": self.info['nat64_nat_prefix']
|
"nat64_prefix": self.info['nat64_nat_prefix']
|
||||||
})
|
})
|
||||||
|
|
||||||
self.init_boilerplate(sw_name)
|
self.init_boilerplate(sw_name)
|
||||||
|
@ -213,7 +213,7 @@ class L2Controller(object):
|
||||||
self.static_nat64_mapping(**nat64map)
|
self.static_nat64_mapping(**nat64map)
|
||||||
|
|
||||||
|
|
||||||
def static_nat64_mapping(self, v6_nat64_prefix, v6_network, v4_network):
|
def static_nat64_mapping(self, nat64_prefix, v6_network, v4_network):
|
||||||
nat64_prefix = str(v6_nat64_prefix)
|
nat64_prefix = str(v6_nat64_prefix)
|
||||||
net_ipv6 = str(v6_network)
|
net_ipv6 = str(v6_network)
|
||||||
net_ipv4 = str(v4_network)
|
net_ipv4 = str(v4_network)
|
||||||
|
|
|
@ -66,18 +66,22 @@ control MyIngress(inout headers hdr,
|
||||||
meta.cast_length = (bit<32>) hdr.ipv6.payload_length;
|
meta.cast_length = (bit<32>) hdr.ipv6.payload_length;
|
||||||
}
|
}
|
||||||
|
|
||||||
action nat64_static(ipv4_addr_t v6_network, ipv4_addr_t v4_network) {
|
/* nat64_prefix is the same as the matching key, but without the mask */
|
||||||
|
action nat64_static(ipv4_addr_t v6_network, ipv4_addr_t v4_network, ipv6_addr_t nat64_prefix) {
|
||||||
ipv6_addr_t src_offset = hdr.ipv6.src_addr - v6_network;
|
ipv6_addr_t src_offset = hdr.ipv6.src_addr - v6_network;
|
||||||
ipv4_addr_t src = v4_network + (ipv4_addr_t) src_offset;
|
ipv4_addr_t src = v4_network + (ipv4_addr_t) src_offset;
|
||||||
|
|
||||||
ipv4_addr_t dst_offset = hdr.ipv6.dst_addr - LPM_MATCH_NETWORK_ADDRESS_IN_TABLE;
|
ipv6_addr_t dst = (ipv4_addr_t) hdr.ipv6.dst_addr - nat64_prefix;
|
||||||
|
|
||||||
nat64_generic(src, dst);
|
nat64_generic(src, dst);
|
||||||
}
|
}
|
||||||
|
|
||||||
action nat46_static(ipv4_addr_t v4_network, ipv6_addr_t nat64_prefix ) {
|
/* matching key: v4_network specified again */
|
||||||
ipv6_addr_t src = hdr.ipv4.dst_addr - v4_network;
|
action nat46_static(ipv6_addr_t v6_network, ipv4_addr_t v4_network, ipv6_addr_t nat64_prefix ) {
|
||||||
ipv6_addr_t src = hdr.ipv4.dst_addr - v4_network;
|
ipv6_addr_t src = nat64_prefix + (ipv6_addr_t) hdr.ipv4.src_addr;
|
||||||
|
|
||||||
|
ipv4_addr_t dst_offset = hdr.ipv4.dst_addr - v4_network;
|
||||||
|
ipv6_addr_t dst = v6_network + (ipv6_addr_t) dst_offset;
|
||||||
|
|
||||||
nat46_generic(src, dst);
|
nat46_generic(src, dst);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue