Skip to content

Commit 99f9902

Browse files
torvalds#267 Load Lua scripts with luaL_loadbufferx
1 parent 3884fca commit 99f9902

File tree

6 files changed

+99
-49
lines changed

6 files changed

+99
-49
lines changed

include/net/xdplua.h

+3-1
Original file line numberDiff line numberDiff line change
@@ -22,19 +22,21 @@
2222

2323
struct xdp_lua_work {
2424
char script[XDP_LUA_MAX_SCRIPT_LEN];
25+
size_t script_len;
2526
struct lua_State *L;
2627
struct sk_buff *skb;
2728
struct work_struct work;
2829
};
2930

3031
DECLARE_PER_CPU(struct xdp_lua_work, luaworks);
3132

33+
3234
#define XDP_LUA_BPF_FUNC(name) BPF_FUNC_lua_##name
3335

3436
#define xdp_lua_get_skb() (this_cpu_ptr(&luaworks)->skb)
3537
#define xdp_lua_set_skb(skb) (this_cpu_ptr(&luaworks)->skb = skb)
3638

37-
void generic_xdp_lua_install_prog(const char *script);
39+
int generic_xdp_lua_install_prog(const char *script, size_t script_len);
3840
void xdp_lua_init(void);
3941

4042
#define __BPF_LUA_MAP_0(l, m, v, ...) l

net/core/rtnetlink.c

+5-5
Original file line numberDiff line numberDiff line change
@@ -2638,14 +2638,14 @@ static int do_setlink(const struct sk_buff *skb,
26382638
#ifdef CONFIG_XDP_LUA
26392639
if (xdp[IFLA_XDP_LUA_PROG]) {
26402640
const char *script;
2641+
int script_len;
26412642

26422643
script = nla_data(xdp[IFLA_XDP_LUA_PROG]);
2643-
if (!script) {
2644-
err = -EINVAL;
2645-
goto errout;
2646-
}
2644+
script_len = nla_len(xdp[IFLA_XDP_LUA_PROG]);
26472645

2648-
generic_xdp_lua_install_prog(script);
2646+
err = generic_xdp_lua_install_prog(script, script_len);
2647+
if (err)
2648+
goto errout;
26492649
}
26502650
#endif /* CONFIG_XDP_LUA */
26512651
}

net/core/xdplua.c

+20-4
Original file line numberDiff line numberDiff line change
@@ -25,23 +25,39 @@ static void per_cpu_xdp_lua_install(struct work_struct *w)
2525
lw = container_of(w, struct xdp_lua_work, work);
2626

