From 4d82fa25659e7bf03e1a4938297853ff5d28c99f Mon Sep 17 00:00:00 2001 From: Victor Nogueira Date: Thu, 30 Jan 2020 21:42:16 +0000 Subject: [PATCH 01/18] add Lunatik submodule --- .gitmodules | 3 +++ init/Kconfig | 6 ++++++ lib/Makefile | 3 +++ lib/lunatik | 1 + net/core/Makefile | 2 ++ 5 files changed, 15 insertions(+) create mode 100644 .gitmodules create mode 160000 lib/lunatik diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 00000000000000..f1d9bd02ab7ca8 --- /dev/null +++ b/.gitmodules @@ -0,0 +1,3 @@ +[submodule "lib/lunatik"] + path = lib/lunatik + url = https://github.com/luainkernel/lunatik.git diff --git a/init/Kconfig b/init/Kconfig index ef59c5c36cdb51..bd5a871e36b222 100644 --- a/init/Kconfig +++ b/init/Kconfig @@ -1307,6 +1307,12 @@ config HAVE_PCSPKR_PLATFORM config BPF bool +config LUNATIK + bool "Lunatik" + default n + help + Support for the Lua interpreter + menuconfig EXPERT bool "Configure standard kernel features (expert users)" # Unhide debug options, to make the on-by-default options visible diff --git a/lib/Makefile b/lib/Makefile index 611872c0692693..3813aeef91a2d3 100644 --- a/lib/Makefile +++ b/lib/Makefile @@ -300,3 +300,6 @@ obj-$(CONFIG_OBJAGG) += objagg.o # KUnit tests obj-$(CONFIG_LIST_KUNIT_TEST) += list-test.o +subdir-ccflags-y += -I$(srctree)/lib/lunatik/lua \ + -D_KERNEL +obj-$(CONFIG_LUNATIK) += lunatik/ diff --git a/lib/lunatik b/lib/lunatik new file mode 160000 index 00000000000000..fb7ef47c930b54 --- /dev/null +++ b/lib/lunatik @@ -0,0 +1 @@ +Subproject commit fb7ef47c930b544804f544654302dac673a6ca48 diff --git a/net/core/Makefile b/net/core/Makefile index 3e2c378e5f3177..3fcf663db99837 100644 --- a/net/core/Makefile +++ b/net/core/Makefile @@ -8,6 +8,8 @@ obj-y := sock.o request_sock.o skbuff.o datagram.o stream.o scm.o \ obj-$(CONFIG_SYSCTL) += sysctl_net_core.o +CFLAGS_dev.o = -Ilib/lunatik/lua/ -D_KERNEL +CFLAGS_filter.o = -Ilib/lunatik/lua/ -D_KERNEL obj-y += dev.o dev_addr_lists.o dst.o netevent.o \ neighbour.o rtnetlink.o utils.o link_watch.o filter.o \ sock_diag.o dev_ioctl.o tso.o sock_reuseport.o \ From ff7c9b9917507e83583bdc24b4850189988831f2 Mon Sep 17 00:00:00 2001 From: Victor Nogueira Date: Fri, 19 Jul 2019 08:04:56 -0300 Subject: [PATCH 02/18] add XDPLua --- include/linux/filter.h | 10 ++ include/linux/netdevice.h | 4 + include/net/xdp.h | 4 + include/uapi/linux/bpf.h | 82 ++++++++++- include/uapi/linux/if_link.h | 3 + net/core/dev.c | 54 +++++++ net/core/filter.c | 203 ++++++++++++++++++++++++++ net/core/rtnetlink.c | 18 +++ net/xdp/Kconfig | 7 + samples/bpf/Makefile | 4 + samples/bpf/xdplua_user.c | 225 +++++++++++++++++++++++++++++ tools/include/uapi/linux/bpf.h | 82 ++++++++++- tools/include/uapi/linux/if_link.h | 3 + tools/lib/bpf/libbpf.h | 3 + tools/lib/bpf/libbpf.map | 1 + tools/lib/bpf/netlink.c | 56 +++++++ 16 files changed, 757 insertions(+), 2 deletions(-) create mode 100644 samples/bpf/xdplua_user.c diff --git a/include/linux/filter.h b/include/linux/filter.h index f349e2c0884c4c..1a01a2e37b9f67 100644 --- a/include/linux/filter.h +++ b/include/linux/filter.h @@ -1268,4 +1268,14 @@ struct bpf_sockopt_kern { s32 retval; }; +#ifdef CONFIG_XDP_LUA +extern struct list_head lua_state_cpu_list; + +struct lua_state_cpu { + struct lua_State *L; + int cpu; + struct list_head list; +}; +#endif /* CONFIG_XDP_LUA */ + #endif /* __LINUX_FILTER_H__ */ diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h index 6c3f7032e8d9d7..b45e5a0e83e824 100644 --- a/include/linux/netdevice.h +++ b/include/linux/netdevice.h @@ -3772,6 +3772,10 @@ u32 __dev_xdp_query(struct net_device *dev, bpf_op_t xdp_op, enum bpf_netdev_command cmd); int xdp_umem_query(struct net_device *dev, u16 queue_id); +#ifdef CONFIG_XDP_LUA +int generic_xdp_lua_install_prog(char *lua_prog); +#endif /* CONFIG_XDP_LUA */ + int __dev_forward_skb(struct net_device *dev, struct sk_buff *skb); int dev_forward_skb(struct net_device *dev, struct sk_buff *skb); bool is_skb_forwardable(const struct net_device *dev, diff --git a/include/net/xdp.h b/include/net/xdp.h index 40c6d3398458f6..de64fe2f1fc0b5 100644 --- a/include/net/xdp.h +++ b/include/net/xdp.h @@ -70,6 +70,10 @@ struct xdp_buff { void *data_hard_start; unsigned long handle; struct xdp_rxq_info *rxq; +#ifdef CONFIG_XDP_LUA + struct sk_buff *skb; + struct lua_State *L; +#endif /* CONFIG_XDP_LUA */ }; struct xdp_frame { diff --git a/include/uapi/linux/bpf.h b/include/uapi/linux/bpf.h index 22f235260a3a35..8c59576a29dbe6 100644 --- a/include/uapi/linux/bpf.h +++ b/include/uapi/linux/bpf.h @@ -2890,6 +2890,73 @@ union bpf_attr { * Obtain the 64bit jiffies * Return * The 64 bit jiffies + * + * void bpf_lua_pcall(void *ctx, char *funcname, int num_args, int num_rets) + * Description + * Calls Lua function funcname with the given nargs arguments in protected mode + * + * void bpf_lua_pop(void *ctx, int n) + * Description + * Pops n elements from the Lua stack + * + * void bpf_lua_pushinteger(void *ctx, int num) + * Description + * Pushes an integer with value n onto the Lua stack. + * + * void bpf_lua_pushlightuserdata(void *ctx, void *ptr) + * Description + * Pushes a light userdata onto the Lua stack. + * Userdata represent C values in Lua. + * A light userdata represents a pointer, a void*. + * It is a value (like a number): you do not create it, + * it has no individual metatable, and it is not collected + * (as it was never created). + * A light userdata is equal to "any" light userdata with + * the same C address. + * + * void bpf_lua_pushlstring(void *ctx, const char *s, size_t len) + * Description + * Pushes the string pointed to by s with size len 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. + * The string can contain any binary data, including embedded zeros. + * + * void bpf_lua_pushmap(void *ctx, void *map) + * Description + * Pushes a BPF map onto the Lua stack + * + * void bpf_lua_pushskb(void *ctx) + * Description + * Pushes an SKB structure onto the Lua stack + * + * void bpf_lua_pushstring(void *ctx, const char *s) + * Description + * 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. + * + * void bpf_lua_setstate(void *ctx) + * Description + * Sets the Lua state pointer in the context struct + * + * int bpf_lua_toboolean(void *ctx, int index) + * Description + * Converts the Lua value at the given index to a C + * boolean value (0 or 1) + * Return + * 1 if the value in the given index of the Lua stack is + * different from from false or null, otherwise returns 0 + * + * int bpf_lua_tointeger(void *ctx, int index) + * Description + * Converts the Lua value at the given index of the Lua stack + * to the signed integral type lua_Integer. + * Return + * The converted Lua value at the given index, if the value is + * convertible to an integer(see the Lua manual for more details + * on type conversion); otherwise returns 0 */ #define __BPF_FUNC_MAPPER(FN) \ FN(unspec), \ @@ -3010,7 +3077,20 @@ union bpf_attr { FN(probe_read_kernel_str), \ FN(tcp_send_ack), \ FN(send_signal_thread), \ - FN(jiffies64), + FN(jiffies64), \ + /* #ifdef CONFIG_XDP_LUA */ \ + FN(lua_pcall), \ + FN(lua_pop), \ + FN(lua_pushinteger), \ + FN(lua_pushlightuserdata), \ + FN(lua_pushlstring), \ + FN(lua_pushmap), \ + FN(lua_pushskb), \ + FN(lua_pushstring), \ + FN(lua_setstate), \ + FN(lua_toboolean), \ + FN(lua_tointeger), + /* #endif CONFIG_XDP_LUA */ /* integer value in 'imm' field of BPF_CALL instruction selects which helper * function eBPF program intends to call diff --git a/include/uapi/linux/if_link.h b/include/uapi/linux/if_link.h index 024af2d1d0af40..dfb1208e6942cd 100644 --- a/include/uapi/linux/if_link.h +++ b/include/uapi/linux/if_link.h @@ -984,6 +984,9 @@ enum { IFLA_XDP_DRV_PROG_ID, IFLA_XDP_SKB_PROG_ID, IFLA_XDP_HW_PROG_ID, +#ifdef CONFIG_XDP_LUA + IFLA_XDP_LUA_PROG, +#endif /* CONFIG_XDP_LUA */ __IFLA_XDP_MAX, }; diff --git a/net/core/dev.c b/net/core/dev.c index 500bba8874b007..6abe540fcd7e83 100644 --- a/net/core/dev.c +++ b/net/core/dev.c @@ -68,6 +68,12 @@ * - netif_rx() feedback */ +#ifdef CONFIG_XDP_LUA +#include +#include +#include +#endif /* CONFIG_XDP_LUA */ + #include #include #include @@ -164,6 +170,10 @@ static int call_netdevice_notifiers_extack(unsigned long val, struct netlink_ext_ack *extack); static struct napi_struct *napi_by_id(unsigned int napi_id); +#ifdef CONFIG_XDP_LUA +struct list_head lua_state_cpu_list; +#endif /* CONFIG_XDP_LUA */ + /* * The @dev_base_head list is protected by @dev_base_lock and the rtnl * semaphore. @@ -4556,6 +4566,9 @@ static u32 netif_receive_generic_xdp(struct sk_buff *skb, rxqueue = netif_get_rxqueue(skb); xdp->rxq = &rxqueue->xdp_rxq; +#ifdef CONFIG_XDP_LUA + xdp->skb = skb; +#endif /* CONFIG_XDP_LUA */ act = bpf_prog_run_xdp(xdp_prog, xdp); @@ -5366,6 +5379,22 @@ static int generic_xdp_install(struct net_device *dev, struct netdev_bpf *xdp) return ret; } +#ifdef CONFIG_XDP_LUA +int generic_xdp_lua_install_prog(char *lua_prog) +{ + struct lua_state_cpu *sc; + + list_for_each_entry(sc, &lua_state_cpu_list, list) { + if (luaL_dostring(sc->L, lua_prog)) { + pr_err(KERN_INFO "error: %s\nOn cpu: %d\n", + lua_tostring(sc->L, -1), sc->cpu); + return -EINVAL; + } + } + return 0; +} +#endif /* CONFIG_XDP_LUA */ + static int netif_receive_skb_internal(struct sk_buff *skb) { int ret; @@ -10462,6 +10491,9 @@ static struct pernet_operations __net_initdata default_device_ops = { static int __init net_dev_init(void) { int i, rc = -ENOMEM; +#ifdef CONFIG_XDP_LUA + struct lua_state_cpu *new_state_cpu; +#endif /* CONFIG_XDP_LUA */ BUG_ON(!dev_boot_phase); @@ -10476,6 +10508,9 @@ static int __init net_dev_init(void) INIT_LIST_HEAD(&ptype_base[i]); INIT_LIST_HEAD(&offload_base); +#ifdef CONFIG_XDP_LUA + INIT_LIST_HEAD(&lua_state_cpu_list); +#endif /* CONFIG_XDP_LUA */ if (register_pernet_subsys(&netdev_net_ops)) goto out; @@ -10506,6 +10541,25 @@ static int __init net_dev_init(void) init_gro_hash(&sd->backlog); sd->backlog.poll = process_backlog; sd->backlog.weight = weight_p; + +#ifdef CONFIG_XDP_LUA + new_state_cpu = (struct lua_state_cpu *) + kmalloc(sizeof(struct lua_state_cpu), GFP_ATOMIC); + if (!new_state_cpu) + continue; + + new_state_cpu->L = luaL_newstate(); + if (!new_state_cpu->L) { + kfree(new_state_cpu); + continue; + } + + luaL_openlibs(new_state_cpu->L); + lua_pop(new_state_cpu->L, 1); + new_state_cpu->cpu = i; + + list_add(&new_state_cpu->list, &lua_state_cpu_list); +#endif /* CONFIG_XDP_LUA */ } dev_boot_phase = 0; diff --git a/net/core/filter.c b/net/core/filter.c index c180871e606d85..7ebcea60e44270 100644 --- a/net/core/filter.c +++ b/net/core/filter.c @@ -74,6 +74,10 @@ #include #include +#ifdef CONFIG_XDP_LUA +#include +#endif /* CONFIG_XDP_LUA */ + /** * sk_filter_trim_cap - run a packet through a socket filter * @sk: sock associated with &sk_buff @@ -5849,6 +5853,181 @@ static const struct bpf_func_proto bpf_tcp_gen_syncookie_proto = { #endif /* CONFIG_INET */ +#ifdef CONFIG_XDP_LUA +BPF_CALL_4(bpf_lua_pcall, struct xdp_buff *, ctx, char *, funcname, + int, num_args, int, num_rets) { + if (lua_getglobal(ctx->L, funcname) != LUA_TFUNCTION) { + pr_err("function %s not found\n", funcname); + lua_pop(ctx->L, num_args); + return 0; + } + + lua_insert(ctx->L, 1); + if (lua_pcall(ctx->L, num_args, num_rets, 0)) { + pr_err("%s\n", lua_tostring(ctx->L, -1)); + lua_pop(ctx->L, 1); + return 0; + } + return num_rets; +} + +static const struct bpf_func_proto bpf_lua_pcall_proto = { + .func = bpf_lua_pcall, + .gpl_only = false, + .pkt_access = false, + .ret_type = RET_INTEGER, + .arg1_type = ARG_PTR_TO_CTX, + .arg2_type = ARG_ANYTHING, + .arg3_type = RET_INTEGER, + .arg4_type = RET_INTEGER, +}; + +BPF_CALL_2(bpf_lua_pop, struct xdp_buff *, ctx, int, index) { + lua_pop(ctx->L, index); + return 0; +} + +static const struct bpf_func_proto bpf_lua_pop_proto = { + .func = bpf_lua_pop, + .gpl_only = false, + .pkt_access = false, + .ret_type = RET_VOID, + .arg1_type = ARG_PTR_TO_CTX, + .arg2_type = ARG_ANYTHING, +}; + +BPF_CALL_2(bpf_lua_pushinteger, struct xdp_buff *, ctx, int, num) { + lua_pushinteger(ctx->L, num); + return 0; +} + +static const struct bpf_func_proto bpf_lua_pushinteger_proto = { + .func = bpf_lua_pushinteger, + .gpl_only = false, + .pkt_access = false, + .ret_type = RET_VOID, + .arg1_type = ARG_PTR_TO_CTX, + .arg2_type = ARG_ANYTHING, +}; + +BPF_CALL_2(bpf_lua_pushlightuserdata, struct xdp_buff *, ctx, void *, ptr) { + lua_pushlightuserdata(ctx->L, ptr); + return 0; +} + +static const struct bpf_func_proto bpf_lua_pushlightuserdata_proto = { + .func = bpf_lua_pushlightuserdata, + .gpl_only = false, + .pkt_access = false, + .ret_type = RET_VOID, + .arg1_type = ARG_PTR_TO_CTX, + .arg2_type = ARG_ANYTHING, +}; + +BPF_CALL_2(bpf_lua_pushmap, struct xdp_buff *, ctx, struct bpf_map *, map) { + lua_pushlightuserdata(ctx->L, map); + return 0; +} + +static const struct bpf_func_proto bpf_lua_pushmap_proto = { + .func = bpf_lua_pushmap, + .gpl_only = false, + .pkt_access = false, + .ret_type = RET_VOID, + .arg1_type = ARG_PTR_TO_CTX, + .arg2_type = ARG_ANYTHING, +}; + +BPF_CALL_3(bpf_lua_pushlstring, struct xdp_buff *, ctx, const char *, str, size_t, len) { + lua_pushlstring(ctx->L, str, len); + return 0; +} + +static const struct bpf_func_proto bpf_lua_pushlstring_proto = { + .func = bpf_lua_pushlstring, + .gpl_only = false, + .pkt_access = false, + .ret_type = RET_VOID, + .arg1_type = ARG_PTR_TO_CTX, + .arg2_type = ARG_ANYTHING, + .arg3_type = ARG_ANYTHING, +}; + +BPF_CALL_1(bpf_lua_pushskb, struct xdp_buff *, ctx) { + lua_pushlightuserdata(ctx->L, ctx->skb); + return 0; +} + +static const struct bpf_func_proto bpf_lua_pushskb_proto = { + .func = bpf_lua_pushskb, + .gpl_only = false, + .pkt_access = false, + .ret_type = RET_VOID, + .arg1_type = ARG_PTR_TO_CTX, +}; + +BPF_CALL_2(bpf_lua_pushstring, struct xdp_buff *, ctx, const char *, str) { + lua_pushstring(ctx->L, str); + return 0; +} + +static const struct bpf_func_proto bpf_lua_pushstring_proto = { + .func = bpf_lua_pushstring, + .gpl_only = false, + .pkt_access = false, + .ret_type = RET_VOID, + .arg1_type = ARG_PTR_TO_CTX, + .arg2_type = ARG_ANYTHING, +}; + +BPF_CALL_1(bpf_lua_setstate, struct xdp_buff *, ctx){ + struct lua_state_cpu *sc; + int cpu = smp_processor_id(); + + list_for_each_entry(sc, &lua_state_cpu_list, list) { + if (sc->cpu == cpu) { + ctx->L = sc->L; + break; + } + } + return 0; +} + +static const struct bpf_func_proto bpf_lua_setstate_proto = { + .func = bpf_lua_setstate, + .gpl_only = false, + .pkt_access = false, + .ret_type = RET_VOID, + .arg1_type = ARG_PTR_TO_CTX, +}; + +BPF_CALL_2(bpf_lua_toboolean, struct xdp_buff *, ctx, int, index) { + return lua_toboolean(ctx->L, index); +} + +static const struct bpf_func_proto bpf_lua_toboolean_proto = { + .func = bpf_lua_toboolean, + .gpl_only = false, + .pkt_access = false, + .ret_type = RET_INTEGER, + .arg1_type = ARG_PTR_TO_CTX, + .arg2_type = ARG_ANYTHING, +}; + +BPF_CALL_2(bpf_lua_tointeger, struct xdp_buff *, ctx, int, index) { + return lua_tointeger(ctx->L, index); +} + +static const struct bpf_func_proto bpf_lua_tointeger_proto = { + .func = bpf_lua_tointeger, + .gpl_only = false, + .pkt_access = false, + .ret_type = RET_INTEGER, + .arg1_type = ARG_PTR_TO_CTX, + .arg2_type = ARG_ANYTHING, +}; +#endif /* CONFIG_XDP_LUA */ + bool bpf_helper_changes_pkt_data(void *func) { if (func == bpf_skb_vlan_push || @@ -5925,6 +6104,30 @@ 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_pcall: + return &bpf_lua_pcall_proto; + case BPF_FUNC_lua_pop: + return &bpf_lua_pop_proto; + case BPF_FUNC_lua_pushinteger: + return &bpf_lua_pushinteger_proto; + case BPF_FUNC_lua_pushlightuserdata: + return &bpf_lua_pushlightuserdata_proto; + case BPF_FUNC_lua_pushlstring: + return &bpf_lua_pushlstring_proto; + case BPF_FUNC_lua_pushmap: + return &bpf_lua_pushmap_proto; + case BPF_FUNC_lua_pushskb: + return &bpf_lua_pushskb_proto; + case BPF_FUNC_lua_pushstring: + return &bpf_lua_pushstring_proto; + case BPF_FUNC_lua_setstate: + return &bpf_lua_setstate_proto; + case BPF_FUNC_lua_toboolean: + return &bpf_lua_toboolean_proto; + case BPF_FUNC_lua_tointeger: + return &bpf_lua_tointeger_proto; +#endif /* CONFIG_XDP_LUA */ default: return NULL; } diff --git a/net/core/rtnetlink.c b/net/core/rtnetlink.c index e1152f4ffe33ef..3f54d1f118fbea 100644 --- a/net/core/rtnetlink.c +++ b/net/core/rtnetlink.c @@ -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 }, +#endif /* CONFIG_XDP_LUA */ }; static const struct rtnl_link_ops *linkinfo_to_kind_ops(const struct nlattr *nla) @@ -2806,6 +2809,21 @@ static int do_setlink(const struct sk_buff *skb, goto errout; status |= DO_SETLINK_NOTIFY; } + +#ifdef CONFIG_XDP_LUA + if (xdp[IFLA_XDP_LUA_PROG]) { + char *lua_prog = nla_data(xdp[IFLA_XDP_LUA_PROG]); + if (!lua_prog) { + err = -EINVAL; + goto errout; + } + + err = generic_xdp_lua_install_prog(lua_prog); + if (err) + goto errout; + } +#endif /* CONFIG_XDP_LUA */ + } errout: diff --git a/net/xdp/Kconfig b/net/xdp/Kconfig index 71af2febe72adf..0c77ed4f41fdd2 100644 --- a/net/xdp/Kconfig +++ b/net/xdp/Kconfig @@ -14,3 +14,10 @@ config XDP_SOCKETS_DIAG help Support for PF_XDP sockets monitoring interface used by the ss tool. If unsure, say Y. + +config XDP_LUA + bool "XDP LUA" + depends on BPF_SYSCALL && LUNATIK + default n + help + Support for Lua scripts inside XDP diff --git a/samples/bpf/Makefile b/samples/bpf/Makefile index 79b0fee6943bbe..0704db76501bdd 100644 --- a/samples/bpf/Makefile +++ b/samples/bpf/Makefile @@ -53,6 +53,8 @@ tprogs-y += task_fd_query tprogs-y += xdp_sample_pkts tprogs-y += ibumad tprogs-y += hbm +# CONFIG_XDP_LUA +tprogs-y += xdplua # Libbpf dependencies LIBBPF = $(TOOLS_PATH)/lib/bpf/libbpf.a @@ -109,6 +111,8 @@ task_fd_query-objs := bpf_load.o task_fd_query_user.o $(TRACE_HELPERS) xdp_sample_pkts-objs := xdp_sample_pkts_user.o $(TRACE_HELPERS) ibumad-objs := bpf_load.o ibumad_user.o $(TRACE_HELPERS) hbm-objs := bpf_load.o hbm.o $(CGROUP_HELPERS) +# CONFIG_XDPLUA +xdplua-objs := xdplua_user.o # Tell kbuild to always build the programs always-y := $(tprogs-y) diff --git a/samples/bpf/xdplua_user.c b/samples/bpf/xdplua_user.c new file mode 100644 index 00000000000000..1e696aa0744e29 --- /dev/null +++ b/samples/bpf/xdplua_user.c @@ -0,0 +1,225 @@ +/* + * Copyright (C) 2019-2020 Victor Nogueira + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation version 2. + * + * This program is distributed "as is" WITHOUT ANY WARRANTY of any + * kind, whether express or implied; without even the implied warranty + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include "bpf/libbpf.h" + +#include "bpf_util.h" + +#define MAXSCRIPTLEN 8192 +#define MAXFILENAMELEN 256 + +static int ifindex = 0; + +static void usage(const char *prog) { + fprintf(stderr, "usage: %s [OPTS]\n" + "\nOPTS:\n" + " -d detach program\n" + " -f lua script path\n" + " -p eBPF program path\n" + " -i iface\n" + " -m monitor\n" + " -s lua script\n", + prog); +} + +static char *extract_lua_prog(const char *path) +{ + FILE *f; + long prog_size; + char *lua_prog; + + f = fopen(path, "r"); + if (f == NULL) { + perror("unable to xopen lua file"); + return NULL; + } + + fseek(f, 0 , SEEK_END); + prog_size = ftell(f); + rewind(f); + + lua_prog = (char *) malloc(prog_size + 1); + memset(lua_prog, 0, prog_size + 1); + if (fread(lua_prog, 1, prog_size, f) < 0) { + perror("unable to read lua file"); + return NULL; + } + + lua_prog[prog_size] = '\0'; + fclose(f); + return lua_prog; +} + +static int do_attach_ebpf(int idx, int fd, const char *name) +{ + int err; + + err = bpf_set_link_xdp_fd(idx, fd, XDP_FLAGS_SKB_MODE); + if (err < 0) + fprintf(stderr, "ERROR: failed to attach program to %s\n", name); + + return err; +} + +static int do_attach_lua(char *lua_prog) +{ + int err; + + err = bpf_set_link_xdp_lua_prog(lua_prog); + if (err < 0) + fprintf(stderr, "ERROR: failed to attach lua script %d\n", err); + + return err; +} + +static int do_detach(int idx, const char *name) +{ + int err; + + err = bpf_set_link_xdp_fd(idx, -1, XDP_FLAGS_SKB_MODE); + if (err < 0) + fprintf(stderr, "ERROR: failed to detach program from %s\n", name); + + return err; +} + +static void poll(int map_fd, int interval) { + long cnt; + unsigned int key = 0; + + while(1) { + bpf_map_lookup_elem(map_fd, &key, &cnt); + printf("pkt count: %lu\n", cnt); + sleep(interval); + } +} + +int main(int argc, char *argv[]) +{ + struct rlimit r = {RLIM_INFINITY, RLIM_INFINITY}; + char lua_filename[MAXFILENAMELEN]; + char filename[MAXFILENAMELEN]; + char lua_script[MAXSCRIPTLEN]; + struct bpf_object *obj; + int opt, prog_fd; + int rx_cnt_map_fd; + int detach = 0, attach_lua = 0, attach_ebpf = 0, monitor = 0, attach_script = 0; + char *lua_prog = NULL; + const char *optstr = "f:p:i:dms:"; + struct bpf_prog_load_attr prog_load_attr = { + .prog_type = BPF_PROG_TYPE_XDP, + }; + + memset(lua_filename, 0, MAXFILENAMELEN); + memset(filename, 0, MAXFILENAMELEN); + while ((opt = getopt(argc, argv, optstr)) != -1) { + switch (opt) { + case 'f': + snprintf(lua_filename, sizeof(lua_filename), + "%s", optarg); + attach_lua = 1; + break; + case 'p': + snprintf(filename, sizeof(filename), + "%s", optarg); + attach_ebpf = 1; + break; + case 'd': + detach = 1; + break; + case 'i': + ifindex = if_nametoindex(optarg); + break; + case 'm': + monitor = 1; + break; + case 's': + snprintf(lua_script, sizeof(lua_script), + "%s", optarg); + attach_script = 1; + break; + default: + usage(basename(argv[0])); + return 1; + } + } + + if (attach_ebpf || detach) { + if (!ifindex) { + printf("ERROR: invalid interface name"); + return 1; + } + } + + if (setrlimit(RLIMIT_MEMLOCK, &r)) { + perror("ERROR: setrlimit(RLIMIT_MEMLOCK)"); + return 1; + } + + if (detach) { + if (do_detach(ifindex, lua_filename) < 0) + return 1; + + return 0; + } + + if (attach_ebpf) { + prog_load_attr.file = filename; + + if (bpf_prog_load_xattr(&prog_load_attr, &obj, &prog_fd)) + return 1; + + if (!prog_fd) { + printf("ERROR: failed to load_bpf_file\n"); + return 1; + } + + if (do_attach_ebpf(ifindex, prog_fd, lua_filename) < 0) + return 1; + + } + + if (attach_lua) { + lua_prog = extract_lua_prog(lua_filename); + if (!lua_prog) + return 1; + + if (do_attach_lua(lua_prog) < 0) { + free(lua_prog); + return 1; + } + + free(lua_prog); + } + + if (attach_script) + if (do_attach_lua(lua_script) < 0) + return 1; + + if (monitor) { + rx_cnt_map_fd = bpf_object__find_map_fd_by_name(obj, "rx_cnt"); + + poll(rx_cnt_map_fd, 1); + } + return 0; +} diff --git a/tools/include/uapi/linux/bpf.h b/tools/include/uapi/linux/bpf.h index 22f235260a3a35..8c59576a29dbe6 100644 --- a/tools/include/uapi/linux/bpf.h +++ b/tools/include/uapi/linux/bpf.h @@ -2890,6 +2890,73 @@ union bpf_attr { * Obtain the 64bit jiffies * Return * The 64 bit jiffies + * + * void bpf_lua_pcall(void *ctx, char *funcname, int num_args, int num_rets) + * Description + * Calls Lua function funcname with the given nargs arguments in protected mode + * + * void bpf_lua_pop(void *ctx, int n) + * Description + * Pops n elements from the Lua stack + * + * void bpf_lua_pushinteger(void *ctx, int num) + * Description + * Pushes an integer with value n onto the Lua stack. + * + * void bpf_lua_pushlightuserdata(void *ctx, void *ptr) + * Description + * Pushes a light userdata onto the Lua stack. + * Userdata represent C values in Lua. + * A light userdata represents a pointer, a void*. + * It is a value (like a number): you do not create it, + * it has no individual metatable, and it is not collected + * (as it was never created). + * A light userdata is equal to "any" light userdata with + * the same C address. + * + * void bpf_lua_pushlstring(void *ctx, const char *s, size_t len) + * Description + * Pushes the string pointed to by s with size len 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. + * The string can contain any binary data, including embedded zeros. + * + * void bpf_lua_pushmap(void *ctx, void *map) + * Description + * Pushes a BPF map onto the Lua stack + * + * void bpf_lua_pushskb(void *ctx) + * Description + * Pushes an SKB structure onto the Lua stack + * + * void bpf_lua_pushstring(void *ctx, const char *s) + * Description + * 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. + * + * void bpf_lua_setstate(void *ctx) + * Description + * Sets the Lua state pointer in the context struct + * + * int bpf_lua_toboolean(void *ctx, int index) + * Description + * Converts the Lua value at the given index to a C + * boolean value (0 or 1) + * Return + * 1 if the value in the given index of the Lua stack is + * different from from false or null, otherwise returns 0 + * + * int bpf_lua_tointeger(void *ctx, int index) + * Description + * Converts the Lua value at the given index of the Lua stack + * to the signed integral type lua_Integer. + * Return + * The converted Lua value at the given index, if the value is + * convertible to an integer(see the Lua manual for more details + * on type conversion); otherwise returns 0 */ #define __BPF_FUNC_MAPPER(FN) \ FN(unspec), \ @@ -3010,7 +3077,20 @@ union bpf_attr { FN(probe_read_kernel_str), \ FN(tcp_send_ack), \ FN(send_signal_thread), \ - FN(jiffies64), + FN(jiffies64), \ + /* #ifdef CONFIG_XDP_LUA */ \ + FN(lua_pcall), \ + FN(lua_pop), \ + FN(lua_pushinteger), \ + FN(lua_pushlightuserdata), \ + FN(lua_pushlstring), \ + FN(lua_pushmap), \ + FN(lua_pushskb), \ + FN(lua_pushstring), \ + FN(lua_setstate), \ + FN(lua_toboolean), \ + FN(lua_tointeger), + /* #endif CONFIG_XDP_LUA */ /* integer value in 'imm' field of BPF_CALL instruction selects which helper * function eBPF program intends to call diff --git a/tools/include/uapi/linux/if_link.h b/tools/include/uapi/linux/if_link.h index 024af2d1d0af40..738280129e2601 100644 --- a/tools/include/uapi/linux/if_link.h +++ b/tools/include/uapi/linux/if_link.h @@ -984,6 +984,9 @@ enum { IFLA_XDP_DRV_PROG_ID, IFLA_XDP_SKB_PROG_ID, IFLA_XDP_HW_PROG_ID, +/* #ifdef CONFIG_XDP_LUA */ + IFLA_XDP_LUA_PROG, +/* #endif CONFIG_XDP_LUA */ __IFLA_XDP_MAX, }; diff --git a/tools/lib/bpf/libbpf.h b/tools/lib/bpf/libbpf.h index 3fe12c9d1f9232..3c10f45f923a8c 100644 --- a/tools/lib/bpf/libbpf.h +++ b/tools/lib/bpf/libbpf.h @@ -439,6 +439,9 @@ LIBBPF_API int bpf_set_link_xdp_fd(int ifindex, int fd, __u32 flags); LIBBPF_API int bpf_get_link_xdp_id(int ifindex, __u32 *prog_id, __u32 flags); LIBBPF_API int bpf_get_link_xdp_info(int ifindex, struct xdp_link_info *info, size_t info_size, __u32 flags); +/* #ifdef CONFIG_XDPLUA */ +LIBBPF_API int bpf_set_link_xdp_lua_prog(char *lua_prog); +/* #endif CONFIG_XDPLUA */ struct perf_buffer; diff --git a/tools/lib/bpf/libbpf.map b/tools/lib/bpf/libbpf.map index b035122142bb9f..931318b213b72c 100644 --- a/tools/lib/bpf/libbpf.map +++ b/tools/lib/bpf/libbpf.map @@ -105,6 +105,7 @@ LIBBPF_0.0.1 { bpf_prog_linfo__lfind; bpf_raw_tracepoint_open; bpf_set_link_xdp_fd; + bpf_set_link_xdp_lua_prog; bpf_task_fd_query; bpf_verify_program; btf__fd; diff --git a/tools/lib/bpf/netlink.c b/tools/lib/bpf/netlink.c index 431bd25c6cdb5a..f877eb676b5f5a 100644 --- a/tools/lib/bpf/netlink.c +++ b/tools/lib/bpf/netlink.c @@ -191,6 +191,62 @@ int bpf_set_link_xdp_fd(int ifindex, int fd, __u32 flags) return ret; } +/* #ifdef CONFIG_XDPLUA */ +int bpf_set_link_xdp_lua_prog(char *lua_prog) { + int sock, seq = 0, ret; + struct nlattr *nla, *nla_xdp; + struct { + struct nlmsghdr nh; + struct ifinfomsg ifinfo; + char attrbuf[8192]; + } req; + __u32 nl_pid; + + sock = libbpf_netlink_open(&nl_pid); + if (sock < 0) + return sock; + + memset(&req, 0, sizeof(req)); + req.nh.nlmsg_len = NLMSG_LENGTH(sizeof(struct ifinfomsg)); + req.nh.nlmsg_flags = NLM_F_REQUEST | NLM_F_ACK; + req.nh.nlmsg_type = RTM_SETLINK; + req.nh.nlmsg_pid = 0; + req.nh.nlmsg_seq = ++seq; + req.ifinfo.ifi_family = AF_UNSPEC; + req.ifinfo.ifi_index = 1; + + /* started nested attribute for XDP */ + nla = (struct nlattr *)(((char *)&req) + + NLMSG_ALIGN(req.nh.nlmsg_len)); + nla->nla_type = NLA_F_NESTED | IFLA_XDP; + nla->nla_len = NLA_HDRLEN; + + /* add XDP LUA PROG */ + nla_xdp = (struct nlattr *)((char *)nla + nla->nla_len); + nla_xdp->nla_type = IFLA_XDP_LUA_PROG; + if (lua_prog) { + nla_xdp->nla_len = NLA_HDRLEN + strlen(lua_prog) + 1; + memcpy((char *)nla_xdp + NLA_HDRLEN, lua_prog, strlen(lua_prog) + 1); + } else { + ret = -EINVAL; + goto cleanup; + } + nla->nla_len += nla_xdp->nla_len; + + req.nh.nlmsg_len += NLA_ALIGN(nla->nla_len); + + if (send(sock, &req, req.nh.nlmsg_len, 0) < 0) { + ret = -errno; + goto cleanup; + } + ret = bpf_netlink_recv(sock, nl_pid, seq, NULL, NULL, NULL); + +cleanup: + close(sock); + return ret; +} +/* #endif CONFIG_XDPLUA */ + static int __dump_link_nlmsg(struct nlmsghdr *nlh, libbpf_dump_nlmsg_t dump_link_nlmsg, void *cookie) { From f278687fce01107306779dabb84a9a0fe603c262 Mon Sep 17 00:00:00 2001 From: Victor Nogueira Date: Thu, 30 Jan 2020 21:47:55 +0000 Subject: [PATCH 03/18] add LuaData submodule --- .gitmodules | 3 +++ include/uapi/linux/bpf.h | 16 ++++++++++++++ lib/Makefile | 2 ++ lib/luadata | 1 + net/core/Makefile | 6 +++-- net/core/dev.c | 2 ++ net/core/filter.c | 40 ++++++++++++++++++++++++++++++++++ tools/include/uapi/linux/bpf.h | 16 ++++++++++++++ 8 files changed, 84 insertions(+), 2 deletions(-) create mode 160000 lib/luadata diff --git a/.gitmodules b/.gitmodules index f1d9bd02ab7ca8..a60359c423290d 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,3 +1,6 @@ [submodule "lib/lunatik"] path = lib/lunatik url = https://github.com/luainkernel/lunatik.git +[submodule "lib/luadata"] + path = lib/luadata + url = https://github.com/luainkernel/luadata diff --git a/include/uapi/linux/bpf.h b/include/uapi/linux/bpf.h index 8c59576a29dbe6..cb14acfb1a388d 100644 --- a/include/uapi/linux/bpf.h +++ b/include/uapi/linux/bpf.h @@ -2891,6 +2891,20 @@ union bpf_attr { * Return * The 64 bit jiffies * + * int bpf_lua_dataref(void *ctx, int offset) + * Description + * Create a new lua data buffer 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 + * of failure + * + * void bpf_lua_dataunref(void *ctx, int data_ref) + * Description + * Releases the data-object reference, allowing it to be + * garbage-collected + * * void bpf_lua_pcall(void *ctx, char *funcname, int num_args, int num_rets) * Description * Calls Lua function funcname with the given nargs arguments in protected mode @@ -3079,6 +3093,8 @@ union bpf_attr { FN(send_signal_thread), \ FN(jiffies64), \ /* #ifdef CONFIG_XDP_LUA */ \ + FN(lua_dataref), \ + FN(lua_dataunref), \ FN(lua_pcall), \ FN(lua_pop), \ FN(lua_pushinteger), \ diff --git a/lib/Makefile b/lib/Makefile index 3813aeef91a2d3..98c960c00fb249 100644 --- a/lib/Makefile +++ b/lib/Makefile @@ -301,5 +301,7 @@ obj-$(CONFIG_OBJAGG) += objagg.o # KUnit tests obj-$(CONFIG_LIST_KUNIT_TEST) += list-test.o subdir-ccflags-y += -I$(srctree)/lib/lunatik/lua \ + -I$(srctree)/lib/luadata/ \ -D_KERNEL obj-$(CONFIG_LUNATIK) += lunatik/ +obj-$(CONFIG_LUADATA) += luadata/ diff --git a/lib/luadata b/lib/luadata new file mode 160000 index 00000000000000..21137a054a8281 --- /dev/null +++ b/lib/luadata @@ -0,0 +1 @@ +Subproject commit 21137a054a828123deea403b106a87e9e8d2795d diff --git a/net/core/Makefile b/net/core/Makefile index 3fcf663db99837..72be363912fb2c 100644 --- a/net/core/Makefile +++ b/net/core/Makefile @@ -8,8 +8,10 @@ obj-y := sock.o request_sock.o skbuff.o datagram.o stream.o scm.o \ obj-$(CONFIG_SYSCTL) += sysctl_net_core.o -CFLAGS_dev.o = -Ilib/lunatik/lua/ -D_KERNEL -CFLAGS_filter.o = -Ilib/lunatik/lua/ -D_KERNEL +CFLAGS_dev.o = -Ilib/lunatik/lua/ -D_KERNEL \ + -Ilib/luadata/ +CFLAGS_filter.o = -Ilib/lunatik/lua/ -D_KERNEL \ + -Ilib/luadata/ obj-y += dev.o dev_addr_lists.o dst.o netevent.o \ neighbour.o rtnetlink.o utils.o link_watch.o filter.o \ sock_diag.o dev_ioctl.o tso.o sock_reuseport.o \ diff --git a/net/core/dev.c b/net/core/dev.c index 6abe540fcd7e83..1363d6bf3ca396 100644 --- a/net/core/dev.c +++ b/net/core/dev.c @@ -72,6 +72,7 @@ #include #include #include +#include #endif /* CONFIG_XDP_LUA */ #include @@ -10555,6 +10556,7 @@ static int __init net_dev_init(void) } luaL_openlibs(new_state_cpu->L); + luaL_requiref(new_state_cpu->L, "data", luaopen_data, 1); lua_pop(new_state_cpu->L, 1); new_state_cpu->cpu = i; diff --git a/net/core/filter.c b/net/core/filter.c index 7ebcea60e44270..717c116a337110 100644 --- a/net/core/filter.c +++ b/net/core/filter.c @@ -76,6 +76,7 @@ #ifdef CONFIG_XDP_LUA #include +#include #endif /* CONFIG_XDP_LUA */ /** @@ -5854,6 +5855,41 @@ static const struct bpf_func_proto bpf_tcp_gen_syncookie_proto = { #endif /* CONFIG_INET */ #ifdef CONFIG_XDP_LUA +BPF_CALL_2(bpf_lua_dataref, struct xdp_buff *, ctx, int, offset) { + if (offset + ctx->data < ctx->data_end) { + int data_ref; + + data_ref = ldata_newref(ctx->L, ctx->data + offset, + ctx->data_end - ctx->data - offset); + return data_ref; + } + + return -1; +} + +static const struct bpf_func_proto bpf_lua_dataref_proto = { + .func = bpf_lua_dataref, + .gpl_only = false, + .pkt_access = false, + .ret_type = RET_INTEGER, + .arg1_type = ARG_PTR_TO_CTX, + .arg1_type = ARG_ANYTHING, +}; + +BPF_CALL_2(bpf_lua_dataunref, struct xdp_buff *, ctx, int, data_ref) { + ldata_unref(ctx->L, data_ref); + return 0; +} + +static const struct bpf_func_proto bpf_lua_dataunref_proto = { + .func = bpf_lua_dataunref, + .gpl_only = false, + .pkt_access = false, + .ret_type = RET_VOID, + .arg1_type = ARG_PTR_TO_CTX, + .arg2_type = ARG_ANYTHING, +}; + BPF_CALL_4(bpf_lua_pcall, struct xdp_buff *, ctx, char *, funcname, int, num_args, int, num_rets) { if (lua_getglobal(ctx->L, funcname) != LUA_TFUNCTION) { @@ -6105,6 +6141,10 @@ bpf_base_func_proto(enum bpf_func_id func_id) case BPF_FUNC_jiffies64: return &bpf_jiffies64_proto; #ifdef CONFIG_XDP_LUA + case BPF_FUNC_lua_dataref: + return &bpf_lua_dataref_proto; + case BPF_FUNC_lua_dataunref: + return &bpf_lua_dataunref_proto; case BPF_FUNC_lua_pcall: return &bpf_lua_pcall_proto; case BPF_FUNC_lua_pop: diff --git a/tools/include/uapi/linux/bpf.h b/tools/include/uapi/linux/bpf.h index 8c59576a29dbe6..cb14acfb1a388d 100644 --- a/tools/include/uapi/linux/bpf.h +++ b/tools/include/uapi/linux/bpf.h @@ -2891,6 +2891,20 @@ union bpf_attr { * Return * The 64 bit jiffies * + * int bpf_lua_dataref(void *ctx, int offset) + * Description + * Create a new lua data buffer 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 + * of failure + * + * void bpf_lua_dataunref(void *ctx, int data_ref) + * Description + * Releases the data-object reference, allowing it to be + * garbage-collected + * * void bpf_lua_pcall(void *ctx, char *funcname, int num_args, int num_rets) * Description * Calls Lua function funcname with the given nargs arguments in protected mode @@ -3079,6 +3093,8 @@ union bpf_attr { FN(send_signal_thread), \ FN(jiffies64), \ /* #ifdef CONFIG_XDP_LUA */ \ + FN(lua_dataref), \ + FN(lua_dataunref), \ FN(lua_pcall), \ FN(lua_pop), \ FN(lua_pushinteger), \ From 7d184d927230edc18f1d2d48eb5663d007c9c0cd Mon Sep 17 00:00:00 2001 From: Lourival Vieira Neto Date: Fri, 7 Feb 2020 21:00:22 +0000 Subject: [PATCH 04/18] add LuaXDP submodule --- .gitmodules | 3 +++ lib/Makefile | 1 + lib/luaxdp | 1 + 3 files changed, 5 insertions(+) create mode 160000 lib/luaxdp diff --git a/.gitmodules b/.gitmodules index a60359c423290d..ffee774e9dc8a6 100644 --- a/.gitmodules +++ b/.gitmodules @@ -4,3 +4,6 @@ [submodule "lib/luadata"] path = lib/luadata url = https://github.com/luainkernel/luadata +[submodule "lib/luaxdp"] + path = lib/luaxdp + url = https://github.com/luainkernel/luaxdp.git diff --git a/lib/Makefile b/lib/Makefile index 98c960c00fb249..738812aad1b161 100644 --- a/lib/Makefile +++ b/lib/Makefile @@ -305,3 +305,4 @@ subdir-ccflags-y += -I$(srctree)/lib/lunatik/lua \ -D_KERNEL obj-$(CONFIG_LUNATIK) += lunatik/ obj-$(CONFIG_LUADATA) += luadata/ +obj-$(CONFIG_LUAXDP) += luaxdp/ diff --git a/lib/luaxdp b/lib/luaxdp new file mode 160000 index 00000000000000..64216b7daa8e11 --- /dev/null +++ b/lib/luaxdp @@ -0,0 +1 @@ +Subproject commit 64216b7daa8e114c97c94c1da31472097cbb9343 From 7e405cfe3f61fe14f16626272e045251ae6d038f Mon Sep 17 00:00:00 2001 From: Lourival Vieira Neto Date: Thu, 30 Jan 2020 23:56:16 +0000 Subject: [PATCH 05/18] add LuaRCU submodule --- .gitmodules | 3 +++ lib/Makefile | 1 + lib/luarcu | 1 + 3 files changed, 5 insertions(+) create mode 160000 lib/luarcu diff --git a/.gitmodules b/.gitmodules index ffee774e9dc8a6..d17f05c06fdfa0 100644 --- a/.gitmodules +++ b/.gitmodules @@ -7,3 +7,6 @@ [submodule "lib/luaxdp"] path = lib/luaxdp url = https://github.com/luainkernel/luaxdp.git +[submodule "lib/luarcu"] + path = lib/luarcu + url = https://github.com/luainkernel/luarcu diff --git a/lib/Makefile b/lib/Makefile index 738812aad1b161..00fc7d38fcc89d 100644 --- a/lib/Makefile +++ b/lib/Makefile @@ -306,3 +306,4 @@ subdir-ccflags-y += -I$(srctree)/lib/lunatik/lua \ obj-$(CONFIG_LUNATIK) += lunatik/ obj-$(CONFIG_LUADATA) += luadata/ obj-$(CONFIG_LUAXDP) += luaxdp/ +obj-$(CONFIG_LUARCU) += luarcu/ diff --git a/lib/luarcu b/lib/luarcu new file mode 160000 index 00000000000000..bc563d5245afc8 --- /dev/null +++ b/lib/luarcu @@ -0,0 +1 @@ +Subproject commit bc563d5245afc8024dd3f47fd8da404a781e0215 From 13a42ebb18143cd3304e8d5579f443cb199fe726 Mon Sep 17 00:00:00 2001 From: Victor Nogueira Date: Tue, 11 Feb 2020 00:37:47 +0000 Subject: [PATCH 06/18] add XDPLua map sample --- samples/bpf/Makefile | 4 +++- samples/bpf/map.lua | 22 +++++++++++++++++++ samples/bpf/xdplua_map_kern.c | 40 +++++++++++++++++++++++++++++++++++ 3 files changed, 65 insertions(+), 1 deletion(-) create mode 100644 samples/bpf/map.lua create mode 100644 samples/bpf/xdplua_map_kern.c diff --git a/samples/bpf/Makefile b/samples/bpf/Makefile index 0704db76501bdd..4b173a2de502f8 100644 --- a/samples/bpf/Makefile +++ b/samples/bpf/Makefile @@ -111,7 +111,7 @@ task_fd_query-objs := bpf_load.o task_fd_query_user.o $(TRACE_HELPERS) xdp_sample_pkts-objs := xdp_sample_pkts_user.o $(TRACE_HELPERS) ibumad-objs := bpf_load.o ibumad_user.o $(TRACE_HELPERS) hbm-objs := bpf_load.o hbm.o $(CGROUP_HELPERS) -# CONFIG_XDPLUA +# CONFIG_XDP_LUA xdplua-objs := xdplua_user.o # Tell kbuild to always build the programs @@ -174,6 +174,8 @@ always-y += ibumad_kern.o always-y += hbm_out_kern.o always-y += hbm_edt_kern.o always-y += xdpsock_kern.o +# CONFIG_XDP_LUA +always-y += xdplua_map_kern.o ifeq ($(ARCH), arm) # Strip all except -D__LINUX_ARM_ARCH__ option needed to handle linux diff --git a/samples/bpf/map.lua b/samples/bpf/map.lua new file mode 100644 index 00000000000000..aa6e733424a8d2 --- /dev/null +++ b/samples/bpf/map.lua @@ -0,0 +1,22 @@ +-- +-- Copyright (C) 2019-2020 Victor Nogueira +-- +-- This program is free software; you can redistribute it and/or +-- modify it under the terms of the GNU General Public License as +-- published by the Free Software Foundation version 2. +-- +-- This program is distributed "as is" WITHOUT ANY WARRANTY of any +-- kind, whether express or implied; without even the implied warranty +-- of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +-- GNU General Public License for more details. +-- +xdp = require'xdp' + +function lookup(map) + local val = xdp.map_lookup(map, 1) + print('val', val) +end + +function update(map) + xdp.map_update(map, 1, 3) +end diff --git a/samples/bpf/xdplua_map_kern.c b/samples/bpf/xdplua_map_kern.c new file mode 100644 index 00000000000000..11f00033204e0c --- /dev/null +++ b/samples/bpf/xdplua_map_kern.c @@ -0,0 +1,40 @@ +/* + * Copyright (C) 2019-2020 Victor Nogueira + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation version 2. + * + * This program is distributed "as is" WITHOUT ANY WARRANTY of any + * kind, whether express or implied; without even the implied warranty + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ +#define KBUILD_MODNAME "foo" +#include +#include + +struct bpf_map_def SEC("maps") lua_test_map = { + .type = BPF_MAP_TYPE_ARRAY, + .key_size = sizeof(int), + .value_size = sizeof(int), + .max_entries = 20, +}; + +SEC("xdp_lua_test_map") +int xdp_lua_test_map_prog(struct xdp_md *ctx) +{ + char lookupname[] = "lookup"; + char updatename[] = "update"; + + bpf_lua_setstate(ctx); + bpf_lua_pushmap(ctx, &lua_test_map); + bpf_lua_pcall(ctx, updatename, 1, 0); + + bpf_lua_pushmap(ctx, &lua_test_map); + bpf_lua_pcall(ctx, lookupname, 1, 0); + + return XDP_PASS; +} + +char _license[] SEC("license") = "GPL"; From 5eb463c6e5bc7c8ac063257e9a721fe5147a903c Mon Sep 17 00:00:00 2001 From: Victor Nogueira Date: Wed, 19 Feb 2020 22:13:09 -0300 Subject: [PATCH 07/18] Fix script loading synchronization issue --- include/linux/filter.h | 10 ----- include/net/xdp.h | 13 ++++++ include/uapi/linux/bpf.h | 5 --- net/core/dev.c | 80 ++++++++++++++++++++-------------- net/core/filter.c | 65 +++++++++++++++------------ samples/bpf/xdplua_map_kern.c | 1 - tools/include/uapi/linux/bpf.h | 5 --- 7 files changed, 98 insertions(+), 81 deletions(-) diff --git a/include/linux/filter.h b/include/linux/filter.h index 1a01a2e37b9f67..f349e2c0884c4c 100644 --- a/include/linux/filter.h +++ b/include/linux/filter.h @@ -1268,14 +1268,4 @@ struct bpf_sockopt_kern { s32 retval; }; -#ifdef CONFIG_XDP_LUA -extern struct list_head lua_state_cpu_list; - -struct lua_state_cpu { - struct lua_State *L; - int cpu; - struct list_head list; -}; -#endif /* CONFIG_XDP_LUA */ - #endif /* __LINUX_FILTER_H__ */ diff --git a/include/net/xdp.h b/include/net/xdp.h index de64fe2f1fc0b5..8c38a85ebff132 100644 --- a/include/net/xdp.h +++ b/include/net/xdp.h @@ -63,6 +63,19 @@ 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]; + struct lua_State *L; + struct work_struct work; + spinlock_t lock; + bool init; +}; + +DECLARE_PER_CPU(struct xdplua_create_work, luaworks); +#endif /* CONFIG_XDP_LUA */ + + struct xdp_buff { void *data; void *data_end; diff --git a/include/uapi/linux/bpf.h b/include/uapi/linux/bpf.h index cb14acfb1a388d..2969135c5a642d 100644 --- a/include/uapi/linux/bpf.h +++ b/include/uapi/linux/bpf.h @@ -2951,10 +2951,6 @@ union bpf_attr { * so the memory at s can be freed or reused immediately after the * function returns. * - * void bpf_lua_setstate(void *ctx) - * Description - * Sets the Lua state pointer in the context struct - * * int bpf_lua_toboolean(void *ctx, int index) * Description * Converts the Lua value at the given index to a C @@ -3103,7 +3099,6 @@ union bpf_attr { FN(lua_pushmap), \ FN(lua_pushskb), \ FN(lua_pushstring), \ - FN(lua_setstate), \ FN(lua_toboolean), \ FN(lua_tointeger), /* #endif CONFIG_XDP_LUA */ diff --git a/net/core/dev.c b/net/core/dev.c index 1363d6bf3ca396..a0c7ea0dd15460 100644 --- a/net/core/dev.c +++ b/net/core/dev.c @@ -71,6 +71,7 @@ #ifdef CONFIG_XDP_LUA #include #include +#include #include #include #endif /* CONFIG_XDP_LUA */ @@ -159,6 +160,9 @@ static DEFINE_SPINLOCK(ptype_lock); static DEFINE_SPINLOCK(offload_lock); +#ifdef CONFIG_XDP_LUA +DEFINE_PER_CPU(struct xdplua_create_work, luaworks); +#endif struct list_head ptype_base[PTYPE_HASH_SIZE] __read_mostly; struct list_head ptype_all __read_mostly; /* Taps */ static struct list_head offload_base __read_mostly; @@ -171,10 +175,6 @@ static int call_netdevice_notifiers_extack(unsigned long val, struct netlink_ext_ack *extack); static struct napi_struct *napi_by_id(unsigned int napi_id); -#ifdef CONFIG_XDP_LUA -struct list_head lua_state_cpu_list; -#endif /* CONFIG_XDP_LUA */ - /* * The @dev_base_head list is protected by @dev_base_lock and the rtnl * semaphore. @@ -4523,6 +4523,9 @@ static u32 netif_receive_generic_xdp(struct sk_buff *skb, bool orig_bcast; int hlen, off; u32 mac_len; +#ifdef CONFIG_XDP_LUA + struct xdplua_create_work *lw; +#endif /* CONFIG_XDP_LUA */ /* Reinjected packets coming from act_mirred or similar should * not get XDP generic processing. @@ -4568,11 +4571,21 @@ static u32 netif_receive_generic_xdp(struct sk_buff *skb, rxqueue = netif_get_rxqueue(skb); xdp->rxq = &rxqueue->xdp_rxq; #ifdef CONFIG_XDP_LUA + lw = this_cpu_ptr(&luaworks); + xdp->skb = skb; + xdp->L = lw->L; #endif /* CONFIG_XDP_LUA */ act = bpf_prog_run_xdp(xdp_prog, xdp); +#ifdef CONFIG_XDP_LUA + if (lw->init) { + lw->init = false; + spin_unlock(&lw->lock); + } +#endif /* CONFIG_XDP_LUA */ + /* check if bpf_xdp_adjust_head was used */ off = xdp->data - orig_data; if (off) { @@ -5381,16 +5394,29 @@ static int generic_xdp_install(struct net_device *dev, struct netdev_bpf *xdp) } #ifdef CONFIG_XDP_LUA -int generic_xdp_lua_install_prog(char *lua_prog) + +static void per_cpu_xdp_lua_install(struct work_struct *w) { + int this_cpu = smp_processor_id(); + struct xdplua_create_work *lw = + container_of(w, struct xdplua_create_work, work); + + spin_lock_bh(&lw->lock); + if (luaL_dostring(lw->L, lw->lua_script)) { + pr_err(KERN_INFO "error: %s\nOn cpu: %d\n", + lua_tostring(lw->L, -1), this_cpu); + } + spin_unlock_bh(&lw->lock); +} + +int generic_xdp_lua_install_prog(char *lua_script) { - struct lua_state_cpu *sc; + int cpu; + struct xdplua_create_work *lw; - list_for_each_entry(sc, &lua_state_cpu_list, list) { - if (luaL_dostring(sc->L, lua_prog)) { - pr_err(KERN_INFO "error: %s\nOn cpu: %d\n", - lua_tostring(sc->L, -1), sc->cpu); - return -EINVAL; - } + for_each_possible_cpu(cpu) { + lw = per_cpu_ptr(&luaworks, cpu); + strcpy(lw->lua_script, lua_script); + schedule_work_on(cpu, &lw->work); } return 0; } @@ -10492,9 +10518,6 @@ static struct pernet_operations __net_initdata default_device_ops = { static int __init net_dev_init(void) { int i, rc = -ENOMEM; -#ifdef CONFIG_XDP_LUA - struct lua_state_cpu *new_state_cpu; -#endif /* CONFIG_XDP_LUA */ BUG_ON(!dev_boot_phase); @@ -10509,9 +10532,6 @@ static int __init net_dev_init(void) INIT_LIST_HEAD(&ptype_base[i]); INIT_LIST_HEAD(&offload_base); -#ifdef CONFIG_XDP_LUA - INIT_LIST_HEAD(&lua_state_cpu_list); -#endif /* CONFIG_XDP_LUA */ if (register_pernet_subsys(&netdev_net_ops)) goto out; @@ -10523,6 +10543,9 @@ static int __init net_dev_init(void) for_each_possible_cpu(i) { struct work_struct *flush = per_cpu_ptr(&flush_works, i); struct softnet_data *sd = &per_cpu(softnet_data, i); +#ifdef CONFIG_XDP_LUA + struct xdplua_create_work *lw = per_cpu_ptr(&luaworks, i); +#endif INIT_WORK(flush, flush_backlog); @@ -10542,25 +10565,18 @@ static int __init net_dev_init(void) init_gro_hash(&sd->backlog); sd->backlog.poll = process_backlog; sd->backlog.weight = weight_p; - #ifdef CONFIG_XDP_LUA - new_state_cpu = (struct lua_state_cpu *) - kmalloc(sizeof(struct lua_state_cpu), GFP_ATOMIC); - if (!new_state_cpu) - continue; + lw->L = luaL_newstate(); + WARN_ON(!lw->L); - new_state_cpu->L = luaL_newstate(); - if (!new_state_cpu->L) { - kfree(new_state_cpu); + if (!lw->L) continue; - } - luaL_openlibs(new_state_cpu->L); - luaL_requiref(new_state_cpu->L, "data", luaopen_data, 1); - lua_pop(new_state_cpu->L, 1); - new_state_cpu->cpu = i; + luaL_openlibs(lw->L); + luaL_requiref(lw->L, "data", luaopen_data, 1); + lua_pop(lw->L, 1); - list_add(&new_state_cpu->list, &lua_state_cpu_list); + INIT_WORK(&lw->work, per_cpu_xdp_lua_install); #endif /* CONFIG_XDP_LUA */ } diff --git a/net/core/filter.c b/net/core/filter.c index 717c116a337110..e79e7279f7a0c5 100644 --- a/net/core/filter.c +++ b/net/core/filter.c @@ -5855,10 +5855,22 @@ 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) { + struct xdplua_create_work *lw; + + lw = this_cpu_ptr(&luaworks); + if (!lw->init) { + lw->init = true; + spin_lock(&lw->lock); + } +} + BPF_CALL_2(bpf_lua_dataref, struct xdp_buff *, ctx, int, offset) { if (offset + ctx->data < ctx->data_end) { int data_ref; + verify_and_lock(); data_ref = ldata_newref(ctx->L, ctx->data + offset, ctx->data_end - ctx->data - offset); return data_ref; @@ -5877,6 +5889,7 @@ static const struct bpf_func_proto bpf_lua_dataref_proto = { }; BPF_CALL_2(bpf_lua_dataunref, struct xdp_buff *, ctx, int, data_ref) { + verify_and_lock(); ldata_unref(ctx->L, data_ref); return 0; } @@ -5892,18 +5905,28 @@ static const struct bpf_func_proto bpf_lua_dataunref_proto = { BPF_CALL_4(bpf_lua_pcall, struct xdp_buff *, ctx, char *, funcname, int, num_args, int, num_rets) { + int base; + + verify_and_lock(); + + base = lua_gettop(ctx->L) - num_args; if (lua_getglobal(ctx->L, funcname) != LUA_TFUNCTION) { pr_err("function %s not found\n", funcname); - lua_pop(ctx->L, num_args); - return 0; + num_rets = 0; + goto clean_state; } - lua_insert(ctx->L, 1); + lua_insert(ctx->L, base + 1); if (lua_pcall(ctx->L, num_args, num_rets, 0)) { pr_err("%s\n", lua_tostring(ctx->L, -1)); - lua_pop(ctx->L, 1); - return 0; + num_rets = 0; + goto clean_state; } + + base += num_rets; + +clean_state: + lua_settop(ctx->L, base); return num_rets; } @@ -5919,6 +5942,7 @@ static const struct bpf_func_proto bpf_lua_pcall_proto = { }; BPF_CALL_2(bpf_lua_pop, struct xdp_buff *, ctx, int, index) { + verify_and_lock(); lua_pop(ctx->L, index); return 0; } @@ -5933,6 +5957,7 @@ static const struct bpf_func_proto bpf_lua_pop_proto = { }; BPF_CALL_2(bpf_lua_pushinteger, struct xdp_buff *, ctx, int, num) { + verify_and_lock(); lua_pushinteger(ctx->L, num); return 0; } @@ -5947,6 +5972,7 @@ static const struct bpf_func_proto bpf_lua_pushinteger_proto = { }; BPF_CALL_2(bpf_lua_pushlightuserdata, struct xdp_buff *, ctx, void *, ptr) { + verify_and_lock(); lua_pushlightuserdata(ctx->L, ptr); return 0; } @@ -5961,6 +5987,7 @@ static const struct bpf_func_proto bpf_lua_pushlightuserdata_proto = { }; BPF_CALL_2(bpf_lua_pushmap, struct xdp_buff *, ctx, struct bpf_map *, map) { + verify_and_lock(); lua_pushlightuserdata(ctx->L, map); return 0; } @@ -5975,6 +6002,7 @@ static const struct bpf_func_proto bpf_lua_pushmap_proto = { }; BPF_CALL_3(bpf_lua_pushlstring, struct xdp_buff *, ctx, const char *, str, size_t, len) { + verify_and_lock(); lua_pushlstring(ctx->L, str, len); return 0; } @@ -5990,6 +6018,7 @@ static const struct bpf_func_proto bpf_lua_pushlstring_proto = { }; BPF_CALL_1(bpf_lua_pushskb, struct xdp_buff *, ctx) { + verify_and_lock(); lua_pushlightuserdata(ctx->L, ctx->skb); return 0; } @@ -6003,6 +6032,7 @@ static const struct bpf_func_proto bpf_lua_pushskb_proto = { }; BPF_CALL_2(bpf_lua_pushstring, struct xdp_buff *, ctx, const char *, str) { + verify_and_lock(); lua_pushstring(ctx->L, str); return 0; } @@ -6016,28 +6046,8 @@ static const struct bpf_func_proto bpf_lua_pushstring_proto = { .arg2_type = ARG_ANYTHING, }; -BPF_CALL_1(bpf_lua_setstate, struct xdp_buff *, ctx){ - struct lua_state_cpu *sc; - int cpu = smp_processor_id(); - - list_for_each_entry(sc, &lua_state_cpu_list, list) { - if (sc->cpu == cpu) { - ctx->L = sc->L; - break; - } - } - return 0; -} - -static const struct bpf_func_proto bpf_lua_setstate_proto = { - .func = bpf_lua_setstate, - .gpl_only = false, - .pkt_access = false, - .ret_type = RET_VOID, - .arg1_type = ARG_PTR_TO_CTX, -}; - BPF_CALL_2(bpf_lua_toboolean, struct xdp_buff *, ctx, int, index) { + verify_and_lock(); return lua_toboolean(ctx->L, index); } @@ -6051,6 +6061,7 @@ static const struct bpf_func_proto bpf_lua_toboolean_proto = { }; BPF_CALL_2(bpf_lua_tointeger, struct xdp_buff *, ctx, int, index) { + verify_and_lock(); return lua_tointeger(ctx->L, index); } @@ -6161,8 +6172,6 @@ bpf_base_func_proto(enum bpf_func_id func_id) return &bpf_lua_pushskb_proto; case BPF_FUNC_lua_pushstring: return &bpf_lua_pushstring_proto; - case BPF_FUNC_lua_setstate: - return &bpf_lua_setstate_proto; case BPF_FUNC_lua_toboolean: return &bpf_lua_toboolean_proto; case BPF_FUNC_lua_tointeger: diff --git a/samples/bpf/xdplua_map_kern.c b/samples/bpf/xdplua_map_kern.c index 11f00033204e0c..d4acad373e8b4f 100644 --- a/samples/bpf/xdplua_map_kern.c +++ b/samples/bpf/xdplua_map_kern.c @@ -27,7 +27,6 @@ int xdp_lua_test_map_prog(struct xdp_md *ctx) char lookupname[] = "lookup"; char updatename[] = "update"; - bpf_lua_setstate(ctx); bpf_lua_pushmap(ctx, &lua_test_map); bpf_lua_pcall(ctx, updatename, 1, 0); diff --git a/tools/include/uapi/linux/bpf.h b/tools/include/uapi/linux/bpf.h index cb14acfb1a388d..2969135c5a642d 100644 --- a/tools/include/uapi/linux/bpf.h +++ b/tools/include/uapi/linux/bpf.h @@ -2951,10 +2951,6 @@ union bpf_attr { * so the memory at s can be freed or reused immediately after the * function returns. * - * void bpf_lua_setstate(void *ctx) - * Description - * Sets the Lua state pointer in the context struct - * * int bpf_lua_toboolean(void *ctx, int index) * Description * Converts the Lua value at the given index to a C @@ -3103,7 +3099,6 @@ union bpf_attr { FN(lua_pushmap), \ FN(lua_pushskb), \ FN(lua_pushstring), \ - FN(lua_setstate), \ FN(lua_toboolean), \ FN(lua_tointeger), /* #endif CONFIG_XDP_LUA */ From e20f35804d80a6489127577ef00b787730bf942a Mon Sep 17 00:00:00 2001 From: Victor Nogueira Date: Wed, 19 Feb 2020 21:14:48 -0300 Subject: [PATCH 08/18] add LuaUnpack submodule --- .gitmodules | 3 +++ include/uapi/linux/bpf.h | 3 ++- lib/Makefile | 3 ++- lib/luaunpack | 1 + net/core/Makefile | 2 +- net/core/filter.c | 21 +++++++++++++++++++++ tools/include/uapi/linux/bpf.h | 8 +++++++- 7 files changed, 37 insertions(+), 4 deletions(-) create mode 160000 lib/luaunpack diff --git a/.gitmodules b/.gitmodules index d17f05c06fdfa0..3b57405d4b5084 100644 --- a/.gitmodules +++ b/.gitmodules @@ -10,3 +10,6 @@ [submodule "lib/luarcu"] path = lib/luarcu url = https://github.com/luainkernel/luarcu +[submodule "lib/luaunpack"] + path = lib/luaunpack + url = https://github.com/VictorNogueiraRio/luaunpack.git diff --git a/include/uapi/linux/bpf.h b/include/uapi/linux/bpf.h index 2969135c5a642d..73f68a87e012b3 100644 --- a/include/uapi/linux/bpf.h +++ b/include/uapi/linux/bpf.h @@ -3100,7 +3100,8 @@ union bpf_attr { FN(lua_pushskb), \ FN(lua_pushstring), \ FN(lua_toboolean), \ - FN(lua_tointeger), + FN(lua_tointeger), \ + FN(lua_newpacket), /* #endif CONFIG_XDP_LUA */ /* integer value in 'imm' field of BPF_CALL instruction selects which helper diff --git a/lib/Makefile b/lib/Makefile index 00fc7d38fcc89d..4b7d3b75bdc196 100644 --- a/lib/Makefile +++ b/lib/Makefile @@ -301,9 +301,10 @@ obj-$(CONFIG_OBJAGG) += objagg.o # KUnit tests obj-$(CONFIG_LIST_KUNIT_TEST) += list-test.o subdir-ccflags-y += -I$(srctree)/lib/lunatik/lua \ - -I$(srctree)/lib/luadata/ \ + -I$(srctree)/lib/luadata/ -I$(srctree)/lib/luaunpack/ \ -D_KERNEL obj-$(CONFIG_LUNATIK) += lunatik/ obj-$(CONFIG_LUADATA) += luadata/ obj-$(CONFIG_LUAXDP) += luaxdp/ obj-$(CONFIG_LUARCU) += luarcu/ +obj-$(CONFIG_LUAUNPACK) += luaunpack/ diff --git a/lib/luaunpack b/lib/luaunpack new file mode 160000 index 00000000000000..0589fc254bedaa --- /dev/null +++ b/lib/luaunpack @@ -0,0 +1 @@ +Subproject commit 0589fc254bedaa648042710a539a1db8cfa3445d diff --git a/net/core/Makefile b/net/core/Makefile index 72be363912fb2c..313adb01e8e22e 100644 --- a/net/core/Makefile +++ b/net/core/Makefile @@ -11,7 +11,7 @@ obj-$(CONFIG_SYSCTL) += sysctl_net_core.o CFLAGS_dev.o = -Ilib/lunatik/lua/ -D_KERNEL \ -Ilib/luadata/ CFLAGS_filter.o = -Ilib/lunatik/lua/ -D_KERNEL \ - -Ilib/luadata/ + -Ilib/luadata/ -Ilib/luaunpack/ obj-y += dev.o dev_addr_lists.o dst.o netevent.o \ neighbour.o rtnetlink.o utils.o link_watch.o filter.o \ sock_diag.o dev_ioctl.o tso.o sock_reuseport.o \ diff --git a/net/core/filter.c b/net/core/filter.c index e79e7279f7a0c5..91cc01b27a28a6 100644 --- a/net/core/filter.c +++ b/net/core/filter.c @@ -77,6 +77,7 @@ #ifdef CONFIG_XDP_LUA #include #include +#include #endif /* CONFIG_XDP_LUA */ /** @@ -6073,6 +6074,24 @@ static const struct bpf_func_proto bpf_lua_tointeger_proto = { .arg1_type = ARG_PTR_TO_CTX, .arg2_type = ARG_ANYTHING, }; + +BPF_CALL_2(bpf_lua_newpacket, struct xdp_buff *, ctx, int, offset) { + if (offset + ctx->data < ctx->data_end) { + return lunpack_newpacket(ctx->L, ctx->data + offset, + ctx->data_end - ctx->data - offset); + } + + return -EINVAL; +} + +static const struct bpf_func_proto bpf_lua_newpacket_proto = { + .func = bpf_lua_newpacket, + .gpl_only = false, + .pkt_access = false, + .ret_type = RET_INTEGER, + .arg1_type = ARG_PTR_TO_CTX, + .arg2_type = ARG_ANYTHING, +}; #endif /* CONFIG_XDP_LUA */ bool bpf_helper_changes_pkt_data(void *func) @@ -6176,6 +6195,8 @@ bpf_base_func_proto(enum bpf_func_id func_id) return &bpf_lua_toboolean_proto; case BPF_FUNC_lua_tointeger: return &bpf_lua_tointeger_proto; + case BPF_FUNC_lua_newpacket: + return &bpf_lua_newpacket_proto; #endif /* CONFIG_XDP_LUA */ default: return NULL; diff --git a/tools/include/uapi/linux/bpf.h b/tools/include/uapi/linux/bpf.h index 2969135c5a642d..2511d90ff8270d 100644 --- a/tools/include/uapi/linux/bpf.h +++ b/tools/include/uapi/linux/bpf.h @@ -2967,6 +2967,11 @@ union bpf_attr { * The converted Lua value at the given index, if the value is * convertible to an integer(see the Lua manual for more details * on type conversion); otherwise returns 0 + * + * void bpf_lua_newpacket(void *ctx, int offset) + * Description + * Create new luaunpack user data buffer pointing to + * the captured packet at the specified offset */ #define __BPF_FUNC_MAPPER(FN) \ FN(unspec), \ @@ -3100,7 +3105,8 @@ union bpf_attr { FN(lua_pushskb), \ FN(lua_pushstring), \ FN(lua_toboolean), \ - FN(lua_tointeger), + FN(lua_tointeger), \ + FN(lua_newpacket), /* #endif CONFIG_XDP_LUA */ /* integer value in 'imm' field of BPF_CALL instruction selects which helper From 36ceb19aa0ce55e9cedb29b2f99e58555c84b66c Mon Sep 17 00:00:00 2001 From: Victor Nogueira Date: Mon, 3 Feb 2020 18:57:06 -0300 Subject: [PATCH 09/18] Add bpf_lua_tostring function --- include/uapi/linux/bpf.h | 12 +++++++++++- net/core/filter.c | 22 ++++++++++++++++++++++ tools/include/uapi/linux/bpf.h | 12 +++++++++++- 3 files changed, 44 insertions(+), 2 deletions(-) diff --git a/include/uapi/linux/bpf.h b/include/uapi/linux/bpf.h index 73f68a87e012b3..09587ebe1259f9 100644 --- a/include/uapi/linux/bpf.h +++ b/include/uapi/linux/bpf.h @@ -2967,6 +2967,15 @@ union bpf_attr { * The converted Lua value at the given index, if the value is * convertible to an integer(see the Lua manual for more details * on type conversion); otherwise returns 0 + * + * void bpf_lua_tostring(void *ctx, const char *str, u32 size, int index) + * Description + * 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 + * 1 if the value at the given index of the Lua stack is a + * string; otherwise it returns 0 */ #define __BPF_FUNC_MAPPER(FN) \ FN(unspec), \ @@ -3101,7 +3110,8 @@ union bpf_attr { FN(lua_pushstring), \ FN(lua_toboolean), \ FN(lua_tointeger), \ - FN(lua_newpacket), + FN(lua_newpacket), \ + FN(lua_tostring), /* #endif CONFIG_XDP_LUA */ /* integer value in 'imm' field of BPF_CALL instruction selects which helper diff --git a/net/core/filter.c b/net/core/filter.c index 91cc01b27a28a6..a0c5a1b416d9cd 100644 --- a/net/core/filter.c +++ b/net/core/filter.c @@ -6092,6 +6092,26 @@ static const struct bpf_func_proto bpf_lua_newpacket_proto = { .arg1_type = ARG_PTR_TO_CTX, .arg2_type = ARG_ANYTHING, }; + +BPF_CALL_4(bpf_lua_tostring, struct xdp_buff *, ctx, char *, str, u32, size, int, index) { + if (lua_isstring(ctx->L, index)) { + strncpy(str, lua_tostring(ctx->L, index), size); + return 1; + } + + return 0; +} + +static const struct bpf_func_proto bpf_lua_tostring_proto = { + .func = bpf_lua_tostring, + .gpl_only = false, + .pkt_access = false, + .ret_type = RET_INTEGER, + .arg1_type = ARG_PTR_TO_CTX, + .arg2_type = ARG_PTR_TO_UNINIT_MEM, + .arg3_type = ARG_CONST_SIZE, + .arg4_type = ARG_ANYTHING, +}; #endif /* CONFIG_XDP_LUA */ bool bpf_helper_changes_pkt_data(void *func) @@ -6197,6 +6217,8 @@ bpf_base_func_proto(enum bpf_func_id func_id) return &bpf_lua_tointeger_proto; case BPF_FUNC_lua_newpacket: return &bpf_lua_newpacket_proto; + case BPF_FUNC_lua_tostring: + return &bpf_lua_tostring_proto; #endif /* CONFIG_XDP_LUA */ default: return NULL; diff --git a/tools/include/uapi/linux/bpf.h b/tools/include/uapi/linux/bpf.h index 2511d90ff8270d..b5c7c1075abfcf 100644 --- a/tools/include/uapi/linux/bpf.h +++ b/tools/include/uapi/linux/bpf.h @@ -2972,6 +2972,15 @@ union bpf_attr { * Description * Create new luaunpack user data buffer pointing to * the captured packet at the specified offset + * + * void bpf_lua_tostring(void *ctx, const char *str, u32 size, int index) + * Description + * 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 + * 1 if the value at the given index of the Lua stack is a + * string; otherwise it returns 0 */ #define __BPF_FUNC_MAPPER(FN) \ FN(unspec), \ @@ -3106,7 +3115,8 @@ union bpf_attr { FN(lua_pushstring), \ FN(lua_toboolean), \ FN(lua_tointeger), \ - FN(lua_newpacket), + FN(lua_newpacket), \ + FN(lua_tostring), /* #endif CONFIG_XDP_LUA */ /* integer value in 'imm' field of BPF_CALL instruction selects which helper From 040b06bede0a5f5a9d758bc3d6d2ee19b6256fcb Mon Sep 17 00:00:00 2001 From: Victor Nogueira Date: Tue, 3 Mar 2020 12:22:29 -0300 Subject: [PATCH 10/18] Add bpf_lua_type function --- include/uapi/linux/bpf.h | 17 ++++++++++++++++- net/core/filter.c | 15 +++++++++++++++ tools/include/uapi/linux/bpf.h | 17 ++++++++++++++++- 3 files changed, 47 insertions(+), 2 deletions(-) diff --git a/include/uapi/linux/bpf.h b/include/uapi/linux/bpf.h index 09587ebe1259f9..6cf025959b7036 100644 --- a/include/uapi/linux/bpf.h +++ b/include/uapi/linux/bpf.h @@ -2976,6 +2976,20 @@ union bpf_attr { * Return * 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) + * Description + * Obtains the type of the Lua value at the given index + * of the Lua stack + * + * Return + * Type of the value in the given valid index, + * or LUA_TNONE for a non-valid (but acceptable) index. + * The types returned by lua_type are coded by the + * 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. */ #define __BPF_FUNC_MAPPER(FN) \ FN(unspec), \ @@ -3111,7 +3125,8 @@ union bpf_attr { FN(lua_toboolean), \ FN(lua_tointeger), \ FN(lua_newpacket), \ - FN(lua_tostring), + FN(lua_tostring), \ + FN(lua_type), /* #endif CONFIG_XDP_LUA */ /* integer value in 'imm' field of BPF_CALL instruction selects which helper diff --git a/net/core/filter.c b/net/core/filter.c index a0c5a1b416d9cd..58dbe7361ef407 100644 --- a/net/core/filter.c +++ b/net/core/filter.c @@ -6112,6 +6112,19 @@ static const struct bpf_func_proto bpf_lua_tostring_proto = { .arg3_type = ARG_CONST_SIZE, .arg4_type = ARG_ANYTHING, }; + +BPF_CALL_2(bpf_lua_type, struct xdp_buff *, ctx, int, index) { + return lua_type(ctx->L, index); +} + +static const struct bpf_func_proto bpf_lua_type_proto = { + .func = bpf_lua_type, + .gpl_only = false, + .pkt_access = false, + .ret_type = RET_INTEGER, + .arg1_type = ARG_PTR_TO_CTX, + .arg2_type = ARG_ANYTHING, +}; #endif /* CONFIG_XDP_LUA */ bool bpf_helper_changes_pkt_data(void *func) @@ -6219,6 +6232,8 @@ bpf_base_func_proto(enum bpf_func_id func_id) return &bpf_lua_newpacket_proto; case BPF_FUNC_lua_tostring: return &bpf_lua_tostring_proto; + case BPF_FUNC_lua_type: + return &bpf_lua_type_proto; #endif /* CONFIG_XDP_LUA */ default: return NULL; diff --git a/tools/include/uapi/linux/bpf.h b/tools/include/uapi/linux/bpf.h index b5c7c1075abfcf..ac03e6ab79b5d0 100644 --- a/tools/include/uapi/linux/bpf.h +++ b/tools/include/uapi/linux/bpf.h @@ -2981,6 +2981,20 @@ union bpf_attr { * Return * 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) + * Description + * Obtains the type of the Lua value at the given index + * of the Lua stack + * + * Return + * Type of the value in the given valid index, + * or LUA_TNONE for a non-valid (but acceptable) index. + * The types returned by lua_type are coded by the + * 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. */ #define __BPF_FUNC_MAPPER(FN) \ FN(unspec), \ @@ -3116,7 +3130,8 @@ union bpf_attr { FN(lua_toboolean), \ FN(lua_tointeger), \ FN(lua_newpacket), \ - FN(lua_tostring), + FN(lua_tostring), \ + FN(lua_type), /* #endif CONFIG_XDP_LUA */ /* integer value in 'imm' field of BPF_CALL instruction selects which helper From 50e056a2ce53a4b2c7f752f7e61765d9f1571cd4 Mon Sep 17 00:00:00 2001 From: Victor Nogueira Date: Sun, 26 Apr 2020 19:30:03 -0300 Subject: [PATCH 11/18] Add javascript challenge sample --- samples/bpf/Makefile | 1 + samples/bpf/checkcookie.lua | 51 +++++++++++++++++ samples/bpf/xdplua_cookie_kern.c | 97 ++++++++++++++++++++++++++++++++ 3 files changed, 149 insertions(+) create mode 100644 samples/bpf/checkcookie.lua create mode 100644 samples/bpf/xdplua_cookie_kern.c diff --git a/samples/bpf/Makefile b/samples/bpf/Makefile index 4b173a2de502f8..b61166a4431769 100644 --- a/samples/bpf/Makefile +++ b/samples/bpf/Makefile @@ -176,6 +176,7 @@ always-y += hbm_edt_kern.o always-y += xdpsock_kern.o # CONFIG_XDP_LUA always-y += xdplua_map_kern.o +always-y += xdplua_cookie_kern.o ifeq ($(ARCH), arm) # Strip all except -D__LINUX_ARM_ARCH__ option needed to handle linux diff --git a/samples/bpf/checkcookie.lua b/samples/bpf/checkcookie.lua new file mode 100644 index 00000000000000..9f8e111cc88112 --- /dev/null +++ b/samples/bpf/checkcookie.lua @@ -0,0 +1,51 @@ +-- +-- Copyright (C) 2020 ring-0 Ltda +-- +-- This program is free software; you can redistribute it and/or +-- modify it under the terms of the GNU General Public License as +-- published by the Free Software Foundation version 2. +-- +-- This program is distributed "as is" WITHOUT ANY WARRANTY of any +-- kind, whether express or implied; without even the implied warranty +-- of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +-- GNU General Public License for more details. +-- +cookies = {} + +local function ip2int(ip) + local oct1, oct2, oct3, oct4 = ip:match("(%d+)%.(%d+)%.(%d+)%.(%d+)") + return (oct4 << 24) + (oct3 << 16) + (oct2 << 8) + oct1 +end + +function loadcookieport(ip, port, cookie) + local ip = ip2int(ip) + + if not cookies[ip] then + cookies[ip] = {} + end + + cookies[ip][port] = cookie +end + +function loadcookie(ip, cookie) + cookies[ip2int(ip)] = cookie +end + +function checkcookieport(pkt, ip, port) + local cookiepkt = tonumber(string.match(tostring(pkt), "Cookie:%s__xdp=(.-)\r\n")) + if not cookies[ip] then + return true + end + + if not cookies[ip][port] then + return true + end + + return cookies[ip][port] == cookiepkt and true or false +end + +function checkcookie(pkt, ip) + local cookiepkt = tonumber(string.match(tostring(pkt), "Cookie:%s__xdp=(.-)\r\n")) + + return cookies[ip] == cookiepkt and true or false +end diff --git a/samples/bpf/xdplua_cookie_kern.c b/samples/bpf/xdplua_cookie_kern.c new file mode 100644 index 00000000000000..c867192da7b55e --- /dev/null +++ b/samples/bpf/xdplua_cookie_kern.c @@ -0,0 +1,97 @@ +/* + * Copyright (C) 2020 ring-0 Ltda + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation version 2. + * + * This program is distributed "as is" WITHOUT ANY WARRANTY of any + * kind, whether express or implied; without even the implied warranty + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ +#define KBUILD_MODNAME "foo" +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define HTTPDSTPORT 80 + +static int parse_tcp(struct xdp_md *ctx, void *data, uint64_t tp_off, + void *data_end, __be32 saddr) { + + struct tcphdr *tcp = data + tp_off; + char cookiefunc[] = "checkcookie"; + int data_ref; + + if (tcp + 1 > data_end) + return XDP_PASS; + + if (tcp->dest == htons(HTTPDSTPORT)) { + bool verdict; + data_ref = bpf_lua_dataref(ctx, tp_off + tcp->doff * 4); + if (data_ref < 0) + return XDP_PASS; + + bpf_lua_pushinteger(ctx, saddr); + + bpf_lua_pcall(ctx, cookiefunc, 2, 1); + + verdict = bpf_lua_toboolean(ctx, -1); + + return verdict ? XDP_PASS : XDP_DROP; + } + + return XDP_PASS; +} + +static inline u64 parse_ipv4(struct xdp_md *ctx, void *data, u64 nh_off, void *data_end, __be32 *saddr) +{ + struct iphdr *iph = data + nh_off; + + if (iph + 1 > data_end) + return -1; + + nh_off += iph->ihl * 4; + + *saddr = iph->saddr; + + return nh_off; +} + +SEC("xdplua_cookie") +int xdp_lua_cookie_prog(struct xdp_md *ctx) +{ + void *data_end = (void *)(long)ctx->data_end; + void *data = (void *)(long)ctx->data; + int rc = XDP_PASS; + struct ethhdr *eth = data; + u16 h_proto; + u64 nh_off; + u64 ip_off; + u_int8_t protonum; + int verdict; + __be32 saddr; + + nh_off = sizeof(*eth); + if (data + nh_off > data_end) + return rc; + + h_proto = eth->h_proto; + if (h_proto != htons(ETH_P_IP)) + return rc; + + ip_off = parse_ipv4(ctx, data, nh_off, data_end, &saddr); + if (ip_off == -1) + return rc; + + return parse_tcp(ctx, data, ip_off, data_end, saddr); +} + +char _license[] SEC("license") = "GPL"; From b6ca1323b6555523fef4da71573d406f7240c5ae Mon Sep 17 00:00:00 2001 From: Victor Nogueira Date: Tue, 11 Aug 2020 13:18:28 -0300 Subject: [PATCH 12/18] Improve xdplua_user's packet counting --- samples/bpf/xdplua_user.c | 35 ++++++++++++++++++++++++++--------- 1 file changed, 26 insertions(+), 9 deletions(-) diff --git a/samples/bpf/xdplua_user.c b/samples/bpf/xdplua_user.c index 1e696aa0744e29..fef4c53356fb0a 100644 --- a/samples/bpf/xdplua_user.c +++ b/samples/bpf/xdplua_user.c @@ -38,7 +38,9 @@ static void usage(const char *prog) { " -p eBPF program path\n" " -i iface\n" " -m monitor\n" - " -s lua script\n", + " -s lua script\n" + " -I Interval\n" + " -D Duration\n", prog); } @@ -103,13 +105,19 @@ static int do_detach(int idx, const char *name) return err; } -static void poll(int map_fd, int interval) { - long cnt; +static void poll(int map_fd, int interval, int duration) { + unsigned int nr_cpus = bpf_num_possible_cpus(); + long cnts[nr_cpus]; unsigned int key = 0; - while(1) { - bpf_map_lookup_elem(map_fd, &key, &cnt); - printf("pkt count: %lu\n", cnt); + for (int i = 0; i < duration; i++) { + unsigned long cnt = 0; + int i; + bpf_map_lookup_elem(map_fd, &key, cnts); + for (i = 0; i < nr_cpus; ++i) { + cnt += cnts[i]; + } + printf("%lu\n", cnt); sleep(interval); } } @@ -123,9 +131,11 @@ int main(int argc, char *argv[]) struct bpf_object *obj; int opt, prog_fd; int rx_cnt_map_fd; - int detach = 0, attach_lua = 0, attach_ebpf = 0, monitor = 0, attach_script = 0; + int detach = 0, attach_lua = 0, attach_ebpf = 0, monitor = 0, attach_script = 0, + interval = 1, duration = 1; + char *lua_prog = NULL; - const char *optstr = "f:p:i:dms:"; + const char *optstr = "f:p:i:dms:I:D:"; struct bpf_prog_load_attr prog_load_attr = { .prog_type = BPF_PROG_TYPE_XDP, }; @@ -158,12 +168,19 @@ int main(int argc, char *argv[]) "%s", optarg); attach_script = 1; break; + case 'I': + interval = atoi(optarg); + break; + case 'D': + duration = atoi(optarg); + break; default: usage(basename(argv[0])); return 1; } } + if (attach_ebpf || detach) { if (!ifindex) { printf("ERROR: invalid interface name"); @@ -219,7 +236,7 @@ int main(int argc, char *argv[]) if (monitor) { rx_cnt_map_fd = bpf_object__find_map_fd_by_name(obj, "rx_cnt"); - poll(rx_cnt_map_fd, 1); + poll(rx_cnt_map_fd, interval, duration); } return 0; } From 2eebe240100db5c57b6d922f9e67a9e7ff07ad77 Mon Sep 17 00:00:00 2001 From: Victor Nogueira Date: Tue, 11 Aug 2020 13:22:04 -0300 Subject: [PATCH 13/18] fixup! Add javascript challenge sample --- samples/bpf/checkcookie.lua | 26 ++++---------------------- 1 file changed, 4 insertions(+), 22 deletions(-) diff --git a/samples/bpf/checkcookie.lua b/samples/bpf/checkcookie.lua index 9f8e111cc88112..734e775dfdc696 100644 --- a/samples/bpf/checkcookie.lua +++ b/samples/bpf/checkcookie.lua @@ -17,35 +17,17 @@ local function ip2int(ip) return (oct4 << 24) + (oct3 << 16) + (oct2 << 8) + oct1 end -function loadcookieport(ip, port, cookie) - local ip = ip2int(ip) - - if not cookies[ip] then - cookies[ip] = {} - end - - cookies[ip][port] = cookie -end - function loadcookie(ip, cookie) cookies[ip2int(ip)] = cookie end -function checkcookieport(pkt, ip, port) - local cookiepkt = tonumber(string.match(tostring(pkt), "Cookie:%s__xdp=(.-)\r\n")) - if not cookies[ip] then - return true - end +function checkcookie(pkt, ip) + local pattern = 'Cookie:%s*=__xdp=(%d+)%s*' + local cookiepkt = tonumber(string.match(tostring(pkt), pattern)) - if not cookies[ip][port] then + if not cookies[ip] then return true end - return cookies[ip][port] == cookiepkt and true or false -end - -function checkcookie(pkt, ip) - local cookiepkt = tonumber(string.match(tostring(pkt), "Cookie:%s__xdp=(.-)\r\n")) - return cookies[ip] == cookiepkt and true or false end From a7684997b01785d464be7050ca8f807212f99911 Mon Sep 17 00:00:00 2001 From: Victor Nogueira Date: Fri, 14 Aug 2020 01:11:32 -0300 Subject: [PATCH 14/18] fixup! add XDPLua --- net/core/filter.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/net/core/filter.c b/net/core/filter.c index 58dbe7361ef407..ae19e3274f2190 100644 --- a/net/core/filter.c +++ b/net/core/filter.c @@ -5999,7 +5999,7 @@ static const struct bpf_func_proto bpf_lua_pushmap_proto = { .pkt_access = false, .ret_type = RET_VOID, .arg1_type = ARG_PTR_TO_CTX, - .arg2_type = ARG_ANYTHING, + .arg2_type = ARG_CONST_MAP_PTR, }; BPF_CALL_3(bpf_lua_pushlstring, struct xdp_buff *, ctx, const char *, str, size_t, len) { From 5e89868e94080f64a62d15b9c07d87af56be6150 Mon Sep 17 00:00:00 2001 From: Victor Nogueira Date: Sun, 23 Aug 2020 12:44:53 -0300 Subject: [PATCH 15/18] fixup! add Lunatik submodule --- lib/lunatik | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/lunatik b/lib/lunatik index fb7ef47c930b54..0574a8d89b8670 160000 --- a/lib/lunatik +++ b/lib/lunatik @@ -1 +1 @@ -Subproject commit fb7ef47c930b544804f544654302dac673a6ca48 +Subproject commit 0574a8d89b86709e132fbb3ea5814e247e74e083 From deac020160ef7b87bd9704f73dc00b786efac6b7 Mon Sep 17 00:00:00 2001 From: Victor Nogueira Date: Mon, 24 Aug 2020 15:38:47 -0300 Subject: [PATCH 16/18] fixup! add XDPLua --- include/uapi/linux/bpf.h | 2 +- tools/include/uapi/linux/bpf.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/include/uapi/linux/bpf.h b/include/uapi/linux/bpf.h index 6cf025959b7036..776f4bd891e764 100644 --- a/include/uapi/linux/bpf.h +++ b/include/uapi/linux/bpf.h @@ -2977,7 +2977,7 @@ union bpf_attr { * 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) + * int bpf_lua_type(void *ctx, int index) * Description * Obtains the type of the Lua value at the given index * of the Lua stack diff --git a/tools/include/uapi/linux/bpf.h b/tools/include/uapi/linux/bpf.h index ac03e6ab79b5d0..ac4265e5d039e9 100644 --- a/tools/include/uapi/linux/bpf.h +++ b/tools/include/uapi/linux/bpf.h @@ -2982,7 +2982,7 @@ union bpf_attr { * 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) + * int bpf_lua_type(void *ctx, int index) * Description * Obtains the type of the Lua value at the given index * of the Lua stack From 114485ee5b42b170e85ad1bc2ffbda3baf0e8831 Mon Sep 17 00:00:00 2001 From: Victor Nogueira Date: Sun, 13 Sep 2020 20:17:36 -0300 Subject: [PATCH 17/18] fixup! add XDPLua --- net/core/filter.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/net/core/filter.c b/net/core/filter.c index ae19e3274f2190..23bd78481fe84e 100644 --- a/net/core/filter.c +++ b/net/core/filter.c @@ -5957,9 +5957,9 @@ static const struct bpf_func_proto bpf_lua_pop_proto = { .arg2_type = ARG_ANYTHING, }; -BPF_CALL_2(bpf_lua_pushinteger, struct xdp_buff *, ctx, int, num) { +BPF_CALL_2(bpf_lua_pushinteger, struct xdp_buff *, ctx, lua_Integer, integer) { verify_and_lock(); - lua_pushinteger(ctx->L, num); + lua_pushinteger(ctx->L, integer); return 0; } From 234a3d6a7bcbdf15b935a1b61764dd692741f2ca Mon Sep 17 00:00:00 2001 From: Victor Nogueira Date: Sun, 20 Sep 2020 22:55:28 -0300 Subject: [PATCH 18/18] fixup! add LuaXDP submodule --- lib/luaxdp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/luaxdp b/lib/luaxdp index 64216b7daa8e11..be34f8706d3c96 160000 --- a/lib/luaxdp +++ b/lib/luaxdp @@ -1 +1 @@ -Subproject commit 64216b7daa8e114c97c94c1da31472097cbb9343 +Subproject commit be34f8706d3c96e1cdb61015c37bc0dd83aeb75b