0001
0002 #define _GNU_SOURCE
0003
0004 #include <errno.h>
0005 #include <stdbool.h>
0006 #include <stdio.h>
0007 #include <string.h>
0008 #include <unistd.h>
0009 #include <sched.h>
0010
0011 #include <arpa/inet.h>
0012 #include <sys/mount.h>
0013 #include <sys/stat.h>
0014
0015 #include <linux/err.h>
0016 #include <linux/in.h>
0017 #include <linux/in6.h>
0018 #include <linux/limits.h>
0019
0020 #include "bpf_util.h"
0021 #include "network_helpers.h"
0022 #include "test_progs.h"
0023
0024 #ifndef IPPROTO_MPTCP
0025 #define IPPROTO_MPTCP 262
0026 #endif
0027
0028 #define clean_errno() (errno == 0 ? "None" : strerror(errno))
0029 #define log_err(MSG, ...) ({ \
0030 int __save = errno; \
0031 fprintf(stderr, "(%s:%d: errno: %s) " MSG "\n", \
0032 __FILE__, __LINE__, clean_errno(), \
0033 ##__VA_ARGS__); \
0034 errno = __save; \
0035 })
0036
0037 struct ipv4_packet pkt_v4 = {
0038 .eth.h_proto = __bpf_constant_htons(ETH_P_IP),
0039 .iph.ihl = 5,
0040 .iph.protocol = IPPROTO_TCP,
0041 .iph.tot_len = __bpf_constant_htons(MAGIC_BYTES),
0042 .tcp.urg_ptr = 123,
0043 .tcp.doff = 5,
0044 };
0045
0046 struct ipv6_packet pkt_v6 = {
0047 .eth.h_proto = __bpf_constant_htons(ETH_P_IPV6),
0048 .iph.nexthdr = IPPROTO_TCP,
0049 .iph.payload_len = __bpf_constant_htons(MAGIC_BYTES),
0050 .tcp.urg_ptr = 123,
0051 .tcp.doff = 5,
0052 };
0053
0054 int settimeo(int fd, int timeout_ms)
0055 {
0056 struct timeval timeout = { .tv_sec = 3 };
0057
0058 if (timeout_ms > 0) {
0059 timeout.tv_sec = timeout_ms / 1000;
0060 timeout.tv_usec = (timeout_ms % 1000) * 1000;
0061 }
0062
0063 if (setsockopt(fd, SOL_SOCKET, SO_RCVTIMEO, &timeout,
0064 sizeof(timeout))) {
0065 log_err("Failed to set SO_RCVTIMEO");
0066 return -1;
0067 }
0068
0069 if (setsockopt(fd, SOL_SOCKET, SO_SNDTIMEO, &timeout,
0070 sizeof(timeout))) {
0071 log_err("Failed to set SO_SNDTIMEO");
0072 return -1;
0073 }
0074
0075 return 0;
0076 }
0077
0078 #define save_errno_close(fd) ({ int __save = errno; close(fd); errno = __save; })
0079
0080 static int __start_server(int type, int protocol, const struct sockaddr *addr,
0081 socklen_t addrlen, int timeout_ms, bool reuseport)
0082 {
0083 int on = 1;
0084 int fd;
0085
0086 fd = socket(addr->sa_family, type, protocol);
0087 if (fd < 0) {
0088 log_err("Failed to create server socket");
0089 return -1;
0090 }
0091
0092 if (settimeo(fd, timeout_ms))
0093 goto error_close;
0094
0095 if (reuseport &&
0096 setsockopt(fd, SOL_SOCKET, SO_REUSEPORT, &on, sizeof(on))) {
0097 log_err("Failed to set SO_REUSEPORT");
0098 return -1;
0099 }
0100
0101 if (bind(fd, addr, addrlen) < 0) {
0102 log_err("Failed to bind socket");
0103 goto error_close;
0104 }
0105
0106 if (type == SOCK_STREAM) {
0107 if (listen(fd, 1) < 0) {
0108 log_err("Failed to listed on socket");
0109 goto error_close;
0110 }
0111 }
0112
0113 return fd;
0114
0115 error_close:
0116 save_errno_close(fd);
0117 return -1;
0118 }
0119
0120 static int start_server_proto(int family, int type, int protocol,
0121 const char *addr_str, __u16 port, int timeout_ms)
0122 {
0123 struct sockaddr_storage addr;
0124 socklen_t addrlen;
0125
0126 if (make_sockaddr(family, addr_str, port, &addr, &addrlen))
0127 return -1;
0128
0129 return __start_server(type, protocol, (struct sockaddr *)&addr,
0130 addrlen, timeout_ms, false);
0131 }
0132
0133 int start_server(int family, int type, const char *addr_str, __u16 port,
0134 int timeout_ms)
0135 {
0136 return start_server_proto(family, type, 0, addr_str, port, timeout_ms);
0137 }
0138
0139 int start_mptcp_server(int family, const char *addr_str, __u16 port,
0140 int timeout_ms)
0141 {
0142 return start_server_proto(family, SOCK_STREAM, IPPROTO_MPTCP, addr_str,
0143 port, timeout_ms);
0144 }
0145
0146 int *start_reuseport_server(int family, int type, const char *addr_str,
0147 __u16 port, int timeout_ms, unsigned int nr_listens)
0148 {
0149 struct sockaddr_storage addr;
0150 unsigned int nr_fds = 0;
0151 socklen_t addrlen;
0152 int *fds;
0153
0154 if (!nr_listens)
0155 return NULL;
0156
0157 if (make_sockaddr(family, addr_str, port, &addr, &addrlen))
0158 return NULL;
0159
0160 fds = malloc(sizeof(*fds) * nr_listens);
0161 if (!fds)
0162 return NULL;
0163
0164 fds[0] = __start_server(type, 0, (struct sockaddr *)&addr, addrlen,
0165 timeout_ms, true);
0166 if (fds[0] == -1)
0167 goto close_fds;
0168 nr_fds = 1;
0169
0170 if (getsockname(fds[0], (struct sockaddr *)&addr, &addrlen))
0171 goto close_fds;
0172
0173 for (; nr_fds < nr_listens; nr_fds++) {
0174 fds[nr_fds] = __start_server(type, 0, (struct sockaddr *)&addr,
0175 addrlen, timeout_ms, true);
0176 if (fds[nr_fds] == -1)
0177 goto close_fds;
0178 }
0179
0180 return fds;
0181
0182 close_fds:
0183 free_fds(fds, nr_fds);
0184 return NULL;
0185 }
0186
0187 void free_fds(int *fds, unsigned int nr_close_fds)
0188 {
0189 if (fds) {
0190 while (nr_close_fds)
0191 close(fds[--nr_close_fds]);
0192 free(fds);
0193 }
0194 }
0195
0196 int fastopen_connect(int server_fd, const char *data, unsigned int data_len,
0197 int timeout_ms)
0198 {
0199 struct sockaddr_storage addr;
0200 socklen_t addrlen = sizeof(addr);
0201 struct sockaddr_in *addr_in;
0202 int fd, ret;
0203
0204 if (getsockname(server_fd, (struct sockaddr *)&addr, &addrlen)) {
0205 log_err("Failed to get server addr");
0206 return -1;
0207 }
0208
0209 addr_in = (struct sockaddr_in *)&addr;
0210 fd = socket(addr_in->sin_family, SOCK_STREAM, 0);
0211 if (fd < 0) {
0212 log_err("Failed to create client socket");
0213 return -1;
0214 }
0215
0216 if (settimeo(fd, timeout_ms))
0217 goto error_close;
0218
0219 ret = sendto(fd, data, data_len, MSG_FASTOPEN, (struct sockaddr *)&addr,
0220 addrlen);
0221 if (ret != data_len) {
0222 log_err("sendto(data, %u) != %d\n", data_len, ret);
0223 goto error_close;
0224 }
0225
0226 return fd;
0227
0228 error_close:
0229 save_errno_close(fd);
0230 return -1;
0231 }
0232
0233 static int connect_fd_to_addr(int fd,
0234 const struct sockaddr_storage *addr,
0235 socklen_t addrlen, const bool must_fail)
0236 {
0237 int ret;
0238
0239 errno = 0;
0240 ret = connect(fd, (const struct sockaddr *)addr, addrlen);
0241 if (must_fail) {
0242 if (!ret) {
0243 log_err("Unexpected success to connect to server");
0244 return -1;
0245 }
0246 if (errno != EPERM) {
0247 log_err("Unexpected error from connect to server");
0248 return -1;
0249 }
0250 } else {
0251 if (ret) {
0252 log_err("Failed to connect to server");
0253 return -1;
0254 }
0255 }
0256
0257 return 0;
0258 }
0259
0260 static const struct network_helper_opts default_opts;
0261
0262 int connect_to_fd_opts(int server_fd, const struct network_helper_opts *opts)
0263 {
0264 struct sockaddr_storage addr;
0265 struct sockaddr_in *addr_in;
0266 socklen_t addrlen, optlen;
0267 int fd, type, protocol;
0268
0269 if (!opts)
0270 opts = &default_opts;
0271
0272 optlen = sizeof(type);
0273 if (getsockopt(server_fd, SOL_SOCKET, SO_TYPE, &type, &optlen)) {
0274 log_err("getsockopt(SOL_TYPE)");
0275 return -1;
0276 }
0277
0278 if (getsockopt(server_fd, SOL_SOCKET, SO_PROTOCOL, &protocol, &optlen)) {
0279 log_err("getsockopt(SOL_PROTOCOL)");
0280 return -1;
0281 }
0282
0283 addrlen = sizeof(addr);
0284 if (getsockname(server_fd, (struct sockaddr *)&addr, &addrlen)) {
0285 log_err("Failed to get server addr");
0286 return -1;
0287 }
0288
0289 addr_in = (struct sockaddr_in *)&addr;
0290 fd = socket(addr_in->sin_family, type, protocol);
0291 if (fd < 0) {
0292 log_err("Failed to create client socket");
0293 return -1;
0294 }
0295
0296 if (settimeo(fd, opts->timeout_ms))
0297 goto error_close;
0298
0299 if (opts->cc && opts->cc[0] &&
0300 setsockopt(fd, SOL_TCP, TCP_CONGESTION, opts->cc,
0301 strlen(opts->cc) + 1))
0302 goto error_close;
0303
0304 if (connect_fd_to_addr(fd, &addr, addrlen, opts->must_fail))
0305 goto error_close;
0306
0307 return fd;
0308
0309 error_close:
0310 save_errno_close(fd);
0311 return -1;
0312 }
0313
0314 int connect_to_fd(int server_fd, int timeout_ms)
0315 {
0316 struct network_helper_opts opts = {
0317 .timeout_ms = timeout_ms,
0318 };
0319
0320 return connect_to_fd_opts(server_fd, &opts);
0321 }
0322
0323 int connect_fd_to_fd(int client_fd, int server_fd, int timeout_ms)
0324 {
0325 struct sockaddr_storage addr;
0326 socklen_t len = sizeof(addr);
0327
0328 if (settimeo(client_fd, timeout_ms))
0329 return -1;
0330
0331 if (getsockname(server_fd, (struct sockaddr *)&addr, &len)) {
0332 log_err("Failed to get server addr");
0333 return -1;
0334 }
0335
0336 if (connect_fd_to_addr(client_fd, &addr, len, false))
0337 return -1;
0338
0339 return 0;
0340 }
0341
0342 int make_sockaddr(int family, const char *addr_str, __u16 port,
0343 struct sockaddr_storage *addr, socklen_t *len)
0344 {
0345 if (family == AF_INET) {
0346 struct sockaddr_in *sin = (void *)addr;
0347
0348 memset(addr, 0, sizeof(*sin));
0349 sin->sin_family = AF_INET;
0350 sin->sin_port = htons(port);
0351 if (addr_str &&
0352 inet_pton(AF_INET, addr_str, &sin->sin_addr) != 1) {
0353 log_err("inet_pton(AF_INET, %s)", addr_str);
0354 return -1;
0355 }
0356 if (len)
0357 *len = sizeof(*sin);
0358 return 0;
0359 } else if (family == AF_INET6) {
0360 struct sockaddr_in6 *sin6 = (void *)addr;
0361
0362 memset(addr, 0, sizeof(*sin6));
0363 sin6->sin6_family = AF_INET6;
0364 sin6->sin6_port = htons(port);
0365 if (addr_str &&
0366 inet_pton(AF_INET6, addr_str, &sin6->sin6_addr) != 1) {
0367 log_err("inet_pton(AF_INET6, %s)", addr_str);
0368 return -1;
0369 }
0370 if (len)
0371 *len = sizeof(*sin6);
0372 return 0;
0373 }
0374 return -1;
0375 }
0376
0377 char *ping_command(int family)
0378 {
0379 if (family == AF_INET6) {
0380
0381 if (!system("which ping6 >/dev/null 2>&1"))
0382 return "ping6";
0383 else
0384 return "ping -6";
0385 }
0386 return "ping";
0387 }
0388
0389 struct nstoken {
0390 int orig_netns_fd;
0391 };
0392
0393 static int setns_by_fd(int nsfd)
0394 {
0395 int err;
0396
0397 err = setns(nsfd, CLONE_NEWNET);
0398 close(nsfd);
0399
0400 if (!ASSERT_OK(err, "setns"))
0401 return err;
0402
0403
0404
0405
0406 err = unshare(CLONE_NEWNS);
0407 if (!ASSERT_OK(err, "unshare"))
0408 return err;
0409
0410
0411
0412
0413 err = mount("none", "/sys", NULL, MS_PRIVATE, NULL);
0414 if (!ASSERT_OK(err, "remount private /sys"))
0415 return err;
0416
0417 err = umount2("/sys", MNT_DETACH);
0418 if (!ASSERT_OK(err, "umount2 /sys"))
0419 return err;
0420
0421 err = mount("sysfs", "/sys", "sysfs", 0, NULL);
0422 if (!ASSERT_OK(err, "mount /sys"))
0423 return err;
0424
0425 err = mount("bpffs", "/sys/fs/bpf", "bpf", 0, NULL);
0426 if (!ASSERT_OK(err, "mount /sys/fs/bpf"))
0427 return err;
0428
0429 return 0;
0430 }
0431
0432 struct nstoken *open_netns(const char *name)
0433 {
0434 int nsfd;
0435 char nspath[PATH_MAX];
0436 int err;
0437 struct nstoken *token;
0438
0439 token = calloc(1, sizeof(struct nstoken));
0440 if (!ASSERT_OK_PTR(token, "malloc token"))
0441 return NULL;
0442
0443 token->orig_netns_fd = open("/proc/self/ns/net", O_RDONLY);
0444 if (!ASSERT_GE(token->orig_netns_fd, 0, "open /proc/self/ns/net"))
0445 goto fail;
0446
0447 snprintf(nspath, sizeof(nspath), "%s/%s", "/var/run/netns", name);
0448 nsfd = open(nspath, O_RDONLY | O_CLOEXEC);
0449 if (!ASSERT_GE(nsfd, 0, "open netns fd"))
0450 goto fail;
0451
0452 err = setns_by_fd(nsfd);
0453 if (!ASSERT_OK(err, "setns_by_fd"))
0454 goto fail;
0455
0456 return token;
0457 fail:
0458 free(token);
0459 return NULL;
0460 }
0461
0462 void close_netns(struct nstoken *token)
0463 {
0464 ASSERT_OK(setns_by_fd(token->orig_netns_fd), "setns_by_fd");
0465 free(token);
0466 }