summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lua/common.c35
1 files changed, 35 insertions, 0 deletions
diff --git a/lua/common.c b/lua/common.c
index a9c60489..9bb52c59 100644
--- a/lua/common.c
+++ b/lua/common.c
@@ -61,6 +61,7 @@ static int luaB_trace(lua_State *L) {
lua_settable(L, -3); \
} while (0)
+#define lua_settableaddr(L, idx, val) lua_sett(L, idx, val, addr)
#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)
@@ -131,6 +132,37 @@ static void lua_puship4(lua_State *L, ip4_addr a) {
lua_setmetatable(L, -2);
}
+static int luaB_addr_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, "_internal");
+ lua_gettable(L, 1);
+ if (!lua_isuserdata(L, -1))
+ luaL_error(L, "fatal: bird internal state not found, type %d", lua_type(L, -1));
+
+ net_addr *addr = lua_touserdata(L, -1);
+ lua_pop(L, 1);
+
+ char c[NET_MAX_TEXT_LENGTH+1];
+ net_format(addr, c, sizeof(c));
+ lua_pushstring(L, c);
+ return 1;
+}
+
+static void lua_pushaddr(lua_State *L, net_addr *addr) {
+ lua_newtable(L);
+ lua_settablelightuserdata(L, "_internal", addr);
+
+ lua_newtable(L);
+ lua_settablecfunction(L, "__tostring", luaB_addr_tostring);
+ lua_settablecfunction(L, "__concat", luaB_generic_concat);
+ lua_setmetatable(L, -2);
+}
+
static lua_bird_state *luaB_getinternalstate(lua_State *L) {
lua_getglobal(L, "bird");
lua_pushstring(L, "_internal_state");
@@ -184,4 +216,7 @@ lua_bird_state *luaB_init(lua_State *L, struct linpool *lp) {
}
void luaB_push_route(lua_State *L, struct rte *e) {
+ lua_newtable(L);
+ lua_settableaddr(L, "prefix", e->net->n.addr);
+ lua_setglobal(L, "route");
}