Re: [PATCH bpf 03/11] bpf: Add write access to tcp_sock and sock fields
From: Alexei Starovoitov <hidden>
Date: 2017-12-20 01:10:52
On 12/18/17 10:21 PM, Lawrence Brakmo wrote:
+#define SOCK_OPS_SET_FIELD(FIELD_NAME, OBJ) \
+ do { \
+ int reg = BPF_REG_9; \
+ BUILD_BUG_ON(FIELD_SIZEOF(OBJ, FIELD_NAME) > \
+ FIELD_SIZEOF(struct bpf_sock_ops, FIELD_NAME)); \
+ while (si->dst_reg == reg || si->src_reg == reg) \
+ reg--; \
+ *insn++ = BPF_STX_MEM(BPF_DW, si->dst_reg, reg, \
+ offsetof(struct bpf_sock_ops_kern, \
+ temp)); \
+ *insn++ = BPF_LDX_MEM(BPF_FIELD_SIZEOF( \
+ struct bpf_sock_ops_kern, \
+ is_fullsock), \
+ reg, si->dst_reg, \
+ offsetof(struct bpf_sock_ops_kern, \
+ is_fullsock)); \
+ *insn++ = BPF_JMP_IMM(BPF_JEQ, reg, 0, 2); \
+ *insn++ = BPF_LDX_MEM(BPF_FIELD_SIZEOF( \
+ struct bpf_sock_ops_kern, sk),\
+ reg, si->dst_reg, \
+ offsetof(struct bpf_sock_ops_kern, sk));\
+ *insn++ = BPF_STX_MEM(BPF_FIELD_SIZEOF(OBJ, FIELD_NAME), \
+ reg, si->src_reg, \
+ offsetof(OBJ, FIELD_NAME)); \
+ *insn++ = BPF_LDX_MEM(BPF_DW, reg, si->dst_reg, \
+ offsetof(struct bpf_sock_ops_kern, \
+ temp)); \
+ } while (0)that's neat. I like it. I guess the prog can check is_fullsock on its own to see whether writes will fail or not, so JEQ above is ok. Only while() loop looks a bit scary. May be replace with two 'if' ? if (si->dst_reg == reg || si->src_reg == reg) reg --; if (si->dst_reg == reg || si->src_reg == reg) reg --; so it's clear that tmp reg will be reg_7, 8 or 9.