X-Git-Url: https://gerrit.fd.io/r/gitweb?a=blobdiff_plain;f=src%2Fvpp-api%2Fvapi%2Fvapi_c_gen.py;h=debd7345f60e63c33e816321d88905f5b8fc1f73;hb=ed1f9adad793d327bc0245e14088ea8e50e54f26;hp=330bd92ef8f36e1c97f4c462994b5522fef4b87a;hpb=1b1ccadc900deffd7b8e306ae8dce79a3115778c;p=vpp.git diff --git a/src/vpp-api/vapi/vapi_c_gen.py b/src/vpp-api/vapi/vapi_c_gen.py index 330bd92ef8f..debd7345f60 100755 --- a/src/vpp-api/vapi/vapi_c_gen.py +++ b/src/vpp-api/vapi/vapi_c_gen.py @@ -1,6 +1,7 @@ #!/usr/bin/env python3 import argparse +import inspect import os import sys import logging @@ -19,13 +20,14 @@ class CField(Field): else: return "vl_api_string_t %s;" % (self.name) else: - if self.len is not None: - return "%s %s[%d];" % (self.type.get_c_name(), self.name, self.len) + if self.len is not None and type(self.len) != dict: + return "%s %s[%d];" % (self.type.get_c_name(), self.name, + self.len) else: return "%s %s;" % (self.type.get_c_name(), self.name) def get_swap_to_be_code(self, struct, var): - if self.len is not None: + if self.len is not None and type(self.len) != dict: if self.len > 0: return "do { unsigned i; for (i = 0; i < %d; ++i) { %s } }"\ " while(0);" % ( @@ -46,7 +48,7 @@ class CField(Field): return self.type.get_swap_to_be_code(struct, "%s" % var) def get_swap_to_host_code(self, struct, var): - if self.len is not None: + if self.len is not None and type(self.len) != dict: if self.len > 0: return "do { unsigned i; for (i = 0; i < %d; ++i) { %s } }"\ " while(0);" % ( @@ -153,6 +155,12 @@ class CSimpleType (SimpleType): 'i64': 'be64toh', 'u64': 'be64toh', } + __packed = "__attribute__((packed))" + pack_dict = { + 'i8': __packed, 'u8': __packed, + 'i16': __packed, 'u16': __packed, + } + def get_c_name(self): return self.name @@ -162,6 +170,9 @@ class CSimpleType (SimpleType): def get_swap_to_host_func_name(self): return self.swap_to_host_dict[self.name] + def get_packed_string(self): + return self.pack_dict[self.name] + def get_swap_to_be_code(self, struct, var, cast=None): x = "%s%s" % (struct, var) return "%s = %s%s(%s);" % (x, @@ -182,14 +193,18 @@ class CSimpleType (SimpleType): pass return False + def get_packed(self): + return self.pack_dict.get(self.name, "") + class CEnum(Enum): def get_c_name(self): return "vapi_enum_%s" % self.name def get_c_def(self): - return "typedef enum {\n%s\n} %s;" % ( + return "typedef enum {\n%s\n} %s %s;" % ( "\n".join([" %s = %s," % (i, j) for i, j in self.value_pairs]), + self.type.get_packed(), self.get_c_name() ) @@ -353,6 +368,37 @@ class CMessage (Message): "}", ]) + def get_verify_msg_size_func_name(self): + return f"vapi_verify_{self.name}_msg_size" + + def get_verify_msg_size_func_decl(self): + return "int %s(%s *msg, uword buf_size)" % ( + self.get_verify_msg_size_func_name(), + self.get_c_name()) + + def get_verify_msg_size_func_def(self): + return inspect.cleandoc( + f""" + {self.get_verify_msg_size_func_decl()} + {{ + if (sizeof({self.get_c_name()}) > buf_size) + {{ + VAPI_ERR("Truncated '{self.name}' msg received, received %lu" + "bytes, expected %lu bytes.", buf_size, + sizeof({self.get_c_name()})); + return -1; + }} + if ({self.get_calc_msg_size_func_name()}(msg) > buf_size) + {{ + VAPI_ERR("Truncated '{self.name}' msg received, received %lu" + "bytes, expected %lu bytes.", buf_size, + sizeof({self.get_calc_msg_size_func_name()})); + return -1; + }} + return 0; + }} + """) + def get_c_def(self): if self.has_payload(): return "\n".join([ @@ -587,7 +633,8 @@ class CMessage (Message): if has_context else ' 0,', (' offsetof(%s, payload),' % self.get_c_name()) if self.has_payload() else ' VAPI_INVALID_MSG_ID,', - ' sizeof(%s),' % self.get_c_name(), + ' (verify_msg_size_fn_t)%s,' % + self.get_verify_msg_size_func_name(), ' (generic_swap_fn_t)%s,' % self.get_swap_to_be_func_name(), ' (generic_swap_fn_t)%s,' % self.get_swap_to_host_func_name(), ' VAPI_INVALID_MSG_ID,', @@ -601,22 +648,6 @@ class CMessage (Message): ]) -vapi_send_with_control_ping = """ -static inline vapi_error_e -vapi_send_with_control_ping (vapi_ctx_t ctx, void *msg, u32 context) -{ - vapi_msg_control_ping *ping = vapi_alloc_control_ping (ctx); - if (!ping) - { - return VAPI_ENOMEM; - } - ping->header.context = context; - vapi_msg_control_ping_hton (ping); - return vapi_send2 (ctx, msg, ping); -} -""" - - def emit_definition(parser, json_file, emitted, o): if o in emitted: return @@ -653,6 +684,8 @@ def emit_definition(parser, json_file, emitted, o): print("%s%s" % (function_attrs, o.get_swap_to_host_func_def())) print("") print("%s%s" % (function_attrs, o.get_calc_msg_size_func_def())) + print("") + print("%s%s" % (function_attrs, o.get_verify_msg_size_func_def())) if not o.is_reply and not o.is_event: print("") print("%s%s" % (function_attrs, o.get_alloc_func_def())) @@ -678,7 +711,8 @@ def gen_json_unified_header(parser, logger, j, io, name): orig_stdout = sys.stdout sys.stdout = io include_guard = "__included_%s" % ( - j.replace(".", "_").replace("/", "_").replace("-", "_")) + j.replace(".", "_").replace("/", "_").replace("-", "_").replace( + "+", "_").replace("@", "_")) print("#ifndef %s" % include_guard) print("#define %s" % include_guard) print("") @@ -692,12 +726,14 @@ def gen_json_unified_header(parser, logger, j, io, name): print("#ifdef __cplusplus") print("extern \"C\" {") print("#endif") - if name == "vpe.api.vapi.h": + if name == "memclnt.api.vapi.h": print("") print("static inline vapi_error_e vapi_send_with_control_ping " "(vapi_ctx_t ctx, void * msg, u32 context);") + elif name == "vlib.api.vapi.h": + print("#include ") else: - print("#include ") + print("#include ") print("") for m in parser.messages_by_json[j].values(): print("extern vapi_msg_id_t %s;" % m.get_msg_id_name()) @@ -724,8 +760,22 @@ def gen_json_unified_header(parser, logger, j, io, name): print("") - if name == "vpe.api.vapi.h": - print("%s" % vapi_send_with_control_ping) + if name == "vlib.api.vapi.h": + vapi_send_with_control_ping_function = """ +static inline vapi_error_e +vapi_send_with_control_ping (vapi_ctx_t ctx, void *msg, u32 context) +{ + vapi_msg_control_ping *ping = vapi_alloc_control_ping (ctx); + if (!ping) + { + return VAPI_ENOMEM; + } + ping->header.context = context; + vapi_msg_control_ping_hton (ping); + return vapi_send2 (ctx, msg, ping); +} +""" + print("%s" % vapi_send_with_control_ping_function) print("") print("#ifdef __cplusplus")