/*
 * 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.
 */
#include <vnet/vnet.h>

#define vl_api_version(n,v) static u32 vpe_api_version = (v);
#include <api/vpe.api.h>
#undef vl_api_version

#include <jni.h>
#include <japi/vppjni.h>
#include <japi/vppjni_bridge_domain.h>
#include <japi/vppjni_env.h>
#include <japi/org_openvpp_vppjapi_vppConn.h>
#include <japi/org_openvpp_vppjapi_vppApi.h>

#include <api/vpe_msg_enum.h>
#define vl_typedefs             /* define message structures */
#include <api/vpe_all_api_h.h> 
#undef vl_typedefs

#define vl_endianfun 
#include <api/vpe_all_api_h.h> 
#undef vl_endianfun

/* instantiate all the print functions we know about */
#define vl_print(handle, ...)
#define vl_printfun
#include <api/vpe_all_api_h.h>
#undef vl_printfun

#define VPPJNI_DEBUG 0

#if VPPJNI_DEBUG == 1
  #define DEBUG_LOG(...) clib_warning(__VA_ARGS__)
#else
  #define DEBUG_LOG(...)
#endif

static int connect_to_vpe(char *name);

/* 
 * The Java runtime isn't compile w/ -fstack-protector,
 * so we have to supply missing external references for the
 * regular vpp libraries. Weak reference in case folks get religion
 * at a later date...
 */
void __stack_chk_guard (void) __attribute__((weak));
void __stack_chk_guard (void) {  }

BIND_JAPI_CLASS(vppBridgeDomainDetails, "()V");
BIND_JAPI_BOOL_FIELD(vppBridgeDomainDetails, arpTerm);
BIND_JAPI_BOOL_FIELD(vppBridgeDomainDetails, flood);
BIND_JAPI_BOOL_FIELD(vppBridgeDomainDetails, forward);
BIND_JAPI_BOOL_FIELD(vppBridgeDomainDetails, learn);
BIND_JAPI_BOOL_FIELD(vppBridgeDomainDetails, uuFlood);
BIND_JAPI_INT_FIELD(vppBridgeDomainDetails, bdId);
BIND_JAPI_STRING_FIELD(vppBridgeDomainDetails, name);
BIND_JAPI_STRING_FIELD(vppBridgeDomainDetails, bviInterfaceName);
BIND_JAPI_OBJ_FIELD(vppBridgeDomainDetails, interfaces, "[Lorg/openvpp/vppjapi/vppBridgeDomainInterfaceDetails;");

BIND_JAPI_CLASS(vppBridgeDomainInterfaceDetails, "()V");
BIND_JAPI_BYTE_FIELD(vppBridgeDomainInterfaceDetails, splitHorizonGroup);
BIND_JAPI_STRING_FIELD(vppBridgeDomainInterfaceDetails, interfaceName);

BIND_JAPI_CLASS(vppInterfaceCounters, "(JJJJJJJJJJJJJJJJJJJJJJ)V");
BIND_JAPI_CLASS(vppInterfaceDetails, "(ILjava/lang/String;I[BBBBBIBBIIBBBBIIII)V");
BIND_JAPI_CLASS(vppIPv4Address, "(IB)V");
BIND_JAPI_CLASS(vppIPv6Address, "([BB)V");
BIND_JAPI_CLASS(vppL2Fib, "([BZLjava/lang/String;ZZ)V");
BIND_JAPI_CLASS(vppVersion, "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V");
BIND_JAPI_CLASS(vppVxlanTunnelDetails, "(IIIII)V");

void vl_client_add_api_signatures (vl_api_memclnt_create_t *mp) 
{
    /* 
     * Send the main API signature in slot 0. This bit of code must
     * match the checks in ../vpe/api/api.c: vl_msg_api_version_check().
     */
    mp->api_versions[0] = clib_host_to_net_u32 (vpe_api_version);
}

/* Note: non-static, called once to set up the initial intfc table */
static int sw_interface_dump (vppjni_main_t * jm)
{
    vl_api_sw_interface_dump_t *mp;
    f64 timeout;
    hash_pair_t * p;
    name_sort_t * nses = 0, * ns;
    sw_interface_subif_t * sub = NULL;

    /* Toss the old name table */
    hash_foreach_pair (p, jm->sw_if_index_by_interface_name, 
    ({
        vec_add2 (nses, ns, 1);
        ns->name = (u8 *)(p->key);
        ns->value = (u32) p->value[0];
    }));

    hash_free (jm->sw_if_index_by_interface_name);

    vec_foreach (ns, nses)
        vec_free (ns->name);

    vec_free (nses);

    vec_foreach (sub, jm->sw_if_subif_table) {
        vec_free (sub->interface_name);
    }
    vec_free (jm->sw_if_subif_table);

    /* recreate the interface name hash table */
    jm->sw_if_index_by_interface_name 
      = hash_create_string (0, sizeof(uword));

    /* Get list of ethernets */
    M(SW_INTERFACE_DUMP, sw_interface_dump);
    mp->name_filter_valid = 1;
    strncpy ((char *) mp->name_filter, "Ether", sizeof(mp->name_filter-1)); 
    S;

    /* and local / loopback interfaces */
    M(SW_INTERFACE_DUMP, sw_interface_dump);
    mp->name_filter_valid = 1;
    strncpy ((char *) mp->name_filter, "lo", sizeof(mp->name_filter-1)); 
    S;

    /* and vxlan tunnel interfaces */
    M(SW_INTERFACE_DUMP, sw_interface_dump);
    mp->name_filter_valid = 1;
    strncpy ((char *) mp->name_filter, "vxlan", sizeof(mp->name_filter-1)); 
    S;

    /* and tap tunnel interfaces */
    M(SW_INTERFACE_DUMP, sw_interface_dump);
    mp->name_filter_valid = 1;
    strncpy ((char *) mp->name_filter, "tap", sizeof(mp->name_filter-1)); 
    S;

    /* and l2tpv3 tunnel interfaces */
    M(SW_INTERFACE_DUMP, sw_interface_dump);
    mp->name_filter_valid = 1;
    strncpy ((char *) mp->name_filter, "l2tpv3_tunnel", 
             sizeof(mp->name_filter-1));
    S;

    /* Use a control ping for synchronization */
    {
        vl_api_control_ping_t * mp;
        M(CONTROL_PING, control_ping);
        S;
    }
    W;
}

JNIEXPORT jobject JNICALL Java_org_openvpp_vppjapi_vppConn_getVppVersion0
  (JNIEnv *env, jobject obj)
{
  vppjni_main_t * jm = &vppjni_main;

  vppjni_lock (jm, 11);
  jstring progName = (*env)->NewStringUTF(env, (char *)jm->program_name);
  jstring buildDir = (*env)->NewStringUTF(env, (char *)jm->build_directory);
  jstring version = (*env)->NewStringUTF(env, (char *)jm->version);
  jstring buildDate = (*env)->NewStringUTF(env, (char *)jm->build_date);
  vppjni_unlock (jm);

  return vppVersionObject(env, progName, buildDir, version, buildDate);
}

static int jm_show_version (vppjni_main_t *jm)
{
  int rv;
  vl_api_show_version_t *mp;
  f64 timeout;

  vppjni_lock (jm, 10);
  M(SHOW_VERSION, show_version);

  S;
  vppjni_unlock (jm);
  WNR;
  return rv;
}

static int jm_stats_enable_disable (vppjni_main_t *jm, u8 enable)
{
  vl_api_want_stats_t * mp;
  f64 timeout;
  int rv;

  vppjni_lock (jm, 13);

  M(WANT_STATS, want_stats);

  mp->enable_disable = enable;

  S;
  vppjni_unlock (jm);
  WNR;

  // already subscribed / already disabled (it's ok)
  if (rv == -2 || rv == -3)
      rv = 0;
  return rv;
}

