> 2021年3月4日 下午10:02,Willem de Bruijn <willemdebruijn.kernel@xxxxxxxxx> 写道: > > On Thu, Mar 4, 2021 at 1:42 AM Xuesen Huang <hxseverything@xxxxxxxxx> wrote: >> >> From: Xuesen Huang <huangxuesen@xxxxxxxxxxxx> >> >> 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 <huangxuesen@xxxxxxxxxxxx> >> Signed-off-by: Li Wang <wangli09@xxxxxxxxxxxx> >> Signed-off-by: Willem de Bruijn <willemb@xxxxxxxxxx> > > Please mark patch target: [PATCH bpf-next] > Thanks. >> --- >> 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(-) > > >> -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). >> +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.