On Wed, Feb 03, 2021 at 05:16 AM CET, Cong Wang wrote: > From: Cong Wang <cong.wang@xxxxxxxxxxxxx> > > Currently TCP_SKB_CB() is hard-coded in skmsg code, it certainly > won't work for any other non-TCP protocols. We can move them to > skb ext instead of playing with skb cb, which is harder to make > correct. > > Of course, except ->data_end, which is used by > sk_skb_convert_ctx_access() to adjust compile-time constant offset. > Fortunately, we can reuse the anonymous union where the field > 'tcp_tsorted_anchor' is and save/restore the overwritten part > before/after a brief use. > > Cc: John Fastabend <john.fastabend@xxxxxxxxx> > Cc: Daniel Borkmann <daniel@xxxxxxxxxxxxx> > Cc: Jakub Sitnicki <jakub@xxxxxxxxxxxxxx> > Cc: Lorenz Bauer <lmb@xxxxxxxxxxxxxx> > Signed-off-by: Cong Wang <cong.wang@xxxxxxxxxxxxx> > --- > include/linux/skbuff.h | 4 ++++ > include/linux/skmsg.h | 45 ++++++++++++++++++++++++++++++++++++++++++ > include/net/tcp.h | 25 ----------------------- > net/Kconfig | 1 + > net/core/filter.c | 3 +-- > net/core/skbuff.c | 7 +++++++ > net/core/skmsg.c | 44 ++++++++++++++++++++++++++++------------- > net/core/sock_map.c | 12 +++++------ > 8 files changed, 94 insertions(+), 47 deletions(-) > > diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h > index 46f901adf1a8..12a28268233a 100644 > --- a/include/linux/skbuff.h > +++ b/include/linux/skbuff.h > @@ -755,6 +755,7 @@ struct sk_buff { > void (*destructor)(struct sk_buff *skb); > }; > struct list_head tcp_tsorted_anchor; > + void *data_end; > }; I think we can avoid `data_end` by computing it in BPF with the help of a scratch register. Similar to how we compute skb_shinfo(skb) in bpf_convert_shinfo_access(). Something like: static struct bpf_insn *bpf_convert_data_end_access(const struct bpf_insn *si, struct bpf_insn *insn) { /* dst_reg = skb->data */ *insn++ = BPF_LDX_MEM(BPF_FIELD_SIZEOF(struct sk_buff, data), si->dst_reg, si->src_reg, offsetof(struct sk_buff, data)); /* AX = skb->len */ *insn++ = BPF_LDX_MEM(BPF_FIELD_SIZEOF(struct sk_buff, len), BPF_REG_AX, si->src_reg, offsetof(struct sk_buff, len)); /* dst_reg = skb->data + skb->len */ *insn++ = BPF_ALU64_REG(BPF_ADD, si->dst_reg, BPF_REG_AX); /* AX = skb->data_len */ *insn++ = BPF_LDX_MEM(BPF_FIELD_SIZEOF(struct sk_buff, data_len), BPF_REG_AX, si->src_reg, offsetof(struct sk_buff, data_len)); /* dst_reg = skb->data + skb->len - skb->data_len */ *insn++ = BPF_ALU64_REG(BPF_SUB, si->dst_reg, BPF_REG_AX); return insn; } [...]