Skip to content

Commit

Permalink
bpf: selftests add sockmap tests
Browse files Browse the repository at this point in the history
This generates a set of sockets, attaches BPF programs, and sends some
simple traffic using basic send/recv pattern. Additionally, we do a bunch
of negative tests to ensure adding/removing socks out of the sockmap fail
correctly.

Signed-off-by: John Fastabend <john.fastabend@gmail.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
  • Loading branch information
John Fastabend authored and David S. Miller committed Aug 16, 2017
1 parent 41bc94f commit 6f6d33f
Show file tree
Hide file tree
Showing 7 changed files with 443 additions and 39 deletions.
29 changes: 29 additions & 0 deletions tools/lib/bpf/libbpf.c
Original file line number Diff line number Diff line change
Expand Up @@ -1744,3 +1744,32 @@ long libbpf_get_error(const void *ptr)
return PTR_ERR(ptr);
return 0;
}

int bpf_prog_load(const char *file, enum bpf_prog_type type,
struct bpf_object **pobj, int *prog_fd)
{
struct bpf_program *prog;
struct bpf_object *obj;
int err;

obj = bpf_object__open(file);
if (IS_ERR(obj))
return -ENOENT;

prog = bpf_program__next(NULL, obj);
if (!prog) {
bpf_object__close(obj);
return -ENOENT;
}

bpf_program__set_type(prog, type);
err = bpf_object__load(obj);
if (err) {
bpf_object__close(obj);
return -EINVAL;
}

*pobj = obj;
*prog_fd = bpf_program__fd(prog);
return 0;
}
2 changes: 2 additions & 0 deletions tools/lib/bpf/libbpf.h
Original file line number Diff line number Diff line change
Expand Up @@ -243,4 +243,6 @@ int bpf_map__pin(struct bpf_map *map, const char *path);

long libbpf_get_error(const void *ptr);

int bpf_prog_load(const char *file, enum bpf_prog_type type,
struct bpf_object **pobj, int *prog_fd);
#endif
2 changes: 1 addition & 1 deletion tools/testing/selftests/bpf/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ TEST_GEN_PROGS = test_verifier test_tag test_maps test_lru_map test_lpm_map test
test_align

TEST_GEN_FILES = test_pkt_access.o test_xdp.o test_l4lb.o test_tcp_estats.o test_obj_id.o \
test_pkt_md_access.o test_xdp_redirect.o
test_pkt_md_access.o test_xdp_redirect.o sockmap_parse_prog.o sockmap_verdict_prog.o

TEST_PROGS := test_kmod.sh test_xdp_redirect.sh

Expand Down
38 changes: 38 additions & 0 deletions tools/testing/selftests/bpf/sockmap_parse_prog.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
#include <linux/bpf.h>
#include "bpf_helpers.h"
#include "bpf_util.h"
#include "bpf_endian.h"

int _version SEC("version") = 1;

#define bpf_printk(fmt, ...) \
({ \
char ____fmt[] = fmt; \
bpf_trace_printk(____fmt, sizeof(____fmt), \
##__VA_ARGS__); \
})

SEC("sk_skb1")
int bpf_prog1(struct __sk_buff *skb)
{
void *data_end = (void *)(long) skb->data_end;
void *data = (void *)(long) skb->data;
__u32 lport = skb->local_port;
__u32 rport = skb->remote_port;
char *d = data;

if (data + 8 > data_end)
return skb->len;

/* This write/read is a bit pointless but tests the verifier and
* strparser handler for read/write pkt data and access into sk
* fields.
*/
d[0] = 1;

bpf_printk("data[0] = (%u): local_port %i remote %i\n",
d[0], lport, bpf_ntohl(rport));
return skb->len;
}

char _license[] SEC("license") = "GPL";
48 changes: 48 additions & 0 deletions tools/testing/selftests/bpf/sockmap_verdict_prog.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
#include <linux/bpf.h>
#include "bpf_helpers.h"
#include "bpf_util.h"
#include "bpf_endian.h"

int _version SEC("version") = 1;

#define bpf_printk(fmt, ...) \
({ \
char ____fmt[] = fmt; \
bpf_trace_printk(____fmt, sizeof(____fmt), \
##__VA_ARGS__); \
})

struct bpf_map_def SEC("maps") sock_map = {
.type = BPF_MAP_TYPE_SOCKMAP,
.key_size = sizeof(int),
.value_size = sizeof(int),
.max_entries = 20,
};

SEC("sk_skb2")
int bpf_prog2(struct __sk_buff *skb)
{
void *data_end = (void *)(long) skb->data_end;
void *data = (void *)(long) skb->data;
__u32 lport = skb->local_port;
__u32 rport = skb->remote_port;
char *d = data;

if (data + 8 > data_end)
return SK_DROP;

d[0] = 0xd;
d[1] = 0xe;
d[2] = 0xa;
d[3] = 0xd;
d[4] = 0xb;
d[5] = 0xe;
d[6] = 0xe;
d[7] = 0xf;

bpf_printk("data[0] = (%u): local_port %i remote %i\n",
d[0], lport, bpf_ntohl(rport));
return bpf_sk_redirect_map(&sock_map, 5, 0);
}

char _license[] SEC("license") = "GPL";
Loading

0 comments on commit 6f6d33f

Please sign in to comment.