1*6c77997bSYan Zhai // SPDX-License-Identifier: GPL-2.0
2*6c77997bSYan Zhai #include <inttypes.h>
3*6c77997bSYan Zhai #include <linux/bpf.h>
4*6c77997bSYan Zhai #include <bpf/bpf_endian.h>
5*6c77997bSYan Zhai #include <bpf/bpf_helpers.h>
6*6c77997bSYan Zhai #include <linux/if_ether.h>
7*6c77997bSYan Zhai #include <linux/ip.h>
8*6c77997bSYan Zhai 
9*6c77997bSYan Zhai /* This function extracts the last byte of the daddr, and uses it
10*6c77997bSYan Zhai  * as output dev index.
11*6c77997bSYan Zhai  */
12*6c77997bSYan Zhai SEC("lwt_xmit")
test_lwt_reroute(struct __sk_buff * skb)13*6c77997bSYan Zhai int test_lwt_reroute(struct __sk_buff *skb)
14*6c77997bSYan Zhai {
15*6c77997bSYan Zhai 	struct iphdr *iph = NULL;
16*6c77997bSYan Zhai 	void *start = (void *)(long)skb->data;
17*6c77997bSYan Zhai 	void *end = (void *)(long)skb->data_end;
18*6c77997bSYan Zhai 
19*6c77997bSYan Zhai 	/* set mark at most once */
20*6c77997bSYan Zhai 	if (skb->mark != 0)
21*6c77997bSYan Zhai 		return BPF_OK;
22*6c77997bSYan Zhai 
23*6c77997bSYan Zhai 	if (start + sizeof(*iph) > end)
24*6c77997bSYan Zhai 		return BPF_DROP;
25*6c77997bSYan Zhai 
26*6c77997bSYan Zhai 	iph = (struct iphdr *)start;
27*6c77997bSYan Zhai 	skb->mark = bpf_ntohl(iph->daddr) & 0xff;
28*6c77997bSYan Zhai 
29*6c77997bSYan Zhai 	/* do not reroute x.x.x.0 packets */
30*6c77997bSYan Zhai 	if (skb->mark == 0)
31*6c77997bSYan Zhai 		return BPF_OK;
32*6c77997bSYan Zhai 
33*6c77997bSYan Zhai 	return BPF_LWT_REROUTE;
34*6c77997bSYan Zhai }
35*6c77997bSYan Zhai 
36*6c77997bSYan Zhai char _license[] SEC("license") = "GPL";
37