|
74 | 74 | #include <net/ipv6_stubs.h> |
75 | 75 | #include <net/bpf_sk_storage.h> |
76 | 76 |
|
| 77 | +#ifdef CONFIG_XDPLUA |
| 78 | +#include <lua.h> |
| 79 | +#endif /* CONFIG_XDPLUA */ |
| 80 | + |
77 | 81 | /** |
78 | 82 | * sk_filter_trim_cap - run a packet through a socket filter |
79 | 83 | * @sk: sock associated with &sk_buff |
@@ -5852,6 +5856,181 @@ static const struct bpf_func_proto bpf_tcp_check_syncookie_proto = { |
5852 | 5856 |
|
5853 | 5857 | #endif /* CONFIG_INET */ |
5854 | 5858 |
|
| 5859 | +#ifdef CONFIG_XDPLUA |
| 5860 | +BPF_CALL_4(bpf_lua_pcall, struct xdp_buff *, ctx, char *, funcname, |
| 5861 | + int, num_args, int, num_rets) { |
| 5862 | + if (lua_getglobal(ctx->L, funcname) != LUA_TFUNCTION) { |
| 5863 | + pr_err("function %s not found\n", funcname); |
| 5864 | + lua_pop(ctx->L, num_args); |
| 5865 | + return 0; |
| 5866 | + } |
| 5867 | + |
| 5868 | + lua_insert(ctx->L, 1); |
| 5869 | + if (lua_pcall(ctx->L, num_args, num_rets, 0)) { |
| 5870 | + pr_err("%s\n", lua_tostring(ctx->L, -1)); |
| 5871 | + lua_pop(ctx->L, 1); |
| 5872 | + return 0; |
| 5873 | + } |
| 5874 | + return num_rets; |
| 5875 | +} |
| 5876 | + |
| 5877 | +static const struct bpf_func_proto bpf_lua_pcall_proto = { |
| 5878 | + .func = bpf_lua_pcall, |
| 5879 | + .gpl_only = false, |
| 5880 | + .pkt_access = false, |
| 5881 | + .ret_type = RET_INTEGER, |
| 5882 | + .arg1_type = ARG_PTR_TO_CTX, |
| 5883 | + .arg2_type = ARG_ANYTHING, |
| 5884 | + .arg3_type = RET_INTEGER, |
| 5885 | + .arg4_type = RET_INTEGER, |
| 5886 | +}; |
| 5887 | + |
| 5888 | +BPF_CALL_2(bpf_lua_pop, struct xdp_buff *, ctx, int, index) { |
| 5889 | + lua_pop(ctx->L, index); |
| 5890 | + return 0; |
| 5891 | +} |
| 5892 | + |
| 5893 | +static const struct bpf_func_proto bpf_lua_pop_proto = { |
| 5894 | + .func = bpf_lua_pop, |
| 5895 | + .gpl_only = false, |
| 5896 | + .pkt_access = false, |
| 5897 | + .ret_type = RET_VOID, |
| 5898 | + .arg1_type = ARG_PTR_TO_CTX, |
| 5899 | + .arg2_type = ARG_ANYTHING, |
| 5900 | +}; |
| 5901 | + |
| 5902 | +BPF_CALL_2(bpf_lua_pushinteger, struct xdp_buff *, ctx, int, num) { |
| 5903 | + lua_pushinteger(ctx->L, num); |
| 5904 | + return 0; |
| 5905 | +} |
| 5906 | + |
| 5907 | +static const struct bpf_func_proto bpf_lua_pushinteger_proto = { |
| 5908 | + .func = bpf_lua_pushinteger, |
| 5909 | + .gpl_only = false, |
| 5910 | + .pkt_access = false, |
| 5911 | + .ret_type = RET_VOID, |
| 5912 | + .arg1_type = ARG_PTR_TO_CTX, |
| 5913 | + .arg2_type = ARG_ANYTHING, |
| 5914 | +}; |
| 5915 | + |
| 5916 | +BPF_CALL_2(bpf_lua_pushlightuserdata, struct xdp_buff *, ctx, void *, ptr) { |
| 5917 | + lua_pushlightuserdata(ctx->L, ptr); |
| 5918 | + return 0; |
| 5919 | +} |
| 5920 | + |
| 5921 | +static const struct bpf_func_proto bpf_lua_pushlightuserdata_proto = { |
| 5922 | + .func = bpf_lua_pushlightuserdata, |
| 5923 | + .gpl_only = false, |
| 5924 | + .pkt_access = false, |
| 5925 | + .ret_type = RET_VOID, |
| 5926 | + .arg1_type = ARG_PTR_TO_CTX, |
| 5927 | + .arg2_type = ARG_ANYTHING, |
| 5928 | +}; |
| 5929 | + |
| 5930 | +BPF_CALL_2(bpf_lua_pushmap, struct xdp_buff *, ctx, struct bpf_map *, map) { |
| 5931 | + lua_pushlightuserdata(ctx->L, map); |
| 5932 | + return 0; |
| 5933 | +} |
| 5934 | + |
| 5935 | +BPF_CALL_3(bpf_lua_pushlstring, struct xdp_buff *, ctx, const char *, str, size_t, len) { |
| 5936 | + lua_pushlstring(ctx->L, str, len); |
| 5937 | + return 0; |
| 5938 | +} |
| 5939 | + |
| 5940 | +static const struct bpf_func_proto bpf_lua_pushlstring_proto = { |
| 5941 | + .func = bpf_lua_pushlstring, |
| 5942 | + .gpl_only = false, |
| 5943 | + .pkt_access = false, |
| 5944 | + .ret_type = RET_VOID, |
| 5945 | + .arg1_type = ARG_PTR_TO_CTX, |
| 5946 | + .arg2_type = ARG_ANYTHING, |
| 5947 | + .arg3_type = ARG_ANYTHING, |
| 5948 | +}; |
| 5949 | + |
| 5950 | +static const struct bpf_func_proto bpf_lua_pushmap_proto = { |
| 5951 | + .func = bpf_lua_pushmap, |
| 5952 | + .gpl_only = false, |
| 5953 | + .pkt_access = false, |
| 5954 | + .ret_type = RET_VOID, |
| 5955 | + .arg1_type = ARG_PTR_TO_CTX, |
| 5956 | + .arg2_type = ARG_ANYTHING, |
| 5957 | +}; |
| 5958 | + |
| 5959 | +BPF_CALL_1(bpf_lua_pushskb, struct xdp_buff *, ctx) { |
| 5960 | + lua_pushlightuserdata(ctx->L, ctx->skb); |
| 5961 | + return 0; |
| 5962 | +} |
| 5963 | + |
| 5964 | +static const struct bpf_func_proto bpf_lua_pushskb_proto = { |
| 5965 | + .func = bpf_lua_pushskb, |
| 5966 | + .gpl_only = false, |
| 5967 | + .pkt_access = false, |
| 5968 | + .ret_type = RET_VOID, |
| 5969 | + .arg1_type = ARG_PTR_TO_CTX, |
| 5970 | +}; |
| 5971 | + |
| 5972 | +BPF_CALL_2(bpf_lua_pushstring, struct xdp_buff *, ctx, const char *, str) { |
| 5973 | + lua_pushstring(ctx->L, str); |
| 5974 | + return 0; |
| 5975 | +} |
| 5976 | + |
| 5977 | +static const struct bpf_func_proto bpf_lua_pushstring_proto = { |
| 5978 | + .func = bpf_lua_pushstring, |
| 5979 | + .gpl_only = false, |
| 5980 | + .pkt_access = false, |
| 5981 | + .ret_type = RET_VOID, |
| 5982 | + .arg1_type = ARG_PTR_TO_CTX, |
| 5983 | + .arg2_type = ARG_ANYTHING, |
| 5984 | +}; |
| 5985 | + |
| 5986 | +BPF_CALL_1(bpf_lua_setstate, struct xdp_buff *, ctx){ |
| 5987 | + struct lua_state_cpu *sc; |
| 5988 | + int cpu = smp_processor_id(); |
| 5989 | + |
| 5990 | + list_for_each_entry(sc, &lua_state_cpu_list, list) { |
| 5991 | + if (sc->cpu == cpu) { |
| 5992 | + ctx->L = sc->L; |
| 5993 | + break; |
| 5994 | + } |
| 5995 | + } |
| 5996 | + return 0; |
| 5997 | +} |
| 5998 | + |
| 5999 | +static const struct bpf_func_proto bpf_lua_setstate_proto = { |
| 6000 | + .func = bpf_lua_setstate, |
| 6001 | + .gpl_only = false, |
| 6002 | + .pkt_access = false, |
| 6003 | + .ret_type = RET_VOID, |
| 6004 | + .arg1_type = ARG_PTR_TO_CTX, |
| 6005 | +}; |
| 6006 | + |
| 6007 | +BPF_CALL_2(bpf_lua_toboolean, struct xdp_buff *, ctx, int, index) { |
| 6008 | + return lua_toboolean(ctx->L, index); |
| 6009 | +} |
| 6010 | + |
| 6011 | +static const struct bpf_func_proto bpf_lua_toboolean_proto = { |
| 6012 | + .func = bpf_lua_toboolean, |
| 6013 | + .gpl_only = false, |
| 6014 | + .pkt_access = false, |
| 6015 | + .ret_type = RET_INTEGER, |
| 6016 | + .arg1_type = ARG_PTR_TO_CTX, |
| 6017 | + .arg2_type = ARG_ANYTHING, |
| 6018 | +}; |
| 6019 | + |
| 6020 | +BPF_CALL_2(bpf_lua_tointeger, struct xdp_buff *, ctx, int, index) { |
| 6021 | + return lua_tointeger(ctx->L, index); |
| 6022 | +} |
| 6023 | + |
| 6024 | +static const struct bpf_func_proto bpf_lua_tointeger_proto = { |
| 6025 | + .func = bpf_lua_tointeger, |
| 6026 | + .gpl_only = false, |
| 6027 | + .pkt_access = false, |
| 6028 | + .ret_type = RET_INTEGER, |
| 6029 | + .arg1_type = ARG_PTR_TO_CTX, |
| 6030 | + .arg2_type = ARG_ANYTHING, |
| 6031 | +}; |
| 6032 | +#endif /* CONFIG_XDPLUA */ |
| 6033 | + |
5855 | 6034 | bool bpf_helper_changes_pkt_data(void *func) |
5856 | 6035 | { |
5857 | 6036 | if (func == bpf_skb_vlan_push || |
@@ -5926,6 +6105,30 @@ bpf_base_func_proto(enum bpf_func_id func_id) |
5926 | 6105 | return &bpf_spin_unlock_proto; |
5927 | 6106 | case BPF_FUNC_trace_printk: |
5928 | 6107 | return bpf_get_trace_printk_proto(); |
| 6108 | +#ifdef CONFIG_XDPLUA |
| 6109 | + case BPF_FUNC_lua_pcall: |
| 6110 | + return &bpf_lua_pcall_proto; |
| 6111 | + case BPF_FUNC_lua_pop: |
| 6112 | + return &bpf_lua_pop_proto; |
| 6113 | + case BPF_FUNC_lua_pushinteger: |
| 6114 | + return &bpf_lua_pushinteger_proto; |
| 6115 | + case BPF_FUNC_lua_pushlightuserdata: |
| 6116 | + return &bpf_lua_pushlightuserdata_proto; |
| 6117 | + case BPF_FUNC_lua_pushlstring: |
| 6118 | + return &bpf_lua_pushlstring_proto; |
| 6119 | + case BPF_FUNC_lua_pushmap: |
| 6120 | + return &bpf_lua_pushmap_proto; |
| 6121 | + case BPF_FUNC_lua_pushskb: |
| 6122 | + return &bpf_lua_pushskb_proto; |
| 6123 | + case BPF_FUNC_lua_pushstring: |
| 6124 | + return &bpf_lua_pushstring_proto; |
| 6125 | + case BPF_FUNC_lua_setstate: |
| 6126 | + return &bpf_lua_setstate_proto; |
| 6127 | + case BPF_FUNC_lua_toboolean: |
| 6128 | + return &bpf_lua_toboolean_proto; |
| 6129 | + case BPF_FUNC_lua_tointeger: |
| 6130 | + return &bpf_lua_tointeger_proto; |
| 6131 | +#endif /* CONFIG_XDPLUA */ |
5929 | 6132 | default: |
5930 | 6133 | return NULL; |
5931 | 6134 | } |
|
0 commit comments