JNIEXPORT jint JNICALL Java_org_openvpp_vppjapi_vppConn_setInterfaceDescription0
  (JNIEnv *env, jobject obj, jstring ifName, jstring ifDesc)
{
    int rv = 0;
    vppjni_main_t * jm = &vppjni_main;
    uword * p;
    u32 sw_if_index = ~0;
    sw_if_config_t *cfg;

    const char *if_name_str = (*env)->GetStringUTFChars (env, ifName, 0);
    const char *if_desc_str = (*env)->GetStringUTFChars (env, ifDesc, 0);

    vppjni_lock (jm, 23);

    p = hash_get_mem (jm->sw_if_index_by_interface_name, if_name_str);
    if (p == 0) {
        rv = -1;
        goto out;
    }
    sw_if_index = (jint) p[0];

    u8 *if_desc = 0;
    vec_validate_init_c_string (if_desc, if_desc_str, strlen(if_desc_str));
    (*env)->ReleaseStringUTFChars (env, ifDesc, if_desc_str);

    p = hash_get (jm->sw_if_config_by_sw_if_index, sw_if_index);
    if (p != 0) {
        cfg = (sw_if_config_t *) (p[0]);
        if (cfg->desc)
            vec_free(cfg->desc);
    }
    else {
        cfg = (sw_if_config_t *) clib_mem_alloc(sizeof(sw_if_config_t));
        hash_set (jm->sw_if_config_by_sw_if_index, sw_if_index, cfg);
    }

    cfg->desc = if_desc;

out:
    (*env)->ReleaseStringUTFChars (env, ifName, if_name_str);
    vppjni_unlock (jm);
    return rv;
}

JNIEXPORT jstring JNICALL Java_org_openvpp_vppjapi_vppConn_getInterfaceDescription0
(JNIEnv * env, jobject obj, jstring ifName)
{
    vppjni_main_t * jm = &vppjni_main;
    u32 sw_if_index = ~0;
    uword * p;
    const char *if_name_str = (*env)->GetStringUTFChars (env, ifName, 0);
    jstring ifDesc = NULL;

    vppjni_lock (jm, 24);
    p = hash_get_mem (jm->sw_if_index_by_interface_name, if_name_str);
    if (p == 0)
        goto out;

    sw_if_index = (jint) p[0];

    p = hash_get (jm->sw_if_config_by_sw_if_index, sw_if_index);
    if (p == 0)
        goto out;

    sw_if_config_t *cfg = (sw_if_config_t *) (p[0]);
    u8 * s = format (0, "%s%c", cfg->desc, 0);
    ifDesc = (*env)->NewStringUTF(env, (char *)s);

out:
    vppjni_unlock (jm);

    return ifDesc;
}

JNIEXPORT jint JNICALL Java_org_openvpp_vppjapi_vppConn_clientConnect
  (JNIEnv *env, jobject obj, jstring clientName)
{
  int rv;
  const char *client_name;
  void vl_msg_reply_handler_hookup(void);
  vppjni_main_t * jm = &vppjni_main;
  api_main_t * am = &api_main;
  u8 * heap;
  mheap_t * h; 
  f64 timeout;
      
  /* 
   * Bail out now if we're not running as root
   */
  if (geteuid() != 0)
    return -1;

  if (jm->is_connected)
      return -2;

  if (jm->heap == 0)
    clib_mem_init (0, 128<<20);

  heap = clib_mem_get_per_cpu_heap();
  h = mheap_header (heap);

  client_name = (*env)->GetStringUTFChars (env, clientName, 0);

  clib_time_init (&jm->clib_time);

  rv = connect_to_vpe ((char *) client_name);

  if (rv < 0)
    clib_warning ("connection failed, rv %d", rv);

  (*env)->ReleaseStringUTFChars (env, clientName, client_name);

  if (rv == 0)
    {
      vl_msg_reply_handler_hookup ();
      jm->is_connected = 1;
      /* make the main heap thread-safe */
      h->flags |= MHEAP_FLAG_THREAD_SAFE;

      jm->reply_hash = hash_create (0, sizeof (uword));
      //jm->callback_hash = hash_create (0, sizeof (uword));
      //jm->ping_hash = hash_create (0, sizeof (uword));
      jm->api_main = am;
      vjbd_main_init(&jm->vjbd_main);
      jm->sw_if_index_by_interface_name = 
        hash_create_string (0, sizeof (uword));
      jm->sw_if_config_by_sw_if_index =
        hash_create (0, sizeof (uword));

      {
        // call control ping first to attach rx thread to java thread
        vl_api_control_ping_t * mp;
        M(CONTROL_PING, control_ping);
        S;
        WNR;

        if (rv != 0) {
            clib_warning ("first control ping failed: %d", rv);
        }
      }
      rv = jm_show_version(jm);
      if (rv != 0)
          clib_warning ("unable to retrieve vpp version (rv: %d)", rv);
      rv = sw_interface_dump(jm);
      if (rv != 0)
          clib_warning ("unable to retrieve interface list (rv: %d)", rv);
      rv = jm_stats_enable_disable(jm, 1);
      if (rv != 0)
          clib_warning ("unable to subscribe to stats (rv: %d)", rv);
    }
  DEBUG_LOG ("clientConnect result: %d", rv);

  return rv;
}

JNIEXPORT void JNICALL Java_org_openvpp_vppjapi_vppConn_clientDisconnect
  (JNIEnv *env, jobject obj)
{
  u8 *save_heap;
  vppjni_main_t * jm = &vppjni_main;
  vl_client_disconnect_from_vlib();
  
  save_heap = jm->heap;
  memset (jm, 0, sizeof (*jm));
  jm->heap = save_heap;
}

void vl_api_generic_reply_handler (vl_api_generic_reply_t *mp)
{
  api_main_t * am = &api_main;
  u16 msg_id = clib_net_to_host_u16 (mp->_vl_msg_id);
  trace_cfg_t *cfgp;
  i32 retval = clib_net_to_host_u32 (mp->retval);
  int total_bytes = sizeof(mp);
  vppjni_main_t * jm = &vppjni_main;
  u8 * saved_reply = 0;
  u32 context = clib_host_to_net_u32 (mp->context);
    
  cfgp = am->api_trace_cfg + msg_id;

  if (!cfgp) 
    clib_warning ("msg id %d: no trace configuration\n", msg_id);
  else
    total_bytes = cfgp->size;

  jm->context_id_received = context;

  DEBUG_LOG ("Received generic reply for msg id %d", msg_id);

  /* A generic reply, successful, we're done */
  if (retval >= 0 && total_bytes == sizeof(*mp))
    return;

  /* Save the reply */
  vec_validate (saved_reply, total_bytes - 1);
  memcpy (saved_reply, mp, total_bytes);

  vppjni_lock (jm, 2);
  hash_set (jm->reply_hash, context, saved_reply);
  jm->saved_reply_count ++;
  vppjni_unlock (jm);
}

JNIEXPORT jint JNICALL Java_org_openvpp_vppjapi_vppConn_getRetval0
(JNIEnv * env, jobject obj, jint context, jint release)
{
  vppjni_main_t * jm = &vppjni_main;
  vl_api_generic_reply_t * mp;
  uword * p;
  int rv = 0;

  /* Dunno yet? */
  if (context > jm->context_id_received)
    return (VNET_API_ERROR_RESPONSE_NOT_READY);

  vppjni_lock (jm, 1);
  p = hash_get (jm->reply_hash, context);

  /* 
   * Two cases: a generic "yes" reply - won't be in the hash table
   * or "no", or "more data" which will be in the table.
   */
  if (p == 0)
    goto out;
      
  mp = (vl_api_generic_reply_t *) (p[0]);
  rv = clib_net_to_host_u32 (mp->retval);

  if (release)
    {
      u8 * free_me = (u8 *) mp;
      vec_free (free_me);
      hash_unset (jm->reply_hash, context);
      jm->saved_reply_count --;
    }

out:
  vppjni_unlock (jm);
  return (rv);
}

static int
name_sort_cmp (void * a1, void * a2)
{
  name_sort_t * n1 = a1;
  name_sort_t * n2 = a2;

  return strcmp ((char *)n1->name, (char *)n2->name);
}

JNIEXPORT jstring JNICALL Java_org_openvpp_vppjapi_vppConn_getInterfaceList0
  (JNIEnv * env, jobject obj, jstring name_filter)
{
  vppjni_main_t * jm = &vppjni_main;
  jstring rv;
  hash_pair_t * p;
  name_sort_t * nses = 0, * ns;
  const char *this_name;
  const char * nf = (*env)->GetStringUTFChars (env, name_filter, NULL);
  u8 * s = 0;
  char *strcasestr (const char *, const char *);

  vppjni_lock (jm, 4);
  
  hash_foreach_pair (p, jm->sw_if_index_by_interface_name, 
    ({
      this_name = (const char *)(p->key);
      if (strlen (nf) == 0 || strcasestr (this_name, nf))
        {
          vec_add2 (nses, ns, 1);
          ns->name = (u8 *)(p->key);
          ns->value = (u32) p->value[0];
        }
    }));

  vec_sort_with_function (nses, name_sort_cmp);

  vec_foreach (ns, nses)
    s = format (s, "%s: %d, ", ns->name, ns->value);

  _vec_len (s) = vec_len (s) - 2;
  vec_terminate_c_string (s);
  vppjni_unlock (jm);

  vec_free (nses);

  (*env)->ReleaseStringUTFChars (env, name_filter, nf);

  rv = (*env)->NewStringUTF (env, (char *) s);
  vec_free (s);
  
  return rv;
}

