-
Notifications
You must be signed in to change notification settings - Fork 111
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
selftests/bpf: Selftest for sys_connect hooks
Add selftest for BPF_CGROUP_INET4_CONNECT and BPF_CGROUP_INET6_CONNECT attach types. Try to connect(2) to specified IP:port and test that: * remote IP:port pair is overridden; * local end of connection is bound to specified IP. All combinations of IPv4/IPv6 and TCP/UDP are tested. Example: # tcpdump -pn -i lo -w connect.pcap 2>/dev/null & [1] 478 # strace -qqf -e connect -o connect.trace ./test_sock_addr.sh Wait for testing IPv4/IPv6 to become available ... OK Load bind4 with invalid type (can pollute stderr) ... REJECTED Load bind4 with valid type ... OK Attach bind4 with invalid type ... REJECTED Attach bind4 with valid type ... OK Load connect4 with invalid type (can pollute stderr) libbpf: load bpf \ program failed: Permission denied libbpf: -- BEGIN DUMP LOG --- libbpf: 0: (b7) r2 = 23569 1: (63) *(u32 *)(r1 +24) = r2 2: (b7) r2 = 16777343 3: (63) *(u32 *)(r1 +4) = r2 invalid bpf_context access off=4 size=4 [ 1518.404609] random: crng init done libbpf: -- END LOG -- libbpf: failed to load program 'cgroup/connect4' libbpf: failed to load object './connect4_prog.o' ... REJECTED Load connect4 with valid type ... OK Attach connect4 with invalid type ... REJECTED Attach connect4 with valid type ... OK Test case #1 (IPv4/TCP): Requested: bind(192.168.1.254, 4040) .. Actual: bind(127.0.0.1, 4444) Requested: connect(192.168.1.254, 4040) from (*, *) .. Actual: connect(127.0.0.1, 4444) from (127.0.0.4, 56068) Test case #2 (IPv4/UDP): Requested: bind(192.168.1.254, 4040) .. Actual: bind(127.0.0.1, 4444) Requested: connect(192.168.1.254, 4040) from (*, *) .. Actual: connect(127.0.0.1, 4444) from (127.0.0.4, 56447) Load bind6 with invalid type (can pollute stderr) ... REJECTED Load bind6 with valid type ... OK Attach bind6 with invalid type ... REJECTED Attach bind6 with valid type ... OK Load connect6 with invalid type (can pollute stderr) libbpf: load bpf \ program failed: Permission denied libbpf: -- BEGIN DUMP LOG --- libbpf: 0: (b7) r6 = 0 1: (63) *(u32 *)(r1 +12) = r6 invalid bpf_context access off=12 size=4 libbpf: -- END LOG -- libbpf: failed to load program 'cgroup/connect6' libbpf: failed to load object './connect6_prog.o' ... REJECTED Load connect6 with valid type ... OK Attach connect6 with invalid type ... REJECTED Attach connect6 with valid type ... OK Test case #3 (IPv6/TCP): Requested: bind(face:b00c:1234:5678::abcd, 6060) .. Actual: bind(::1, 6666) Requested: connect(face:b00c:1234:5678::abcd, 6060) from (*, *) Actual: connect(::1, 6666) from (::6, 37458) Test case #4 (IPv6/UDP): Requested: bind(face:b00c:1234:5678::abcd, 6060) .. Actual: bind(::1, 6666) Requested: connect(face:b00c:1234:5678::abcd, 6060) from (*, *) Actual: connect(::1, 6666) from (::6, 39315) ### SUCCESS # egrep 'connect\(.*AF_INET' connect.trace | \ > egrep -vw 'htons\(1025\)' | fold -b -s -w 72 502 connect(7, {sa_family=AF_INET, sin_port=htons(4040), sin_addr=inet_addr("192.168.1.254")}, 128) = 0 502 connect(8, {sa_family=AF_INET, sin_port=htons(4040), sin_addr=inet_addr("192.168.1.254")}, 128) = 0 502 connect(9, {sa_family=AF_INET6, sin6_port=htons(6060), inet_pton(AF_INET6, "face:b00c:1234:5678::abcd", &sin6_addr), sin6_flowinfo=0, sin6_scope_id=0}, 128) = 0 502 connect(10, {sa_family=AF_INET6, sin6_port=htons(6060), inet_pton(AF_INET6, "face:b00c:1234:5678::abcd", &sin6_addr), sin6_flowinfo=0, sin6_scope_id=0}, 128) = 0 # fg tcpdump -pn -i lo -w connect.pcap 2> /dev/null # tcpdump -r connect.pcap -n tcp | cut -c 1-72 reading from file connect.pcap, link-type EN10MB (Ethernet) 17:57:40.383533 IP 127.0.0.4.56068 > 127.0.0.1.4444: Flags [S], seq 1333 17:57:40.383566 IP 127.0.0.1.4444 > 127.0.0.4.56068: Flags [S.], seq 112 17:57:40.383589 IP 127.0.0.4.56068 > 127.0.0.1.4444: Flags [.], ack 1, w 17:57:40.384578 IP 127.0.0.1.4444 > 127.0.0.4.56068: Flags [R.], seq 1, 17:57:40.403327 IP6 ::6.37458 > ::1.6666: Flags [S], seq 406513443, win 17:57:40.403357 IP6 ::1.6666 > ::6.37458: Flags [S.], seq 2448389240, ac 17:57:40.403376 IP6 ::6.37458 > ::1.6666: Flags [.], ack 1, win 342, opt 17:57:40.404263 IP6 ::1.6666 > ::6.37458: Flags [R.], seq 1, ack 1, win Signed-off-by: Andrey Ignatov <rdna@fb.com> Signed-off-by: Alexei Starovoitov <ast@kernel.org> Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
- Loading branch information
Showing
8 changed files
with
284 additions
and
4 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
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,45 @@ | ||
// SPDX-License-Identifier: GPL-2.0 | ||
// Copyright (c) 2018 Facebook | ||
|
||
#include <string.h> | ||
|
||
#include <linux/stddef.h> | ||
#include <linux/bpf.h> | ||
#include <linux/in.h> | ||
#include <linux/in6.h> | ||
#include <sys/socket.h> | ||
|
||
#include "bpf_helpers.h" | ||
#include "bpf_endian.h" | ||
|
||
#define SRC_REWRITE_IP4 0x7f000004U | ||
#define DST_REWRITE_IP4 0x7f000001U | ||
#define DST_REWRITE_PORT4 4444 | ||
|
||
int _version SEC("version") = 1; | ||
|
||
SEC("cgroup/connect4") | ||
int connect_v4_prog(struct bpf_sock_addr *ctx) | ||
{ | ||
struct sockaddr_in sa; | ||
|
||
/* Rewrite destination. */ | ||
ctx->user_ip4 = bpf_htonl(DST_REWRITE_IP4); | ||
ctx->user_port = bpf_htons(DST_REWRITE_PORT4); | ||
|
||
if (ctx->type == SOCK_DGRAM || ctx->type == SOCK_STREAM) { | ||
///* Rewrite source. */ | ||
memset(&sa, 0, sizeof(sa)); | ||
|
||
sa.sin_family = AF_INET; | ||
sa.sin_port = bpf_htons(0); | ||
sa.sin_addr.s_addr = bpf_htonl(SRC_REWRITE_IP4); | ||
|
||
if (bpf_bind(ctx, (struct sockaddr *)&sa, sizeof(sa)) != 0) | ||
return 0; | ||
} | ||
|
||
return 1; | ||
} | ||
|
||
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,61 @@ | ||
// SPDX-License-Identifier: GPL-2.0 | ||
// Copyright (c) 2018 Facebook | ||
|
||
#include <string.h> | ||
|
||
#include <linux/stddef.h> | ||
#include <linux/bpf.h> | ||
#include <linux/in.h> | ||
#include <linux/in6.h> | ||
#include <sys/socket.h> | ||
|
||
#include "bpf_helpers.h" | ||
#include "bpf_endian.h" | ||
|
||
#define SRC_REWRITE_IP6_0 0 | ||
#define SRC_REWRITE_IP6_1 0 | ||
#define SRC_REWRITE_IP6_2 0 | ||
#define SRC_REWRITE_IP6_3 6 | ||
|
||
#define DST_REWRITE_IP6_0 0 | ||
#define DST_REWRITE_IP6_1 0 | ||
#define DST_REWRITE_IP6_2 0 | ||
#define DST_REWRITE_IP6_3 1 | ||
|
||
#define DST_REWRITE_PORT6 6666 | ||
|
||
int _version SEC("version") = 1; | ||
|
||
SEC("cgroup/connect6") | ||
int connect_v6_prog(struct bpf_sock_addr *ctx) | ||
{ | ||
struct sockaddr_in6 sa; | ||
|
||
/* Rewrite destination. */ | ||
ctx->user_ip6[0] = bpf_htonl(DST_REWRITE_IP6_0); | ||
ctx->user_ip6[1] = bpf_htonl(DST_REWRITE_IP6_1); | ||
ctx->user_ip6[2] = bpf_htonl(DST_REWRITE_IP6_2); | ||
ctx->user_ip6[3] = bpf_htonl(DST_REWRITE_IP6_3); | ||
|
||
ctx->user_port = bpf_htons(DST_REWRITE_PORT6); | ||
|
||
if (ctx->type == SOCK_DGRAM || ctx->type == SOCK_STREAM) { | ||
/* Rewrite source. */ | ||
memset(&sa, 0, sizeof(sa)); | ||
|
||
sa.sin6_family = AF_INET6; | ||
sa.sin6_port = bpf_htons(0); | ||
|
||
sa.sin6_addr.s6_addr32[0] = bpf_htonl(SRC_REWRITE_IP6_0); | ||
sa.sin6_addr.s6_addr32[1] = bpf_htonl(SRC_REWRITE_IP6_1); | ||
sa.sin6_addr.s6_addr32[2] = bpf_htonl(SRC_REWRITE_IP6_2); | ||
sa.sin6_addr.s6_addr32[3] = bpf_htonl(SRC_REWRITE_IP6_3); | ||
|
||
if (bpf_bind(ctx, (struct sockaddr *)&sa, sizeof(sa)) != 0) | ||
return 0; | ||
} | ||
|
||
return 1; | ||
} | ||
|
||
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
Oops, something went wrong.