/*---------------------------------------------------------------------*/ static int linker_output(lua_State *L) { TRACE_LUA_FUNC_START(); Linker_Intf *linker; int nargs = lua_gettop(L); int i; linker = check_linker(L, 1); if (linker->type == LINKER_MERGE) { linker->output_link[0] = luaL_optstring(L, 2, 0); linker->output_count = 1; } else { /* for LINKER_LB or LINKER_DUP, etc. */ for (i = 2; i <= nargs; i++) { linker->output_link[linker->output_count] = luaL_optstring(L, i, 0); linker->output_count++; } } lua_settop(L, 1); TRACE_LUA_FUNC_END(); return 1; }
/** * XXX - This function needs to be improved... */ static int linker_new(lua_State *L) { TRACE_LUA_FUNC_START(); int arg = -1; int nargs = lua_gettop(L); const char *brick_name = luaL_optstring(L, 1, 0); int i; if (nargs == 2) { arg = luaL_optint(L, 2, 0); } Linker_Intf *linker = push_linker(L); for (i = 3; elibs[i].init != NULL; i++) { if (!strcmp(elibs[i].getId(), brick_name)) linker->type = i; } linker->hash_split = arg; TRACE_DEBUG_LOG("Hash splitting logic: %d\n", linker->hash_split); linker->output_count = 0; linker->input_count = 0; linker->next_linker = NULL; TRACE_LUA_FUNC_END(); return 1; }
/*---------------------------------------------------------------------*/ static int pushline(lua_State *L, int firstline) { TRACE_LUA_FUNC_START(); char buffer[LUA_MAXINPUT]; char *b = buffer; size_t l; const char *prmt = get_prompt(L, firstline); if (lua_readline(L, b, prmt) == 0) { TRACE_LUA_FUNC_END(); return 0; /* no input */ } l = strlen(b); /* line ends with newline? */ if (l > 0 && b[l-1] == '\n') b[l-1] = '\0'; /* remove it */ /* first line starts with `=' ? */ if (firstline && b[0] == '=') lua_pushfstring(L, "return %s", b+1); /* change it to `return' */ else lua_pushstring(L, b); lua_freeline(L, b); TRACE_LUA_FUNC_END(); return 1; }
/*---------------------------------------------------------------------*/ int linker_register(lua_State *L) { TRACE_LUA_FUNC_START(); /* create methods table, add it to the globals */ luaL_openlib(L, "Brick", linker_methods, 0); /* create metatable for Linker, & add it to the Lua registry */ luaL_newmetatable(L, "Brick"); /* fill metatable */ luaL_openlib(L, 0, linker_meta, 0); lua_pushliteral(L, "__index"); /* dup methods table*/ lua_pushvalue(L, -3); /* metatable.__index = methods */ lua_rawset(L, -3); lua_pushliteral(L, "__metatable"); /* dup methods table*/ lua_pushvalue(L, -3); /* hide metatable: metatable.__metatable = methods */ lua_rawset(L, -3); /* drop metatable */ lua_pop(L, 1); TRACE_LUA_FUNC_END(); return 1; /* return methods on the stack */ }
/*---------------------------------------------------------------------*/ static int loadline(lua_State *L) { TRACE_LUA_FUNC_START(); int status; lua_settop(L, 0); if (!pushline(L, 1)) { TRACE_LUA_FUNC_END(); return -1; /* no input */ } for (;;) { /* repeat until gets a complete line */ status = luaL_loadbuffer(L, lua_tostring(L, 1), lua_strlen(L, 1), "=stdin"); if (!incomplete(L, status)) break; /* cannot try to add lines? */ if (!pushline(L, 0)) {/* no more input? */ TRACE_LUA_FUNC_END(); return -1; } lua_pushliteral(L, "\n"); /* add a new line... */ lua_insert(L, -2); /* ...between the two lines */ lua_concat(L, 3); /* join them */ } TRACE_DEBUG_LOG("%s\n", lua_tostring(L, 1)); TRACE_LUA_FUNC_END(); return status; }
/*---------------------------------------------------------------------*/ static int pkteng_new(lua_State *L) { TRACE_LUA_FUNC_START(); int nargs = lua_gettop(L); const char *ename = luaL_optstring(L, 1, 0); int cpu = -1; int buffer_sz = 512; /* only grab cpu metric if it is mentioned */ if (nargs >= 2) buffer_sz = luaL_optint(L, 2, 0); if (nargs == 3) cpu = luaL_optint(L, 3, 0); /* parse and populate the remaining fields */ PktEngine_Intf *pe = push_pkteng(L); pe->eng_name = ename; pe->cpu = cpu; pe->buffer_sz = buffer_sz; pktengine_new((uint8_t *)pe->eng_name, pe->buffer_sz, pe->cpu); TRACE_LUA_FUNC_END(); return 1; }
/*---------------------------------------------------------------------*/ static int docall(lua_State *L, int narg, int clear) { TRACE_LUA_FUNC_START(); int status; int base; /* function index */ base = lua_gettop(L) - narg; /* push traceback function */ lua_pushcfunction(L, traceback); /* put it under chunk & args */ lua_insert(L, base); status = lua_pcall(L, narg, (clear ? 0 : LUA_MULTRET), base); /* remove traceback function */ lua_remove(L, base); /* force a complete garbage collection in case of errors */ if (status != 0) lua_gc(L, LUA_GCCOLLECT, 0); TRACE_LUA_FUNC_END(); return status; }
/*---------------------------------------------------------------------*/ static void dotty(lua_State *L) { TRACE_LUA_FUNC_START(); int status; while (!stop_processing && (status = loadline(L)) != -1) { lua_saveline(L, 1); lua_remove(L, 1); /* remove line */ if (status == 0) status = docall(L, 0, 0); report(L, status); if (status == 0 && lua_gettop(L) > 0) { /* any result to print? */ lua_getglobal(L, "print"); lua_insert(L, 1); if (lua_pcall(L, lua_gettop(L)-1, 0, 0) != 0) TRACE_LOG("%s", lua_pushfstring (L, "error calling " LUA_QL("print") " (%s)", lua_tostring(L, -1))); } } lua_settop(L, 0); /* clear stack */ TRACE_FLUSH(); TRACE_LUA_FUNC_END(); }
/*---------------------------------------------------------------------*/ static int linker_input(lua_State *L) { TRACE_LUA_FUNC_START(); Linker_Intf *linker; int i; int nargs = lua_gettop(L); linker = check_linker(L, 1); /* pick as many input sources as possible */ if (linker->type == LINKER_MERGE) { for (i = 2; i <= nargs; i++) { linker->input_link[linker->input_count] = luaL_optstring(L, i, 0); linker->input_count++; } } else { /* for LINKER_LB or LINKER_DUP, etc. */ linker->input_link[0] = luaL_optstring(L, 2, 0); linker->input_count = 1; } lua_settop(L, 1); TRACE_LUA_FUNC_END(); return 1; }
/*---------------------------------------------------------------------*/ static int traceback(lua_State *L) { TRACE_LUA_FUNC_START(); lua_getfield(L, LUA_GLOBALSINDEX, "debug"); if (!lua_istable(L, -1)) { lua_pop(L, 1); TRACE_LUA_FUNC_END(); return 1; } lua_getfield(L, -1, "traceback"); if (!lua_isfunction(L, -1)) { lua_pop(L, 2); TRACE_LUA_FUNC_END(); return 1; } /* pass error message */ lua_pushvalue(L, 1); /* skip this function & traceback */ lua_pushinteger(L, 2); /* call debug.traceback */ lua_call(L, 2, 1); TRACE_LUA_FUNC_END(); return 1; }
/** * Overloaded garbage collector */ static int linker_gc(lua_State *L) { TRACE_LUA_FUNC_START(); TRACE_DEBUG_LOG("Wiping off Linker: %p\n", to_linker(L, 1)); TRACE_LUA_FUNC_END(); UNUSED(L); return 0; }
/*---------------------------------------------------------------------*/ static Linker_Intf * to_linker(lua_State *L, int index) { TRACE_LUA_FUNC_START(); Linker_Intf *linker = (Linker_Intf *)lua_touserdata(L, index); if (linker == NULL) luaL_typerror(L, index, "Brick"); TRACE_LUA_FUNC_END(); return linker; }
/** * Overloaded garbage collector */ static int pkteng_gc(lua_State *L) { TRACE_LUA_FUNC_START(); TRACE_DEBUG_LOG("Wiping off PktEngine: %p\n", to_pkteng(L, 1)); TRACE_LUA_FUNC_END(); UNUSED(L); return 0; }
/*---------------------------------------------------------------------*/ static int platform_show_stats(lua_State *L) { /* this prints the system-wide statitics */ TRACE_LUA_FUNC_START(); pktengines_list_stats(stdout); TRACE_LUA_FUNC_END(); UNUSED(L); return 0; }
/*---------------------------------------------------------------------*/ static PktEngine_Intf * to_pkteng(lua_State *L, int index) { TRACE_LUA_FUNC_START(); /* fetches pktengine object param from lua stack */ PktEngine_Intf *pe = (PktEngine_Intf *)lua_touserdata(L, index); if (pe == NULL) luaL_typerror(L, index, "PktEngine"); TRACE_LUA_FUNC_END(); return pe; }
/*---------------------------------------------------------------------*/ static PktEngine_Intf * push_pkteng(lua_State *L) { TRACE_LUA_FUNC_START(); /* pushes pktengine object to the lua stack */ PktEngine_Intf *pe = (PktEngine_Intf *)lua_newuserdata(L, sizeof(PktEngine_Intf)); luaL_getmetatable(L, "PktEngine"); lua_setmetatable(L, -2); TRACE_LUA_FUNC_END(); return pe; }
/*---------------------------------------------------------------------*/ static int luaopen_linker(lua_State *L) { /* this loads the pkteng lua interface */ TRACE_LUA_FUNC_START(); linker_register(L); TRACE_LUA_FUNC_END(); return 1; }
/*---------------------------------------------------------------------*/ static Linker_Intf * push_linker(lua_State *L) { TRACE_LUA_FUNC_START(); Linker_Intf *linker = (Linker_Intf *)lua_newuserdata(L, sizeof(Linker_Intf)); luaL_getmetatable(L, "Brick"); lua_setmetatable(L, -2); TRACE_LUA_FUNC_END(); return linker; }
/*---------------------------------------------------------------------*/ static int dostring(lua_State *L, const char *s, const char *name) { TRACE_LUA_FUNC_START(); int status; status = luaL_loadbuffer(L, s, strlen(s), name) || docall(L, 0, 1); TRACE_LUA_FUNC_END(); return report(L, status); }
/*---------------------------------------------------------------------*/ static int dofile(lua_State *L, const char *name) { TRACE_LUA_FUNC_START(); int status; status = luaL_loadfile(L, name) || docall(L, 0, 1); TRACE_LUA_FUNC_END(); return report(L, status); }
/*---------------------------------------------------------------------*/ static PktEngine_Intf * check_pkteng(lua_State *L, int index) { TRACE_LUA_FUNC_START(); PktEngine_Intf *pe; /* see if the param data type is actually PktEngine */ luaL_checktype(L, index, LUA_TUSERDATA); pe = (PktEngine_Intf *)luaL_checkudata(L, index, "PktEngine"); if (pe == NULL) luaL_typerror(L, index, "PktEngine"); TRACE_LUA_FUNC_END(); return pe; }
/*---------------------------------------------------------------------*/ static int pkteng_stop(lua_State *L) { TRACE_LUA_FUNC_START(); PktEngine_Intf *pe = check_pkteng(L, 1); lua_settop(L, 1); pktengine_stop((uint8_t *)pe->eng_name); TRACE_LUA_FUNC_END(); return 1; }
/*---------------------------------------------------------------------*/ static int shutdown_wrap(lua_State *L) { /* this shut downs the system */ TRACE_LUA_FUNC_START(); UNUSED(L); /* assigning this to 1 shuts down the lua shell */ stop_processing = 1; clean_exit(EXIT_SUCCESS); TRACE_LUA_FUNC_END(); return 0; }
/*---------------------------------------------------------------------*/ static int platform_dir_create_meta(lua_State *L) { TRACE_LUA_FUNC_START(); luaL_newmetatable(L, METATABLE); /* set its __gc field */ lua_pushstring(L, "__gc"); lua_settable(L, -2); TRACE_LUA_FUNC_END(); return 1; }
/*---------------------------------------------------------------------*/ int register_lua_procs(lua_State *L) { TRACE_LUA_FUNC_START(); /* loads all lua interfaces */ luaopen_platform(L); luaopen_pkteng(L); luaopen_linker(L); TRACE_LUA_FUNC_END(); return 0; }
/*---------------------------------------------------------------------*/ static int luaopen_platform(lua_State *L) { /* load systems' lua interface */ TRACE_LUA_FUNC_START(); platform_dir_create_meta(L); TRACE_DEBUG_LOG("%s", "Loading "PLATFORM_NAME" command metatable\n"); luaL_openlib(L, PLATFORM_NAME, platformlib, 0); platform_set_info(L); TRACE_LUA_FUNC_END(); return 1; }
/*---------------------------------------------------------------------*/ static void init_lua(lua_State *L, struct Smain *s) { TRACE_LUA_FUNC_START(); /* stop collector during initialization */ lua_gc(L, LUA_GCSTOP, 0); /* open libraries */ luaL_openlibs(L); lua_gc(L, LUA_GCRESTART, 0); s->status = handle_luainit(L); TRACE_LUA_FUNC_END(); }
/*---------------------------------------------------------------------*/ static int linker_help(lua_State *L) { TRACE_LUA_FUNC_START(); fprintf(stdout, "LoadBalance/Duplicator/Merge/Filter/? Commands:\n" " help()\n" " new([<split-mode>])\n" " connect_input(<interfaces>)\n" " connect_output(<interfaces>)\n" ); UNUSED(L); TRACE_LUA_FUNC_END(); return 0; }
/** * Will only work for Lua-5.2 */ static int pkteng_tostring(lua_State *L) { TRACE_LUA_FUNC_START(); char buff[LUA_MAXINPUT]; PktEngine_Intf *pe; fprintf(stderr, "Calling %s\n", __FUNCTION__); pe = to_pkteng(L, 1); sprintf(buff, "PktEngine:\n\tName: %s\n\tType: netmap\n\tBatch: %d\n", pe->eng_name, pe->batch); lua_pushfstring(L, "%s", buff); TRACE_LUA_FUNC_END(); return 1; }
/*---------------------------------------------------------------------*/ static Linker_Intf * check_linker(lua_State *L, int index) { TRACE_LUA_FUNC_START(); Linker_Intf *linker; /* Retrieve linker */ luaL_checktype(L, index, LUA_TUSERDATA); linker = (Linker_Intf *)luaL_optudata(L, index); if (linker == NULL) luaL_typerror(L, index, "Brick"); TRACE_LUA_FUNC_END(); return linker; }