JNIEXPORT jint JNICALL Java_org_openvpp_vppjapi_vppConn_swIfIndexFromName0
  (JNIEnv * env, jobject obj, jstring interfaceName)
{
  vppjni_main_t * jm = &vppjni_main;
  jint rv = -1;
  const char * if_name = (*env)->GetStringUTFChars (env, interfaceName, NULL);
  uword * p;

  vppjni_lock (jm, 5);

  p = hash_get_mem (jm->sw_if_index_by_interface_name, if_name);

  if (p != 0)
      rv = (jint) p[0];

  vppjni_unlock (jm);
  
  (*env)->ReleaseStringUTFChars (env, interfaceName, if_name);

  return rv;
}

JNIEXPORT jobject JNICALL Java_org_openvpp_vppjapi_vppConn_getInterfaceCounters0
(JNIEnv * env, jobject obj, jint swIfIndex)
{
    vppjni_main_t * jm = &vppjni_main;
    sw_interface_stats_t *s;
    u32 sw_if_index = swIfIndex;
    jobject result = NULL;

    vppjni_lock (jm, 16);

    if (sw_if_index >= vec_len(jm->sw_if_stats_by_sw_if_index)) {
        goto out;
    }
    s = &jm->sw_if_stats_by_sw_if_index[sw_if_index];
    if (!s->valid) {
        goto out;
    }

    result = vppInterfaceCountersObject(env,
            s->rx.octets, s->rx.pkts.ip4, s->rx.pkts.ip6, s->rx.pkts.unicast,
            s->rx.pkts.multicast, s->rx.pkts.broadcast, s->rx.pkts.discard,
            s->rx.pkts.fifo_full, s->rx.pkts.error, s->rx.pkts.unknown_proto,
            s->rx.pkts.miss,
            s->tx.octets, s->tx.pkts.ip4, s->tx.pkts.ip6, s->tx.pkts.unicast,
            s->tx.pkts.multicast, s->tx.pkts.broadcast, s->tx.pkts.discard,
            s->tx.pkts.fifo_full, s->tx.pkts.error, s->tx.pkts.unknown_proto,
            s->tx.pkts.miss);

out:
    vppjni_unlock (jm);
    return result;
}

JNIEXPORT jstring JNICALL Java_org_openvpp_vppjapi_vppConn_interfaceNameFromSwIfIndex0
(JNIEnv * env, jobject obj, jint swIfIndex)
{
    vppjni_main_t * jm = &vppjni_main;
    sw_interface_details_t *sw_if_details;
    u32 sw_if_index;
    jstring ifname = NULL;

    vppjni_lock (jm, 8);

    sw_if_index = swIfIndex;

    if (sw_if_index >= vec_len(jm->sw_if_table)) {
        goto out;
    }
    sw_if_details = &jm->sw_if_table[sw_if_index];
    if (!sw_if_details->valid) {
        goto out;
    }

    u8 * s = format (0, "%s%c", sw_if_details->interface_name, 0);
    ifname = (*env)->NewStringUTF(env, (char *)s);

out:
    vppjni_unlock (jm);

    return ifname;
}

JNIEXPORT void JNICALL Java_org_openvpp_vppjapi_vppConn_clearInterfaceTable0
(JNIEnv * env, jobject obj)
{
    vppjni_main_t * jm = &vppjni_main;

    vppjni_lock (jm, 21);

    vec_reset_length(jm->sw_if_table);

    vppjni_unlock (jm);
}

static jobjectArray sw_if_dump_get_interfaces ();

JNIEXPORT jobjectArray JNICALL Java_org_openvpp_vppjapi_vppConn_swInterfaceDump0
(JNIEnv * env, jobject obj, jbyte name_filter_valid, jbyteArray name_filter)
{
    vppjni_main_t *jm = &vppjni_main;
    f64 timeout;
    vl_api_sw_interface_dump_t * mp;
    u32 my_context_id;
    int rv;
    rv = vppjni_sanity_check (jm);
    if (rv) {
        clib_warning("swInterfaceDump sanity_check rv = %d", rv);
        return NULL;
    }

    vppjni_lock (jm, 7);
    my_context_id = vppjni_get_context_id (jm);
    jsize cnt = (*env)->GetArrayLength (env, name_filter);

    M(SW_INTERFACE_DUMP, sw_interface_dump);
    mp->context = clib_host_to_net_u32 (my_context_id);
    mp->name_filter_valid = name_filter_valid;

    if (cnt > sizeof(mp->name_filter))
        cnt = sizeof(mp->name_filter);

    (*env)->GetByteArrayRegion(env, name_filter, 0, cnt, (jbyte *)mp->name_filter);

    DEBUG_LOG ("interface filter (%d, %s, len: %d)", mp->name_filter_valid, (char *)mp->name_filter, cnt);

    jm->collect_indices = 1;

    S;
    {
        // now send control ping so we know when it ends
        vl_api_control_ping_t * mp;
        M(CONTROL_PING, control_ping);
        mp->context = clib_host_to_net_u32 (my_context_id);

        S;
    }
    vppjni_unlock (jm);
    WNR;

    vppjni_lock (jm, 7);
    jobjectArray result = sw_if_dump_get_interfaces(env);
    vppjni_unlock (jm);
    return result;
}

static jobjectArray sw_if_dump_get_interfaces (JNIEnv * env)
{
    vppjni_main_t * jm = &vppjni_main;
    sw_interface_details_t *sw_if_details;
    u32 i;

    int len = vec_len(jm->sw_if_dump_if_indices);

    jobjectArray ifArray = vppInterfaceDetailsArray(env, len);

    for (i = 0; i < len; i++) {
        u32 sw_if_index = jm->sw_if_dump_if_indices[i];
        ASSERT(sw_if_index < vec_len(jm->sw_if_table));
        sw_if_details = &jm->sw_if_table[sw_if_index];
        ASSERT(sw_if_details->valid);

        u8 * s = format (0, "%s%c", sw_if_details->interface_name, 0);

        jstring ifname = (*env)->NewStringUTF(env, (char *)s);
        jint ifIndex = sw_if_details->sw_if_index;
        jint supIfIndex = sw_if_details->sup_sw_if_index;
        jbyteArray physAddr = (*env)->NewByteArray(env,
                sw_if_details->l2_address_length);
        (*env)->SetByteArrayRegion(env, physAddr, 0,
                sw_if_details->l2_address_length,
                (signed char*)sw_if_details->l2_address);
        jint subId = sw_if_details->sub_id;
        jint subOuterVlanId = sw_if_details->sub_outer_vlan_id;
        jint subInnerVlanId = sw_if_details->sub_inner_vlan_id;
        jint vtrOp = sw_if_details->vtr_op;
        jint vtrPushDot1q = sw_if_details->vtr_push_dot1q;
        jint vtrTag1 = sw_if_details->vtr_tag1;
        jint vtrTag2 = sw_if_details->vtr_tag2;

        jbyte adminUpDown = sw_if_details->admin_up_down;
        jbyte linkUpDown = sw_if_details->link_up_down;
        jbyte linkDuplex = sw_if_details->link_duplex;
        jbyte linkSpeed = sw_if_details->link_speed;
        jbyte subDot1ad = sw_if_details->sub_dot1ad;
        jbyte subNumberOfTags = sw_if_details->sub_number_of_tags;
        jbyte subExactMatch = sw_if_details->sub_exact_match;
        jbyte subDefault = sw_if_details->sub_default;
        jbyte subOuterVlanIdAny = sw_if_details->sub_outer_vlan_id_any;
        jbyte subInnerVlanIdAny = sw_if_details->sub_inner_vlan_id_any;

        jobject ifObj = vppInterfaceDetailsObject(env,
                ifIndex, ifname,
                supIfIndex, physAddr, adminUpDown, linkUpDown,
                linkDuplex, linkSpeed, subId, subDot1ad,
                subNumberOfTags, subOuterVlanId, subInnerVlanId,
                subExactMatch, subDefault, subOuterVlanIdAny,
                subInnerVlanIdAny, vtrOp, vtrPushDot1q, vtrTag1, vtrTag2);
        (*env)->SetObjectArrayElement(env, ifArray, i, ifObj);
    }

    jm->collect_indices = 0;
    vec_reset_length(jm->sw_if_dump_if_indices);
    return ifArray;
}

