In theory: implement NAT64 from v6 to v4 without externs

This commit is contained in:
Nico Schottelius 2019-07-21 10:23:49 +02:00
commit 018e4cc9ff
3 changed files with 53 additions and 26 deletions

View file

@ -1,8 +1,6 @@
#ifndef NICO_DELTA_CHECKSUM
#define NICO_DELTA_CHECKSUM
#include "headers.p4"
action v4sum() {
@ -128,6 +126,10 @@ action delta_ipv4_from_v6_to_v4()
{
bit<16> tmp = 0;
/* we don't have ANY checksum, but tcp or udp: we can
base on that ones for calculating the diff for IPv4
Does NOT contain payload! -> can be done manually */
tmp = tmp + (bit<16>) hdr.ipv4.version; /* 4 bit */
tmp = tmp + (bit<16>) hdr.ipv4.ihl; /* 4 bit */
@ -136,18 +138,15 @@ action delta_ipv4_from_v6_to_v4()
tmp = tmp + (bit<16>) hdr.ipv4.totalLen; /* 16 bit */
tmp = tmp + (bit<16>) hdr.ipv4.identification; /* 16 bit */
tmp = tmp + (bit<16>) hdr.ipv4.flags; /* 3 bit */
/* we don't have ANY checksum, but tcp or udp: we can
base on that ones for calculating the diff for IPv4
tmp = tmp + (bit<16>) hdr.ipv4.fragOffset; /* 13 bit */
tmp = tmp + (bit<16>) hdr.ipv4.ttl; /* 8 bit */
tmp = tmp + (bit<16>) hdr.ipv4.protocol; /* 8 bit */
tmp = tmp + (bit<16>) hdr.ipv4.src_addr[15:0]; /* 16 bit */
tmp = tmp + (bit<16>) hdr.ipv4.src_addr[31:16]; /* 16 bit */
tmp = tmp + (bit<16>) hdr.ipv4.dst_addr[15:0]; /* 16 bit */
tmp = tmp + (bit<16>) hdr.ipv4.dst_addr[31:16]; /* 16 bit */
Does NOT contain payload! -> can be done manually
tmp = tmp + (bit<16>) hdr.ipv4.fragOffset;
tmp = tmp + (bit<16>) hdr.ipv4.ttl,
tmp = tmp + (bit<16>) hdr.ipv4.protocol,
tmp = tmp + (bit<16>) hdr.ipv4.src_addr,
tmp = tmp + (bit<16>) hdr.ipv4.dst_addr
*/
hdr.ipv4.checksum = 0; /* TO BE DONE! */
hdr.ipv4.checksum = ~tmp;
}

View file

@ -2,6 +2,7 @@
#define NICO_NAT64_GENERIC
#include "actions_controller.p4"
#include "actions_delta_checksum.p4"
/********************** NAT64 / NAT46 ACTIONS GENERIC ***********************************/
@ -28,31 +29,32 @@ action nat64_icmp6_generic()
action nat64_generic(ipv4_addr_t src, ipv4_addr_t dst) {
hdr.ipv4.setValid();
meta.chk_ipv4 = 1; /* need to calculate the hdrchecksum */
/* Stuff that might need to be fixed */
hdr.ipv4.version = (bit<4>)4;
hdr.ipv4.ihl = (bit<4>)5; // internet header length: 4*5 = 20
/* 5 is ok as long as
we don't use options / padding /
anything after the destination address */
hdr.ipv4.diff_serv = (bit<6>)0; // no ToS
hdr.ipv4.ecn = (bit<2>)0; // unsupported
/* 5 is ok as long as we don't use options / padding /
anything after the destination address */
hdr.ipv4.ihl = (bit<4>) 5; // internet header length: 4*5 = 20
hdr.ipv4.totalLen = (bit<16>) hdr.ipv6.payload_length + 20; // ok under above constraints
hdr.ipv4.identification = (bit<16>) 0; // no support for fragments
hdr.ipv4.flags = (bit<3>) 0; // DF bit and more fragments
hdr.ipv4.fragOffset = (bit<13>) 0; // 0 as there are no fragments
hdr.ipv4.ttl = hdr.ipv6.hop_limit;
hdr.ipv4.protocol = hdr.ipv6.next_header;
hdr.ipv4.src_addr = src;
hdr.ipv4.dst_addr = dst;
/* Stuff that should be fine */
hdr.ethernet.ethertype = TYPE_IPV4;
hdr.ipv4.dst_addr = dst;
hdr.ipv4.src_addr = src;
hdr.ipv4.ttl = hdr.ipv6.hop_limit;
hdr.ipv4.protocol = hdr.ipv6.next_header;
#ifdef USE_NICO_DELTA_CHECKSUM
delta_ipv4_from_v6_to_v4();
#else
meta.chk_ipv4 = 1; /* need to calculate the hdrchecksum */
#endif
hdr.ipv6.setInvalid();
}