/* -*- P4_16 -*- */ #include #include #include "headers.p4" #include "parsers.p4" #include "checksums.p4" #include "settings.p4" /************************************************************************* ************** I N G R E S S P R O C E S S I N G ******************* *************************************************************************/ control MyIngress(inout headers hdr, inout metadata meta, inout standard_metadata_t standard_metadata) { /********************** ACTIONS ***********************************/ /* As the name says */ action drop() { mark_to_drop(); } /* As the name says */ action send_to_controller() { clone3(CloneType.I2E, 100, meta); } /* Output PKG on correct ports (plural) */ action multicast_pkg(mcast_t mcast_grp) { standard_metadata.mcast_grp = mcast_grp; } action icmp6_neighbor_solicitation(ipv6_addr_t addr) { /* egress = ingress */ standard_metadata.egress_spec = standard_metadata.ingress_port; hdr.ipv6.dst_addr = hdr.ipv6.src_addr; hdr.ipv6.src_addr = addr; hdr.icmp6.type = ICMP6_NA; } /********************** Reply to NDP for US ***********************************/ table ndp_answer { key = { hdr.ipv6.dst_addr: exact; /* our multicast embedded mac address */ hdr.icmp6.type: exact; } actions = { send_to_controller; reply_icmp6_neighbor_solicitation; NoAction; } size = NDP_TABLE_SIZE; default_action = NoAction; } /********************** debugging / general support ***********************************/ table port2mcast { key = { standard_metadata.ingress_port : exact; } actions = { multicast_pkg; send_to_controller; NoAction; } size = NDP_TABLE_SIZE; default_action = NoAction; // default_action = send_to_controller; } /* Handle multicast registration of NDP */ table addr2mcast { key = { hdr.ipv6.dst_addr: exact; } actions = { multicast_pkg; send_to_controller; NoAction; } size = NDP_TABLE_SIZE; default_action = NoAction; // default_action = send_to_controller; } /********************** NDP support ***********************************/ table ndp { key = { hdr.ipv6.dst_addr: lpm; standard_metadata.ingress_port : exact; } actions = { multicast_pkg; send_to_controller; NoAction; } size = NDP_TABLE_SIZE; // default_action = NoAction; default_action = send_to_controller; } /********************** ADDRESS TABLES ***********************************/ action icmp6_answer() { if(hdr.icmp6.isValid()) { if(hdr.icmp6.code == ICMP6_ECHO_REQUEST) { ipv6_addr_t tmp = hdr.ipv6.src_addr; hdr.ipv6.src_addr = hdr.ipv6.dst_addr; hdr.ipv6.dst_addr = tmp; hdr.icmp6.code = ICMP6_ECHO_REPLY; } } /* do something: - change src/dst - change type */ } table v6_addresses { key = { hdr.ipv6.dst_addr: exact; // hdr.ipv6.next_header: exact; } actions = { icmp6_answer; send_to_controller; NoAction; } size = ADDRESS_TABLE_SIZE; // default_action = send_to_controller; default_action = NoAction; } /********************** ROUTING (egress definiton) TABLES ***********************************/ action set_egress_port (port_t out_port) { standard_metadata.egress_spec = out_port; } table v6_routing { key = { hdr.ipv6.dst_addr: lpm; } actions = { set_egress_port; NoAction; } size = ROUTING_TABLE_SIZE; default_action = NoAction; } table v4_routing { key = { hdr.ipv4.dst_addr: lpm; } actions = { set_egress_port; NoAction; } size = ROUTING_TABLE_SIZE; default_action = NoAction; } /********************** APPLYING TABLES ***********************************/ apply { if(hdr.ipv6.isValid()) { /* FIXME: structure / use .hit to do logic */ ndp_answer.apply(); ndp.apply(); /* flood or if it is us - answer */ v6_addresses.apply(); v6_routing.apply(); } if(hdr.ipv4.isValid()) { v4_routing.apply(); } } } /************************************************************************* **************** E G R E S S P R O C E S S I N G ******************* *************************************************************************/ control MyEgress(inout headers hdr, inout metadata meta, inout standard_metadata_t standard_metadata) { apply { /* set tcp header valid after modifying it -- keep this in mind*/ // hdr.tcp.setValid(); } } /************************************************************************* *********************** S W I T C H ******************************* *************************************************************************/ V1Switch( MyParser(), MyVerifyChecksum(), MyIngress(), MyEgress(), MyComputeChecksum(), MyDeparser() ) main;