/*
 * 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]);
}


