summaryrefslogtreecommitdiffstats
path: root/test/test_cnat.py
AgeCommit message (Expand)AuthorFilesLines
2022-05-10tests: replace pycodestyle with blackKlement Sekera1-155/+227
2021-11-22vlib: add virtual time supportBenoƮt Ganne1-9/+2
2021-10-21cnat: improve testsNathan Skrzypczak1-737/+562
2021-05-13tests: move test source to vpp/testDave Wallace1-0/+975
>106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307
/*
 * Copyright (c) 2015 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.
 */
#ifndef __included_vppjni_h__
#define __included_vppjni_h__

#include <vnet/vnet.h>
#include <vnet/ip/ip.h>
#include <vnet/api_errno.h>
#include <vlibapi/api.h>
#include <vlibmemory/api.h>
#include <jni.h>
#include <japi/vppjni_bridge_domain.h>

typedef struct {
    u8 * name;
    u32 value;
} name_sort_t;

typedef struct {
    u8 valid; // used in a vector of sw_interface_details_t

    u8 interface_name[64];
    u32 sw_if_index;
    u32 sup_sw_if_index;
    u32 l2_address_length;
    u8 l2_address[8];
    u8 admin_up_down;
    u8 link_up_down;
    u8 link_duplex;
    u8 link_speed;
    u32 sub_id;
    u8 sub_dot1ad;
    u8 sub_number_of_tags;
    u16 sub_outer_vlan_id;
    u16 sub_inner_vlan_id;
    u8 sub_exact_match;
    u8 sub_default;
    u8 sub_outer_vlan_id_any;
    u8 sub_inner_vlan_id_any;
    u32 vtr_op;
    u32 vtr_push_dot1q;
    u32 vtr_tag1;
    u32 vtr_tag2;
} sw_interface_details_t;

typedef struct {
    u8 * interface_name;
    u32 sw_if_index;
    /* 
     * Subinterface ID. A number 0-N to uniquely identify 
     * this subinterface under the super interface
     */
    u32 sub_id;

    /* 0 = dot1q, 1=dot1ad */
    u8 sub_dot1ad;

    /* Number of tags 0-2 */
    u8 sub_number_of_tags;
    u16 sub_outer_vlan_id;
    u16 sub_inner_vlan_id;
    u8 sub_exact_match;
    u8 sub_default;
    u8 sub_outer_vlan_id_any;
    u8 sub_inner_vlan_id_any;

    /* vlan tag rewrite */
    u32 vtr_op;
    u32 vtr_push_dot1q;
    u32 vtr_tag1;
    u32 vtr_tag2;
} sw_interface_subif_t;

typedef struct {
    u8 *desc;
} sw_if_config_t;

typedef struct {
    u32 ip;
    u8 prefix_length;
} ipv4_address_t;

typedef struct {
    u8 ip[16];
    u8 prefix_length;
} ipv6_address_t;

typedef struct {
  u64 ip4;
  u64 ip6;
  u64 unicast;
  u64 multicast;
  u64 broadcast;
  u64 discard;
  u64 fifo_full;
  u64 error;
  u64 unknown_proto;
  u64 miss;
} packet_counters_t;

typedef struct {
  u64 octets;
  packet_counters_t pkts;
} if_counters_t;

typedef struct {
  u8 valid;
  u32 sw_if_index;
  if_counters_t rx;
  if_counters_t tx;
} sw_interface_stats_t;

typedef struct {
    u32 src_address;
    u32 dst_address;
    u32 encap_vrf_id;
    u32 vni;
    u32 decap_next_index;
} vxlan_tunnel_details_t;


