91 lines · c
1// SPDX-License-Identifier: GPL-2.02#include <netinet/in.h>3#include <linux/bpf.h>4#include <bpf/bpf_helpers.h>5 6char _license[] SEC("license") = "GPL";7 8__s32 page_size = 0;9 10SEC("cgroup/getsockopt")11int _getsockopt_child(struct bpf_sockopt *ctx)12{13 __u8 *optval_end = ctx->optval_end;14 __u8 *optval = ctx->optval;15 16 if (ctx->level != SOL_IP || ctx->optname != IP_TOS)17 goto out;18 19 if (optval + 1 > optval_end)20 return 0; /* EPERM, bounds check */21 22 if (optval[0] != 0x80)23 return 0; /* EPERM, unexpected optval from the kernel */24 25 ctx->retval = 0; /* Reset system call return value to zero */26 27 optval[0] = 0x90;28 ctx->optlen = 1;29 30 return 1;31 32out:33 /* optval larger than PAGE_SIZE use kernel's buffer. */34 if (ctx->optlen > page_size)35 ctx->optlen = 0;36 return 1;37}38 39SEC("cgroup/getsockopt")40int _getsockopt_parent(struct bpf_sockopt *ctx)41{42 __u8 *optval_end = ctx->optval_end;43 __u8 *optval = ctx->optval;44 45 if (ctx->level != SOL_IP || ctx->optname != IP_TOS)46 goto out;47 48 if (optval + 1 > optval_end)49 return 0; /* EPERM, bounds check */50 51 if (optval[0] != 0x90)52 return 0; /* EPERM, unexpected optval from the kernel */53 54 ctx->retval = 0; /* Reset system call return value to zero */55 56 optval[0] = 0xA0;57 ctx->optlen = 1;58 59 return 1;60 61out:62 /* optval larger than PAGE_SIZE use kernel's buffer. */63 if (ctx->optlen > page_size)64 ctx->optlen = 0;65 return 1;66}67 68SEC("cgroup/setsockopt")69int _setsockopt(struct bpf_sockopt *ctx)70{71 __u8 *optval_end = ctx->optval_end;72 __u8 *optval = ctx->optval;73 74 if (ctx->level != SOL_IP || ctx->optname != IP_TOS)75 goto out;76 77 if (optval + 1 > optval_end)78 return 0; /* EPERM, bounds check */79 80 optval[0] += 0x10;81 ctx->optlen = 1;82 83 return 1;84 85out:86 /* optval larger than PAGE_SIZE use kernel's buffer. */87 if (ctx->optlen > page_size)88 ctx->optlen = 0;89 return 1;90}91