From 03e1d559f912513e1bc2ffc615b7833471afc790 Mon Sep 17 00:00:00 2001 From: Klement Sekera Date: Sun, 6 Aug 2023 19:33:16 +0200 Subject: vapi: improve vl_api_string_t handling Define vl_api_string_t to correspond with vlibapi/api_types.h Fix allocation and size calculation routine generation. Type: improvement Change-Id: I6b0a3eb3459d75d326e67bfb76dac8125e480afa Signed-off-by: Klement Sekera --- src/vpp-api/vapi/vapi_c_gen.py | 51 +++++++++++++++++++++++++--------- src/vpp-api/vapi/vapi_c_test.c | 10 +++---- src/vpp-api/vapi/vapi_cpp_test.cpp | 8 +++--- src/vpp-api/vapi/vapi_json_parser.py | 54 ++++++++++++++++++++++++++++-------- 4 files changed, 89 insertions(+), 34 deletions(-) (limited to 'src/vpp-api/vapi') diff --git a/src/vpp-api/vapi/vapi_c_gen.py b/src/vpp-api/vapi/vapi_c_gen.py index 37f5ac12447..609f4bbd27e 100755 --- a/src/vpp-api/vapi/vapi_c_gen.py +++ b/src/vpp-api/vapi/vapi_c_gen.py @@ -23,7 +23,7 @@ class CField(Field): return "vapi_type_%s" % self.name def get_c_def(self): - if self.type.get_c_name() == "vl_api_string_t": + if self.type.get_c_name() == "string": if self.len: return "u8 %s[%d];" % (self.name, self.len) else: @@ -85,12 +85,15 @@ class CField(Field): def needs_byte_swap(self): return self.type.needs_byte_swap() - def get_vla_field_length_name(self, path): + def get_vla_parameter_name(self, path): return "%s_%s_array_size" % ("_".join(path), self.name) + def get_vla_field_name(self, path): + return ".".join(path + [self.nelem_field.name]) + def get_alloc_vla_param_names(self, path): if self.is_vla(): - result = [self.get_vla_field_length_name(path)] + result = [self.get_vla_parameter_name(path)] else: result = [] if self.type.has_vla(): @@ -98,20 +101,22 @@ class CField(Field): result.extend(t) return result - def get_vla_calc_size_code(self, prefix, path): + def get_vla_calc_size_code(self, prefix, path, is_alloc): if self.is_vla(): result = [ "sizeof(%s.%s[0]) * %s" % ( ".".join([prefix] + path), self.name, - self.get_vla_field_length_name(path), + self.get_vla_parameter_name(path) + if is_alloc + else "%s.%s" % (prefix, self.get_vla_field_name(path)), ) ] else: result = [] if self.type.has_vla(): - t = self.type.get_vla_calc_size_code(prefix, path + [self.name]) + t = self.type.get_vla_calc_size_code(prefix, path + [self.name], is_alloc) result.extend(t) return result @@ -123,7 +128,7 @@ class CField(Field): % ( ".".join([prefix] + path), self.nelem_field.name, - self.get_vla_field_length_name(path), + self.get_vla_parameter_name(path), ) ) if self.type.has_vla(): @@ -173,12 +178,12 @@ class CStruct(Struct): for x in f.get_alloc_vla_param_names(path) ] - def get_vla_calc_size_code(self, prefix, path): + def get_vla_calc_size_code(self, prefix, path, is_alloc): return [ x for f in self.fields if f.has_vla() - for x in f.get_vla_calc_size_code(prefix, path) + for x in f.get_vla_calc_size_code(prefix, path, is_alloc) ] @@ -288,6 +293,8 @@ class CUnion(Union): class CStructType(StructType, CStruct): def get_c_name(self): + if self.name == "vl_api_string_t": + return "vl_api_string_t" return "vapi_type_%s" % self.name def get_swap_to_be_func_name(self): @@ -398,7 +405,9 @@ class CMessage(Message): " + %s" % x for f in self.fields if f.has_vla() - for x in f.get_vla_calc_size_code("msg->payload", []) + for x in f.get_vla_calc_size_code( + "msg->payload", [], is_alloc=True + ) ] ), ), @@ -442,10 +451,12 @@ class CMessage(Message): " return sizeof(*msg)%s;" % "".join( [ - "+ msg->payload.%s * sizeof(msg->payload.%s[0])" - % (f.nelem_field.name, f.name) + " + %s" % x for f in self.fields - if f.nelem_field is not None + if f.has_vla() + for x in f.get_vla_calc_size_code( + "msg->payload", [], is_alloc=False + ) ] ), "}", @@ -885,6 +896,20 @@ def gen_json_unified_header(parser, logger, j, io, name): print("#ifdef __cplusplus") print('extern "C" {') print("#endif") + + print("#ifndef __vl_api_string_swap_fns_defined__") + print("#define __vl_api_string_swap_fns_defined__") + print("") + print("#include ") + print("") + function_attrs = "static inline " + o = parser.types["vl_api_string_t"] + print("%s%s" % (function_attrs, o.get_swap_to_be_func_def())) + print("") + print("%s%s" % (function_attrs, o.get_swap_to_host_func_def())) + print("") + print("#endif //__vl_api_string_swap_fns_defined__") + if name == "memclnt.api.vapi.h": print("") print( diff --git a/src/vpp-api/vapi/vapi_c_test.c b/src/vpp-api/vapi/vapi_c_test.c index 5eccb0fac38..3f88dedca48 100644 --- a/src/vpp-api/vapi/vapi_c_test.c +++ b/src/vpp-api/vapi/vapi_c_test.c @@ -605,7 +605,7 @@ START_TEST (test_loopbacks_1) { dctx.last_called = false; clib_memset (&seen, 0, sizeof (seen)); - dump = vapi_alloc_sw_interface_dump (ctx); + dump = vapi_alloc_sw_interface_dump (ctx, 0); while (VAPI_EAGAIN == (rv = vapi_sw_interface_dump (ctx, dump, sw_interface_dump_cb, @@ -634,7 +634,7 @@ START_TEST (test_loopbacks_1) } dctx.last_called = false; clib_memset (&seen, 0, sizeof (seen)); - dump = vapi_alloc_sw_interface_dump (ctx); + dump = vapi_alloc_sw_interface_dump (ctx, 0); while (VAPI_EAGAIN == (rv = vapi_sw_interface_dump (ctx, dump, sw_interface_dump_cb, &dctx))) @@ -763,7 +763,7 @@ START_TEST (test_loopbacks_2) bool seen[num_ifs]; clib_memset (&seen, 0, sizeof (seen)); sw_interface_dump_ctx dctx = { false, num_ifs, sw_if_indexes, seen, 0 }; - vapi_msg_sw_interface_dump *dump = vapi_alloc_sw_interface_dump (ctx); + vapi_msg_sw_interface_dump *dump = vapi_alloc_sw_interface_dump (ctx, 0); while (VAPI_EAGAIN == (rv = vapi_sw_interface_dump (ctx, dump, sw_interface_dump_cb, &dctx))) @@ -803,7 +803,7 @@ START_TEST (test_loopbacks_2) } clib_memset (&seen, 0, sizeof (seen)); dctx.last_called = false; - dump = vapi_alloc_sw_interface_dump (ctx); + dump = vapi_alloc_sw_interface_dump (ctx, 0); while (VAPI_EAGAIN == (rv = vapi_sw_interface_dump (ctx, dump, sw_interface_dump_cb, &dctx))) @@ -922,7 +922,7 @@ START_TEST (test_no_response_2) { printf ("--- Simulate no response to dump message ---\n"); vapi_error_e rv; - vapi_msg_sw_interface_dump *dump = vapi_alloc_sw_interface_dump (ctx); + vapi_msg_sw_interface_dump *dump = vapi_alloc_sw_interface_dump (ctx, 0); dump->header._vl_msg_id = ~0; /* malformed ID causes vpp to drop the msg */ int no_called = 0; while (VAPI_EAGAIN == diff --git a/src/vpp-api/vapi/vapi_cpp_test.cpp b/src/vpp-api/vapi/vapi_cpp_test.cpp index 25df5b70e8f..56ebb39cb58 100644 --- a/src/vpp-api/vapi/vapi_cpp_test.cpp +++ b/src/vpp-api/vapi/vapi_cpp_test.cpp @@ -193,7 +193,7 @@ START_TEST (test_loopbacks_1) { // new context bool seen[num_ifs] = {0}; - Sw_interface_dump d (con); + Sw_interface_dump d (con, 0); auto rv = d.execute (); ck_assert_int_eq (VAPI_OK, rv); WAIT_FOR_RESPONSE (d, rv); @@ -232,7 +232,7 @@ START_TEST (test_loopbacks_1) } { // new context - Sw_interface_dump d (con); + Sw_interface_dump d (con, 0); auto rv = d.execute (); ck_assert_int_eq (VAPI_OK, rv); WAIT_FOR_RESPONSE (d, rv); @@ -347,7 +347,7 @@ START_TEST (test_loopbacks_2) } Sw_interface_dump_cb swdcb (ccbs); - Sw_interface_dump d (con, std::ref (swdcb)); + Sw_interface_dump d (con, 0, std::ref (swdcb)); auto rv = d.execute (); ck_assert_int_eq (VAPI_OK, rv); WAIT_FOR_RESPONSE (d, rv); @@ -373,7 +373,7 @@ START_TEST (test_loopbacks_2) } { // new context - Sw_interface_dump d (con); + Sw_interface_dump d (con, 0); auto rv = d.execute (); ck_assert_int_eq (VAPI_OK, rv); WAIT_FOR_RESPONSE (d, rv); diff --git a/src/vpp-api/vapi/vapi_json_parser.py b/src/vpp-api/vapi/vapi_json_parser.py index 00c234fc014..c06cb8cf77b 100644 --- a/src/vpp-api/vapi/vapi_json_parser.py +++ b/src/vpp-api/vapi/vapi_json_parser.py @@ -197,12 +197,18 @@ class Message(object): "array `%s' doesn't have reference to member " "containing the actual length" % (name, field[1]) ) - if field[0] == "string" and field[2] > 0: - field_type = json_parser.lookup_type_like_id("u8") + if field[0] == "string" and field[2] == 0: + field_type = json_parser.lookup_type_like_id("vl_api_string_t") + p = field_class(field_name=field[1], field_type=field_type) + else: + if field[0] == "string" and field[2] > 0: + field_type = json_parser.lookup_type_like_id("u8") - p = field_class( - field_name=field[1], field_type=field_type, array_len=field[2] - ) + p = field_class( + field_name=field[1], + field_type=field_type, + array_len=field[2], + ) elif l == 4: nelem_field = None for f in fields: @@ -255,13 +261,31 @@ class StructType(Type, Struct): p = field_class(field_name=field[1], field_type=field_type) elif len(field) == 3: if field[2] == 0: - raise ParseError( - "While parsing type `%s': array `%s' has " - "variable length" % (name, field[1]) + if name == "vl_api_string_t": + p = None + for f in fields: + if f.name == "length": + nelem_field = f + p = field_class( + field_name=field[1], + field_type=field_type, + array_len=field[2], + nelem_field=nelem_field, + ) + break + if p is None: + raise ParseError( + "While parsing type `%s': missing `length'" % name + ) + else: + raise ParseError( + "While parsing type `%s': array `%s' has " + "variable length" % (name, field[1]) + ) + else: + p = field_class( + field_name=field[1], field_type=field_type, array_len=field[2] ) - p = field_class( - field_name=field[1], field_type=field_type, array_len=field[2] - ) elif len(field) == 4: nelem_field = None for f in fields: @@ -344,7 +368,13 @@ class JsonParser(object): ] } - self.types["string"] = simple_type_class("vl_api_string_t") + self.types["string"] = simple_type_class("u8") + self.types["vl_api_string_t"] = struct_type_class( + ["vl_api_string_t", ["u32", "length"], ["u8", "buf", 0]], + self, + field_class, + logger, + ) self.replies = set() self.events = set() self.streams = set() -- cgit 1.2.3-korg