From 6021965926654eb96c22391725ae0133ea77e784 Mon Sep 17 00:00:00 2001 From: Quentin Young Date: Sat, 11 May 2019 00:55:50 +0000 Subject: [PATCH] lib: clean up frrlua.[ch] * Use frrlua_* prefix to differentiate from Lua builtins * Allow frrlua_initialize to pass an empty script * Fixup naming of table accessors * Fixup naming of prefix -> table encoder * Fixup BGP routemap code to new function names * Fix includes for frrlua.h * Clean up doc comments Signed-off-by: Quentin Young --- bgpd/bgp_routemap.c | 14 ++--- lib/frrlua.c | 135 +++++++++++++++++++++++++++----------------- lib/frrlua.h | 85 ++++++++++++++++------------ 3 files changed, 139 insertions(+), 95 deletions(-) diff --git a/bgpd/bgp_routemap.c b/bgpd/bgp_routemap.c index 637eaca397..d9457ea616 100644 --- a/bgpd/bgp_routemap.c +++ b/bgpd/bgp_routemap.c @@ -344,9 +344,9 @@ route_match_command(void *rule, const struct prefix *prefix, void *object) int status = RMAP_NOMATCH; u_int32_t locpref = 0; u_int32_t newlocpref = 0; - enum lua_rm_status lrm_status; + enum frrlua_rm_status lrm_status; struct bgp_path_info *path = (struct bgp_path_info *)object; - lua_State *L = lua_initialize("/etc/frr/lua.scr"); + lua_State *L = frrlua_initialize("/etc/frr/lua.scr"); if (L == NULL) return status; @@ -354,9 +354,7 @@ route_match_command(void *rule, const struct prefix *prefix, void *object) /* * Setup the prefix information to pass in */ - lua_setup_prefix_table(L, prefix); - - zlog_debug("Set up prefix table"); + frrlua_newtable_prefix(L, prefix); /* * Setup the bgp_path_info information */ @@ -376,7 +374,7 @@ route_match_command(void *rule, const struct prefix *prefix, void *object) /* * Run the rule */ - lrm_status = lua_run_rm_rule(L, rule); + lrm_status = frrlua_run_rm_rule(L, rule); switch (lrm_status) { case LUA_RM_FAILURE: zlog_debug("RM_FAILURE"); @@ -387,13 +385,13 @@ route_match_command(void *rule, const struct prefix *prefix, void *object) case LUA_RM_MATCH_AND_CHANGE: zlog_debug("MATCH AND CHANGE"); lua_getglobal(L, "nexthop"); - path->attr->med = get_integer(L, "metric"); + path->attr->med = frrlua_table_get_integer(L, "metric"); /* * This needs to be abstraced with the set function */ if (path->attr->flag & ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF)) locpref = path->attr->local_pref; - newlocpref = get_integer(L, "localpref"); + newlocpref = frrlua_table_get_integer(L, "localpref"); if (newlocpref != locpref) { path->attr->flag |= ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF); path->attr->local_pref = newlocpref; diff --git a/lib/frrlua.c b/lib/frrlua.c index 9f9cf8c1f6..0c6d607b7a 100644 --- a/lib/frrlua.c +++ b/lib/frrlua.c @@ -2,25 +2,23 @@ * This file defines the lua interface into * FRRouting. * - * Copyright (C) 2016 Cumulus Networks, Inc. - * Donald Sharp + * Copyright (C) 2016-2019 Cumulus Networks, Inc. + * Donald Sharp, Quentin Young * - * This file is part of FRRouting (FRR). + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the Free + * Software Foundation; either version 2 of the License, or (at your option) + * any later version. * - * FRR is free software; you can redistribute it and/or modify it under the - * terms of the GNU General Public License as published by the Free Software - * Foundation; either version 2, or (at your option) any later version. - * - * FRR is distributed in the hope that it will be useful, but WITHOUT ANY - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more - * details. + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. * * You should have received a copy of the GNU General Public License along - * with FRR; see the file COPYING. If not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * with this program; see the file COPYING; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ - #include #if defined(HAVE_LUA) @@ -28,6 +26,12 @@ #include "frrlua.h" #include "log.h" +/* + * Lua -> FRR function bindings. + * + * This section defines functions exportable into Lua environments. + */ + static int lua_zlog_debug(lua_State *L) { int debug_lua = 1; @@ -39,7 +43,14 @@ static int lua_zlog_debug(lua_State *L) return 0; } -const char *get_string(lua_State *L, const char *key) +/* + * FRR convenience functions. + * + * This section has convenience functions used to make interacting with the Lua + * stack easier. + */ + +const char *frrlua_table_get_string(lua_State *L, const char *key) { const char *str; @@ -52,7 +63,7 @@ const char *get_string(lua_State *L, const char *key) return str; } -int get_integer(lua_State *L, const char *key) +int frrlua_table_get_integer(lua_State *L, const char *key) { int result; @@ -65,44 +76,19 @@ int get_integer(lua_State *L, const char *key) return result; } -static void *lua_alloc(void *ud, void *ptr, size_t osize, - size_t nsize) -{ - (void)ud; (void)osize; /* not used */ - if (nsize == 0) { - free(ptr); - return NULL; - } else - return realloc(ptr, nsize); -} - -lua_State *lua_initialize(const char *file) -{ - int status; - lua_State *L = lua_newstate(lua_alloc, NULL); - - zlog_debug("Newstate: %p", L); - luaL_openlibs(L); - zlog_debug("Opened lib"); - status = luaL_loadfile(L, file); - if (status) { - zlog_debug("Failure to open %s %d", file, status); - lua_close(L); - return NULL; - } - - lua_pcall(L, 0, LUA_MULTRET, 0); - zlog_debug("Setting global function"); - lua_pushcfunction(L, lua_zlog_debug); - lua_setglobal(L, "zlog_debug"); - - return L; -} +/* + * Encoders. + * + * This section has functions that convert internal FRR datatypes into Lua + * datatypes. + */ -void lua_setup_prefix_table(lua_State *L, const struct prefix *prefix) +void frrlua_newtable_prefix(lua_State *L, const struct prefix *prefix) { char buffer[100]; + zlog_debug("frrlua: pushing prefix table"); + lua_newtable(L); lua_pushstring(L, prefix2str(prefix, buffer, 100)); lua_setfield(L, -2, "route"); @@ -111,7 +97,14 @@ void lua_setup_prefix_table(lua_State *L, const struct prefix *prefix) lua_setglobal(L, "prefix"); } -enum lua_rm_status lua_run_rm_rule(lua_State *L, const char *rule) +/* + * Experimental. + * + * This section has experimental Lua functionality that doesn't belong + * elsewhere. + */ + +enum frrlua_rm_status frrlua_run_rm_rule(lua_State *L, const char *rule) { int status; @@ -126,4 +119,44 @@ enum lua_rm_status lua_run_rm_rule(lua_State *L, const char *rule) status = lua_tonumber(L, -1); return status; } + +/* Initialization */ + +static void *frrlua_alloc(void *ud, void *ptr, size_t osize, size_t nsize) +{ + (void)ud; + (void)osize; /* not used */ + + if (nsize == 0) { + free(ptr); + return NULL; + } else + return realloc(ptr, nsize); +} + +lua_State *frrlua_initialize(const char *file) +{ + int status; + lua_State *L = lua_newstate(frrlua_alloc, NULL); + + zlog_debug("Newstate: %p", L); + luaL_openlibs(L); + zlog_debug("Opened lib"); + if (file) { + status = luaL_loadfile(L, file); + if (status) { + zlog_debug("Failure to open %s %d", file, status); + lua_close(L); + return NULL; + } + lua_pcall(L, 0, LUA_MULTRET, 0); + } + + zlog_debug("Setting global function"); + lua_pushcfunction(L, lua_zlog_debug); + lua_setglobal(L, "zlog_debug"); + + return L; +} + #endif diff --git a/lib/frrlua.h b/lib/frrlua.h index 40c7a67b89..5d5e63da69 100644 --- a/lib/frrlua.h +++ b/lib/frrlua.h @@ -1,27 +1,23 @@ /* - * This file defines the lua interface into - * FRRouting. + * Copyright (C) 2016-2019 Cumulus Networks, Inc. + * Donald Sharp, Quentin Young * - * Copyright (C) 2016 Cumulus Networks, Inc. - * Donald Sharp + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the Free + * Software Foundation; either version 2 of the License, or (at your option) + * any later version. * - * This file is part of FRRouting (FRR). - * - * FRR is free software; you can redistribute it and/or modify it under the - * terms of the GNU General Public License as published by the Free Software - * Foundation; either version 2, or (at your option) any later version. - * - * FRR is distributed in the hope that it will be useful, but WITHOUT ANY - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more - * details. + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. * * You should have received a copy of the GNU General Public License along - * with FRR; see the file COPYING. If not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * with this program; see the file COPYING; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ -#ifndef __LUA_H__ -#define __LUA_H__ +#ifndef __FRRLUA_H__ +#define __FRRLUA_H__ #if defined(HAVE_LUA) @@ -29,18 +25,16 @@ #include "lualib.h" #include "lauxlib.h" +#include "prefix.h" + #ifdef __cplusplus extern "C" { #endif /* - * These functions are helper functions that - * try to glom some of the lua_XXX functionality - * into what we actually need, instead of having - * to make multiple calls to set up what - * we want + * Status enum for Lua routemap processing results */ -enum lua_rm_status { +enum frrlua_rm_status { /* * Script function run failure. This will translate into a * deny @@ -63,26 +57,45 @@ enum lua_rm_status { }; /* - * Open up the lua.scr file and parse - * initial global values, if any. + * Creates a new Lua state, loads all libraries, and if a script is provided, + * runs it. + * + * Returns: + * The new Lua state. + */ +lua_State *frrlua_initialize(const char *file); + +/* + * Pushes a new table containing relevant fields from a prefix structure. + * + * Additionally sets the global variable "prefix" to point at this table. */ -lua_State *lua_initialize(const char *file); +void frrlua_newtable_prefix(lua_State *L, const struct prefix *prefix); -void lua_setup_prefix_table(lua_State *L, const struct prefix *prefix); +/* + * Runs a routemap rule or something + */ +enum frrlua_rm_status frrlua_run_rm_rule(lua_State *L, const char *rule); -enum lua_rm_status lua_run_rm_rule(lua_State *L, const char *rule); +/* + * Retrieve a string from table on the top of the stack. + * + * key + * Key of string value in table + */ +const char *frrlua_table_get_string(lua_State *L, const char *key); /* - * Get particular string/integer information - * from a table. It is *assumed* that - * the table has already been selected + * Retrieve an integer from table on the top of the stack. + * + * key + * Key of string value in table */ -const char *get_string(lua_State *L, const char *key); -int get_integer(lua_State *L, const char *key); +int frrlua_table_get_integer(lua_State *L, const char *key); #ifdef __cplusplus } #endif -#endif -#endif +#endif /* HAVE_LUA */ +#endif /* __FRRLUA_H__ */ -- 2.39.5