mirror of
https://github.com/torvalds/linux.git
synced 2026-04-18 14:53:58 -04:00
bpf, sockmap: Build helper to create connected socket pair
A common operation for testing is to spin up a pair of sockets that are connected. Then we can use these to run specific tests that need to send data, check BPF programs and so on. The sockmap_listen programs already have this logic lets move it into the new sockmap_helpers header file for general use. Signed-off-by: John Fastabend <john.fastabend@gmail.com> Signed-off-by: Daniel Borkmann <daniel@iogearbox.net> Reviewed-by: Jakub Sitnicki <jakub@cloudflare.com> Link: https://lore.kernel.org/bpf/20230523025618.113937-11-john.fastabend@gmail.com
This commit is contained in:
committed by
Daniel Borkmann
parent
4e02588d9a
commit
298970c8af
@@ -269,4 +269,122 @@ static inline struct sockaddr *sockaddr(struct sockaddr_storage *ss)
|
||||
return (struct sockaddr *)ss;
|
||||
}
|
||||
|
||||
static inline int add_to_sockmap(int sock_mapfd, int fd1, int fd2)
|
||||
{
|
||||
u64 value;
|
||||
u32 key;
|
||||
int err;
|
||||
|
||||
key = 0;
|
||||
value = fd1;
|
||||
err = xbpf_map_update_elem(sock_mapfd, &key, &value, BPF_NOEXIST);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
key = 1;
|
||||
value = fd2;
|
||||
return xbpf_map_update_elem(sock_mapfd, &key, &value, BPF_NOEXIST);
|
||||
}
|
||||
|
||||
static inline int create_pair(int s, int family, int sotype, int *c, int *p)
|
||||
{
|
||||
struct sockaddr_storage addr;
|
||||
socklen_t len;
|
||||
int err = 0;
|
||||
|
||||
len = sizeof(addr);
|
||||
err = xgetsockname(s, sockaddr(&addr), &len);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
*c = xsocket(family, sotype, 0);
|
||||
if (*c < 0)
|
||||
return errno;
|
||||
err = xconnect(*c, sockaddr(&addr), len);
|
||||
if (err) {
|
||||
err = errno;
|
||||
goto close_cli0;
|
||||
}
|
||||
|
||||
*p = xaccept_nonblock(s, NULL, NULL);
|
||||
if (*p < 0) {
|
||||
err = errno;
|
||||
goto close_cli0;
|
||||
}
|
||||
return err;
|
||||
close_cli0:
|
||||
close(*c);
|
||||
return err;
|
||||
}
|
||||
|
||||
static inline int create_socket_pairs(int s, int family, int sotype,
|
||||
int *c0, int *c1, int *p0, int *p1)
|
||||
{
|
||||
int err;
|
||||
|
||||
err = create_pair(s, family, sotype, c0, p0);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
err = create_pair(s, family, sotype, c1, p1);
|
||||
if (err) {
|
||||
close(*c0);
|
||||
close(*p0);
|
||||
}
|
||||
return err;
|
||||
}
|
||||
|
||||
static inline int enable_reuseport(int s, int progfd)
|
||||
{
|
||||
int err, one = 1;
|
||||
|
||||
err = xsetsockopt(s, SOL_SOCKET, SO_REUSEPORT, &one, sizeof(one));
|
||||
if (err)
|
||||
return -1;
|
||||
err = xsetsockopt(s, SOL_SOCKET, SO_ATTACH_REUSEPORT_EBPF, &progfd,
|
||||
sizeof(progfd));
|
||||
if (err)
|
||||
return -1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int socket_loopback_reuseport(int family, int sotype, int progfd)
|
||||
{
|
||||
struct sockaddr_storage addr;
|
||||
socklen_t len;
|
||||
int err, s;
|
||||
|
||||
init_addr_loopback(family, &addr, &len);
|
||||
|
||||
s = xsocket(family, sotype, 0);
|
||||
if (s == -1)
|
||||
return -1;
|
||||
|
||||
if (progfd >= 0)
|
||||
enable_reuseport(s, progfd);
|
||||
|
||||
err = xbind(s, sockaddr(&addr), len);
|
||||
if (err)
|
||||
goto close;
|
||||
|
||||
if (sotype & SOCK_DGRAM)
|
||||
return s;
|
||||
|
||||
err = xlisten(s, SOMAXCONN);
|
||||
if (err)
|
||||
goto close;
|
||||
|
||||
return s;
|
||||
close:
|
||||
xclose(s);
|
||||
return -1;
|
||||
}
|
||||
|
||||
static inline int socket_loopback(int family, int sotype)
|
||||
{
|
||||
return socket_loopback_reuseport(family, sotype, -1);
|
||||
}
|
||||
|
||||
|
||||
#endif // __SOCKMAP_HELPERS__
|
||||
|
||||
Reference in New Issue
Block a user