diff --git a/p4src/headers.p4 b/p4src/headers.p4 index 8a93b72..3c06323 100644 --- a/p4src/headers.p4 +++ b/p4src/headers.p4 @@ -31,7 +31,14 @@ const bit<8> ICMP6_ECHO_REPLY = 129; const bit<8> ICMP6_NS = 135; const bit<8> ICMP6_NA = 136; +/* RFC4861, Section 4.6 */ +const bit<8> ICMP6_NDP_OPT_SOURCE_LL = 1; +const bit<8> ICMP6_NDP_OPT_TARGET_LL = 2; +const bit<8> ICMP6_NDP_OPT_PREFIX_INFO = 3; +const bit<8> ICMP6_NDP_OPT_REDIR_HEADER = 4; +const bit<8> ICMP6_NDP_OPT_MTU = 5; +/* Tasks from switch to controller - no RFC, internal */ const task_t TASK_ICMP6_NS = 1; const task_t TASK_ICMP6_GENERAL = 2; const task_t TASK_DEBUG = 3; @@ -119,6 +126,13 @@ header icmp6_na_ns_t { ipv6_addr_t target_addr; } +header icmp6_option_link_layer_addr_t { + bit<8> type; + bit<8> ll_length; + mac_addr_t mac_addr; +} + + header icmp_t { bit<8> type; bit<8> code; @@ -143,6 +157,7 @@ struct headers { cpu_t cpu; icmp6_t icmp6; icmp6_na_ns_t icmp6_na_ns; + icmp6_option_link_layer_addr_t icmp6_option_link_layer_addr; } struct metadata { diff --git a/p4src/parsers.p4 b/p4src/parsers.p4 index 44a11ae..aa330d5 100644 --- a/p4src/parsers.p4 +++ b/p4src/parsers.p4 @@ -55,9 +55,12 @@ parser MyParser(packet_in packet, } state icmp6_neighbor_solicitation { - packet.extract(hdr.icmp6_na_ns); - transition accept; + packet.extract(hdr.icmp6_na_ns); + /* BUG: This MIGHT fail */ + packet.extract(hdr.icmp6_option_link_layer_addr); + + transition accept; } diff --git a/p4src/static-mapping.p4 b/p4src/static-mapping.p4 index 2189c5a..993353f 100644 --- a/p4src/static-mapping.p4 +++ b/p4src/static-mapping.p4 @@ -42,23 +42,40 @@ control MyIngress(inout headers hdr, standard_metadata.mcast_grp = mcast_grp; } - action icmp6_neighbor_solicitation(ipv6_addr_t addr, mac_addr_t hwaddr) { + action icmp6_neighbor_solicitation(ipv6_addr_t addr, mac_addr_t mac_addr) { /* egress = ingress */ standard_metadata.egress_spec = standard_metadata.ingress_port; + /* 1. IPv6 changes */ hdr.ipv6.dst_addr = hdr.ipv6.src_addr; hdr.ipv6.src_addr = addr; + + /* 2. ICMP6 changes */ hdr.icmp6.type = ICMP6_NA; + hdr.icmp6.code = 0; + // checksum is calculated in deparser - /* ether + ipv6 + icmp6 */ - ipv6_addr_t tgt_addr = + /* 3. icmp6/neighbor advertisement: values taken from real world answers */ + hdr.icmp6_na_ns.router = 0; + hdr.icmp6_na_ns.solicitated = 1; + hdr.icmp6_na_ns.override = 1; + hdr.icmp6_na_ns.reserved = 0; + hdr.icmp6_na_ns.target_addr = addr; + /* 4. Link layer options */ + hdr.icmp6_option_link_layer_addr.type = ICMP6_NDP_OPT_TARGET_LL; + 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); hdr.icmp6_na.setValid(); hdr.icmp6_na.solicitated = 1; hdr.icmp6_na.override = 1; - + */ /* checksum trigger / content */ meta.do_cksum = 1;