/* -*- 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 ***********************************/ action drop() { mark_to_drop(); } action set_egress_port (port_t out_port) { standard_metadata.egress_spec = out_port; } action controller_debug() { meta.task = TASK_DEBUG; clone3(CloneType.I2E, 100, meta); } action controller_reply(task_t task) { meta.task = task; clone3(CloneType.I2E, 100, meta); } action multicast_pkg(mcast_t mcast_grp) { /* Output PKG on correct ports (plural) */ 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 = { controller_debug; 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; controller_debug; NoAction; } size = NDP_TABLE_SIZE; default_action = NoAction; // default_action = controller_debug; } /* Handle multicast registration of NDP */ table addr2mcast { key = { hdr.ipv6.dst_addr: exact; } actions = { multicast_pkg; controller_debug; NoAction; } size = NDP_TABLE_SIZE; default_action = NoAction; // default_action = controller_debug; } /********************** NDP support ***********************************/ table ndp { key = { hdr.ipv6.dst_addr: lpm; standard_metadata.ingress_port : exact; } actions = { multicast_pkg; controller_debug; NoAction; } size = NDP_TABLE_SIZE; // default_action = NoAction; default_action = controller_debug; } /********************** 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 */ } /********************** ROUTING (egress definiton) TABLES ***********************************/ table v6_addresses { key = { hdr.ipv6.dst_addr: exact; } actions = { controller_debug; controller_reply; NoAction; } size = ADDRESS_TABLE_SIZE; default_action = NoAction; } table v6_networks { key = { hdr.ipv6.dst_addr: lpm; } actions = { set_egress_port; controller_debug; controller_reply; NoAction; } size = ROUTING_TABLE_SIZE; default_action = NoAction; } table v4_networks { 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_networks.apply(); } if(hdr.ipv4.isValid()) { v4_networks.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 { // ingress clone if (standard_metadata.instance_type == 1){ hdr.cpu.setValid(); hdr.cpu.task = meta.task; hdr.cpu.ethertype = hdr.ethernet.ethertype; hdr.ethernet.ethertype = TYPE_CPU; } } } /************************************************************************* *********************** S W I T C H ******************************* *************************************************************************/ V1Switch( MyParser(), MyVerifyChecksum(), MyIngress(), MyEgress(), MyComputeChecksum(), MyDeparser() ) main; /* set tcp header valid after modifying it -- keep this in mind*/ // hdr.tcp.setValid(); // hdr.cpu.srcAddr = hdr.ethernet.srcAddr; // hdr.cpu.ingress_port = (bit<16>)meta.ingress_port; // truncate((bit<32>)22); //ether+cpu header