JNIEXPORT jint JNICALL Java_org_openvpp_vppjapi_vppConn_findOrAddBridgeDomainId0
  (JNIEnv * env, jobject obj, jstring bridgeDomain)
{
  vppjni_main_t * jm = &vppjni_main;
  static u8 * bd_name = 0;
  jint rv = -1;
  const char * bdName = (*env)->GetStringUTFChars (env, bridgeDomain, NULL);

  vec_validate_init_c_string (bd_name, bdName, strlen(bdName));
  (*env)->ReleaseStringUTFChars (env, bridgeDomain, bdName);

  vppjni_lock (jm, 6);
  rv = (jint)vjbd_find_or_add_bd (&jm->vjbd_main, bd_name);
  vppjni_unlock (jm);
  
  _vec_len(bd_name) = 0;
  return rv;
}

JNIEXPORT jint JNICALL Java_org_openvpp_vppjapi_vppConn_bridgeDomainIdFromName0
  (JNIEnv * env, jobject obj, jstring bridgeDomain)
{
  vppjni_main_t * jm = &vppjni_main;
  static u8 * bd_name = 0;
  jint rv = -1;
  const char * bdName = (*env)->GetStringUTFChars (env, bridgeDomain, NULL);

  vec_validate_init_c_string (bd_name, bdName, strlen(bdName));
  (*env)->ReleaseStringUTFChars (env, bridgeDomain, bdName);

  vppjni_lock (jm, 20);
  rv = (jint)vjbd_id_from_name(&jm->vjbd_main, (u8 *)bd_name);
  vppjni_unlock (jm);

  _vec_len(bd_name) = 0;

  return rv;
}

JNIEXPORT jint JNICALL Java_org_openvpp_vppjapi_vppConn_bridgeDomainIdFromInterfaceName0
  (JNIEnv * env, jobject obj, jstring interfaceName)
{
  vppjni_main_t * jm = &vppjni_main;
  vjbd_main_t * bdm = &jm->vjbd_main;
  u32 sw_if_index;
  jint rv = -1;
  const char * if_name;
  uword * p;

  if_name = (*env)->GetStringUTFChars (env, interfaceName, NULL);

  vppjni_lock (jm, 14);

  p = hash_get_mem (jm->sw_if_index_by_interface_name, if_name);

  if (p != 0) {
      sw_if_index = (jint) p[0];
      p = hash_get (bdm->bd_id_by_sw_if_index, sw_if_index);
      if (p != 0) {
          rv = (jint) p[0];
      }
  }

  vppjni_unlock (jm);

  (*env)->ReleaseStringUTFChars (env, interfaceName, if_name);

  return rv;
}

/* 
 * Special-case: build the interface table, maintain
 * the next loopback sw_if_index vbl.
 */
static void vl_api_sw_interface_details_t_handler
(vl_api_sw_interface_details_t * mp)
{
  vppjni_main_t * jm = &vppjni_main;
  static sw_interface_details_t empty_sw_if_details = {0,};
  sw_interface_details_t *sw_if_details;
  u32 sw_if_index;

  vppjni_lock (jm, 1);

  sw_if_index = ntohl (mp->sw_if_index);

  u8 * s = format (0, "%s%c", mp->interface_name, 0);

  if (jm->collect_indices) {
      u32 pos = vec_len(jm->sw_if_dump_if_indices);
      vec_validate(jm->sw_if_dump_if_indices, pos);
      jm->sw_if_dump_if_indices[pos] = sw_if_index;
  }

  vec_validate_init_empty(jm->sw_if_table, sw_if_index, empty_sw_if_details);
  sw_if_details = &jm->sw_if_table[sw_if_index];
  sw_if_details->valid = 1;

  snprintf((char *)sw_if_details->interface_name,
          sizeof(sw_if_details->interface_name), "%s", (char *)s);
  sw_if_details->sw_if_index = sw_if_index;
  sw_if_details->sup_sw_if_index = ntohl(mp->sup_sw_if_index);
  sw_if_details->l2_address_length = ntohl (mp->l2_address_length);
  ASSERT(sw_if_details->l2_address_length <= sizeof(sw_if_details->l2_address));
  memcpy(sw_if_details->l2_address, mp->l2_address,
          sw_if_details->l2_address_length);
  sw_if_details->sub_id = ntohl (mp->sub_id);
  sw_if_details->sub_outer_vlan_id = ntohl (mp->sub_outer_vlan_id);
  sw_if_details->sub_inner_vlan_id = ntohl (mp->sub_inner_vlan_id);
  sw_if_details->vtr_op = ntohl (mp->vtr_op);
  sw_if_details->vtr_push_dot1q = ntohl (mp->vtr_push_dot1q);
  sw_if_details->vtr_tag1 = ntohl (mp->vtr_tag1);
  sw_if_details->vtr_tag2 = ntohl (mp->vtr_tag2);

  sw_if_details->admin_up_down = mp->admin_up_down;
  sw_if_details->link_up_down = mp->link_up_down;
  sw_if_details->link_duplex = mp->link_duplex;
  sw_if_details->link_speed = mp->link_speed;
  sw_if_details->sub_dot1ad = mp->sub_dot1ad;
  sw_if_details->sub_number_of_tags = mp->sub_number_of_tags;
  sw_if_details->sub_exact_match = mp->sub_exact_match;
  sw_if_details->sub_default = mp->sub_default;
  sw_if_details->sub_outer_vlan_id_any = mp->sub_outer_vlan_id_any;
  sw_if_details->sub_inner_vlan_id_any = mp->sub_inner_vlan_id_any;

  hash_set_mem (jm->sw_if_index_by_interface_name, s, sw_if_index);
  DEBUG_LOG ("Got interface %s", (char *)s);

  /* In sub interface case, fill the sub interface table entry */
  if (mp->sw_if_index != mp->sup_sw_if_index) {
    sw_interface_subif_t * sub = NULL;

    vec_add2(jm->sw_if_subif_table, sub, 1);

    vec_validate(sub->interface_name, strlen((char *)s) + 1);
    strncpy((char *)sub->interface_name, (char *)s,
            vec_len(sub->interface_name));
    sub->sw_if_index = ntohl(mp->sw_if_index);
    sub->sub_id = ntohl(mp->sub_id);

    sub->sub_dot1ad = mp->sub_dot1ad;
    sub->sub_number_of_tags = mp->sub_number_of_tags;
    sub->sub_outer_vlan_id = ntohs(mp->sub_outer_vlan_id);
    sub->sub_inner_vlan_id = ntohs(mp->sub_inner_vlan_id);
    sub->sub_exact_match = mp->sub_exact_match;
    sub->sub_default = mp->sub_default;
    sub->sub_outer_vlan_id_any = mp->sub_outer_vlan_id_any;
    sub->sub_inner_vlan_id_any = mp->sub_inner_vlan_id_any;

    /* vlan tag rewrite */
    sub->vtr_op = ntohl(mp->vtr_op);
    sub->vtr_push_dot1q = ntohl(mp->vtr_push_dot1q);
    sub->vtr_tag1 = ntohl(mp->vtr_tag1);
    sub->vtr_tag2 = ntohl(mp->vtr_tag2);
  }
  vppjni_unlock (jm);
}

static void vl_api_sw_interface_set_flags_t_handler
(vl_api_sw_interface_set_flags_t * mp)
{
  /* $$$ nothing for the moment */
}

static jintArray create_array_of_bd_ids(JNIEnv * env, jint bd_id)
{
    vppjni_main_t *jm = &vppjni_main;
    vjbd_main_t * bdm = &jm->vjbd_main;
    u32 *buf = NULL;
    u32 i;

    if (bd_id != ~0) {
        vec_add1(buf, bd_id);
    } else {
        for (i = 0; i < vec_len(bdm->bd_oper); i++) {
            u32 bd_id = bdm->bd_oper[i].bd_id;
            vec_add1(buf, bd_id);
        }
    }

    jintArray bdidArray = (*env)->NewIntArray(env, vec_len(buf));

    (*env)->SetIntArrayRegion(env, bdidArray, 0, vec_len(buf), (int*)buf);

    vec_free(buf);

    return bdidArray;
}

static void bridge_domain_oper_free(void)
{
    vppjni_main_t *jm = &vppjni_main;
    vjbd_main_t *bdm = &jm->vjbd_main;
    u32 i;

    for (i = 0; i < vec_len(bdm->bd_oper); i++) {
        vec_free(bdm->bd_oper->l2fib_oper);
    }
    vec_reset_length(bdm->bd_oper);
    hash_free(bdm->bd_id_by_sw_if_index);
    hash_free(bdm->oper_bd_index_by_bd_id);
}

