256 lines
		
	
	
	
		
			6.8 KiB
		
	
	
	
		
			Text
		
	
	
	
	
	
		
		
			
		
	
	
			256 lines
		
	
	
	
		
			6.8 KiB
		
	
	
	
		
			Text
		
	
	
	
	
	
| 
								 | 
							
								/* -*- P4_16 -*- */
							 | 
						||
| 
								 | 
							
								#include <core.p4>
							 | 
						||
| 
								 | 
							
								#include <v1model.p4>
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								#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;
							 | 
						||
| 
								 | 
							
								        meta.ingress_port = standard_metadata.ingress_port;
							 | 
						||
| 
								 | 
							
								        clone3(CloneType.I2E, 100, meta);
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    action controller_reply(task_t task) {
							 | 
						||
| 
								 | 
							
								        meta.task = task;
							 | 
						||
| 
								 | 
							
								        meta.ingress_port = standard_metadata.ingress_port;
							 | 
						||
| 
								 | 
							
								        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;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    action icmp6_echo_reply() {
							 | 
						||
| 
								 | 
							
								        mac_addr_t mac_tmp = hdr.ethernet.dst_addr;
							 | 
						||
| 
								 | 
							
								        hdr.ethernet.dst_addr = hdr.ethernet.src_addr;
							 | 
						||
| 
								 | 
							
								        hdr.ethernet.src_addr = mac_tmp;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        ipv6_addr_t addr_tmp = hdr.ipv6.dst_addr;
							 | 
						||
| 
								 | 
							
								        hdr.ipv6.dst_addr = hdr.ipv6.src_addr;
							 | 
						||
| 
								 | 
							
								        hdr.ipv6.src_addr = addr_tmp;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        hdr.icmp6.type = ICMP6_ECHO_REPLY;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        meta.do_cksum = true;
							 | 
						||
| 
								 | 
							
								        meta.cast_length = (bit<32>) hdr.ipv6.payload_length;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    /* this needs SESSIONS!!
							 | 
						||
| 
								 | 
							
								    - icmp6: (src addr, dst addr, ID??, )
							 | 
						||
| 
								 | 
							
								    - tcp: (src port, dst port, dst_addr, src addr)
							 | 
						||
| 
								 | 
							
								    - udp: (src port, dst port, dst_addr, src addr)
							 | 
						||
| 
								 | 
							
								    */
							 | 
						||
| 
								 | 
							
								    // action nat64_static(ipv4_addr_t nataddr, ipv6_addr_t nat64_prefix) {
							 | 
						||
| 
								 | 
							
								    //     hdr.ipv4.dst_addr = hdr.ipv6.dst_addr - nat64_prefix;
							 | 
						||
| 
								 | 
							
								    //     hdr.ipv4.dst_addr = hdr.ipv6.dst_addr - nat64_prefix;
							 | 
						||
| 
								 | 
							
								    // }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    /********************** 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;
							 | 
						||
| 
								 | 
							
								            icmp6_echo_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.cpu.ingress_port = (bit<16>)meta.ingress_port;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								            hdr.ethernet.ethertype = TYPE_CPU;
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/*************************************************************************
							 | 
						||
| 
								 | 
							
								***********************  S W I T C H  *******************************
							 | 
						||
| 
								 | 
							
								*************************************************************************/
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								V1Switch(
							 | 
						||
| 
								 | 
							
								MyParser(),
							 | 
						||
| 
								 | 
							
								MyVerifyChecksum(),
							 | 
						||
| 
								 | 
							
								MyIngress(),
							 | 
						||
| 
								 | 
							
								MyEgress(),
							 | 
						||
| 
								 | 
							
								MyComputeChecksum(),
							 | 
						||
| 
								 | 
							
								MyDeparser()
							 | 
						||
| 
								 | 
							
								) main;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        //     truncate((bit<32>)22); //ether+cpu header
							 |