blob: f49cf693e707fbda6302732e7e9d740bbb945a27 [file] [log] [blame]
Carmelo Cascone4f011022017-06-05 01:41:02 -04001#include "include/defines.p4"
2#include "include/headers.p4"
3#include "include/parser.p4"
4#include "include/actions.p4"
5#include "include/port_counters.p4"
Carmelo Cascone16de6db2017-08-22 00:27:57 +02006#include "include/packet_io.p4"
7
8/*
Carmelo Casconef1d0a422017-09-07 17:21:46 +02009 Make sure to define ECMP_GROUP_SIZE at compile-time.
10 This is the expected number of ports of an ECMP group.
Carmelo Cascone16de6db2017-08-22 00:27:57 +020011 This value is fixed, .i.e. we do not support ECMP over port groups of different size.
12 Due to hardware limitations, this value must be constant and a power of 2.
13*/
Carmelo Cascone4f011022017-06-05 01:41:02 -040014
15header_type ecmp_metadata_t {
16 fields {
Carmelo Cascone8aa05482017-09-12 13:21:59 +020017 group_id : 16;
Carmelo Cascone4f011022017-06-05 01:41:02 -040018 selector : 16;
19 }
20}
21
22metadata ecmp_metadata_t ecmp_metadata;
23
24field_list ecmp_hash_fields {
25 ipv4.srcAddr;
26 ipv4.dstAddr;
Carmelo Cascone6230a612017-09-13 03:25:41 +020027 tcp.srcPort;
28 tcp.dstPort;
Carmelo Cascone4f011022017-06-05 01:41:02 -040029}
30
31field_list_calculation ecmp_hash {
32 input {
33 ecmp_hash_fields;
34 }
Carmelo Cascone465ec2c2017-09-12 19:54:43 +020035 algorithm : crc16;
36 output_width : 16;
Carmelo Cascone4f011022017-06-05 01:41:02 -040037}
38
Carmelo Cascone8aa05482017-09-12 13:21:59 +020039action ecmp_group(group_id) {
40 modify_field(ecmp_metadata.group_id, group_id);
Carmelo Cascone16de6db2017-08-22 00:27:57 +020041 modify_field_with_hash_based_offset(ecmp_metadata.selector, 0, ecmp_hash, ECMP_GROUP_SIZE);
Carmelo Cascone4f011022017-06-05 01:41:02 -040042}
43
Carmelo Cascone16de6db2017-08-22 00:27:57 +020044#ifdef __TOFINO_BUILD__
45@pragma immediate 0
46#endif
Carmelo Cascone4f011022017-06-05 01:41:02 -040047table table0 {
48 reads {
Carmelo Cascone16de6db2017-08-22 00:27:57 +020049 IGR_PORT_FIELD : ternary;
50 ethernet.dstAddr : ternary;
51 ethernet.srcAddr : ternary;
Carmelo Cascone4f011022017-06-05 01:41:02 -040052 ethernet.etherType : ternary;
53 }
54 actions {
55 set_egress_port;
56 ecmp_group;
57 send_to_cpu;
Carmelo Cascone16de6db2017-08-22 00:27:57 +020058 _drop;
Carmelo Cascone4f011022017-06-05 01:41:02 -040059 }
60 support_timeout: true;
61}
62
63table ecmp_group_table {
64 reads {
Carmelo Cascone8aa05482017-09-12 13:21:59 +020065 ecmp_metadata.group_id : exact;
Carmelo Cascone4f011022017-06-05 01:41:02 -040066 ecmp_metadata.selector : exact;
67 }
68 actions {
69 set_egress_port;
70 }
71}
72
73counter table0_counter {
74 type: packets;
75 direct: table0;
76 min_width : 32;
77}
78
79counter ecmp_group_table_counter {
80 type: packets;
81 direct: ecmp_group_table;
82 min_width : 32;
83}
84
85control ingress {
Carmelo Cascone16de6db2017-08-22 00:27:57 +020086 if (not valid(packet_out_hdr)) {
87 apply(table0) {
88 ecmp_group {
89 apply(ecmp_group_table);
90 }
Carmelo Cascone4f011022017-06-05 01:41:02 -040091 }
92 }
Carmelo Casconef2ac7202017-09-08 00:57:44 +020093 ingress_pkt_io_control();
Carmelo Cascone4f011022017-06-05 01:41:02 -040094 process_port_counters();
Carmelo Cascone4f011022017-06-05 01:41:02 -040095}