mirror of
https://git.proxmox.com/git/mirror_frr
synced 2025-08-07 13:33:15 +00:00
lib: Change frrscript_call to call function instead
There is some rather heavy error checking logic in frrscript_call. Normally I'd put this in the _frrscript_call function, but the error checking needs to happen before the encoders/decoders in the macro are called. The error checking looks messy but its really just nested ternary expressions insite a larger statement expression. Signed-off-by: Donald Lee <dlqs@gmx.com>
This commit is contained in:
parent
f0cddf950f
commit
40d038d2a1
@ -138,41 +138,57 @@ static void lua_function_free(struct lua_function_state *lfs)
|
|||||||
|
|
||||||
/* Generic script APIs */
|
/* Generic script APIs */
|
||||||
|
|
||||||
int _frrscript_call(struct frrscript *fs)
|
int _frrscript_call_lua(struct lua_function_state *lfs, int nargs)
|
||||||
{
|
{
|
||||||
|
|
||||||
int ret = lua_pcall(fs->L, 0, 0, 0);
|
int ret;
|
||||||
|
ret = lua_pcall(lfs->L, nargs, 1, 0);
|
||||||
|
|
||||||
switch (ret) {
|
switch (ret) {
|
||||||
case LUA_OK:
|
case LUA_OK:
|
||||||
break;
|
break;
|
||||||
case LUA_ERRRUN:
|
case LUA_ERRRUN:
|
||||||
zlog_err("Script '%s' runtime error: %s", fs->name,
|
zlog_err("Lua hook call '%s' : runtime error: %s", lfs->name,
|
||||||
lua_tostring(fs->L, -1));
|
lua_tostring(lfs->L, -1));
|
||||||
break;
|
break;
|
||||||
case LUA_ERRMEM:
|
case LUA_ERRMEM:
|
||||||
zlog_err("Script '%s' memory error: %s", fs->name,
|
zlog_err("Lua hook call '%s' : memory error: %s", lfs->name,
|
||||||
lua_tostring(fs->L, -1));
|
lua_tostring(lfs->L, -1));
|
||||||
break;
|
break;
|
||||||
case LUA_ERRERR:
|
case LUA_ERRERR:
|
||||||
zlog_err("Script '%s' error handler error: %s", fs->name,
|
zlog_err("Lua hook call '%s' : error handler error: %s",
|
||||||
lua_tostring(fs->L, -1));
|
lfs->name, lua_tostring(lfs->L, -1));
|
||||||
break;
|
break;
|
||||||
case LUA_ERRGCMM:
|
case LUA_ERRGCMM:
|
||||||
zlog_err("Script '%s' garbage collector error: %s", fs->name,
|
zlog_err("Lua hook call '%s' : garbage collector error: %s",
|
||||||
lua_tostring(fs->L, -1));
|
lfs->name, lua_tostring(lfs->L, -1));
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
zlog_err("Script '%s' unknown error: %s", fs->name,
|
zlog_err("Lua hook call '%s' : unknown error: %s", lfs->name,
|
||||||
lua_tostring(fs->L, -1));
|
lua_tostring(lfs->L, -1));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ret != LUA_OK) {
|
if (ret != LUA_OK) {
|
||||||
lua_pop(fs->L, 1);
|
lua_pop(lfs->L, 1);
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (lua_gettop(lfs->L) != 1) {
|
||||||
|
zlog_err(
|
||||||
|
"Lua hook call '%s': Lua function should return only 1 result",
|
||||||
|
lfs->name);
|
||||||
|
ret = 1;
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (lua_istable(lfs->L, 1) != 1) {
|
||||||
|
zlog_err(
|
||||||
|
"Lua hook call '%s': Lua function should return a Lua table",
|
||||||
|
lfs->name);
|
||||||
|
ret = 1;
|
||||||
|
}
|
||||||
|
|
||||||
done:
|
done:
|
||||||
/* LUA_OK is 0, so we can just return lua_pcall's result directly */
|
/* LUA_OK is 0, so we can just return lua_pcall's result directly */
|
||||||
return ret;
|
return ret;
|
||||||
|
@ -119,16 +119,12 @@ void frrscript_register_type_codecs(struct frrscript_codec *codecs);
|
|||||||
*/
|
*/
|
||||||
void frrscript_init(const char *scriptdir);
|
void frrscript_init(const char *scriptdir);
|
||||||
|
|
||||||
#define ENCODE_ARGS(name, value) \
|
#define ENCODE_ARGS(name, value) ENCODE_ARGS_WITH_STATE(lfs->L, value)
|
||||||
do { \
|
|
||||||
ENCODE_ARGS_WITH_STATE(L, value); \
|
|
||||||
lua_setglobal(L, name); \
|
|
||||||
} while (0)
|
|
||||||
|
|
||||||
#define DECODE_ARGS(name, value) \
|
#define DECODE_ARGS(name, value) \
|
||||||
do { \
|
do { \
|
||||||
lua_getglobal(L, name); \
|
lua_getfield(lfs->L, 1, name); \
|
||||||
DECODE_ARGS_WITH_STATE(L, value); \
|
DECODE_ARGS_WITH_STATE(lfs->L, value); \
|
||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -179,7 +175,7 @@ const struct prefix * : lua_decode_noop \
|
|||||||
* Returns:
|
* Returns:
|
||||||
* 0 if the script ran successfully, nonzero otherwise.
|
* 0 if the script ran successfully, nonzero otherwise.
|
||||||
*/
|
*/
|
||||||
int _frrscript_call(struct frrscript *fs);
|
int _frrscript_call_lua(struct lua_function_state *lfs, int nargs);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Wrapper for call script. Maps values passed in to their encoder
|
* Wrapper for call script. Maps values passed in to their encoder
|
||||||
@ -191,15 +187,32 @@ int _frrscript_call(struct frrscript *fs);
|
|||||||
* Returns:
|
* Returns:
|
||||||
* 0 if the script ran successfully, nonzero otherwise.
|
* 0 if the script ran successfully, nonzero otherwise.
|
||||||
*/
|
*/
|
||||||
#define frrscript_call(fs, ...) \
|
|
||||||
({ \
|
#define frrscript_call(fs, f, ...) \
|
||||||
lua_State *L = fs->L; \
|
({ \
|
||||||
MAP_LISTS(ENCODE_ARGS, ##__VA_ARGS__); \
|
struct lua_function_state lookup = {.name = f}; \
|
||||||
int ret = _frrscript_call(fs); \
|
struct lua_function_state *lfs; \
|
||||||
if (ret == 0) { \
|
lfs = hash_lookup(fs->lua_function_hash, &lookup); \
|
||||||
MAP_LISTS(DECODE_ARGS, ##__VA_ARGS__); \
|
lfs == NULL ? ({ \
|
||||||
} \
|
zlog_err( \
|
||||||
ret; \
|
"Lua script call: tried to call '%s' in '%s' which was not loaded", \
|
||||||
|
f, fs->name); \
|
||||||
|
1; \
|
||||||
|
}) \
|
||||||
|
: ({ \
|
||||||
|
MAP_LISTS(ENCODE_ARGS, ##__VA_ARGS__); \
|
||||||
|
_frrscript_call_lua(lfs, PP_NARG(__VA_ARGS__)); \
|
||||||
|
}) != 0 \
|
||||||
|
? ({ \
|
||||||
|
zlog_err( \
|
||||||
|
"Lua script call: '%s' in '%s' returned non-zero exit code", \
|
||||||
|
f, fs->name); \
|
||||||
|
1; \
|
||||||
|
}) \
|
||||||
|
: ({ \
|
||||||
|
MAP_LISTS(DECODE_ARGS, ##__VA_ARGS__); \
|
||||||
|
0; \
|
||||||
|
}); \
|
||||||
})
|
})
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
Loading…
Reference in New Issue
Block a user