Hi
I really don’t know what is wrong in my implementation:
#include <core.p4>
#include <psa.p4>
const bit<16> ETHERTYPE_TPID = 0x8100;
const bit<16> ETHERTYPE_IPV4 = 0x0800;
/* Define all the headers the program will recognize
* The actual sets of headers processed by each gress can differ
*/
header ethernet_h {
bit<48> dst_addr;
bit<48> src_addr;
bit<16> ether_type;
}
header vlan_tag_h {
bit<16> pcp_cfi_vid;
bit<16> ether_type;
}
header ipv4_h {
bit<8> version_ihl;
bit<8> diffserv;
bit<16> total_len;
bit<16> identification;
bit<16> flags_frag_offset;
bit<8> ttl;
bit<8> protocol;
bit<16> hdr_checksum;
bit<32> src_addr;
bit<32> dst_addr;
}
const int IPV4_HOST_SIZE = 65536;
typedef bit<48> ethernet_addr_t;
struct my_ingress_headers_t {
ethernet_h ethernet;
vlan_tag_h vlan_tag;
ipv4_h ipv4;
}
struct my_ingress_metadata_t {
}
struct empty_metadata_t {
}
parser Ingress_Parser(
packet_in pkt,
out my_ingress_headers_t hdr,
inout my_ingress_metadata_t meta,
in psa_ingress_parser_input_metadata_t ig_intr_md,
in empty_metadata_t resub_meta,
in empty_metadata_t recirc_meta)
{
state start {
transition parse_ethernet;
}
state parse_ethernet {
pkt.extract(hdr.ethernet);
transition select(hdr.ethernet.ether_type) {
ETHERTYPE_TPID: parse_vlan_tag;
ETHERTYPE_IPV4: parse_ipv4;
default: accept;
}
}
state parse_vlan_tag {
pkt.extract(hdr.vlan_tag);
transition select(hdr.vlan_tag.ether_type) {
ETHERTYPE_IPV4: parse_ipv4;
default: accept;
}
}
state parse_ipv4 {
pkt.extract(hdr.ipv4);
transition accept;
}
}
action update_pkt_count (inout bit<8> counter, in ClassOfService_t class )
{
counter = counter + (bit<8>)class;
}
control ingress(
inout my_ingress_headers_t hdr,
inout my_ingress_metadata_t meta,
in psa_ingress_input_metadata_t ig_intr_md,
inout psa_ingress_output_metadata_t ostd
)
{
Register<bit<8>, bit<8>>(5) reg_counter;
/*
* If got match -> egress
* to port 1 else drop
*/
action send(PortId_t port, ClassOfService_t class) {
bit<8> tmp;
ostd.egress_port = (PortId_t) port;
ostd.drop = false;
ostd.class_of_service = (ClassOfService_t) class;
tmp = reg_counter.read(0);
update_pkt_count(tmp, ostd.class_of_service);
reg_counter.write(0, tmp);
}
action drop() {
ostd.drop = true;
}
action set_port_and_src_mac( PortId_t port,
ethernet_addr_t src_mac,
ethernet_addr_t dst_mac) {
send_to_port(ostd, port);
hdr.ethernet.src_addr = src_mac;
hdr.ethernet.dst_addr = dst_mac;
}
table ipv4_host {
key = { hdr.ipv4.dst_addr : exact; }
actions = {
send;drop;
@defaultonly NoAction;
}
const default_action = NoAction();
size = IPV4_HOST_SIZE;
}
apply {
ipv4_host.apply();
}
}
control Ingress_Deparser(packet_out pkt,
out empty_metadata_t clone_i2e_meta,
out empty_metadata_t resubmit_meta,
out empty_metadata_t normal_meta,
inout my_ingress_headers_t hdr,
in my_ingress_metadata_t meta,
in psa_ingress_output_metadata_t istd)
{
apply {
pkt.emit(hdr);
}
}
struct my_egress_headers_t {
}
struct my_egress_metadata_t {
}
parser Egress_Parser(
packet_in pkt,
out my_egress_headers_t hdr,
inout my_ingress_metadata_t meta,
in psa_egress_parser_input_metadata_t istd,
in empty_metadata_t normal_meta,
in empty_metadata_t clone_i2e_meta,
in empty_metadata_t clone_e2e_meta)
{
state start {
transition accept;
}
}
control egress(
inout my_egress_headers_t hdr,
inout my_ingress_metadata_t meta,
in psa_egress_input_metadata_t istd,
inout psa_egress_output_metadata_t ostd)
{
apply {
}
}
control Egress_Deparser(packet_out pkt,
out empty_metadata_t clone_e2e_meta,
out empty_metadata_t recirculate_meta,
inout my_egress_headers_t hdr,
in my_ingress_metadata_t meta,
in psa_egress_output_metadata_t istd,
in psa_egress_deparser_input_metadata_t edstd)
{
apply {
pkt.emit(hdr);
}
}
#if __p4c__
bit<32> test_version = __p4c_version__;
#endif
IngressPipeline(Ingress_Parser(), ingress(), Ingress_Deparser()) pipe;
EgressPipeline(Egress_Parser(), egress(), Egress_Deparser()) ep;
PSA_Switch(pipe, PacketReplicationEngine(), ep, BufferingQueueingEngine()) main;
when I send traffic I see that there is matches in my table:
pipeline> pipeline PIPELINE0 stats
Davidi's: status counter: 4
Input ports:
Port 0: packets 224060118 bytes 13443607080 empty 13799034802
Port 1: packets 254070246 bytes 15244214760 empty 13769024679
Output ports:
Port 0: packets 0 bytes 0 clone 0 clonerr 0
Port 1: packets 357764924 bytes 21465895440 clone 0 clonerr 0
DROP: packets 120365439 bytes 5536810194 clone 0 clonerr 0
Davidi's-Tables:
Table ipv4_host:
Hit (packets): 357764928
Miss (packets): 120365440
Action NoAction (packets): 120365440
Action send (packets): 357764928
Action drop_1 (packets): 0
Learner tables:
pipeline> pipeline PIPELINE0 regrd reg_counter 0
Command failed.
but as you can see I can read the reg value from dpdk application CLI.
I configure the table like:
match 0x0A000000 action send port 0x1 class 17
match 0x0B652B58 action send port 0x0 class 11
I would expect to get 17+… for those packets that got match
Thanks in advance!
Guy