Skip to content
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

Open
wants to merge 18 commits into
base: master-5.6
Choose a base branch
from
Open

add XDPLua #7

wants to merge 18 commits into from

Conversation

VictorNogueiraRio
Copy link
Member

No description provided.

struct lua_State *L;
struct work_struct work;
spinlock_t lock;
bool init;
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

s/init/inuse/

Copy link

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) {
Copy link
Member Author

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;
}

Copy link

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) {
Copy link
Member Author

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);
}

Copy link

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..

@@ -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];
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

s/8192/MAXSCRIPTLEN/

Copy link

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
Copy link
Member Author

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

Copy link

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 {
Copy link
Member Author

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

Copy link

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)
Copy link
Member Author

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?

Copy link

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..

Copy link

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);
Copy link
Member Author

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 },
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

s/8192/MAXSCRIPTLEN

* 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)
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

s/void/int/

* 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)
Copy link
Member Author

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;
Copy link

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>
Copy link

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;
}
Copy link

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;

Copy link

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:
Copy link

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;
}

Copy link

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 */

Copy link

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
Copy link

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";
Copy link

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
Copy link

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";
Copy link

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");

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

s/\n//

}
}


Copy link

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
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
* 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
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
* 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,
Copy link

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:
Copy link

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;
Copy link

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 = {
Copy link

@lneto lneto Sep 1, 2020

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);
Copy link

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
Copy link

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.
Copy link

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.
Copy link

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..

Copy link

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
Copy link

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]);
Copy link

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

Copy link

@lneto lneto left a 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.

Copy link

@marcelstanley marcelstanley left a 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) {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

From #3

Suggested change
if (fread(lua_prog, 1, prog_size, f) < 0) {
size_t read = fread(lua_prog, 1, prog_size, f);
if (read < 0) {

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Development

Successfully merging this pull request may close these issues.

3 participants