2727
local_bh_disable();
28-
if (luaL_dostring(lw->L, lw->script)) {
29-
pr_err(KERN_INFO "error: %s\nOn cpu: %d\n",
28+
if (luaL_loadbufferx(lw->L, lw->script, lw->script_len, NULL, "t")) {
29+
pr_err("error loading Lua script: %s\non cpu: %d\n",
3030
lua_tostring(lw->L, -1), this_cpu);
3131
lua_pop(lw->L, 1);
32+
goto enable;
3233
}
34+
35+
if (lua_pcall(lw->L, 0, LUA_MULTRET, 0)) {
36+
pr_err("error running Lua script: %s\non cpu: %d\n",
37+
lua_tostring(lw->L, -1), this_cpu);
38+
lua_pop(lw->L, 1);
39+
}
40+
41+
enable:
3342
local_bh_enable();
3443
}
3544

36-
void generic_xdp_lua_install_prog(const char *script)
45+
int generic_xdp_lua_install_prog(const char *script, size_t script_len)
3746
{
3847
int i;
3948

49+
if (!script || script_len == 0)
50+
return -EINVAL;
51+
52+
if (script_len > XDP_LUA_MAX_SCRIPT_LEN)
53+
return -ENAMETOOLONG;
54+
4055
for_each_possible_cpu(i) {
4156
struct xdp_lua_work *lw;
4257

4358
lw = per_cpu_ptr(&luaworks, i);
44-
strncpy(lw->script, script, XDP_LUA_MAX_SCRIPT_LEN);
59+
memcpy(lw->script, script, script_len);
60+
lw->script_len = script_len;
4561
schedule_work_on(i, &lw->work);
4662
}
4763

samples/bpf/xdplua_user.c

+59-27
Original file line numberDiff line numberDiff line change
@@ -41,10 +41,22 @@ static void usage(const char *prog) {
4141
prog);
4242
}
4343

44-
static char *extract_script(const char *path)
44+
static int try_strncpy(char *dest, const char *src, size_t n, const char *fmt) {
45+
int srclen = strnlen(src, n);
46+
47+
if (srclen == n) {
48+
int err = ENAMETOOLONG;
49+
fprintf(stderr, fmt, strerror(err));
50+
return -err;
51+
}
52+
53+
strncpy(dest, src, n);
54+
return srclen;
55+
}
56+
57+
static char *extract_script(const char *path, size_t *script_len)
4558
{
4659
FILE *f;
47-
long script_len;
4860
size_t read;
4961
char *script = NULL;
5062

@@ -55,25 +67,33 @@ static char *extract_script(const char *path)
5567
}
5668

5769
if (fseek(f, 0 , SEEK_END) < 0) {
58-
perror("unable to reach end of script file");
70+
perror("unable to reach end of file");
5971
goto out;
6072
}
61-
script_len = ftell(f);
62-
if (script_len < 0) {
63-
perror("error while attempting to get script length");
73+
74+
*script_len = (size_t) ftell(f);
75+
if (*script_len < 0) {
76+
perror("error while attempting to get file length");
6477
goto out;
6578
}
66-
rewind(f);
6779

68-
script = (char *) malloc(script_len + 1);
80+
fseek(f, 0, *script_len);
81+
82+
if (*script_len > XDP_LUA_MAX_SCRIPT_LEN)
83+
fprintf(stderr, "lua file can't have more than %d bytes\n",
84+
XDP_LUA_MAX_SCRIPT_LEN);
85+
86+
script = (char *) malloc(sizeof(char) * (*script_len));
6987
if (!script) {
7088
perror("failed to alloc lua script");
7189
goto out;
7290
}
73-
memset(script, 0, script_len + 1);
74-
read = fread(script, 1, script_len, f);
75-
if (read != script_len) {
76-
perror("unable to read lua file");
91+
92+
rewind(f);
93+
94+
read = fread(script, sizeof(char), *script_len, f);
95+
if (read != *script_len) {
96+
fprintf(stderr, "unable to read file %s\n", path);
7797
free(script);
7898
script = NULL;
7999
goto out;
@@ -95,11 +115,11 @@ static int do_attach_ebpf(int idx, int fd, const char *name)
95115
return err;
96116
}
97117

98-
static int do_attach_lua(const char *script)
118+
static int do_attach_lua(const char *script, size_t script_len)
99119
{
100120
int err;
101121

102-
err = bpf_set_link_xdp_lua_script(script);
122+
err = bpf_set_link_xdp_lua_script(script, script_len);
103123
if (err < 0)
104124
fprintf(stderr, "ERROR: failed to attach lua script %d\n", err);
105125

@@ -138,19 +158,23 @@ static void poll(int map_fd, int interval, int duration) {
138158
}
139159
}
140160

161+
#define strncpy_err(fmt, err) fprintf(stderr, fmt, strerr(-err))
162+
141163
int main(int argc, char *argv[])
142164
{
143165
struct rlimit r = {RLIM_INFINITY, RLIM_INFINITY};
144166
char lua_filename[MAXFILENAMELEN];
145167
char filename[MAXFILENAMELEN];
146168
char script[XDP_LUA_MAX_SCRIPT_LEN];
169+
size_t script_len = 0;
147170
char ifname[IFNAMSIZ];
148171
struct bpf_object *obj;
149172
int opt, prog_fd;
150173
int rx_cnt_map_fd;
151174
int ifindex = 0;
152175
int detach = 0, attach_lua_file = 0, attach_ebpf = 0, monitor = 0,
153176
attach_lua_script = 0, interval = 1, duration = 1;
177+
int err = 0;
154178

155179
const char *optstr = "f:p:i:dms:I:D:";
156180
struct bpf_prog_load_attr prog_load_attr = {
@@ -163,28 +187,36 @@ int main(int argc, char *argv[])
163187
while ((opt = getopt(argc, argv, optstr)) != -1) {
164188
switch (opt) {
165189
case 'f':
166-
snprintf(lua_filename, sizeof(lua_filename), "%s", optarg);
190+
err = try_strncpy(lua_filename, optarg, MAXFILENAMELEN, "Invalid lua filename\nerr: %s\n");
191+
if (err < 0)
192+
return 1;
167193
attach_lua_file = 1;
168194
break;
169195
case 'p':
170-
snprintf(filename, sizeof(filename),
171-
"%s", optarg);
196+
err = try_strncpy(filename, optarg, MAXFILENAMELEN, "Invalid bpf prog filename\nerr: %s");
197+
if (err < 0)
198+
return 1;
172199
attach_ebpf = 1;
173200
break;
174201
case 'd':
175202
detach = 1;
176203
break;
177204
case 'i':
178-
snprintf(ifname, sizeof(ifname), "%s", optarg);
205+
script_len = try_strncpy(ifname, optarg, IFNAMSIZ, "Invalid interface name\nerr: %s");
206+
if (script_len < 0)
207+
return 1;
179208
ifindex = if_nametoindex(optarg);
180209
break;
181210
case 'm':
182211
monitor = 1;
183212
break;
184-
case 's':
185-
snprintf(script, sizeof(script), "%s", optarg);
213+
case 's': {
214+
err = try_strncpy(script, optarg, XDP_LUA_MAX_SCRIPT_LEN, "Invalid lua script\nerr: %s");
215+
if (err < 0)
216+
return 1;
186217
attach_lua_script = 1;
187218
break;
219+
}
188220
case 'I':
189221
interval = atoi(optarg);
190222
break;
@@ -197,7 +229,6 @@ int main(int argc, char *argv[])
197229
}
198230
}
199231

200-
201232
if (attach_ebpf || detach) {
202233
if (!ifindex) {
203234
printf("ERROR: invalid interface name");
@@ -234,20 +265,21 @@ int main(int argc, char *argv[])
234265
}
235266

236267
if (attach_lua_file) {
237-
char *extracted_script = extract_script(lua_filename);
268+
int ret = 0;
269+
size_t extracted_script_len;
270+
char *extracted_script = extract_script(lua_filename, &extracted_script_len);
238271
if (!extracted_script)
239272
return 1;
240273

241-
if (do_attach_lua(extracted_script) < 0) {
242-
free(extracted_script);
243-
return 1;
244-
}
274+
if (do_attach_lua(extracted_script, extracted_script_len) < 0)
275+
ret = 1;
245276

246277
free(extracted_script);
278+
return ret;
247279
}
248280

249281
if (attach_lua_script)
250-
if (do_attach_lua(script) < 0)
282+
if (do_attach_lua(script, script_len) < 0)
251283
return 1;
252284

253285
if (monitor) {

tools/lib/bpf/bpf.c

+11-11
Original file line numberDiff line numberDiff line change
@@ -621,16 +621,16 @@ int bpf_set_link_xdp_fd(int ifindex, int fd, __u32 flags)
621621
}
622622

623623
/* #ifdef CONFIG_XDPLUA */
624-
int bpf_set_link_xdp_lua_script(const char *script)
624+
int bpf_set_link_xdp_lua_script(const char *script, size_t script_len)
625625
{
626626
struct sockaddr_nl sa;
627627
int sock, seq = 0, len, ret = -1;
628628
char buf[4096];
629-
struct nlattr *nla, *nla_xdp;
629+
struct nlattr *nla, *nla_xdp_lua;
630630
struct {
631631
struct nlmsghdr nh;
632632
struct ifinfomsg ifinfo;
633-
char attrbuf[XDP_LUA_MAX_SCRIPT_LEN + 64];
633+
char attrbuf[XDP_LUA_MAX_SCRIPT_LEN];
634634
} req;
635635
struct nlmsghdr *nh;
636636
struct nlmsgerr *err;
@@ -681,24 +681,24 @@ int bpf_set_link_xdp_lua_script(const char *script)
681681
nla->nla_type = NLA_F_NESTED | IFLA_XDP;
682682
nla->nla_len = NLA_HDRLEN;
683683

684-
/* add XDP LUA PROG */
685-
nla_xdp = (struct nlattr *)((char *)nla + nla->nla_len);
686-
nla_xdp->nla_type = IFLA_XDP_LUA_PROG;
684+
/* add XDP LUA SCRIPT */
685+
nla_xdp_lua = (struct nlattr *)((char *)nla + nla->nla_len);
686+
nla_xdp_lua->nla_type = IFLA_XDP_LUA_PROG;
687687
if (script) {
688-
if (strlen(script) + 1 > XDP_LUA_MAX_SCRIPT_LEN) {
688+
if (script_len > XDP_LUA_MAX_SCRIPT_LEN) {
689689
fprintf(stderr, "script length cannot exceed %d bytes\n",
690690
XDP_LUA_MAX_SCRIPT_LEN);
691-
ret = -EINVAL;
691+
ret = -ENAMETOOLONG;
692692
goto cleanup;
693693
}
694694

695-
nla_xdp->nla_len = NLA_HDRLEN + strlen(script) + 1;
696-
memcpy((char *)nla_xdp + NLA_HDRLEN, script, strlen(script) + 1);
695+
nla_xdp_lua->nla_len = NLA_HDRLEN + script_len;
696+
memcpy((char *)nla_xdp_lua + NLA_HDRLEN, script, script_len);
697697
} else {
698698
ret = -EINVAL;
699699
goto cleanup;
700700
}
701-
nla->nla_len += nla_xdp->nla_len;
701+
nla->nla_len += nla_xdp_lua->nla_len;
702702

703703
req.nh.nlmsg_len += NLA_ALIGN(nla->nla_len);
704704

tools/lib/bpf/libbpf.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -285,7 +285,7 @@ int bpf_prog_load(const char *file, enum bpf_prog_type type,
285285

286286
int bpf_set_link_xdp_fd(int ifindex, int fd, __u32 flags);
287287
/* #ifdef CONFIG_XDP_LUA */
288-
int bpf_set_link_xdp_lua_script(const char *script);
288+
int bpf_set_link_xdp_lua_script(const char *script, size_t script_len);
289289
/* #endif CONFIG_XDP_LUA */
290290

291291
enum bpf_perf_event_ret {

0 commit comments

Comments
 (0)