blob: 7146cd2e8a66f0e6cc88539114d0675fba295f79 [file] [log] [blame]
Carmelo Casconec8d34862017-07-30 00:48:23 -04001/*
Brian O'Connora09fe5b2017-08-03 21:12:30 -07002 * Copyright 2017-present Open Networking Foundation
Carmelo Casconec8d34862017-07-30 00:48:23 -04003 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
Yi Tseng21629932017-06-06 11:17:43 -070017#include <core.p4>
18#include <v1model.p4>
19#include "include/defines.p4"
20#include "include/headers.p4"
Carmelo Cascone3304fd52017-07-30 00:43:01 -040021
22typedef bit<16> group_id_t;
Carmelo Casconeeb018122017-09-06 13:16:03 +020023
24/*
25 Expected number of ports of an ECMP group.
26 This value is fixed, .i.e. we do not support ECMP over port groups of different size.
27 Due to hardware limitations, this value must be constant and a power of 2.
28*/
29#define ECMP_GROUP_SIZE 128w2
Carmelo Cascone3304fd52017-07-30 00:43:01 -040030
31struct ecmp_metadata_t {
32 group_id_t group_id;
33 bit<16> selector;
34}
35
36struct metadata_t {
37 ecmp_metadata_t ecmp_metadata;
38 intrinsic_metadata_t intrinsic_metadata;
39}
40
Yi Tseng21629932017-06-06 11:17:43 -070041#include "include/parsers.p4"
42#include "include/port_counters.p4"
43#include "include/checksums.p4"
44#include "include/actions.p4"
Carmelo Cascone837e6452017-07-19 20:35:22 -040045#include "include/packet_io.p4"
Yi Tseng21629932017-06-06 11:17:43 -070046
47
Carmelo Cascone837e6452017-07-19 20:35:22 -040048control ingress(inout headers_t hdr, inout metadata_t meta, inout standard_metadata_t standard_metadata) {
49
Yi Tseng21629932017-06-06 11:17:43 -070050 direct_counter(CounterType.packets) ecmp_group_table_counter;
51 direct_counter(CounterType.packets) table0_counter;
52
Carmelo Casconeeb018122017-09-06 13:16:03 +020053 action ecmp_group(group_id_t group_id) {
Carmelo Cascone837e6452017-07-19 20:35:22 -040054 meta.ecmp_metadata.group_id = group_id;
Carmelo Casconeeb018122017-09-06 13:16:03 +020055 hash(meta.ecmp_metadata.selector, HashAlgorithm.crc32, (bit<64>)0,
Carmelo Cascone837e6452017-07-19 20:35:22 -040056 { hdr.ipv4.srcAddr, hdr.ipv4.dstAddr, hdr.ipv4.protocol, hdr.tcp.srcPort, hdr.tcp.dstPort, hdr.udp.srcPort,
Carmelo Casconeeb018122017-09-06 13:16:03 +020057 hdr.udp.dstPort }, ECMP_GROUP_SIZE);
Yi Tseng21629932017-06-06 11:17:43 -070058 }
59
60 table ecmp_group_table {
61 actions = {
62 set_egress_port(standard_metadata);
63 }
64 key = {
Carmelo Cascone837e6452017-07-19 20:35:22 -040065 meta.ecmp_metadata.group_id : exact;
Yi Tseng21629932017-06-06 11:17:43 -070066 meta.ecmp_metadata.selector: exact;
67 }
68 counters = ecmp_group_table_counter;
69 }
70
71 table table0 {
72 support_timeout = true;
73 actions = {
74 ecmp_group;
75 set_egress_port(standard_metadata);
76 send_to_cpu(standard_metadata);
Carmelo Casconeeb018122017-09-06 13:16:03 +020077 _drop(standard_metadata);
Yi Tseng21629932017-06-06 11:17:43 -070078 }
79 key = {
80 standard_metadata.ingress_port: ternary;
81 hdr.ethernet.dstAddr : ternary;
82 hdr.ethernet.srcAddr : ternary;
83 hdr.ethernet.etherType : ternary;
84 }
85 counters = table0_counter;
Carmelo Casconeeb018122017-09-06 13:16:03 +020086 default_action = _drop(standard_metadata);
Yi Tseng21629932017-06-06 11:17:43 -070087 }
Carmelo Cascone837e6452017-07-19 20:35:22 -040088
Yi Tseng21629932017-06-06 11:17:43 -070089 PortCountersControl() port_counters_control;
Carmelo Cascone837e6452017-07-19 20:35:22 -040090 PacketIoIngressControl() packet_io_ingress_control;
91
Yi Tseng21629932017-06-06 11:17:43 -070092 apply {
Carmelo Cascone837e6452017-07-19 20:35:22 -040093 packet_io_ingress_control.apply(hdr, standard_metadata);
94 if (!hdr.packet_out.isValid()) {
95 switch (table0.apply().action_run) {
96 ecmp_group: {
97 ecmp_group_table.apply();
98 }
Yi Tseng21629932017-06-06 11:17:43 -070099 }
100 }
Yi Tseng21629932017-06-06 11:17:43 -0700101 port_counters_control.apply(hdr, meta, standard_metadata);
102 }
103}
104
Carmelo Cascone837e6452017-07-19 20:35:22 -0400105control egress(inout headers_t hdr, inout metadata_t meta, inout standard_metadata_t standard_metadata) {
106
107 PacketIoEgressControl() packet_io_egress_control;
Yi Tseng21629932017-06-06 11:17:43 -0700108 apply {
Carmelo Cascone837e6452017-07-19 20:35:22 -0400109 packet_io_egress_control.apply(hdr, standard_metadata);
Yi Tseng21629932017-06-06 11:17:43 -0700110 }
111}
112
113V1Switch(ParserImpl(), verifyChecksum(), ingress(), egress(), computeChecksum(), DeparserImpl()) main;