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.

Reply via email to