brintos

brintos / linux-shallow public Read only

0
0
Text · 2.4 KiB · 31ca229 Raw
99 lines · c
1// SPDX-License-Identifier: GPL-2.02 3#include <vmlinux.h>4#include "xdp_metadata.h"5#include <bpf/bpf_helpers.h>6#include <bpf/bpf_endian.h>7 8struct {9	__uint(type, BPF_MAP_TYPE_XSKMAP);10	__uint(max_entries, 4);11	__type(key, __u32);12	__type(value, __u32);13} xsk SEC(".maps");14 15struct {16	__uint(type, BPF_MAP_TYPE_PROG_ARRAY);17	__uint(max_entries, 1);18	__type(key, __u32);19	__type(value, __u32);20} prog_arr SEC(".maps");21 22extern int bpf_xdp_metadata_rx_timestamp(const struct xdp_md *ctx,23					 __u64 *timestamp) __ksym;24extern int bpf_xdp_metadata_rx_hash(const struct xdp_md *ctx, __u32 *hash,25				    enum xdp_rss_hash_type *rss_type) __ksym;26extern int bpf_xdp_metadata_rx_vlan_tag(const struct xdp_md *ctx,27					__be16 *vlan_proto,28					__u16 *vlan_tci) __ksym;29 30SEC("xdp")31int rx(struct xdp_md *ctx)32{33	void *data, *data_meta, *data_end;34	struct ipv6hdr *ip6h = NULL;35	struct ethhdr *eth = NULL;36	struct udphdr *udp = NULL;37	struct iphdr *iph = NULL;38	struct xdp_meta *meta;39	u64 timestamp = -1;40	int ret;41 42	data = (void *)(long)ctx->data;43	data_end = (void *)(long)ctx->data_end;44	eth = data;45	if (eth + 1 < data_end) {46		if (eth->h_proto == bpf_htons(ETH_P_IP)) {47			iph = (void *)(eth + 1);48			if (iph + 1 < data_end && iph->protocol == IPPROTO_UDP)49				udp = (void *)(iph + 1);50		}51		if (eth->h_proto == bpf_htons(ETH_P_IPV6)) {52			ip6h = (void *)(eth + 1);53			if (ip6h + 1 < data_end && ip6h->nexthdr == IPPROTO_UDP)54				udp = (void *)(ip6h + 1);55		}56		if (udp && udp + 1 > data_end)57			udp = NULL;58	}59 60	if (!udp)61		return XDP_PASS;62 63	/* Forwarding UDP:8080 to AF_XDP */64	if (udp->dest != bpf_htons(8080))65		return XDP_PASS;66 67	/* Reserve enough for all custom metadata. */68 69	ret = bpf_xdp_adjust_meta(ctx, -(int)sizeof(struct xdp_meta));70	if (ret != 0)71		return XDP_DROP;72 73	data = (void *)(long)ctx->data;74	data_meta = (void *)(long)ctx->data_meta;75 76	if (data_meta + sizeof(struct xdp_meta) > data)77		return XDP_DROP;78 79	meta = data_meta;80 81	/* Export metadata. */82 83	/* We expect veth bpf_xdp_metadata_rx_timestamp to return 0 HW84	 * timestamp, so put some non-zero value into AF_XDP frame for85	 * the userspace.86	 */87	bpf_xdp_metadata_rx_timestamp(ctx, &timestamp);88	if (timestamp == 0)89		meta->rx_timestamp = 1;90 91	bpf_xdp_metadata_rx_hash(ctx, &meta->rx_hash, &meta->rx_hash_type);92	bpf_xdp_metadata_rx_vlan_tag(ctx, &meta->rx_vlan_proto,93				     &meta->rx_vlan_tci);94 95	return bpf_redirect_map(&xsk, ctx->rx_queue_index, XDP_PASS);96}97 98char _license[] SEC("license") = "GPL";99