1 // SPDX-License-Identifier: GPL-2.0 2 #include <netinet/in.h> 3 #include <linux/bpf.h> 4 #include <bpf/bpf_helpers.h> 5 6 char _license[] SEC("license") = "GPL"; 7 8 __s32 page_size = 0; 9 10 SEC("cgroup/getsockopt") 11 int _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 32 out: 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 39 SEC("cgroup/getsockopt") 40 int _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 61 out: 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 68 SEC("cgroup/setsockopt") 69 int _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 85 out: 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