]> asedeno.scripts.mit.edu Git - linux.git/blobdiff - net/core/filter.c
bpf: allow BPF programs access skb_shared_info->gso_segs field
[linux.git] / net / core / filter.c
index 2b3b436ef5457bf44c99780d6dec0b5f403f005c..8e587dd1da200494b900bd14eec7f875f5453773 100644 (file)
@@ -6700,6 +6700,27 @@ static u32 bpf_convert_ctx_access(enum bpf_access_type type,
                                                             target_size));
                break;
 
+       case offsetof(struct __sk_buff, gso_segs):
+               /* si->dst_reg = skb_shinfo(SKB); */
+#ifdef NET_SKBUFF_DATA_USES_OFFSET
+               *insn++ = BPF_LDX_MEM(BPF_FIELD_SIZEOF(struct sk_buff, head),
+                                     si->dst_reg, si->src_reg,
+                                     offsetof(struct sk_buff, head));
+               *insn++ = BPF_LDX_MEM(BPF_FIELD_SIZEOF(struct sk_buff, end),
+                                     BPF_REG_AX, si->src_reg,
+                                     offsetof(struct sk_buff, end));
+               *insn++ = BPF_ALU64_REG(BPF_ADD, si->dst_reg, BPF_REG_AX);
+#else
+               *insn++ = BPF_LDX_MEM(BPF_FIELD_SIZEOF(struct sk_buff, end),
+                                     si->dst_reg, si->src_reg,
+                                     offsetof(struct sk_buff, end));
+#endif
+               *insn++ = BPF_LDX_MEM(BPF_FIELD_SIZEOF(struct skb_shared_info, gso_segs),
+                                     si->dst_reg, si->dst_reg,
+                                     bpf_target_off(struct skb_shared_info,
+                                                    gso_segs, 2,
+                                                    target_size));
+               break;
        case offsetof(struct __sk_buff, wire_len):
                BUILD_BUG_ON(FIELD_SIZEOF(struct qdisc_skb_cb, pkt_len) != 4);