mirror of
https://github.com/xdp-project/BNG-router.git
synced 2024-05-06 15:54:53 +00:00
74 lines
2.0 KiB
C
74 lines
2.0 KiB
C
![]() |
/* SPDX-License-Identifier: GPL-2.0 */
|
||
|
/* Copyright (C) 2020 Authors of Cilium */
|
||
|
/* For now, only import the xdp_load_bytes() and xdp_store_bytes() helpers
|
||
|
* from Cilium.
|
||
|
*/
|
||
|
|
||
|
#ifndef __XDP_CONTEXT_HELPERS_H
|
||
|
#define __XDP_CONTEXT_HELPERS_H
|
||
|
|
||
|
#include <linux/types.h>
|
||
|
#include <linux/bpf.h>
|
||
|
|
||
|
#include "../bpf/builtins.h"
|
||
|
#include "../bpf/errno.h"
|
||
|
|
||
|
/* This must be a mask and all offsets guaranteed to be less than that. */
|
||
|
#define __CTX_OFF_MAX 0x3fff
|
||
|
|
||
|
static __always_inline __maybe_unused int
|
||
|
xdp_load_bytes(const struct xdp_md *ctx, __u64 off, void *to, const __u64 len)
|
||
|
{
|
||
|
void *from;
|
||
|
int ret;
|
||
|
/* LLVM tends to generate code that verifier doesn't understand,
|
||
|
* so force it the way we want it in order to open up a range
|
||
|
* on the reg.
|
||
|
*/
|
||
|
asm volatile("r1 = *(u32 *)(%[ctx] +0)\n\t"
|
||
|
"r2 = *(u32 *)(%[ctx] +4)\n\t"
|
||
|
"%[off] &= %[offmax]\n\t"
|
||
|
"r1 += %[off]\n\t"
|
||
|
"%[from] = r1\n\t"
|
||
|
"r1 += %[len]\n\t"
|
||
|
"if r1 > r2 goto +2\n\t"
|
||
|
"%[ret] = 0\n\t"
|
||
|
"goto +1\n\t"
|
||
|
"%[ret] = %[errno]\n\t"
|
||
|
: [ret]"=r"(ret), [from]"=r"(from)
|
||
|
: [ctx]"r"(ctx), [off]"r"(off), [len]"ri"(len),
|
||
|
[offmax]"i"(__CTX_OFF_MAX), [errno]"i"(-EINVAL)
|
||
|
: "r1", "r2");
|
||
|
if (!ret)
|
||
|
memcpy(to, from, len);
|
||
|
return ret;
|
||
|
}
|
||
|
|
||
|
static __always_inline __maybe_unused int
|
||
|
xdp_store_bytes(const struct xdp_md *ctx, __u64 off, const void *from,
|
||
|
const __u64 len, __u64 flags __maybe_unused)
|
||
|
{
|
||
|
void *to;
|
||
|
int ret;
|
||
|
/* See xdp_load_bytes(). */
|
||
|
asm volatile("r1 = *(u32 *)(%[ctx] +0)\n\t"
|
||
|
"r2 = *(u32 *)(%[ctx] +4)\n\t"
|
||
|
"%[off] &= %[offmax]\n\t"
|
||
|
"r1 += %[off]\n\t"
|
||
|
"%[to] = r1\n\t"
|
||
|
"r1 += %[len]\n\t"
|
||
|
"if r1 > r2 goto +2\n\t"
|
||
|
"%[ret] = 0\n\t"
|
||
|
"goto +1\n\t"
|
||
|
"%[ret] = %[errno]\n\t"
|
||
|
: [ret]"=r"(ret), [to]"=r"(to)
|
||
|
: [ctx]"r"(ctx), [off]"r"(off), [len]"ri"(len),
|
||
|
[offmax]"i"(__CTX_OFF_MAX), [errno]"i"(-EINVAL)
|
||
|
: "r1", "r2");
|
||
|
if (!ret)
|
||
|
memcpy(to, from, len);
|
||
|
return ret;
|
||
|
}
|
||
|
|
||
|
#endif
|