// Copyright (c) 2017, Google Inc.
//
// P4_16 specification for packet punting behavior.
// Note: This code has not been tested and is expected to contain bugs.

#ifndef P4_SPEC_PUNT_P4_
#define P4_SPEC_PUNT_P4_

#include "headers.p4"
#include "parser.p4"

//------------------------------------------------------------------------------
// Global defines
//------------------------------------------------------------------------------

#define CPU_MIRROR_SESSION_ID 1023
// TODO(samarabdi): Make sure this is also the behavior of the v1model extern
#define METER_GREEN 0

//------------------------------------------------------------------------------
// Control Pipelines
//------------------------------------------------------------------------------

control punt(inout parsed_packet_t hdr,
             inout local_metadata_t local_metadata,
             inout standard_metadata_t standard_metadata) {

  @proto_package("punt")
  direct_meter<bit<2>>(MeterType.bytes) ingress_port_meter;

  @proto_package("punt")
  direct_counter(CounterType.packets) punt_packet_counter;

  @proto_package("punt")
  action set_queue_and_clone_to_cpu(@proto_tag(1) bit<5> queue_id) {
    local_metadata.cpu_cos_queue_id = queue_id;
    local_metadata.egress_spec_at_punt_match = standard_metadata.egress_spec;
    clone3<tuple<bit<9>>>(CloneType.I2E, CPU_MIRROR_SESSION_ID,
                          {standard_metadata.ingress_port});
    ingress_port_meter.read(local_metadata.color);
    punt_packet_counter.count();
  }

  @proto_package("punt")
  action set_queue_and_send_to_cpu(@proto_tag(1) bit<5> queue_id) {
    local_metadata.cpu_cos_queue_id = queue_id;
    local_metadata.egress_spec_at_punt_match = standard_metadata.egress_spec;
    standard_metadata.egress_spec = CPU_PORT;
    ingress_port_meter.read(local_metadata.color);
    punt_packet_counter.count();
  }

  // Combined punt table.
  @proto_package("punt")
  table punt_table {
    key = {
      standard_metadata.ingress_port: ternary @proto_tag(1);
      standard_metadata.egress_spec: ternary @proto_tag(2);

      hdr.ethernet.ether_type: ternary @proto_tag(3);

      hdr.ipv4_base.diffserv: ternary @proto_tag(4);
      hdr.ipv6_base.traffic_class: ternary @proto_tag(5);
      hdr.ipv4_base.ttl: ternary @proto_tag(6);
      hdr.ipv6_base.hop_limit: ternary @proto_tag(7);
      hdr.ipv4_base.src_addr: ternary @proto_tag(8);
      hdr.ipv4_base.dst_addr: ternary @proto_tag(9);
      hdr.ipv6_base.src_addr: ternary @proto_tag(10);
      hdr.ipv6_base.dst_addr: ternary @proto_tag(11);
      hdr.ipv4_base.protocol: ternary @proto_tag(12);
      hdr.ipv6_base.next_header: ternary @proto_tag(13);

      hdr.arp.target_proto_addr: ternary @proto_tag(14);
      local_metadata.icmp_code: ternary @proto_tag(15);

      hdr.vlan_tag[0].vid: ternary @proto_tag(16);
      hdr.vlan_tag[0].pcp: ternary @proto_tag(17);

      local_metadata.class_id: ternary @proto_tag(18);
      local_metadata.vrf_id: ternary @proto_tag(19);
    }
    actions = {
      @proto_tag(1) set_queue_and_clone_to_cpu;
      @proto_tag(2) set_queue_and_send_to_cpu;
    }
    meters = ingress_port_meter;
    counters = punt_packet_counter;
  }

  apply {
    punt_table.apply();
    if(local_metadata.color != METER_GREEN) {
      mark_to_drop();
    }
  }
} // end punt

#endif // P4_SPEC_PUNT_P4_
