Thread (3 messages) flat view 3 messages, 2 authors, 2021-03-05

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.
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help