-
Notifications
You must be signed in to change notification settings - Fork 2
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
add XDPLua #7
base: master-5.6
Are you sure you want to change the base?
add XDPLua #7
Conversation
struct lua_State *L; | ||
struct work_struct work; | ||
spinlock_t lock; | ||
bool init; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
s/init/inuse/
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I was about to add this comment ;-)
@@ -5849,6 +5855,278 @@ static const struct bpf_func_proto bpf_tcp_gen_syncookie_proto = { | |||
|
|||
#endif /* CONFIG_INET */ | |||
|
|||
#ifdef CONFIG_XDP_LUA | |||
|
|||
static inline void verify_and_lock(void) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Suggested change, by @lneto
static inline lua_State *xdplua_lock(void) {
struct xdplua_create_work *lw;
lw = this_cpu_ptr(&luaworks);
if (!lw->inuse) {
lw->inuse = true;
spin_lock(&lw->lock);
}
return lw->L;
}
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
please, take care about {
.. please review the whole patch..
} | ||
} | ||
|
||
BPF_CALL_2(bpf_lua_dataref, struct xdp_buff *, ctx, int, offset) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Suggested change, by @lneto
BPF_CALL_2(bpf_lua_dataref, struct xdp_buff *, ctx, int, offset) {
lua_State *L;
if (ctx->data_end <= offset + ctx->data)
return -1;
L = xdplua_lock();
return ldata_newref(L, ctx->data + offset,
ctx->data_end - ctx->data - offset);
}
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
btw, I got your concern about moving such declarations to another file.. but we can solve this using some macro sorcery.. however, we can leave it as a TODO.. let's merge this PR first..
bdd9779
to
2eebe24
Compare
@@ -63,13 +63,30 @@ struct xdp_rxq_info { | |||
struct xdp_mem_info mem; | |||
} ____cacheline_aligned; /* perf critical, avoid false-sharing */ | |||
|
|||
#ifdef CONFIG_XDP_LUA | |||
struct xdplua_create_work { | |||
char lua_script[8192]; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
s/8192/MAXSCRIPTLEN/
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
XDPLUA_MAX_SCRIPT_LEN
or XDPLUA_MAXSCRIPTLEN
? any variation looks good for me.. 👍
struct xdp_buff { | ||
void *data; | ||
void *data_end; | ||
void *data_meta; | ||
void *data_hard_start; | ||
unsigned long handle; | ||
struct xdp_rxq_info *rxq; | ||
#ifdef CONFIG_XDP_LUA |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
With the creation of struct xdplua_create_work
there probably is no reason to modify struct xdp_buff
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
agreed..
@@ -63,13 +63,30 @@ struct xdp_rxq_info { | |||
struct xdp_mem_info mem; | |||
} ____cacheline_aligned; /* perf critical, avoid false-sharing */ | |||
|
|||
#ifdef CONFIG_XDP_LUA | |||
struct xdplua_create_work { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe we should add a field of luadata's datarefs into this struct to automate the reference control of these objects
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@VictorNogueiraRio it makes sense to me.. also, we should rename this struct.. perhaps, xdplua_work
.. create_work
sounds like a function..
lw->L = luaL_newstate(); | ||
WARN_ON(!lw->L); | ||
|
||
if (!lw->L) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We need to improve this, @lneto any suggestions?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
IMHO, we should fail XDPLua initiation completely and destroy all states we have created so far.. and, of course, disable XDPLua execution in runtime putting a guard..
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
btw, another example of what I was arguing on slack is to move all this code to a xdplua_init()
function
|
||
for_each_possible_cpu(cpu) { | ||
lw = per_cpu_ptr(&luaworks, cpu); | ||
strcpy(lw->lua_script, lua_script); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
strncpy(lw->lua_script, lua_script, MAXSCRIPTLEN);
@@ -1876,6 +1876,9 @@ static const struct nla_policy ifla_xdp_policy[IFLA_XDP_MAX + 1] = { | |||
[IFLA_XDP_ATTACHED] = { .type = NLA_U8 }, | |||
[IFLA_XDP_FLAGS] = { .type = NLA_U32 }, | |||
[IFLA_XDP_PROG_ID] = { .type = NLA_U32 }, | |||
#ifdef CONFIG_XDP_LUA | |||
[IFLA_XDP_LUA_PROG] = { .type = NLA_STRING, .len = 8192 }, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
s/8192/MAXSCRIPTLEN
include/uapi/linux/bpf.h
Outdated
* 1 if the value at the given index of the Lua stack is a | ||
* string; otherwise it returns 0 | ||
* | ||
* void bpf_lua_type(void *ctx, int index) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
s/void/int/
tools/include/uapi/linux/bpf.h
Outdated
* 1 if the value at the given index of the Lua stack is a | ||
* string; otherwise it returns 0 | ||
* | ||
* void bpf_lua_type(void *ctx, int index) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
s/void/int/
int generic_xdp_lua_install_prog(char *lua_script) | ||
{ | ||
int cpu; | ||
struct xdplua_create_work *lw; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this variable can be moved to the for_each scope, right?
#ifdef CONFIG_XDP_LUA | ||
#include <lua.h> | ||
#include <luadata.h> | ||
#include <luaunpack.h> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
one example of what I was arguing on slack is to have one single header to xdplua, e.g., xdplua.h
if (lua_isstring(ctx->L, index)) { | ||
strncpy(str, lua_tostring(ctx->L, index), size); | ||
return 1; | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
let's handle the exception case first.. suggestion:
if (!lua_isstring(ctx->L, index))
return 0;
strncpy(str, lua_tostring(ctx->L, index), size);
return 1;
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@VictorNogueiraRio what's the use case, if we have none, I would simply remove this helper. At least, I would rename it to something like bpf_lua_copystring
. Also, I believe you should pop the string out of the stack, right?
@@ -5925,6 +6203,38 @@ bpf_base_func_proto(enum bpf_func_id func_id) | |||
return bpf_get_trace_printk_proto(); | |||
case BPF_FUNC_jiffies64: | |||
return &bpf_jiffies64_proto; | |||
#ifdef CONFIG_XDP_LUA | |||
case BPF_FUNC_lua_dataref: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
we could automate it using a macro.. e.g., XDP_LUA_BPF_FUNC(lua_dataref);
@@ -2806,6 +2809,21 @@ static int do_setlink(const struct sk_buff *skb, | |||
goto errout; | |||
status |= DO_SETLINK_NOTIFY; | |||
} | |||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
s/\n//
goto errout; | ||
} | ||
#endif /* CONFIG_XDP_LUA */ | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
s/\n//
|
||
function update(map) | ||
xdp.map_update(map, 1, 3) | ||
end |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
we should move this file out of this PR
return XDP_PASS; | ||
} | ||
|
||
char _license[] SEC("license") = "GPL"; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
we should move this file out of this PR
end | ||
|
||
return cookies[ip] == cookiepkt and true or false | ||
end |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
we should move this file out of this PR
return parse_tcp(ctx, data, ip_off, data_end, saddr); | ||
} | ||
|
||
char _license[] SEC("license") = "GPL"; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
we should move this file out of this PR
|
||
if (monitor) { | ||
rx_cnt_map_fd = bpf_object__find_map_fd_by_name(obj, "rx_cnt"); | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
s/\n//
} | ||
} | ||
|
||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
s/\n//
* | ||
* int bpf_lua_dataref(void *ctx, int offset) | ||
* Description | ||
* Create a new lua data buffer object pointing to the captured |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
* Create a new lua data buffer object pointing to the captured | |
* Creates a new lua data object pointing to the captured |
* packet at the specified offset. The function leaves the new | ||
* object on top of the Lua stack. | ||
* Return | ||
* Data object reference number on success, or -1 in case |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
* Data object reference number on success, or -1 in case | |
* Data object reference number on success, or LUA_NOREF in case |
.arg2_type = ARG_ANYTHING, | ||
}; | ||
|
||
BPF_CALL_4(bpf_lua_pcall, struct xdp_buff *, ctx, char *, funcname, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@VictorNogueiraRio I believed we have already discussed that we should just wrap lua_pcall
and allow the caller to handle the errors..
|
||
base += num_rets; | ||
|
||
clean_state: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
s/_state//
BPF_CALL_2(bpf_lua_pushmap, struct xdp_buff *, ctx, struct bpf_map *, map) { | ||
verify_and_lock(); | ||
lua_pushlightuserdata(ctx->L, map); | ||
return 0; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
do we always need to return int even if we want a void?
return 0; | ||
} | ||
|
||
static const struct bpf_func_proto bpf_lua_pushlstring_proto = { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I really believe we can have a macro to generate the wrapper.. including such struct..
P.S.: we can leave it as a TODO, of course..
}; | ||
|
||
BPF_CALL_2(bpf_lua_type, struct xdp_buff *, ctx, int, index) { | ||
return lua_type(ctx->L, index); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
are you sure we don't need to lock here?
* Converts the Lua value at the given index of the Lua | ||
* stack to a C string and copies size bytes of it to | ||
* value pointed by str | ||
* Return |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
you said it's void above..
* following constants defined in lua.h: LUA_TNIL (0), | ||
* LUA_TNUMBER, LUA_TBOOLEAN, LUA_TSTRING, LUA_TTABLE, | ||
* LUA_TFUNCTION, LUA_TUSERDATA, LUA_TTHREAD, and | ||
* LUA_TLIGHTUSERDATA. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
we don't need this long description.. you can just refer to the manual or lua.h itself as you're doing already..
* Pushes the zero-terminated string pointed to by s onto the stack. | ||
* Lua makes (or reuses) an internal copy of the given string, | ||
* so the memory at s can be freed or reused immediately after the | ||
* function returns. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
we don't need to replicate Lua's manual here.. just refer to it..
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this comment refers to all wrappers.. please, review all..
* | ||
* void bpf_lua_pushskb(void *ctx) | ||
* Description | ||
* Pushes an SKB structure onto the Lua stack |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
we are going to get rid of this, right?
|
||
#ifdef CONFIG_XDP_LUA | ||
if (xdp[IFLA_XDP_LUA_PROG]) { | ||
char *lua_prog = nla_data(xdp[IFLA_XDP_LUA_PROG]); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
script? I think we should uniformize it.. we are using both lua_prog
and lua_script
in the code.. I would rename them all to script
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think moving the code from dev.c, filter.c and rtnetlink.c to a xdplua.c would cleanup the patch considerably.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just adding a minor request. I still need to do a thorough review.
|
||
lua_prog = (char *) malloc(prog_size + 1); | ||
memset(lua_prog, 0, prog_size + 1); | ||
if (fread(lua_prog, 1, prog_size, f) < 0) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
From #3
if (fread(lua_prog, 1, prog_size, f) < 0) { | |
size_t read = fread(lua_prog, 1, prog_size, f); | |
if (read < 0) { |
No description provided.