From 3a3cfe4762753dbd5744acaa02153c49f6c73fe1 Mon Sep 17 00:00:00 2001 From: Donald Lee Date: Sun, 20 Jun 2021 08:25:22 +0800 Subject: [PATCH] lib: Add decoder functions Split existing lua_to* functions into two functions: - lua_decode_*: unmarshall Lua values into an existing C data structure - lua_to*: allocate *and* unmarshall Lua values into C data structure This allows us to mutate C data structures passed into frrscript_call, without allocation Signed-off-by: Donald Lee --- lib/frrlua.c | 75 +++++++++++++++++++++++++++++++++++-------------- lib/frrlua.h | 16 +++++++++++ lib/frrscript.h | 14 +++++++-- 3 files changed, 82 insertions(+), 23 deletions(-) diff --git a/lib/frrlua.c b/lib/frrlua.c index d8aaa3aa3c..9fb744cde2 100644 --- a/lib/frrlua.c +++ b/lib/frrlua.c @@ -71,14 +71,17 @@ void lua_pushprefix(lua_State *L, const struct prefix *prefix) lua_setfield(L, -2, "family"); } -void *lua_toprefix(lua_State *L, int idx) +void lua_decode_prefix(lua_State *L, int idx, struct prefix *prefix) { - struct prefix *p = XCALLOC(MTYPE_TMP, sizeof(struct prefix)); - lua_getfield(L, idx, "network"); - (void)str2prefix(lua_tostring(L, -1), p); + (void)str2prefix(lua_tostring(L, -1), prefix); lua_pop(L, 1); +} +void *lua_toprefix(lua_State *L, int idx) +{ + struct prefix *p = XCALLOC(MTYPE_TMP, sizeof(struct prefix)); + lua_decode_prefix(L, idx, p); return p; } @@ -109,10 +112,8 @@ void lua_pushinterface(lua_State *L, const struct interface *ifp) lua_setfield(L, -2, "linklayer_type"); } -void *lua_tointerface(lua_State *L, int idx) +void lua_decode_interface(lua_State *L, int idx, struct interface *ifp) { - struct interface *ifp = XCALLOC(MTYPE_TMP, sizeof(struct interface)); - lua_getfield(L, idx, "name"); strlcpy(ifp->name, lua_tostring(L, -1), sizeof(ifp->name)); lua_pop(L, 1); @@ -146,13 +147,19 @@ void *lua_tointerface(lua_State *L, int idx) lua_getfield(L, idx, "linklayer_type"); ifp->ll_type = lua_tointeger(L, -1); lua_pop(L, 1); +} +void *lua_tointerface(lua_State *L, int idx) +{ + struct interface *ifp = XCALLOC(MTYPE_TMP, sizeof(struct interface)); + lua_decode_interface(L, idx, ifp); return ifp; } void lua_pushinaddr(lua_State *L, const struct in_addr *addr) { char buf[INET_ADDRSTRLEN]; + inet_ntop(AF_INET, addr, buf, sizeof(buf)); lua_newtable(L); @@ -162,14 +169,17 @@ void lua_pushinaddr(lua_State *L, const struct in_addr *addr) lua_setfield(L, -2, "string"); } -void *lua_toinaddr(lua_State *L, int idx) +void lua_decode_inaddr(lua_State *L, int idx, struct in_addr *inaddr) { - struct in_addr *inaddr = XCALLOC(MTYPE_TMP, sizeof(struct in_addr)); - lua_getfield(L, idx, "value"); inaddr->s_addr = lua_tointeger(L, -1); lua_pop(L, 1); +} +void *lua_toinaddr(lua_State *L, int idx) +{ + struct in_addr *inaddr = XCALLOC(MTYPE_TMP, sizeof(struct in_addr)); + lua_decode_inaddr(L, idx, inaddr); return inaddr; } @@ -177,6 +187,7 @@ void *lua_toinaddr(lua_State *L, int idx) void lua_pushin6addr(lua_State *L, const struct in6_addr *addr) { char buf[INET6_ADDRSTRLEN]; + inet_ntop(AF_INET6, addr, buf, sizeof(buf)); lua_newtable(L); @@ -186,20 +197,24 @@ void lua_pushin6addr(lua_State *L, const struct in6_addr *addr) lua_setfield(L, -2, "string"); } -void *lua_toin6addr(lua_State *L, int idx) +void lua_decode_in6addr(lua_State *L, int idx, struct in6_addr *in6addr) { - struct in6_addr *in6addr = XCALLOC(MTYPE_TMP, sizeof(struct in6_addr)); - lua_getfield(L, idx, "string"); inet_pton(AF_INET6, lua_tostring(L, -1), in6addr); lua_pop(L, 1); +} +void *lua_toin6addr(lua_State *L, int idx) +{ + struct in6_addr *in6addr = XCALLOC(MTYPE_TMP, sizeof(struct in6_addr)); + lua_decode_in6addr(L, idx, in6addr); return in6addr; } void lua_pushsockunion(lua_State *L, const union sockunion *su) { char buf[SU_ADDRSTRLEN]; + sockunion2str(su, buf, sizeof(buf)); lua_newtable(L); @@ -210,13 +225,17 @@ void lua_pushsockunion(lua_State *L, const union sockunion *su) lua_setfield(L, -2, "string"); } -void *lua_tosockunion(lua_State *L, int idx) +void lua_decode_sockunion(lua_State *L, int idx, union sockunion *su) { - union sockunion *su = XCALLOC(MTYPE_TMP, sizeof(union sockunion)); - lua_getfield(L, idx, "string"); str2sockunion(lua_tostring(L, -1), su); +} + +void *lua_tosockunion(lua_State *L, int idx) +{ + union sockunion *su = XCALLOC(MTYPE_TMP, sizeof(union sockunion)); + lua_decode_sockunion(L, idx, su); return su; } @@ -225,12 +244,16 @@ void lua_pushtimet(lua_State *L, const time_t *time) lua_pushinteger(L, *time); } +void lua_decode_timet(lua_State *L, int idx, time_t *t) +{ + *t = lua_tointeger(L, idx); +} + void *lua_totimet(lua_State *L, int idx) { time_t *t = XCALLOC(MTYPE_TMP, sizeof(time_t)); - *t = lua_tointeger(L, idx); - + lua_decode_timet(L, idx, t); return t; } @@ -239,17 +262,27 @@ void lua_pushintegerp(lua_State *L, const long long *num) lua_pushinteger(L, *num); } -void *lua_tointegerp(lua_State *L, int idx) +void lua_decode_integerp(lua_State *L, int idx, long long *num) { int isnum; - long long *num = XCALLOC(MTYPE_TMP, sizeof(long long)); - *num = lua_tonumberx(L, idx, &isnum); assert(isnum); +} + +void *lua_tointegerp(lua_State *L, int idx) +{ + long long *num = XCALLOC(MTYPE_TMP, sizeof(long long)); + lua_decode_integerp(L, idx, num); return num; } +void lua_decode_stringp(lua_State *L, int idx, char *str) +{ + strlcpy(str, lua_tostring(L, idx), strlen(str) + 1); + lua_pop(L, 1); +} + void *lua_tostringp(lua_State *L, int idx) { char *string = XSTRDUP(MTYPE_TMP, lua_tostring(L, idx)); diff --git a/lib/frrlua.h b/lib/frrlua.h index 6fb30938b0..3ca5b1f778 100644 --- a/lib/frrlua.h +++ b/lib/frrlua.h @@ -50,6 +50,8 @@ static inline void lua_pushstring_wrapper(lua_State *L, const char *str) */ void lua_pushprefix(lua_State *L, const struct prefix *prefix); +void lua_decode_prefix(lua_State *L, int idx, struct prefix *prefix); + /* * Converts the Lua value at idx to a prefix. * @@ -63,6 +65,8 @@ void *lua_toprefix(lua_State *L, int idx); */ void lua_pushinterface(lua_State *L, const struct interface *ifp); +void lua_decode_interface(lua_State *L, int idx, struct interface *ifp); + /* * Converts the Lua value at idx to an interface. * @@ -77,6 +81,8 @@ void *lua_tointerface(lua_State *L, int idx); */ void lua_pushinaddr(lua_State *L, const struct in_addr *addr); +void lua_decode_inaddr(lua_State *L, int idx, struct in_addr *addr); + /* * Converts the Lua value at idx to an in_addr. * @@ -90,6 +96,8 @@ void *lua_toinaddr(lua_State *L, int idx); */ void lua_pushin6addr(lua_State *L, const struct in6_addr *addr); +void lua_decode_in6addr(lua_State *L, int idx, struct in6_addr *addr); + /* * Converts the Lua value at idx to an in6_addr. * @@ -103,6 +111,8 @@ void *lua_toin6addr(lua_State *L, int idx); */ void lua_pushtimet(lua_State *L, const time_t *time); +void lua_decode_timet(lua_State *L, int idx, time_t *time); + /* * Converts the Lua value at idx to a time_t. * @@ -116,6 +126,8 @@ void *lua_totimet(lua_State *L, int idx); */ void lua_pushsockunion(lua_State *L, const union sockunion *su); +void lua_decode_sockunion(lua_State *L, int idx, union sockunion *su); + /* * Converts the Lua value at idx to a sockunion. * @@ -129,6 +141,8 @@ void *lua_tosockunion(lua_State *L, int idx); */ void lua_pushintegerp(lua_State *L, const long long *num); +void lua_decode_integerp(lua_State *L, int idx, long long *num); + /* * Converts the Lua value at idx to an int. * @@ -137,6 +151,8 @@ void lua_pushintegerp(lua_State *L, const long long *num); */ void *lua_tointegerp(lua_State *L, int idx); +void lua_decode_stringp(lua_State *L, int idx, char *str); + /* * Pop string. * diff --git a/lib/frrscript.h b/lib/frrscript.h index 5410f53e11..14e1834a11 100644 --- a/lib/frrscript.h +++ b/lib/frrscript.h @@ -105,7 +105,7 @@ void frrscript_init(const char *scriptdir); #define DECODE_ARGS(name, value) \ do { \ lua_getglobal(L, name); \ - DECODE_ARGS_WITH_STATE(L, value) \ + DECODE_ARGS_WITH_STATE(L, value); \ } while (0) #define ENCODE_ARGS_WITH_STATE(L, value) \ @@ -120,7 +120,17 @@ time_t * : lua_pushtimet, \ char * : lua_pushstring_wrapper \ )(L, value) -#define DECODE_ARGS_WITH_STATE(L, value) _Generic((value), )(L, value); +#define DECODE_ARGS_WITH_STATE(L, value) \ + _Generic((value), \ +long long * : lua_decode_integerp, \ +struct prefix * : lua_decode_prefix, \ +struct interface * : lua_decode_interface, \ +struct in_addr * : lua_decode_inaddr, \ +struct in6_addr * : lua_decode_in6addr, \ +union sockunion * : lua_decode_sockunion, \ +time_t * : lua_decode_timet, \ +char * : lua_decode_stringp \ +)(L, -1, value) /* * Call script. -- 2.39.5