aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPaul Vinciguerra <pvinci@vinciconsulting.com>2019-05-14 21:01:28 -0400
committerNeale Ranns <nranns@cisco.com>2019-07-08 17:47:33 +0000
commit888640a398f974cf388bdc983d10e78591275b37 (patch)
treed777158dece54df369f7e6a6f76e12cbdc1733ab
parent44e60468a2f0ad7ceff67de718fe3c401016ef6d (diff)
map gbp papi: match endianess of f64
clib_net_to_host_f64, clib_host_to_net_f64 are now implemented as '=', https://gerrit.fd.io/r/#/c/20406/ set papi to match. - all f64 api references are now wrapped with clib_net_to_host_f64 or clib_host_to_net_f64. IEEE f64 endianess is not defined. If clib_net_to_host_f64 and clib_host_to_net_f64 are later defined in VPP as big-endian, it is a single character change in the papi vpp_serializer. Note: This breaks the api in a manner that would not be detected by the flag day initiative. The scope is small. This only impacts map.api, which applied the u64 transformation, while the gbp api uses '='. The implementation of "=" raises issues for the papi socket implementation if used between systems of differing endianess. See Vratko's comments. - Added get_f64_endian_value() to api to allow client to verify endianess of f64's. Type: fix Depends-on: https://gerrit.fd.io/r/#/c/20484/ Change-Id: I00fc64a6557ba0190398df211aa0ea5c7eb101df Signed-off-by: Paul Vinciguerra <pvinci@vinciconsulting.com>
-rw-r--r--src/plugins/gbp/gbp_api.c4
-rw-r--r--src/plugins/map/map_api.c8
-rw-r--r--src/vnet/api_errno.h4
-rw-r--r--src/vpp-api/python/vpp_papi/vpp_serializer.py2
-rw-r--r--src/vpp/api/api.c35
-rw-r--r--src/vpp/api/vpe.api50
-rw-r--r--test/test_endian.py38
7 files changed, 130 insertions, 11 deletions
diff --git a/src/plugins/gbp/gbp_api.c b/src/plugins/gbp/gbp_api.c
index f487e160808..7c7026aae84 100644
--- a/src/plugins/gbp/gbp_api.c
+++ b/src/plugins/gbp/gbp_api.c
@@ -246,7 +246,9 @@ gbp_endpoint_send_details (index_t gei, void *args)
mp->endpoint.n_ips = n_ips;
mp->endpoint.flags = gbp_endpoint_flags_encode (gef->gef_flags);
mp->handle = htonl (gei);
- mp->age = vlib_time_now (vlib_get_main ()) - ge->ge_last_time;
+ mp->age =
+ clib_host_to_net_f64 (vlib_time_now (vlib_get_main ()) -
+ ge->ge_last_time);
mac_address_encode (&ge->ge_key.gek_mac, mp->endpoint.mac);
vec_foreach_index (ii, ge->ge_key.gek_ips)
diff --git a/src/plugins/map/map_api.c b/src/plugins/map/map_api.c
index 1d2614ccb5d..4a0834d786b 100644
--- a/src/plugins/map/map_api.c
+++ b/src/plugins/map/map_api.c
@@ -461,7 +461,7 @@ static void
int rv;
f64 ht_ratio;
- ht_ratio = (f64) clib_net_to_host_u64 (mp->ht_ratio);
+ ht_ratio = (f64) clib_net_to_host_f64 (mp->ht_ratio);
if (ht_ratio == ~0)
ht_ratio = MAP_IP6_REASS_CONF_HT_RATIO_MAX + 1;
@@ -587,15 +587,13 @@ vl_api_map_param_get_t_handler (vl_api_map_param_get_t * mp)
clib_net_to_host_u16 (mm->ip4_reass_conf_lifetime_ms);
rmp->ip4_pool_size = clib_net_to_host_u16 (mm->ip4_reass_conf_pool_size);
rmp->ip4_buffers = clib_net_to_host_u32 (mm->ip4_reass_conf_buffers);
- rmp->ip4_ht_ratio =
- clib_net_to_host_u64 ((u64) mm->ip4_reass_conf_ht_ratio);
+ rmp->ip4_ht_ratio = clib_net_to_host_f64 (mm->ip4_reass_conf_ht_ratio);
rmp->ip6_lifetime_ms =
clib_net_to_host_u16 (mm->ip6_reass_conf_lifetime_ms);
rmp->ip6_pool_size = clib_net_to_host_u16 (mm->ip6_reass_conf_pool_size);
rmp->ip6_buffers = clib_net_to_host_u32 (mm->ip6_reass_conf_buffers);
- rmp->ip6_ht_ratio =
- clib_net_to_host_u64 ((u64) mm->ip6_reass_conf_ht_ratio);
+ rmp->ip6_ht_ratio = clib_net_to_host_f64 (mm->ip6_reass_conf_ht_ratio);
rmp->sec_check_enable = mm->sec_check;
rmp->sec_check_fragments = mm->sec_check_frag;
diff --git a/src/vnet/api_errno.h b/src/vnet/api_errno.h
index 14297558405..0702fd7ec9e 100644
--- a/src/vnet/api_errno.h
+++ b/src/vnet/api_errno.h
@@ -149,8 +149,8 @@ _(INVALID_PROTOCOL, -153, "Invalid Protocol") \
_(INVALID_ALGORITHM, -154, "Invalid Algorithm") \
_(RSRC_IN_USE, -155, "Resource In Use") \
_(KEY_LENGTH, -156, "invalid Key Length") \
-_(FIB_PATH_UNSUPPORTED_NH_PROTO, -157, "Unsupported FIB Path protocol")
-
+_(FIB_PATH_UNSUPPORTED_NH_PROTO, -157, "Unsupported FIB Path protocol") \
+_(API_ENDIAN_FAILED, -159, "Endian mismatch detected")
typedef enum
{
#define _(a,b,c) VNET_API_ERROR_##a = (b),
diff --git a/src/vpp-api/python/vpp_papi/vpp_serializer.py b/src/vpp-api/python/vpp_papi/vpp_serializer.py
index fe9a083d6c8..9e17c4a2b8c 100644
--- a/src/vpp-api/python/vpp_papi/vpp_serializer.py
+++ b/src/vpp-api/python/vpp_papi/vpp_serializer.py
@@ -74,7 +74,7 @@ class BaseTypes(object):
'u32': '>I',
'i32': '>i',
'u64': '>Q',
- 'f64': '>d',
+ 'f64': '=d',
'bool': '>?',
'header': '>HI'}
diff --git a/src/vpp/api/api.c b/src/vpp/api/api.c
index 66857fbac9f..9ae027dab9b 100644
--- a/src/vpp/api/api.c
+++ b/src/vpp/api/api.c
@@ -86,7 +86,9 @@ _(SHOW_THREADS, show_threads) \
_(GET_NODE_GRAPH, get_node_graph) \
_(GET_NEXT_INDEX, get_next_index) \
_(LOG_DUMP, log_dump) \
-_(SHOW_VPE_SYSTEM_TIME_TICKS, show_vpe_system_time_ticks)
+_(SHOW_VPE_SYSTEM_TIME_TICKS, show_vpe_system_time_ticks) \
+_(GET_F64_ENDIAN_VALUE, get_f64_endian_value) \
+_(GET_F64_INCREMENT_BY_ONE, get_f64_increment_by_one) \
#define QUOTE_(x) #x
#define QUOTE(x) QUOTE_(x)
@@ -554,6 +556,37 @@ static void
/* *INDENT-ON* */
}
+static void
+vl_api_get_f64_endian_value_t_handler (vl_api_get_f64_endian_value_t * mp)
+{
+ int rv = 0;
+ f64 one = 1.0;
+ vl_api_get_f64_endian_value_reply_t *rmp;
+ if (1.0 != clib_net_to_host_f64 (mp->f64_one))
+ rv = VNET_API_ERROR_API_ENDIAN_FAILED;
+
+ /* *INDENT-OFF* */
+ REPLY_MACRO2(VL_API_GET_F64_ENDIAN_VALUE_REPLY,
+ ({
+ rmp->f64_one_result = clib_host_to_net_f64 (one);
+ }));
+ /* *INDENT-ON* */
+}
+
+static void
+vl_api_get_f64_increment_by_one_t_handler (vl_api_get_f64_increment_by_one_t *
+ mp)
+{
+ int rv = 0;
+ vl_api_get_f64_increment_by_one_reply_t *rmp;
+
+ /* *INDENT-OFF* */
+ REPLY_MACRO2(VL_API_GET_F64_INCREMENT_BY_ONE_REPLY,
+ ({
+ rmp->f64_value = clib_host_to_net_f64 (clib_net_to_host_f64(mp->f64_value) + 1.0);
+ }));
+ /* *INDENT-ON* */
+}
#define BOUNCE_HANDLER(nn) \
static void vl_api_##nn##_t_handler ( \
diff --git a/src/vpp/api/vpe.api b/src/vpp/api/vpe.api
index bd6b9d5638f..7c466b9a7a4 100644
--- a/src/vpp/api/vpe.api
+++ b/src/vpp/api/vpe.api
@@ -19,7 +19,7 @@
called through a shared memory interface.
*/
-option version = "1.3.0";
+option version = "1.4.0";
/*
* Note: API placement cleanup in progress
@@ -332,6 +332,54 @@ define show_vpe_system_time_ticks_reply
f64 vpe_system_time_ticks;
};
+/** \brief f64 types are not standardized across the wire. Sense wire format in each direction by sending the f64 value 1.0.
+ @param client_index - opaque cookie to identify the sender
+ @param context - sender context, to match reply w/ request
+ @param f64_one - The constant of 1.0. If you send a different value, expect an rv=VNET_API_ERROR_API_ENDIAN_FAILED.
+*/
+define get_f64_endian_value
+{
+ u32 client_index;
+ u32 context;
+ f64 f64_one [default=1.0];
+};
+
+/** \brief get_f64_endian_value reply message
+ @param context - sender context which was passed in the request
+ @param retval - return value - VNET_API_ERROR_API_ENDIAN_FAILED if f64_one != 1.0
+ @param f64_one_result - The value of 'f64 1.0'
+*/
+define get_f64_endian_value_reply
+{
+ u32 context;
+ u32 retval;
+ f64 f64_one_result;
+};
+
+/** \brief Verify f64 wire format by sending a value and receiving the value + 1.0
+ @param client_index - opaque cookie to identify the sender.
+ @param context - sender context, to match reply w/ request.
+ @param f64_value - The value you want to test. Default: 1.0.
+*/
+define get_f64_increment_by_one
+{
+ u32 client_index;
+ u32 context;
+ f64 f64_value [default=1.0];
+};
+
+/** \brief get_f64_increment_by_one reply
+ @param client_index - opaque cookie to identify the sender.
+ @param context - sender context, to match reply w/ request.
+ @param f64_value - The input f64_value incremented by 1.0.
+*/
+define get_f64_increment_by_one_reply
+{
+ u32 context;
+ u32 retval;
+ f64 f64_value;
+};
+
/*
* Local Variables:
* eval: (c-set-style "gnu")
diff --git a/test/test_endian.py b/test/test_endian.py
new file mode 100644
index 00000000000..462ee2b6b57
--- /dev/null
+++ b/test/test_endian.py
@@ -0,0 +1,38 @@
+# Copyright (c) 2019. Vinci Consulting Corp. All Rights Reserved.
+#
+# 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.
+
+import framework
+import vpp_papi_provider
+
+F64_ONE = 1.0
+
+
+class TestEndian(framework.VppTestCase):
+ """TestEndian"""
+
+ def test_f64_endian_value(self):
+ try:
+ rv = self.vapi.get_f64_endian_value(f64_one=F64_ONE)
+ self.assertEqual(rv.f64_one_result, F64_ONE,
+ "client incorrectly deserializes f64 values. "
+ "Expected: %r. Received: %r." % (
+ F64_ONE, rv.f64_one_result))
+ except vpp_papi_provider.UnexpectedApiReturnValueError:
+ self.fail('client incorrectly serializes f64 values.')
+
+ def test_get_f64_increment_by_one(self):
+ expected = 43.0
+ rv = self.vapi.get_f64_increment_by_one(f64_value=42.0)
+ self.assertEqual(rv.f64_value, expected, 'Expected %r, received:%r.'
+ % (expected, rv.f64_value))