|
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 |
@@ -4787,6 +4791,181 @@ static const struct bpf_func_proto bpf_lwt_seg6_adjust_srh_proto = { |
4787 | 4791 | }; |
4788 | 4792 | #endif /* CONFIG_IPV6_SEG6_BPF */ |
4789 | 4793 |
|
| 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 | + |
4790 | 4969 | bool bpf_helper_changes_pkt_data(void *func) |
4791 | 4970 | { |
4792 | 4971 | if (func == bpf_skb_vlan_push || |
@@ -4842,6 +5021,30 @@ bpf_base_func_proto(enum bpf_func_id func_id) |
4842 | 5021 | if (capable(CAP_SYS_ADMIN)) |
4843 | 5022 | return bpf_get_trace_printk_proto(); |
4844 | 5023 | /* 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 */ |
4845 | 5048 | default: |
4846 | 5049 | return NULL; |
4847 | 5050 | } |
|
0 commit comments