|
| 1 | +/* SPDX-License-Identifier: GPL-2.0 */ |
| 2 | +/* Copyright (C) 2020 Authors of Cilium |
| 3 | + * |
| 4 | + * Code copied from cilium/bpf/include/bpf/ctx/xdp.h |
| 5 | + * https://github.com/cilium/cilium/blob/master/bpf/include/bpf/ctx/xdp.h |
| 6 | + */ |
| 7 | + |
| 8 | +#ifndef _XDP_DATA_ACCESS_HELPERS_H_ |
| 9 | +#define _XDP_DATA_ACCESS_HELPERS_H_ |
| 10 | + |
| 11 | +/* This must be a mask and all offsets guaranteed to be less than that. */ |
| 12 | +//#define __CTX_OFF_MAX 0xff |
| 13 | +#define __CTX_OFF_MAX 0x1fff |
| 14 | + |
| 15 | +#ifndef __maybe_unused |
| 16 | +# define __maybe_unused __attribute__((__unused__)) |
| 17 | +#endif |
| 18 | + |
| 19 | +#ifndef EINVAL |
| 20 | +# define EINVAL 22 |
| 21 | +#endif |
| 22 | + |
| 23 | +#ifndef memcpy |
| 24 | +# define memcpy(dest, src, n) __builtin_memcpy((dest), (src), (n)) |
| 25 | +#endif |
| 26 | + |
| 27 | +static __always_inline __maybe_unused int |
| 28 | +xdp_load_bytes(struct xdp_md *ctx, __u64 off, void *to, const __u64 len) |
| 29 | +{ |
| 30 | + void *from; |
| 31 | + int ret; |
| 32 | + /* LLVM tends to generate code that verifier doesn't understand, |
| 33 | + * so force it the way we want it in order to open up a range |
| 34 | + * on the reg. |
| 35 | + */ |
| 36 | + asm volatile("r1 = *(u32 *)(%[ctx] +0)\n\t" |
| 37 | + "r2 = *(u32 *)(%[ctx] +4)\n\t" |
| 38 | + "%[off] &= %[offmax]\n\t" |
| 39 | + "r1 += %[off]\n\t" |
| 40 | + "%[from] = r1\n\t" |
| 41 | + "r1 += %[len]\n\t" |
| 42 | + "if r1 > r2 goto +2\n\t" |
| 43 | + "%[ret] = 0\n\t" |
| 44 | + "goto +1\n\t" |
| 45 | + "%[ret] = %[errno]\n\t" |
| 46 | + : [ret]"=r"(ret), [from]"=r"(from) |
| 47 | + : [ctx]"r"(ctx), [off]"r"(off), [len]"ri"(len), |
| 48 | + [offmax]"i"(__CTX_OFF_MAX), [errno]"i"(-EINVAL) |
| 49 | + : "r1", "r2"); |
| 50 | + if (!ret) |
| 51 | + memcpy(to, from, len); |
| 52 | + return ret; |
| 53 | +} |
| 54 | + |
| 55 | +static __always_inline __maybe_unused int |
| 56 | +xdp_store_bytes(struct xdp_md *ctx, __u64 off, const void *from, |
| 57 | + const __u64 len, __u64 flags __maybe_unused) |
| 58 | +{ |
| 59 | + void *to; |
| 60 | + int ret; |
| 61 | + /* See xdp_load_bytes(). */ |
| 62 | + asm volatile("r1 = *(u32 *)(%[ctx] +0)\n\t" |
| 63 | + "r2 = *(u32 *)(%[ctx] +4)\n\t" |
| 64 | + "%[off] &= %[offmax]\n\t" |
| 65 | + "r1 += %[off]\n\t" |
| 66 | + "%[to] = r1\n\t" |
| 67 | + "r1 += %[len]\n\t" |
| 68 | + "if r1 > r2 goto +2\n\t" |
| 69 | + "%[ret] = 0\n\t" |
| 70 | + "goto +1\n\t" |
| 71 | + "%[ret] = %[errno]\n\t" |
| 72 | + : [ret]"=r"(ret), [to]"=r"(to) |
| 73 | + : [ctx]"r"(ctx), [off]"r"(off), [len]"ri"(len), |
| 74 | + [offmax]"i"(__CTX_OFF_MAX), [errno]"i"(-EINVAL) |
| 75 | + : "r1", "r2"); |
| 76 | + if (!ret) |
| 77 | + memcpy(to, from, len); |
| 78 | + return ret; |
| 79 | +} |
| 80 | + |
| 81 | +#define ctx_load_bytes xdp_load_bytes |
| 82 | +#define ctx_store_bytes xdp_store_bytes |
| 83 | + |
| 84 | +#endif /* _XDP_DATA_ACCESS_HELPERS_H_ */ |
0 commit comments