JNIEXPORT jintArray JNICALL Java_org_openvpp_vppjapi_vppConn_bridgeDomainDump0
(JNIEnv * env, jobject obj, jint bd_id)
{
    vppjni_main_t *jm = &vppjni_main;
    vl_api_bridge_domain_dump_t * mp;
    u32 my_context_id;
    f64 timeout;
    int rv;
    rv = vppjni_sanity_check (jm);
    if (rv) return NULL;

    vppjni_lock (jm, 15);

    if (~0 == bd_id) {
        bridge_domain_oper_free();
    }

    my_context_id = vppjni_get_context_id (jm);
    M(BRIDGE_DOMAIN_DUMP, bridge_domain_dump);
    mp->context = clib_host_to_net_u32 (my_context_id);
    mp->bd_id = clib_host_to_net_u32(bd_id);
    S;

    /* Use a control ping for synchronization */
    {
        vl_api_control_ping_t * mp;
        M(CONTROL_PING, control_ping);
        S;
    }

    WNR;
    if (0 != rv) {
        return NULL;
    }

    jintArray ret = create_array_of_bd_ids(env, bd_id);

    vppjni_unlock (jm);

    return ret;
}

static void
vl_api_bridge_domain_details_t_handler (vl_api_bridge_domain_details_t * mp)
{
  vppjni_main_t *jm = &vppjni_main;
  vjbd_main_t * bdm = &jm->vjbd_main;
  vjbd_oper_t * bd_oper;
  u32 bd_id, bd_index;

  bd_id = ntohl (mp->bd_id);

  bd_index = vec_len(bdm->bd_oper);
  vec_validate (bdm->bd_oper, bd_index);
  bd_oper = vec_elt_at_index(bdm->bd_oper, bd_index);

  hash_set(bdm->oper_bd_index_by_bd_id, bd_id, bd_index);

  bd_oper->bd_id = bd_id;
  bd_oper->flood = mp->flood != 0;
  bd_oper->forward = mp->forward != 0;
  bd_oper->learn =  mp->learn != 0;
  bd_oper->uu_flood = mp->uu_flood != 0;
  bd_oper->arp_term = mp->arp_term != 0;
  bd_oper->bvi_sw_if_index = ntohl (mp->bvi_sw_if_index);
  bd_oper->n_sw_ifs = ntohl (mp->n_sw_ifs);

  bd_oper->bd_sw_if_oper = 0;
}

static void
vl_api_bridge_domain_sw_if_details_t_handler
(vl_api_bridge_domain_sw_if_details_t * mp)
{
  vppjni_main_t *jm = &vppjni_main;
  vjbd_main_t * bdm = &jm->vjbd_main;
  bd_sw_if_oper_t * bd_sw_if_oper;
  u32 bd_id, sw_if_index;

  bd_id = ntohl (mp->bd_id);
  sw_if_index = ntohl (mp->sw_if_index);

  uword *p;
  p = hash_get (bdm->oper_bd_index_by_bd_id, bd_id);
  if (p == 0) {
      clib_warning("Invalid bd_id %d in bridge_domain_sw_if_details_t_handler", bd_id);
      return;
  }
  u32 oper_bd_index = (jint) p[0];
  vjbd_oper_t *bd_oper = vec_elt_at_index(bdm->bd_oper, oper_bd_index);

  u32 len = vec_len(bd_oper->bd_sw_if_oper);
  vec_validate(bd_oper->bd_sw_if_oper, len);
  bd_sw_if_oper = &bd_oper->bd_sw_if_oper[len];
  bd_sw_if_oper->bd_id = bd_id;
  bd_sw_if_oper->sw_if_index = sw_if_index;
  bd_sw_if_oper->shg = mp->shg;

  hash_set(bdm->bd_id_by_sw_if_index, sw_if_index, bd_id);
}

static const char* interface_name_from_sw_if_index(u32 sw_if_index)
{
    vppjni_main_t *jm = &vppjni_main;

    if (sw_if_index >= vec_len(jm->sw_if_table)) {
        return NULL;
    }
    if (!jm->sw_if_table[sw_if_index].valid) {
        return NULL;
    }
    return (const char*)jm->sw_if_table[sw_if_index].interface_name;
}

JNIEXPORT jobject JNICALL Java_org_openvpp_vppjapi_vppConn_getBridgeDomainDetails0
(JNIEnv * env, jobject obj, jint bdId)
{
    vppjni_main_t *jm = &vppjni_main;
    vjbd_main_t * bdm = &jm->vjbd_main;
    u32 oper_bd_index;
    u32 bd_id = bdId;
    jobject rv = NULL;
    uword *p;

    vppjni_lock (jm, 16);

    p = hash_get (bdm->oper_bd_index_by_bd_id, bd_id);
    if (p == 0) {
        rv = NULL;
        goto out;
    }
    oper_bd_index = (jint) p[0];

    vjbd_oper_t *bd_oper = vec_elt_at_index(bdm->bd_oper, oper_bd_index);


    /* setting BridgeDomainDetails */

    jobject bddObj = vppBridgeDomainDetailsObject(env);

    u8 *vec_bd_name = vjbd_oper_name_from_id(bdm, bd_id);
    if (NULL == vec_bd_name) {
        rv = NULL;
        goto out;
    }
    char *str_bd_name = (char*)format (0, "%s%c", vec_bd_name, 0);
    vec_free(vec_bd_name);
    jstring bdName = (*env)->NewStringUTF(env, str_bd_name);
    vec_free(str_bd_name);
    if (NULL == bdName) {
        rv = NULL;
        goto out;
    }

    set_vppBridgeDomainDetails_name(env, bddObj, bdName);
    set_vppBridgeDomainDetails_bdId(env, bddObj, bdId);
    set_vppBridgeDomainDetails_flood(env, bddObj, (jboolean)bd_oper->flood);
    set_vppBridgeDomainDetails_uuFlood(env, bddObj, (jboolean)bd_oper->uu_flood);
    set_vppBridgeDomainDetails_forward(env, bddObj, (jboolean)bd_oper->forward);
    set_vppBridgeDomainDetails_learn(env, bddObj, (jboolean)bd_oper->learn);
    set_vppBridgeDomainDetails_arpTerm(env, bddObj, (jboolean)bd_oper->arp_term);

    jstring bviInterfaceName = NULL;
    if (~0 != bd_oper->bvi_sw_if_index) {
        const char *str_if_name = interface_name_from_sw_if_index(bd_oper->bvi_sw_if_index);
        if (NULL == str_if_name) {
            clib_warning("Could not get interface name for sw_if_index %d", bd_oper->bvi_sw_if_index);
            rv = NULL;
            goto out;
        }
        bviInterfaceName = (*env)->NewStringUTF(env, str_if_name);
        if (NULL == bviInterfaceName) {
            rv = NULL;
            goto out;
        }
    }

    set_vppBridgeDomainDetails_bviInterfaceName(env, bddObj, bviInterfaceName);

    /* setting BridgeDomainInterfaceDetails */

    u32 len = vec_len(bd_oper->bd_sw_if_oper);
    ASSERT(len == bd_oper->n_sw_ifs);

    jobjectArray bdidArray = vppBridgeDomainInterfaceDetailsArray(env, len);

    u32 i;
    for (i = 0; i < len; i++) {
        bd_sw_if_oper_t *sw_if_oper = &bd_oper->bd_sw_if_oper[i];

        jobject bdidObj = vppBridgeDomainInterfaceDetailsObject(env);
        (*env)->SetObjectArrayElement(env, bdidArray, i, bdidObj);

        u32 sw_if_index = sw_if_oper->sw_if_index;
        const char *str_if_name = interface_name_from_sw_if_index(sw_if_index);
        if (NULL == str_if_name) {
            rv = NULL;
            goto out;
        }
        jstring interfaceName = (*env)->NewStringUTF(env, str_if_name);
        if (NULL == interfaceName) {
            rv = NULL;
            goto out;
        }

        set_vppBridgeDomainInterfaceDetails_interfaceName(env, bdidObj, interfaceName);
        set_vppBridgeDomainInterfaceDetails_splitHorizonGroup(env, bdidObj, (jbyte)sw_if_oper->shg);
    }

    set_vppBridgeDomainDetails_interfaces(env, bddObj, bdidArray);

    rv = bddObj;

out:

    vppjni_unlock (jm);

    return rv;
}

