From nobody Fri Nov 29 04:34:27 2024 Received: from mail-lf1-f51.google.com (mail-lf1-f51.google.com [209.85.167.51]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 8C3681428F3 for ; Tue, 24 Sep 2024 09:01:18 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.167.51 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1727168481; cv=none; b=sweRZZemCXsUijmgwBf2qfskVfMsxRdzYK/evgNsIPhFIyw4b5vcx9ImnS6PtUW1F1DBoYjTm2mLfRYmi2ScI/7dgRaGnlaO1UXVVh36XMydfk8vhe88PvPAYbN0IcYMshlx8JOWBWGHieHJR9WoNw9qjLyp21ClmMrQItK7CA0= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1727168481; c=relaxed/simple; bh=MyD71HI4MA2yAUC70K/NmNxJQezcMoO+zPtOIctDAQY=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To; b=XCyDZn4C5rH0c01ihZebFuwIeTP08WcgRx9sAMRoNxgyFngWY9TCvBrHASlXrOarfUyxNXoT4ZLzRwKMnJ0xaXr6bepy8LutBEu4XSlLmca3ykdS7tiSknCd8uTqQcQLHtw8KIv3H5sS2kTt7XS127uPchOSY52ywwODzFot478= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=daynix.com; spf=none smtp.mailfrom=daynix.com; dkim=pass (2048-bit key) header.d=daynix-com.20230601.gappssmtp.com header.i=@daynix-com.20230601.gappssmtp.com header.b=zfHKkb3K; arc=none smtp.client-ip=209.85.167.51 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=daynix.com Authentication-Results: smtp.subspace.kernel.org; spf=none smtp.mailfrom=daynix.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=daynix-com.20230601.gappssmtp.com header.i=@daynix-com.20230601.gappssmtp.com header.b="zfHKkb3K" Received: by mail-lf1-f51.google.com with SMTP id 2adb3069b0e04-5365a9574b6so7368356e87.1 for ; Tue, 24 Sep 2024 02:01:18 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=daynix-com.20230601.gappssmtp.com; s=20230601; t=1727168477; x=1727773277; darn=vger.kernel.org; h=to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:from:to:cc:subject:date:message-id :reply-to; bh=V1kAAAtErX+Mbn0MQOV75jcovDzbdqf7yjREy+JSPNM=; b=zfHKkb3KibxvDG5DI/1jxvJJM9Gy5bFU/hA3gzLoOJNG5cY68nvUbFmZoJNWOoPbDy QdaYyjaAb+YHTb32soahm61/QCfUkLcbYwh9MFZW5VVNL3CnoQdVdOQEuqrB0aeLDAbR wRsROTSzAzcptQ2AAQrlEtHnd8Fz+gu3i052WcwCW5HwebECApodwXSohXu2OJ7Cdy79 h5/KonEDAFIGqVzRjWdNiHm86V7XbNMHG27rsxEEoxK8YMhIa4nv/54xCGrM76BqW9B7 Ojr/B48NlthQ1kxLCxVYD16uTnewynObyTOFg5WHAtJQIu6qyBr4cMq53p64xoTMd7+o kyqw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1727168477; x=1727773277; h=to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=V1kAAAtErX+Mbn0MQOV75jcovDzbdqf7yjREy+JSPNM=; b=pLnoM0PmusSLNgNl3+bf0qAvxKg1WD8uq0fMv6EEXdSShX2BEVD2YJpAGJPqoyM8Qq 2Y06HbFWftZzBoNt2k3cLCva/K5hZDxHIZl/twH8U7PIBiHPAmi7WDzz78gwu70pWdXz 4CgTetTmdCkjKF+nV0PN3zPx3Brn9BwG0Crf0IgNT4BEVprtx8J4v5zBBu46i3/J/Eny 50RnRAbDtADmGeZCSZ5R7d6XPcbneo55ybL8p1HL/XAOqEHLLGpGj96NdWM3C6veA43n 7/R6sfIgFLV98pX3dcb2EfcFcOZ1t9/vVozJCpaiO4DBKJHS1Fwwauk0zYk6LEL3w1Zg HJCg== X-Forwarded-Encrypted: i=1; AJvYcCW/ww9VM5SiZYSrp4BDay/vFbLYAfGXH4Ql14hy35qNqCWjXKLK20DmXwgzstEejmxNJ8LtjPTKQ3jAC4c=@vger.kernel.org X-Gm-Message-State: AOJu0YyJaVgJ/ADh9OHf8GOiHpMU734PddyCVHI7+GUtt8QJGgZolwSt 7QlwxJBj5j/aBT9eCcWHO+5nkbvev8Rvp4szF7VJz60sJorY5UsKteUa134I544= X-Google-Smtp-Source: AGHT+IFwbEJheNGzEgD5vAlxy6ttzfcaZu81VFeEqJsY1P5iYb/DMCt1ffXE/8oRaqbajpxcR435Vg== X-Received: by 2002:a05:6512:39d4:b0:533:c9d:a01f with SMTP id 2adb3069b0e04-536ac2d6a7amr8799569e87.4.1727168476563; Tue, 24 Sep 2024 02:01:16 -0700 (PDT) Received: from localhost ([193.32.29.227]) by smtp.gmail.com with UTF8SMTPSA id a640c23a62f3a-a9392f34959sm59743266b.8.2024.09.24.02.01.15 (version=TLS1_3 cipher=TLS_AES_128_GCM_SHA256 bits=128/128); Tue, 24 Sep 2024 02:01:16 -0700 (PDT) From: Akihiko Odaki Date: Tue, 24 Sep 2024 11:01:06 +0200 Subject: [PATCH RFC v4 1/9] skbuff: Introduce SKB_EXT_TUN_VNET_HASH Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20240924-rss-v4-1-84e932ec0e6c@daynix.com> References: <20240924-rss-v4-0-84e932ec0e6c@daynix.com> In-Reply-To: <20240924-rss-v4-0-84e932ec0e6c@daynix.com> To: Jonathan Corbet , Willem de Bruijn , Jason Wang , "David S. Miller" , Eric Dumazet , Jakub Kicinski , Paolo Abeni , "Michael S. Tsirkin" , Xuan Zhuo , Shuah Khan , linux-doc@vger.kernel.org, linux-kernel@vger.kernel.org, netdev@vger.kernel.org, kvm@vger.kernel.org, virtualization@lists.linux-foundation.org, linux-kselftest@vger.kernel.org, Yuri Benditovich , Andrew Melnychenko , Stephen Hemminger , gur.stavi@huawei.com, Akihiko Odaki X-Mailer: b4 0.14-dev-fd6e3 This new extension will be used by tun to carry the hash values and types to report with virtio-net headers. Signed-off-by: Akihiko Odaki --- include/linux/if_tun.h | 5 +++++ include/linux/skbuff.h | 3 +++ net/core/skbuff.c | 4 ++++ 3 files changed, 12 insertions(+) diff --git a/include/linux/if_tun.h b/include/linux/if_tun.h index 043d442994b0..47034aede329 100644 --- a/include/linux/if_tun.h +++ b/include/linux/if_tun.h @@ -9,6 +9,11 @@ #include #include =20 +struct tun_vnet_hash_ext { + u32 value; + u16 report; +}; + #define TUN_XDP_FLAG 0x1UL =20 #define TUN_MSG_UBUF 1 diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h index 29c3ea5b6e93..a361c4150144 100644 --- a/include/linux/skbuff.h +++ b/include/linux/skbuff.h @@ -4718,6 +4718,9 @@ enum skb_ext_id { #endif #if IS_ENABLED(CONFIG_MCTP_FLOWS) SKB_EXT_MCTP, +#endif +#if IS_ENABLED(CONFIG_TUN) + SKB_EXT_TUN_VNET_HASH, #endif SKB_EXT_NUM, /* must be last */ }; diff --git a/net/core/skbuff.c b/net/core/skbuff.c index 83f8cd8aa2d1..997d79d5612c 100644 --- a/net/core/skbuff.c +++ b/net/core/skbuff.c @@ -60,6 +60,7 @@ #include #include #include +#include #include #include #include @@ -4979,6 +4980,9 @@ static const u8 skb_ext_type_len[] =3D { #if IS_ENABLED(CONFIG_MCTP_FLOWS) [SKB_EXT_MCTP] =3D SKB_EXT_CHUNKSIZEOF(struct mctp_flow), #endif +#if IS_ENABLED(CONFIG_TUN) + [SKB_EXT_TUN_VNET_HASH] =3D SKB_EXT_CHUNKSIZEOF(struct tun_vnet_hash_ext), +#endif }; =20 static __always_inline unsigned int skb_ext_total_length(void) --=20 2.46.0 From nobody Fri Nov 29 04:34:27 2024 Received: from mail-ed1-f50.google.com (mail-ed1-f50.google.com [209.85.208.50]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 18022155330 for ; Tue, 24 Sep 2024 09:01:19 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.208.50 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1727168482; cv=none; b=ZKw8CxnlJJvuU+9LahWmTg4Hd0pqOtYCgfA/QZqDcQdaqKli3OMQGD5pIbHcq/1fN/8SI6P4kKAFDU4Dok5UvEwd5ogB+dFIIJOKKvH8kLVzyfgfPvnUL6F4T4OPtTy5QpX0ugghzk0UpYhvtD7BKNV49PRPbfCjgV7k2qHTTMc= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1727168482; c=relaxed/simple; bh=sOAXGGuPxVhRSBMMLtZjJhQOr2JtLUlri/1Ey3yMBnI=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To; b=iBsCYcIeOsmCMPX/j4LuKyFCyHexjADwzJC3KkDf4UydQUXrZWRzqQ5RILFYl1YFjnyX4Nlq8uxRFyZGZeqPi3WSjPQBmKxES/TY68SE/HfY6dW4ocx2aP9Omdx2+siHw9kA+FatfXhUpais4ngz3jBfTske6ya/4gZS0v3lzHU= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=daynix.com; spf=none smtp.mailfrom=daynix.com; dkim=pass (2048-bit key) header.d=daynix-com.20230601.gappssmtp.com header.i=@daynix-com.20230601.gappssmtp.com header.b=1Qp7CrpT; arc=none smtp.client-ip=209.85.208.50 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=daynix.com Authentication-Results: smtp.subspace.kernel.org; spf=none smtp.mailfrom=daynix.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=daynix-com.20230601.gappssmtp.com header.i=@daynix-com.20230601.gappssmtp.com header.b="1Qp7CrpT" Received: by mail-ed1-f50.google.com with SMTP id 4fb4d7f45d1cf-5c4226a5af8so6855391a12.1 for ; Tue, 24 Sep 2024 02:01:19 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=daynix-com.20230601.gappssmtp.com; s=20230601; t=1727168478; x=1727773278; darn=vger.kernel.org; h=to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:from:to:cc:subject:date:message-id :reply-to; bh=Ov2zUxVwXGroWMKfnwaYR/rA1EzTscWc/86yRpml0UI=; b=1Qp7CrpTHkbJfKVRRUEMi92mkKVMJtsf7eqFjsrffUEOgu4kQg8EWaMK/0HDI/lKDn WckKlqF7RjOSW3UHriAy4AF6+Zqro07LC/KeLJv3WZvd/78gSfavc4xu9sqqTFEynHhb nyx2qX4TP2+42acQCsSBOIwcrnqFhee8AaBxzaT2IOJjLkb5tq+GCtObfZNQBg+lH6ye qVupj8se9wtJ0sUwgnJgNrW7zYw9PyVOlXE0ffZKBtwc3So4Qw1+aRAeCp0iQqoPpSHh gRdBTnNE8g8wN/x3W+iFWm0CSjj/4UZyeu1xDxZB2dW0yOqmVOxwgYF0hJH/UCsKHB/u jkGw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1727168478; x=1727773278; h=to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=Ov2zUxVwXGroWMKfnwaYR/rA1EzTscWc/86yRpml0UI=; b=P8DiMi5rkhHfR3QHzygPmJCdSZ1fPOrd4Lj2uyMtGdditPRZg54brbkgRlwxJM0F1U PkaF+bOz1s2HNzS/CRS6AI/SzWNyfaVFy2nGIFemXqZjMD9OCF+lZC7nHU4VijgflZqw CKSYIqW0Pg9jGrRqN5XfZLMbinbM5B2trWTo37tzc9x8jbzYLQ9wzVqy0/w/hDlFyCjw HJurjfkGGvzP3VVlFWtiggy7E+INnxbYQm/9gxriNdkzXRKqgE9XOaJTSha1Ak6pMsov YQrFXADIH6VNgFPn4HPicULUdICrY6hmqDumIriDAE5RIUpRDpqNHYLmJj7TTT9DlHmu Em1w== X-Forwarded-Encrypted: i=1; AJvYcCXYfC2T7jzMVz/WJzhF1gMY58pKDloF60fZ8lbe13DQcG/7yVeSj4lgfTGCMaQhWH/uqZpPOGdYcgeJkKQ=@vger.kernel.org X-Gm-Message-State: AOJu0YwAtxY/VLLRETWYfS9dpSndpHcgPQ3YrITr3sXxEGriWMo4yvZA pwc7zHwQG4Pk/yLp/yv82E+sfxJdGWy62OnSXzg9th2xcQgZ8UxyIq6cxAOf11c= X-Google-Smtp-Source: AGHT+IFWAkqffQdJf6+ooG5u5r4ZbQRITl2L+f/622eMMHM38TeEo3AkjhjZ7Qd4F4SO1RqijO7WQw== X-Received: by 2002:a17:907:9348:b0:a8d:3998:2d2 with SMTP id a640c23a62f3a-a90d518718fmr1921620866b.58.1727168478186; Tue, 24 Sep 2024 02:01:18 -0700 (PDT) Received: from localhost ([193.32.29.227]) by smtp.gmail.com with UTF8SMTPSA id a640c23a62f3a-a9393134bd2sm58552866b.214.2024.09.24.02.01.17 (version=TLS1_3 cipher=TLS_AES_128_GCM_SHA256 bits=128/128); Tue, 24 Sep 2024 02:01:17 -0700 (PDT) From: Akihiko Odaki Date: Tue, 24 Sep 2024 11:01:07 +0200 Subject: [PATCH RFC v4 2/9] virtio_net: Add functions for hashing Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20240924-rss-v4-2-84e932ec0e6c@daynix.com> References: <20240924-rss-v4-0-84e932ec0e6c@daynix.com> In-Reply-To: <20240924-rss-v4-0-84e932ec0e6c@daynix.com> To: Jonathan Corbet , Willem de Bruijn , Jason Wang , "David S. Miller" , Eric Dumazet , Jakub Kicinski , Paolo Abeni , "Michael S. Tsirkin" , Xuan Zhuo , Shuah Khan , linux-doc@vger.kernel.org, linux-kernel@vger.kernel.org, netdev@vger.kernel.org, kvm@vger.kernel.org, virtualization@lists.linux-foundation.org, linux-kselftest@vger.kernel.org, Yuri Benditovich , Andrew Melnychenko , Stephen Hemminger , gur.stavi@huawei.com, Akihiko Odaki X-Mailer: b4 0.14-dev-fd6e3 They are useful to implement VIRTIO_NET_F_RSS and VIRTIO_NET_F_HASH_REPORT. Signed-off-by: Akihiko Odaki --- include/linux/virtio_net.h | 174 +++++++++++++++++++++++++++++++++++++++++= ++++ 1 file changed, 174 insertions(+) diff --git a/include/linux/virtio_net.h b/include/linux/virtio_net.h index 276ca543ef44..f7a4149efb3e 100644 --- a/include/linux/virtio_net.h +++ b/include/linux/virtio_net.h @@ -9,6 +9,180 @@ #include #include =20 +struct virtio_net_hash { + u32 value; + u16 report; +}; + +struct virtio_net_toeplitz_state { + u32 hash; + u32 key_buffer; + const __be32 *key; +}; + +#define VIRTIO_NET_SUPPORTED_HASH_TYPES (VIRTIO_NET_RSS_HASH_TYPE_IPv4 | \ + VIRTIO_NET_RSS_HASH_TYPE_TCPv4 | \ + VIRTIO_NET_RSS_HASH_TYPE_UDPv4 | \ + VIRTIO_NET_RSS_HASH_TYPE_IPv6 | \ + VIRTIO_NET_RSS_HASH_TYPE_TCPv6 | \ + VIRTIO_NET_RSS_HASH_TYPE_UDPv6) + +#define VIRTIO_NET_RSS_MAX_KEY_SIZE 40 + +static inline void virtio_net_toeplitz_calc(struct virtio_net_toeplitz_sta= te *state, + const __be32 *input, size_t len) +{ + u32 key; + + while (len) { + state->key++; + key =3D be32_to_cpu(*state->key); + + for (u32 bit =3D BIT(31); bit; bit >>=3D 1) { + if (be32_to_cpu(*input) & bit) + state->hash ^=3D state->key_buffer; + + state->key_buffer =3D + (state->key_buffer << 1) | !!(key & bit); + } + + input++; + len--; + } +} + +static inline u8 virtio_net_hash_key_length(u32 types) +{ + size_t len =3D 0; + + if (types & VIRTIO_NET_HASH_REPORT_IPv4) + len =3D max(len, + sizeof(struct flow_dissector_key_ipv4_addrs)); + + if (types & + (VIRTIO_NET_HASH_REPORT_TCPv4 | VIRTIO_NET_HASH_REPORT_UDPv4)) + len =3D max(len, + sizeof(struct flow_dissector_key_ipv4_addrs) + + sizeof(struct flow_dissector_key_ports)); + + if (types & VIRTIO_NET_HASH_REPORT_IPv6) + len =3D max(len, + sizeof(struct flow_dissector_key_ipv6_addrs)); + + if (types & + (VIRTIO_NET_HASH_REPORT_TCPv6 | VIRTIO_NET_HASH_REPORT_UDPv6)) + len =3D max(len, + sizeof(struct flow_dissector_key_ipv6_addrs) + + sizeof(struct flow_dissector_key_ports)); + + return sizeof_field(struct virtio_net_toeplitz_state, key_buffer) + len; +} + +static inline u32 virtio_net_hash_report(u32 types, + struct flow_dissector_key_basic key) +{ + switch (key.n_proto) { + case cpu_to_be16(ETH_P_IP): + if (key.ip_proto =3D=3D IPPROTO_TCP && + (types & VIRTIO_NET_RSS_HASH_TYPE_TCPv4)) + return VIRTIO_NET_HASH_REPORT_TCPv4; + + if (key.ip_proto =3D=3D IPPROTO_UDP && + (types & VIRTIO_NET_RSS_HASH_TYPE_UDPv4)) + return VIRTIO_NET_HASH_REPORT_UDPv4; + + if (types & VIRTIO_NET_RSS_HASH_TYPE_IPv4) + return VIRTIO_NET_HASH_REPORT_IPv4; + + return VIRTIO_NET_HASH_REPORT_NONE; + + case cpu_to_be16(ETH_P_IPV6): + if (key.ip_proto =3D=3D IPPROTO_TCP && + (types & VIRTIO_NET_RSS_HASH_TYPE_TCPv6)) + return VIRTIO_NET_HASH_REPORT_TCPv6; + + if (key.ip_proto =3D=3D IPPROTO_UDP && + (types & VIRTIO_NET_RSS_HASH_TYPE_UDPv6)) + return VIRTIO_NET_HASH_REPORT_UDPv6; + + if (types & VIRTIO_NET_RSS_HASH_TYPE_IPv6) + return VIRTIO_NET_HASH_REPORT_IPv6; + + return VIRTIO_NET_HASH_REPORT_NONE; + + default: + return VIRTIO_NET_HASH_REPORT_NONE; + } +} + +static inline void virtio_net_hash_rss(const struct sk_buff *skb, + u32 types, const __be32 *key, + struct virtio_net_hash *hash) +{ + struct virtio_net_toeplitz_state toeplitz_state =3D { + .key_buffer =3D be32_to_cpu(*key), + .key =3D key + }; + struct flow_keys flow; + u16 report; + + if (!skb_flow_dissect_flow_keys(skb, &flow, 0)) { + hash->report =3D VIRTIO_NET_HASH_REPORT_NONE; + return; + } + + report =3D virtio_net_hash_report(types, flow.basic); + + switch (report) { + case VIRTIO_NET_HASH_REPORT_IPv4: + virtio_net_toeplitz_calc(&toeplitz_state, + (__be32 *)&flow.addrs.v4addrs, + sizeof(flow.addrs.v4addrs) / 4); + break; + + case VIRTIO_NET_HASH_REPORT_TCPv4: + virtio_net_toeplitz_calc(&toeplitz_state, + (__be32 *)&flow.addrs.v4addrs, + sizeof(flow.addrs.v4addrs) / 4); + virtio_net_toeplitz_calc(&toeplitz_state, &flow.ports.ports, 1); + break; + + case VIRTIO_NET_HASH_REPORT_UDPv4: + virtio_net_toeplitz_calc(&toeplitz_state, + (__be32 *)&flow.addrs.v4addrs, + sizeof(flow.addrs.v4addrs) / 4); + virtio_net_toeplitz_calc(&toeplitz_state, &flow.ports.ports, 1); + break; + + case VIRTIO_NET_HASH_REPORT_IPv6: + virtio_net_toeplitz_calc(&toeplitz_state, + (__be32 *)&flow.addrs.v6addrs, + sizeof(flow.addrs.v6addrs) / 4); + break; + + case VIRTIO_NET_HASH_REPORT_TCPv6: + virtio_net_toeplitz_calc(&toeplitz_state, + (__be32 *)&flow.addrs.v6addrs, + sizeof(flow.addrs.v6addrs) / 4); + virtio_net_toeplitz_calc(&toeplitz_state, &flow.ports.ports, 1); + break; + + case VIRTIO_NET_HASH_REPORT_UDPv6: + virtio_net_toeplitz_calc(&toeplitz_state, + (__be32 *)&flow.addrs.v6addrs, + sizeof(flow.addrs.v6addrs) / 4); + virtio_net_toeplitz_calc(&toeplitz_state, &flow.ports.ports, 1); + break; + + default: + hash->report =3D VIRTIO_NET_HASH_REPORT_NONE; + return; + } + + hash->value =3D toeplitz_state.hash; + hash->report =3D report; +} + static inline bool virtio_net_hdr_match_proto(__be16 protocol, __u8 gso_ty= pe) { switch (gso_type & ~VIRTIO_NET_HDR_GSO_ECN) { --=20 2.46.0 From nobody Fri Nov 29 04:34:27 2024 Received: from mail-ed1-f49.google.com (mail-ed1-f49.google.com [209.85.208.49]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id E6E89156F2B for ; Tue, 24 Sep 2024 09:01:21 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.208.49 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1727168483; cv=none; b=qn4NQilhJojzCcEiAiioYl+37PijNa3KEs7VLfiEMeFHkWtCAgh0O3kxUd9PGrMBzAQ5KgTAeP6JJabLjk9EQKcV3trCaKMCjYir8XHDtf6hwb2/XzEsdmZfTYFC6KPlnTtqrx9nc9wdhQbSmaneEg5/Tca7i4e8AcyJr6BasoU= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1727168483; c=relaxed/simple; bh=jkhM+x9bNKZH2KnPiJz0Wz2oSY9j9Yf3OXEdL7BBvmc=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To; b=PeDqJnKrHmOhIZkO2ehS/PEicIx2b6mts08U4jyreEYMYuiP7GRbjJejq2cCl3d//IcNIXbeJuXpPxzZJFOAyDFr1f9fe8Tfw3TXunclgSJMKvKCHV/q2f/Ur9bfnbM4cKXfHDAnyg9usRdEY9/aoB3E1kL0HoMBPd9bcqGt85M= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=daynix.com; spf=none smtp.mailfrom=daynix.com; dkim=pass (2048-bit key) header.d=daynix-com.20230601.gappssmtp.com header.i=@daynix-com.20230601.gappssmtp.com header.b=i/YFuAt2; arc=none smtp.client-ip=209.85.208.49 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=daynix.com Authentication-Results: smtp.subspace.kernel.org; spf=none smtp.mailfrom=daynix.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=daynix-com.20230601.gappssmtp.com header.i=@daynix-com.20230601.gappssmtp.com header.b="i/YFuAt2" Received: by mail-ed1-f49.google.com with SMTP id 4fb4d7f45d1cf-5c5b9d2195eso3508535a12.1 for ; Tue, 24 Sep 2024 02:01:21 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=daynix-com.20230601.gappssmtp.com; s=20230601; t=1727168480; x=1727773280; darn=vger.kernel.org; h=to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:from:to:cc:subject:date:message-id :reply-to; bh=GLQiR3TXPfmR5MbSmS8z1giBJhJI6LMQJhK91hzIYDE=; b=i/YFuAt2kUDgdhMLNiLfwvnLHrHNKIRH5RltR9Kk4QaB09kSG64ykLz4L3TSaHXfNp gZALPqXuzwzSvDZBNemoN0Rs1cSX3nvxGQYJlSVRPWv8HGma99W9IGmbJYunMGSQ55LG Bib/VZS/eBXixyCLtNG0Ex9IF8b0H/K13Ija+CTW/Vos1SmUVf3QItkOaxfvSvk54gMV OyW53cmnLF1wpkbquZZmtowSDL5Kq5mHEdHIyqHBoERrxsUzsux4l9fcC1uKYTFd30SR wDgXQuDdAd8kyFzx5Pslbs8MGHie7AufcRk8o46y/PauLJOC4rDULwDF9GPR7rejXztf bHWQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1727168480; x=1727773280; h=to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=GLQiR3TXPfmR5MbSmS8z1giBJhJI6LMQJhK91hzIYDE=; b=Wq9Z6zbZjauA3ZivGnSM6SlREfdSj7yOaxY642gDPq6brv4kJfZu6ZYdVTRLZPw/tr 418L/02xejVlZlLDS9jwxS04Dx8t1U0IkWZbsdst9uBzNDaJ1XZISqKzz/L+HblKJS28 4TZqJTpyxd2BbC+JboW49kRViFcEKXwc8rQSL0QQvRiTm1mCuL5WxiGp/ujILjlsdtKH AgRAcjUhdPrm/OVQlLq/CR/URue/mZhuJh67E7Hdh+CkUxbfIRHSW305Aczw9N0G0S97 gl5zXtM/iGnCHCbbuWBA99bOlqu5ATgpOd/kjSXImx8go7fIIwc7g8hqibKRafYLIAz4 rUrg== X-Forwarded-Encrypted: i=1; AJvYcCUs4aohqqlurdPhOmnguiyFHl8hmtwgsGmcq42TsKHtmzZ5bmnkapi8mZs53pxuJpb+2EgnB824wHiqHqQ=@vger.kernel.org X-Gm-Message-State: AOJu0YyfOER7sXQ+T5k5zjflL0g5FOhb8GzEpGkGyajdEbJjNYCgbnZd LhYgTdSw3o2pRbh7GE3dW/tWfBWnkld57sQQjGYjEm8FP9RYBGSJ3IGObsOAVeQ= X-Google-Smtp-Source: AGHT+IFpGV2s1+MT/Wmetrjt1jnUx/JVoB/QDy6LvgWwnmt/y8aBUWSPmWV8V/zA8CCvTi/SZQaLnw== X-Received: by 2002:a17:906:6a22:b0:a8a:7b8e:fe52 with SMTP id a640c23a62f3a-a90d58c1039mr1494327966b.59.1727168480198; Tue, 24 Sep 2024 02:01:20 -0700 (PDT) Received: from localhost ([193.32.29.227]) by smtp.gmail.com with UTF8SMTPSA id a640c23a62f3a-a93930f470asm58712666b.151.2024.09.24.02.01.18 (version=TLS1_3 cipher=TLS_AES_128_GCM_SHA256 bits=128/128); Tue, 24 Sep 2024 02:01:19 -0700 (PDT) From: Akihiko Odaki Date: Tue, 24 Sep 2024 11:01:08 +0200 Subject: [PATCH RFC v4 3/9] net: flow_dissector: Export flow_keys_dissector_symmetric Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20240924-rss-v4-3-84e932ec0e6c@daynix.com> References: <20240924-rss-v4-0-84e932ec0e6c@daynix.com> In-Reply-To: <20240924-rss-v4-0-84e932ec0e6c@daynix.com> To: Jonathan Corbet , Willem de Bruijn , Jason Wang , "David S. Miller" , Eric Dumazet , Jakub Kicinski , Paolo Abeni , "Michael S. Tsirkin" , Xuan Zhuo , Shuah Khan , linux-doc@vger.kernel.org, linux-kernel@vger.kernel.org, netdev@vger.kernel.org, kvm@vger.kernel.org, virtualization@lists.linux-foundation.org, linux-kselftest@vger.kernel.org, Yuri Benditovich , Andrew Melnychenko , Stephen Hemminger , gur.stavi@huawei.com, Akihiko Odaki X-Mailer: b4 0.14-dev-fd6e3 flow_keys_dissector_symmetric is useful to derive a symmetric hash and to know its source such as IPv4, IPv6, TCP, and UDP. Signed-off-by: Akihiko Odaki --- include/net/flow_dissector.h | 1 + net/core/flow_dissector.c | 3 ++- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/include/net/flow_dissector.h b/include/net/flow_dissector.h index ced79dc8e856..d01c1ec77b7d 100644 --- a/include/net/flow_dissector.h +++ b/include/net/flow_dissector.h @@ -423,6 +423,7 @@ __be32 flow_get_u32_src(const struct flow_keys *flow); __be32 flow_get_u32_dst(const struct flow_keys *flow); =20 extern struct flow_dissector flow_keys_dissector; +extern struct flow_dissector flow_keys_dissector_symmetric; extern struct flow_dissector flow_keys_basic_dissector; =20 /* struct flow_keys_digest: diff --git a/net/core/flow_dissector.c b/net/core/flow_dissector.c index 0e638a37aa09..9822988f2d49 100644 --- a/net/core/flow_dissector.c +++ b/net/core/flow_dissector.c @@ -1852,7 +1852,8 @@ void make_flow_keys_digest(struct flow_keys_digest *d= igest, } EXPORT_SYMBOL(make_flow_keys_digest); =20 -static struct flow_dissector flow_keys_dissector_symmetric __read_mostly; +struct flow_dissector flow_keys_dissector_symmetric __read_mostly; +EXPORT_SYMBOL(flow_keys_dissector_symmetric); =20 u32 __skb_get_hash_symmetric_net(const struct net *net, const struct sk_bu= ff *skb) { --=20 2.46.0 From nobody Fri Nov 29 04:34:27 2024 Received: from mail-ed1-f41.google.com (mail-ed1-f41.google.com [209.85.208.41]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id E65C41741D2 for ; Tue, 24 Sep 2024 09:01:24 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.208.41 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1727168486; cv=none; b=Ranjv00vVhNHlgbv0N0xEQE64eIGqR0K/ElqnWcXqo/IrqKC5A1KLy6WqRQyCTekbgcBCwQ+QrrmACt9D3PG+1E/dKpERfWSn5arPbVr9JnCguKG7CLak1DALKNhnW3Gfz/6Q6yIUrIWpUZZe2Gc0KB8FgJMZwhu6AjNPMK/NqQ= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1727168486; c=relaxed/simple; bh=ewPtrkqvk7tD3P+mpp0by+kAXiz3ZKe4MhDOXA8p8qI=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To; b=Ns5FpIsWoGSaDJHGy8Kvh6Bh0AMlQN7sjA1oX2X6cAw59F/jXD88J6kmuVG2RmTEnSrLpxO5JjEdP1xBxodEwVYVvXHSdVB7voelpYw+c1OfcYo/Y+NrNmYx5TFkTw5oA5EoMobQFguqdEcrQPGrfw6gzhP2aeHa9FIfcNl2At8= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=daynix.com; spf=none smtp.mailfrom=daynix.com; dkim=pass (2048-bit key) header.d=daynix-com.20230601.gappssmtp.com header.i=@daynix-com.20230601.gappssmtp.com header.b=zYFb+yGH; arc=none smtp.client-ip=209.85.208.41 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=daynix.com Authentication-Results: smtp.subspace.kernel.org; spf=none smtp.mailfrom=daynix.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=daynix-com.20230601.gappssmtp.com header.i=@daynix-com.20230601.gappssmtp.com header.b="zYFb+yGH" Received: by mail-ed1-f41.google.com with SMTP id 4fb4d7f45d1cf-5c40aea5c40so8095754a12.0 for ; Tue, 24 Sep 2024 02:01:24 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=daynix-com.20230601.gappssmtp.com; s=20230601; t=1727168483; x=1727773283; darn=vger.kernel.org; h=to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:from:to:cc:subject:date:message-id :reply-to; bh=cqdM7AXxfnozdS0h/go68YV5to8QygcNOYorhOUDEHE=; b=zYFb+yGHY7hDTToG5WBFWR+RrE9rxARBX9dwK3FqcSTWPy/dFaxkqQF/jzIkWNjKaj bvv29kIq/0OSOhQUs4zsMSlfbS370rB8dRZEJhJIwIpAfTX/rE/uGVZF+Bkh1ewIGOxt K6PW/7XV5/kcDRei6HqtKkOYgPMIfo1vMxKubwwtGMDnh+cYbwLQgUL/cu30fhYTQjZe YV0tPZ40sEFrg3GzSgPxZLRiwc/YJQmYteVhWAC9PL00kchIsqUAd3zmo+FTwcbpaB8L O/vXdhEGHBDGICjaVA0CSIhvuIpM2bSayPkqQQ8XSActDLWUKPmR8916zbsr3iR8I5X9 molQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1727168483; x=1727773283; h=to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=cqdM7AXxfnozdS0h/go68YV5to8QygcNOYorhOUDEHE=; b=GGy/uut/wk39r4bXAaasgIrDOMUHjMlatOwZ1i8pY1jm+/+KTm2nt9DtaVNrvXODKf qHyoeJV5sHgkxdnZk0EC8dwCbqrdpM6qbibiEJdQ9S0Uf6hWksntci0x2n8A2E+mcUiu caDujkwJpVIkquTgAr+jhCsdY8szwu6wgvhcyF2RDztMgG8BCOph/vCuqdYT8HIQfPqF DENEDGY7Y0nDhYj32zfuyz/aSLm66s1q4/y8U8XlXQ7LeVViS3pjz7V6bvUjq9//nZ1k A0WIRWi514yqEtrB9fw6NeR4rJOq23k3DtXwpiLZl3wn3X2GAK2YCKY6soTYCP+MKrIs 57jg== X-Forwarded-Encrypted: i=1; AJvYcCUWEv9QPL99Wxks9/NkgECgq35jSQ2H3+9G7NWp5F3PyjXVjbNrDBSixC1hoXKklaRUUbMLcckouminjZw=@vger.kernel.org X-Gm-Message-State: AOJu0Yy9xut2/rUQiFS+HqGF91/T1reSX6wQtO6cQ3LsAQipjy8wYsUj 0LGbJvJPva8yOpHzFapbHSZXfqjtr4Qo7sKXpWTNVaCtDplEmyapCuDBPT4RCU4= X-Google-Smtp-Source: AGHT+IFYf5KaP4Pzb9vgh1qbbep/BjQkKcAMhxJhINPSfPa8KAAu/uVDRcfMAnuh0Cd6Ah0QYwKNXQ== X-Received: by 2002:a05:6402:34c9:b0:5c5:cda5:9328 with SMTP id 4fb4d7f45d1cf-5c5cdfa04e3mr2809831a12.4.1727168483131; Tue, 24 Sep 2024 02:01:23 -0700 (PDT) Received: from localhost ([193.32.29.227]) by smtp.gmail.com with UTF8SMTPSA id 4fb4d7f45d1cf-5c5cf4c52aesm526635a12.59.2024.09.24.02.01.20 (version=TLS1_3 cipher=TLS_AES_128_GCM_SHA256 bits=128/128); Tue, 24 Sep 2024 02:01:22 -0700 (PDT) From: Akihiko Odaki Date: Tue, 24 Sep 2024 11:01:09 +0200 Subject: [PATCH RFC v4 4/9] tap: Pad virtio header with zero Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20240924-rss-v4-4-84e932ec0e6c@daynix.com> References: <20240924-rss-v4-0-84e932ec0e6c@daynix.com> In-Reply-To: <20240924-rss-v4-0-84e932ec0e6c@daynix.com> To: Jonathan Corbet , Willem de Bruijn , Jason Wang , "David S. Miller" , Eric Dumazet , Jakub Kicinski , Paolo Abeni , "Michael S. Tsirkin" , Xuan Zhuo , Shuah Khan , linux-doc@vger.kernel.org, linux-kernel@vger.kernel.org, netdev@vger.kernel.org, kvm@vger.kernel.org, virtualization@lists.linux-foundation.org, linux-kselftest@vger.kernel.org, Yuri Benditovich , Andrew Melnychenko , Stephen Hemminger , gur.stavi@huawei.com, Akihiko Odaki X-Mailer: b4 0.14-dev-fd6e3 tap used to simply advance iov_iter when it needs to pad virtio header, which leaves the garbage in the buffer as is. This is especially problematic when tap starts to allow enabling the hash reporting feature; even if the feature is enabled, the packet may lack a hash value and may contain a hole in the virtio header because the packet arrived before the feature gets enabled or does not contain the header fields to be hashed. If the hole is not filled with zero, it is impossible to tell if the packet lacks a hash value. In theory, a user of tap can fill the buffer with zero before calling read() to avoid such a problem, but leaving the garbage in the buffer is awkward anyway so fill the buffer in tap. Signed-off-by: Akihiko Odaki --- drivers/net/tap.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/tap.c b/drivers/net/tap.c index 77574f7a3bd4..ba044302ccc6 100644 --- a/drivers/net/tap.c +++ b/drivers/net/tap.c @@ -813,7 +813,7 @@ static ssize_t tap_put_user(struct tap_queue *q, sizeof(vnet_hdr)) return -EFAULT; =20 - iov_iter_advance(iter, vnet_hdr_len - sizeof(vnet_hdr)); + iov_iter_zero(vnet_hdr_len - sizeof(vnet_hdr), iter); } total =3D vnet_hdr_len; total +=3D skb->len; --=20 2.46.0 From nobody Fri Nov 29 04:34:27 2024 Received: from mail-ej1-f50.google.com (mail-ej1-f50.google.com [209.85.218.50]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 2BBCA178388 for ; Tue, 24 Sep 2024 09:01:26 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.218.50 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1727168488; cv=none; b=bw/oYi5eqmkV3N1aYxdaOApqthD5hWsrcjUFciCEV9k6RK6jNQNgRtAEcyZZWSB0n7VVdkSc0Os2JjknXlVIUniCflnAuHgwov4uzqgw4XDNJikh0qxwiyVufmZ64b2ANjU9qn7+L8bCynHx9KIC7c4Qwpllbj7nPaoMUyFy5gg= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1727168488; c=relaxed/simple; bh=VYv+sy+VDukn69W3Bu5/T2bthOtDJXnePcCJtj3KG4w=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To; b=t+zqnuCDazxxpqRZFVbfVp2DaKl95n/algqCIfXUDnqP2OSUaTtxRss8ywBqJASwNHpiuA9g1mZ3OMjm7mAD2syYbF+6cfB5pDbLlm+8RXKFQKTAIxppiuJlzXLYP520svPsis62XjiXNIlCQLo4RKThQsXNxekA+3WXCBRZRFQ= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=daynix.com; spf=none smtp.mailfrom=daynix.com; dkim=pass (2048-bit key) header.d=daynix-com.20230601.gappssmtp.com header.i=@daynix-com.20230601.gappssmtp.com header.b=zupO9Ba2; arc=none smtp.client-ip=209.85.218.50 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=daynix.com Authentication-Results: smtp.subspace.kernel.org; spf=none smtp.mailfrom=daynix.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=daynix-com.20230601.gappssmtp.com header.i=@daynix-com.20230601.gappssmtp.com header.b="zupO9Ba2" Received: by mail-ej1-f50.google.com with SMTP id a640c23a62f3a-a8a7b1c2f2bso878623066b.0 for ; Tue, 24 Sep 2024 02:01:26 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=daynix-com.20230601.gappssmtp.com; s=20230601; t=1727168485; x=1727773285; darn=vger.kernel.org; h=to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:from:to:cc:subject:date:message-id :reply-to; bh=1z2jVjMLVH28Vvu6Jrp+eHoNG85dGW4/noaq6q8us20=; b=zupO9Ba2eoaQV4vuwKtBUj2VFLr9Q98dCTZWlgvFOWpYJOo42ecmed61dm2HzIX0Wi B6+eZSOflcBWi7BcdcBTTy1VuJgKMgq87+KeVSxAIN1zaWssrfIispNgq/HqKSei82kf G3Q6vL/R7KYx+3y/EwcnPXLhbonqH1vZsLhhYtzewuEbbUkPUwajUHUCKij7evnY3eej Me8/wVdbZ5FoPxG4AEX4rVUGt/l0hlHPop8jKU9Gyho7zLfX6GF76nq6oRgzgh8BhCW6 9E9lcTPHk49j4QJFVfHqzd0Tzi/O4+/a1dcgdgEOSYKif3TvfuYo8kKkARWiHB/Psjw7 d15w== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1727168485; x=1727773285; h=to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=1z2jVjMLVH28Vvu6Jrp+eHoNG85dGW4/noaq6q8us20=; b=KIG5adD1FSM6e5i18O+kq3ogBKZrX94nXj5eEXsD8BRYNrmBPORzT/prSap4Sbb/Z2 VnfnQ1BjDFbN7Vwke3tNVwRIUTh09uxz8iVYbKnQGn7ZJnMscfvSXYx0P3+TAfdgRrdi /TOXm2YOCvShFTItCKZkitmWCpVVixUV6CIK4U0l0yG5e6TEualqVqA3ELnguDa7uR4f s/Ra7auyKHDYD/UC4vn3/jq+t5Q+NhDMAnDdAH8unoPfFZ+FqRIBug1umz7V6U5gRXQt 3h0xSHKVitYSJbXpLf9QzQFvCE5Wm2nK8ACCy8hhlZEq1mt2kuCta1sH5348nNmONXd5 UTVw== X-Forwarded-Encrypted: i=1; AJvYcCVMraQK9FwtXytXgjH3ql/sh5CGEBBNMuEEFyZEx6jWJm4NsASCRQLDSfFe/GV6NqhqBg5slgHZYHjbm8w=@vger.kernel.org X-Gm-Message-State: AOJu0YyT4E7nFLYRhA76t3XEYaQhLAaRp2ZUq2RYevITwdBVbOWWkRrH IzL7eE5uQRMQVRZsotvuX2ymt41d5IXX72fcucuE3A/VwKAf6NV7SAwTYCkjgWI= X-Google-Smtp-Source: AGHT+IHUq/dkWRpPMqsa4EeYb9S0z67V0A8NcjQ83e5aXy7PtfQ3vrN7fPuwMQhOhYz1y6x1alrMzg== X-Received: by 2002:a17:907:e212:b0:a90:430e:6a34 with SMTP id a640c23a62f3a-a90d503382dmr1557301366b.31.1727168485178; Tue, 24 Sep 2024 02:01:25 -0700 (PDT) Received: from localhost ([193.32.29.227]) by smtp.gmail.com with UTF8SMTPSA id a640c23a62f3a-a9393138be1sm58586966b.219.2024.09.24.02.01.23 (version=TLS1_3 cipher=TLS_AES_128_GCM_SHA256 bits=128/128); Tue, 24 Sep 2024 02:01:24 -0700 (PDT) From: Akihiko Odaki Date: Tue, 24 Sep 2024 11:01:10 +0200 Subject: [PATCH RFC v4 5/9] tun: Pad virtio header with zero Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20240924-rss-v4-5-84e932ec0e6c@daynix.com> References: <20240924-rss-v4-0-84e932ec0e6c@daynix.com> In-Reply-To: <20240924-rss-v4-0-84e932ec0e6c@daynix.com> To: Jonathan Corbet , Willem de Bruijn , Jason Wang , "David S. Miller" , Eric Dumazet , Jakub Kicinski , Paolo Abeni , "Michael S. Tsirkin" , Xuan Zhuo , Shuah Khan , linux-doc@vger.kernel.org, linux-kernel@vger.kernel.org, netdev@vger.kernel.org, kvm@vger.kernel.org, virtualization@lists.linux-foundation.org, linux-kselftest@vger.kernel.org, Yuri Benditovich , Andrew Melnychenko , Stephen Hemminger , gur.stavi@huawei.com, Akihiko Odaki X-Mailer: b4 0.14-dev-fd6e3 tun used to simply advance iov_iter when it needs to pad virtio header, which leaves the garbage in the buffer as is. This is especially problematic when tun starts to allow enabling the hash reporting feature; even if the feature is enabled, the packet may lack a hash value and may contain a hole in the virtio header because the packet arrived before the feature gets enabled or does not contain the header fields to be hashed. If the hole is not filled with zero, it is impossible to tell if the packet lacks a hash value. In theory, a user of tun can fill the buffer with zero before calling read() to avoid such a problem, but leaving the garbage in the buffer is awkward anyway so fill the buffer in tun. Signed-off-by: Akihiko Odaki --- drivers/net/tun.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/net/tun.c b/drivers/net/tun.c index 1d06c560c5e6..9d93ab9ee58f 100644 --- a/drivers/net/tun.c +++ b/drivers/net/tun.c @@ -2073,7 +2073,7 @@ static ssize_t tun_put_user_xdp(struct tun_struct *tu= n, if (unlikely(copy_to_iter(&gso, sizeof(gso), iter) !=3D sizeof(gso))) return -EFAULT; - iov_iter_advance(iter, vnet_hdr_sz - sizeof(gso)); + iov_iter_zero(vnet_hdr_sz - sizeof(gso), iter); } =20 ret =3D copy_to_iter(xdp_frame->data, size, iter) + vnet_hdr_sz; @@ -2146,7 +2146,7 @@ static ssize_t tun_put_user(struct tun_struct *tun, if (copy_to_iter(&gso, sizeof(gso), iter) !=3D sizeof(gso)) return -EFAULT; =20 - iov_iter_advance(iter, vnet_hdr_sz - sizeof(gso)); + iov_iter_zero(vnet_hdr_sz - sizeof(gso), iter); } =20 if (vlan_hlen) { --=20 2.46.0 From nobody Fri Nov 29 04:34:27 2024 Received: from mail-ej1-f41.google.com (mail-ej1-f41.google.com [209.85.218.41]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 4DF7517BEBD for ; Tue, 24 Sep 2024 09:01:29 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.218.41 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1727168492; cv=none; b=LLv5TOtobDcdSNnI0/L7UgOwp8TwvU0F7U34h8ocIDKOxvrIAmcz1f0n7pNItSj7e6JlCgltdFd/WoyTs5lgCBgmGYiVhsOw8cHX507gyzlC1vl3p+iFZJaZL/jA9/fTlu7M3cow9LGlDseFbuUuK6b8qpPES8yaRnxjmY7lzi8= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1727168492; c=relaxed/simple; bh=oV1JUkP8W1vYe9S7wWIQJD4ympP3jMhWLs2iFcdTwzc=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To; b=e75/vbnJWUYzSwt4/mmTkJRj7TAfNr+f9ckCEBapO1rlCnAgkrcFsk8Qm5wtYaI819Hq1+9ZsozkZ6rFsYArlh7c3mfHHZOOgXgTLv2ITl6l7SyN0HzbS2m1WQAS34G3khl3l4Pct1BYCvBTr+cRbbLMSzWG1ebW9zD6ZGZRpw4= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=daynix.com; spf=none smtp.mailfrom=daynix.com; dkim=pass (2048-bit key) header.d=daynix-com.20230601.gappssmtp.com header.i=@daynix-com.20230601.gappssmtp.com header.b=3Kf8QxFf; arc=none smtp.client-ip=209.85.218.41 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=daynix.com Authentication-Results: smtp.subspace.kernel.org; spf=none smtp.mailfrom=daynix.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=daynix-com.20230601.gappssmtp.com header.i=@daynix-com.20230601.gappssmtp.com header.b="3Kf8QxFf" Received: by mail-ej1-f41.google.com with SMTP id a640c23a62f3a-a8d64b27c45so969000566b.3 for ; Tue, 24 Sep 2024 02:01:29 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=daynix-com.20230601.gappssmtp.com; s=20230601; t=1727168488; x=1727773288; darn=vger.kernel.org; h=to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:from:to:cc:subject:date:message-id :reply-to; bh=6Om/3wu4kS687ZdFV0+xHRhdMwLbgwny48pP3LqMtoo=; b=3Kf8QxFfR9qPypajMdaXoxOmDk4kIhNL4WKaun2XscswINf+FK447gTvi0kcDS+9hW bE7veGGYqNeSCXXp8OlK/80nKt/BPUlHhd18IxfWRiBDT8og5GLA66aH8quIij812sym j2sI/wRx+H2VzC+w2KNL6vg1yWkREtZhBBUd25un+N3qurBodYAlu1hjljRbGjHSK7k7 ZNujZPasN57G27CZl5q/o/aw/ceXgMxffax+6ZILVXH5IFIXMTN4HWcV09uRQxlpDAY4 xlDu/0WJeVYikBGn6PQyqcbllEX7jgdP0SUUJKPH9f+LClMFwZ92StQeBWr8NFwOog4c IzOQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1727168488; x=1727773288; h=to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=6Om/3wu4kS687ZdFV0+xHRhdMwLbgwny48pP3LqMtoo=; b=pMWSDrStl+UwZ2E+FOlYdyIzxiNY99Ks+dMUDyw0xbQzIscK+sHGRAdVn/xhZY1gWr bWZ4rRB1EOKHnyiUwGG8fTOQ17OSc38Rp57lk3CAgNFIkdvpiaW9sfDBjwqQpSStaJ4S 7gjR8qQdPLP2VgQGwv1ePXdTOIFgB9/ck28k2nWKQ8ygtEhI/SPNp+8tSv2kFxaxLbZD UbXg0VTV09toeJL63uKgxGIL9PkVYgrJlsdokcRP3Dzp8j43WhYGcxU1hlt9W9e9HmBp 9kvX8p4sQXHWrS17NaSAypNszWxR9+Smq2B0dA6gmVip1sU9rUY+L7eZYcUGFI0URfna WNGQ== X-Forwarded-Encrypted: i=1; AJvYcCVpTCtU0N8X6dkVkYiGz3lOlEAN9hZgnQK2qtLHzpWTbqjXvwJLokLbM35hdSxiSB5/M1yrZ8eVTwCYQrE=@vger.kernel.org X-Gm-Message-State: AOJu0YyWZTusa9FPoHF0M44xfvr1moTbxrpprrCBeBSvzOrpEm7bw+gW SwptKJI7jP07X3yP6Au2nR5rKXTEI/0nlMpDVzlfUjuFpHeR+vq36RCsBz/EAEs= X-Google-Smtp-Source: AGHT+IHs03bJZmwoKWOU8mAuHuG6wZ42PI14gDUKn/VRNPY8OWcO6YXdGtf+F+s8OwpND/dwpJC7yA== X-Received: by 2002:a17:906:dace:b0:a91:158f:6692 with SMTP id a640c23a62f3a-a91158f6847mr376252166b.62.1727168487389; Tue, 24 Sep 2024 02:01:27 -0700 (PDT) Received: from localhost ([193.32.29.227]) by smtp.gmail.com with UTF8SMTPSA id a640c23a62f3a-a93930c8a98sm60206466b.124.2024.09.24.02.01.26 (version=TLS1_3 cipher=TLS_AES_128_GCM_SHA256 bits=128/128); Tue, 24 Sep 2024 02:01:26 -0700 (PDT) From: Akihiko Odaki Date: Tue, 24 Sep 2024 11:01:11 +0200 Subject: [PATCH RFC v4 6/9] tun: Introduce virtio-net hash reporting feature Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20240924-rss-v4-6-84e932ec0e6c@daynix.com> References: <20240924-rss-v4-0-84e932ec0e6c@daynix.com> In-Reply-To: <20240924-rss-v4-0-84e932ec0e6c@daynix.com> To: Jonathan Corbet , Willem de Bruijn , Jason Wang , "David S. Miller" , Eric Dumazet , Jakub Kicinski , Paolo Abeni , "Michael S. Tsirkin" , Xuan Zhuo , Shuah Khan , linux-doc@vger.kernel.org, linux-kernel@vger.kernel.org, netdev@vger.kernel.org, kvm@vger.kernel.org, virtualization@lists.linux-foundation.org, linux-kselftest@vger.kernel.org, Yuri Benditovich , Andrew Melnychenko , Stephen Hemminger , gur.stavi@huawei.com, Akihiko Odaki X-Mailer: b4 0.14-dev-fd6e3 Allow the guest to reuse the hash value to make receive steering consistent between the host and guest, and to save hash computation. Signed-off-by: Akihiko Odaki --- Documentation/networking/tuntap.rst | 7 +++ drivers/net/Kconfig | 1 + drivers/net/tun.c | 117 +++++++++++++++++++++++++++++++-= ---- include/uapi/linux/if_tun.h | 44 ++++++++++++++ 4 files changed, 155 insertions(+), 14 deletions(-) diff --git a/Documentation/networking/tuntap.rst b/Documentation/networking= /tuntap.rst index 4d7087f727be..86b4ae8caa8a 100644 --- a/Documentation/networking/tuntap.rst +++ b/Documentation/networking/tuntap.rst @@ -206,6 +206,13 @@ enable is true we enable it, otherwise we disable it:: return ioctl(fd, TUNSETQUEUE, (void *)&ifr); } =20 +3.4 Reference +------------- + +``linux/if_tun.h`` defines the interface described below: + +.. kernel-doc:: include/uapi/linux/if_tun.h + Universal TUN/TAP device driver Frequently Asked Question =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D =20 diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig index 9920b3a68ed1..e2a7bd703550 100644 --- a/drivers/net/Kconfig +++ b/drivers/net/Kconfig @@ -395,6 +395,7 @@ config TUN tristate "Universal TUN/TAP device driver support" depends on INET select CRC32 + select SKB_EXTENSIONS help TUN/TAP provides packet reception and transmission for user space programs. It can be viewed as a simple Point-to-Point or Ethernet diff --git a/drivers/net/tun.c b/drivers/net/tun.c index 9d93ab9ee58f..986e4a5bf04d 100644 --- a/drivers/net/tun.c +++ b/drivers/net/tun.c @@ -173,6 +173,10 @@ struct tun_prog { struct bpf_prog *prog; }; =20 +struct tun_vnet_hash_container { + struct tun_vnet_hash common; +}; + /* Since the socket were moved to tun_file, to preserve the behavior of pe= rsist * device, socket filter, sndbuf and vnet header size were restore when the * file were attached to a persist device. @@ -210,6 +214,7 @@ struct tun_struct { struct bpf_prog __rcu *xdp_prog; struct tun_prog __rcu *steering_prog; struct tun_prog __rcu *filter_prog; + struct tun_vnet_hash vnet_hash; struct ethtool_link_ksettings link_ksettings; /* init args */ struct file *file; @@ -221,6 +226,11 @@ struct veth { __be16 h_vlan_TCI; }; =20 +static const struct tun_vnet_hash tun_vnet_hash_cap =3D { + .flags =3D TUN_VNET_HASH_REPORT, + .types =3D VIRTIO_NET_SUPPORTED_HASH_TYPES +}; + static void tun_flow_init(struct tun_struct *tun); static void tun_flow_uninit(struct tun_struct *tun); =20 @@ -322,10 +332,15 @@ static long tun_set_vnet_be(struct tun_struct *tun, i= nt __user *argp) if (get_user(be, argp)) return -EFAULT; =20 - if (be) + if (be) { + if (!(tun->flags & TUN_VNET_LE) && + (tun->vnet_hash.flags & TUN_VNET_HASH_REPORT)) + return -EBUSY; + tun->flags |=3D TUN_VNET_BE; - else + } else { tun->flags &=3D ~TUN_VNET_BE; + } =20 return 0; } @@ -524,12 +539,17 @@ static inline void tun_flow_save_rps_rxhash(struct tu= n_flow_entry *e, u32 hash) */ static u16 tun_automq_select_queue(struct tun_struct *tun, struct sk_buff = *skb) { + struct tun_vnet_hash_ext *ext; + struct flow_keys keys; struct tun_flow_entry *e; u32 txq, numqueues; =20 numqueues =3D READ_ONCE(tun->numqueues); =20 - txq =3D __skb_get_hash_symmetric(skb); + memset(&keys, 0, sizeof(keys)); + skb_flow_dissect(skb, &flow_keys_dissector_symmetric, &keys, 0); + + txq =3D flow_hash_from_keys(&keys); e =3D tun_flow_find(&tun->flows[tun_hashfn(txq)], txq); if (e) { tun_flow_save_rps_rxhash(e, txq); @@ -538,6 +558,16 @@ static u16 tun_automq_select_queue(struct tun_struct *= tun, struct sk_buff *skb) txq =3D reciprocal_scale(txq, numqueues); } =20 + if (tun->vnet_hash.flags & TUN_VNET_HASH_REPORT) { + ext =3D skb_ext_add(skb, SKB_EXT_TUN_VNET_HASH); + if (ext) { + u32 types =3D tun->vnet_hash.types; + + ext->report =3D virtio_net_hash_report(types, keys.basic); + ext->value =3D skb->l4_hash ? skb->hash : txq; + } + } + return txq; } =20 @@ -2120,33 +2150,58 @@ static ssize_t tun_put_user(struct tun_struct *tun, } =20 if (vnet_hdr_sz) { - struct virtio_net_hdr gso; + struct tun_vnet_hash_ext *ext; + size_t vnet_hdr_content_sz =3D sizeof(struct virtio_net_hdr); + union { + struct virtio_net_hdr hdr; + struct virtio_net_hdr_v1_hash hdr_v1_hash; + } vnet_hdr; + int ret; =20 if (iov_iter_count(iter) < vnet_hdr_sz) return -EINVAL; =20 - if (virtio_net_hdr_from_skb(skb, &gso, - tun_is_little_endian(tun), true, - vlan_hlen)) { + ext =3D vnet_hdr_sz < sizeof(vnet_hdr.hdr_v1_hash) ? + NULL : skb_ext_find(skb, SKB_EXT_TUN_VNET_HASH); + + if (ext) { + vnet_hdr_content_sz =3D sizeof(vnet_hdr.hdr_v1_hash); + memset(&vnet_hdr, 0, vnet_hdr_content_sz); + vnet_hdr.hdr_v1_hash.hdr.num_buffers =3D __cpu_to_virtio16(true, 1); + vnet_hdr.hdr_v1_hash.hash_value =3D cpu_to_le32(ext->value); + vnet_hdr.hdr_v1_hash.hash_report =3D cpu_to_le16(ext->report); + } else { + vnet_hdr_content_sz =3D sizeof(struct virtio_net_hdr); + } + + ret =3D virtio_net_hdr_from_skb(skb, + &vnet_hdr.hdr, + tun_is_little_endian(tun), + true, + vlan_hlen); + + if (ret) { struct skb_shared_info *sinfo =3D skb_shinfo(skb); =20 if (net_ratelimit()) { netdev_err(tun->dev, "unexpected GSO type: 0x%x, gso_size %d, hdr_len = %d\n", - sinfo->gso_type, tun16_to_cpu(tun, gso.gso_size), - tun16_to_cpu(tun, gso.hdr_len)); + sinfo->gso_type, + tun16_to_cpu(tun, vnet_hdr.hdr.gso_size), + tun16_to_cpu(tun, vnet_hdr.hdr.hdr_len)); print_hex_dump(KERN_ERR, "tun: ", DUMP_PREFIX_NONE, 16, 1, skb->head, - min((int)tun16_to_cpu(tun, gso.hdr_len), 64), true); + min(tun16_to_cpu(tun, vnet_hdr.hdr.hdr_len), 64), + true); } WARN_ON_ONCE(1); return -EINVAL; } =20 - if (copy_to_iter(&gso, sizeof(gso), iter) !=3D sizeof(gso)) + if (copy_to_iter(&vnet_hdr, vnet_hdr_content_sz, iter) !=3D vnet_hdr_con= tent_sz) return -EFAULT; =20 - iov_iter_zero(vnet_hdr_sz - sizeof(gso), iter); + iov_iter_zero(vnet_hdr_sz - vnet_hdr_content_sz, iter); } =20 if (vlan_hlen) { @@ -3094,6 +3149,7 @@ static long __tun_chr_ioctl(struct file *file, unsign= ed int cmd, int le; int ret; bool do_notify =3D false; + struct tun_vnet_hash vnet_hash; =20 if (cmd =3D=3D TUNSETIFF || cmd =3D=3D TUNSETQUEUE || (_IOC_TYPE(cmd) =3D=3D SOCK_IOC_TYPE && cmd !=3D SIOCGSKNS)) { @@ -3115,6 +3171,9 @@ static long __tun_chr_ioctl(struct file *file, unsign= ed int cmd, if (!ns_capable(net->user_ns, CAP_NET_ADMIN)) return -EPERM; return open_related_ns(&net->ns, get_net_ns); + } else if (cmd =3D=3D TUNGETVNETHASHCAP) { + return copy_to_user(argp, &tun_vnet_hash_cap, sizeof(tun_vnet_hash_cap))= ? + -EFAULT : 0; } =20 rtnl_lock(); @@ -3314,6 +3373,12 @@ static long __tun_chr_ioctl(struct file *file, unsig= ned int cmd, break; } =20 + if (tun->vnet_hash.flags & TUN_VNET_HASH_REPORT && + vnet_hdr_sz < (int)sizeof(struct virtio_net_hdr_v1_hash)) { + ret =3D -EBUSY; + break; + } + tun->vnet_hdr_sz =3D vnet_hdr_sz; break; =20 @@ -3328,10 +3393,17 @@ static long __tun_chr_ioctl(struct file *file, unsi= gned int cmd, ret =3D -EFAULT; break; } - if (le) + if (le) { tun->flags |=3D TUN_VNET_LE; - else + } else { + if (tun->vnet_hash.flags & TUN_VNET_HASH_REPORT && + !tun_legacy_is_little_endian(tun)) { + ret =3D -EBUSY; + break; + } + tun->flags &=3D ~TUN_VNET_LE; + } break; =20 case TUNGETVNETBE: @@ -3396,6 +3468,23 @@ static long __tun_chr_ioctl(struct file *file, unsig= ned int cmd, ret =3D open_related_ns(&net->ns, get_net_ns); break; =20 + case TUNSETVNETHASH: + if (copy_from_user(&vnet_hash, argp, sizeof(vnet_hash))) { + ret =3D -EFAULT; + break; + } + argp =3D (struct tun_vnet_hash __user *)argp + 1; + + if ((vnet_hash.flags & TUN_VNET_HASH_REPORT) && + (tun->vnet_hdr_sz < sizeof(struct virtio_net_hdr_v1_hash) || + !tun_is_little_endian(tun))) { + ret =3D -EBUSY; + break; + } + + tun->vnet_hash =3D vnet_hash; + break; + default: ret =3D -EINVAL; break; diff --git a/include/uapi/linux/if_tun.h b/include/uapi/linux/if_tun.h index 287cdc81c939..1561e8ce0a0a 100644 --- a/include/uapi/linux/if_tun.h +++ b/include/uapi/linux/if_tun.h @@ -62,6 +62,30 @@ #define TUNSETCARRIER _IOW('T', 226, int) #define TUNGETDEVNETNS _IO('T', 227) =20 +/** + * define TUNGETVNETHASHCAP - ioctl to get virtio_net hashing capability. + * + * The argument is a pointer to &struct tun_vnet_hash which will store the + * maximal virtio_net hashing configuration. + */ +#define TUNGETVNETHASHCAP _IOR('T', 228, struct tun_vnet_hash) + +/** + * define TUNSETVNETHASH - ioctl to configure virtio_net hashing + * + * The argument is a pointer to &struct tun_vnet_hash. + * + * %TUNSETVNETHDRSZ ioctl must be called with a number greater than or equ= al to + * the size of &struct virtio_net_hdr_v1_hash before calling this ioctl wi= th + * %TUN_VNET_HASH_REPORT. + * + * The virtio_net header must be configured as little-endian before callin= g this + * ioctl with %TUN_VNET_HASH_REPORT. + * + * This ioctl currently has no effect on XDP packets. + */ +#define TUNSETVNETHASH _IOW('T', 229, struct tun_vnet_hash) + /* TUNSETIFF ifr flags */ #define IFF_TUN 0x0001 #define IFF_TAP 0x0002 @@ -115,4 +139,24 @@ struct tun_filter { __u8 addr[][ETH_ALEN]; }; =20 +/** + * define TUN_VNET_HASH_REPORT - Request virtio_net hash reporting for vho= st + */ +#define TUN_VNET_HASH_REPORT 0x0001 + +/** + * struct tun_vnet_hash - virtio_net hashing configuration + * @flags: + * Bitmask consists of %TUN_VNET_HASH_REPORT and %TUN_VNET_HASH_RSS + * @pad: + * Should be filled with zero before passing to %TUNSETVNETHASH + * @types: + * Bitmask of allowed hash types + */ +struct tun_vnet_hash { + __u16 flags; + __u8 pad[2]; + __u32 types; +}; + #endif /* _UAPI__IF_TUN_H */ --=20 2.46.0 From nobody Fri Nov 29 04:34:27 2024 Received: from mail-lf1-f54.google.com (mail-lf1-f54.google.com [209.85.167.54]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 6520817E005 for ; Tue, 24 Sep 2024 09:01:32 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.167.54 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1727168494; cv=none; b=YkC5m98o518lZoEuaq9yKFPbCKZYVWcUeTM36MRx8gXlj6S/G1FolH8DYDnM6kKotG/ux441ZmzJ1Nhy2d858fKZedcqNSoVipsn33PzUv22uXmnKEFOFtu4h+YJH8/un3CDXUUMMZLRrsEM83SxdEVO0/9QbCukHjmYmQyh0cs= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1727168494; c=relaxed/simple; bh=BqiOF36eGEzK1kC4qfdF9HSccFKNzNFy1wd25a7fw8Y=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To; b=feh6y4vXRrLqFoT1yiqU7HnH4vLI0ZhXKG3dJEBcQ2x9elxDJFt+Zlka0hbnUfDGt8UCRcyXmyHhgGzLjpf8Od/88eDgpc2oPStQnNscnAqrmmplycDJ0dMOaAZL3W4WWNLT3YzND+2TpJDxMUIB7p2o1l2YbFGfknBr36LmMLc= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=daynix.com; spf=none smtp.mailfrom=daynix.com; dkim=pass (2048-bit key) header.d=daynix-com.20230601.gappssmtp.com header.i=@daynix-com.20230601.gappssmtp.com header.b=Yolsy7Ae; arc=none smtp.client-ip=209.85.167.54 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=daynix.com Authentication-Results: smtp.subspace.kernel.org; spf=none smtp.mailfrom=daynix.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=daynix-com.20230601.gappssmtp.com header.i=@daynix-com.20230601.gappssmtp.com header.b="Yolsy7Ae" Received: by mail-lf1-f54.google.com with SMTP id 2adb3069b0e04-536a2759f0eso1421236e87.3 for ; Tue, 24 Sep 2024 02:01:32 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=daynix-com.20230601.gappssmtp.com; s=20230601; t=1727168491; x=1727773291; darn=vger.kernel.org; h=to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:from:to:cc:subject:date:message-id :reply-to; bh=6RBR4ATFwa2DujiC7hD9cms582pJp14NlPm8BLwampE=; b=Yolsy7Aem6lnBT4qR0LKd96+BKO7CMSscNUUy14Iv9O3X+A0ixs53koF23fur5fAcB Kgmbayy+ishsCI0Qs1sgZAx2990iSRa/mP7gNw/iLGjvJt6YEB45KpleJ781uB9I6ly2 djl9PXxaeZ6ovG7heFIPF6vQzaxEVm0ZZDcSMWdfCUwSgPux1xlZUEqXKMaFShYzj3TV A2YtSSLGm841mCR//7mr74etumoktzr6FjqzoPlxDFZkRVgSyB6TFnRvQpYJDi7V2O6E dxvbYD2dDlm5kbhNbbEnFEPLoXOosn2OMSN5VVo9MRiGHfgcjsaGLcgK0HLfwm5nnzNm f05Q== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1727168491; x=1727773291; h=to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=6RBR4ATFwa2DujiC7hD9cms582pJp14NlPm8BLwampE=; b=s4Wh9chS80OqZCaVYCsUnp3N16XrevLquT+LnD99QwVuzZI9xnUBaWl7HBVc6jHSIS XjmP35ccR3t/TGrbKD77Gs/Ck0LDMP9hP903E+u+x+6JUNne4J5HxOzwavOMk8P8GJNY gnFBVBWkThz4TPX3rAN6KVxTT25XjgEMwiQnmJD+3fyk2ffmi+aZ9DDJNAkK4amx4xkN ZkPWyBnLN4/Kz5C/MjfNbYm3f9qVek5/UipBlH+vQGAsKUZ7YCPouSEw3ilQ8TLHYYJO 3gv6WQ9eFph/ApVv4yCdQz7sDohwq57Za0sfA61N4HJ234AKHw3l9mbogJrlUvGigGk/ NfFA== X-Forwarded-Encrypted: i=1; AJvYcCXu1F5okWqv3qNMsTABCdgdvF+9ofoxlkjFnW2Fe5BnkZ0qEKLxGLfeblLW4ZuwwFBE40jCBxXE8ZqDVZQ=@vger.kernel.org X-Gm-Message-State: AOJu0Yzg7QaAr7pQoFSlHW+LosXNGvhsMCbCWqrLRD+A8dcQckHOuZeA y0zlRDf0UUJgcJkWocZTr2ZWNKMMqwIPG9nFhNL0C7+UN/nr6MNYD3I6nlw4wXI= X-Google-Smtp-Source: AGHT+IGnxbsfjWUZgFFSmmowMsSKYMIW4hkUUB3O/HwRE13GAq+t2XHXYFNBXuQ3/HO9v4TxEfO7kw== X-Received: by 2002:a05:6512:3f15:b0:533:efaf:ab26 with SMTP id 2adb3069b0e04-536ad182603mr7210150e87.36.1727168490499; Tue, 24 Sep 2024 02:01:30 -0700 (PDT) Received: from localhost ([193.32.29.227]) by smtp.gmail.com with UTF8SMTPSA id 4fb4d7f45d1cf-5c5cf4d77d9sm535632a12.94.2024.09.24.02.01.28 (version=TLS1_3 cipher=TLS_AES_128_GCM_SHA256 bits=128/128); Tue, 24 Sep 2024 02:01:29 -0700 (PDT) From: Akihiko Odaki Date: Tue, 24 Sep 2024 11:01:12 +0200 Subject: [PATCH RFC v4 7/9] tun: Introduce virtio-net RSS Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20240924-rss-v4-7-84e932ec0e6c@daynix.com> References: <20240924-rss-v4-0-84e932ec0e6c@daynix.com> In-Reply-To: <20240924-rss-v4-0-84e932ec0e6c@daynix.com> To: Jonathan Corbet , Willem de Bruijn , Jason Wang , "David S. Miller" , Eric Dumazet , Jakub Kicinski , Paolo Abeni , "Michael S. Tsirkin" , Xuan Zhuo , Shuah Khan , linux-doc@vger.kernel.org, linux-kernel@vger.kernel.org, netdev@vger.kernel.org, kvm@vger.kernel.org, virtualization@lists.linux-foundation.org, linux-kselftest@vger.kernel.org, Yuri Benditovich , Andrew Melnychenko , Stephen Hemminger , gur.stavi@huawei.com, Akihiko Odaki X-Mailer: b4 0.14-dev-fd6e3 RSS is a receive steering algorithm that can be negotiated to use with virtio_net. Conventionally the hash calculation was done by the VMM. However, computing the hash after the queue was chosen defeats the purpose of RSS. Another approach is to use eBPF steering program. This approach has another downside: it cannot report the calculated hash due to the restrictive nature of eBPF steering program. Introduce the code to perform RSS to the kernel in order to overcome thse challenges. An alternative solution is to extend the eBPF steering program so that it will be able to report to the userspace, but I didn't opt for it because extending the current mechanism of eBPF steering program as is because it relies on legacy context rewriting, and introducing kfunc-based eBPF will result in non-UAPI dependency while the other relevant virtualization APIs such as KVM and vhost_net are UAPIs. Signed-off-by: Akihiko Odaki --- drivers/net/tun.c | 158 ++++++++++++++++++++++++++++++++++++++--= ---- include/uapi/linux/if_tun.h | 27 ++++++++ 2 files changed, 163 insertions(+), 22 deletions(-) diff --git a/drivers/net/tun.c b/drivers/net/tun.c index 986e4a5bf04d..680eb4561a7f 100644 --- a/drivers/net/tun.c +++ b/drivers/net/tun.c @@ -175,6 +175,9 @@ struct tun_prog { =20 struct tun_vnet_hash_container { struct tun_vnet_hash common; + struct tun_vnet_hash_rss rss; + __be32 rss_key[VIRTIO_NET_RSS_MAX_KEY_SIZE]; + u16 rss_indirection_table[]; }; =20 /* Since the socket were moved to tun_file, to preserve the behavior of pe= rsist @@ -214,7 +217,7 @@ struct tun_struct { struct bpf_prog __rcu *xdp_prog; struct tun_prog __rcu *steering_prog; struct tun_prog __rcu *filter_prog; - struct tun_vnet_hash vnet_hash; + struct tun_vnet_hash_container __rcu *vnet_hash; struct ethtool_link_ksettings link_ksettings; /* init args */ struct file *file; @@ -227,7 +230,7 @@ struct veth { }; =20 static const struct tun_vnet_hash tun_vnet_hash_cap =3D { - .flags =3D TUN_VNET_HASH_REPORT, + .flags =3D TUN_VNET_HASH_REPORT | TUN_VNET_HASH_RSS, .types =3D VIRTIO_NET_SUPPORTED_HASH_TYPES }; =20 @@ -333,8 +336,10 @@ static long tun_set_vnet_be(struct tun_struct *tun, in= t __user *argp) return -EFAULT; =20 if (be) { + struct tun_vnet_hash_container *vnet_hash =3D rtnl_dereference(tun->vnet= _hash); + if (!(tun->flags & TUN_VNET_LE) && - (tun->vnet_hash.flags & TUN_VNET_HASH_REPORT)) + vnet_hash && (vnet_hash->flags & TUN_VNET_HASH_REPORT)) return -EBUSY; =20 tun->flags |=3D TUN_VNET_BE; @@ -537,7 +542,8 @@ static inline void tun_flow_save_rps_rxhash(struct tun_= flow_entry *e, u32 hash) * the userspace application move between processors, we may get a * different rxq no. here. */ -static u16 tun_automq_select_queue(struct tun_struct *tun, struct sk_buff = *skb) +static u16 tun_automq_select_queue(struct tun_struct *tun, struct sk_buff = *skb, + const struct tun_vnet_hash_container *vnet_hash) { struct tun_vnet_hash_ext *ext; struct flow_keys keys; @@ -558,10 +564,10 @@ static u16 tun_automq_select_queue(struct tun_struct = *tun, struct sk_buff *skb) txq =3D reciprocal_scale(txq, numqueues); } =20 - if (tun->vnet_hash.flags & TUN_VNET_HASH_REPORT) { + if (vnet_hash && (vnet_hash->common.flags & TUN_VNET_HASH_REPORT)) { ext =3D skb_ext_add(skb, SKB_EXT_TUN_VNET_HASH); if (ext) { - u32 types =3D tun->vnet_hash.types; + u32 types =3D vnet_hash->common.types; =20 ext->report =3D virtio_net_hash_report(types, keys.basic); ext->value =3D skb->l4_hash ? skb->hash : txq; @@ -588,6 +594,37 @@ static u16 tun_ebpf_select_queue(struct tun_struct *tu= n, struct sk_buff *skb) return ret % numqueues; } =20 +static u16 tun_vnet_rss_select_queue(struct tun_struct *tun, + struct sk_buff *skb, + const struct tun_vnet_hash_container *vnet_hash) +{ + struct tun_vnet_hash_ext *ext; + struct virtio_net_hash hash; + u32 numqueues =3D READ_ONCE(tun->numqueues); + u16 txq, index; + + if (!numqueues) + return 0; + + virtio_net_hash_rss(skb, vnet_hash->common.types, vnet_hash->rss_key, &ha= sh); + + if (!hash.report) + return vnet_hash->rss.unclassified_queue % numqueues; + + if (vnet_hash->common.flags & TUN_VNET_HASH_REPORT) { + ext =3D skb_ext_add(skb, SKB_EXT_TUN_VNET_HASH); + if (ext) { + ext->value =3D hash.value; + ext->report =3D hash.report; + } + } + + index =3D hash.value & vnet_hash->rss.indirection_table_mask; + txq =3D READ_ONCE(vnet_hash->rss_indirection_table[index]); + + return txq % numqueues; +} + static u16 tun_select_queue(struct net_device *dev, struct sk_buff *skb, struct net_device *sb_dev) { @@ -595,10 +632,16 @@ static u16 tun_select_queue(struct net_device *dev, s= truct sk_buff *skb, u16 ret; =20 rcu_read_lock(); - if (rcu_dereference(tun->steering_prog)) + if (rcu_dereference(tun->steering_prog)) { ret =3D tun_ebpf_select_queue(tun, skb); - else - ret =3D tun_automq_select_queue(tun, skb); + } else { + struct tun_vnet_hash_container *vnet_hash =3D rcu_dereference(tun->vnet_= hash); + + if (vnet_hash && (vnet_hash->common.flags & TUN_VNET_HASH_RSS)) + ret =3D tun_vnet_rss_select_queue(tun, skb, vnet_hash); + else + ret =3D tun_automq_select_queue(tun, skb, vnet_hash); + } rcu_read_unlock(); =20 return ret; @@ -2376,6 +2419,9 @@ static void tun_free_netdev(struct net_device *dev) security_tun_dev_free_security(tun->security); __tun_set_ebpf(tun, &tun->steering_prog, NULL); __tun_set_ebpf(tun, &tun->filter_prog, NULL); + rtnl_lock(); + kfree_rcu_mightsleep(rtnl_dereference(tun->vnet_hash)); + rtnl_unlock(); } =20 static void tun_setup(struct net_device *dev) @@ -3074,13 +3120,9 @@ static int tun_set_queue(struct file *file, struct i= freq *ifr) } =20 static int tun_set_ebpf(struct tun_struct *tun, struct tun_prog __rcu **pr= og_p, - void __user *data) + int fd) { struct bpf_prog *prog; - int fd; - - if (copy_from_user(&fd, data, sizeof(fd))) - return -EFAULT; =20 if (fd =3D=3D -1) { prog =3D NULL; @@ -3146,10 +3188,12 @@ static long __tun_chr_ioctl(struct file *file, unsi= gned int cmd, int ifindex; int sndbuf; int vnet_hdr_sz; + int fd; int le; int ret; bool do_notify =3D false; - struct tun_vnet_hash vnet_hash; + struct tun_vnet_hash vnet_hash_common; + struct tun_vnet_hash_container *vnet_hash; =20 if (cmd =3D=3D TUNSETIFF || cmd =3D=3D TUNSETQUEUE || (_IOC_TYPE(cmd) =3D=3D SOCK_IOC_TYPE && cmd !=3D SIOCGSKNS)) { @@ -3373,7 +3417,8 @@ static long __tun_chr_ioctl(struct file *file, unsign= ed int cmd, break; } =20 - if (tun->vnet_hash.flags & TUN_VNET_HASH_REPORT && + vnet_hash =3D rtnl_dereference(tun->vnet_hash); + if (vnet_hash && (vnet_hash->common.flags & TUN_VNET_HASH_REPORT) && vnet_hdr_sz < (int)sizeof(struct virtio_net_hdr_v1_hash)) { ret =3D -EBUSY; break; @@ -3396,7 +3441,8 @@ static long __tun_chr_ioctl(struct file *file, unsign= ed int cmd, if (le) { tun->flags |=3D TUN_VNET_LE; } else { - if (tun->vnet_hash.flags & TUN_VNET_HASH_REPORT && + vnet_hash =3D rtnl_dereference(tun->vnet_hash); + if (vnet_hash && (vnet_hash->common.flags & TUN_VNET_HASH_REPORT) && !tun_legacy_is_little_endian(tun)) { ret =3D -EBUSY; break; @@ -3446,11 +3492,27 @@ static long __tun_chr_ioctl(struct file *file, unsi= gned int cmd, break; =20 case TUNSETSTEERINGEBPF: - ret =3D tun_set_ebpf(tun, &tun->steering_prog, argp); + if (get_user(fd, (int __user *)argp)) { + ret =3D -EFAULT; + break; + } + + vnet_hash =3D rtnl_dereference(tun->vnet_hash); + if (fd !=3D -1 && vnet_hash && (vnet_hash->common.flags & TUN_VNET_HASH_= RSS)) { + ret =3D -EBUSY; + break; + } + + ret =3D tun_set_ebpf(tun, &tun->steering_prog, fd); break; =20 case TUNSETFILTEREBPF: - ret =3D tun_set_ebpf(tun, &tun->filter_prog, argp); + if (get_user(fd, (int __user *)argp)) { + ret =3D -EFAULT; + break; + } + + ret =3D tun_set_ebpf(tun, &tun->filter_prog, fd); break; =20 case TUNSETCARRIER: @@ -3469,20 +3531,72 @@ static long __tun_chr_ioctl(struct file *file, unsi= gned int cmd, break; =20 case TUNSETVNETHASH: - if (copy_from_user(&vnet_hash, argp, sizeof(vnet_hash))) { + if (copy_from_user(&vnet_hash_common, argp, sizeof(vnet_hash_common))) { ret =3D -EFAULT; break; } argp =3D (struct tun_vnet_hash __user *)argp + 1; =20 - if ((vnet_hash.flags & TUN_VNET_HASH_REPORT) && + if ((vnet_hash_common.flags & TUN_VNET_HASH_REPORT) && (tun->vnet_hdr_sz < sizeof(struct virtio_net_hdr_v1_hash) || !tun_is_little_endian(tun))) { ret =3D -EBUSY; break; } =20 - tun->vnet_hash =3D vnet_hash; + if (vnet_hash_common.flags & TUN_VNET_HASH_RSS) { + struct tun_vnet_hash_rss rss; + size_t indirection_table_size; + size_t key_size; + size_t size; + + if (tun->steering_prog) { + ret =3D -EBUSY; + break; + } + + if (copy_from_user(&rss, argp, sizeof(rss))) { + ret =3D -EFAULT; + break; + } + argp =3D (struct tun_vnet_hash_rss __user *)argp + 1; + + indirection_table_size =3D ((size_t)rss.indirection_table_mask + 1) * 2; + key_size =3D virtio_net_hash_key_length(vnet_hash_common.types); + size =3D struct_size(vnet_hash, rss_indirection_table, + (size_t)rss.indirection_table_mask + 1); + + vnet_hash =3D kmalloc(size, GFP_KERNEL); + if (!vnet_hash) { + ret =3D -ENOMEM; + break; + } + + if (copy_from_user(vnet_hash->rss_indirection_table, + argp, indirection_table_size)) { + kfree(vnet_hash); + ret =3D -EFAULT; + break; + } + argp =3D (u16 __user *)argp + rss.indirection_table_mask + 1; + + if (copy_from_user(vnet_hash->rss_key, argp, key_size)) { + kfree(vnet_hash); + ret =3D -EFAULT; + break; + } + + vnet_hash->rss =3D rss; + } else { + vnet_hash =3D kmalloc(sizeof(vnet_hash->common), GFP_KERNEL); + if (!vnet_hash) { + ret =3D -ENOMEM; + break; + } + } + + vnet_hash->common =3D vnet_hash_common; + kfree_rcu_mightsleep(rcu_replace_pointer_rtnl(tun->vnet_hash, vnet_hash)= ); break; =20 default: diff --git a/include/uapi/linux/if_tun.h b/include/uapi/linux/if_tun.h index 1561e8ce0a0a..1c130409db5d 100644 --- a/include/uapi/linux/if_tun.h +++ b/include/uapi/linux/if_tun.h @@ -75,6 +75,14 @@ * * The argument is a pointer to &struct tun_vnet_hash. * + * The argument is a pointer to the compound of the following in order if + * %TUN_VNET_HASH_RSS is set: + * + * 1. &struct tun_vnet_hash + * 2. &struct tun_vnet_hash_rss + * 3. Indirection table + * 4. Key + * * %TUNSETVNETHDRSZ ioctl must be called with a number greater than or equ= al to * the size of &struct virtio_net_hdr_v1_hash before calling this ioctl wi= th * %TUN_VNET_HASH_REPORT. @@ -144,6 +152,13 @@ struct tun_filter { */ #define TUN_VNET_HASH_REPORT 0x0001 =20 +/** + * define TUN_VNET_HASH_RSS - Request virtio_net RSS + * + * This is mutually exclusive with eBPF steering program. + */ +#define TUN_VNET_HASH_RSS 0x0002 + /** * struct tun_vnet_hash - virtio_net hashing configuration * @flags: @@ -159,4 +174,16 @@ struct tun_vnet_hash { __u32 types; }; =20 +/** + * struct tun_vnet_hash_rss - virtio_net RSS configuration + * @indirection_table_mask: + * Bitmask to be applied to the indirection table index + * @unclassified_queue: + * The index of the queue to place unclassified packets in + */ +struct tun_vnet_hash_rss { + __u16 indirection_table_mask; + __u16 unclassified_queue; +}; + #endif /* _UAPI__IF_TUN_H */ --=20 2.46.0 From nobody Fri Nov 29 04:34:27 2024 Received: from mail-ej1-f46.google.com (mail-ej1-f46.google.com [209.85.218.46]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 341EA17F4F5 for ; Tue, 24 Sep 2024 09:01:34 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.218.46 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1727168496; cv=none; b=r/aVXKzJMtxXGzGnIJLlBEkEonNHezMyeN0UbQXXDck8j6ZUpDtUBgPdOLIxhhoxsQhxfkx95BJx+mOrtgWi2ysRRqyCDqVlTgY55jpllCF6NR8u7ul6Yndo6+ASSpeDSE3YRWR+JCSvrKWHzPhuQiwDm8APgblAItNxMKPskQE= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1727168496; c=relaxed/simple; bh=e08ENqTLK5JcmDylEEeTBcLi/nTW9l3fmedd0ouh1RM=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To; b=Nah+c0YvedjzTICk1ijuD4m/3NzsiJb31Pwp9h4h3CKyHa1IElFMOybgEiBBXaFSJoPk6mXlbt32sRSkYILPMrznkc3nIdFMrCbREMiSM3BXDX0iX5ukQXbLZivFJfh4cq2mEXu3r0V4HQALeFOx3FVp94uA2VK2WKpe3YKqx7I= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=daynix.com; spf=none smtp.mailfrom=daynix.com; dkim=pass (2048-bit key) header.d=daynix-com.20230601.gappssmtp.com header.i=@daynix-com.20230601.gappssmtp.com header.b=JGU2H2ta; arc=none smtp.client-ip=209.85.218.46 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=daynix.com Authentication-Results: smtp.subspace.kernel.org; spf=none smtp.mailfrom=daynix.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=daynix-com.20230601.gappssmtp.com header.i=@daynix-com.20230601.gappssmtp.com header.b="JGU2H2ta" Received: by mail-ej1-f46.google.com with SMTP id a640c23a62f3a-a8a789c4fc5so178389066b.0 for ; Tue, 24 Sep 2024 02:01:34 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=daynix-com.20230601.gappssmtp.com; s=20230601; t=1727168492; x=1727773292; darn=vger.kernel.org; h=to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:from:to:cc:subject:date:message-id :reply-to; bh=R8uC1YZ5gvrV1+ajGvrmjOhgo2HYayZdkAvkK7Fa+7w=; b=JGU2H2taFdkUsUQXXcbeL15OlbBoOrbI7og7j182NfrDVeh3Wf7fz63A5VECU4F888 cZKIoq0cfnKk3ULvPK+WHVtauZiiHCw96lKuLtOBhbv5w+yrUAzCxTYksww1aPYf5myA URNWM5M/sJpjfGRsVM3GhnHgMbPgNbkJChFe5BiGb8UJDZzVCBM+e2/phjeALw5S8ns9 lFoN0bYjx8Dbji2EinFVFm6iMlE9gggiXOzqAs26iyTW9NGgkLG8oiSZTi38UdRK4xcV p/CBzYMLGM6RmCO1lSbYunkQrIM/Cu4rfTQcgXQw8ruAJ94GOW7AV0zCc+oVmzuOfEuM e0MQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1727168492; x=1727773292; h=to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=R8uC1YZ5gvrV1+ajGvrmjOhgo2HYayZdkAvkK7Fa+7w=; b=jNSSl4RCf2TJTR99WwdThE9HZjpP86LgpBdened/f0wG78KsZzM6xFPpdk6xCRpgO9 Sb1gi/jnegMNuPKzaaGHIbsmTQLBGlF3L8WEjYQLBGfnWCirU/yHTQJbdKifiDmoebkz U+zI4dyxbXK5ukokbtU5TIp12tFkhvDGd6b5JvTtWCmBUqaAm7X1NIkQPiimjISjJjR7 qjQn0fDS/uiOOSrdU58kWSA+noqpIMQupoGtMyWRtWr8vWsheIX/anZFE6OQyvh9kW0R je6UGG4BwlhBSEYpw0XUHDNx/my81gyFOyYYIAy8lOhpdFxKso2he6bS2M8AXZwpZ2g/ ylgQ== X-Forwarded-Encrypted: i=1; AJvYcCUi+DI/w2sg4iqwrvF96puzp6U0nBWkwYaA+yDL1LjNNw+4b3QeBmnnaYSvSGvBX6xK97Q8tK0PeOfhFKg=@vger.kernel.org X-Gm-Message-State: AOJu0Yxo/YJeoQjLVHSGln0BDX/qlO3pviTUW5vWqkb318wlSaM29ahX olCpzDenspydNH1WmS1pLWJPzv7FaA8OSbJKWj9ql1nhrOyEgkW5nW6AMcUPJ0E= X-Google-Smtp-Source: AGHT+IFq5sBJ06iX9OtdDPFMXWGEosJkbgULc80N/OOenc94AJI6Omnui5rtwKZhueXabsKZj/CY5Q== X-Received: by 2002:a17:907:26c3:b0:a80:c0ed:2145 with SMTP id a640c23a62f3a-a92c47fa679mr259474866b.2.1727168492503; Tue, 24 Sep 2024 02:01:32 -0700 (PDT) Received: from localhost ([193.32.29.227]) by smtp.gmail.com with UTF8SMTPSA id a640c23a62f3a-a9392f33efbsm60865566b.10.2024.09.24.02.01.31 (version=TLS1_3 cipher=TLS_AES_128_GCM_SHA256 bits=128/128); Tue, 24 Sep 2024 02:01:32 -0700 (PDT) From: Akihiko Odaki Date: Tue, 24 Sep 2024 11:01:13 +0200 Subject: [PATCH RFC v4 8/9] selftest: tun: Add tests for virtio-net hashing Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20240924-rss-v4-8-84e932ec0e6c@daynix.com> References: <20240924-rss-v4-0-84e932ec0e6c@daynix.com> In-Reply-To: <20240924-rss-v4-0-84e932ec0e6c@daynix.com> To: Jonathan Corbet , Willem de Bruijn , Jason Wang , "David S. Miller" , Eric Dumazet , Jakub Kicinski , Paolo Abeni , "Michael S. Tsirkin" , Xuan Zhuo , Shuah Khan , linux-doc@vger.kernel.org, linux-kernel@vger.kernel.org, netdev@vger.kernel.org, kvm@vger.kernel.org, virtualization@lists.linux-foundation.org, linux-kselftest@vger.kernel.org, Yuri Benditovich , Andrew Melnychenko , Stephen Hemminger , gur.stavi@huawei.com, Akihiko Odaki X-Mailer: b4 0.14-dev-fd6e3 The added tests confirm tun can perform RSS and hash reporting, and reject invalid configurations for them. Signed-off-by: Akihiko Odaki --- tools/testing/selftests/net/Makefile | 2 +- tools/testing/selftests/net/tun.c | 666 +++++++++++++++++++++++++++++++= +++- 2 files changed, 660 insertions(+), 8 deletions(-) diff --git a/tools/testing/selftests/net/Makefile b/tools/testing/selftests= /net/Makefile index 9d5aa817411b..8e2ab5068171 100644 --- a/tools/testing/selftests/net/Makefile +++ b/tools/testing/selftests/net/Makefile @@ -110,6 +110,6 @@ $(OUTPUT)/reuseport_bpf_numa: LDLIBS +=3D -lnuma $(OUTPUT)/tcp_mmap: LDLIBS +=3D -lpthread -lcrypto $(OUTPUT)/tcp_inq: LDLIBS +=3D -lpthread $(OUTPUT)/bind_bhash: LDLIBS +=3D -lpthread -$(OUTPUT)/io_uring_zerocopy_tx: CFLAGS +=3D -I../../../include/ +$(OUTPUT)/io_uring_zerocopy_tx $(OUTPUT)/tun: CFLAGS +=3D -I../../../inclu= de/ =20 include bpf.mk diff --git a/tools/testing/selftests/net/tun.c b/tools/testing/selftests/ne= t/tun.c index fa83918b62d1..f46affa39d5c 100644 --- a/tools/testing/selftests/net/tun.c +++ b/tools/testing/selftests/net/tun.c @@ -2,21 +2,37 @@ =20 #define _GNU_SOURCE =20 +#include #include #include +#include #include #include #include #include -#include +#include +#include +#include +#include +#include +#include +#include #include +#include #include #include -#include -#include +#include +#include +#include +#include =20 #include "../kselftest_harness.h" =20 +#define TUN_HWADDR_SOURCE { 0x02, 0x00, 0x00, 0x00, 0x00, 0x00 } +#define TUN_HWADDR_DEST { 0x02, 0x00, 0x00, 0x00, 0x00, 0x01 } +#define TUN_IPADDR_SOURCE htonl((172 << 24) | (17 << 16) | 0) +#define TUN_IPADDR_DEST htonl((172 << 24) | (17 << 16) | 1) + static int tun_attach(int fd, char *dev) { struct ifreq ifr; @@ -39,7 +55,7 @@ static int tun_detach(int fd, char *dev) return ioctl(fd, TUNSETQUEUE, (void *) &ifr); } =20 -static int tun_alloc(char *dev) +static int tun_alloc(char *dev, short flags) { struct ifreq ifr; int fd, err; @@ -52,7 +68,8 @@ static int tun_alloc(char *dev) =20 memset(&ifr, 0, sizeof(ifr)); strcpy(ifr.ifr_name, dev); - ifr.ifr_flags =3D IFF_TAP | IFF_NAPI | IFF_MULTI_QUEUE; + ifr.ifr_flags =3D flags | IFF_TAP | IFF_NAPI | IFF_NO_PI | + IFF_MULTI_QUEUE; =20 err =3D ioctl(fd, TUNSETIFF, (void *) &ifr); if (err < 0) { @@ -64,6 +81,40 @@ static int tun_alloc(char *dev) return fd; } =20 +static bool tun_add_to_bridge(int local_fd, const char *name) +{ + struct ifreq ifreq =3D { + .ifr_name =3D "xbridge", + .ifr_ifindex =3D if_nametoindex(name) + }; + + if (!ifreq.ifr_ifindex) { + perror("if_nametoindex"); + return false; + } + + if (ioctl(local_fd, SIOCBRADDIF, &ifreq)) { + perror("SIOCBRADDIF"); + return false; + } + + return true; +} + +static bool tun_set_flags(int local_fd, const char *name, short flags) +{ + struct ifreq ifreq =3D { .ifr_flags =3D flags }; + + strcpy(ifreq.ifr_name, name); + + if (ioctl(local_fd, SIOCSIFFLAGS, &ifreq)) { + perror("SIOCSIFFLAGS"); + return false; + } + + return true; +} + static int tun_delete(char *dev) { struct { @@ -102,6 +153,159 @@ static int tun_delete(char *dev) return ret; } =20 +static uint32_t tun_sum(const void *buf, size_t len) +{ + const uint16_t *sbuf =3D buf; + uint32_t sum =3D 0; + + while (len > 1) { + sum +=3D *sbuf++; + len -=3D 2; + } + + if (len) + sum +=3D *(uint8_t *)sbuf; + + return sum; +} + +static uint16_t tun_build_ip_check(uint32_t sum) +{ + return ~((sum & 0xffff) + (sum >> 16)); +} + +static uint32_t tun_build_ip_pseudo_sum(const void *iphdr) +{ + uint16_t tot_len =3D ntohs(((struct iphdr *)iphdr)->tot_len); + + return tun_sum((char *)iphdr + offsetof(struct iphdr, saddr), 8) + + htons(((struct iphdr *)iphdr)->protocol) + + htons(tot_len - sizeof(struct iphdr)); +} + +static uint32_t tun_build_ipv6_pseudo_sum(const void *ipv6hdr) +{ + return tun_sum((char *)ipv6hdr + offsetof(struct ipv6hdr, saddr), 32) + + ((struct ipv6hdr *)ipv6hdr)->payload_len + + htons(((struct ipv6hdr *)ipv6hdr)->nexthdr); +} + +static void tun_build_ethhdr(struct ethhdr *ethhdr, uint16_t proto) +{ + *ethhdr =3D (struct ethhdr) { + .h_dest =3D TUN_HWADDR_DEST, + .h_source =3D TUN_HWADDR_SOURCE, + .h_proto =3D htons(proto) + }; +} + +static void tun_build_iphdr(void *dest, uint16_t len, uint8_t protocol) +{ + struct iphdr iphdr =3D { + .ihl =3D sizeof(iphdr) / 4, + .version =3D 4, + .tot_len =3D htons(sizeof(iphdr) + len), + .ttl =3D 255, + .protocol =3D protocol, + .saddr =3D TUN_IPADDR_SOURCE, + .daddr =3D TUN_IPADDR_DEST + }; + + iphdr.check =3D tun_build_ip_check(tun_sum(&iphdr, sizeof(iphdr))); + memcpy(dest, &iphdr, sizeof(iphdr)); +} + +static void tun_build_ipv6hdr(void *dest, uint16_t len, uint8_t protocol) +{ + struct ipv6hdr ipv6hdr =3D { + .version =3D 6, + .payload_len =3D htons(len), + .nexthdr =3D protocol, + .saddr =3D { + .s6_addr32 =3D { + htonl(0xffff0000), 0, 0, TUN_IPADDR_SOURCE + } + }, + .daddr =3D { + .s6_addr32 =3D { + htonl(0xffff0000), 0, 0, TUN_IPADDR_DEST + } + }, + }; + + memcpy(dest, &ipv6hdr, sizeof(ipv6hdr)); +} + +static void tun_build_tcphdr(void *dest, uint32_t sum) +{ + struct tcphdr tcphdr =3D { + .source =3D htons(9), + .dest =3D htons(9), + .fin =3D 1, + .doff =3D sizeof(tcphdr) / 4, + }; + uint32_t tcp_sum =3D tun_sum(&tcphdr, sizeof(tcphdr)); + + tcphdr.check =3D tun_build_ip_check(sum + tcp_sum); + memcpy(dest, &tcphdr, sizeof(tcphdr)); +} + +static void tun_build_udphdr(void *dest, uint32_t sum) +{ + struct udphdr udphdr =3D { + .source =3D htons(9), + .dest =3D htons(9), + .len =3D htons(sizeof(udphdr)), + }; + uint32_t udp_sum =3D tun_sum(&udphdr, sizeof(udphdr)); + + udphdr.check =3D tun_build_ip_check(sum + udp_sum); + memcpy(dest, &udphdr, sizeof(udphdr)); +} + +static bool tun_vnet_hash_check(int source_fd, const int *dest_fds, + const void *buffer, size_t len, + uint8_t flags, + uint16_t hash_report, uint32_t hash_value) +{ + size_t read_len =3D sizeof(struct virtio_net_hdr_v1_hash) + len; + struct virtio_net_hdr_v1_hash *read_buffer; + struct virtio_net_hdr_v1_hash hdr =3D { + .hdr =3D { + .flags =3D flags, + .num_buffers =3D hash_report ? htole16(1) : 0 + }, + .hash_value =3D htole32(hash_value), + .hash_report =3D htole16(hash_report) + }; + int ret; + int txq =3D hash_report ? hash_value & 1 : 2; + + if (write(source_fd, buffer, len) !=3D len) { + perror("write"); + return false; + } + + read_buffer =3D malloc(read_len); + if (!read_buffer) { + perror("malloc"); + return false; + } + + ret =3D read(dest_fds[txq], read_buffer, read_len); + if (ret !=3D read_len) { + perror("read"); + free(read_buffer); + return false; + } + + ret =3D !memcmp(read_buffer, &hdr, sizeof(*read_buffer)) && + !memcmp(read_buffer + 1, buffer, len); + + free(read_buffer); + return ret; +} + FIXTURE(tun) { char ifname[IFNAMSIZ]; @@ -112,10 +316,10 @@ FIXTURE_SETUP(tun) { memset(self->ifname, 0, sizeof(self->ifname)); =20 - self->fd =3D tun_alloc(self->ifname); + self->fd =3D tun_alloc(self->ifname, 0); ASSERT_GE(self->fd, 0); =20 - self->fd2 =3D tun_alloc(self->ifname); + self->fd2 =3D tun_alloc(self->ifname, 0); ASSERT_GE(self->fd2, 0); } =20 @@ -159,4 +363,452 @@ TEST_F(tun, reattach_close_delete) { EXPECT_EQ(tun_delete(self->ifname), 0); } =20 +FIXTURE(tun_vnet_hash) +{ + int local_fd; + int source_fd; + int dest_fds[3]; +}; + +FIXTURE_SETUP(tun_vnet_hash) +{ + static const struct { + struct tun_vnet_hash hdr; + struct tun_vnet_hash_rss rss; + uint16_t rss_indirection_table[2]; + uint8_t rss_key[40]; + } vnet_hash =3D { + .hdr =3D { + .flags =3D TUN_VNET_HASH_REPORT | TUN_VNET_HASH_RSS, + .types =3D VIRTIO_NET_RSS_HASH_TYPE_IPv4 | + VIRTIO_NET_RSS_HASH_TYPE_TCPv4 | + VIRTIO_NET_RSS_HASH_TYPE_UDPv4 | + VIRTIO_NET_RSS_HASH_TYPE_IPv6 | + VIRTIO_NET_RSS_HASH_TYPE_TCPv6 | + VIRTIO_NET_RSS_HASH_TYPE_UDPv6 + }, + .rss =3D { .indirection_table_mask =3D 1, .unclassified_queue =3D 5 }, + .rss_indirection_table =3D { 3, 4 }, + .rss_key =3D { + 0x6d, 0x5a, 0x56, 0xda, 0x25, 0x5b, 0x0e, 0xc2, + 0x41, 0x67, 0x25, 0x3d, 0x43, 0xa3, 0x8f, 0xb0, + 0xd0, 0xca, 0x2b, 0xcb, 0xae, 0x7b, 0x30, 0xb4, + 0x77, 0xcb, 0x2d, 0xa3, 0x80, 0x30, 0xf2, 0x0c, + 0x6a, 0x42, 0xb7, 0x3b, 0xbe, 0xac, 0x01, 0xfa + } + }; + + struct { + struct virtio_net_hdr_v1_hash vnet_hdr; + struct ethhdr ethhdr; + struct arphdr arphdr; + unsigned char sender_hwaddr[6]; + uint32_t sender_ipaddr; + unsigned char target_hwaddr[6]; + uint32_t target_ipaddr; + } __packed packet =3D { + .ethhdr =3D { + .h_source =3D TUN_HWADDR_SOURCE, + .h_dest =3D { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }, + .h_proto =3D htons(ETH_P_ARP) + }, + .arphdr =3D { + .ar_hrd =3D htons(ARPHRD_ETHER), + .ar_pro =3D htons(ETH_P_IP), + .ar_hln =3D ETH_ALEN, + .ar_pln =3D 4, + .ar_op =3D htons(ARPOP_REQUEST) + }, + .sender_hwaddr =3D TUN_HWADDR_DEST, + .sender_ipaddr =3D TUN_IPADDR_DEST, + .target_ipaddr =3D TUN_IPADDR_DEST + }; + + char source_ifname[IFNAMSIZ] =3D ""; + char dest_ifname[IFNAMSIZ] =3D ""; + int i; + + self->local_fd =3D socket(AF_LOCAL, SOCK_STREAM, 0); + ASSERT_LE(0, self->local_fd); + + self->source_fd =3D tun_alloc(source_ifname, 0); + ASSERT_LE(0, self->source_fd) { + EXPECT_EQ(0, close(self->local_fd)); + } + + ASSERT_TRUE(tun_set_flags(self->local_fd, source_ifname, IFF_UP)) { + EXPECT_EQ(0, close(self->local_fd)); + } + + self->dest_fds[0] =3D tun_alloc(dest_ifname, IFF_VNET_HDR); + ASSERT_LE(0, self->dest_fds[0]) { + EXPECT_EQ(0, close(self->source_fd)); + EXPECT_EQ(0, close(self->local_fd)); + } + + i =3D sizeof(struct virtio_net_hdr_v1_hash); + ASSERT_EQ(ioctl(self->dest_fds[0], TUNSETVNETHDRSZ, &i), 0) { + EXPECT_EQ(0, close(self->dest_fds[0])); + EXPECT_EQ(0, close(self->source_fd)); + EXPECT_EQ(0, close(self->local_fd)); + } + + i =3D 1; + ASSERT_EQ(ioctl(self->dest_fds[0], TUNSETVNETLE, &i), 0) { + EXPECT_EQ(0, close(self->dest_fds[0])); + EXPECT_EQ(0, close(self->source_fd)); + EXPECT_EQ(0, close(self->local_fd)); + } + + ASSERT_TRUE(tun_set_flags(self->local_fd, dest_ifname, IFF_UP)) { + EXPECT_EQ(0, close(self->dest_fds[0])); + EXPECT_EQ(0, close(self->source_fd)); + EXPECT_EQ(0, close(self->local_fd)); + } + + ASSERT_EQ(write(self->dest_fds[0], &packet, sizeof(packet)), + sizeof(packet)) { + EXPECT_EQ(0, close(self->dest_fds[0])); + EXPECT_EQ(0, close(self->source_fd)); + EXPECT_EQ(0, close(self->local_fd)); + } + + ASSERT_EQ(ioctl(self->dest_fds[0], TUNSETVNETHASH, &vnet_hash), 0) { + EXPECT_EQ(0, close(self->dest_fds[0])); + EXPECT_EQ(0, close(self->source_fd)); + EXPECT_EQ(0, close(self->local_fd)); + } + + for (i =3D 1; i < ARRAY_SIZE(self->dest_fds); i++) { + self->dest_fds[i] =3D tun_alloc(dest_ifname, IFF_VNET_HDR); + ASSERT_LE(0, self->dest_fds[i]) { + while (i) { + i--; + EXPECT_EQ(0, close(self->local_fd)); + } + + EXPECT_EQ(0, close(self->source_fd)); + EXPECT_EQ(0, close(self->local_fd)); + } + } + + ASSERT_EQ(ioctl(self->local_fd, SIOCBRADDBR, "xbridge"), 0) { + EXPECT_EQ(0, ioctl(self->local_fd, SIOCBRDELBR, "xbridge")); + + for (i =3D 0; i < ARRAY_SIZE(self->dest_fds); i++) + EXPECT_EQ(0, close(self->dest_fds[i])); + + EXPECT_EQ(0, close(self->source_fd)); + EXPECT_EQ(0, close(self->local_fd)); + } + + ASSERT_TRUE(tun_add_to_bridge(self->local_fd, source_ifname)) { + EXPECT_EQ(0, ioctl(self->local_fd, SIOCBRDELBR, "xbridge")); + + for (i =3D 0; i < ARRAY_SIZE(self->dest_fds); i++) + EXPECT_EQ(0, close(self->dest_fds[i])); + + EXPECT_EQ(0, close(self->source_fd)); + EXPECT_EQ(0, close(self->local_fd)); + } + + ASSERT_TRUE(tun_add_to_bridge(self->local_fd, dest_ifname)) { + EXPECT_EQ(0, ioctl(self->local_fd, SIOCBRDELBR, "xbridge")); + + for (i =3D 0; i < ARRAY_SIZE(self->dest_fds); i++) + EXPECT_EQ(0, close(self->dest_fds[i])); + + EXPECT_EQ(0, close(self->source_fd)); + EXPECT_EQ(0, close(self->local_fd)); + } + + ASSERT_TRUE(tun_set_flags(self->local_fd, "xbridge", IFF_UP)) { + EXPECT_EQ(0, ioctl(self->local_fd, SIOCBRDELBR, "xbridge")); + + for (i =3D 0; i < ARRAY_SIZE(self->dest_fds); i++) + EXPECT_EQ(0, close(self->dest_fds[i])); + + EXPECT_EQ(0, close(self->source_fd)); + EXPECT_EQ(0, close(self->local_fd)); + } +} + +FIXTURE_TEARDOWN(tun_vnet_hash) +{ + ASSERT_TRUE(tun_set_flags(self->local_fd, "xbridge", 0)) { + for (size_t i =3D 0; i < ARRAY_SIZE(self->dest_fds); i++) + EXPECT_EQ(0, close(self->dest_fds[i])); + + EXPECT_EQ(0, close(self->source_fd)); + EXPECT_EQ(0, close(self->local_fd)); + } + + EXPECT_EQ(0, ioctl(self->local_fd, SIOCBRDELBR, "xbridge")); + + for (size_t i =3D 0; i < ARRAY_SIZE(self->dest_fds); i++) + EXPECT_EQ(0, close(self->dest_fds[i])); + + EXPECT_EQ(0, close(self->source_fd)); + EXPECT_EQ(0, close(self->local_fd)); +} + +TEST_F(tun_vnet_hash, unclassified) +{ + struct { + struct ethhdr ethhdr; + struct iphdr iphdr; + } __packed packet; + + tun_build_ethhdr(&packet.ethhdr, ETH_P_LOOPBACK); + + EXPECT_TRUE(tun_vnet_hash_check(self->source_fd, self->dest_fds, + &packet, sizeof(packet), 0, + VIRTIO_NET_HASH_REPORT_NONE, 0)); +} + +TEST_F(tun_vnet_hash, ipv4) +{ + struct { + struct ethhdr ethhdr; + struct iphdr iphdr; + } __packed packet; + + tun_build_ethhdr(&packet.ethhdr, ETH_P_IP); + tun_build_iphdr(&packet.iphdr, 0, 253); + + EXPECT_TRUE(tun_vnet_hash_check(self->source_fd, self->dest_fds, + &packet, sizeof(packet), 0, + VIRTIO_NET_HASH_REPORT_IPv4, + 0x6e45d952)); +} + +TEST_F(tun_vnet_hash, tcpv4) +{ + struct { + struct ethhdr ethhdr; + struct iphdr iphdr; + struct tcphdr tcphdr; + } __packed packet; + + tun_build_ethhdr(&packet.ethhdr, ETH_P_IP); + tun_build_iphdr(&packet.iphdr, sizeof(struct tcphdr), IPPROTO_TCP); + + tun_build_tcphdr(&packet.tcphdr, + tun_build_ip_pseudo_sum(&packet.iphdr)); + + EXPECT_TRUE(tun_vnet_hash_check(self->source_fd, self->dest_fds, + &packet, sizeof(packet), + VIRTIO_NET_HDR_F_DATA_VALID, + VIRTIO_NET_HASH_REPORT_TCPv4, + 0xfb63539a)); +} + +TEST_F(tun_vnet_hash, udpv4) +{ + struct { + struct ethhdr ethhdr; + struct iphdr iphdr; + struct udphdr udphdr; + } __packed packet; + + tun_build_ethhdr(&packet.ethhdr, ETH_P_IP); + tun_build_iphdr(&packet.iphdr, sizeof(struct udphdr), IPPROTO_UDP); + + tun_build_udphdr(&packet.udphdr, + tun_build_ip_pseudo_sum(&packet.iphdr)); + + EXPECT_TRUE(tun_vnet_hash_check(self->source_fd, self->dest_fds, + &packet, sizeof(packet), + VIRTIO_NET_HDR_F_DATA_VALID, + VIRTIO_NET_HASH_REPORT_UDPv4, + 0xfb63539a)); +} + +TEST_F(tun_vnet_hash, ipv6) +{ + struct { + struct ethhdr ethhdr; + struct ipv6hdr ipv6hdr; + } __packed packet; + + tun_build_ethhdr(&packet.ethhdr, ETH_P_IPV6); + tun_build_ipv6hdr(&packet.ipv6hdr, 0, 253); + + EXPECT_TRUE(tun_vnet_hash_check(self->source_fd, self->dest_fds, + &packet, sizeof(packet), 0, + VIRTIO_NET_HASH_REPORT_IPv6, + 0xd6eb560f)); +} + +TEST_F(tun_vnet_hash, tcpv6) +{ + struct { + struct ethhdr ethhdr; + struct ipv6hdr ipv6hdr; + struct tcphdr tcphdr; + } __packed packet; + + tun_build_ethhdr(&packet.ethhdr, ETH_P_IPV6); + tun_build_ipv6hdr(&packet.ipv6hdr, sizeof(struct tcphdr), IPPROTO_TCP); + + tun_build_tcphdr(&packet.tcphdr, + tun_build_ipv6_pseudo_sum(&packet.ipv6hdr)); + + EXPECT_TRUE(tun_vnet_hash_check(self->source_fd, self->dest_fds, + &packet, sizeof(packet), + VIRTIO_NET_HDR_F_DATA_VALID, + VIRTIO_NET_HASH_REPORT_TCPv6, + 0xc2b9f251)); +} + +TEST_F(tun_vnet_hash, udpv6) +{ + struct { + struct ethhdr ethhdr; + struct ipv6hdr ipv6hdr; + struct udphdr udphdr; + } __packed packet; + + tun_build_ethhdr(&packet.ethhdr, ETH_P_IPV6); + tun_build_ipv6hdr(&packet.ipv6hdr, sizeof(struct udphdr), IPPROTO_UDP); + + tun_build_udphdr(&packet.udphdr, + tun_build_ipv6_pseudo_sum(&packet.ipv6hdr)); + + EXPECT_TRUE(tun_vnet_hash_check(self->source_fd, self->dest_fds, + &packet, sizeof(packet), + VIRTIO_NET_HDR_F_DATA_VALID, + VIRTIO_NET_HASH_REPORT_UDPv6, + 0xc2b9f251)); +} + +FIXTURE(tun_vnet_hash_config) +{ + int fd; +}; + +FIXTURE_SETUP(tun_vnet_hash_config) +{ + char ifname[IFNAMSIZ]; + + ifname[0] =3D 0; + self->fd =3D tun_alloc(ifname, 0); + ASSERT_LE(0, self->fd); +} + +FIXTURE_TEARDOWN(tun_vnet_hash_config) +{ + EXPECT_EQ(close(self->fd), 0); +} + +TEST_F(tun_vnet_hash_config, cap) +{ + struct tun_vnet_hash cap; + + ASSERT_EQ(0, ioctl(self->fd, TUNGETVNETHASHCAP, &cap)); + EXPECT_EQ(cap.types, + VIRTIO_NET_RSS_HASH_TYPE_IPv4 | + VIRTIO_NET_RSS_HASH_TYPE_TCPv4 | + VIRTIO_NET_RSS_HASH_TYPE_UDPv4 | + VIRTIO_NET_RSS_HASH_TYPE_IPv6 | + VIRTIO_NET_RSS_HASH_TYPE_TCPv6 | + VIRTIO_NET_RSS_HASH_TYPE_UDPv6); +} + +TEST_F(tun_vnet_hash_config, insufficient_hdr_sz) +{ + static const struct tun_vnet_hash vnet_hash =3D { + .flags =3D TUN_VNET_HASH_REPORT + }; + int i; + + i =3D 1; + ASSERT_EQ(0, ioctl(self->fd, TUNSETVNETLE, &i)); + + ASSERT_EQ(-1, ioctl(self->fd, TUNSETVNETHASH, &vnet_hash)); + EXPECT_EQ(errno, EBUSY); +} + +TEST_F(tun_vnet_hash_config, shrink_hdr_sz) +{ + static const struct tun_vnet_hash vnet_hash =3D { + .flags =3D TUN_VNET_HASH_REPORT + }; + int i; + + i =3D sizeof(struct virtio_net_hdr_v1_hash); + ASSERT_EQ(0, ioctl(self->fd, TUNSETVNETHDRSZ, &i)); + + i =3D 1; + ASSERT_EQ(0, ioctl(self->fd, TUNSETVNETLE, &i)); + + ASSERT_EQ(0, ioctl(self->fd, TUNSETVNETHASH, &vnet_hash)); + + i =3D sizeof(struct virtio_net_hdr); + ASSERT_EQ(-1, ioctl(self->fd, TUNSETVNETHDRSZ, &i)); + EXPECT_EQ(errno, EBUSY); +} + +TEST_F(tun_vnet_hash_config, set_be_early) +{ + static const struct tun_vnet_hash vnet_hash =3D { + .flags =3D TUN_VNET_HASH_REPORT + }; + int i; + + i =3D 1; + if (ioctl(self->fd, TUNSETVNETBE, &i)) + return; + + i =3D sizeof(struct virtio_net_hdr_v1_hash); + ASSERT_EQ(0, ioctl(self->fd, TUNSETVNETHDRSZ, &i)); + + ASSERT_EQ(-1, ioctl(self->fd, TUNSETVNETHASH, &vnet_hash)); + EXPECT_EQ(errno, EBUSY); +} + +TEST_F(tun_vnet_hash_config, set_be_later) +{ + static const struct tun_vnet_hash vnet_hash =3D { + .flags =3D TUN_VNET_HASH_REPORT + }; + int i; + + i =3D sizeof(struct virtio_net_hdr_v1_hash); + ASSERT_EQ(0, ioctl(self->fd, TUNSETVNETHDRSZ, &i)); + + if (ioctl(self->fd, TUNSETVNETHASH, &vnet_hash)) + return; + + i =3D 1; + ASSERT_EQ(-1, ioctl(self->fd, TUNSETVNETBE, &i)); + EXPECT_TRUE(errno =3D=3D EBUSY || errno =3D=3D EINVAL); +} + +TEST_F(tun_vnet_hash_config, unset_le_later) +{ + static const struct tun_vnet_hash vnet_hash =3D { + .flags =3D TUN_VNET_HASH_REPORT + }; + int i; + + i =3D sizeof(struct virtio_net_hdr_v1_hash); + ASSERT_EQ(0, ioctl(self->fd, TUNSETVNETHDRSZ, &i)); + + i =3D 1; + ioctl(self->fd, TUNSETVNETBE, &i); + + if (!ioctl(self->fd, TUNSETVNETHASH, &vnet_hash)) + return; + + i =3D 1; + ASSERT_EQ(0, ioctl(self->fd, TUNSETVNETLE, &i)); + + ASSERT_EQ(0, ioctl(self->fd, TUNSETVNETHASH, &vnet_hash)); + + i =3D 0; + ASSERT_EQ(-1, ioctl(self->fd, TUNSETVNETLE, &i)); + EXPECT_EQ(errno, EBUSY); +} + TEST_HARNESS_MAIN --=20 2.46.0 From nobody Fri Nov 29 04:34:27 2024 Received: from mail-ed1-f52.google.com (mail-ed1-f52.google.com [209.85.208.52]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id CFC98184521 for ; Tue, 24 Sep 2024 09:01:36 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.208.52 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1727168498; cv=none; b=lwzcmqJFGRu3sAv96jKwagcHAp2d+2yGa/lUterFrDOJiaO2nWcJB0Yq/wggClUg/hSOBce48rRbeZJaWQIYj3LnJTzvDXC+TjBvN9DLpXddpC0O7Xejdc55p0gRZ3q9sijzY7yxyJQ+EzZvd0E0FY5XzliTmhcRe/9zRGS8zlE= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1727168498; c=relaxed/simple; bh=2fqPz17MRcLXtYYBT9jcWjUzidfYf/z7eYbmCSZjWTI=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To; b=P55fPX028cU+La8tRA5KSqa5tVCcBe8K4eVsphAXxDdBoV6Itw/883YOv+tQnI6YHvjo/tQHD1yKVXIGJkvVOEqpgZBvO7GFVTst2HlNN11sr0pa1dJKK2v6SgTkPo6t0p9O3iqKO70ApRh39hkf3DxtijGOQ/cKoEotfE1jCwo= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=daynix.com; spf=none smtp.mailfrom=daynix.com; dkim=pass (2048-bit key) header.d=daynix-com.20230601.gappssmtp.com header.i=@daynix-com.20230601.gappssmtp.com header.b=16/egj4t; arc=none smtp.client-ip=209.85.208.52 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=daynix.com Authentication-Results: smtp.subspace.kernel.org; spf=none smtp.mailfrom=daynix.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=daynix-com.20230601.gappssmtp.com header.i=@daynix-com.20230601.gappssmtp.com header.b="16/egj4t" Received: by mail-ed1-f52.google.com with SMTP id 4fb4d7f45d1cf-5c43003a667so7387198a12.3 for ; Tue, 24 Sep 2024 02:01:36 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=daynix-com.20230601.gappssmtp.com; s=20230601; t=1727168495; x=1727773295; darn=vger.kernel.org; h=to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:from:to:cc:subject:date:message-id :reply-to; bh=ldxygdAUBk4mdAzGg1OPlp5HlR7yVW+p2ali8303Ccc=; b=16/egj4tbMuwzY5iQ1q8y5LydOMDyUtDR1qtTkcOMcOvhFkUK4c7Wfye91lOkRhLeK 6rgTh66Kjbpo98e7EO/xZPAzIxatcSzw+Ig2mVim56GgKpqIlE2X+r0TR1GyRFuJQ2WJ ygUwuZrFWC+YgY6Ys7levb7vLVekDj/YOlqZeIkdKN0nY6HqyQxXcMFGiKkrmwvz6be8 ELipaU6ZnRQuT2njyVKvmpBgdCesU6UkYtqTrj3JsKgSBvhTVQ6xqDtH/MVjQPWfzTje Ur81jUfYo1qVWf6sepOgHAaP1wiCTyafq9nviCBiXiKUxINyxIyhAcdSo7Aksnn36DfH HsWg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1727168495; x=1727773295; h=to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=ldxygdAUBk4mdAzGg1OPlp5HlR7yVW+p2ali8303Ccc=; b=FRDmrRUQ5rlJoTk17FpsgS3YZN/YXz9ea3RbkTQYtbZl5yFBuVC54N8qiqJTU+N/Te iQzcbJg/0+f+HbXpTvk/YSV9rVJQByzE4rmBVsbSHqPIzwZYjv2bIQiWzgkCjEL/RBnB Ewh5Z/DybeXen7Mj/bosaWQDCeELl8a0EJ1IgmdJ7YSBqKcwWW/FSjcHPkdpILf8N3EG lMjhxCWGkTyMk2zA+MNVT+kNa6cgTtLgminaz6lKFiYnAbRWgKOgJTyYg6Dti9uiV75j A2f7yEzqWQd5EeA7KZUh4juKroYdZtMyri6zzObg9S/7BclHRhf0rNOJ3BGRSnX40qY7 WGzA== X-Forwarded-Encrypted: i=1; AJvYcCW71sbaYlC5nDbpxC5vXWTrUjY5O1b4n4OwS+Y0jo69PpzYkTCsEodWhA4gzCFXMz6UOD3bsf5F4lTN+Ag=@vger.kernel.org X-Gm-Message-State: AOJu0YwMf9W797WorlAV1JjvUwc42uFpGHnSAydaiBkm3PkYvZAys4tV 2r1UtgVU1UKV5SwWr52Qkvw90T0kWpFjGmWblMAc2LixqA6kull4dl8e/Vd6U3U= X-Google-Smtp-Source: AGHT+IFFGNZvMoEmnxV4kikQ2H333bCCtXL26WeV3JaDRS2Q6nCPUSS8kmDRZE0LD3ZUPP5h6fZgnQ== X-Received: by 2002:a05:6402:354a:b0:5c6:34c5:e5d7 with SMTP id 4fb4d7f45d1cf-5c634c5e97fmr874444a12.7.1727168495205; Tue, 24 Sep 2024 02:01:35 -0700 (PDT) Received: from localhost ([193.32.29.227]) by smtp.gmail.com with UTF8SMTPSA id 4fb4d7f45d1cf-5c5cf48c04esm527645a12.14.2024.09.24.02.01.33 (version=TLS1_3 cipher=TLS_AES_128_GCM_SHA256 bits=128/128); Tue, 24 Sep 2024 02:01:34 -0700 (PDT) From: Akihiko Odaki Date: Tue, 24 Sep 2024 11:01:14 +0200 Subject: [PATCH RFC v4 9/9] vhost/net: Support VIRTIO_NET_F_HASH_REPORT Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20240924-rss-v4-9-84e932ec0e6c@daynix.com> References: <20240924-rss-v4-0-84e932ec0e6c@daynix.com> In-Reply-To: <20240924-rss-v4-0-84e932ec0e6c@daynix.com> To: Jonathan Corbet , Willem de Bruijn , Jason Wang , "David S. Miller" , Eric Dumazet , Jakub Kicinski , Paolo Abeni , "Michael S. Tsirkin" , Xuan Zhuo , Shuah Khan , linux-doc@vger.kernel.org, linux-kernel@vger.kernel.org, netdev@vger.kernel.org, kvm@vger.kernel.org, virtualization@lists.linux-foundation.org, linux-kselftest@vger.kernel.org, Yuri Benditovich , Andrew Melnychenko , Stephen Hemminger , gur.stavi@huawei.com, Akihiko Odaki X-Mailer: b4 0.14-dev-fd6e3 VIRTIO_NET_F_HASH_REPORT allows to report hash values calculated on the host. When VHOST_NET_F_VIRTIO_NET_HDR is employed, it will report no hash values (i.e., the hash_report member is always set to VIRTIO_NET_HASH_REPORT_NONE). Otherwise, the values reported by the underlying socket will be reported. VIRTIO_NET_F_HASH_REPORT requires VIRTIO_F_VERSION_1. Signed-off-by: Akihiko Odaki --- drivers/vhost/net.c | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/drivers/vhost/net.c b/drivers/vhost/net.c index f16279351db5..ec1167a782ec 100644 --- a/drivers/vhost/net.c +++ b/drivers/vhost/net.c @@ -73,6 +73,7 @@ enum { VHOST_NET_FEATURES =3D VHOST_FEATURES | (1ULL << VHOST_NET_F_VIRTIO_NET_HDR) | (1ULL << VIRTIO_NET_F_MRG_RXBUF) | + (1ULL << VIRTIO_NET_F_HASH_REPORT) | (1ULL << VIRTIO_F_ACCESS_PLATFORM) | (1ULL << VIRTIO_F_RING_RESET) }; @@ -1604,10 +1605,13 @@ static int vhost_net_set_features(struct vhost_net = *n, u64 features) size_t vhost_hlen, sock_hlen, hdr_len; int i; =20 - hdr_len =3D (features & ((1ULL << VIRTIO_NET_F_MRG_RXBUF) | - (1ULL << VIRTIO_F_VERSION_1))) ? - sizeof(struct virtio_net_hdr_mrg_rxbuf) : - sizeof(struct virtio_net_hdr); + if (features & (1ULL << VIRTIO_NET_F_HASH_REPORT)) + hdr_len =3D sizeof(struct virtio_net_hdr_v1_hash); + else if (features & ((1ULL << VIRTIO_NET_F_MRG_RXBUF) | + (1ULL << VIRTIO_F_VERSION_1))) + hdr_len =3D sizeof(struct virtio_net_hdr_mrg_rxbuf); + else + hdr_len =3D sizeof(struct virtio_net_hdr); if (features & (1 << VHOST_NET_F_VIRTIO_NET_HDR)) { /* vhost provides vnet_hdr */ vhost_hlen =3D hdr_len; @@ -1688,6 +1692,10 @@ static long vhost_net_ioctl(struct file *f, unsigned= int ioctl, return -EFAULT; if (features & ~VHOST_NET_FEATURES) return -EOPNOTSUPP; + if ((features & ((1ULL << VIRTIO_F_VERSION_1) | + (1ULL << VIRTIO_NET_F_HASH_REPORT))) =3D=3D + (1ULL << VIRTIO_NET_F_HASH_REPORT)) + return -EINVAL; return vhost_net_set_features(n, features); case VHOST_GET_BACKEND_FEATURES: features =3D VHOST_NET_BACKEND_FEATURES; --=20 2.46.0