tools/testing/selftests/bpf/progs/test_tc_tunnel.c

Source file repositories/reference/linux-study-clean/tools/testing/selftests/bpf/progs/test_tc_tunnel.c

File Facts

System
Linux kernel
Corpus path
tools/testing/selftests/bpf/progs/test_tc_tunnel.c
Extension
.c
Size
16841 bytes
Lines
703
Domain
Support Tooling And Documentation
Bucket
tools
Inferred role
Support Tooling And Documentation: implementation source
Status
source implementation candidate

Why This File Exists

Repository support layer: documentation, build tooling, samples, user-space helper tools, generated initramfs support, licenses, and validation utilities.

Dependency Surface

Detected Declarations

Annotated Snippet

struct vxlanhdr___local {
	__be32 vx_flags;
	__be32 vx_vni;
};

#define	L2_PAD_SZ	(sizeof(struct vxlanhdr___local) + ETH_HLEN)

#define	UDP_PORT		5555
#define	MPLS_OVER_UDP_PORT	6635
#define	ETH_OVER_UDP_PORT	7777
#define	VXLAN_UDP_PORT		8472

#define	EXTPROTO_VXLAN	0x1

#define	VXLAN_FLAGS     bpf_htonl(1<<27)
#define	VNI_ID		1
#define	VXLAN_VNI	bpf_htonl(VNI_ID << 8)

#ifndef NEXTHDR_DEST
#define NEXTHDR_DEST	60
#endif

/* MPLS label 1000 with S bit (last label) set and ttl of 255. */
static const __u32 mpls_label = __bpf_constant_htonl(1000 << 12 |
						     MPLS_LS_S_MASK | 0xff);
struct gre_hdr {
	__be16 flags;
	__be16 protocol;
} __attribute__((packed));

union l4hdr {
	struct udphdr udp;
	struct gre_hdr gre;
};

struct v4hdr {
	struct iphdr ip;
	union l4hdr l4hdr;
	__u8 pad[L2_PAD_SZ];		/* space for L2 header / vxlan header ... */
} __attribute__((packed));

struct v6hdr {
	struct ipv6hdr ip;
	union l4hdr l4hdr;
	__u8 pad[L2_PAD_SZ];		/* space for L2 header / vxlan header ... */
} __attribute__((packed));

static __always_inline void set_ipv4_csum(struct iphdr *iph)
{
	__u16 *iph16 = (__u16 *)iph;
	__u32 csum;
	int i;

	iph->check = 0;

	__pragma_loop_unroll_full
	for (i = 0, csum = 0; i < sizeof(*iph) >> 1; i++)
		csum += *iph16++;

	iph->check = ~((csum & 0xffff) + (csum >> 16));
}

static __always_inline int __encap_ipv4(struct __sk_buff *skb, __u8 encap_proto,
					__u16 l2_proto, __u16 ext_proto)
{
	struct iphdr iph_inner = {0};
	__u16 udp_dst = UDP_PORT;
	struct v4hdr h_outer;
	struct tcphdr tcph;
	int olen, l2_len;
	__u8 *l2_hdr = NULL;
	int tcp_off;
	__u64 flags;

	/* Most tests encapsulate a packet into a tunnel with the same
	 * network protocol, and derive the outer header fields from
	 * the inner header.
	 *
	 * The 6in4 case tests different inner and outer protocols. As
	 * the inner is ipv6, but the outer expects an ipv4 header as
	 * input, manually build a struct iphdr based on the ipv6hdr.
	 */
	if (encap_proto == IPPROTO_IPV6) {
		const __u32 saddr = (192 << 24) | (168 << 16) | (1 << 8) | 1;
		const __u32 daddr = (192 << 24) | (168 << 16) | (1 << 8) | 2;
		struct ipv6hdr iph6_inner;

		/* Read the IPv6 header */
		if (bpf_skb_load_bytes(skb, ETH_HLEN, &iph6_inner,
				       sizeof(iph6_inner)) < 0)

Annotation

Implementation Notes