mirror of
https://git.proxmox.com/git/mirror_frr
synced 2025-08-04 16:57:43 +00:00
Merge pull request #9012 from dlqs/lua-poly
Refactor decoder for Lua hook system
This commit is contained in:
commit
36547f400e
@ -488,12 +488,6 @@ match *exactly*.
|
|||||||
In the above example, we defined encoders/decoders for a value of
|
In the above example, we defined encoders/decoders for a value of
|
||||||
``struct prefix *``, but not ``struct prefix`` or ``const struct prefix *``.
|
``struct prefix *``, but not ``struct prefix`` or ``const struct prefix *``.
|
||||||
|
|
||||||
``const`` values are a special case. We want to use them in our Lua scripts
|
|
||||||
but not modify them, so creating a decoder for them would be meaningless.
|
|
||||||
But we still need a decoder for the type of value so that the compiler will be
|
|
||||||
satisfied.
|
|
||||||
For that, use ``lua_decode_noop``:
|
|
||||||
|
|
||||||
.. code-block:: diff
|
.. code-block:: diff
|
||||||
|
|
||||||
#define DECODE_ARGS_WITH_STATE(L, value) \
|
#define DECODE_ARGS_WITH_STATE(L, value) \
|
||||||
|
43
lib/frrlua.c
43
lib/frrlua.c
@ -259,12 +259,12 @@ void *lua_tosockunion(lua_State *L, int idx)
|
|||||||
return su;
|
return su;
|
||||||
}
|
}
|
||||||
|
|
||||||
void lua_pushintegerp(lua_State *L, const long long *num)
|
void lua_pushintegerp(lua_State *L, const int *num)
|
||||||
{
|
{
|
||||||
lua_pushinteger(L, *num);
|
lua_pushinteger(L, *num);
|
||||||
}
|
}
|
||||||
|
|
||||||
void lua_decode_integerp(lua_State *L, int idx, long long *num)
|
void lua_decode_integerp(lua_State *L, int idx, int *num)
|
||||||
{
|
{
|
||||||
int isnum;
|
int isnum;
|
||||||
*num = lua_tonumberx(L, idx, &isnum);
|
*num = lua_tonumberx(L, idx, &isnum);
|
||||||
@ -274,7 +274,7 @@ void lua_decode_integerp(lua_State *L, int idx, long long *num)
|
|||||||
|
|
||||||
void *lua_tointegerp(lua_State *L, int idx)
|
void *lua_tointegerp(lua_State *L, int idx)
|
||||||
{
|
{
|
||||||
long long *num = XCALLOC(MTYPE_SCRIPT_RES, sizeof(long long));
|
int *num = XCALLOC(MTYPE_SCRIPT_RES, sizeof(int));
|
||||||
|
|
||||||
lua_decode_integerp(L, idx, num);
|
lua_decode_integerp(L, idx, num);
|
||||||
return num;
|
return num;
|
||||||
@ -332,6 +332,28 @@ void lua_pushnexthop_group(lua_State *L, const struct nexthop_group *ng)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void lua_pushlonglongp(lua_State *L, const long long *num)
|
||||||
|
{
|
||||||
|
/* lua library function; this can take a long long */
|
||||||
|
lua_pushinteger(L, *num);
|
||||||
|
}
|
||||||
|
|
||||||
|
void lua_decode_longlongp(lua_State *L, int idx, long long *num)
|
||||||
|
{
|
||||||
|
int isnum;
|
||||||
|
*num = lua_tonumberx(L, idx, &isnum);
|
||||||
|
lua_pop(L, 1);
|
||||||
|
assert(isnum);
|
||||||
|
}
|
||||||
|
|
||||||
|
void *lua_tolonglongp(lua_State *L, int idx)
|
||||||
|
{
|
||||||
|
long long *num = XCALLOC(MTYPE_SCRIPT_RES, sizeof(long long));
|
||||||
|
|
||||||
|
lua_decode_longlongp(L, idx, num);
|
||||||
|
return num;
|
||||||
|
}
|
||||||
|
|
||||||
void lua_decode_stringp(lua_State *L, int idx, char *str)
|
void lua_decode_stringp(lua_State *L, int idx, char *str)
|
||||||
{
|
{
|
||||||
strlcpy(str, lua_tostring(L, idx), strlen(str) + 1);
|
strlcpy(str, lua_tostring(L, idx), strlen(str) + 1);
|
||||||
@ -345,21 +367,6 @@ void *lua_tostringp(lua_State *L, int idx)
|
|||||||
return string;
|
return string;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* Decoder for const values, since we cannot modify them.
|
|
||||||
*/
|
|
||||||
void lua_decode_noop(lua_State *L, int idx, const void *ptr)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Noop decoder for int.
|
|
||||||
*/
|
|
||||||
void lua_decode_integer_noop(lua_State *L, int idx, int i)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Logging.
|
* Logging.
|
||||||
*
|
*
|
||||||
|
26
lib/frrlua.h
26
lib/frrlua.h
@ -121,9 +121,9 @@ void lua_pushnexthop(lua_State *L, const struct nexthop *nexthop);
|
|||||||
/*
|
/*
|
||||||
* Converts an int to a Lua value and pushes it on the stack.
|
* Converts an int to a Lua value and pushes it on the stack.
|
||||||
*/
|
*/
|
||||||
void lua_pushintegerp(lua_State *L, const long long *num);
|
void lua_pushintegerp(lua_State *L, const int *num);
|
||||||
|
|
||||||
void lua_decode_integerp(lua_State *L, int idx, long long *num);
|
void lua_decode_integerp(lua_State *L, int idx, int *num);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Converts the Lua value at idx to an int.
|
* Converts the Lua value at idx to an int.
|
||||||
@ -133,6 +133,21 @@ void lua_decode_integerp(lua_State *L, int idx, long long *num);
|
|||||||
*/
|
*/
|
||||||
void *lua_tointegerp(lua_State *L, int idx);
|
void *lua_tointegerp(lua_State *L, int idx);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Converts a long long to a Lua value and pushes it on the stack.
|
||||||
|
*/
|
||||||
|
void lua_pushlonglongp(lua_State *L, const long long *num);
|
||||||
|
|
||||||
|
void lua_decode_longlongp(lua_State *L, int idx, long long *num);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Converts the Lua value at idx to a long long.
|
||||||
|
*
|
||||||
|
* Returns:
|
||||||
|
* long long allocated with MTYPE_TMP.
|
||||||
|
*/
|
||||||
|
void *lua_tolonglongp(lua_State *L, int idx);
|
||||||
|
|
||||||
void lua_decode_stringp(lua_State *L, int idx, char *str);
|
void lua_decode_stringp(lua_State *L, int idx, char *str);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -143,13 +158,6 @@ void lua_decode_stringp(lua_State *L, int idx, char *str);
|
|||||||
*/
|
*/
|
||||||
void *lua_tostringp(lua_State *L, int idx);
|
void *lua_tostringp(lua_State *L, int idx);
|
||||||
|
|
||||||
/*
|
|
||||||
* No-op decoders
|
|
||||||
*/
|
|
||||||
void lua_decode_noop(lua_State *L, int idx, const void *ptr);
|
|
||||||
|
|
||||||
void lua_decode_integer_noop(lua_State *L, int idx, int i);
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Retrieve an integer from table on the top of the stack.
|
* Retrieve an integer from table on the top of the stack.
|
||||||
*
|
*
|
||||||
|
@ -25,6 +25,8 @@ DEFINE_MTYPE_STATIC(LIB, SCRIPT, "Scripting");
|
|||||||
|
|
||||||
struct frrscript_names_head frrscript_names_hash;
|
struct frrscript_names_head frrscript_names_hash;
|
||||||
|
|
||||||
|
void _lua_decode_noop(lua_State *L, ...) {}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Wrapper for frrscript_names_add
|
* Wrapper for frrscript_names_add
|
||||||
* Use this to register hook calls when a daemon starts up
|
* Use this to register hook calls when a daemon starts up
|
||||||
|
@ -180,6 +180,11 @@ void frrscript_fini(void);
|
|||||||
assert(lua_gettop(lfs->L) == 1); \
|
assert(lua_gettop(lfs->L) == 1); \
|
||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Noop function. Used below where we need a noop decoder for any type.
|
||||||
|
*/
|
||||||
|
void _lua_decode_noop(lua_State *, ...);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Maps the type of value to its encoder/decoder.
|
* Maps the type of value to its encoder/decoder.
|
||||||
* Add new mappings here.
|
* Add new mappings here.
|
||||||
@ -192,7 +197,9 @@ void frrscript_fini(void);
|
|||||||
#define ENCODE_ARGS_WITH_STATE(L, value) \
|
#define ENCODE_ARGS_WITH_STATE(L, value) \
|
||||||
_Generic((value), \
|
_Generic((value), \
|
||||||
int : lua_pushinteger, \
|
int : lua_pushinteger, \
|
||||||
long long * : lua_pushintegerp, \
|
int * : lua_pushintegerp, \
|
||||||
|
long long : lua_pushinteger, \
|
||||||
|
long long * : lua_pushlonglongp, \
|
||||||
struct prefix * : lua_pushprefix, \
|
struct prefix * : lua_pushprefix, \
|
||||||
struct interface * : lua_pushinterface, \
|
struct interface * : lua_pushinterface, \
|
||||||
struct in_addr * : lua_pushinaddr, \
|
struct in_addr * : lua_pushinaddr, \
|
||||||
@ -211,8 +218,8 @@ struct zebra_dplane_ctx * : lua_pushzebra_dplane_ctx \
|
|||||||
|
|
||||||
#define DECODE_ARGS_WITH_STATE(L, value) \
|
#define DECODE_ARGS_WITH_STATE(L, value) \
|
||||||
_Generic((value), \
|
_Generic((value), \
|
||||||
int : lua_decode_integer_noop, \
|
int * : lua_decode_integerp, \
|
||||||
long long * : lua_decode_integerp, \
|
long long * : lua_decode_longlongp, \
|
||||||
struct prefix * : lua_decode_prefix, \
|
struct prefix * : lua_decode_prefix, \
|
||||||
struct interface * : lua_decode_interface, \
|
struct interface * : lua_decode_interface, \
|
||||||
struct in_addr * : lua_decode_inaddr, \
|
struct in_addr * : lua_decode_inaddr, \
|
||||||
@ -220,13 +227,7 @@ struct in6_addr * : lua_decode_in6addr, \
|
|||||||
union sockunion * : lua_decode_sockunion, \
|
union sockunion * : lua_decode_sockunion, \
|
||||||
char * : lua_decode_stringp, \
|
char * : lua_decode_stringp, \
|
||||||
struct attr * : lua_decode_attr, \
|
struct attr * : lua_decode_attr, \
|
||||||
struct peer * : lua_decode_noop, \
|
default : _lua_decode_noop \
|
||||||
const struct prefix * : lua_decode_noop, \
|
|
||||||
const struct ipaddr * : lua_decode_noop, \
|
|
||||||
const struct ethaddr * : lua_decode_noop, \
|
|
||||||
const struct nexthop_group * : lua_decode_noop, \
|
|
||||||
const struct nexthop * : lua_decode_noop, \
|
|
||||||
struct zebra_dplane_ctx * : lua_decode_noop \
|
|
||||||
)((L), -1, (value))
|
)((L), -1, (value))
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -13,14 +13,22 @@ static void test_encode_decode(void)
|
|||||||
{
|
{
|
||||||
lua_State *L = luaL_newstate();
|
lua_State *L = luaL_newstate();
|
||||||
|
|
||||||
long long a = 123;
|
int a = 123;
|
||||||
long long b = a;
|
int b = a;
|
||||||
|
|
||||||
lua_pushintegerp(L, &a);
|
lua_pushintegerp(L, &a);
|
||||||
lua_decode_integerp(L, -1, &a);
|
lua_decode_integerp(L, -1, &a);
|
||||||
assert(a == b);
|
assert(a == b);
|
||||||
assert(lua_gettop(L) == 0);
|
assert(lua_gettop(L) == 0);
|
||||||
|
|
||||||
|
long long ll_a = 123L;
|
||||||
|
long long ll_b = a;
|
||||||
|
|
||||||
|
lua_pushlonglongp(L, &ll_a);
|
||||||
|
lua_decode_longlongp(L, -1, &ll_a);
|
||||||
|
assert(ll_a == ll_b);
|
||||||
|
assert(lua_gettop(L) == 0);
|
||||||
|
|
||||||
time_t time_a = 100;
|
time_t time_a = 100;
|
||||||
time_t time_b;
|
time_t time_b;
|
||||||
|
|
||||||
|
@ -32,7 +32,7 @@ int main(int argc, char **argv)
|
|||||||
assert(result == 0);
|
assert(result == 0);
|
||||||
result = frrscript_call(fs, "bar", ("a", &a), ("b", &b));
|
result = frrscript_call(fs, "bar", ("a", &a), ("b", &b));
|
||||||
assert(result == 0);
|
assert(result == 0);
|
||||||
long long *cptr = frrscript_get_result(fs, "bar", "c", lua_tointegerp);
|
long long *cptr = frrscript_get_result(fs, "bar", "c", lua_tolonglongp);
|
||||||
|
|
||||||
/* a should not occur in the returned table in script */
|
/* a should not occur in the returned table in script */
|
||||||
assert(a == 100);
|
assert(a == 100);
|
||||||
@ -47,7 +47,7 @@ int main(int argc, char **argv)
|
|||||||
result = frrscript_call(fs, "fact", ("n", &n));
|
result = frrscript_call(fs, "fact", ("n", &n));
|
||||||
assert(result == 0);
|
assert(result == 0);
|
||||||
long long *ansptr =
|
long long *ansptr =
|
||||||
frrscript_get_result(fs, "fact", "ans", lua_tointegerp);
|
frrscript_get_result(fs, "fact", "ans", lua_tolonglongp);
|
||||||
assert(*ansptr == 120);
|
assert(*ansptr == 120);
|
||||||
|
|
||||||
/* check consecutive call + get_result without re-loading */
|
/* check consecutive call + get_result without re-loading */
|
||||||
|
Loading…
Reference in New Issue
Block a user