forked from torvalds/linux
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
bpf: Add tests and samples for LWT-BPF
Adds a series of tests to verify the functionality of attaching BPF programs at LWT hooks. Also adds a sample which collects a histogram of packet sizes which pass through an LWT hook. $ ./lwt_len_hist.sh Starting netserver with host 'IN(6)ADDR_ANY' port '12865' and family AF_UNSPEC MIGRATED TCP STREAM TEST from 0.0.0.0 (0.0.0.0) port 0 AF_INET to 192.168.253.2 () port 0 AF_INET : demo Recv Send Send Socket Socket Message Elapsed Size Size Size Time Throughput bytes bytes bytes secs. 10^6bits/sec 87380 16384 16384 10.00 39857.69 1 -> 1 : 0 | | 2 -> 3 : 0 | | 4 -> 7 : 0 | | 8 -> 15 : 0 | | 16 -> 31 : 0 | | 32 -> 63 : 22 | | 64 -> 127 : 98 | | 128 -> 255 : 213 | | 256 -> 511 : 1444251 |******** | 512 -> 1023 : 660610 |*** | 1024 -> 2047 : 535241 |** | 2048 -> 4095 : 19 | | 4096 -> 8191 : 180 | | 8192 -> 16383 : 5578023 |************************************* | 16384 -> 32767 : 632099 |*** | 32768 -> 65535 : 6575 | | Signed-off-by: Thomas Graf <[email protected]> Acked-by: Alexei Starovoitov <[email protected]> Signed-off-by: David S. Miller <[email protected]>
- Loading branch information
Showing
7 changed files
with
855 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
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
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,37 @@ | ||
#!/bin/bash | ||
|
||
NS1=lwt_ns1 | ||
VETH0=tst_lwt1a | ||
VETH1=tst_lwt1b | ||
|
||
TRACE_ROOT=/sys/kernel/debug/tracing | ||
|
||
function cleanup { | ||
ip route del 192.168.253.2/32 dev $VETH0 2> /dev/null | ||
ip link del $VETH0 2> /dev/null | ||
ip link del $VETH1 2> /dev/null | ||
ip netns exec $NS1 killall netserver | ||
ip netns delete $NS1 2> /dev/null | ||
} | ||
|
||
cleanup | ||
|
||
ip netns add $NS1 | ||
ip link add $VETH0 type veth peer name $VETH1 | ||
ip link set dev $VETH0 up | ||
ip addr add 192.168.253.1/24 dev $VETH0 | ||
ip link set $VETH1 netns $NS1 | ||
ip netns exec $NS1 ip link set dev $VETH1 up | ||
ip netns exec $NS1 ip addr add 192.168.253.2/24 dev $VETH1 | ||
ip netns exec $NS1 netserver | ||
|
||
echo 1 > ${TRACE_ROOT}/tracing_on | ||
cp /dev/null ${TRACE_ROOT}/trace | ||
ip route add 192.168.253.2/32 encap bpf out obj lwt_len_hist_kern.o section len_hist dev $VETH0 | ||
netperf -H 192.168.253.2 -t TCP_STREAM | ||
cat ${TRACE_ROOT}/trace | grep -v '^#' | ||
./lwt_len_hist | ||
cleanup | ||
echo 0 > ${TRACE_ROOT}/tracing_on | ||
|
||
exit 0 |
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 @@ | ||
/* Copyright (c) 2016 Thomas Graf <[email protected]> | ||
* | ||
* This program is free software; you can redistribute it and/or | ||
* modify it under the terms of version 2 of the GNU General Public | ||
* License as published by the Free Software Foundation. | ||
* | ||
* This program is distributed in the hope that it will be useful, but | ||
* WITHOUT ANY WARRANTY; without even the implied warranty of | ||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
* General Public License for more details. | ||
*/ | ||
|
||
#include <uapi/linux/bpf.h> | ||
#include <uapi/linux/if_ether.h> | ||
#include <uapi/linux/ip.h> | ||
#include <uapi/linux/in.h> | ||
#include "bpf_helpers.h" | ||
|
||
# define printk(fmt, ...) \ | ||
({ \ | ||
char ____fmt[] = fmt; \ | ||
bpf_trace_printk(____fmt, sizeof(____fmt), \ | ||
##__VA_ARGS__); \ | ||
}) | ||
|
||
struct bpf_elf_map { | ||
__u32 type; | ||
__u32 size_key; | ||
__u32 size_value; | ||
__u32 max_elem; | ||
__u32 flags; | ||
__u32 id; | ||
__u32 pinning; | ||
}; | ||
|
||
struct bpf_elf_map SEC("maps") lwt_len_hist_map = { | ||
.type = BPF_MAP_TYPE_PERCPU_HASH, | ||
.size_key = sizeof(__u64), | ||
.size_value = sizeof(__u64), | ||
.pinning = 2, | ||
.max_elem = 1024, | ||
}; | ||
|
||
static unsigned int log2(unsigned int v) | ||
{ | ||
unsigned int r; | ||
unsigned int shift; | ||
|
||
r = (v > 0xFFFF) << 4; v >>= r; | ||
shift = (v > 0xFF) << 3; v >>= shift; r |= shift; | ||
shift = (v > 0xF) << 2; v >>= shift; r |= shift; | ||
shift = (v > 0x3) << 1; v >>= shift; r |= shift; | ||
r |= (v >> 1); | ||
return r; | ||
} | ||
|
||
static unsigned int log2l(unsigned long v) | ||
{ | ||
unsigned int hi = v >> 32; | ||
if (hi) | ||
return log2(hi) + 32; | ||
else | ||
return log2(v); | ||
} | ||
|
||
SEC("len_hist") | ||
int do_len_hist(struct __sk_buff *skb) | ||
{ | ||
__u64 *value, key, init_val = 1; | ||
|
||
key = log2l(skb->len); | ||
|
||
value = bpf_map_lookup_elem(&lwt_len_hist_map, &key); | ||
if (value) | ||
__sync_fetch_and_add(value, 1); | ||
else | ||
bpf_map_update_elem(&lwt_len_hist_map, &key, &init_val, BPF_ANY); | ||
|
||
return BPF_OK; | ||
} | ||
|
||
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,76 @@ | ||
#include <linux/unistd.h> | ||
#include <linux/bpf.h> | ||
|
||
#include <stdlib.h> | ||
#include <stdio.h> | ||
#include <unistd.h> | ||
#include <string.h> | ||
#include <errno.h> | ||
#include <arpa/inet.h> | ||
|
||
#include "libbpf.h" | ||
#include "bpf_util.h" | ||
|
||
#define MAX_INDEX 64 | ||
#define MAX_STARS 38 | ||
|
||
static void stars(char *str, long val, long max, int width) | ||
{ | ||
int i; | ||
|
||
for (i = 0; i < (width * val / max) - 1 && i < width - 1; i++) | ||
str[i] = '*'; | ||
if (val > max) | ||
str[i - 1] = '+'; | ||
str[i] = '\0'; | ||
} | ||
|
||
int main(int argc, char **argv) | ||
{ | ||
unsigned int nr_cpus = bpf_num_possible_cpus(); | ||
const char *map_filename = "/sys/fs/bpf/tc/globals/lwt_len_hist_map"; | ||
uint64_t values[nr_cpus], sum, max_value = 0, data[MAX_INDEX] = {}; | ||
uint64_t key = 0, next_key, max_key = 0; | ||
char starstr[MAX_STARS]; | ||
int i, map_fd; | ||
|
||
map_fd = bpf_obj_get(map_filename); | ||
if (map_fd < 0) { | ||
fprintf(stderr, "bpf_obj_get(%s): %s(%d)\n", | ||
map_filename, strerror(errno), errno); | ||
return -1; | ||
} | ||
|
||
while (bpf_get_next_key(map_fd, &key, &next_key) == 0) { | ||
if (next_key >= MAX_INDEX) { | ||
fprintf(stderr, "Key %lu out of bounds\n", next_key); | ||
continue; | ||
} | ||
|
||
bpf_lookup_elem(map_fd, &next_key, values); | ||
|
||
sum = 0; | ||
for (i = 0; i < nr_cpus; i++) | ||
sum += values[i]; | ||
|
||
data[next_key] = sum; | ||
if (sum && next_key > max_key) | ||
max_key = next_key; | ||
|
||
if (sum > max_value) | ||
max_value = sum; | ||
|
||
key = next_key; | ||
} | ||
|
||
for (i = 1; i <= max_key + 1; i++) { | ||
stars(starstr, data[i - 1], max_value, MAX_STARS); | ||
printf("%8ld -> %-8ld : %-8ld |%-*s|\n", | ||
(1l << i) >> 1, (1l << i) - 1, data[i - 1], | ||
MAX_STARS, starstr); | ||
} | ||
|
||
close(map_fd); | ||
|
||
return 0; | ||
} |
Oops, something went wrong.