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