Skip to content

Commit 8d652aa

Browse files
add XDPLua
1 parent 6342d77 commit 8d652aa

16 files changed

Lines changed: 708 additions & 2 deletions

File tree

include/linux/filter.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1113,4 +1113,13 @@ struct bpf_sock_ops_kern {
11131113
*/
11141114
};
11151115

1116+
#ifdef CONFIG_XDP_LUA
1117+
extern struct list_head lua_state_cpu_list;
1118+
1119+
struct lua_state_cpu {
1120+
struct lua_State *L;
1121+
int cpu;
1122+
struct list_head list;
1123+
};
1124+
#endif /* CONFIG_XDP_LUA */
11161125
#endif /* __LINUX_FILTER_H__ */

include/linux/netdevice.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3587,6 +3587,10 @@ u32 __dev_xdp_query(struct net_device *dev, bpf_op_t xdp_op,
35873587
enum bpf_netdev_command cmd);
35883588
int xdp_umem_query(struct net_device *dev, u16 queue_id);
35893589

3590+
#ifdef CONFIG_XDP_LUA
3591+
int generic_xdp_lua_install_prog(char *lua_prog);
3592+
#endif /* CONFIG_XDP_LUA */
3593+
35903594
int __dev_forward_skb(struct net_device *dev, struct sk_buff *skb);
35913595
int dev_forward_skb(struct net_device *dev, struct sk_buff *skb);
35923596
bool is_skb_forwardable(const struct net_device *dev,

include/net/xdp.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,10 @@ struct xdp_buff {
7070
void *data_hard_start;
7171
unsigned long handle;
7272
struct xdp_rxq_info *rxq;
73+
#ifdef CONFIG_XDP_LUA
74+
struct sk_buff *skb;
75+
struct lua_State *L;
76+
#endif /* CONFIG_XDP_LUA */
7377
};
7478

7579
struct xdp_frame {

include/uapi/linux/bpf.h

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2226,7 +2226,20 @@ union bpf_attr {
22262226
FN(get_current_cgroup_id), \
22272227
FN(get_local_storage), \
22282228
FN(sk_select_reuseport), \
2229-
FN(skb_ancestor_cgroup_id),
2229+
FN(skb_ancestor_cgroup_id), \
2230+
/* #ifdef CONFIG_XDP_LUA */ \
2231+
FN(lua_pcall), \
2232+
FN(lua_pop), \
2233+
FN(lua_pushinteger), \
2234+
FN(lua_pushlightuserdata), \
2235+
FN(lua_pushlstring), \
2236+
FN(lua_pushmap), \
2237+
FN(lua_pushskb), \
2238+
FN(lua_pushstring), \
2239+
FN(lua_setstate), \
2240+
FN(lua_toboolean), \
2241+
FN(lua_tointeger),
2242+
/* #endif CONFIG_XDP_LUA */
22302243

22312244
/* integer value in 'imm' field of BPF_CALL instruction selects which helper
22322245
* function eBPF program intends to call

include/uapi/linux/if_link.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -945,6 +945,9 @@ enum {
945945
IFLA_XDP_DRV_PROG_ID,
946946
IFLA_XDP_SKB_PROG_ID,
947947
IFLA_XDP_HW_PROG_ID,
948+
#ifdef CONFIG_XDP_LUA
949+
IFLA_XDP_LUA_PROG,
950+
#endif /* CONFIG_XDP_LUA */
948951
__IFLA_XDP_MAX,
949952
};
950953

net/core/dev.c

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,12 @@
7272
* - netif_rx() feedback
7373
*/
7474

75+
#ifdef CONFIG_XDP_LUA
76+
#include <lua.h>
77+
#include <lauxlib.h>
78+
#include <lualib.h>
79+
#endif /* CONFIG_XDP_LUA */
80+
7581
#include <linux/uaccess.h>
7682
#include <linux/bitops.h>
7783
#include <linux/capability.h>
@@ -164,6 +170,10 @@ static int call_netdevice_notifiers_info(unsigned long val,
164170
struct netdev_notifier_info *info);
165171
static struct napi_struct *napi_by_id(unsigned int napi_id);
166172

173+
#ifdef CONFIG_XDP_LUA
174+
struct list_head lua_state_cpu_list;
175+
#endif /* CONFIG_XDP_LUA */
176+
167177
/*
168178
* The @dev_base_head list is protected by @dev_base_lock and the rtnl
169179
* semaphore.
@@ -4320,6 +4330,9 @@ static u32 netif_receive_generic_xdp(struct sk_buff *skb,
43204330

43214331
rxqueue = netif_get_rxqueue(skb);
43224332
xdp->rxq = &rxqueue->xdp_rxq;
4333+
#ifdef CONFIG_XDP_LUA
4334+
xdp->skb = skb;
4335+
#endif /* CONFIG_XDP_LUA */
43234336

43244337
act = bpf_prog_run_xdp(xdp_prog, xdp);
43254338

@@ -5088,6 +5101,22 @@ static int generic_xdp_install(struct net_device *dev, struct netdev_bpf *xdp)
50885101
return ret;
50895102
}
50905103

5104+
#ifdef CONFIG_XDP_LUA
5105+
int generic_xdp_lua_install_prog(char *lua_prog)
5106+
{
5107+
struct lua_state_cpu *sc;
5108+
5109+
list_for_each_entry(sc, &lua_state_cpu_list, list) {
5110+
if (luaL_dostring(sc->L, lua_prog)) {
5111+
pr_err(KERN_INFO "error: %s\nOn cpu: %d\n",
5112+
lua_tostring(sc->L, -1), sc->cpu);
5113+
return -EINVAL;
5114+
}
5115+
}
5116+
return 0;
5117+
}
5118+
#endif /* CONFIG_XDP_LUA */
5119+
50915120
static int netif_receive_skb_internal(struct sk_buff *skb)
50925121
{
50935122
int ret;
@@ -9570,6 +9599,9 @@ static struct pernet_operations __net_initdata default_device_ops = {
95709599
static int __init net_dev_init(void)
95719600
{
95729601
int i, rc = -ENOMEM;
9602+
#ifdef CONFIG_XDP_LUA
9603+
struct lua_state_cpu *new_state_cpu;
9604+
#endif /* CONFIG_XDP_LUA */
95739605

95749606
BUG_ON(!dev_boot_phase);
95759607

@@ -9584,6 +9616,9 @@ static int __init net_dev_init(void)
95849616
INIT_LIST_HEAD(&ptype_base[i]);
95859617

95869618
INIT_LIST_HEAD(&offload_base);
9619+
#ifdef CONFIG_XDP_LUA
9620+
INIT_LIST_HEAD(&lua_state_cpu_list);
9621+
#endif /* CONFIG_XDP_LUA */
95879622

95889623
if (register_pernet_subsys(&netdev_net_ops))
95899624
goto out;
@@ -9614,6 +9649,25 @@ static int __init net_dev_init(void)
96149649
init_gro_hash(&sd->backlog);
96159650
sd->backlog.poll = process_backlog;
96169651
sd->backlog.weight = weight_p;
9652+
9653+
#ifdef CONFIG_XDP_LUA
9654+
new_state_cpu = (struct lua_state_cpu *)
9655+
kmalloc(sizeof(struct lua_state_cpu), GFP_ATOMIC);
9656+
if (!new_state_cpu)
9657+
continue;
9658+
9659+
new_state_cpu->L = luaL_newstate();
9660+
if (!new_state_cpu->L) {
9661+
kfree(new_state_cpu);
9662+
continue;
9663+
}
9664+
9665+
luaL_openlibs(new_state_cpu->L);
9666+
lua_pop(new_state_cpu->L, 1);
9667+
new_state_cpu->cpu = i;
9668+
9669+
list_add(&new_state_cpu->list, &lua_state_cpu_list);
9670+
#endif /* CONFIG_XDP_LUA */
96179671
}
96189672

96199673
dev_boot_phase = 0;

net/core/filter.c

Lines changed: 203 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,10 @@
6969
#include <net/seg6.h>
7070
#include <net/seg6_local.h>
7171

72+
#ifdef CONFIG_XDP_LUA
73+
#include <lua.h>
74+
#endif /* CONFIG_XDP_LUA */
75+
7276
/**
7377
* sk_filter_trim_cap - run a packet through a socket filter
7478
* @sk: sock associated with &sk_buff
@@ -4787,6 +4791,181 @@ static const struct bpf_func_proto bpf_lwt_seg6_adjust_srh_proto = {
47874791
};
47884792
#endif /* CONFIG_IPV6_SEG6_BPF */
47894793

4794+
#ifdef CONFIG_XDP_LUA
4795+
BPF_CALL_4(bpf_lua_pcall, struct xdp_buff *, ctx, char *, funcname,
4796+
int, num_args, int, num_rets) {
4797+
if (lua_getglobal(ctx->L, funcname) != LUA_TFUNCTION) {
4798+
pr_err("function %s not found\n", funcname);
4799+
lua_pop(ctx->L, num_args);
4800+
return 0;
4801+
}
4802+
4803+
lua_insert(ctx->L, 1);
4804+
if (lua_pcall(ctx->L, num_args, num_rets, 0)) {
4805+
pr_err("%s\n", lua_tostring(ctx->L, -1));
4806+
lua_pop(ctx->L, 1);
4807+
return 0;
4808+
}
4809+
return num_rets;
4810+
}
4811+
4812+
static const struct bpf_func_proto bpf_lua_pcall_proto = {
4813+
.func = bpf_lua_pcall,
4814+
.gpl_only = false,
4815+
.pkt_access = false,
4816+
.ret_type = RET_INTEGER,
4817+
.arg1_type = ARG_PTR_TO_CTX,
4818+
.arg2_type = ARG_ANYTHING,
4819+
.arg3_type = RET_INTEGER,
4820+
.arg4_type = RET_INTEGER,
4821+
};
4822+
4823+
BPF_CALL_2(bpf_lua_pop, struct xdp_buff *, ctx, int, index) {
4824+
lua_pop(ctx->L, index);
4825+
return 0;
4826+
}
4827+
4828+
static const struct bpf_func_proto bpf_lua_pop_proto = {
4829+
.func = bpf_lua_pop,
4830+
.gpl_only = false,
4831+
.pkt_access = false,
4832+
.ret_type = RET_VOID,
4833+
.arg1_type = ARG_PTR_TO_CTX,
4834+
.arg2_type = ARG_ANYTHING,
4835+
};
4836+
4837+
BPF_CALL_2(bpf_lua_pushinteger, struct xdp_buff *, ctx, int, num) {
4838+
lua_pushinteger(ctx->L, num);
4839+
return 0;
4840+
}
4841+
4842+
static const struct bpf_func_proto bpf_lua_pushinteger_proto = {
4843+
.func = bpf_lua_pushinteger,
4844+
.gpl_only = false,
4845+
.pkt_access = false,
4846+
.ret_type = RET_VOID,
4847+
.arg1_type = ARG_PTR_TO_CTX,
4848+
.arg2_type = ARG_ANYTHING,
4849+
};
4850+
4851+
BPF_CALL_2(bpf_lua_pushlightuserdata, struct xdp_buff *, ctx, void *, ptr) {
4852+
lua_pushlightuserdata(ctx->L, ptr);
4853+
return 0;
4854+
}
4855+
4856+
static const struct bpf_func_proto bpf_lua_pushlightuserdata_proto = {
4857+
.func = bpf_lua_pushlightuserdata,
4858+
.gpl_only = false,
4859+
.pkt_access = false,
4860+
.ret_type = RET_VOID,
4861+
.arg1_type = ARG_PTR_TO_CTX,
4862+
.arg2_type = ARG_ANYTHING,
4863+
};
4864+
4865+
BPF_CALL_3(bpf_lua_pushlstring, struct xdp_buff *, ctx, const char *, str, size_t, len) {
4866+
lua_pushlstring(ctx->L, str, len);
4867+
return 0;
4868+
}
4869+
4870+
static const struct bpf_func_proto bpf_lua_pushlstring_proto = {
4871+
.func = bpf_lua_pushlstring,
4872+
.gpl_only = false,
4873+
.pkt_access = false,
4874+
.ret_type = RET_VOID,
4875+
.arg1_type = ARG_PTR_TO_CTX,
4876+
.arg2_type = ARG_ANYTHING,
4877+
.arg3_type = ARG_ANYTHING,
4878+
};
4879+
4880+
BPF_CALL_2(bpf_lua_pushmap, struct xdp_buff *, ctx, struct bpf_map *, map) {
4881+
lua_pushlightuserdata(ctx->L, map);
4882+
return 0;
4883+
}
4884+
4885+
static const struct bpf_func_proto bpf_lua_pushmap_proto = {
4886+
.func = bpf_lua_pushmap,
4887+
.gpl_only = false,
4888+
.pkt_access = false,
4889+
.ret_type = RET_VOID,
4890+
.arg1_type = ARG_PTR_TO_CTX,
4891+
.arg2_type = ARG_ANYTHING,
4892+
};
4893+
4894+
BPF_CALL_1(bpf_lua_pushskb, struct xdp_buff *, ctx) {
4895+
lua_pushlightuserdata(ctx->L, ctx->skb);
4896+
return 0;
4897+
}
4898+
4899+
static const struct bpf_func_proto bpf_lua_pushskb_proto = {
4900+
.func = bpf_lua_pushskb,
4901+
.gpl_only = false,
4902+
.pkt_access = false,
4903+
.ret_type = RET_VOID,
4904+
.arg1_type = ARG_PTR_TO_CTX,
4905+
};
4906+
4907+
BPF_CALL_2(bpf_lua_pushstring, struct xdp_buff *, ctx, const char *, str) {
4908+
lua_pushstring(ctx->L, str);
4909+
return 0;
4910+
}
4911+
4912+
static const struct bpf_func_proto bpf_lua_pushstring_proto = {
4913+
.func = bpf_lua_pushstring,
4914+
.gpl_only = false,
4915+
.pkt_access = false,
4916+
.ret_type = RET_VOID,
4917+
.arg1_type = ARG_PTR_TO_CTX,
4918+
.arg2_type = ARG_ANYTHING,
4919+
};
4920+
4921+
BPF_CALL_1(bpf_lua_setstate, struct xdp_buff *, ctx){
4922+
struct lua_state_cpu *sc;
4923+
int cpu = smp_processor_id();
4924+
4925+
list_for_each_entry(sc, &lua_state_cpu_list, list) {
4926+
if (sc->cpu == cpu) {
4927+
ctx->L = sc->L;
4928+
break;
4929+
}
4930+
}
4931+
return 0;
4932+
}
4933+
4934+
static const struct bpf_func_proto bpf_lua_setstate_proto = {
4935+
.func = bpf_lua_setstate,
4936+
.gpl_only = false,
4937+
.pkt_access = false,
4938+
.ret_type = RET_VOID,
4939+
.arg1_type = ARG_PTR_TO_CTX,
4940+
};
4941+
4942+
BPF_CALL_2(bpf_lua_toboolean, struct xdp_buff *, ctx, int, index) {
4943+
return lua_toboolean(ctx->L, index);
4944+
}
4945+
4946+
static const struct bpf_func_proto bpf_lua_toboolean_proto = {
4947+
.func = bpf_lua_toboolean,
4948+
.gpl_only = false,
4949+
.pkt_access = false,
4950+
.ret_type = RET_INTEGER,
4951+
.arg1_type = ARG_PTR_TO_CTX,
4952+
.arg2_type = ARG_ANYTHING,
4953+
};
4954+
4955+
BPF_CALL_2(bpf_lua_tointeger, struct xdp_buff *, ctx, int, index) {
4956+
return lua_tointeger(ctx->L, index);
4957+
}
4958+
4959+
static const struct bpf_func_proto bpf_lua_tointeger_proto = {
4960+
.func = bpf_lua_tointeger,
4961+
.gpl_only = false,
4962+
.pkt_access = false,
4963+
.ret_type = RET_INTEGER,
4964+
.arg1_type = ARG_PTR_TO_CTX,
4965+
.arg2_type = ARG_ANYTHING,
4966+
};
4967+
#endif /* CONFIG_XDP_LUA */
4968+
47904969
bool bpf_helper_changes_pkt_data(void *func)
47914970
{
47924971
if (func == bpf_skb_vlan_push ||
@@ -4842,6 +5021,30 @@ bpf_base_func_proto(enum bpf_func_id func_id)
48425021
if (capable(CAP_SYS_ADMIN))
48435022
return bpf_get_trace_printk_proto();
48445023
/* else: fall through */
5024+
#ifdef CONFIG_XDP_LUA
5025+
case BPF_FUNC_lua_pcall:
5026+
return &bpf_lua_pcall_proto;
5027+
case BPF_FUNC_lua_pop:
5028+
return &bpf_lua_pop_proto;
5029+
case BPF_FUNC_lua_pushinteger:
5030+
return &bpf_lua_pushinteger_proto;
5031+
case BPF_FUNC_lua_pushlightuserdata:
5032+
return &bpf_lua_pushlightuserdata_proto;
5033+
case BPF_FUNC_lua_pushlstring:
5034+
return &bpf_lua_pushlstring_proto;
5035+
case BPF_FUNC_lua_pushmap:
5036+
return &bpf_lua_pushmap_proto;
5037+
case BPF_FUNC_lua_pushskb:
5038+
return &bpf_lua_pushskb_proto;
5039+
case BPF_FUNC_lua_pushstring:
5040+
return &bpf_lua_pushstring_proto;
5041+
case BPF_FUNC_lua_setstate:
5042+
return &bpf_lua_setstate_proto;
5043+
case BPF_FUNC_lua_toboolean:
5044+
return &bpf_lua_toboolean_proto;
5045+
case BPF_FUNC_lua_tointeger:
5046+
return &bpf_lua_tointeger_proto;
5047+
#endif /* CONFIG_XDP_LUA */
48455048
default:
48465049
return NULL;
48475050
}

0 commit comments

Comments
 (0)