static jobject l2_fib_create_object(JNIEnv *env, bd_l2fib_oper_t *l2_fib)
{
    u32 sw_if_index = l2_fib->sw_if_index;
    const char *str_if_name = interface_name_from_sw_if_index(sw_if_index);
    if (NULL == str_if_name) {
        return NULL;
    }
    jstring interfaceName = (*env)->NewStringUTF(env, str_if_name);
    if (NULL == interfaceName) {
        return NULL;
    }

    jbyteArray physAddr = (*env)->NewByteArray(env, 6);
    (*env)->SetByteArrayRegion(env, physAddr, 0, 6,
            (signed char*)l2_fib->mac_addr.fields.mac);
    jboolean staticConfig = !l2_fib->learned;
    jstring outgoingInterface = interfaceName;
    jboolean filter = l2_fib->filter;
    jboolean bridgedVirtualInterface = l2_fib->bvi;

    return vppL2FibObject(env, physAddr, staticConfig, outgoingInterface, filter, bridgedVirtualInterface);
}

JNIEXPORT jobjectArray JNICALL Java_org_openvpp_vppjapi_vppConn_l2FibTableDump0
(JNIEnv * env, jobject obj, jint bd_id)
{
  vppjni_main_t *jm = &vppjni_main;
  vjbd_main_t * bdm = &jm->vjbd_main;
  vl_api_l2_fib_table_dump_t *mp;
  jobjectArray l2FibArray = NULL;
  vjbd_oper_t *bd_oper;
  u32 oper_bd_index;
  uword *p;
  f64 timeout;
  int rv;
  u32 i;

  vppjni_lock (jm, 17);

  //vjbd_l2fib_oper_reset (bdm);

  p = hash_get (bdm->oper_bd_index_by_bd_id, bd_id);
  if (p == 0) {
      goto done;
  }
  oper_bd_index = p[0];
  bd_oper = vec_elt_at_index(bdm->bd_oper, oper_bd_index);
  vec_reset_length (bd_oper->l2fib_oper);

  /* Get list of l2 fib table entries */
  M(L2_FIB_TABLE_DUMP, l2_fib_table_dump);
  mp->bd_id = ntohl(bd_id);
  S;

  /* Use a control ping for synchronization */
  {
    vl_api_control_ping_t * mp;
    M(CONTROL_PING, control_ping);
    S;
  }

  WNR;
  if (0 != rv) {
      goto done;
  }

  u32 count = vec_len(bd_oper->l2fib_oper);
  bd_l2fib_oper_t *l2fib_oper = bd_oper->l2fib_oper;

  l2FibArray = vppL2FibArray(env, count);
  for (i = 0; i < count; i++) {
      bd_l2fib_oper_t *l2_fib = &l2fib_oper[i];
      jobject l2FibObj = l2_fib_create_object(env, l2_fib);
      (*env)->SetObjectArrayElement(env, l2FibArray, i, l2FibObj);
  }

done:
  vppjni_unlock (jm);

  return l2FibArray;
}

static void
vl_api_l2_fib_table_entry_t_handler (vl_api_l2_fib_table_entry_t * mp)
{
  //static u8 * mac_addr;
  vppjni_main_t *jm = &vppjni_main;
  vjbd_main_t * bdm = &jm->vjbd_main;
  vjbd_oper_t * bd_oper;
  u32 bd_id, oper_bd_index;
  //uword mhash_val_l2fi;
  bd_l2fib_oper_t * l2fib_oper;
  l2fib_u64_mac_t * l2fe_u64_mac = (l2fib_u64_mac_t *)&mp->mac;

  bd_id = ntohl (mp->bd_id);

  uword *p = hash_get (bdm->oper_bd_index_by_bd_id, bd_id);
  if (p == 0) {
      return;
  }
  oper_bd_index = (jint) p[0];
  bd_oper = vec_elt_at_index(bdm->bd_oper, oper_bd_index);

#if 0
  vec_validate (mac_addr, MAC_ADDRESS_SIZE);
  memcpy (mac_addr, l2fe_u64_mac->fields.mac, MAC_ADDRESS_SIZE);
  mhash_val_l2fi = vec_len (bd_oper->l2fib_oper);
  if (mhash_elts (&bd_oper->l2fib_index_by_mac) == 0)
    mhash_init (&bd_oper->l2fib_index_by_mac, sizeof (u32), MAC_ADDRESS_SIZE);
  mhash_set_mem (&bd_oper->l2fib_index_by_mac, mac_addr, &mhash_val_l2fi, 0);
#endif

  vec_add2 (bd_oper->l2fib_oper, l2fib_oper, 1);

  l2fib_oper->bd_id = bd_id;
  l2fib_oper->mac_addr.raw = l2fib_mac_to_u64 (l2fe_u64_mac->fields.mac);
  l2fib_oper->sw_if_index = ntohl (mp->sw_if_index);
  l2fib_oper->learned = !mp->static_mac;
  l2fib_oper->filter = mp->filter_mac;
  l2fib_oper->bvi = mp->bvi_mac;
}

static int ipAddressDump
(JNIEnv * env, jobject obj, jstring interfaceName, jboolean isIPv6)
{
    vppjni_main_t *jm = &vppjni_main;
    vl_api_ip_address_dump_t * mp;
    const char *if_name;
    u32 my_context_id;
    u32 sw_if_index;
    f64 timeout;
    uword *p;
    int rv = 0;

    if (NULL == interfaceName) {
        return -1;
    }

    if_name = (*env)->GetStringUTFChars (env, interfaceName, NULL);
    p = hash_get_mem (jm->sw_if_index_by_interface_name, if_name);
    (*env)->ReleaseStringUTFChars (env, interfaceName, if_name);
    if (p == 0) {
        return -1;
    }
    sw_if_index = (u32) p[0];

    rv = vppjni_sanity_check (jm);
    if (0 != rv) {
        return rv;
    }

    my_context_id = vppjni_get_context_id (jm);
    M(IP_ADDRESS_DUMP, ip_address_dump);
    mp->context = clib_host_to_net_u32 (my_context_id);
    mp->sw_if_index = clib_host_to_net_u32(sw_if_index);
    mp->is_ipv6 = isIPv6;
    jm->is_ipv6 = isIPv6;
    S;

    /* Use a control ping for synchronization */
    {
      vl_api_control_ping_t * mp;
      M(CONTROL_PING, control_ping);
      S;
    }

    WNR;

    return rv;
}

JNIEXPORT jobjectArray JNICALL Java_org_openvpp_vppjapi_vppConn_ipv4AddressDump0
(JNIEnv * env, jobject obj, jstring interfaceName)
{
    vppjni_main_t *jm = &vppjni_main;
    jobject returnArray = NULL;
    int i;

    vppjni_lock (jm, 18);

    vec_reset_length(jm->ipv4_addresses);

    if (0 != ipAddressDump(env, obj, interfaceName, 0)) {
        goto done;
    }

    u32 count = vec_len(jm->ipv4_addresses);
    ipv4_address_t *ipv4_address = jm->ipv4_addresses;

    jobjectArray ipv4AddressArray = vppIPv4AddressArray(env, count);

    for (i = 0; i < count; i++) {
        ipv4_address_t *address = &ipv4_address[i];

        jint ip = address->ip;
        jbyte prefixLength = address->prefix_length;

        jobject ipv4AddressObj = vppIPv4AddressObject(env, ip, prefixLength);

        (*env)->SetObjectArrayElement(env, ipv4AddressArray, i, ipv4AddressObj);
    }

    returnArray = ipv4AddressArray;

done:
    vppjni_unlock (jm);
    return returnArray;
}

JNIEXPORT jobjectArray JNICALL Java_org_openvpp_vppjapi_vppConn_ipv6AddressDump0
(JNIEnv * env, jobject obj, jstring interfaceName)
{
    vppjni_main_t *jm = &vppjni_main;
    jobject returnArray = NULL;
    int i;

    vppjni_lock (jm, 19);

    vec_reset_length(jm->ipv6_addresses);

    if (0 != ipAddressDump(env, obj, interfaceName, 1)) {
        goto done;
    }

    u32 count = vec_len(jm->ipv6_addresses);
    ipv6_address_t *ipv6_address = jm->ipv6_addresses;

    jobjectArray ipv6AddressArray = vppIPv6AddressArray(env, count);

    for (i = 0; i < count; i++) {
        ipv6_address_t *address = &ipv6_address[i];

        jbyteArray ip = (*env)->NewByteArray(env, 16);
        (*env)->SetByteArrayRegion(env, ip, 0, 16,
                (signed char*)address->ip);

        jbyte prefixLength = address->prefix_length;

        jobject ipv6AddressObj = vppIPv6AddressObject(env, ip, prefixLength);

        (*env)->SetObjectArrayElement(env, ipv6AddressArray, i, ipv6AddressObj);
    }

    returnArray = ipv6AddressArray;

done:
    vppjni_unlock (jm);
    return returnArray;
}

