From 4c42e913c4f9723d27f6501f6e1b6a13b9c2f9f8 Mon Sep 17 00:00:00 2001 From: Marek Gradzki Date: Tue, 9 Aug 2016 13:23:08 +0200 Subject: [PATCH] HONEYCOMB-228 Snat plugin jvpp support Change-Id: I5510a0ae3ecfeb5bd41c3a73e6e05465ebd96165 Signed-off-by: Marek Gradzki Signed-off-by: Maros Marsalek --- build-data/packages/plugins.mk | 3 +- plugins/snat-plugin/Makefile.am | 55 ++++++++++ plugins/snat-plugin/configure.ac | 15 +++ .../io/fd/vpp/jvpp/snat/test/CallbackApiTest.java | 70 ++++++++++++ .../snat/jvpp/io/fd/vpp/jvpp/snat/test/Readme.txt | 1 + plugins/snat-plugin/snat/jvpp_snat.c | 119 +++++++++++++++++++++ plugins/snat-plugin/snat/jvpp_snat.h | 45 ++++++++ 7 files changed, 307 insertions(+), 1 deletion(-) create mode 100644 plugins/snat-plugin/snat/jvpp/io/fd/vpp/jvpp/snat/test/CallbackApiTest.java create mode 100644 plugins/snat-plugin/snat/jvpp/io/fd/vpp/jvpp/snat/test/Readme.txt create mode 100644 plugins/snat-plugin/snat/jvpp_snat.c create mode 100644 plugins/snat-plugin/snat/jvpp_snat.h diff --git a/build-data/packages/plugins.mk b/build-data/packages/plugins.mk index 5d217c75cd4..53040194b89 100644 --- a/build-data/packages/plugins.mk +++ b/build-data/packages/plugins.mk @@ -11,7 +11,8 @@ plugins_CPPFLAGS = $(call installed_includes_fn, \ vnet \ svm \ vpp-api-test \ - vlib-api) + vlib-api \ + vpp-api) plugins_LDFLAGS = $(call installed_libs_fn, \ vppinfra \ diff --git a/plugins/snat-plugin/Makefile.am b/plugins/snat-plugin/Makefile.am index 91fec414363..081340b5ff1 100644 --- a/plugins/snat-plugin/Makefile.am +++ b/plugins/snat-plugin/Makefile.am @@ -58,3 +58,58 @@ snat_test_plugin_la_SOURCES = \ install-data-hook: @(cd $(vpppluginsdir) && $(RM) $(vppplugins_LTLIBRARIES)) @(cd $(vppapitestpluginsdir) && $(RM) $(vppapitestplugins_LTLIBRARIES)) + + + +# +# Java code generation +# +jvpp_registry_root = ../../vpp-api/java +jvpp_registry_version = 16.12 +jsnat_jarfile = jvpp-snat-$(PACKAGE_VERSION).jar +jvpp_package_dir = io/fd/vpp/jvpp/snat +jvpp_root = snat/jvpp +jvpp_target_dir = target +jvpp_target = $(jvpp_root)/$(jvpp_target_dir) +api_file=$(srcdir)/snat/snat.api + +lib_LTLIBRARIES = libjvpp_snat.la +libjvpp_snat_la_SOURCES = snat/snat.api.h snat/jvpp_snat.c snat/jvpp/io_fd_vpp_jvpp_snat_JVppSnatImpl.h +libjvpp_snat_la_LIBADD = -lvlibmemoryclient -lvlibapi -lvppinfra \ + -lpthread -lm -lrt -L$(jvpp_registry_root)/.libs -ljvpp_common +libjvpp_snat_la_LDFLAGS = -module +libjvpp_snat_la_CPPFLAGS = -I$(JAVA_HOME)/include -I$(JAVA_HOME)/include/linux -I../ -I$(srcdir)/../ + +BUILT_SOURCES += $(jvpp_root)/io_fd_vpp_jvpp_snat_JVppSnatImpl.h + +$(jvpp_root)/io_fd_vpp_jvpp_snat_JVppSnatImpl.h: defs_snat_papi.py + dir=`pwd`; \ + mkdir -p $(jvpp_target); \ + mkdir -p $(jvpp_root)/$(jvpp_package_dir); \ + cd $(jvpp_root)/$(jvpp_package_dir); \ + mkdir -p dto future callfacade callback notification test; \ + @srcdir@/$(jvpp_registry_root)/jvpp/gen/jvpp_gen.py -i $${dir}/defs_snat_papi.py --plugin_name snat --control_ping_class SnatControlPing; \ + cd -; \ + mv -f $(jvpp_root)/$(jvpp_package_dir)/jvpp_snat_gen.h $(jvpp_root)/jvpp_snat_gen.h; \ + cp $(srcdir)/$(jvpp_root)/$(jvpp_package_dir)/test/*.java $(jvpp_root)/$(jvpp_package_dir)/test/; \ + cd $(jvpp_root); \ + $(JAVAC) -classpath .:$(jvpp_target_dir):../../$(jvpp_registry_root)/jvpp-registry-$(jvpp_registry_version).jar -d $(jvpp_target_dir) $(jvpp_package_dir)/*.java \ + $(jvpp_package_dir)/dto/*.java \ + $(jvpp_package_dir)/callback/*.java \ + $(jvpp_package_dir)/notification/*.java \ + $(jvpp_package_dir)/future/*.java \ + $(jvpp_package_dir)/callfacade/*.java \ + $(jvpp_package_dir)/test/*.java \ + || (echo "snat jvpp compilation failed: $$?"; exit 1); \ + $(JAVAH) -classpath .:$(jvpp_target_dir):../../$(jvpp_registry_root)/jvpp-registry-$(jvpp_registry_version).jar -d . io.fd.vpp.jvpp.snat.JVppSnatImpl ; + +$(jsnat_jarfile): libjvpp_snat.la + cp .libs/libjvpp_snat.so.0.0.0 $(jvpp_target); \ + cd $(jvpp_target); \ + $(JAR) cfv $(JARFLAGS) ../../../$@ libjvpp_snat.so.0.0.0 $(jvpp_package_dir)/* ; cd ..; + +defs_snat_papi.py: + @echo " jSnat_sfc API"; \ + vppapigen --input $(api_file) --python defs_snat_papi.py; + +all-local: $(jsnat_jarfile) diff --git a/plugins/snat-plugin/configure.ac b/plugins/snat-plugin/configure.ac index 9af139e4073..e7408b93850 100644 --- a/plugins/snat-plugin/configure.ac +++ b/plugins/snat-plugin/configure.ac @@ -1,4 +1,5 @@ AC_INIT(snat_plugin, 1.0) +AC_CONFIG_MACRO_DIR([../../vpp-api/java/m4]) AM_INIT_AUTOMAKE AM_SILENT_RULES([yes]) AC_PREFIX_DEFAULT([/usr]) @@ -6,6 +7,20 @@ AC_PREFIX_DEFAULT([/usr]) AC_PROG_LIBTOOL AC_PROG_CC +if test -f /usr/bin/lsb_release && test `lsb_release -si` == "Ubuntu" && test `lsb_release -sr` == "14.04" && test -d /usr/lib/jvm/java-8-openjdk-amd64/ ; then + JAVA_HOME=/usr/lib/jvm/java-8-openjdk-amd64/ + JAVAC=${JAVA_HOME}/bin/javac + PATH=${JAVA_HOME}/bin/:${PATH} + break +fi + +AX_CHECK_JAVA_HOME +AX_PROG_JAVAC +AX_PROG_JAVAH +AX_PROG_JAR +AX_PROG_JAVADOC +AX_PROG_JAVA + AC_ARG_WITH(dpdk, AC_HELP_STRING([--with-dpdk],[Use the Intel dpdk]), [with_dpdk=1], diff --git a/plugins/snat-plugin/snat/jvpp/io/fd/vpp/jvpp/snat/test/CallbackApiTest.java b/plugins/snat-plugin/snat/jvpp/io/fd/vpp/jvpp/snat/test/CallbackApiTest.java new file mode 100644 index 00000000000..850e1774fbc --- /dev/null +++ b/plugins/snat-plugin/snat/jvpp/io/fd/vpp/jvpp/snat/test/CallbackApiTest.java @@ -0,0 +1,70 @@ +/* + * Copyright (c) 2016 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. + */ + +package io.fd.vpp.jvpp.snat.test; + +import io.fd.vpp.jvpp.JVpp; +import io.fd.vpp.jvpp.JVppRegistry; +import io.fd.vpp.jvpp.JVppRegistryImpl; +import io.fd.vpp.jvpp.VppCallbackException; +import io.fd.vpp.jvpp.snat.JVppSnatImpl; +import io.fd.vpp.jvpp.snat.callback.SnatInterfaceAddDelFeatureCallback; +import io.fd.vpp.jvpp.snat.dto.SnatInterfaceAddDelFeature; +import io.fd.vpp.jvpp.snat.dto.SnatInterfaceAddDelFeatureReply; + +public class CallbackApiTest { + + static class TestCallback implements SnatInterfaceAddDelFeatureCallback { + + @Override + public void onSnatInterfaceAddDelFeatureReply(final SnatInterfaceAddDelFeatureReply msg) { + System.out.printf("Received SnatInterfaceAddDelFeatureReply: context=%d\n", + msg.context); + } + + @Override + public void onError(VppCallbackException ex) { + System.out.printf("Received onError exception: call=%s, context=%d, retval=%d\n", ex.getMethodName(), + ex.getCtxId(), ex.getErrorCode()); + } + } + + public static void main(String[] args) throws Exception { + testCallbackApi(); + } + + private static void testCallbackApi() throws Exception { + System.out.println("Testing Java callback API for snat plugin"); + JVppRegistry registry = new JVppRegistryImpl("SnatCallbackApiTest"); + JVpp jvpp = new JVppSnatImpl(); + + registry.register(jvpp, new TestCallback()); + + System.out.println("Sending SnatInterfaceAddDelFeature request..."); + SnatInterfaceAddDelFeature request = new SnatInterfaceAddDelFeature(); + request.isAdd = 1; + request.isInside = 1; + request.swIfIndex = 1; + final int result = jvpp.send(request); + System.out.printf("SnatInterfaceAddDelFeature send result = %d\n", result); + + Thread.sleep(1000); + + System.out.println("Disconnecting..."); + registry.close(); + Thread.sleep(1000); + } +} diff --git a/plugins/snat-plugin/snat/jvpp/io/fd/vpp/jvpp/snat/test/Readme.txt b/plugins/snat-plugin/snat/jvpp/io/fd/vpp/jvpp/snat/test/Readme.txt new file mode 100644 index 00000000000..ac1b8f3f787 --- /dev/null +++ b/plugins/snat-plugin/snat/jvpp/io/fd/vpp/jvpp/snat/test/Readme.txt @@ -0,0 +1 @@ +sudo java -cp build-vpp-native/vpp-api/java/jvpp-registry-16.12.jar:build-vpp-native/vpp-api/java/jvpp-core-16.12.jar:build-vpp-native/plugins/snat-plugin/jvpp-snat-1.0.jar io.fd.vpp.jvpp.snat.test.CallbackApiTest diff --git a/plugins/snat-plugin/snat/jvpp_snat.c b/plugins/snat-plugin/snat/jvpp_snat.c new file mode 100644 index 00000000000..537299ae751 --- /dev/null +++ b/plugins/snat-plugin/snat/jvpp_snat.c @@ -0,0 +1,119 @@ +/* + * Copyright (c) 2016 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 + +#include +#define vl_typedefs /* define message structures */ +#include +#undef vl_typedefs + +#define vl_endianfun +#include +#undef vl_endianfun + +#define vl_print(handle, ...) +#define vl_printfun +#include +#undef vl_printfun + +/* Get the API version number */ +#define vl_api_version(n,v) static u32 api_version=(v); +#include +#undef vl_api_version + +#include +#include +#include + +#if VPPJNI_DEBUG == 1 + #define DEBUG_LOG(...) clib_warning(__VA_ARGS__) +#else + #define DEBUG_LOG(...) +#endif + +#include + +#include "snat/jvpp/io_fd_vpp_jvpp_snat_JVppSnatImpl.h" +#include "jvpp_snat.h" +#include "snat/jvpp/jvpp_snat_gen.h" + +/* + * Class: io_fd_vpp_jvpp_snat_JVppsnatImpl + * Method: init0 + * Signature: (JI)V + */ +JNIEXPORT void JNICALL Java_io_fd_vpp_jvpp_snat_JVppSnatImpl_init0 + (JNIEnv *env, jclass clazz, jobject callback, jlong queue_address, jint my_client_index) { + snat_main_t * plugin_main = &snat_main; + u8 * name; + clib_warning ("Java_io_fd_vpp_jvpp_snat_JVppSnatImpl_init0"); + + plugin_main->my_client_index = my_client_index; + plugin_main->vl_input_queue = (unix_shared_memory_queue_t *)queue_address; + + name = format (0, "snat_%08x%c", api_version, 0); + plugin_main->msg_id_base = vl_client_get_first_plugin_msg_id ((char *) name); + + plugin_main->callbackObject = (*env)->NewGlobalRef(env, callback); + plugin_main->callbackClass = (jclass)(*env)->NewGlobalRef(env, (*env)->GetObjectClass(env, callback)); + + #define _(N,n) \ + vl_msg_api_set_handlers(VL_API_##N + plugin_main->msg_id_base, #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_api_reply_handler; + #undef _ +} + +JNIEXPORT void JNICALL Java_io_fd_vpp_jvpp_snat_JVppSnatImpl_close0 +(JNIEnv *env, jclass clazz) { + snat_main_t * plugin_main = &snat_main; + + // cleanup: + (*env)->DeleteGlobalRef(env, plugin_main->callbackClass); + (*env)->DeleteGlobalRef(env, plugin_main->callbackObject); + + plugin_main->callbackClass = NULL; + plugin_main->callbackObject = NULL; +} + +/* Attach thread to JVM and cache class references when initiating JVPP SNAT */ +jint JNI_OnLoad(JavaVM *vm, void *reserved) { + JNIEnv* env; + + if ((*vm)->GetEnv(vm, (void**) &env, JNI_VERSION_1_8) != JNI_OK) { + return JNI_EVERSION; + } + + if (cache_class_references(env) != 0) { + clib_warning ("Failed to cache class references\n"); + return JNI_ERR; + } + + return JNI_VERSION_1_8; +} + +/* Clean up cached references when disposing JVPP SNAT */ +void JNI_OnUnload(JavaVM *vm, void *reserved) { + JNIEnv* env; + if ((*vm)->GetEnv(vm, (void**) &env, JNI_VERSION_1_8) != JNI_OK) { + return; + } + delete_class_references(env); +} diff --git a/plugins/snat-plugin/snat/jvpp_snat.h b/plugins/snat-plugin/snat/jvpp_snat.h new file mode 100644 index 00000000000..6426bda8834 --- /dev/null +++ b/plugins/snat-plugin/snat/jvpp_snat.h @@ -0,0 +1,45 @@ +/* + * Copyright (c) 2016 Cisco and/or its affiliates. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef __included_jvpp_snat_h__ +#define __included_jvpp_snat_h__ + +#include +#include +#include +#include +#include +#include + +/* Global state for JVPP-SNAT */ +typedef struct { + /* Base message index for the nsh plugin */ + u16 msg_id_base; + + /* Pointer to shared memory queue */ + unix_shared_memory_queue_t * vl_input_queue; + + /* VPP api client index */ + u32 my_client_index; + + /* Callback object and class references enabling asynchronous Java calls */ + jobject callbackObject; + jclass callbackClass; + +} snat_main_t; + +snat_main_t snat_main __attribute__((aligned (64))); + + +#endif /* __included_jvpp_snat_h__ */ -- 2.16.6