History

bpf: Add bpf_skb_adjust_room flag BPF_F_ADJ_ROOM_ENCAP_L2_ETH

bpf_skb_adjust_room sets the inner_protocol as skb->protocol for packets encapsulation. But that is not appropriate when pushing Ethernet header. Add an option to further specify encap L2 type and set the inner_protocol as ETH_P_TEB.

Xuesen Huang committed 5 years ago

Commit d01b59c1 parent bce86233 files · +20 −1Browse files

Unified · Split

3 files
  1. include/uapi/linux/bpf.h +5 −0
  2. net/core/filter.c +10 −1
  3. tools/include/uapi/linux/bpf.h +5 −0
include/uapi/linux/bpf.h+5−0
@@ -2484,6 +2484,10 @@ union bpf_attr { · 2483 unmodified lines
24842484 * Use with ENCAP_L3/L4 flags to further specify the tunnel
24852485 * type; *len* is the length of the inner MAC header.
24862486 *
2487+ * * **BPF_F_ADJ_ROOM_ENCAP_L2_ETH**:
2488+ * Use with BPF_F_ADJ_ROOM_ENCAP_L2 flag to further specify the
2489+ * L2 type as Ethernet.
2490+ *
24872491 * A call to this helper is susceptible to change the underlying
24882492 * packet buffer. Therefore, at load time, all checks on pointers
24892493 * previously done by the verifier are invalidated and must be
@@ -4916,6 +4920,7 @@ enum { · 2426 unmodified lines
49164920 BPF_F_ADJ_ROOM_ENCAP_L4_GRE = (1ULL << 3),
49174921 BPF_F_ADJ_ROOM_ENCAP_L4_UDP = (1ULL << 4),
49184922 BPF_F_ADJ_ROOM_NO_CSUM_RESET = (1ULL << 5),
4923+ BPF_F_ADJ_ROOM_ENCAP_L2_ETH = (1ULL << 6),
49194924 };
49204925
49214926 enum {
net/core/filter.c+10−1
@@ -3409,6 +3409,7 @@ static u32 bpf_skb_net_base_len(const struct sk_buff *skb) · 3408 unmodified lines
34093409 BPF_F_ADJ_ROOM_ENCAP_L3_MASK | \
34103410 BPF_F_ADJ_ROOM_ENCAP_L4_GRE | \
34113411 BPF_F_ADJ_ROOM_ENCAP_L4_UDP | \
3412+ BPF_F_ADJ_ROOM_ENCAP_L2_ETH | \
34123413 BPF_F_ADJ_ROOM_ENCAP_L2( \
34133414 BPF_ADJ_ROOM_ENCAP_L2_MASK))
34143415
@@ -3445,6 +3446,10 @@ static int bpf_skb_net_grow(struct sk_buff *skb, u32 off, u32 len_diff, · 30 unmodified lines
34453446 flags & BPF_F_ADJ_ROOM_ENCAP_L4_UDP)
34463447 return -EINVAL;
34473448
3449+ if (flags & BPF_F_ADJ_ROOM_ENCAP_L2_ETH &&
3450+ inner_mac_len < ETH_HLEN)
3451+ return -EINVAL;
3452+
34483453 if (skb->encapsulation)
34493454 return -EALREADY;
34503455
@@ -3463,7 +3468,11 @@ static int bpf_skb_net_grow(struct sk_buff *skb, u32 off, u32 len_diff, · 12 unmodified lines
34633468 skb->inner_mac_header = inner_net - inner_mac_len;
34643469 skb->inner_network_header = inner_net;
34653470 skb->inner_transport_header = inner_trans;
3466− skb_set_inner_protocol(skb, skb->protocol);
3471+
3472+ if (flags & BPF_F_ADJ_ROOM_ENCAP_L2_ETH)
3473+ skb_set_inner_protocol(skb, htons(ETH_P_TEB));
3474+ else
3475+ skb_set_inner_protocol(skb, skb->protocol);
34673476
34683477 skb->encapsulation = 1;
34693478 skb_set_network_header(skb, mac_len);
tools/include/uapi/linux/bpf.h+5−0
@@ -2484,6 +2484,10 @@ union bpf_attr { · 2483 unmodified lines
24842484 * Use with ENCAP_L3/L4 flags to further specify the tunnel
24852485 * type; *len* is the length of the inner MAC header.
24862486 *
2487+ * * **BPF_F_ADJ_ROOM_ENCAP_L2_ETH**:
2488+ * Use with BPF_F_ADJ_ROOM_ENCAP_L2 flag to further specify the
2489+ * L2 type as Ethernet.
2490+ *
24872491 * A call to this helper is susceptible to change the underlying
24882492 * packet buffer. Therefore, at load time, all checks on pointers
24892493 * previously done by the verifier are invalidated and must be
@@ -4916,6 +4920,7 @@ enum { · 2426 unmodified lines
49164920 BPF_F_ADJ_ROOM_ENCAP_L4_GRE = (1ULL << 3),
49174921 BPF_F_ADJ_ROOM_ENCAP_L4_UDP = (1ULL << 4),
49184922 BPF_F_ADJ_ROOM_NO_CSUM_RESET = (1ULL << 5),
4923+ BPF_F_ADJ_ROOM_ENCAP_L2_ETH = (1ULL << 6),
49194924 };
49204925
49214926 enum {