There is no lwt test case for BPF_REROUTE yet. Add test cases for both normal and abnormal situations. The abnormal situation is set up with an fq qdisc on the reroute target device. Without proper fixes, overflow this qdisc queue limit (to trigger a drop) would panic the kernel. Signed-off-by: Yan Zhai <yan@cloudflare.com> Signed-off-by: Daniel Borkmann <daniel@iogearbox.net> Link: https://lore.kernel.org/bpf/62c8ddc1e924269dcf80d2e8af1a1e632cee0b3a.1692326837.git.yan@cloudflare.com
36 lines
795 B
C
36 lines
795 B
C
// SPDX-License-Identifier: GPL-2.0
|
|
#include <inttypes.h>
|
|
#include <linux/bpf.h>
|
|
#include <bpf/bpf_endian.h>
|
|
#include <bpf/bpf_helpers.h>
|
|
#include <linux/if_ether.h>
|
|
#include <linux/ip.h>
|
|
|
|
/* This function extracts the last byte of the daddr, and uses it
|
|
* as output dev index.
|
|
*/
|
|
SEC("lwt_xmit")
|
|
int test_lwt_reroute(struct __sk_buff *skb)
|
|
{
|
|
struct iphdr *iph = NULL;
|
|
void *start = (void *)(long)skb->data;
|
|
void *end = (void *)(long)skb->data_end;
|
|
|
|
/* set mark at most once */
|
|
if (skb->mark != 0)
|
|
return BPF_OK;
|
|
|
|
if (start + sizeof(*iph) > end)
|
|
return BPF_DROP;
|
|
|
|
iph = (struct iphdr *)start;
|
|
skb->mark = bpf_ntohl(iph->daddr) & 0xff;
|
|
|
|
/* do not reroute x.x.x.0 packets */
|
|
if (skb->mark == 0)
|
|
return BPF_OK;
|
|
|
|
return BPF_LWT_REROUTE;
|
|
}
|
|
|
|
char _license[] SEC("license") = "GPL";
|