OSDN Git Service

selftests/bpf: Test sys_connect BPF hooks with TFO
authorAndrey Ignatov <rdna@fb.com>
Tue, 26 Jun 2018 21:22:41 +0000 (14:22 -0700)
committerDaniel Borkmann <daniel@iogearbox.net>
Wed, 27 Jun 2018 09:22:38 +0000 (11:22 +0200)
TCP Fast Open is triggered by sys_sendmsg with MSG_FASTOPEN flag for
SOCK_STREAM socket.

Even though it's sys_sendmsg, it eventually calls __inet_stream_connect
the same way sys_connect does for TCP.  __inet_stream_connect, in turn,
already has BPF hooks for sys_connect.

That means TFO is already covered by BPF_CGROUP_INET{4,6}_CONNECT and
the only missing piece is selftest. The patch adds selftest for TFO.

Signed-off-by: Andrey Ignatov <rdna@fb.com>
Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
tools/testing/selftests/bpf/test_sock_addr.c

index a5e76b9..2e45c92 100644 (file)
@@ -998,8 +998,9 @@ int init_pktinfo(int domain, struct cmsghdr *cmsg)
        return 0;
 }
 
-static int sendmsg_to_server(const struct sockaddr_storage *addr,
-                            socklen_t addr_len, int set_cmsg, int *syscall_err)
+static int sendmsg_to_server(int type, const struct sockaddr_storage *addr,
+                            socklen_t addr_len, int set_cmsg, int flags,
+                            int *syscall_err)
 {
        union {
                char buf[CMSG_SPACE(sizeof(struct in6_pktinfo))];
@@ -1022,7 +1023,7 @@ static int sendmsg_to_server(const struct sockaddr_storage *addr,
                goto err;
        }
 
-       fd = socket(domain, SOCK_DGRAM, 0);
+       fd = socket(domain, type, 0);
        if (fd == -1) {
                log_err("Failed to create client socket");
                goto err;
@@ -1052,7 +1053,7 @@ static int sendmsg_to_server(const struct sockaddr_storage *addr,
                }
        }
 
-       if (sendmsg(fd, &hdr, 0) != sizeof(data)) {
+       if (sendmsg(fd, &hdr, flags) != sizeof(data)) {
                log_err("Fail to send message to server");
                *syscall_err = errno;
                goto err;
@@ -1066,6 +1067,15 @@ out:
        return fd;
 }
 
+static int fastconnect_to_server(const struct sockaddr_storage *addr,
+                                socklen_t addr_len)
+{
+       int sendmsg_err;
+
+       return sendmsg_to_server(SOCK_STREAM, addr, addr_len, /*set_cmsg*/0,
+                                MSG_FASTOPEN, &sendmsg_err);
+}
+
 static int recvmsg_from_client(int sockfd, struct sockaddr_storage *src_addr)
 {
        struct timeval tv;
@@ -1185,6 +1195,20 @@ static int run_connect_test_case(const struct sock_addr_test *test)
        if (cmp_local_ip(clientfd, &expected_src_addr))
                goto err;
 
+       if (test->type == SOCK_STREAM) {
+               /* Test TCP Fast Open scenario */
+               clientfd = fastconnect_to_server(&requested_addr, addr_len);
+               if (clientfd == -1)
+                       goto err;
+
+               /* Make sure src and dst addrs were overridden properly */
+               if (cmp_peer_addr(clientfd, &expected_addr))
+                       goto err;
+
+               if (cmp_local_ip(clientfd, &expected_src_addr))
+                       goto err;
+       }
+
        goto out;
 err:
        err = -1;
@@ -1222,8 +1246,9 @@ static int run_sendmsg_test_case(const struct sock_addr_test *test)
                if (clientfd >= 0)
                        close(clientfd);
 
-               clientfd = sendmsg_to_server(&requested_addr, addr_len,
-                                            set_cmsg, &err);
+               clientfd = sendmsg_to_server(test->type, &requested_addr,
+                                            addr_len, set_cmsg, /*flags*/0,
+                                            &err);
                if (err)
                        goto out;
                else if (clientfd == -1)