static void vl_api_ip_address_details_t_handler (vl_api_ip_address_details_t * mp)
{
    vppjni_main_t * jm = &vppjni_main;

    if (!jm->is_ipv6) {
        ipv4_address_t *address = 0;
        vec_add2(jm->ipv4_addresses, address, 1);
        memcpy(&address->ip, mp->ip, 4);
        address->prefix_length = mp->prefix_length;
    } else {
        ipv6_address_t *address = 0;
        vec_add2(jm->ipv6_addresses, address, 1);
        memcpy(address->ip, mp->ip, 16);
        address->prefix_length = mp->prefix_length;
    }
}

#define VXLAN_TUNNEL_INTERFACE_NAME_PREFIX "vxlan_tunnel"

JNIEXPORT jobjectArray JNICALL Java_org_openvpp_vppjapi_vppConn_vxlanTunnelDump0
(JNIEnv * env, jobject obj, jint swIfIndex)
{
    vppjni_main_t *jm = &vppjni_main;
    vl_api_vxlan_tunnel_dump_t * mp;
    jobjectArray returnArray = NULL;
    u32 my_context_id;
    f64 timeout;
    int rv = 0;
    int i;

    vppjni_lock (jm, 22);

    vec_reset_length(jm->vxlan_tunnel_details);

    my_context_id = vppjni_get_context_id (jm);
    M(VXLAN_TUNNEL_DUMP, vxlan_tunnel_dump);
    mp->context = clib_host_to_net_u32 (my_context_id);
    mp->sw_if_index = clib_host_to_net_u32 (swIfIndex);
    S;

    /* Use a control ping for synchronization */
    {
      vl_api_control_ping_t * mp;
      M(CONTROL_PING, control_ping);
      S;
    }

    WNR;
    if (0 != rv) {
        goto done;
    }

    u32 count = vec_len(jm->vxlan_tunnel_details);

    jobjectArray vxlanTunnelDetailsArray = vppVxlanTunnelDetailsArray(env, count);

    for (i = 0; i < count; i++) {
        vxlan_tunnel_details_t *details = &jm->vxlan_tunnel_details[i];

        jint src_address = details->src_address;
        jint dst_address = details->dst_address;
        jint encap_vrf_id = details->encap_vrf_id;
        jint vni = details->vni;
        jint decap_next_index = details->decap_next_index;

        jobject vxlanTunnelDetailsObj = vppVxlanTunnelDetailsObject(env,
                src_address, dst_address, encap_vrf_id, vni, decap_next_index);

        (*env)->SetObjectArrayElement(env, vxlanTunnelDetailsArray, i,
                vxlanTunnelDetailsObj);
    }

    returnArray = vxlanTunnelDetailsArray;

done:
    vppjni_unlock (jm);
    return returnArray;
}

static void vl_api_vxlan_tunnel_details_t_handler
(vl_api_vxlan_tunnel_details_t * mp)
{
    vppjni_main_t * jm = &vppjni_main;
    vxlan_tunnel_details_t *tunnel_details;

    vec_add2(jm->vxlan_tunnel_details, tunnel_details, 1);
    tunnel_details->src_address = ntohl(mp->src_address);
    tunnel_details->dst_address = ntohl(mp->dst_address);
    tunnel_details->encap_vrf_id = ntohl(mp->encap_vrf_id);
    tunnel_details->vni = ntohl(mp->vni);
    tunnel_details->decap_next_index = ntohl(mp->decap_next_index);
}

/* cleanup handler for RX thread */
static void cleanup_rx_thread(void *arg)
{
  vppjni_main_t * jm = &vppjni_main;

  vppjni_lock (jm, 99);

  int getEnvStat = (*jm->jvm)->GetEnv(jm->jvm, (void **)&(jm->jenv), JNI_VERSION_1_6);
  if (getEnvStat == JNI_EVERSION) {
    clib_warning ("Unsupported JNI version\n");
    jm->retval = -999;
    goto out;
  } else if (getEnvStat != JNI_EDETACHED) {
    (*jm->jvm)->DetachCurrentThread(jm->jvm);
  }
out:
  vppjni_unlock (jm);
}

static void
vl_api_show_version_reply_t_handler (vl_api_show_version_reply_t * mp)
{
  vppjni_main_t * jm = &vppjni_main;
  i32 retval = ntohl(mp->retval);

  if (retval >= 0) {
    DEBUG_LOG ("show version request succeeded(%d)");
    strncpy((char*)jm->program_name, (const char*)mp->program,
            sizeof(jm->program_name)-1);
    jm->program_name[sizeof(jm->program_name)-1] = 0;

    strncpy((char*)jm->build_directory, (const char*)mp->build_directory,
            sizeof(jm->build_directory)-1);
    jm->build_directory[sizeof(jm->build_directory)-1] = 0;

    strncpy((char*)jm->version, (const char*)mp->version,
            sizeof(jm->version)-1);
    jm->version[sizeof(jm->version)-1] = 0;

    strncpy((char*)jm->build_date, (const char*)mp->build_date,
            sizeof(jm->build_date)-1);
    jm->build_date[sizeof(jm->build_date)-1] = 0;
  } else {
    clib_error ("show version request failed(%d)", retval);
  }
  jm->retval = retval;
  jm->result_ready = 1;
}

static void vl_api_want_stats_reply_t_handler (vl_api_want_stats_reply_t * mp)
{
  vppjni_main_t * jm = &vppjni_main;
  jm->retval = mp->retval; // FIXME: vpp api does not do ntohl on this retval
  jm->result_ready = 1;
}

// control ping needs to be very first thing called
// to attach rx thread to java thread
static void vl_api_control_ping_reply_t_handler
(vl_api_control_ping_reply_t * mp)
{
  vppjni_main_t * jm = &vppjni_main;
  i32 retval = ntohl(mp->retval);
  jm->retval = retval;

  // attach to java thread if not attached
  int getEnvStat = (*jm->jvm)->GetEnv(jm->jvm, (void **)&(jm->jenv), JNI_VERSION_1_6);
  if (getEnvStat == JNI_EDETACHED) {
    if ((*jm->jvm)->AttachCurrentThread(jm->jvm, (void **)&(jm->jenv), NULL) != 0) {
      clib_warning("Failed to attach thread\n");
      jm->retval = -999;
      goto out;
    }

    // workaround as we can't use pthread_cleanup_push
    pthread_key_create(&jm->cleanup_rx_thread_key, cleanup_rx_thread);
    // destructor is only called if the value of key is non null
    pthread_setspecific(jm->cleanup_rx_thread_key, (void *)1);
  } else if (getEnvStat == JNI_EVERSION) {
    clib_warning ("Unsupported JNI version\n");
    jm->retval = -999;
    goto out;
  }
  // jm->jenv is now stable global reference that can be reused (only within RX thread)

#if 0
  // ! callback system removed for now
  //
  // get issuer msg-id
  p = hash_get (jm->ping_hash, context);
  if (p != 0) { // ping marks end of some dump call
    JNIEnv *env = jm->jenv;
    u16 msg_id = (u16)p[0];

    // we will no longer need this
    hash_unset (jm->ping_hash, context);

    // get original caller obj
    p = hash_get (jm->callback_hash, context);

    if (p == 0) // don't have callback stored
      goto out;

    jobject obj = (jobject)p[0]; // object that called original call

    switch (msg_id) {
      case VL_API_SW_INTERFACE_DUMP:
        if (0 != sw_if_dump_call_all_callbacks(obj)) {
          goto out2;
        }
        break;
      default:
        clib_warning("Unhandled control ping issuer msg-id: %d", msg_id);
        goto out2;
        break;
    }
  out2:
    // free the saved obj
    hash_unset (jm->callback_hash, context);
    // delete global reference
    (*env)->DeleteGlobalRef(env, obj);
  }
#endif

out:
  jm->result_ready = 1;
}

#define VPPJNI_DEBUG_COUNTERS 0

