Re: [PATCH] selftests_bpf: extend test_tc_tunnel test with vxlan
From: Xuesen Huang <hidden>
Date: 2021-03-05 12:21:30
Also in:
bpf, lkml
2021年3月4日 下午10:02,Willem de Bruijn [off-list ref] 写道: On Thu, Mar 4, 2021 at 1:42 AM Xuesen Huang [off-list ref] wrote:quoted
From: Xuesen Huang <redacted> Add BPF_F_ADJ_ROOM_ENCAP_L2_ETH flag to the existing tests which encapsulates the ethernet as the inner l2 header. Update a vxlan encapsulation test case. Signed-off-by: Xuesen Huang <redacted> Signed-off-by: Li Wang <redacted> Signed-off-by: Willem de Bruijn <willemb@google.com>Please mark patch target: [PATCH bpf-next]
Thanks.
quoted
--- tools/testing/selftests/bpf/progs/test_tc_tunnel.c | 113 ++++++++++++++++++--- tools/testing/selftests/bpf/test_tc_tunnel.sh | 15 ++- 2 files changed, 111 insertions(+), 17 deletions(-)quoted
-static __always_inline int encap_ipv4(struct __sk_buff *skb, __u8 encap_proto, - __u16 l2_proto) +static __always_inline int __encap_ipv4(struct __sk_buff *skb, __u8 encap_proto, + __u16 l2_proto, __u16 ext_proto) { __u16 udp_dst = UDP_PORT; struct iphdr iph_inner; struct v4hdr h_outer; struct tcphdr tcph; int olen, l2_len; + __u8 *l2_hdr = NULL; int tcp_off; __u64 flags;@@ -141,7 +157,11 @@ static __always_inline int encap_ipv4(struct __sk_buff *skb, __u8 encap_proto, break; case ETH_P_TEB: l2_len = ETH_HLEN; - udp_dst = ETH_OVER_UDP_PORT; + if (ext_proto & EXTPROTO_VXLAN) { + udp_dst = VXLAN_UDP_PORT; + l2_len += sizeof(struct vxlanhdr); + } else + udp_dst = ETH_OVER_UDP_PORT; break; } flags |= BPF_F_ADJ_ROOM_ENCAP_L2(l2_len);@@ -171,14 +191,26 @@ static __always_inline int encap_ipv4(struct __sk_buff *skb, __u8 encap_proto, } /* add L2 encap (if specified) */ + l2_hdr = (__u8 *)&h_outer + olen; switch (l2_proto) { case ETH_P_MPLS_UC: - *((__u32 *)((__u8 *)&h_outer + olen)) = mpls_label; + *(__u32 *)l2_hdr = mpls_label; break; case ETH_P_TEB: - if (bpf_skb_load_bytes(skb, 0, (__u8 *)&h_outer + olen, - ETH_HLEN)) + flags |= BPF_F_ADJ_ROOM_ENCAP_L2_ETH; + + if (ext_proto & EXTPROTO_VXLAN) { + struct vxlanhdr *vxlan_hdr = (struct vxlanhdr *)l2_hdr; + + vxlan_hdr->vx_flags = VXLAN_FLAGS; + vxlan_hdr->vx_vni = bpf_htonl((VXLAN_VNI & VXLAN_VNI_MASK) << 8); + + l2_hdr += sizeof(struct vxlanhdr);should this be l2_len? (here and ipv6 below)
Should be l2_hdr. It’s a little tricky. l2_len has already been modified above. We use l2_hdr here to help us to find the address in h_outer to load original Ethernet header which is different in (eth) and (vxlan + eth).
quoted
+SEC("encap_vxlan_eth") +int __encap_vxlan_eth(struct __sk_buff *skb) +{ + if (skb->protocol == __bpf_constant_htons(ETH_P_IP)) + return __encap_ipv4(skb, IPPROTO_UDP, + ETH_P_TEB, + EXTPROTO_VXLAN);non-standard indentation: align with the opening parenthesis. (here and ipv6 below)
Thanks.