Skip to content

Commit 9c441fe

Browse files
SPYFFAlexei Starovoitov
authored andcommitted
selftests/bpf: Add test for SO_BINDTODEVICE opt of bpf_setsockopt
This test intended to verify if SO_BINDTODEVICE option works in bpf_setsockopt. Because we already in the SOL_SOCKET level in this connect bpf prog its safe to verify the sanity in the beginning of the connect_v4_prog by calling the bind_to_device test helper. The testing environment already created by the test_sock_addr.sh script so this test assume that two netdevices already existing in the system: veth pair with names test_sock_addr1 and test_sock_addr2. The test will try to bind the socket to those devices first. Then the test assume there are no netdevice with "nonexistent_dev" name so the bpf_setsockopt will give use ENODEV error. At the end the test remove the device binding from the socket by binding it to an empty name. Signed-off-by: Ferenc Fejes <[email protected]> Signed-off-by: Alexei Starovoitov <[email protected]> Link: https://lore.kernel.org/bpf/3f055b8e45c65639c5c73d0b4b6c589e60b86f15.1590871065.git.fejes@inf.elte.hu
1 parent 70c5899 commit 9c441fe

File tree

1 file changed

+33
-0
lines changed

1 file changed

+33
-0
lines changed

tools/testing/selftests/bpf/progs/connect4_prog.c

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@
99
#include <linux/in6.h>
1010
#include <sys/socket.h>
1111
#include <netinet/tcp.h>
12+
#include <linux/if.h>
13+
#include <errno.h>
1214

1315
#include <bpf/bpf_helpers.h>
1416
#include <bpf/bpf_endian.h>
@@ -21,6 +23,10 @@
2123
#define TCP_CA_NAME_MAX 16
2224
#endif
2325

26+
#ifndef IFNAMSIZ
27+
#define IFNAMSIZ 16
28+
#endif
29+
2430
int _version SEC("version") = 1;
2531

2632
__attribute__ ((noinline))
@@ -75,6 +81,29 @@ static __inline int set_cc(struct bpf_sock_addr *ctx)
7581
return 0;
7682
}
7783

84+
static __inline int bind_to_device(struct bpf_sock_addr *ctx)
85+
{
86+
char veth1[IFNAMSIZ] = "test_sock_addr1";
87+
char veth2[IFNAMSIZ] = "test_sock_addr2";
88+
char missing[IFNAMSIZ] = "nonexistent_dev";
89+
char del_bind[IFNAMSIZ] = "";
90+
91+
if (bpf_setsockopt(ctx, SOL_SOCKET, SO_BINDTODEVICE,
92+
&veth1, sizeof(veth1)))
93+
return 1;
94+
if (bpf_setsockopt(ctx, SOL_SOCKET, SO_BINDTODEVICE,
95+
&veth2, sizeof(veth2)))
96+
return 1;
97+
if (bpf_setsockopt(ctx, SOL_SOCKET, SO_BINDTODEVICE,
98+
&missing, sizeof(missing)) != -ENODEV)
99+
return 1;
100+
if (bpf_setsockopt(ctx, SOL_SOCKET, SO_BINDTODEVICE,
101+
&del_bind, sizeof(del_bind)))
102+
return 1;
103+
104+
return 0;
105+
}
106+
78107
SEC("cgroup/connect4")
79108
int connect_v4_prog(struct bpf_sock_addr *ctx)
80109
{
@@ -88,6 +117,10 @@ int connect_v4_prog(struct bpf_sock_addr *ctx)
88117
tuple.ipv4.daddr = bpf_htonl(DST_REWRITE_IP4);
89118
tuple.ipv4.dport = bpf_htons(DST_REWRITE_PORT4);
90119

120+
/* Bind to device and unbind it. */
121+
if (bind_to_device(ctx))
122+
return 0;
123+
91124
if (ctx->type != SOCK_STREAM && ctx->type != SOCK_DGRAM)
92125
return 0;
93126
else if (ctx->type == SOCK_STREAM)

0 commit comments

Comments
 (0)