static void vl_api_vnet_interface_counters_t_handler
(vl_api_vnet_interface_counters_t *mp)
{
  vppjni_main_t *jm = &vppjni_main;
  CLIB_UNUSED(char *counter_name);
  u32 count, sw_if_index;
  int i;
  static sw_interface_stats_t empty_stats = {0, };

  vppjni_lock (jm, 12);
  count = ntohl (mp->count);
  sw_if_index = ntohl (mp->first_sw_if_index);
  if (mp->is_combined == 0) {
    u64 * vp, v;
    vp = (u64 *) mp->data;

    for (i = 0; i < count; i++) {
      sw_interface_details_t *sw_if = NULL;

      v = clib_mem_unaligned (vp, u64);
      v = clib_net_to_host_u64 (v);
      vp++;

      if (sw_if_index < vec_len(jm->sw_if_table))
        sw_if = vec_elt_at_index(jm->sw_if_table, sw_if_index);

      if (sw_if /* && (sw_if->admin_up_down == 1)*/ && sw_if->interface_name[0] != 0)
        {
          vec_validate_init_empty(jm->sw_if_stats_by_sw_if_index, sw_if_index, empty_stats);
          sw_interface_stats_t * s = vec_elt_at_index(jm->sw_if_stats_by_sw_if_index, sw_if_index);

          s->sw_if_index = sw_if_index;
          s->valid = 1;

          switch (mp->vnet_counter_type) {
          case  VNET_INTERFACE_COUNTER_DROP:
            counter_name = "drop";
            s->rx.pkts.discard = v;
            break;
          case  VNET_INTERFACE_COUNTER_PUNT:
            counter_name = "punt";
            s->rx.pkts.unknown_proto = v;
            break;
          case  VNET_INTERFACE_COUNTER_IP4:
            counter_name = "ip4";
            s->rx.pkts.ip4 = v;
            break;
          case  VNET_INTERFACE_COUNTER_IP6:
            counter_name = "ip6";
            s->rx.pkts.ip6 = v;
            break;
          case  VNET_INTERFACE_COUNTER_RX_NO_BUF:
            counter_name = "rx-no-buf";
            s->rx.pkts.fifo_full = v;
            break;
          case  VNET_INTERFACE_COUNTER_RX_MISS:
            counter_name = "rx-miss";
            s->rx.pkts.miss = v;
            break;
          case  VNET_INTERFACE_COUNTER_RX_ERROR:
            counter_name = "rx-error";
            s->rx.pkts.error = v;
            break;
          case  VNET_INTERFACE_COUNTER_TX_ERROR:
            counter_name = "tx-error (fifo-full)";
            s->tx.pkts.fifo_full = v;
            break;
          default:
            counter_name = "bogus";
            break;
          }

#if VPPJNI_DEBUG_COUNTERS == 1
          clib_warning ("%s (%d): %s (%lld)\n", sw_if->interface_name, s->sw_if_index,
                        counter_name, v);
#endif
        }
      sw_if_index++;
    }
  } else {
    vlib_counter_t *vp;
    u64 packets, bytes;
    vp = (vlib_counter_t *) mp->data;

    for (i = 0; i < count; i++) {
      sw_interface_details_t *sw_if = NULL;

      packets = clib_mem_unaligned (&vp->packets, u64);
      packets = clib_net_to_host_u64 (packets);
      bytes = clib_mem_unaligned (&vp->bytes, u64);
      bytes = clib_net_to_host_u64 (bytes);
      vp++;

      if (sw_if_index < vec_len(jm->sw_if_table))
        sw_if = vec_elt_at_index(jm->sw_if_table, sw_if_index);

      if (sw_if /* && (sw_if->admin_up_down == 1) */ && sw_if->interface_name[0] != 0)
        {
          vec_validate_init_empty(jm->sw_if_stats_by_sw_if_index, sw_if_index, empty_stats);
          sw_interface_stats_t * s = vec_elt_at_index(jm->sw_if_stats_by_sw_if_index, sw_if_index);

          s->valid = 1;
          s->sw_if_index = sw_if_index;

          switch (mp->vnet_counter_type) {
          case  VNET_INTERFACE_COUNTER_RX:
            s->rx.pkts.unicast = packets;
            s->rx.octets = bytes;
            counter_name = "rx";
            break;

          case  VNET_INTERFACE_COUNTER_TX:
            s->tx.pkts.unicast = packets;
            s->tx.octets = bytes;
            counter_name = "tx";
            break;

          default:
            counter_name = "bogus";
            break;
          }

#if VPPJNI_DEBUG_COUNTERS == 1
          clib_warning ("%s (%d): %s.packets %lld\n", 
                   sw_if->interface_name,
                   sw_if_index, counter_name, packets);
          clib_warning ("%s (%d): %s.bytes %lld\n", 
                   sw_if->interface_name,
                   sw_if_index, counter_name, bytes);
#endif
        }
      sw_if_index++;
    }
  }
  vppjni_unlock (jm);
}

jint JNI_OnLoad(JavaVM *vm, void *reserved) {
  vppjni_main_t * jm = &vppjni_main;
  JNIEnv* env;
  if ((*vm)->GetEnv(vm, (void**) &env, JNI_VERSION_1_6) != JNI_OK) {
    return JNI_ERR;
  }

  if (vppjni_init(env) != 0) {
      return JNI_ERR;
  }

  jm->jvm = vm;
  return JNI_VERSION_1_6;
}

void JNI_OnUnload(JavaVM *vm, void *reserved) {
  vppjni_main_t * jm = &vppjni_main;
  JNIEnv* env;
  if ((*vm)->GetEnv(vm, (void**) &env, JNI_VERSION_1_6) != JNI_OK) {
    return;
  }

  vppjni_uninit(env);

  jm->jenv = NULL;
  jm->jvm = NULL;
}

#define foreach_vpe_api_msg                             \
_(CONTROL_PING_REPLY, control_ping_reply)               \
_(SW_INTERFACE_DETAILS, sw_interface_details)           \
_(SHOW_VERSION_REPLY, show_version_reply)               \
_(WANT_STATS_REPLY, want_stats_reply)                   \
_(VNET_INTERFACE_COUNTERS, vnet_interface_counters)     \
_(SW_INTERFACE_SET_FLAGS, sw_interface_set_flags)       \
_(BRIDGE_DOMAIN_DETAILS, bridge_domain_details)         \
_(BRIDGE_DOMAIN_SW_IF_DETAILS, bridge_domain_sw_if_details) \
_(L2_FIB_TABLE_ENTRY, l2_fib_table_entry)               \
_(IP_ADDRESS_DETAILS, ip_address_details)               \
_(VXLAN_TUNNEL_DETAILS, vxlan_tunnel_details)

static int connect_to_vpe(char *name)
{
  vppjni_main_t * jm = &vppjni_main;
  api_main_t * am = &api_main;

  if (vl_client_connect_to_vlib("/vpe-api", name, 32) < 0)
    return -1;

  jm->my_client_index = am->my_client_index;
  jm->vl_input_queue = am->shmem_hdr->vl_input_queue;

#define _(N,n)                                                  \
    vl_msg_api_set_handlers(VL_API_##N, #n,                     \
                           vl_api_##n##_t_handler,	        \
                           vl_noop_handler,                     \
                           vl_api_##n##_t_endian,               \
                           vl_api_##n##_t_print,                \
                           sizeof(vl_api_##n##_t), 1); 
    foreach_vpe_api_msg;
#undef _
  

  return 0;
}

/* Format an IP6 address. */
u8 * format_ip6_address (u8 * s, va_list * args)
{
  ip6_address_t * a = va_arg (*args, ip6_address_t *);
  u32 max_zero_run = 0, this_zero_run = 0;
  int max_zero_run_index = -1, this_zero_run_index=0;
  int in_zero_run = 0, i;
  int last_double_colon = 0;

  /* Ugh, this is a pain. Scan forward looking for runs of 0's */
  for (i = 0; i < ARRAY_LEN (a->as_u16); i++)
    {
      if (a->as_u16[i] == 0)
        {
          if (in_zero_run)
            this_zero_run++;
          else
            {
              in_zero_run = 1;
              this_zero_run =1;
              this_zero_run_index = i;
            }
        }
      else
        {
          if (in_zero_run)
            {
              /* offer to compress the biggest run of > 1 zero */
              if (this_zero_run > max_zero_run && this_zero_run > 1)
                {
                  max_zero_run_index = this_zero_run_index;
                  max_zero_run = this_zero_run;
                }
            }
          in_zero_run = 0;
          this_zero_run = 0;
        }
    }

  if (in_zero_run)
    {
      if (this_zero_run > max_zero_run && this_zero_run > 1)
        {
          max_zero_run_index = this_zero_run_index;
          max_zero_run = this_zero_run;
        }
    }
  
  for (i = 0; i < ARRAY_LEN (a->as_u16); i++)
    {
      if (i == max_zero_run_index)
        {
	  s = format (s, "::");
          i += max_zero_run - 1;
          last_double_colon = 1;
        }
      else
	{
	  s = format (s, "%s%x",
		      (last_double_colon || i == 0) ? "" : ":",
		      clib_net_to_host_u16 (a->as_u16[i]));
	  last_double_colon = 0;
	}
    }

  return s;
}

/* Format an IP4 address. */
u8 * format_ip4_address (u8 * s, va_list * args)
{
  u8 * a = va_arg (*args, u8 *);
  return format (s, "%d.%d.%d.%d", a[0], a[1], a[2], a[3]);
}


