-
Notifications
You must be signed in to change notification settings - Fork 89
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Adds the draft of the XDP scheduler testing tool
This commit contains the XDP scheduling framework. It consists of a testing program called xdp_scheduler_tester, XDP and DEQUEUE schedulers, and trace files that the xdp_scheduler_tester program uses to check the XDP schedulers for correctness. The FIFO and PIFO schedulers are fully functional in this commit. However, it defines flows as UDP port numbers. However, future commits will change the flow definition to a five-tuple instead. The WFQ implementation is partially complete. It needs changes on the dequeue hook and has a few verifier issues preventing the current version from loading. Signed-off-by: Frey Alfredsson <[email protected]>
- Loading branch information
1 parent
ce71462
commit 8416368
Showing
11 changed files
with
1,133 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause) | ||
|
||
USER_TARGETS := xdp_scheduler_tester | ||
BPF_TARGETS := $(patsubst %.c,%,$(wildcard *.bpf.c)) | ||
|
||
# Depend on bpftool for auto generating | ||
# | ||
|
||
LIB_DIR = ../lib | ||
|
||
include $(LIB_DIR)/common.mk |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
#define EEXIST 17 /* File exists */ | ||
|
||
#define BPF_MAP_TYPE_PIFO 31 | ||
|
||
static long (*bpf_packet_dequeue)(void *ctx, void *map, __u64 flags) = (void *) 181; | ||
static long (*bpf_packet_return)(void *ctx, void *pkt) = (void *) 183; | ||
|
||
static __always_inline void * | ||
bpf_map_lookup_or_try_init(void *map, const void *key, const void *init) | ||
{ | ||
void *val; | ||
long err; | ||
|
||
val = bpf_map_lookup_elem(map, key); | ||
if (val) | ||
return val; | ||
|
||
err = bpf_map_update_elem(map, key, init, BPF_NOEXIST); | ||
if (err && err != -EEXIST) | ||
return 0; | ||
|
||
return bpf_map_lookup_elem(map, key); | ||
} | ||
|
||
static __always_inline int bpf_max(__u64 left, __u64 right) | ||
{ | ||
return right > left ? right : left; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
# Used for debugging the xdp_scheduler_tester syntax | ||
global bpf file=./xdp_scheduler_fifo.bpf.o | ||
|
||
udp eth proto=2 dst port=8080 # In-line comment | ||
udp eth proto=1 dst port=8080 | ||
dequeue udp eth proto=1 dst port=8080 | ||
dequeue udp eth proto=2 dst port=8080 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
global bpf file=./xdp_scheduler_fifo.bpf.o | ||
udp dst port=8080 | ||
udp dst port=8081 | ||
udp dst port=8082 | ||
dequeue udp dst port=8080 | ||
dequeue udp dst port=8081 | ||
dequeue udp dst port=8082 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
global bpf file=./xdp_scheduler_pifo.bpf.o | ||
udp dst port=8002 | ||
udp dst port=8000 | ||
udp dst port=8001 | ||
dequeue udp dst port=8000 | ||
dequeue udp dst port=8001 | ||
dequeue udp dst port=8002 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,96 @@ | ||
// SPDX-License-Identifier: GPL-2.0 | ||
/* Copyright (c) 2022 Freysteinn Alfredsson <[email protected]> */ | ||
|
||
#include <vmlinux_local.h> | ||
#include <linux/bpf.h> | ||
#include <bpf/bpf_endian.h> | ||
#include <bpf/bpf_helpers.h> | ||
#include <xdp/parsing_helpers.h> | ||
|
||
#include "bpf_local_helpers.h" | ||
|
||
struct { | ||
__uint(type, BPF_MAP_TYPE_PIFO); | ||
__uint(key_size, sizeof(__u32)); | ||
__uint(value_size, sizeof(__u32)); | ||
__uint(max_entries, 1024); | ||
} pifo_map SEC(".maps"); | ||
|
||
/* Simple FIFO */ | ||
SEC("xdp") | ||
int enqueue_prog(struct xdp_md *xdp) | ||
{ | ||
void *data = (void *)(long)xdp->data; | ||
void *data_end = (void *)(long)xdp->data_end; | ||
struct ethhdr *eth = data; | ||
|
||
if (eth + 1 > data_end) | ||
return XDP_DROP; | ||
|
||
return bpf_redirect_map(&pifo_map, 0, 0); | ||
} | ||
|
||
SEC("dequeue") | ||
int dequeue_prog(struct dequeue_ctx *ctx) | ||
{ | ||
void *pkt = (void *) bpf_packet_dequeue(ctx, &pifo_map, 0); | ||
if (!pkt) | ||
return 0; | ||
else | ||
return bpf_packet_return(ctx, pkt); | ||
} | ||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
/* Weighted Fair-Queueing */ | ||
/* | ||
SEC("xdp") | ||
int xdp_wfq(struct xdp_md *xdp) | ||
{ | ||
void *data = (void *)(long)xdp->data; | ||
void *data_end = (void *)(long)xdp->data_end; | ||
struct ethhdr *eth = data; | ||
__u16 proto; | ||
__u16 pifo; | ||
if (eth + 1 > data_end) | ||
return XDP_DROP; | ||
proto = bpf_ntohs(eth->h_proto); | ||
if (proto == 0) | ||
pifo = proto; | ||
else if (proto == 1) | ||
pifo = proto; | ||
else | ||
pifo = 2; | ||
bpf_printk("Kern XDP prio %d", pifo); | ||
return bpf_redirect_map(&pifo_map, 0, pifo); | ||
} | ||
SEC("dequeue") | ||
int dequeue_wfq(struct dequeue_ctx *ctx) | ||
{ | ||
void *pkt = (void *) bpf_packet_dequeue(ctx, &pifo_map, 0); | ||
if (!pkt) | ||
return 0; | ||
else { | ||
bpf_printk("Kern DEQUEUE"); | ||
return bpf_packet_return(ctx, pkt); | ||
} | ||
} | ||
*/ | ||
|
||
char _license[] SEC("license") = "GPL"; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,82 @@ | ||
// SPDX-License-Identifier: GPL-2.0 | ||
/* Copyright (c) 2022 Freysteinn Alfredsson <[email protected]> */ | ||
|
||
#include <vmlinux_local.h> | ||
#include <linux/bpf.h> | ||
#include <bpf/bpf_endian.h> | ||
#include <bpf/bpf_helpers.h> | ||
#include <xdp/parsing_helpers.h> | ||
|
||
#include "bpf_local_helpers.h" | ||
|
||
struct { | ||
__uint(type, BPF_MAP_TYPE_PIFO); | ||
__uint(key_size, sizeof(__u32)); | ||
__uint(value_size, sizeof(__u32)); | ||
__uint(max_entries, 1024); | ||
} pifo_map SEC(".maps"); | ||
|
||
/* Simple PIFO strict priority */ | ||
SEC("xdp") | ||
int enqueue_prog(struct xdp_md *xdp) | ||
{ | ||
void *data_end = (void *)(long)xdp->data_end; | ||
void *data = (void *)(long)xdp->data; | ||
struct hdr_cursor nh = { .pos = data }; | ||
struct ethhdr *eth; | ||
int eth_type; | ||
struct iphdr *iphdr; | ||
struct ipv6hdr *ipv6hdr; | ||
int ip_type; | ||
struct udphdr *udphdr; | ||
int udp_len; | ||
int udp_dst_port; | ||
__u16 prio = 0; | ||
|
||
/* Parse Ethernet and IP/IPv6 headers */ | ||
eth_type = parse_ethhdr(&nh, data_end, ð); | ||
if (eth_type == bpf_htons(ETH_P_IP)) { | ||
ip_type = parse_iphdr(&nh, data_end, &iphdr); | ||
if (ip_type != IPPROTO_UDP) { | ||
goto out; | ||
} | ||
} else if (eth_type == bpf_htons(ETH_P_IPV6)) { | ||
ip_type = parse_ip6hdr(&nh, data_end, &ipv6hdr); | ||
if (ip_type != IPPROTO_UDP) { | ||
goto out; | ||
} | ||
} else { | ||
goto out; | ||
} | ||
|
||
/* Parse UDP header */ | ||
udp_len = parse_udphdr(&nh, data_end, &udphdr); | ||
if (udp_len < 0) { | ||
goto out; | ||
} | ||
udp_dst_port = bpf_htons(udphdr->dest); | ||
|
||
/* Calculate scheduling priority */ | ||
prio = 0; | ||
if (udp_dst_port == 8001) | ||
prio = 1; | ||
else if (udp_dst_port > 8001) | ||
prio = 2; | ||
|
||
return bpf_redirect_map(&pifo_map, prio, 0); | ||
out: | ||
return XDP_DROP; | ||
} | ||
|
||
SEC("dequeue") | ||
int dequeue_prog(struct dequeue_ctx *ctx) | ||
{ | ||
void *pkt = (void *) bpf_packet_dequeue(ctx, &pifo_map, 0); | ||
if (!pkt) | ||
return 0; | ||
else { | ||
return bpf_packet_return(ctx, pkt); | ||
} | ||
} | ||
|
||
char _license[] SEC("license") = "GPL"; |
Oops, something went wrong.