diff --git a/p4app/controller.py b/p4app/controller.py index 0d46fe6..3a0d711 100755 --- a/p4app/controller.py +++ b/p4app/controller.py @@ -38,6 +38,17 @@ table_id_fields = { 5: 'TABLE_V4_NETWORKS' } +table_proto = { + 'ICMP6_ECHO_REQUEST' : 128, + 'ICMP6_ECHO_REPLY' : 129, + 'ICMP6_NS' : 135, + 'ICMP6_NA' : 136, + 'ICMP_ECHO_REPLY' : 0, + 'ICMP_ECHO_REQUEST' : 8 +} + + + class CpuHeader(Packet): name = 'CpuPacket' fields_desc = [ @@ -273,17 +284,41 @@ class L2Controller(object): v6_src, v6_dst, v4_dst, v4_src, v4_dst, v6_src)) -# [str(v6_src) - self.controller.table_add("nat64", "nat64_static", - [str(v6_dst)], + self.controller.table_add("nat64_icmp6", + "nat64_icmp6_echo_request", + [str(v6_dst), + str(table_proto['ICMP6_ECHO_REQUEST']) + ], [str(v6_src.network_address), str(v4_dst.network_address), str(v6_dst.network_address)] ) -# [str(v4_src) - self.controller.table_add("nat46", "nat46_static", - [str(v4_dst)], + self.controller.table_add("nat64_icmp6", + "nat64_icmp6_echo_reply", + [str(v6_dst), + str(table_proto['ICMP6_ECHO_REPLY']) + ], + [str(v6_src.network_address), + str(v4_dst.network_address), + str(v6_dst.network_address)] + ) + + self.controller.table_add("nat46_icmp", + "nat46_icmp_echo_reply", + [str(v4_dst) + str(table_proto['ICMP_ECHO_REPLY']) + ], + [str(v6_src.network_address), + str(v4_dst.network_address), + str(v6_dst.network_address)] + ) + + self.controller.table_add("nat46_icmp", + "nat46_icmp_echo_request", + [str(v4_dst) + str(table_proto['ICMP_ECHO_REQUEST']) + ], [str(v6_src.network_address), str(v4_dst.network_address), str(v6_dst.network_address)] diff --git a/p4src/static-mapping.p4 b/p4src/static-mapping.p4 index 6f1ecd8..5995923 100644 --- a/p4src/static-mapping.p4 +++ b/p4src/static-mapping.p4 @@ -48,28 +48,28 @@ control MyIngress(inout headers hdr, /********************** NAT64 / NAT46 ACTIONS ***********************************/ + /* if replacing actions */ + action nat64_icmp6_echo_request(ipv6_addr_t v6_src, ipv4_addr_t v4_dst, ipv6_addr_t nat64_prefix) { + nat64_static(v6_src, v4_dst, nat64_prefix); + nat64_icmp6(); - action mimic_assign_echo_request() - { hdr.icmp.type = ICMP_ECHO_REQUEST; } - /* changes for icmp6 -> icmp - - first echo request/reply - - later maybe other - */ + action nat64_icmp6_echo_reply(ipv6_addr_t v6_src, ipv4_addr_t v4_dst, ipv6_addr_t nat64_prefix) { + nat64_static(v6_src, v4_dst, nat64_prefix); + nat64_icmp6(); + + hdr.icmp.type = ICMP_ECHO_REPLY; + } + + + /* changes for icmp6 -> icmp */ action nat64_icmp6() { hdr.icmp.setValid(); hdr.ipv4.protocol = PROTO_ICMP; // overwrite generic same protocol assumption - // if(hdr.icmp6.type == ICMP6_ECHO_REQUEST) { - // mimic_assign_echo_request(); - // } - // if(hdr.icmp6.type == ICMP6_ECHO_REPLY) { - // hdr.icmp.type = ICMP_ECHO_REPLY; - // } - /* trigger checksumming */ meta.switch_task = TASK_CHECKSUM_ICMP; @@ -80,7 +80,6 @@ control MyIngress(inout headers hdr, hdr.icmp6_option_link_layer_addr.setInvalid(); } - /* NAT64 protocol unspecific changes */ action nat64_generic(ipv4_addr_t src, ipv4_addr_t dst) { hdr.ipv4.setValid(); @@ -117,6 +116,8 @@ control MyIngress(inout headers hdr, /* NAT46: protocol unspecific changes */ action nat46_generic(ipv6_addr_t src, ipv6_addr_t dst) { hdr.ipv6.setValid(); + hdr.ipv4.setInvalid(); + hdr.ethernet.ethertype = TYPE_IPV6; hdr.ipv6.dst_addr = dst; @@ -130,10 +131,8 @@ control MyIngress(inout headers hdr, hdr.ipv6.next_header = hdr.ipv4.protocol; hdr.ipv6.hop_limit = hdr.ipv4.ttl; - hdr.ipv4.setInvalid(); } - /* nat64_prefix is the same as the matching key, but without the mask */ action nat64_static(ipv6_addr_t v6_src, ipv4_addr_t v4_dst, ipv6_addr_t nat64_prefix) { ipv6_addr_t src_offset = hdr.ipv6.src_addr - v6_src; @@ -142,7 +141,14 @@ control MyIngress(inout headers hdr, ipv4_addr_t dst = (ipv4_addr_t) (hdr.ipv6.dst_addr - nat64_prefix); nat64_generic(src, dst); + } + action nat46_icmp_echo_request(ipv6_addr_t v6_src, ipv4_addr_t v4_dst, ipv6_addr_t nat64_prefix) { + ; /* TBD */ + } + + action nat46_icmp_echo_reply(ipv6_addr_t v6_src, ipv4_addr_t v4_dst, ipv6_addr_t nat64_prefix) { + ; /* TBD */ } /* matching key: v4_network specified again */ @@ -153,19 +159,17 @@ control MyIngress(inout headers hdr, ipv6_addr_t dst = v6_src + (ipv6_addr_t) dst_offset; nat46_generic(src, dst); - - /* fix the protocol specific translations */ - // switch() ... } - table nat64 { + table nat64_icmp6 { key = { hdr.ipv6.dst_addr: lpm; - hdr.ipv6.next_header: exact; + hdr.icmp6.type: exact; } actions = { controller_debug; - nat64_static; + nat64_icmp6_echo_reply; + nat64_icmp6_echo_request; controller_debug_table_id; NoAction; } @@ -173,14 +177,15 @@ control MyIngress(inout headers hdr, default_action = controller_debug_table_id(TABLE_NAT64); } - table nat46 { + table nat46_icmp { key = { -// hdr.ipv4.src_addr: lpm; hdr.ipv4.dst_addr: lpm; + hdr.icmp.type: exact; } actions = { controller_debug; - nat46_static; + nat46_icmp_echo_reply; + nat46_icmp_echo_request; controller_debug_table_id; NoAction; } @@ -228,7 +233,6 @@ control MyIngress(inout headers hdr, hdr.icmp6_option_link_layer_addr.ll_length = 1; /* 1* 64 bit */ hdr.icmp6_option_link_layer_addr.mac_addr = mac_addr; - /* version1: rebuilding packet */ /* truncate((bit<32>)(112 + 320 + 32)/8); @@ -369,64 +373,15 @@ control MyIngress(inout headers hdr, } /********************** APPLYING TABLES ***********************************/ - apply { - /* V2: matching all protocols in same table */ - if(hdr.ipv6.isValid()) { - switch(nat64.apply().action_run) { - nat64_icmp6: { nat64_icmp6_if_table.apply() } - nat64_tcp: { ... } // nothing, directly handled - nat64_udp: { ... } // nothing, directly handled - } - /* not sure how to get .hit & .action_run */ - if(there_was_a_hit_in_nat64) { - v4_networks.apply(); /* apply egress for IPv4 */ - exit; /* no further v6 processing */ - } - } - - /* V3: matching protocols in distinct tables */ - if(hdr.ipv6.isValid()) { - switch(nat64_icmp6.apply().hit) { - v4_networks.apply(); /* apply egress for IPv4 */ - exit; /* no further v6 processing */ - } - - /* the next two might be able to be merged */ - switch(nat64_udp.apply().hit) { - v4_networks.apply(); /* apply egress for IPv4 */ - exit; /* no further v6 processing */ - } - switch(nat64_tcp.apply().hit) { - v4_networks.apply(); /* apply egress for IPv4 */ - exit; /* no further v6 processing */ - } - } - - switch(nat64.apply().action_run) { - nat64_icmp6: { nat64_icmp6_if_table.apply() } - nat64_tcp: { ... } // nothing, directly handled - nat64_udp: { ... } // nothing, directly handled - } - /* not sure how to get .hit & .action_run */ - if(there_was_a_hit_in_nat64) { - v4_networks.apply(); /* apply egress for IPv4 */ - exit; /* no further v6 processing */ - } - } - - - apply { if(hdr.ipv6.isValid()) { icmp6.apply(); /* icmp6 echo, icmp6 ndp */ - switch(nat64.apply().action_run) { - nat64_icmp6: { nat64_icmp6_if_table.apply() } + if(nat64_icmp6.apply().hit) { + v4_networks.apply(); /* apply egress for IPv4 */ + exit; /* no further v6 processing */ } - v4_networks.apply(); /* apply egress */ - exit; /* no further v6 processing */ - } v6_networks.apply(); /* egress / routing */ } else if(hdr.ipv4.isValid()) { if(nat46.apply().hit) { /* v4->v6 */