typedef struct {
  /* Context IDs */
  volatile u32 context_id_sent;
  volatile u32 context_id_received;

  /* Spinlock */
  volatile u32 lock;
  u32 tag;

  /* To recycle pseudo-synchronous message code from vpp_api_test... */
  volatile u32 result_ready;
  volatile i32 retval;
  volatile u8 *shmem_result;

  /* thread cleanup */
  pthread_key_t cleanup_rx_thread_key;
  /* attachment of rx thread to java thread */
  JNIEnv *jenv;
  JavaVM *jvm;
  uword *callback_hash;     // map context_id => jobject
  uword *ping_hash;         // map ping context_id => msg type called

  /* Timestamp */
  clib_time_t clib_time;

  /* connected indication */
  u8 is_connected;

  /* context -> non-trivial reply hash */
  uword * reply_hash;
  u32 saved_reply_count;

  /* interface name map */
  uword * sw_if_index_by_interface_name;

  /* interface counters */
  sw_interface_stats_t * sw_if_stats_by_sw_if_index;

  /* interface table */
  sw_interface_details_t * sw_if_table;

  uword * sw_if_config_by_sw_if_index;

  /* interface indices of responses to one sw_if_dump request */
  u8 collect_indices;
  u32 * sw_if_dump_if_indices;

  /* program name, build_dir, version */
  u8 program_name[32];
  u8 build_directory[256];
  u8 version[32];
  u8 build_date[32];

  /* subinterface table */
  sw_interface_subif_t * sw_if_subif_table;

  /* used in ip_address_dump request and response handling */
  ipv4_address_t *ipv4_addresses;
  ipv6_address_t *ipv6_addresses;
  u8 is_ipv6;

  /* used in vxlan_tunnel_dump request and response handling */
  vxlan_tunnel_details_t *vxlan_tunnel_details;

  /* main heap */
  u8 * heap;

  /* convenience */
  unix_shared_memory_queue_t * vl_input_queue;
  api_main_t * api_main;
  u32 my_client_index;

  vjbd_main_t vjbd_main;
} vppjni_main_t;

vppjni_main_t vppjni_main __attribute__((aligned (64)));


static inline u32 vppjni_get_context_id (vppjni_main_t * jm)
{
  u32 my_context_id;
  my_context_id = __sync_add_and_fetch (&jm->context_id_sent, 1);
  return my_context_id;
}

static inline void vppjni_lock (vppjni_main_t * jm, u32 tag)
{
  while (__sync_lock_test_and_set (&jm->lock, 1))
    ;
  jm->tag = tag;
}

static inline void vppjni_unlock (vppjni_main_t * jm)
{
  jm->tag = 0;
  CLIB_MEMORY_BARRIER();
  jm->lock = 0;
}

static inline f64 vppjni_time_now (vppjni_main_t *jm)
{
  return clib_time_now (&jm->clib_time);
}

static inline int vppjni_sanity_check (vppjni_main_t * jm)
{
  if (!jm->is_connected)
    return VNET_API_ERROR_NOT_CONNECTED;
  return 0;
}

#define __PACKED(x) x __attribute__((packed))

typedef __PACKED(struct _vl_api_generic_reply {
  u16 _vl_msg_id;
  u32 context;
  i32 retval;
  u8 data[0];
}) vl_api_generic_reply_t;

void vl_api_generic_reply_handler (vl_api_generic_reply_t *mp);

/* M: construct, but don't yet send a message */

#define M(T,t)                                  \
do {                                            \
  jm->result_ready = 0;                         \
  mp = vl_msg_api_alloc(sizeof(*mp));           \
  memset (mp, 0, sizeof (*mp));                 \
  mp->_vl_msg_id = ntohs (VL_API_##T);          \
  mp->client_index = jm->my_client_index;       \
 } while(0);

#define M2(T,t,n)                               \
do {                                            \
  jm->result_ready = 0;                         \
  mp = vl_msg_api_alloc(sizeof(*mp)+(n));       \
  memset (mp, 0, sizeof (*mp));                 \
  mp->_vl_msg_id = ntohs (VL_API_##T);          \
  mp->client_index = jm->my_client_index;       \
 } while(0);


/* S: send a message */
#define S (vl_msg_api_send_shmem (jm->vl_input_queue, (u8 *)&mp))

/* W: wait for results, with timeout */
#define W                                       \
  do {                                          \
    timeout = vppjni_time_now (jm) + 1.0;       \
                                                \
    while (vppjni_time_now (jm) < timeout) {    \
      if (jm->result_ready == 1) {              \
        return (jm->retval);                    \
      }                                         \
    }                                           \
    return -99;                                 \
} while(0);

/* WNR: wait for results, with timeout (without returning) */
#define WNR                                     \
  do {                                          \
    timeout = vppjni_time_now (jm) + 1.0;       \
                                                \
    rv = -99;                                   \
    while (vppjni_time_now (jm) < timeout) {    \
      if (jm->result_ready == 1) {              \
        rv = (jm->retval);                      \
        break;                                  \
      }                                         \
    }                                           \
} while(0);

#endif /* __included_vppjni_h__ */