diff options
| author | 姜萍 <[email protected]> | 2020-04-10 12:02:56 +0800 |
|---|---|---|
| committer | 姜萍 <[email protected]> | 2020-04-10 12:02:56 +0800 |
| commit | 11f30017086bec9feff546608deea2a1ad6b10a9 (patch) | |
| tree | 53d0d9511e8772fa3f1f9fb5eb38a8a2e33704d0 /p4src | |
0410 commit
Diffstat (limited to 'p4src')
| -rw-r--r-- | p4src/.DS_Store | bin | 0 -> 6148 bytes | |||
| -rw-r--r-- | p4src/super_vlan_0409.p4 | 566 | ||||
| -rw-r--r-- | p4src/super_vlan_0410.p4 | 566 |
3 files changed, 1132 insertions, 0 deletions
diff --git a/p4src/.DS_Store b/p4src/.DS_Store Binary files differnew file mode 100644 index 0000000..12edfb5 --- /dev/null +++ b/p4src/.DS_Store diff --git a/p4src/super_vlan_0409.p4 b/p4src/super_vlan_0409.p4 new file mode 100644 index 0000000..638928d --- /dev/null +++ b/p4src/super_vlan_0409.p4 @@ -0,0 +1,566 @@ +/* -*- P4_16 -*- */ + +#include <core.p4> +#include <tna.p4> + +/************************************************************************* + ************* C O N S T A N T S A N D T Y P E S ******************* +*************************************************************************/ + +/* Header Stuff */ +enum bit<16> ether_type_t { + TPID = 0x8100, + IPV4 = 0x0800, + ARP = 0x0806, + IPV6 = 0x86DD, + MPLS = 0x8847 +} + +enum bit<8> ip_protocol_t { + ICMP = 1, + IGMP = 2, + TCP = 6, + UDP = 17 +} + +enum bit<16> arp_opcode_t { + REQUEST = 1, + REPLY = 2 +} + + +enum bit<8> icmp_type_t { + ECHO_REPLY = 0, + ECHO_REQUEST = 8 +} + +typedef bit<48> mac_addr_t; +typedef bit<32> ipv4_addr_t; + +/* Metadata and Table Stuff */ +const int IPV4_HOST_SIZE = 65536; +const int IPV4_LPM_SIZE = 12288; + +#define NEXTHOP_ID_WIDTH 14 +#define SUBVLAN_ID_WIDTH 12 +#define SUPERVLAN_ID_WIDTH 8 +typedef bit<NEXTHOP_ID_WIDTH> nexthop_id_t; +const int NEXTHOP_SIZE = 1 << NEXTHOP_ID_WIDTH; +typedef bit<SUBVLAN_ID_WIDTH> subvlan_id_t; +typedef bit<SUPERVLAN_ID_WIDTH> supervlan_id_t; +const int VLAN_SIZE = 512; + +/************************************************************************* + *********************** H E A D E R S ********************************* + *************************************************************************/ +/* Define all the headers the program will recognize */ +/* The actual sets of headers processed by each gress can differ */ + +/* Standard ethernet header */ +header ethernet_h { + mac_addr_t dst_addr; + mac_addr_t src_addr; + ether_type_t ether_type; +} + +header vlan_tag_h { + bit<3> pcp; + bit<1> cfi; + bit<12> vid; + ether_type_t ether_type; +} + +header ipv4_h { + bit<4> version; + bit<4> ihl; + bit<8> diffserv; + bit<16> total_len; + bit<16> identification; + bit<3> flags; + bit<13> frag_offset; + bit<8> ttl; + ip_protocol_t protocol; + bit<16> hdr_checksum; + ipv4_addr_t src_addr; + ipv4_addr_t dst_addr; +} + +header ipv4_options_h { + varbit<320> data; +} + +header icmp_h { + icmp_type_t msg_type; + bit<8> msg_code; + bit<16> checksum; +} + +header arp_h { + bit<16> hw_type; + ether_type_t proto_type; + bit<8> hw_addr_len; + bit<8> proto_addr_len; + arp_opcode_t opcode; +} + +header arp_ipv4_h { + mac_addr_t src_hw_addr; + ipv4_addr_t src_proto_addr; + mac_addr_t dst_hw_addr; + ipv4_addr_t dst_proto_addr; +} + + + +/************************************************************************* + ************** I N G R E S S P R O C E S S I N G ******************* + *************************************************************************/ + + /*********************** H E A D E R S ************************/ + +struct my_ingress_headers_t { + ethernet_h ethernet; + vlan_tag_h[2] vlan_tag; + arp_h arp; + arp_ipv4_h arp_ipv4; + ipv4_h ipv4; + icmp_h icmp; +} + + /****** G L O B A L I N G R E S S M E T A D A T A *********/ + +struct my_ingress_metadata_t { + ipv4_addr_t dst_ipv4; + mac_addr_t dst_mac; + subvlan_id_t src_subvid; + bit<1> ipv4_csum_err; +} + + /*********************** P A R S E R **************************/ + +parser IngressParser(packet_in pkt, + /* User */ + out my_ingress_headers_t hdr, + out my_ingress_metadata_t meta, + /* Intrinsic */ + out ingress_intrinsic_metadata_t ig_intr_md) +{ + Checksum() ipv4_checksum; + + /* This is a mandatory state, required by Tofino Architecture */ + state start { + pkt.extract(ig_intr_md); + pkt.advance(PORT_METADATA_SIZE); + transition meta_init; + } + + state meta_init { + meta.ipv4_csum_err = 0; + meta.dst_ipv4 = 0; + meta.dst_mac = 0; + transition parse_ethernet; + } + + state parse_ethernet { + pkt.extract(hdr.ethernet); + transition select(hdr.ethernet.ether_type) { + ether_type_t.TPID : parse_vlan_tag; + ether_type_t.IPV4 : parse_ipv4; + ether_type_t.ARP : parse_arp; + default: accept; + } + } + + state parse_vlan_tag { + pkt.extract(hdr.vlan_tag.next); + transition select(hdr.vlan_tag.last.ether_type) { + ether_type_t.TPID : parse_vlan_tag; + ether_type_t.IPV4 : parse_ipv4; + ether_type_t.ARP : parse_arp; + default: accept; + } + } + + state parse_ipv4 { + pkt.extract(hdr.ipv4); + meta.dst_ipv4 = hdr.ipv4.dst_addr; + + ipv4_checksum.add(hdr.ipv4); + meta.ipv4_csum_err = (bit<1>)ipv4_checksum.verify(); + + transition select( + hdr.ipv4.ihl, + hdr.ipv4.frag_offset, + hdr.ipv4.protocol) + { + (5, 0, ip_protocol_t.ICMP) : parse_icmp; + default: accept; + } + } + + state parse_icmp { + pkt.extract(hdr.icmp); + transition accept; + } + + state parse_arp { + pkt.extract(hdr.arp); + transition select(hdr.arp.hw_type, hdr.arp.proto_type) { + (0x0001, ether_type_t.IPV4) : parse_arp_ipv4; + default: reject; // Currently the same as accept + } + } + + state parse_arp_ipv4 { + pkt.extract(hdr.arp_ipv4); + meta.dst_ipv4 = hdr.arp_ipv4.dst_proto_addr; + transition accept; + } +} + + /***************** M A T C H - A C T I O N *********************/ + +control Ingress( + /* User */ + inout my_ingress_headers_t hdr, + inout my_ingress_metadata_t meta, + /* Intrinsic */ + in ingress_intrinsic_metadata_t ig_intr_md, + in ingress_intrinsic_metadata_from_parser_t ig_prsr_md, + inout ingress_intrinsic_metadata_for_deparser_t ig_dprsr_md, + inout ingress_intrinsic_metadata_for_tm_t ig_tm_md) +{ + nexthop_id_t nexthop_id = 0; + mac_addr_t mac_da = 0; + mac_addr_t mac_sa = 0; + PortId_t egress_port = 511; /* Non-existent port */ + bit<8> ttl_dec = 0; + subvlan_id_t tmp_vid = 0; + subvlan_id_t src_subvid = 0; + subvlan_id_t dst_subvid = 0; + supervlan_id_t src_supervid = 0; + supervlan_id_t dst_supervid = 0; + supervlan_id_t tmp_supervid = 0; + bool same_flag = false; + bool l3_flag = false; + bit<48> switch_mac = 0; + + action l2_switch(PortId_t port){ + egress_port = port; + mac_da = hdr.ethernet.dst_addr; + mac_sa = hdr.ethernet.src_addr; + ttl_dec = 0; + } + action set_l3_flag(){ + l3_flag = true; + } + + table is_l2_switch { + key = { + hdr.ethernet.dst_addr : exact; + } + actions = {l2_switch; set_l3_flag;@defaultonly NoAction;} + size = 512; + const default_action = NoAction(); + } + + + action set_trunk_port(PortId_t port){ + egress_port = port; + mac_da = hdr.ethernet.dst_addr; + mac_sa = hdr.ethernet.src_addr; + ttl_dec = 0; + } + action drop() { + ig_dprsr_md.drop_ctl = 1; + } + + table Trunk_switch{ + key = { + hdr.ethernet.dst_addr : exact; + } + actions = {set_trunk_port; drop;} + size = 512; + default_action = drop(); + } + + + action set_src_vid(subvlan_id_t subvid, supervlan_id_t supervid){ + meta.src_subvid = subvid; + src_supervid = supervid; + } + table Port_to_srcvid { + key = {ig_intr_md.ingress_port : exact;} + actions = {set_src_vid; @defaultonly NoAction; } + size = VLAN_SIZE; + const default_action = NoAction(); + } + + + action set_dst_vid(subvlan_id_t subvid, supervlan_id_t supervid){ + dst_subvid = subvid; + dst_supervid = supervid; + } + table dstIP_to_dstvid { + key = { + hdr.ipv4.dst_addr : exact; + } + actions = {set_dst_vid; @defaultonly NoAction; } + size = 512; + const default_action = NoAction(); + } + + + action set_super_MAC(bit<48> new_mac_switch){ + switch_mac = new_mac_switch; + } + table src_supervid_to_mac{ + key = { + src_supervid : exact; + } + actions = {set_super_MAC; @defaultonly NoAction; } + size = 512; + const default_action = NoAction(); + } + +/****************** IPv4 Lookup ********************/ + action set_nexthop(nexthop_id_t nexthop) { + nexthop_id = nexthop; + } + + table ipv4_host { + key = { + same_flag : exact; + hdr.ipv4.dst_addr : exact; + } + actions = { set_nexthop; @defaultonly NoAction; } + size = IPV4_HOST_SIZE; + const default_action = NoAction(); + } + + table ipv4_lpm { + key = { + same_flag : exact; + hdr.ipv4.dst_addr : lpm; + } + actions = { set_nexthop; } + + default_action = set_nexthop(0); + size = IPV4_LPM_SIZE; + } + + /****************** Nexthop ********************/ + action send(PortId_t port) { + mac_da = hdr.ethernet.dst_addr; + mac_sa = hdr.ethernet.src_addr; + egress_port = port; + ttl_dec = 0; + } + + action l3_switch(PortId_t port, bit<48> new_mac_da, bit<48> new_mac_sa) { + mac_da = new_mac_da; + mac_sa = new_mac_sa; /*目的ip对应的交换机MAC*/ + egress_port = port; + ttl_dec = 1; + } + + table nexthop { + key = { nexthop_id : exact; } + actions = { send; drop; l3_switch; } + size = NEXTHOP_SIZE; + default_action = drop(); + } + + /****************** Metadata Processing ********************/ + action send_back() { + ig_tm_md.ucast_egress_port = ig_intr_md.ingress_port; + } + + action forward_ipv4() { + hdr.ethernet.dst_addr = mac_da; + hdr.ethernet.src_addr = mac_sa; + hdr.ipv4.ttl = hdr.ipv4.ttl |-| ttl_dec; + ig_tm_md.ucast_egress_port = egress_port; + } + + action send_arp_reply_in() { + hdr.ethernet.dst_addr = hdr.arp_ipv4.src_hw_addr; + hdr.ethernet.src_addr = mac_da; /*ARP请求同一个sub_vlan中的主机MAC,把主机的真实MAC作为源MAC回复*/ + + hdr.arp.opcode = arp_opcode_t.REPLY; + hdr.arp_ipv4.dst_hw_addr = hdr.arp_ipv4.src_hw_addr; + hdr.arp_ipv4.dst_proto_addr = hdr.arp_ipv4.src_proto_addr; + hdr.arp_ipv4.src_hw_addr = mac_da; + hdr.arp_ipv4.src_proto_addr = meta.dst_ipv4; + + send_back(); + } + + action send_arp_reply_out() { + hdr.ethernet.dst_addr = hdr.arp_ipv4.src_hw_addr; + hdr.ethernet.src_addr = switch_mac; /*ARP请求不同sub_vlan中的主机MAC,把交换机的MAC作为源MAC回复*/ + + hdr.arp.opcode = arp_opcode_t.REPLY; + hdr.arp_ipv4.dst_hw_addr = hdr.arp_ipv4.src_hw_addr; + hdr.arp_ipv4.dst_proto_addr = hdr.arp_ipv4.src_proto_addr; + hdr.arp_ipv4.src_hw_addr = mac_sa; + hdr.arp_ipv4.src_proto_addr = meta.dst_ipv4; + + send_back(); + } + + table forward_or_respond { + key = { + same_flag : exact; + hdr.arp.isValid() : exact; + hdr.arp_ipv4.isValid() : exact; + hdr.ipv4.isValid() : exact; + hdr.arp.opcode : ternary; + } + actions = { + forward_ipv4; + send_arp_reply_in; + send_arp_reply_out; + drop; + } + const entries = { + (true, false, false, true, _) : + forward_ipv4(); + (false, false, false, true, _) : + forward_ipv4(); + (true, true, true, false, arp_opcode_t.REQUEST) : + send_arp_reply_in(); + (false, true, true, false, arp_opcode_t.REQUEST) : + send_arp_reply_out(); + } + default_action = drop(); + } + + apply{ + if(meta.ipv4_csum_err == 0){ + if(!is_l2_switch.apply().hit){ + Trunk_switch.apply(); + } + if(!l3_flag){ + same_flag = true; + } + if(!same_flag){ + Port_to_srcvid.apply(); + dstIP_to_dstvid.apply(); + if((src_supervid == dst_supervid)&&(meta.src_subvid == dst_subvid)){ + same_flag = true; + } + src_supervid_to_mac.apply(); + if (!ipv4_host.apply().hit) { + ipv4_lpm.apply(); + } + nexthop.apply(); + } + forward_or_respond.apply(); + } + } +} + + /********************* D E P A R S E R ************************/ + +control IngressDeparser(packet_out pkt, + /* User */ + inout my_ingress_headers_t hdr, + in my_ingress_metadata_t meta, + /* Intrinsic */ + in ingress_intrinsic_metadata_for_deparser_t ig_dprsr_md) +{ + Checksum() ipv4_checksum; + + apply { + hdr.ipv4.hdr_checksum = ipv4_checksum.update({ + hdr.ipv4.version, + hdr.ipv4.ihl, + hdr.ipv4.diffserv, + hdr.ipv4.total_len, + hdr.ipv4.identification, + hdr.ipv4.flags, + hdr.ipv4.frag_offset, + hdr.ipv4.ttl, + hdr.ipv4.protocol, + hdr.ipv4.src_addr, + hdr.ipv4.dst_addr + /* Adding hdr.ipv4_options.data results in an error */ + }); + pkt.emit(hdr); + } +} + + +/************************************************************************* + **************** E G R E S S P R O C E S S I N G ******************* + *************************************************************************/ + + /*********************** H E A D E R S ************************/ + +struct my_egress_headers_t { +} + + /******** G L O B A L E G R E S S M E T A D A T A *********/ + +struct my_egress_metadata_t { +} + + /*********************** P A R S E R **************************/ + +parser EgressParser(packet_in pkt, + /* User */ + out my_egress_headers_t hdr, + out my_egress_metadata_t meta, + /* Intrinsic */ + out egress_intrinsic_metadata_t eg_intr_md) +{ + /* This is a mandatory state, required by Tofino Architecture */ + state start { + pkt.extract(eg_intr_md); + transition accept; + } +} + + /***************** M A T C H - A C T I O N *********************/ + +control Egress( + /* User */ + inout my_egress_headers_t hdr, + inout my_egress_metadata_t meta, + /* Intrinsic */ + in egress_intrinsic_metadata_t eg_intr_md, + in egress_intrinsic_metadata_from_parser_t eg_prsr_md, + inout egress_intrinsic_metadata_for_deparser_t eg_dprsr_md, + inout egress_intrinsic_metadata_for_output_port_t eg_oport_md) +{ + apply { + } +} + + /********************* D E P A R S E R ************************/ + +control EgressDeparser(packet_out pkt, + /* User */ + inout my_egress_headers_t hdr, + in my_egress_metadata_t meta, + /* Intrinsic */ + in egress_intrinsic_metadata_for_deparser_t eg_dprsr_md) +{ + apply { + pkt.emit(hdr); + } +} + + +/************ F I N A L P A C K A G E ******************************/ +Pipeline( + IngressParser(), + Ingress(), + IngressDeparser(), + EgressParser(), + Egress(), + EgressDeparser() +) pipe; + +Switch(pipe) main; diff --git a/p4src/super_vlan_0410.p4 b/p4src/super_vlan_0410.p4 new file mode 100644 index 0000000..1a2da7d --- /dev/null +++ b/p4src/super_vlan_0410.p4 @@ -0,0 +1,566 @@ +/* -*- P4_16 -*- */ + +#include <core.p4> +#include <tna.p4> + +/************************************************************************* + ************* C O N S T A N T S A N D T Y P E S ******************* +*************************************************************************/ + +/* Header Stuff */ +enum bit<16> ether_type_t { + TPID = 0x8100, + IPV4 = 0x0800, + ARP = 0x0806, + IPV6 = 0x86DD, + MPLS = 0x8847 +} + +enum bit<8> ip_protocol_t { + ICMP = 1, + IGMP = 2, + TCP = 6, + UDP = 17 +} + +enum bit<16> arp_opcode_t { + REQUEST = 1, + REPLY = 2 +} + + +enum bit<8> icmp_type_t { + ECHO_REPLY = 0, + ECHO_REQUEST = 8 +} + +typedef bit<48> mac_addr_t; +typedef bit<32> ipv4_addr_t; + +/* Metadata and Table Stuff */ +const int IPV4_HOST_SIZE = 65536; +const int IPV4_LPM_SIZE = 12288; + +#define NEXTHOP_ID_WIDTH 14 +#define SUBVLAN_ID_WIDTH 12 +#define SUPERVLAN_ID_WIDTH 8 +typedef bit<NEXTHOP_ID_WIDTH> nexthop_id_t; +const int NEXTHOP_SIZE = 1 << NEXTHOP_ID_WIDTH; +typedef bit<SUBVLAN_ID_WIDTH> subvlan_id_t; +typedef bit<SUPERVLAN_ID_WIDTH> supervlan_id_t; +const int VLAN_SIZE = 512; + +/************************************************************************* + *********************** H E A D E R S ********************************* + *************************************************************************/ +/* Define all the headers the program will recognize */ +/* The actual sets of headers processed by each gress can differ */ + +/* Standard ethernet header */ +header ethernet_h { + mac_addr_t dst_addr; + mac_addr_t src_addr; + ether_type_t ether_type; +} + +header vlan_tag_h { + bit<3> pcp; + bit<1> cfi; + bit<12> vid; + ether_type_t ether_type; +} + +header ipv4_h { + bit<4> version; + bit<4> ihl; + bit<8> diffserv; + bit<16> total_len; + bit<16> identification; + bit<3> flags; + bit<13> frag_offset; + bit<8> ttl; + ip_protocol_t protocol; + bit<16> hdr_checksum; + ipv4_addr_t src_addr; + ipv4_addr_t dst_addr; +} + +header ipv4_options_h { + varbit<320> data; +} + +header icmp_h { + icmp_type_t msg_type; + bit<8> msg_code; + bit<16> checksum; +} + +header arp_h { + bit<16> hw_type; + ether_type_t proto_type; + bit<8> hw_addr_len; + bit<8> proto_addr_len; + arp_opcode_t opcode; +} + +header arp_ipv4_h { + mac_addr_t src_hw_addr; + ipv4_addr_t src_proto_addr; + mac_addr_t dst_hw_addr; + ipv4_addr_t dst_proto_addr; +} + + + +/************************************************************************* + ************** I N G R E S S P R O C E S S I N G ******************* + *************************************************************************/ + + /*********************** H E A D E R S ************************/ + +struct my_ingress_headers_t { + ethernet_h ethernet; + vlan_tag_h[2] vlan_tag; + arp_h arp; + arp_ipv4_h arp_ipv4; + ipv4_h ipv4; + icmp_h icmp; +} + + /****** G L O B A L I N G R E S S M E T A D A T A *********/ + +struct my_ingress_metadata_t { + ipv4_addr_t dst_ipv4; + mac_addr_t dst_mac; + subvlan_id_t src_subvid; + bit<1> ipv4_csum_err; +} + + /*********************** P A R S E R **************************/ + +parser IngressParser(packet_in pkt, + /* User */ + out my_ingress_headers_t hdr, + out my_ingress_metadata_t meta, + /* Intrinsic */ + out ingress_intrinsic_metadata_t ig_intr_md) +{ + Checksum() ipv4_checksum; + + /* This is a mandatory state, required by Tofino Architecture */ + state start { + pkt.extract(ig_intr_md); + pkt.advance(PORT_METADATA_SIZE); + transition meta_init; + } + + state meta_init { + meta.ipv4_csum_err = 0; + meta.dst_ipv4 = 0; + meta.dst_mac = 0; + transition parse_ethernet; + } + + state parse_ethernet { + pkt.extract(hdr.ethernet); + transition select(hdr.ethernet.ether_type) { + ether_type_t.TPID : parse_vlan_tag; + ether_type_t.IPV4 : parse_ipv4; + ether_type_t.ARP : parse_arp; + default: accept; + } + } + + state parse_vlan_tag { + pkt.extract(hdr.vlan_tag.next); + transition select(hdr.vlan_tag.last.ether_type) { + ether_type_t.TPID : parse_vlan_tag; + ether_type_t.IPV4 : parse_ipv4; + ether_type_t.ARP : parse_arp; + default: accept; + } + } + + state parse_ipv4 { + pkt.extract(hdr.ipv4); + meta.dst_ipv4 = hdr.ipv4.dst_addr; + + ipv4_checksum.add(hdr.ipv4); + meta.ipv4_csum_err = (bit<1>)ipv4_checksum.verify(); + + transition select( + hdr.ipv4.ihl, + hdr.ipv4.frag_offset, + hdr.ipv4.protocol) + { + (5, 0, ip_protocol_t.ICMP) : parse_icmp; + default: accept; + } + } + + state parse_icmp { + pkt.extract(hdr.icmp); + transition accept; + } + + state parse_arp { + pkt.extract(hdr.arp); + transition select(hdr.arp.hw_type, hdr.arp.proto_type) { + (0x0001, ether_type_t.IPV4) : parse_arp_ipv4; + default: reject; // Currently the same as accept + } + } + + state parse_arp_ipv4 { + pkt.extract(hdr.arp_ipv4); + meta.dst_ipv4 = hdr.arp_ipv4.dst_proto_addr; + transition accept; + } +} + + /***************** M A T C H - A C T I O N *********************/ + +control Ingress( + /* User */ + inout my_ingress_headers_t hdr, + inout my_ingress_metadata_t meta, + /* Intrinsic */ + in ingress_intrinsic_metadata_t ig_intr_md, + in ingress_intrinsic_metadata_from_parser_t ig_prsr_md, + inout ingress_intrinsic_metadata_for_deparser_t ig_dprsr_md, + inout ingress_intrinsic_metadata_for_tm_t ig_tm_md) +{ + nexthop_id_t nexthop_id = 0; + mac_addr_t mac_da = 0; + mac_addr_t mac_sa = 0; + PortId_t egress_port = 511; /* Non-existent port */ + bit<8> ttl_dec = 0; + subvlan_id_t tmp_vid = 0; + subvlan_id_t src_subvid = 0; + subvlan_id_t dst_subvid = 0; + supervlan_id_t src_supervid = 0; + supervlan_id_t dst_supervid = 0; + supervlan_id_t tmp_supervid = 0; + bool same_flag = false; + bool l3_flag = false; + bit<48> switch_mac = 0; + + action l2_switch(PortId_t port){ + egress_port = port; + mac_da = hdr.ethernet.dst_addr; + mac_sa = hdr.ethernet.src_addr; + ttl_dec = 0; + } + action set_l3_flag(){ + l3_flag = true; + } + + table is_l2_switch { + key = { + hdr.ethernet.dst_addr : exact; + } + actions = {l2_switch; set_l3_flag;@defaultonly NoAction;} + size = 512; + const default_action = NoAction(); + } + + + action set_trunk_port(PortId_t port){ + egress_port = port; + mac_da = hdr.ethernet.dst_addr; + mac_sa = hdr.ethernet.src_addr; + ttl_dec = 0; + } + action drop() { + ig_dprsr_md.drop_ctl = 1; + } + + table Trunk_switch{ + key = { + hdr.ethernet.dst_addr : exact; + } + actions = {set_trunk_port; drop;} + size = 512; + default_action = drop(); + } + + + action set_src_vid(subvlan_id_t subvid, supervlan_id_t supervid){ + meta.src_subvid = subvid; + src_supervid = supervid; + } + table Port_to_srcvid { + key = {ig_intr_md.ingress_port : exact;} + actions = {set_src_vid; @defaultonly NoAction; } + size = VLAN_SIZE; + const default_action = NoAction(); + } + + + action set_dst_vid(subvlan_id_t subvid, supervlan_id_t supervid){ + dst_subvid = subvid; + dst_supervid = supervid; + } + table dstIP_to_dstvid { + key = { + meta.dst_ipv4 : exact; + } + actions = {set_dst_vid; @defaultonly NoAction; } + size = 512; + const default_action = NoAction(); + } + + + action set_super_MAC(bit<48> new_mac_switch){ + switch_mac = new_mac_switch; + } + table src_supervid_to_mac{ + key = { + src_supervid : exact; + } + actions = {set_super_MAC; @defaultonly NoAction; } + size = 512; + const default_action = NoAction(); + } + +/****************** IPv4 Lookup ********************/ + action set_nexthop(nexthop_id_t nexthop) { + nexthop_id = nexthop; + } + + table ipv4_host { + key = { + same_flag : exact; + meta.dst_ipv4 : exact; + } + actions = { set_nexthop; @defaultonly NoAction; } + size = IPV4_HOST_SIZE; + const default_action = NoAction(); + } + + table ipv4_lpm { + key = { + same_flag : exact; + meta.dst_ipv4 : lpm; + } + actions = { set_nexthop; } + + default_action = set_nexthop(0); + size = IPV4_LPM_SIZE; + } + + /****************** Nexthop ********************/ + action send(PortId_t port) { + mac_da = hdr.ethernet.dst_addr; + mac_sa = hdr.ethernet.src_addr; + egress_port = port; + ttl_dec = 0; + } + + action l3_switch(PortId_t port, bit<48> new_mac_da, bit<48> new_mac_sa) { + mac_da = new_mac_da; + mac_sa = new_mac_sa; /*目的ip对应的交换机MAC*/ + egress_port = port; + ttl_dec = 1; + } + + table nexthop { + key = { nexthop_id : exact; } + actions = { send; drop; l3_switch; } + size = NEXTHOP_SIZE; + default_action = drop(); + } + + /****************** Metadata Processing ********************/ + action send_back() { + ig_tm_md.ucast_egress_port = ig_intr_md.ingress_port; + } + + action forward_ipv4() { + hdr.ethernet.dst_addr = mac_da; + hdr.ethernet.src_addr = mac_sa; + hdr.ipv4.ttl = hdr.ipv4.ttl |-| ttl_dec; + ig_tm_md.ucast_egress_port = egress_port; + } + + action send_arp_reply_in() { + hdr.ethernet.dst_addr = hdr.arp_ipv4.src_hw_addr; + hdr.ethernet.src_addr = mac_da; /*ARP请求同一个sub_vlan中的主机MAC,把主机的真实MAC作为源MAC回复*/ + + hdr.arp.opcode = arp_opcode_t.REPLY; + hdr.arp_ipv4.dst_hw_addr = hdr.arp_ipv4.src_hw_addr; + hdr.arp_ipv4.dst_proto_addr = hdr.arp_ipv4.src_proto_addr; + hdr.arp_ipv4.src_hw_addr = mac_da; + hdr.arp_ipv4.src_proto_addr = meta.dst_ipv4; + + send_back(); + } + + action send_arp_reply_out() { + hdr.ethernet.dst_addr = hdr.arp_ipv4.src_hw_addr; + hdr.ethernet.src_addr = switch_mac; /*ARP请求不同sub_vlan中的主机MAC,把交换机的MAC作为源MAC回复*/ + + hdr.arp.opcode = arp_opcode_t.REPLY; + hdr.arp_ipv4.dst_hw_addr = hdr.arp_ipv4.src_hw_addr; + hdr.arp_ipv4.dst_proto_addr = hdr.arp_ipv4.src_proto_addr; + hdr.arp_ipv4.src_hw_addr = mac_sa; + hdr.arp_ipv4.src_proto_addr = meta.dst_ipv4; + + send_back(); + } + + table forward_or_respond { + key = { + same_flag : exact; + hdr.arp.isValid() : exact; + hdr.arp_ipv4.isValid() : exact; + hdr.ipv4.isValid() : exact; + hdr.arp.opcode : ternary; + } + actions = { + forward_ipv4; + send_arp_reply_in; + send_arp_reply_out; + drop; + } + const entries = { + (true, false, false, true, _) : + forward_ipv4(); + (false, false, false, true, _) : + forward_ipv4(); + (true, true, true, false, arp_opcode_t.REQUEST) : + send_arp_reply_in(); + (false, true, true, false, arp_opcode_t.REQUEST) : + send_arp_reply_out(); + } + default_action = drop(); + } + + apply{ + if(meta.ipv4_csum_err == 0){ + if(!is_l2_switch.apply().hit){ + Trunk_switch.apply(); + } + if(!l3_flag){ + same_flag = true; + } + if(!same_flag){ + Port_to_srcvid.apply(); + dstIP_to_dstvid.apply(); + if((src_supervid == dst_supervid)&&(meta.src_subvid == dst_subvid)){ + same_flag = true; + } + src_supervid_to_mac.apply(); + if (!ipv4_host.apply().hit) { + ipv4_lpm.apply(); + } + nexthop.apply(); + } + forward_or_respond.apply(); + } + } +} + + /********************* D E P A R S E R ************************/ + +control IngressDeparser(packet_out pkt, + /* User */ + inout my_ingress_headers_t hdr, + in my_ingress_metadata_t meta, + /* Intrinsic */ + in ingress_intrinsic_metadata_for_deparser_t ig_dprsr_md) +{ + Checksum() ipv4_checksum; + + apply { + hdr.ipv4.hdr_checksum = ipv4_checksum.update({ + hdr.ipv4.version, + hdr.ipv4.ihl, + hdr.ipv4.diffserv, + hdr.ipv4.total_len, + hdr.ipv4.identification, + hdr.ipv4.flags, + hdr.ipv4.frag_offset, + hdr.ipv4.ttl, + hdr.ipv4.protocol, + hdr.ipv4.src_addr, + hdr.ipv4.dst_addr + /* Adding hdr.ipv4_options.data results in an error */ + }); + pkt.emit(hdr); + } +} + + +/************************************************************************* + **************** E G R E S S P R O C E S S I N G ******************* + *************************************************************************/ + + /*********************** H E A D E R S ************************/ + +struct my_egress_headers_t { +} + + /******** G L O B A L E G R E S S M E T A D A T A *********/ + +struct my_egress_metadata_t { +} + + /*********************** P A R S E R **************************/ + +parser EgressParser(packet_in pkt, + /* User */ + out my_egress_headers_t hdr, + out my_egress_metadata_t meta, + /* Intrinsic */ + out egress_intrinsic_metadata_t eg_intr_md) +{ + /* This is a mandatory state, required by Tofino Architecture */ + state start { + pkt.extract(eg_intr_md); + transition accept; + } +} + + /***************** M A T C H - A C T I O N *********************/ + +control Egress( + /* User */ + inout my_egress_headers_t hdr, + inout my_egress_metadata_t meta, + /* Intrinsic */ + in egress_intrinsic_metadata_t eg_intr_md, + in egress_intrinsic_metadata_from_parser_t eg_prsr_md, + inout egress_intrinsic_metadata_for_deparser_t eg_dprsr_md, + inout egress_intrinsic_metadata_for_output_port_t eg_oport_md) +{ + apply { + } +} + + /********************* D E P A R S E R ************************/ + +control EgressDeparser(packet_out pkt, + /* User */ + inout my_egress_headers_t hdr, + in my_egress_metadata_t meta, + /* Intrinsic */ + in egress_intrinsic_metadata_for_deparser_t eg_dprsr_md) +{ + apply { + pkt.emit(hdr); + } +} + + +/************ F I N A L P A C K A G E ******************************/ +Pipeline( + IngressParser(), + Ingress(), + IngressDeparser(), + EgressParser(), + Egress(), + EgressDeparser() +) pipe; + +Switch(pipe) main; |
