/*
 * Copyright (c) 2021 Cisco and/or its affiliates.
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at:
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

option version = "0.1.1";

import "vnet/interface_types.api";
import "vnet/ip/ip_types.api";

enum pnat_mask
{
    PNAT_SA = 0x1,
    PNAT_DA = 0x2,
    PNAT_SPORT = 0x4,
    PNAT_DPORT = 0x8,
    PNAT_COPY_BYTE = 0x10,
    PNAT_CLEAR_BYTE = 0x20,
};

enum pnat_attachment_point
{
    PNAT_IP4_INPUT,
    PNAT_IP4_OUTPUT,
    PNAT_ATTACHMENT_POINT_MAX,
};

typedef pnat_match_tuple
{
    vl_api_ip4_address_t src;
    vl_api_ip4_address_t dst;
    vl_api_ip_proto_t proto;
    u16 sport;
    u16 dport;
    vl_api_pnat_mask_t mask;
};

typedef pnat_rewrite_tuple
{
    vl_api_ip4_address_t src;
    vl_api_ip4_address_t dst;
    u16 sport;
    u16 dport;
    vl_api_pnat_mask_t mask; // needed?
    u8 from_offset;
    u8 to_offset;
    u8 clear_offset;
};

autoendian define pnat_binding_add
{
    u32 client_index;
    u32 context;
    vl_api_pnat_match_tuple_t match;
    vl_api_pnat_rewrite_tuple_t rewrite;
};

autoendian define pnat_binding_add_reply
{
    u32 context;
    i32 retval;
    u32 binding_index;
};

autoendian autoreply define pnat_binding_del
{
    u32 client_index;
    u32 context;
    u32 binding_index;
};

autoendian autoreply define pnat_binding_attach
{
  u32 client_index;
  u32 context;
  vl_api_interface_index_t sw_if_index;
  vl_api_pnat_attachment_point_t attachment;
  u32 binding_index;
};

autoendian autoreply define pnat_binding_detach
{
  u32 client_index;
  u32 context;
  vl_api_interface_index_t sw_if_index;
  vl_api_pnat_attachment_point_t attachment;
  u32 binding_index;
};

service {
  rpc pnat_bindings_get returns pnat_bindings_get_reply
    stream pnat_bindings_details;
  rpc pnat_interfaces_get returns pnat_interfaces_get_reply
    stream pnat_interfaces_details;
};

define pnat_bindings_get
{
  u32 client_index;
  u32 context;
  u32 cursor;
};

define pnat_bindings_get_reply
{
  u32 context;
  i32 retval;
  u32 cursor;
};

define pnat_bindings_details
{
  u32 context;
  vl_api_pnat_match_tuple_t match;
  vl_api_pnat_rewrite_tuple_t rewrite;
};

define pnat_interfaces_get
{
  u32 client_index;
  u32 context;
  u32 cursor;
};

define pnat_interfaces_get_reply
{
  u32 context;
  i32 retval;
  u32 cursor;
};

define pnat_interfaces_details
{
  u32 context;
  vl_api_interface_index_t sw_if_index;
  bool enabled[2]; /* PNAT_ATTACHMENT_POINT_MAX */
  vl_api_pnat_mask_t lookup_mask[2]; /* PNAT_ATTACHMENT_POINT_MAX */
};

counters pnat {
  none {
    severity info;
    type counter64;
    units "packets";
    description "successfully rewritten";
  };

  rewrite {
    severity error;
    type counter64;
    units "packets";
    description "rewrite failed";
  };
  tooshort {
    severity info;
    type counter64;
    units "packets";
    description "packet too short for rewrite";
  };
};

paths {
  "/err/pnat-input" "pnat";
  "/err/pnat-output" "pnat";
};