From patchwork Wed May 13 21:38:39 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Andrey Ignatov X-Patchwork-Id: 1289733 X-Patchwork-Delegate: bpf@iogearbox.net Return-Path: X-Original-To: incoming-bpf@patchwork.ozlabs.org Delivered-To: patchwork-incoming-bpf@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=vger.kernel.org (client-ip=23.128.96.18; helo=vger.kernel.org; envelope-from=bpf-owner@vger.kernel.org; receiver=) Authentication-Results: ozlabs.org; dmarc=pass (p=quarantine dis=none) header.from=fb.com Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=fb.com header.i=@fb.com header.a=rsa-sha256 header.s=facebook header.b=Hfy1knTO; dkim-atps=neutral Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by ozlabs.org (Postfix) with ESMTP id 49Mp3K2RQMz9sRK for ; Thu, 14 May 2020 07:39:25 +1000 (AEST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1729583AbgEMVjY (ORCPT ); Wed, 13 May 2020 17:39:24 -0400 Received: from mx0b-00082601.pphosted.com ([67.231.153.30]:53048 "EHLO mx0b-00082601.pphosted.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1729258AbgEMVjX (ORCPT ); Wed, 13 May 2020 17:39:23 -0400 Received: from pps.filterd (m0148460.ppops.net [127.0.0.1]) by mx0a-00082601.pphosted.com (8.16.0.42/8.16.0.42) with SMTP id 04DLdIMM030462 for ; Wed, 13 May 2020 14:39:22 -0700 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=fb.com; h=from : to : cc : subject : date : message-id : in-reply-to : references : mime-version : content-transfer-encoding : content-type; s=facebook; bh=HynFpvEUD2Y6XuOyNovUrDusN7xztU6v07/sTQlrTCU=; b=Hfy1knTOJmcZ9Q55xdz04UnUSxAfpD6bZYKxGaW6M02MGF1v0Alr0HHJOYvD57Psx6vM hbyRpkwk9zypRMAim0VtjjUeA3wyAr8HyILdeMHBp9lwTx2HHag3HdSncAE1hx50OKOk LdxKBJKNOkVeiT+97RBoDHC0RFoLI+pvSCs= Received: from mail.thefacebook.com ([163.114.132.120]) by mx0a-00082601.pphosted.com with ESMTP id 3100x5ykp7-8 (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128 verify=NOT) for ; Wed, 13 May 2020 14:39:22 -0700 Received: from intmgw002.41.prn1.facebook.com (2620:10d:c085:208::11) by mail.thefacebook.com (2620:10d:c085:11d::4) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.1847.3; Wed, 13 May 2020 14:39:16 -0700 Received: by dev082.prn2.facebook.com (Postfix, from userid 572249) id D3F31370094C; Wed, 13 May 2020 14:39:06 -0700 (PDT) Smtp-Origin-Hostprefix: dev From: Andrey Ignatov Smtp-Origin-Hostname: dev082.prn2.facebook.com To: CC: Andrey Ignatov , , , Smtp-Origin-Cluster: prn2c23 Subject: [PATCH v2 bpf-next 4/5] selftests/bpf: Add connect_fd_to_fd, connect_wait net helpers Date: Wed, 13 May 2020 14:38:39 -0700 Message-ID: X-Mailer: git-send-email 2.24.1 In-Reply-To: References: MIME-Version: 1.0 X-FB-Internal: Safe X-Proofpoint-Virus-Version: vendor=fsecure engine=2.50.10434:6.0.216, 18.0.676 definitions=2020-05-13_09:2020-05-13,2020-05-13 signatures=0 X-Proofpoint-Spam-Details: rule=fb_default_notspam policy=fb_default score=0 lowpriorityscore=0 mlxlogscore=999 spamscore=0 clxscore=1015 cotscore=-2147483648 malwarescore=0 impostorscore=0 bulkscore=0 adultscore=0 priorityscore=1501 phishscore=0 mlxscore=0 suspectscore=15 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.12.0-2004280000 definitions=main-2005130185 X-FB-Internal: deliver Sender: bpf-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: bpf@vger.kernel.org Add two new network helpers. connect_fd_to_fd connects an already created client socket fd to address of server fd. Sometimes it's useful to separate client socket creation and connecting this socket to a server, e.g. if client socket has to be created in a cgroup different from that of server cgroup. Additionally connect_to_fd is now implemented using connect_fd_to_fd, both helpers don't treat EINPROGRESS as an error and let caller decide how to proceed with it. connect_wait is a helper to work with non-blocking client sockets so that if connect_to_fd or connect_fd_to_fd returned -1 with errno == EINPROGRESS, caller can wait for connect to finish or for connection timeout. The helper returns -1 on error, 0 on timeout (1sec, hard-coded), and positive number on success. Signed-off-by: Andrey Ignatov Acked-by: Yonghong Song --- tools/testing/selftests/bpf/network_helpers.c | 66 +++++++++++++++---- tools/testing/selftests/bpf/network_helpers.h | 2 + 2 files changed, 56 insertions(+), 12 deletions(-) diff --git a/tools/testing/selftests/bpf/network_helpers.c b/tools/testing/selftests/bpf/network_helpers.c index 0ff64b70b746..542d71ed7f5d 100644 --- a/tools/testing/selftests/bpf/network_helpers.c +++ b/tools/testing/selftests/bpf/network_helpers.c @@ -4,10 +4,14 @@ #include #include #include + +#include + #include #include #include +#include "bpf_util.h" #include "network_helpers.h" #define clean_errno() (errno == 0 ? "None" : strerror(errno)) @@ -77,8 +81,6 @@ static const size_t timeo_optlen = sizeof(timeo_sec); int connect_to_fd(int family, int type, int server_fd) { - struct sockaddr_storage addr; - socklen_t len = sizeof(addr); int fd; fd = socket(family, type, 0); @@ -87,24 +89,64 @@ int connect_to_fd(int family, int type, int server_fd) return -1; } - if (setsockopt(fd, SOL_SOCKET, SO_RCVTIMEO, &timeo_sec, timeo_optlen)) { + if (connect_fd_to_fd(fd, server_fd) < 0 && errno != EINPROGRESS) { + close(fd); + return -1; + } + + return fd; +} + +int connect_fd_to_fd(int client_fd, int server_fd) +{ + struct sockaddr_storage addr; + socklen_t len = sizeof(addr); + + if (setsockopt(client_fd, SOL_SOCKET, SO_RCVTIMEO, &timeo_sec, + timeo_optlen)) { log_err("Failed to set SO_RCVTIMEO"); - goto out; + return -1; } if (getsockname(server_fd, (struct sockaddr *)&addr, &len)) { log_err("Failed to get server addr"); - goto out; + return -1; } - if (connect(fd, (const struct sockaddr *)&addr, len) < 0) { - log_err("Fail to connect to server with family %d", family); - goto out; + if (connect(client_fd, (const struct sockaddr *)&addr, len) < 0) { + if (errno != EINPROGRESS) + log_err("Failed to connect to server"); + return -1; } - return fd; + return 0; +} + +int connect_wait(int fd) +{ + struct epoll_event ev = {}, events[2]; + int timeout_ms = 1000; + int efd, nfd; + + efd = epoll_create1(EPOLL_CLOEXEC); + if (efd < 0) { + log_err("Failed to open epoll fd"); + return -1; + } + + ev.events = EPOLLRDHUP | EPOLLOUT; + ev.data.fd = fd; + + if (epoll_ctl(efd, EPOLL_CTL_ADD, fd, &ev) < 0) { + log_err("Failed to register fd=%d on epoll fd=%d", fd, efd); + close(efd); + return -1; + } + + nfd = epoll_wait(efd, events, ARRAY_SIZE(events), timeout_ms); + if (nfd < 0) + log_err("Failed to wait for I/O event on epoll fd=%d", efd); -out: - close(fd); - return -1; + close(efd); + return nfd; } diff --git a/tools/testing/selftests/bpf/network_helpers.h b/tools/testing/selftests/bpf/network_helpers.h index a0be7db4f67d..86914e6e7b53 100644 --- a/tools/testing/selftests/bpf/network_helpers.h +++ b/tools/testing/selftests/bpf/network_helpers.h @@ -35,5 +35,7 @@ extern struct ipv6_packet pkt_v6; int start_server(int family, int type); int connect_to_fd(int family, int type, int server_fd); +int connect_fd_to_fd(int client_fd, int server_fd); +int connect_wait(int client_fd); #endif