|
| 1 | +#include <core.p4> |
| 2 | +#include <v1model.p4> |
| 3 | + |
| 4 | +struct ingress_metadata_t { |
| 5 | + bit<32> flow_ipg; |
| 6 | + bit<13> flowlet_map_index; |
| 7 | + bit<16> flowlet_id; |
| 8 | + bit<32> flowlet_lasttime; |
| 9 | + bit<14> ecmp_offset; |
| 10 | + bit<32> nhop_ipv4; |
| 11 | +} |
| 12 | + |
| 13 | +struct intrinsic_metadata_t { |
| 14 | + bit<48> ingress_global_timestamp; |
| 15 | + bit<32> lf_field_list; |
| 16 | + bit<16> mcast_grp; |
| 17 | + bit<16> egress_rid; |
| 18 | +} |
| 19 | + |
| 20 | +header ethernet_t { |
| 21 | + bit<48> dstAddr; |
| 22 | + bit<48> srcAddr; |
| 23 | + bit<16> etherType; |
| 24 | +} |
| 25 | + |
| 26 | +header ipv4_t { |
| 27 | + bit<4> version; |
| 28 | + bit<4> ihl; |
| 29 | + bit<8> diffserv; |
| 30 | + bit<16> totalLen; |
| 31 | + bit<16> identification; |
| 32 | + bit<3> flags; |
| 33 | + bit<13> fragOffset; |
| 34 | + bit<8> ttl; |
| 35 | + bit<8> protocol; |
| 36 | + bit<16> hdrChecksum; |
| 37 | + bit<32> srcAddr; |
| 38 | + bit<32> dstAddr; |
| 39 | +} |
| 40 | + |
| 41 | +header tcp_t { |
| 42 | + bit<16> srcPort; |
| 43 | + bit<16> dstPort; |
| 44 | + bit<32> seqNo; |
| 45 | + bit<32> ackNo; |
| 46 | + bit<4> dataOffset; |
| 47 | + bit<3> res; |
| 48 | + bit<3> ecn; |
| 49 | + bit<6> ctrl; |
| 50 | + bit<16> window; |
| 51 | + bit<16> checksum; |
| 52 | + bit<16> urgentPtr; |
| 53 | +} |
| 54 | + |
| 55 | +struct metadata { |
| 56 | + @name("ingress_metadata") |
| 57 | + ingress_metadata_t ingress_metadata; |
| 58 | + @name("intrinsic_metadata") |
| 59 | + intrinsic_metadata_t intrinsic_metadata; |
| 60 | +} |
| 61 | + |
| 62 | +struct headers { |
| 63 | + @name("ethernet") |
| 64 | + ethernet_t ethernet; |
| 65 | + @name("ipv4") |
| 66 | + ipv4_t ipv4; |
| 67 | + @name("tcp") |
| 68 | + tcp_t tcp; |
| 69 | +} |
| 70 | + |
| 71 | +parser ParserImpl(packet_in packet, out headers hdr, inout metadata meta, inout standard_metadata_t standard_metadata) { |
| 72 | + @name("parse_ethernet") state parse_ethernet { |
| 73 | + packet.extract(hdr.ethernet); |
| 74 | + transition select(hdr.ethernet.etherType) { |
| 75 | + 16w0x800: parse_ipv4; |
| 76 | + default: accept; |
| 77 | + } |
| 78 | + } |
| 79 | + @name("parse_ipv4") state parse_ipv4 { |
| 80 | + packet.extract(hdr.ipv4); |
| 81 | + transition select(hdr.ipv4.protocol) { |
| 82 | + 8w6: parse_tcp; |
| 83 | + default: accept; |
| 84 | + } |
| 85 | + } |
| 86 | + @name("parse_tcp") state parse_tcp { |
| 87 | + packet.extract(hdr.tcp); |
| 88 | + transition accept; |
| 89 | + } |
| 90 | + @name("start") state start { |
| 91 | + transition parse_ethernet; |
| 92 | + } |
| 93 | +} |
| 94 | + |
| 95 | +control egress(inout headers hdr, inout metadata meta, inout standard_metadata_t standard_metadata) { |
| 96 | + @name("rewrite_mac") action rewrite_mac(bit<48> smac) { |
| 97 | + hdr.ethernet.srcAddr = smac; |
| 98 | + } |
| 99 | + @name("_drop") action _drop() { |
| 100 | + mark_to_drop(); |
| 101 | + } |
| 102 | + @name("send_frame") table send_frame() { |
| 103 | + actions = { |
| 104 | + rewrite_mac; |
| 105 | + _drop; |
| 106 | + NoAction; |
| 107 | + } |
| 108 | + key = { |
| 109 | + standard_metadata.egress_port: exact; |
| 110 | + } |
| 111 | + size = 256; |
| 112 | + default_action = NoAction(); |
| 113 | + } |
| 114 | + apply { |
| 115 | + send_frame.apply(); |
| 116 | + } |
| 117 | +} |
| 118 | + |
| 119 | +control ingress(inout headers hdr, inout metadata meta, inout standard_metadata_t standard_metadata) { |
| 120 | + @name("flowlet_id") register<bit<16>>(32w8192) flowlet_id; |
| 121 | + @name("flowlet_lasttime") register<bit<32>>(32w8192) flowlet_lasttime; |
| 122 | + @name("_drop") action _drop() { |
| 123 | + mark_to_drop(); |
| 124 | + } |
| 125 | + @name("set_ecmp_select") action set_ecmp_select(bit<8> ecmp_base, bit<8> ecmp_count) { |
| 126 | + hash(meta.ingress_metadata.ecmp_offset, HashAlgorithm.crc16, (bit<10>)ecmp_base, { hdr.ipv4.srcAddr, hdr.ipv4.dstAddr, hdr.ipv4.protocol, hdr.tcp.srcPort, hdr.tcp.dstPort, meta.ingress_metadata.flowlet_id }, (bit<20>)ecmp_count); |
| 127 | + } |
| 128 | + @name("set_nhop") action set_nhop(bit<32> nhop_ipv4, bit<9> port) { |
| 129 | + meta.ingress_metadata.nhop_ipv4 = nhop_ipv4; |
| 130 | + standard_metadata.egress_spec = port; |
| 131 | + hdr.ipv4.ttl = hdr.ipv4.ttl + 8w255; |
| 132 | + } |
| 133 | + @name("lookup_flowlet_map") action lookup_flowlet_map() { |
| 134 | + hash(meta.ingress_metadata.flowlet_map_index, HashAlgorithm.crc16, (bit<13>)0, { hdr.ipv4.srcAddr, hdr.ipv4.dstAddr, hdr.ipv4.protocol, hdr.tcp.srcPort, hdr.tcp.dstPort }, (bit<26>)13); |
| 135 | + flowlet_id.read(meta.ingress_metadata.flowlet_id, (bit<32>)meta.ingress_metadata.flowlet_map_index); |
| 136 | + meta.ingress_metadata.flow_ipg = meta.intrinsic_metadata.ingress_global_timestamp; |
| 137 | + flowlet_lasttime.read(meta.ingress_metadata.flowlet_lasttime, (bit<32>)meta.ingress_metadata.flowlet_map_index); |
| 138 | + meta.ingress_metadata.flow_ipg = meta.ingress_metadata.flow_ipg - meta.ingress_metadata.flowlet_lasttime; |
| 139 | + flowlet_lasttime.write((bit<32>)meta.ingress_metadata.flowlet_map_index, (bit<32>)meta.intrinsic_metadata.ingress_global_timestamp); |
| 140 | + } |
| 141 | + @name("set_dmac") action set_dmac(bit<48> dmac) { |
| 142 | + hdr.ethernet.dstAddr = dmac; |
| 143 | + } |
| 144 | + @name("update_flowlet_id") action update_flowlet_id() { |
| 145 | + meta.ingress_metadata.flowlet_id = meta.ingress_metadata.flowlet_id + 16w1; |
| 146 | + flowlet_id.write((bit<32>)meta.ingress_metadata.flowlet_map_index, (bit<16>)meta.ingress_metadata.flowlet_id); |
| 147 | + } |
| 148 | + @name("ecmp_group") table ecmp_group() { |
| 149 | + actions = { |
| 150 | + _drop; |
| 151 | + set_ecmp_select; |
| 152 | + NoAction; |
| 153 | + } |
| 154 | + key = { |
| 155 | + hdr.ipv4.dstAddr: lpm; |
| 156 | + } |
| 157 | + size = 1024; |
| 158 | + default_action = NoAction(); |
| 159 | + } |
| 160 | + @name("ecmp_nhop") table ecmp_nhop() { |
| 161 | + actions = { |
| 162 | + _drop; |
| 163 | + set_nhop; |
| 164 | + NoAction; |
| 165 | + } |
| 166 | + key = { |
| 167 | + meta.ingress_metadata.ecmp_offset: exact; |
| 168 | + } |
| 169 | + size = 16384; |
| 170 | + default_action = NoAction(); |
| 171 | + } |
| 172 | + @name("flowlet") table flowlet() { |
| 173 | + actions = { |
| 174 | + lookup_flowlet_map; |
| 175 | + NoAction; |
| 176 | + } |
| 177 | + default_action = NoAction(); |
| 178 | + } |
| 179 | + @name("forward") table forward() { |
| 180 | + actions = { |
| 181 | + set_dmac; |
| 182 | + _drop; |
| 183 | + NoAction; |
| 184 | + } |
| 185 | + key = { |
| 186 | + meta.ingress_metadata.nhop_ipv4: exact; |
| 187 | + } |
| 188 | + size = 512; |
| 189 | + default_action = NoAction(); |
| 190 | + } |
| 191 | + @name("new_flowlet") table new_flowlet() { |
| 192 | + actions = { |
| 193 | + update_flowlet_id; |
| 194 | + NoAction; |
| 195 | + } |
| 196 | + default_action = NoAction(); |
| 197 | + } |
| 198 | + apply { |
| 199 | + @atomic { |
| 200 | + flowlet.apply(); |
| 201 | + if (meta.ingress_metadata.flow_ipg > 32w50000) |
| 202 | + new_flowlet.apply(); |
| 203 | + } |
| 204 | + ecmp_group.apply(); |
| 205 | + ecmp_nhop.apply(); |
| 206 | + forward.apply(); |
| 207 | + } |
| 208 | +} |
| 209 | + |
| 210 | +control DeparserImpl(packet_out packet, in headers hdr) { |
| 211 | + apply { |
| 212 | + packet.emit(hdr.ethernet); |
| 213 | + packet.emit(hdr.ipv4); |
| 214 | + packet.emit(hdr.tcp); |
| 215 | + } |
| 216 | +} |
| 217 | + |
| 218 | +control verifyChecksum(in headers hdr, inout metadata meta, inout standard_metadata_t standard_metadata) { |
| 219 | + Checksum16() ipv4_checksum; |
| 220 | + apply { |
| 221 | + if (hdr.ipv4.hdrChecksum == ipv4_checksum.get({ hdr.ipv4.version, hdr.ipv4.ihl, hdr.ipv4.diffserv, hdr.ipv4.totalLen, hdr.ipv4.identification, hdr.ipv4.flags, hdr.ipv4.fragOffset, hdr.ipv4.ttl, hdr.ipv4.protocol, hdr.ipv4.srcAddr, hdr.ipv4.dstAddr })) |
| 222 | + mark_to_drop(); |
| 223 | + } |
| 224 | +} |
| 225 | + |
| 226 | +control computeChecksum(inout headers hdr, inout metadata meta, inout standard_metadata_t standard_metadata) { |
| 227 | + Checksum16() ipv4_checksum; |
| 228 | + apply { |
| 229 | + hdr.ipv4.hdrChecksum = ipv4_checksum.get({ hdr.ipv4.version, hdr.ipv4.ihl, hdr.ipv4.diffserv, hdr.ipv4.totalLen, hdr.ipv4.identification, hdr.ipv4.flags, hdr.ipv4.fragOffset, hdr.ipv4.ttl, hdr.ipv4.protocol, hdr.ipv4.srcAddr, hdr.ipv4.dstAddr }); |
| 230 | + } |
| 231 | +} |
| 232 | + |
| 233 | +V1Switch(ParserImpl(), verifyChecksum(), ingress(), egress(), computeChecksum(), DeparserImpl()) main; |
0 commit comments