summaryrefslogtreecommitdiffstats
path: root/src/vpp-api
diff options
context:
space:
mode:
authorMarek Gradzki <mgradzki@cisco.com>2017-01-27 08:57:40 +0100
committerDamjan Marion <dmarion.lists@gmail.com>2017-01-27 19:53:59 +0000
commit4746a5d75ebb080d15d5d743dca3a85d0265176f (patch)
tree1b3d9f6ddbeed9a9b561cb688afbf67c73c9f34c /src/vpp-api
parent32e1c010b0c34fd0984f7fc45fae648a182025c5 (diff)
jvpp: utilize per-message CRCs (VPP-544)
Since messages ids are no longer statically referenced, fixes also VPP-611. Change-Id: Ic8e6ee2b7f1142c185595347984d69350be25ac3 Signed-off-by: Marek Gradzki <mgradzki@cisco.com>
Diffstat (limited to 'src/vpp-api')
-rw-r--r--src/vpp-api/java/jvpp-acl/jvpp_acl.c8
-rw-r--r--src/vpp-api/java/jvpp-common/jvpp_common.c16
-rw-r--r--src/vpp-api/java/jvpp-common/jvpp_common.h7
-rw-r--r--src/vpp-api/java/jvpp-core/jvpp_core.c8
-rw-r--r--src/vpp-api/java/jvpp-ioamexport/jvpp_ioam_export.c8
-rw-r--r--src/vpp-api/java/jvpp-ioampot/jvpp_ioam_pot.c8
-rw-r--r--src/vpp-api/java/jvpp-ioamtrace/jvpp_ioam_trace.c8
-rw-r--r--src/vpp-api/java/jvpp-registry/jvpp_registry.c54
-rw-r--r--src/vpp-api/java/jvpp-snat/jvpp_snat.c8
-rwxr-xr-xsrc/vpp-api/java/jvpp/gen/jvpp_gen.py2
-rw-r--r--src/vpp-api/java/jvpp/gen/jvppgen/jvpp_c_gen.py31
11 files changed, 143 insertions, 15 deletions
diff --git a/src/vpp-api/java/jvpp-acl/jvpp_acl.c b/src/vpp-api/java/jvpp-acl/jvpp_acl.c
index d56abe3d0ba..9150ce6b699 100644
--- a/src/vpp-api/java/jvpp-acl/jvpp_acl.c
+++ b/src/vpp-api/java/jvpp-acl/jvpp_acl.c
@@ -74,8 +74,14 @@ JNIEXPORT void JNICALL Java_io_fd_vpp_jvpp_acl_JVppAclImpl_init0
plugin_main->callbackObject = (*env)->NewGlobalRef(env, callback);
plugin_main->callbackClass = (jclass)(*env)->NewGlobalRef(env, (*env)->GetObjectClass(env, callback));
+ // verify API has not changed since jar generation
+ #define _(N) \
+ get_message_id(env, #N); \
+ foreach_supported_api_message;
+ #undef _
+
#define _(N,n) \
- vl_msg_api_set_handlers(VL_API_##N + plugin_main->msg_id_base, #n, \
+ vl_msg_api_set_handlers(get_message_id(env, #N), #n, \
vl_api_##n##_t_handler, \
vl_noop_handler, \
vl_api_##n##_t_endian, \
diff --git a/src/vpp-api/java/jvpp-common/jvpp_common.c b/src/vpp-api/java/jvpp-common/jvpp_common.c
index a161c09c95b..b88c0ea2197 100644
--- a/src/vpp-api/java/jvpp-common/jvpp_common.c
+++ b/src/vpp-api/java/jvpp-common/jvpp_common.c
@@ -63,3 +63,19 @@ void call_on_error(const char* callName, int contextId, int retval,
(*env)->CallVoidMethod(env, callbackObject, callbackExcMethod, excObject);
DEBUG_LOG("CallOnError : Response sent\n");
}
+
+u32 get_message_id(JNIEnv *env, const char *key) {
+ uword *p = hash_get(jvpp_main.messages_hash, key);
+ if (!p) {
+ jclass exClass = (*env)->FindClass(env, "java/lang/IllegalStateException");
+ char *msgBuf = clib_mem_alloc(strlen(key) + 40);
+ strcpy(msgBuf, "API mismatch detected: ");
+ strcat(msgBuf, key);
+ strcat(msgBuf, " is missing");
+ DEBUG_LOG("get_message_id : %s\n", msgBuf);
+ (*env)->ThrowNew(env, exClass, msgBuf);
+ clib_mem_free(msgBuf);
+ return 0;
+ }
+ return (u32) p[0];
+}
diff --git a/src/vpp-api/java/jvpp-common/jvpp_common.h b/src/vpp-api/java/jvpp-common/jvpp_common.h
index bbb203edcb4..34502d04ab8 100644
--- a/src/vpp-api/java/jvpp-common/jvpp_common.h
+++ b/src/vpp-api/java/jvpp-common/jvpp_common.h
@@ -37,6 +37,7 @@ typedef struct {
/* Convenience */
unix_shared_memory_queue_t * vl_input_queue;
u32 my_client_index;
+ uword *messages_hash;
} jvpp_main_t;
extern jvpp_main_t jvpp_main __attribute__((aligned (64)));
@@ -64,4 +65,10 @@ void call_on_error(const char* callName, int contextId, int retval,
jclass callbackClass, jobject callbackObject,
jclass callbackExceptionClass);
+/**
+ * Retrieves message id based on message name and crc (key format: name_crc).
+ * Throws java/lang/IllegalStateException on failure.
+ */
+u32 get_message_id(JNIEnv *env, const char* key);
+
#endif /* __included_jvpp_common_h__ */
diff --git a/src/vpp-api/java/jvpp-core/jvpp_core.c b/src/vpp-api/java/jvpp-core/jvpp_core.c
index ef4cb8e3e7e..c04666b2952 100644
--- a/src/vpp-api/java/jvpp-core/jvpp_core.c
+++ b/src/vpp-api/java/jvpp-core/jvpp_core.c
@@ -67,8 +67,14 @@ JNIEXPORT void JNICALL Java_io_fd_vpp_jvpp_core_JVppCoreImpl_init0
plugin_main->callbackObject = (*env)->NewGlobalRef(env, callback);
plugin_main->callbackClass = (jclass)(*env)->NewGlobalRef(env, (*env)->GetObjectClass(env, callback));
+ // verify API has not changed since jar generation
+ #define _(N) \
+ get_message_id(env, #N); \
+ foreach_supported_api_message;
+ #undef _
+
#define _(N,n) \
- vl_msg_api_set_handlers(VL_API_##N, #n, \
+ vl_msg_api_set_handlers(get_message_id(env, #N), #n, \
vl_api_##n##_t_handler, \
vl_noop_handler, \
vl_noop_handler, \
diff --git a/src/vpp-api/java/jvpp-ioamexport/jvpp_ioam_export.c b/src/vpp-api/java/jvpp-ioamexport/jvpp_ioam_export.c
index 5cda89d1a17..068d2ec3c51 100644
--- a/src/vpp-api/java/jvpp-ioamexport/jvpp_ioam_export.c
+++ b/src/vpp-api/java/jvpp-ioamexport/jvpp_ioam_export.c
@@ -74,8 +74,14 @@ JNIEXPORT void JNICALL Java_io_fd_vpp_jvpp_ioamexport_JVppIoamexportImpl_init0
plugin_main->callbackObject = (*env)->NewGlobalRef(env, callback);
plugin_main->callbackClass = (jclass)(*env)->NewGlobalRef(env, (*env)->GetObjectClass(env, callback));
+ // verify API has not changed since jar generation
+ #define _(N) \
+ get_message_id(env, #N); \
+ foreach_supported_api_message;
+ #undef _
+
#define _(N,n) \
- vl_msg_api_set_handlers(VL_API_##N + plugin_main->msg_id_base, #n, \
+ vl_msg_api_set_handlers(get_message_id(env, #N), #n, \
vl_api_##n##_t_handler, \
vl_noop_handler, \
vl_api_##n##_t_endian, \
diff --git a/src/vpp-api/java/jvpp-ioampot/jvpp_ioam_pot.c b/src/vpp-api/java/jvpp-ioampot/jvpp_ioam_pot.c
index 9291dbba078..51b6a075324 100644
--- a/src/vpp-api/java/jvpp-ioampot/jvpp_ioam_pot.c
+++ b/src/vpp-api/java/jvpp-ioampot/jvpp_ioam_pot.c
@@ -74,8 +74,14 @@ JNIEXPORT void JNICALL Java_io_fd_vpp_jvpp_ioampot_JVppIoampotImpl_init0
plugin_main->callbackObject = (*env)->NewGlobalRef(env, callback);
plugin_main->callbackClass = (jclass)(*env)->NewGlobalRef(env, (*env)->GetObjectClass(env, callback));
+ // verify API has not changed since jar generation
+ #define _(N) \
+ get_message_id(env, #N); \
+ foreach_supported_api_message;
+ #undef _
+
#define _(N,n) \
- vl_msg_api_set_handlers(VL_API_##N + plugin_main->msg_id_base, #n, \
+ vl_msg_api_set_handlers(get_message_id(env, #N), #n, \
vl_api_##n##_t_handler, \
vl_noop_handler, \
vl_api_##n##_t_endian, \
diff --git a/src/vpp-api/java/jvpp-ioamtrace/jvpp_ioam_trace.c b/src/vpp-api/java/jvpp-ioamtrace/jvpp_ioam_trace.c
index 0bf178898ac..2f74b5ad077 100644
--- a/src/vpp-api/java/jvpp-ioamtrace/jvpp_ioam_trace.c
+++ b/src/vpp-api/java/jvpp-ioamtrace/jvpp_ioam_trace.c
@@ -74,8 +74,14 @@ JNIEXPORT void JNICALL Java_io_fd_vpp_jvpp_ioamtrace_JVppIoamtraceImpl_init0
plugin_main->callbackObject = (*env)->NewGlobalRef(env, callback);
plugin_main->callbackClass = (jclass)(*env)->NewGlobalRef(env, (*env)->GetObjectClass(env, callback));
+ // verify API has not changed since jar generation
+ #define _(N) \
+ get_message_id(env, #N); \
+ foreach_supported_api_message;
+ #undef _
+
#define _(N,n) \
- vl_msg_api_set_handlers(VL_API_##N + plugin_main->msg_id_base, #n, \
+ vl_msg_api_set_handlers(get_message_id(env, #N), #n, \
vl_api_##n##_t_handler, \
vl_noop_handler, \
vl_api_##n##_t_endian, \
diff --git a/src/vpp-api/java/jvpp-registry/jvpp_registry.c b/src/vpp-api/java/jvpp-registry/jvpp_registry.c
index cbd5e0ab39a..add872db801 100644
--- a/src/vpp-api/java/jvpp-registry/jvpp_registry.c
+++ b/src/vpp-api/java/jvpp-registry/jvpp_registry.c
@@ -52,16 +52,21 @@ void __stack_chk_guard(void) __attribute__((weak));
void __stack_chk_guard(void) {
}
+#define CONTROL_PING_MESSAGE "control_ping"
+#define CONTROL_PING_REPLY_MESSAGE "control_ping_reply"
+
typedef struct {
/* UThread attachment */
volatile u32 control_ping_result_ready;
volatile i32 control_ping_retval;
- /* Control poing callback */
+ /* Control ping callback */
jobject registryObject;
jclass registryClass;
jclass controlPingReplyClass;
jclass callbackExceptionClass;
+ int control_ping_msg_id;
+ int control_ping_reply_msg_id;
/* Thread cleanup */
pthread_key_t cleanup_rx_thread_key;
@@ -168,6 +173,41 @@ static void vl_api_control_ping_reply_t_handler(
out: rm->control_ping_result_ready = 1;
}
+static int find_ping_id() {
+ int rv = 0;
+ jvpp_main_t * jm = &jvpp_main;
+ jvpp_registry_main_t * rm = &jvpp_registry_main;
+ api_main_t *am = &api_main;
+ hash_pair_t *hp;
+ jm->messages_hash = am->msg_index_by_name_and_crc;
+
+ rm->control_ping_msg_id = -1;
+ rm->control_ping_reply_msg_id = -1;
+
+ hash_foreach_pair (hp, jm->messages_hash,
+ ({
+ char *key = (char *)hp->key; // key format: name_crc
+ int msg_name_len = strlen(key) - 9; // ignore crc
+ if (strlen(CONTROL_PING_MESSAGE) == msg_name_len &&
+ strncmp(CONTROL_PING_MESSAGE, (char *)hp->key, msg_name_len) == 0) {
+ rm->control_ping_msg_id = (u32)hp->value[0];
+ }
+ if (strlen(CONTROL_PING_REPLY_MESSAGE) == msg_name_len &&
+ strncmp(CONTROL_PING_REPLY_MESSAGE, (char *)hp->key, msg_name_len) == 0) {
+ rm->control_ping_reply_msg_id = (u32)hp->value[0];
+ }
+ }));
+ if (rm->control_ping_msg_id == -1) {
+ clib_warning("failed to find id for %s", CONTROL_PING_MESSAGE);
+ rv = -1;
+ }
+ if (rm->control_ping_reply_msg_id == -1) {
+ clib_warning("failed to find id for %s", CONTROL_PING_REPLY_MESSAGE);
+ rv = -1;
+ }
+ return rv;
+}
+
static int send_initial_control_ping() {
f64 timeout;
clib_time_t clib_time;
@@ -180,7 +220,7 @@ static int send_initial_control_ping() {
rm->control_ping_result_ready = 0;
mp = vl_msg_api_alloc(sizeof(*mp));
memset(mp, 0, sizeof(*mp));
- mp->_vl_msg_id = ntohs(VL_API_CONTROL_PING);
+ mp->_vl_msg_id = ntohs(rm->control_ping_msg_id);
mp->client_index = jm->my_client_index;
// send message:
@@ -197,7 +237,7 @@ static int send_initial_control_ping() {
}
if (rv != 0) {
- clib_warning("common: first control ping failed: %d", rv);
+ clib_warning("first control ping failed: %d", rv);
}
return rv;
@@ -206,6 +246,7 @@ static int send_initial_control_ping() {
static int connect_to_vpe(char *name) {
jvpp_main_t * jm = &jvpp_main;
api_main_t * am = &api_main;
+ jvpp_registry_main_t * rm = &jvpp_registry_main;
if (vl_client_connect_to_vlib("/vpe-api", name, 32) < 0)
return -1;
@@ -214,7 +255,10 @@ static int connect_to_vpe(char *name) {
jm->vl_input_queue = am->shmem_hdr->vl_input_queue;
- vl_msg_api_set_handlers(VL_API_CONTROL_PING_REPLY, "control_ping_reply",
+ if (find_ping_id() < 0)
+ return -1;
+
+ vl_msg_api_set_handlers(rm->control_ping_reply_msg_id, CONTROL_PING_REPLY_MESSAGE,
vl_api_control_ping_reply_t_handler, vl_noop_handler,
vl_api_control_ping_reply_t_endian,
vl_api_control_ping_reply_t_print,
@@ -286,7 +330,7 @@ JNIEXPORT jint JNICALL Java_io_fd_vpp_jvpp_JVppRegistryImpl_controlPing0(
mp = vl_msg_api_alloc(sizeof(*mp));
memset(mp, 0, sizeof(*mp));
- mp->_vl_msg_id = ntohs(VL_API_CONTROL_PING);
+ mp->_vl_msg_id = ntohs(rm->control_ping_msg_id);
mp->client_index = jm->my_client_index;
mp->context = clib_host_to_net_u32(my_context_id);
diff --git a/src/vpp-api/java/jvpp-snat/jvpp_snat.c b/src/vpp-api/java/jvpp-snat/jvpp_snat.c
index 1095b6eb725..c4d1afe8d34 100644
--- a/src/vpp-api/java/jvpp-snat/jvpp_snat.c
+++ b/src/vpp-api/java/jvpp-snat/jvpp_snat.c
@@ -74,8 +74,14 @@ JNIEXPORT void JNICALL Java_io_fd_vpp_jvpp_snat_JVppSnatImpl_init0
plugin_main->callbackObject = (*env)->NewGlobalRef(env, callback);
plugin_main->callbackClass = (jclass)(*env)->NewGlobalRef(env, (*env)->GetObjectClass(env, callback));
+ // verify API has not changed since jar generation
+ #define _(N) \
+ get_message_id(env, #N);
+ foreach_supported_api_message;
+ #undef _
+
#define _(N,n) \
- vl_msg_api_set_handlers(VL_API_##N + plugin_main->msg_id_base, #n, \
+ vl_msg_api_set_handlers(get_message_id(env, #N), #n, \
vl_api_##n##_t_handler, \
vl_noop_handler, \
vl_api_##n##_t_endian, \
diff --git a/src/vpp-api/java/jvpp/gen/jvpp_gen.py b/src/vpp-api/java/jvpp/gen/jvpp_gen.py
index f51b11d0cf8..2a5ada989bb 100755
--- a/src/vpp-api/java/jvpp/gen/jvpp_gen.py
+++ b/src/vpp-api/java/jvpp/gen/jvpp_gen.py
@@ -6,7 +6,7 @@
# You may obtain a copy of the License at:
#
# http://www.apache.org/licenses/LICENSE-2.0
-# l
+#
# 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.
diff --git a/src/vpp-api/java/jvpp/gen/jvppgen/jvpp_c_gen.py b/src/vpp-api/java/jvpp/gen/jvppgen/jvpp_c_gen.py
index 611171c47b5..5b0fbc95035 100644
--- a/src/vpp-api/java/jvpp/gen/jvppgen/jvpp_c_gen.py
+++ b/src/vpp-api/java/jvpp/gen/jvppgen/jvpp_c_gen.py
@@ -130,7 +130,7 @@ JNIEXPORT jint JNICALL Java_io_fd_vpp_jvpp_${plugin_name}_JVpp${java_plugin_name
// create message:
mp = vl_msg_api_alloc(sizeof(*mp));
memset (mp, 0, sizeof (*mp));
- mp->_vl_msg_id = ntohs (VL_API_${c_name_uppercase} + plugin_main->msg_id_base);
+ mp->_vl_msg_id = ntohs (get_message_id(env, "${c_name}_${crc}"));
mp->client_index = plugin_main->my_client_index;
mp->context = clib_host_to_net_u32 (my_context_id);
@@ -181,6 +181,7 @@ def generate_jni_impl(func_list, plugin_name, inputfile):
field_name=camel_case_function_name,
c_name_uppercase=f_name_uppercase,
c_name=f_name,
+ crc=f['crc'],
plugin_name=plugin_name,
java_plugin_name=plugin_name.title(),
request_class=request_class,
@@ -282,7 +283,7 @@ def generate_msg_handlers(func_list, plugin_name, inputfile):
return "\n".join(handlers)
-handler_registration_template = Template("""_(${upercase_name}, ${name}) \\
+handler_registration_template = Template("""_(${name}_${crc}, ${name}) \\
""")
@@ -298,11 +299,30 @@ def generate_handler_registration(func_list):
handler_registration.append(handler_registration_template.substitute(
name=name,
- upercase_name=name.upper()))
+ crc=f['crc']))
return "".join(handler_registration)
+api_verification_template = Template("""_(${name}_${crc}) \\
+""")
+
+
+def generate_api_verification(func_list):
+ api_verification = ["#define foreach_supported_api_message \\\n"]
+ for f in func_list:
+ name = f['name']
+
+ if util.is_ignored(name):
+ continue
+
+ api_verification.append(api_verification_template.substitute(
+ name=name,
+ crc=f['crc']))
+
+ return "".join(api_verification)
+
+
jvpp_c_template = Template("""/**
* This file contains JNI bindings for jvpp Java API.
* It was generated by jvpp_c_gen.py based on $inputfile
@@ -312,6 +332,9 @@ jvpp_c_template = Template("""/**
// JAVA class reference cache
$class_cache
+// List of supported API messages used for verification
+$api_verification
+
// JNI bindings
$jni_implementations
@@ -330,11 +353,13 @@ def generate_jvpp(func_list, plugin_name, inputfile, path):
jni_impl = generate_jni_impl(func_list, plugin_name, inputfile)
msg_handlers = generate_msg_handlers(func_list, plugin_name, inputfile)
handler_registration = generate_handler_registration(func_list)
+ api_verification = generate_api_verification(func_list)
jvpp_c_file = open("%s/jvpp_%s_gen.h" % (path, plugin_name), 'w')
jvpp_c_file.write(jvpp_c_template.substitute(
inputfile=inputfile,
class_cache=class_cache,
+ api_verification=api_verification,
jni_implementations=jni_impl,
msg_handlers=msg_handlers,
handler_registration=handler_registration))