Commit 02b4e126 authored by Daniel Xu's avatar Daniel Xu Committed by Alexei Starovoitov
Browse files

bpf: selftests: test_tunnel: Use vmlinux.h declarations



vmlinux.h declarations are more ergnomic, especially when working with
kfuncs. The uapi headers are often incomplete for kfunc definitions.

This commit also switches bitfield accesses to use CO-RE helpers.
Switching to vmlinux.h definitions makes the verifier very
unhappy with raw bitfield accesses. The error is:

    ; md.u.md2.dir = direction;
    33: (69) r1 = *(u16 *)(r2 +11)
    misaligned stack access off (0x0; 0x0)+-64+11 size 2

Fix by using CO-RE-aware bitfield reads and writes.

Co-developed-by: default avatarAntony Antony <antony.antony@secunet.com>
Signed-off-by: default avatarAntony Antony <antony.antony@secunet.com>
Signed-off-by: default avatarDaniel Xu <dxu@dxuuu.xyz>
Link: https://lore.kernel.org/r/884bde1d9a351d126a3923886b945ea6b1b0776b.1702593901.git.dxu@dxuuu.xyz


Signed-off-by: default avatarAlexei Starovoitov <ast@kernel.org>
parent 77a7a822
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -26,6 +26,7 @@
#define IPV6_AUTOFLOWLABEL	70

#define TC_ACT_UNSPEC		(-1)
#define TC_ACT_OK		0
#define TC_ACT_SHOT		2

#define SOL_TCP			6
+21 −55
Original line number Diff line number Diff line
@@ -6,62 +6,26 @@
 * modify it under the terms of version 2 of the GNU General Public
 * License as published by the Free Software Foundation.
 */
#include <stddef.h>
#include <string.h>
#include <arpa/inet.h>
#include <linux/bpf.h>
#include <linux/if_ether.h>
#include <linux/if_packet.h>
#include <linux/if_tunnel.h>
#include <linux/ip.h>
#include <linux/ipv6.h>
#include <linux/icmp.h>
#include <linux/types.h>
#include <linux/socket.h>
#include <linux/pkt_cls.h>
#include <linux/erspan.h>
#include <linux/udp.h>
#include "vmlinux.h"
#include <bpf/bpf_core_read.h>
#include <bpf/bpf_helpers.h>
#include <bpf/bpf_endian.h>
#include "bpf_kfuncs.h"
#include "bpf_tracing_net.h"

#define log_err(__ret) bpf_printk("ERROR line:%d ret:%d\n", __LINE__, __ret)

#define VXLAN_UDP_PORT		4789
#define ETH_P_IP		0x0800
#define PACKET_HOST		0
#define TUNNEL_CSUM		bpf_htons(0x01)
#define TUNNEL_KEY		bpf_htons(0x04)

/* Only IPv4 address assigned to veth1.
 * 172.16.1.200
 */
#define ASSIGNED_ADDR_VETH1 0xac1001c8

struct geneve_opt {
	__be16	opt_class;
	__u8	type;
	__u8	length:5;
	__u8	r3:1;
	__u8	r2:1;
	__u8	r1:1;
	__u8	opt_data[8]; /* hard-coded to 8 byte */
};

struct vxlanhdr {
	__be32 vx_flags;
	__be32 vx_vni;
} __attribute__((packed));

struct vxlan_metadata {
	__u32     gbp;
};

struct bpf_fou_encap {
	__be16 sport;
	__be16 dport;
};

enum bpf_fou_encap_type {
	FOU_BPF_ENCAP_FOU,
	FOU_BPF_ENCAP_GUE,
};

int bpf_skb_set_fou_encap(struct __sk_buff *skb_ctx,
			  struct bpf_fou_encap *encap, int type) __ksym;
int bpf_skb_get_fou_encap(struct __sk_buff *skb_ctx,
@@ -205,9 +169,9 @@ int erspan_set_tunnel(struct __sk_buff *skb)
	__u8 hwid = 7;

	md.version = 2;
	md.u.md2.dir = direction;
	md.u.md2.hwid = hwid & 0xf;
	md.u.md2.hwid_upper = (hwid >> 4) & 0x3;
	BPF_CORE_WRITE_BITFIELD(&md.u.md2, dir, direction);
	BPF_CORE_WRITE_BITFIELD(&md.u.md2, hwid, (hwid & 0xf));
	BPF_CORE_WRITE_BITFIELD(&md.u.md2, hwid_upper, (hwid >> 4) & 0x3);
#endif

	ret = bpf_skb_set_tunnel_opt(skb, &md, sizeof(md));
@@ -246,8 +210,9 @@ int erspan_get_tunnel(struct __sk_buff *skb)
	bpf_printk("\tindex %x\n", index);
#else
	bpf_printk("\tdirection %d hwid %x timestamp %u\n",
		   md.u.md2.dir,
		   (md.u.md2.hwid_upper << 4) + md.u.md2.hwid,
		   BPF_CORE_READ_BITFIELD(&md.u.md2, dir),
		   (BPF_CORE_READ_BITFIELD(&md.u.md2, hwid_upper) << 4) +
		   BPF_CORE_READ_BITFIELD(&md.u.md2, hwid),
		   bpf_ntohl(md.u.md2.timestamp));
#endif

@@ -284,9 +249,9 @@ int ip4ip6erspan_set_tunnel(struct __sk_buff *skb)
	__u8 hwid = 17;

	md.version = 2;
	md.u.md2.dir = direction;
	md.u.md2.hwid = hwid & 0xf;
	md.u.md2.hwid_upper = (hwid >> 4) & 0x3;
	BPF_CORE_WRITE_BITFIELD(&md.u.md2, dir, direction);
	BPF_CORE_WRITE_BITFIELD(&md.u.md2, hwid, (hwid & 0xf));
	BPF_CORE_WRITE_BITFIELD(&md.u.md2, hwid_upper, (hwid >> 4) & 0x3);
#endif

	ret = bpf_skb_set_tunnel_opt(skb, &md, sizeof(md));
@@ -326,8 +291,9 @@ int ip4ip6erspan_get_tunnel(struct __sk_buff *skb)
	bpf_printk("\tindex %x\n", index);
#else
	bpf_printk("\tdirection %d hwid %x timestamp %u\n",
		   md.u.md2.dir,
		   (md.u.md2.hwid_upper << 4) + md.u.md2.hwid,
		   BPF_CORE_READ_BITFIELD(&md.u.md2, dir),
		   (BPF_CORE_READ_BITFIELD(&md.u.md2, hwid_upper) << 4) +
		   BPF_CORE_READ_BITFIELD(&md.u.md2, hwid),
		   bpf_ntohl(md.u.md2.timestamp));
#endif