summaryrefslogtreecommitdiff
path: root/lua/common.c
diff options
context:
space:
mode:
Diffstat (limited to 'lua/common.c')
-rw-r--r--lua/common.c47
1 files changed, 46 insertions, 1 deletions
diff --git a/lua/common.c b/lua/common.c
index d9467967..fad2f857 100644
--- a/lua/common.c
+++ b/lua/common.c
@@ -64,6 +64,12 @@ static int luaB_trace(lua_State *L) {
#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)
+#define lua_settablelightuserdata(L, idx, val) lua_sett(L, idx, val, lightuserdata)
+
+#define lua_setglobalcfunction(L, n, val) do { \
+ lua_pushcfunction(L, val); \
+ lua_setglobal(L, n); \
+} while (0)
static int luaB_generic_concat(lua_State *L) {
int n = lua_gettop(L);
@@ -125,7 +131,34 @@ static void lua_puship4(lua_State *L, ip4_addr a) {
lua_setmetatable(L, -2);
}
-void luaB_push_bird(lua_State *L) {
+static lua_bird_state *luaB_getinternalstate(lua_State *L) {
+ lua_getglobal(L, "bird");
+ lua_pushstring(L, "_internal_state");
+ lua_gettable(L, -2);
+ if (!lua_isuserdata(L, -1))
+ luaL_error(L, "fatal: bird internal state not found, type %d", lua_type(L, -1));
+
+ lua_bird_state *lbs = lua_touserdata(L, -1);
+ lua_pop(L, 2); /* Pop the user data and then the table. The string is consumed by gettable(). */
+ return lbs;
+}
+
+static int luaB_global_exception(lua_State *L, int value) {
+ int n = lua_gettop(L);
+ if (n > 1)
+ log(L_WARN "Called exception with too many arguments.");
+
+ lua_bird_state *lbs = luaB_getinternalstate(L);
+ lbs->exception = value;
+
+ lua_error(L);
+ return 0;
+}
+
+static inline int luaB_accept(lua_State *L) { return luaB_global_exception(L, F_ACCEPT); }
+static inline int luaB_reject(lua_State *L) { return luaB_global_exception(L, F_REJECT); }
+
+lua_bird_state *luaB_init(lua_State *L, struct linpool *lp) {
lua_newtable(L);
lua_settablecfunction(L, "err", luaB_err);
@@ -133,9 +166,21 @@ void luaB_push_bird(lua_State *L) {
lua_settablecfunction(L, "info", luaB_info);
lua_settablecfunction(L, "trace", luaB_trace);
+ lua_bird_state *lbs = lp_allocz(lp, sizeof(lua_bird_state));
+
+ lua_settablelightuserdata(L, "_internal_state", lbs);
+
lua_settableip4(L, "router_id", config->router_id);
lua_setglobal(L, "bird");
+
+ lua_pushcfunction(L, luaB_accept);
+ lua_setglobal(L, "accept");
+
+ lua_pushcfunction(L, luaB_reject);
+ lua_setglobal(L, "reject");
+
+ return lbs;
}
void luaB_push_route(lua_State *L, struct rte *e) {