255 lines
		
	
	
	
		
			6.8 KiB
		
	
	
	
		
			Text
		
	
	
	
	
	
			
		
		
	
	
			255 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 = 1;
 | 
						|
    }
 | 
						|
 | 
						|
    /* 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
 |