diff --git a/lib/printf.c b/lib/printf.c index 533a1300..7ccbb4cc 100644 --- a/lib/printf.c +++ b/lib/printf.c @@ -8,6 +8,7 @@ */ #include "nest/bird.h" +#include "conf/conf.h" #include "string.h" #include diff --git a/lua/common.c b/lua/common.c index fea030f5..d9467967 100644 --- a/lua/common.c +++ b/lua/common.c @@ -1,4 +1,5 @@ #include "nest/bird.h" +#include "conf/conf.h" #include "filter/filter.h" #include "lua.h" @@ -54,24 +55,88 @@ static int luaB_trace(lua_State *L) { return 0; } -void luaB_push_bird_table(lua_State *L) { +#define lua_sett(L, idx, val, what) do { \ + lua_pushstring(L, idx); \ + lua_push##what(L, val); \ + lua_settable(L, -3); \ +} while (0) + +#define lua_settablecfunction(L, idx, val) lua_sett(L, idx, val, cfunction) +#define lua_settableinteger(L, idx, val) lua_sett(L, idx, val, integer) +#define lua_settableip4(L, idx, val) lua_sett(L, idx, val, ip4) + +static int luaB_generic_concat(lua_State *L) { + int n = lua_gettop(L); + if (n != 2) { + log(L_WARN "__concat needs exactly 2 arguments"); + return 0; + } + + const char *a, *b; + size_t la, lb; + + a = luaL_tolstring(L, 1, &la); + b = luaL_tolstring(L, 2, &lb); + + if (a == NULL) { + a = ""; + la = 0; + } + + if (b == NULL) { + b = ""; + lb = 0; + } + + char *c = alloca(la + lb + 1); + memcpy(c, a, la); + memcpy(c + la, b, lb); + c[la + lb] = 0; + + lua_pushlstring(L, c, la + lb); + + return 1; +} + +static int luaB_ip4_tostring(lua_State *L) { + int n = lua_gettop(L); + if (n != 1) { + log(L_WARN "__tostring needs exactly 1 argument"); + return 0; + } + + lua_pushliteral(L, "addr"); + lua_gettable(L, 1); + lua_Integer a = lua_tointeger(L, -1); + char c[IP4_MAX_TEXT_LENGTH]; + bsnprintf(c, IP4_MAX_TEXT_LENGTH, "%I4", a); + + lua_pushstring(L, c); + return 1; +} + +static void lua_puship4(lua_State *L, ip4_addr a) { + lua_newtable(L); + lua_settableinteger(L, "addr", a); + + lua_newtable(L); + lua_settablecfunction(L, "__tostring", luaB_ip4_tostring); + lua_settablecfunction(L, "__concat", luaB_generic_concat); + lua_setmetatable(L, -2); +} + +void luaB_push_bird(lua_State *L) { lua_newtable(L); - lua_pushstring(L, "err"); - lua_pushcfunction(L, luaB_err); - lua_settable(L, -3); + lua_settablecfunction(L, "err", luaB_err); + lua_settablecfunction(L, "warn", luaB_warn); + lua_settablecfunction(L, "info", luaB_info); + lua_settablecfunction(L, "trace", luaB_trace); - lua_pushstring(L, "warn"); - lua_pushcfunction(L, luaB_warn); - lua_settable(L, -3); - - lua_pushstring(L, "info"); - lua_pushcfunction(L, luaB_info); - lua_settable(L, -3); - - lua_pushstring(L, "trace"); - lua_pushcfunction(L, luaB_trace); - lua_settable(L, -3); + lua_settableip4(L, "router_id", config->router_id); lua_setglobal(L, "bird"); } + +void luaB_push_route(lua_State *L, struct rte *e) { +} diff --git a/lua/filter.c b/lua/filter.c index 9dabb28f..aae549ab 100644 --- a/lua/filter.c +++ b/lua/filter.c @@ -9,7 +9,8 @@ int filter_lua_chunk(const char *chunk, struct rte **e, struct rta *a, struct ea_list **ea, struct linpool *lp) { lua_State *L = luaL_newstate(); luaL_openlibs(L); - luaB_push_bird_table(L); + luaB_push_bird(L); + luaB_push_route(L, *e); int le = luaL_dostring(L, chunk); int out; if (le) { diff --git a/lua/lua.h b/lua/lua.h index 7e6f31ce..d2c522b9 100644 --- a/lua/lua.h +++ b/lua/lua.h @@ -2,4 +2,5 @@ #include -void luaB_push_bird_table(lua_State *L); +void luaB_push_bird(lua_State *L); +void luaB_push_route(lua_State *L, rte *e);