xref: /linux/tools/testing/selftests/bpf/progs/test_dst_clear.c (revision aec2f682d47c54ef434b2d440992626d80b1ebdc)
1 // SPDX-License-Identifier: GPL-2.0
2 /* Copyright (c) 2026 Meta Platforms, Inc. and affiliates. */
3 
4 #include "vmlinux.h"
5 #include "bpf_tracing_net.h"
6 #include <bpf/bpf_helpers.h>
7 #include <bpf/bpf_endian.h>
8 
9 #define UDP_TEST_PORT 7777
10 
11 void *bpf_cast_to_kern_ctx(void *) __ksym;
12 
13 bool had_dst = false;
14 bool dst_cleared = false;
15 
16 SEC("tc/egress")
17 int dst_clear(struct __sk_buff *skb)
18 {
19 	struct sk_buff *kskb;
20 	struct iphdr iph;
21 	struct udphdr udph;
22 	int err;
23 
24 	if (skb->protocol != __bpf_constant_htons(ETH_P_IP))
25 		return TC_ACT_OK;
26 
27 	if (bpf_skb_load_bytes(skb, ETH_HLEN, &iph, sizeof(iph)))
28 		return TC_ACT_OK;
29 
30 	if (iph.protocol != IPPROTO_UDP)
31 		return TC_ACT_OK;
32 
33 	if (bpf_skb_load_bytes(skb, ETH_HLEN + sizeof(iph), &udph, sizeof(udph)))
34 		return TC_ACT_OK;
35 
36 	if (udph.dest != __bpf_constant_htons(UDP_TEST_PORT))
37 		return TC_ACT_OK;
38 
39 	kskb = bpf_cast_to_kern_ctx(skb);
40 	had_dst = (kskb->_skb_refdst != 0);
41 
42 	/* Same-protocol encap (IPIP): protocol stays IPv4, but the dst
43 	 * from the original routing is no longer valid for the outer hdr.
44 	 */
45 	err = bpf_skb_adjust_room(skb, (s32)sizeof(struct iphdr),
46 				  BPF_ADJ_ROOM_MAC,
47 				  BPF_F_ADJ_ROOM_FIXED_GSO |
48 				  BPF_F_ADJ_ROOM_ENCAP_L3_IPV4);
49 	if (err)
50 		return TC_ACT_SHOT;
51 
52 	dst_cleared = (kskb->_skb_refdst == 0);
53 
54 	return TC_ACT_SHOT;
55 }
56 
57 char __license[] SEC("license") = "GPL";
58