/*
 * 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_getVppVersion
  (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_setInterfaceDescription
  (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_getInterfaceDescription
(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_getRetval
(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_getInterfaceList
  (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_swIfIndexFromName
  (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_getInterfaceCounters
(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_interfaceNameFromSwIfIndex
(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_clearInterfaceTable
(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_swInterfaceDump
(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_findOrAddBridgeDomainId
  (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_bridgeDomainIdFromName
  (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_bridgeDomainIdFromInterfaceName
  (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);

    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_bridgeDomainDump
(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_getBridgeDomainDetails
(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_l2FibTableDump
(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_ipv4AddressDump
(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_ipv6AddressDump
(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_vxlanTunnelDump
(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 */
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]);
}


