blob: a3514b4d646e0dcbf01feea0edfdf3944383bcb8 [file] [log] [blame]
#include "include/defines.p4"
#include "include/headers.p4"
#include "include/parser.p4"
#include "include/actions.p4"
#include "include/port_counters.p4"
#include "include/packet_io.p4"
#define SELECTOR_WIDTH 32
header_type wcmp_meta_t {
fields {
groupId : 16;
numBits: 8;
selector : SELECTOR_WIDTH;
}
}
metadata wcmp_meta_t wcmp_meta;
field_list wcmp_hash_fields {
ipv4.srcAddr;
ipv4.dstAddr;
ipv4.protocol;
tcp.srcPort;
tcp.dstPort;
udp.srcPort;
udp.dstPort;
}
field_list_calculation wcmp_hash {
input {
wcmp_hash_fields;
}
algorithm : crc32;
output_width : 32;
}
action wcmp_group(groupId) {
modify_field(wcmp_meta.groupId, groupId);
modify_field_with_hash_based_offset(wcmp_meta.numBits, 2, wcmp_hash, (SELECTOR_WIDTH - 2));
}
action wcmp_set_selector() {
modify_field(wcmp_meta.selector,
(((1 << wcmp_meta.numBits) - 1) << (SELECTOR_WIDTH - wcmp_meta.numBits)));
}
table table0 {
reads {
IGR_PORT_FIELD : ternary;
ethernet.dstAddr : ternary;
ethernet.srcAddr : ternary;
ethernet.etherType : ternary;
}
actions {
set_egress_port;
wcmp_group;
send_to_cpu;
_drop;
}
support_timeout: true;
}
table wcmp_set_selector_table {
actions {
wcmp_set_selector;
}
}
table wcmp_group_table {
reads {
wcmp_meta.groupId : exact;
wcmp_meta.selector : lpm;
}
actions {
set_egress_port;
}
}
counter table0_counter {
type: packets;
direct: table0;
min_width : 32;
}
counter wcmp_group_table_counter {
type: packets;
direct: wcmp_group_table;
min_width : 32;
}
control ingress {
if (not valid(packet_out_hdr)) {
apply(table0) {
wcmp_group {
apply(wcmp_set_selector_table) {
wcmp_set_selector {
apply(wcmp_group_table);
}
}
}
}
}
ingress_pkt_io_control();
process_port_counters();
}