From nobody Wed Dec 17 13:46:03 2025 Received: from mail-pl1-f181.google.com (mail-pl1-f181.google.com [209.85.214.181]) (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 2E42E2376EC for ; Mon, 17 Mar 2025 10:58:15 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.214.181 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1742209098; cv=none; b=iVhtQ11nADanmOTmrIxLZqxzZgqlBopnVU/vjQ6rl1jGYAWnVlG0pGUVfhlGzxGQPS9eEvkI6CwT0rQfNT3VRtVdGczkvowf9CM47NmcZUXnlwmHte5VIZw4xRiowEMl2YUkznKdvF/DS6b1baSlDL+4xZ/8XCeilKHIfT+3iwk= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1742209098; c=relaxed/simple; bh=A53HI8g8TXDmrSrb60YtMTi8R2diB0tM4HU4FoVrwbo=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To; b=GM/birmyt22t4NdI2GdGP4hHZC03fuFfQ0TesHpeuVaSn9fUBIZnMVkv1VKXQcL5g3oyGheVRG8aa1uhLx0/AloHdukDjyZRZftF5wROfD9TE487GHpSkXAf+PXzu5xAgmVYBU8tBvyH0ajgAx9yyKQpYEUqLkBPk3bnZvJkUfw= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=daynix.com; spf=pass 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=BcIsiHyO; arc=none smtp.client-ip=209.85.214.181 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=daynix.com Authentication-Results: smtp.subspace.kernel.org; spf=pass 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="BcIsiHyO" Received: by mail-pl1-f181.google.com with SMTP id d9443c01a7336-22622ddcc35so4249045ad.2 for ; Mon, 17 Mar 2025 03:58:15 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=daynix-com.20230601.gappssmtp.com; s=20230601; t=1742209095; x=1742813895; 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=fDwrrcdF9GBvmBADJUBP7MW6rPk3woZkA2TcvHwrsYM=; b=BcIsiHyO3kxJ+dOI4pP+XCJ+gLU7zkPLP4p7OyaFob77Uo9F/cV0wF4V2wcRco4jcW a7YA4cV+sjovS4QKCVP5AchgZ3ywA0qFQn4kUNsNhBY9ZMxezKwD0GRY8MAKviYQO/rt /fWRe351NQHDV3THx6pltiQ07hhgoQgqoHdi4HYEEeuiZRJ55Qz9STEMlYLGam0uQ50G iDNOM7N442LSYMlturt3wUdX2QPNDUwwOC5fw52zSCHYKzVJDSvbQR8ALilWvlsCSHnD HA1hOEsgSFNeVMb+/CJS7MikmWnIB3pCfIViL9pgbRds1L8o0rVyQEgPd1m5zGsb1+9M Yz+g== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1742209095; x=1742813895; 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=fDwrrcdF9GBvmBADJUBP7MW6rPk3woZkA2TcvHwrsYM=; b=do3Mo7BBN4SaGHWTpoe3MsnJieo5+x1lCpNNaTvBvvXIgAoRuruGjx9BcobNGXNM6p 03Phsh1VzmcHdIks+fDjOzPJgMUZpGXqpMcaenQagnJLm0m1YXX0d3Y5xYMr8Hb3KQ/G H5bNw1HwrJWXAtTTvrur+Nl4Iw7WixqNFYS/qqzx0iZJrNsbOl9yQcTAl/DL5hZ5Rc/P Sb42EJGdnxwq/tNZlIHOvDcz38HCONwLhRTkq8zxjIrhpadnh1Cs5Pcf2aCBs8QV8OMq mcFl0pM2Ucq6d2POEBONxE4OWQ7suNsMI8+XxguGQCt2/86Bnf4b3XYRUMqVdYzBe6Jc zbKg== X-Forwarded-Encrypted: i=1; AJvYcCUeBeDbn99DhLBgD5/q/vU1GQg4o2q/v/qSI9YZ6CL362LBIIaues8FoCWJHNLdyCgZhedZaCdVLvxpWpc=@vger.kernel.org X-Gm-Message-State: AOJu0YwpYOOYRx4PYAGXehQMW1sPds/gCT5QjIh/ceT/W8ekkz0smp1a kIOxYG31EDcW9FsRdGtRoxhjBu0iTfRvMapX37HTyS7vmnlDLjnXgFu+4C3k5Jc= X-Gm-Gg: ASbGncsPQkFy5jHZhXu65xVdAxU/WQ9XDkVQ+ZVZnHoVg10kfbxyOyPsJkPVVkzVAzZ 13e87YY/QJ7uAdvBCsHPGQktlwxDlbVA11B0l6gJuvDNOL0iKY1/G6WszG+svxx+BE5pheNIyCn 5nS+S4tP+Pyo3nsD7l4lTVsCmKFcxUkkgcBrOSgj941syh2K5faH2MqcA3F4/SNKHdlv2Gplkh4 ipC8Z1BR++FjF15EweQSvXd1naRHCKQ0UXHrtG32KZEInoeDm7mfDbcUrPWB8HVbNTXiJWEyTQ2 2SmFAp8z0UE53OsjmuitxJuUJalSkt0OF9XHca9I0+wXakn2 X-Google-Smtp-Source: AGHT+IGKAamQW1VJHhOiPWsXr0LWlMC6SyVWcWtUe1c/o3wn5KN+tr3yiUg/2SmrfP+56yqz+GYVjA== X-Received: by 2002:a05:6a00:13a8:b0:730:97a6:f04 with SMTP id d2e1a72fcca58-7372233aef3mr13784392b3a.7.1742209095418; Mon, 17 Mar 2025 03:58:15 -0700 (PDT) Received: from localhost ([157.82.207.107]) by smtp.gmail.com with UTF8SMTPSA id d2e1a72fcca58-737115293a8sm7455308b3a.10.2025.03.17.03.58.11 (version=TLS1_3 cipher=TLS_AES_128_GCM_SHA256 bits=128/128); Mon, 17 Mar 2025 03:58:15 -0700 (PDT) From: Akihiko Odaki Date: Mon, 17 Mar 2025 19:57:51 +0900 Subject: [PATCH net-next v11 01/10] 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: <20250317-rss-v11-1-4cacca92f31f@daynix.com> References: <20250317-rss-v11-0-4cacca92f31f@daynix.com> In-Reply-To: <20250317-rss-v11-0-4cacca92f31f@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, Lei Yang , Simon Horman , Akihiko Odaki X-Mailer: b4 0.15-dev-edae6 They are useful to implement VIRTIO_NET_F_RSS and VIRTIO_NET_F_HASH_REPORT. Signed-off-by: Akihiko Odaki Tested-by: Lei Yang --- include/linux/virtio_net.h | 188 +++++++++++++++++++++++++++++++++++++++++= ++++ 1 file changed, 188 insertions(+) diff --git a/include/linux/virtio_net.h b/include/linux/virtio_net.h index 02a9f4dc594d..426f33b4b824 100644 --- a/include/linux/virtio_net.h +++ b/include/linux/virtio_net.h @@ -9,6 +9,194 @@ #include #include =20 +struct virtio_net_hash { + u32 value; + u16 report; +}; + +struct virtio_net_toeplitz_state { + u32 hash; + const u32 *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_convert_key(u32 *input, size_t len) +{ + while (len >=3D sizeof(*input)) { + *input =3D be32_to_cpu((__force __be32)*input); + input++; + len -=3D sizeof(*input); + } +} + +static inline void virtio_net_toeplitz_calc(struct virtio_net_toeplitz_sta= te *state, + const __be32 *input, size_t len) +{ + while (len >=3D sizeof(*input)) { + for (u32 map =3D be32_to_cpu(*input); map; map &=3D (map - 1)) { + u32 i =3D ffs(map); + + state->hash ^=3D state->key[0] << (32 - i) | + (u32)((u64)state->key[1] >> i); + } + + state->key++; + input++; + len -=3D sizeof(*input); + } +} + +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 len + sizeof(u32); +} + +static inline u32 virtio_net_hash_report(u32 types, + const struct flow_keys_basic *keys) +{ + switch (keys->basic.n_proto) { + case cpu_to_be16(ETH_P_IP): + if (!(keys->control.flags & FLOW_DIS_IS_FRAGMENT)) { + if (keys->basic.ip_proto =3D=3D IPPROTO_TCP && + (types & VIRTIO_NET_RSS_HASH_TYPE_TCPv4)) + return VIRTIO_NET_HASH_REPORT_TCPv4; + + if (keys->basic.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 (!(keys->control.flags & FLOW_DIS_IS_FRAGMENT)) { + if (keys->basic.ip_proto =3D=3D IPPROTO_TCP && + (types & VIRTIO_NET_RSS_HASH_TYPE_TCPv6)) + return VIRTIO_NET_HASH_REPORT_TCPv6; + + if (keys->basic.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 u32 *key, + struct virtio_net_hash *hash) +{ + struct virtio_net_toeplitz_state toeplitz_state =3D { .key =3D key }; + struct flow_keys flow; + struct flow_keys_basic flow_basic; + u16 report; + + if (!skb_flow_dissect_flow_keys(skb, &flow, 0)) { + hash->report =3D VIRTIO_NET_HASH_REPORT_NONE; + return; + } + + flow_basic =3D (struct flow_keys_basic) { + .control =3D flow.control, + .basic =3D flow.basic + }; + + 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)); + break; + + case VIRTIO_NET_HASH_REPORT_TCPv4: + virtio_net_toeplitz_calc(&toeplitz_state, + (__be32 *)&flow.addrs.v4addrs, + sizeof(flow.addrs.v4addrs)); + virtio_net_toeplitz_calc(&toeplitz_state, &flow.ports.ports, + sizeof(flow.ports.ports)); + break; + + case VIRTIO_NET_HASH_REPORT_UDPv4: + virtio_net_toeplitz_calc(&toeplitz_state, + (__be32 *)&flow.addrs.v4addrs, + sizeof(flow.addrs.v4addrs)); + virtio_net_toeplitz_calc(&toeplitz_state, &flow.ports.ports, + sizeof(flow.ports.ports)); + break; + + case VIRTIO_NET_HASH_REPORT_IPv6: + virtio_net_toeplitz_calc(&toeplitz_state, + (__be32 *)&flow.addrs.v6addrs, + sizeof(flow.addrs.v6addrs)); + break; + + case VIRTIO_NET_HASH_REPORT_TCPv6: + virtio_net_toeplitz_calc(&toeplitz_state, + (__be32 *)&flow.addrs.v6addrs, + sizeof(flow.addrs.v6addrs)); + virtio_net_toeplitz_calc(&toeplitz_state, &flow.ports.ports, + sizeof(flow.ports.ports)); + break; + + case VIRTIO_NET_HASH_REPORT_UDPv6: + virtio_net_toeplitz_calc(&toeplitz_state, + (__be32 *)&flow.addrs.v6addrs, + sizeof(flow.addrs.v6addrs)); + virtio_net_toeplitz_calc(&toeplitz_state, &flow.ports.ports, + sizeof(flow.ports.ports)); + 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.48.1 From nobody Wed Dec 17 13:46:03 2025 Received: from mail-pl1-f173.google.com (mail-pl1-f173.google.com [209.85.214.173]) (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 E2B8E2356AA for ; Mon, 17 Mar 2025 10:58:21 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.214.173 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1742209103; cv=none; b=DAj8aHsDyhMghQ3yqy+Dl3JTR7CB+YtWoPTHEs3JYZF3p+xXMjH1SFNqS6bT4tSZQ7qvvxYA6M7NtFrr3gaOmq+BmBjU0EH0fEsGwutWEbyc8QhUqluXrjrp3AI7MSN+WV5h82wzVuPEfcqw5GHYKgH9EveLNmeDyDeCk0JqZwM= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1742209103; c=relaxed/simple; bh=tjt6UJr/WhYJJgKlXXv2tzURIehZ2/2wH4imLUM3bx4=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To; b=p4c6Ly4wmZ5ZqPWb9TTAehFUFHMd3C1NXMObAHDHY56IxDLkgAh95mRDUij486IzS4DQR8I8ViSVcDogVyWoUDY/KECv3b//RGm3Jic2JByhx/qphIZ1M2I31z6NCqUD/8Gwl4axWZNo3zbUtMRJL+ny7wQNsWxqHHS52f/M4ao= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=daynix.com; spf=pass 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=j+lLz8eL; arc=none smtp.client-ip=209.85.214.173 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=daynix.com Authentication-Results: smtp.subspace.kernel.org; spf=pass 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="j+lLz8eL" Received: by mail-pl1-f173.google.com with SMTP id d9443c01a7336-2240b4de12bso29524195ad.2 for ; Mon, 17 Mar 2025 03:58:21 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=daynix-com.20230601.gappssmtp.com; s=20230601; t=1742209101; x=1742813901; 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=DgNJjOB2VNdnBavlgHvSgZbzYgc2stuH8jHGRqRaRcM=; b=j+lLz8eLakE81+m0yuyOwLTi6gTHraSkvo0Bi4u+gW2U2Sl6vi0Aw8laftxhDCcw5v JGKhFhWq07jScGJH8mIIgEIZ6MIor4gD/Euj8PmubgbLmqqdWPkHHq5EWA8zEzNttsCa uEy9bxX07xU9LUtF5EJqBmBFrMylPUqTZGsBq6Hx/rgdu9MwdXwqVVvm0YPhJ84i4MyJ Q2/l36HDxR3ugO4kS8QTXuQtpme3NWj2u8eShO+TKyr2mgwC1loyGGZAInZMG//1oYWG orUfUxb1Y9Hi1awZR1Y/UvzN7ACW+lq3JakHZYAeD6XQd/HIl1JFjQ7OkyEWGM4RKfRt uxJQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1742209101; x=1742813901; 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=DgNJjOB2VNdnBavlgHvSgZbzYgc2stuH8jHGRqRaRcM=; b=NSRnBW1CKw+iQY2X5B6tAZHooOiWtRX9fCN1Y1iPy8xKdxpLHkPFIuhP0QGR/p8kHb vYswmCOwtxwe4QQnCNYmavJdIB9kLKA2XZHrMDy4nQgV09ksI2++55s8QE0pT+ukmIqn p/W/fbgAPLYsF4X5ylUCTeSZVARXHUnr470lnZUSDHFraCUKQJM6Er9vq4rHCyvPzoFh dCItvqsRukqOPBMS0NSxBKw1ZI9U/RVwWwBewsin43cO86j6mMn3QXMi9bHCUN6VQJXX VWUMJ52ST02Zyk6lFBzd99LBNerXrdSpOnpaUqJDJOckBQ8VbQoODPDvYAdCTrin9Ney +yYw== X-Forwarded-Encrypted: i=1; AJvYcCVKaoE8XpvOCaWa9TaOKeGQSYvoqLnMcs6qlbFU5KGNajYmQMc8oPO+h9TZNAMOH3oVMY5X8P+cpfryCYI=@vger.kernel.org X-Gm-Message-State: AOJu0Yx8VU+G42uvPhbH7v07rsJchnkxmSkGFLQV/8Tlw4vmheYYTfKY Z6avO67Re8zCUPZ7d/eLX/XS26Xrx9EV+nyK0NLFsGivRb+LTzgVePrpGBUjNkv2rvPzZL6gIN1 qTVI= X-Gm-Gg: ASbGncuVFse2Cq7QfSEmujMINj32SOvRdGqVKhqlOycAJjz+wFY+Ut1jwy+uRbkBzmh D0dmX/3AyRZI6vCvl9lhOVsDt2TBBjY1NPsRGukg3mHjghsYs0gyYu07rjAPeG2JHK9vRJs+0TT cX8jZPBZ4zy0WYbsVw3UVa2f5sn+06VvHl/XCA0HwM2R27n0HnNuLlGh+Jz9zwsnhgvUoKvBXvS vQ5u4PnsnUF/p49ERZ5tztus7NI+rnNwpJS+Wm/1UliH1pJH313A9CTWTOdIMFazMPHZvnXeOID 9wm4snbAgtjfgBENK2OKWY+kNDxdhafROVcu/WXOUIfNoQOoUBnMkoi2o2A= X-Google-Smtp-Source: AGHT+IGYq7HCRRL8m4VKOQxjMlmqfYplWsVLO77u9xzWoCNDu3x4nlybmlZH5cMRcZ12ODXkwSAaKg== X-Received: by 2002:a17:903:11c4:b0:21f:85ee:f2df with SMTP id d9443c01a7336-225e0a896a9mr153965305ad.15.1742209101298; Mon, 17 Mar 2025 03:58:21 -0700 (PDT) Received: from localhost ([157.82.207.107]) by smtp.gmail.com with UTF8SMTPSA id d9443c01a7336-225c688856fsm72665785ad.14.2025.03.17.03.58.16 (version=TLS1_3 cipher=TLS_AES_128_GCM_SHA256 bits=128/128); Mon, 17 Mar 2025 03:58:21 -0700 (PDT) From: Akihiko Odaki Date: Mon, 17 Mar 2025 19:57:52 +0900 Subject: [PATCH net-next v11 02/10] 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: <20250317-rss-v11-2-4cacca92f31f@daynix.com> References: <20250317-rss-v11-0-4cacca92f31f@daynix.com> In-Reply-To: <20250317-rss-v11-0-4cacca92f31f@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, Lei Yang , Simon Horman , Akihiko Odaki X-Mailer: b4 0.15-dev-edae6 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 Tested-by: Lei Yang --- 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 9cd8de6bebb5..32c7ee31330c 100644 --- a/net/core/flow_dissector.c +++ b/net/core/flow_dissector.c @@ -1862,7 +1862,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.48.1 From nobody Wed Dec 17 13:46:03 2025 Received: from mail-pl1-f179.google.com (mail-pl1-f179.google.com [209.85.214.179]) (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 DAD7C2356C9 for ; Mon, 17 Mar 2025 10:58:27 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.214.179 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1742209109; cv=none; b=EYYOshwSlHVeiXMQCpOWTX4dNlhQs5XYCnMsQ24ASyJwIzawuIeq0GF+2GDyRQ4PJxRcUwHjsEmuFtl6xdYmDsf/vndka2EWHziqpyiukgnxRL5BrqdBFZp4T8lEvjZQpkF8ssaZBQIgebpVGwgKf0zxry5ZThjiSqayNh/77JE= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1742209109; c=relaxed/simple; bh=uj6BiB0IqVm8+xs3f9Zn6aCjK6f7zlPp0hv2djTMvTQ=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To; b=YDvdrcApE6xgw9atv9SFXr9HaNdv4rnx8h/G9L2YfeBZhskVqzVt+Uzwtwl4B2yYkSAPxZsRNblHmoXSHBPfIrJsRmy2Gg+91u8MyIjyJkezRRU/UA9FokGBK/5WNgVItM6ZkGYCNuWv1NsGQx0NlWVU/bFUA3YsZIHTxGvb4Pc= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=daynix.com; spf=pass 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=JhDTdWnk; arc=none smtp.client-ip=209.85.214.179 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=daynix.com Authentication-Results: smtp.subspace.kernel.org; spf=pass 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="JhDTdWnk" Received: by mail-pl1-f179.google.com with SMTP id d9443c01a7336-225e3002dffso36554395ad.1 for ; Mon, 17 Mar 2025 03:58:27 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=daynix-com.20230601.gappssmtp.com; s=20230601; t=1742209107; x=1742813907; 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=CFouu/EN4lEKQm+2Nyv7q163Sd7hDT7Qc+wcMAoVrxU=; b=JhDTdWnkWTengsPMPkeyo1QZCS6FfZIqiLpH6pIyZPbEP94MvsL4E8m7EPQp7W3sB/ l0rB2Z0KtyhrUIkHAql6I24dqGU6BIo5lz4bBFKbV/S/ITj3fWlRSb5KuTjbMdCj6Yk1 J98azBh0ZwLCy9hYuStfeVXLWAyAl6ankKLy3PlwmZv+tf64MZ2a+NBBAJZtZ7xrnmyY uFuwOe2CKnZ3aUiAGEnE4rmN1sV8iMrZmpYlP60F/KjumYzWFF3Or2tcO81+Cn94ueVU xeTiP2nYrx3B+Z8BNWPCyI5G9t9YdLbrc9sqnPFD5Ej/+jzoqRwdWm7itDmZ6ST3Rlfw exiw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1742209107; x=1742813907; 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=CFouu/EN4lEKQm+2Nyv7q163Sd7hDT7Qc+wcMAoVrxU=; b=fCSw6luxIoaDuHQWaFRgDGYxPhFVJsImrNrL/Z946aYPuavvewpKEbx+L3TbfoNjKK wWEDLl3oRVTOWRt6DBUNrHssl+LLLOdZVttD883+rl4Df1PiJkFyuIpnQ1HapzVbSfxa DmfrZB18ZyX7uH+lxsSFJmDRdvUoi5FlelCXSc0vKzm7SnaIj5UxWtw/5BEjNWY2m/HM MnSnj92YSWADg/4QqtUFnku6/IMS6JMvEnMA7vzOhdqZyES+Du5AN2+InFzCzpSdczsR CRkM6+ayGgMe8Hr770H3Re51HZb+SA4t4S6Tm35z8WZJ4emECdjbN25jHNoMcFXhB75f zyNg== X-Forwarded-Encrypted: i=1; AJvYcCVrnXZrLTHUNBs3uhAOBMHZ+3A9CrsiS2wiuwHPXfVrZNAnmeGC4kVPFpd2RxZ7/N3G0ECXfnbgIBUWXQI=@vger.kernel.org X-Gm-Message-State: AOJu0YxaSWwTsN6Y4dU2qz3QukJV3FH+lkTijm8NJDpIglUycgZCDdlA 8WkNt8eNj8w25pje967ShI/QCNGrKwSBpU8uwDfvPWHLIJpe9cGUzW/tUrh0O3s= X-Gm-Gg: ASbGncuztUyITxOYW8k8ww6DBIhrbpRHdronIEhx/mubI0y8lq78dsFWAMUwLAPBZ/p fvyUtKqoTtfPPBUScGNlf02Hnxw/FEqnZwzJgBpQccZLhf42YbHlxewEvQhP4xzfz2ACC7O//j6 /8qij8ADN0vYxfYNXuvYK5/glQz0q6PkJFqcDGVCDixcpM/EUXBABcWARSx88DSX2/jVgAuCv6v VnHSSnBN8vPhZacAqYEdoJL0Wu+kigwTTUA9CuICG2xC1IHTQkTpRWXp2qCps6TrDEEuzTZTwM7 F0WosCuIR80dj5+NXsSrhDv56B2SUxuH3rqWt2tbY/0AvRiV X-Google-Smtp-Source: AGHT+IHGq79Rsv/kZfRVhSkItW1GnSGSGi4cX7skmUfl1fStmFO3ltKgY+5Iw+7Yo4D17wVag2aDMg== X-Received: by 2002:a17:902:d542:b0:223:58ff:c722 with SMTP id d9443c01a7336-225e0a75b3fmr179867305ad.28.1742209107158; Mon, 17 Mar 2025 03:58:27 -0700 (PDT) Received: from localhost ([157.82.207.107]) by smtp.gmail.com with UTF8SMTPSA id d9443c01a7336-225c68aa906sm72547105ad.88.2025.03.17.03.58.22 (version=TLS1_3 cipher=TLS_AES_128_GCM_SHA256 bits=128/128); Mon, 17 Mar 2025 03:58:26 -0700 (PDT) From: Akihiko Odaki Date: Mon, 17 Mar 2025 19:57:53 +0900 Subject: [PATCH net-next v11 03/10] tun: Allow steering eBPF program to fall back 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: <20250317-rss-v11-3-4cacca92f31f@daynix.com> References: <20250317-rss-v11-0-4cacca92f31f@daynix.com> In-Reply-To: <20250317-rss-v11-0-4cacca92f31f@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, Lei Yang , Simon Horman , Akihiko Odaki X-Mailer: b4 0.15-dev-edae6 This clarifies a steering eBPF program takes precedence over the other steering algorithms. Signed-off-by: Akihiko Odaki Tested-by: Lei Yang --- Documentation/networking/tuntap.rst | 7 +++++++ drivers/net/tun.c | 28 +++++++++++++++++----------- include/uapi/linux/if_tun.h | 9 +++++++++ 3 files changed, 33 insertions(+), 11 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/tun.c b/drivers/net/tun.c index d8f4d3e996a7..9133ab9ed3f5 100644 --- a/drivers/net/tun.c +++ b/drivers/net/tun.c @@ -476,21 +476,29 @@ static u16 tun_automq_select_queue(struct tun_struct = *tun, struct sk_buff *skb) return txq; } =20 -static u16 tun_ebpf_select_queue(struct tun_struct *tun, struct sk_buff *s= kb) +static bool tun_ebpf_select_queue(struct tun_struct *tun, struct sk_buff *= skb, + u16 *ret) { struct tun_prog *prog; u32 numqueues; - u16 ret =3D 0; + u32 prog_ret; + + prog =3D rcu_dereference(tun->steering_prog); + if (!prog) + return false; =20 numqueues =3D READ_ONCE(tun->numqueues); - if (!numqueues) - return 0; + if (!numqueues) { + *ret =3D 0; + return true; + } =20 - prog =3D rcu_dereference(tun->steering_prog); - if (prog) - ret =3D bpf_prog_run_clear_cb(prog->prog, skb); + prog_ret =3D bpf_prog_run_clear_cb(prog->prog, skb); + if (prog_ret =3D=3D TUN_STEERINGEBPF_FALLBACK) + return false; =20 - return ret % numqueues; + *ret =3D (u16)prog_ret % numqueues; + return true; } =20 static u16 tun_select_queue(struct net_device *dev, struct sk_buff *skb, @@ -500,9 +508,7 @@ static u16 tun_select_queue(struct net_device *dev, str= uct sk_buff *skb, u16 ret; =20 rcu_read_lock(); - if (rcu_dereference(tun->steering_prog)) - ret =3D tun_ebpf_select_queue(tun, skb); - else + if (!tun_ebpf_select_queue(tun, skb, &ret)) ret =3D tun_automq_select_queue(tun, skb); rcu_read_unlock(); =20 diff --git a/include/uapi/linux/if_tun.h b/include/uapi/linux/if_tun.h index 287cdc81c939..980de74724fc 100644 --- a/include/uapi/linux/if_tun.h +++ b/include/uapi/linux/if_tun.h @@ -115,4 +115,13 @@ struct tun_filter { __u8 addr[][ETH_ALEN]; }; =20 +/** + * define TUN_STEERINGEBPF_FALLBACK - A steering eBPF return value to fall= back + * + * A steering eBPF program may return this value to fall back to the steer= ing + * algorithm that should have been used if the program was not set. This a= llows + * selectively overriding the steering decision. + */ +#define TUN_STEERINGEBPF_FALLBACK -1 + #endif /* _UAPI__IF_TUN_H */ --=20 2.48.1 From nobody Wed Dec 17 13:46:03 2025 Received: from mail-pl1-f169.google.com (mail-pl1-f169.google.com [209.85.214.169]) (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 E604023A98E for ; Mon, 17 Mar 2025 10:58:33 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.214.169 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1742209115; cv=none; b=AOJQ1xpWApXLsPAt40ptulAMeC9QSCPun1bEGrvQSQZMOdOynhdqei+U93QvXkkhtyW4PGHoytwULZ7KOy6STiUGW6G8gsJHZT9yoo6sXmdUyd8YwNnZ07samk6qYXIGZX71g+V5gorZviZiW/C8t1iX17+awX8ckoNC8zYRdHU= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1742209115; c=relaxed/simple; bh=nFlZruyUGC1SefIAzclzdj2tkbf6BBZOp0YpRTkvlMg=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To; b=CudYIoqahaEC6N4Hzy5H1DtSDAVhrpLW9Qf+ru+0xkGi+UXnBJWTsTGR71USV20G02F5gBwGPVDdXWsGjyl1mERo8lVe1EFfaWEeJvFSBcQp6f5Uh67jLBKhtk5ieEOaU7emciw8ICXxGfzl2+Rc/SI4SHoVBsMW/OmVnNwMYJE= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=daynix.com; spf=pass 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=M45Cs1Ep; arc=none smtp.client-ip=209.85.214.169 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=daynix.com Authentication-Results: smtp.subspace.kernel.org; spf=pass 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="M45Cs1Ep" Received: by mail-pl1-f169.google.com with SMTP id d9443c01a7336-2243803b776so30744765ad.0 for ; Mon, 17 Mar 2025 03:58:33 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=daynix-com.20230601.gappssmtp.com; s=20230601; t=1742209113; x=1742813913; 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=DF+oAfxAaVuIF8loqeGyU6Uzr2digKuwKsJalo4eV8o=; b=M45Cs1EpGrLKJa5+NYMCDbql5+InxZk/+T+NqAuEdCreKGhkCpbPfQi8hX0Gl6CGx5 HT4SWbIWs9/dLnQBeuHcDHgd9DmkorlPatkgjEW3GU85kMvjxWcX2OJTVccVzBSLX2n4 cfBbPFk9FbP8xch9yIpexiwESOoFlb/oQnuFTzC4NdObtqiMuZZy+qync69eqzddj1oS 1KEmwdgjzPiF1BjPh2H1JyFHq6XaR0QAAZQ2u7nUQkOBgO0u+vO1cgYYeE5gnuxvoYyR yZPCxEBdJgOQxtC9acYySGBo2dCGVSB1dkAsLAzv/+7KTv8dsit1Xb178EUaUgpUy4Mw CUtg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1742209113; x=1742813913; 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=DF+oAfxAaVuIF8loqeGyU6Uzr2digKuwKsJalo4eV8o=; b=FGZBKTodTyHtDAT8SQSap4Vd0fFkYoX63RQCO+qlqF/nvB2zoByVXlH7IK8Zp0+WSk x5RVrNF62hBCGzbyAbyaKmaFtiHjVderN7o4mcyw0q5PXmQORdE/4PLE7Mh7HJDCbBOU gBZihkZT9jDIZCbB3fx1Y1xXFLq14fgDjtXc7BT2fVJupJFyF4jR/qHPgT9TZ+//yPpx bcekKGZCRTxSjRYjs8tZCFKbVD/8rbQCmdkxbyao9db0c3Vu1Ywxsn58nDRg3NSmMzwq MFQTCdT4HiuGKPAMrmdhO1fQmQeB5GC6bOAJv4Z0L27iH8OJKvydkPmsBeBbJ6jPHqkM eSlw== X-Forwarded-Encrypted: i=1; AJvYcCUGIK2kxQkng67DtGg28V3ZTB42LsuJqnIKxSxufjVWpBeAc3XXa4XGQ+9jtPvwW0bOqyMveujso+8XPSI=@vger.kernel.org X-Gm-Message-State: AOJu0Yx2Q5db/mMIwFDfEwafkpkOFsS8qgvakRlNjHPlNYpTcT0cH7IZ UEPOlj0nA07RxRmupQWWb0DNAirgulrtkUIMCscbvrOK9Uwv1PbP7zVF5OH4VHY= X-Gm-Gg: ASbGnctCuI/Aa9QQkuJ5cAETlGokHCznPCkOfCKqlPmJ1bumT6zmlPl+oHbp49nqP/y LxhFtri6qCkWaQzERTA6eaNCpuMolqTRVC5Hv5PjMW+d8sQHcENFikeOGrvy+Ln4nR+vkti4ON+ iSVgzGInVzrVj/FV2Rd0U4riCBkxyhjaxGdLjfw9m6i7JGTIHPHPycy0XkpnsTuyndt8UFqyZ4O rkyFEF/lfTv/7P9fvzGrFNNdcd56u2YBvYZc5bKX4N6HjfNN2jmqxfCuayYLK/D1e+zl5XNDsdh qmbeuLPHAneivQ8p+ykkn0fwk7XrBG9wtAcDjT4mPyl3D2QQ X-Google-Smtp-Source: AGHT+IFXupmuGmu6gHP1FkeYwrRwPZhFLo2ew2wOdmTTzj5IIHUL/pIizUJC+QYtkF4syjlrofB0Tg== X-Received: by 2002:a17:902:ce0b:b0:224:10a2:cad5 with SMTP id d9443c01a7336-225e0a1d661mr148593695ad.10.1742209113022; Mon, 17 Mar 2025 03:58:33 -0700 (PDT) Received: from localhost ([157.82.207.107]) by smtp.gmail.com with UTF8SMTPSA id d9443c01a7336-225c6ba6d5dsm72426865ad.153.2025.03.17.03.58.28 (version=TLS1_3 cipher=TLS_AES_128_GCM_SHA256 bits=128/128); Mon, 17 Mar 2025 03:58:32 -0700 (PDT) From: Akihiko Odaki Date: Mon, 17 Mar 2025 19:57:54 +0900 Subject: [PATCH net-next v11 04/10] tun: Add common virtio-net hash feature code 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: <20250317-rss-v11-4-4cacca92f31f@daynix.com> References: <20250317-rss-v11-0-4cacca92f31f@daynix.com> In-Reply-To: <20250317-rss-v11-0-4cacca92f31f@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, Lei Yang , Simon Horman , Akihiko Odaki X-Mailer: b4 0.15-dev-edae6 Add common code required for the features being added to TUN and TAP. They will be enabled for each of them in following patches. Added Features =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D Hash reporting Tested-by: Lei Yang -------------- Allow the guest to reuse the hash value to make receive steering consistent between the host and guest, and to save hash computation. Receive Side Scaling (RSS) -------------------------- 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. Added ioctls =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D They are designed to make extensibility and VM migration compatible. This change only adds the implementation and does not expose them to the userspace. TUNGETVNETHASHCAP ----------------- This ioctl tells supported features and hash types. It is useful to check if a VM can be migrated to the current host. TUNSETVNETHASH -------------- This ioctl allows setting features and hash types to be enabled. It limits the features exposed to the guest to ensure proper migration. It also sets RSS parameters, depending on the enabled features and hash types. Signed-off-by: Akihiko Odaki Tested-by: Lei Yang --- drivers/net/tap.c | 10 ++- drivers/net/tun.c | 12 +++- drivers/net/tun_vnet.h | 155 ++++++++++++++++++++++++++++++++++++++++= +--- include/uapi/linux/if_tun.h | 73 +++++++++++++++++++++ 4 files changed, 236 insertions(+), 14 deletions(-) diff --git a/drivers/net/tap.c b/drivers/net/tap.c index d4ece538f1b2..25c60ff2d3f2 100644 --- a/drivers/net/tap.c +++ b/drivers/net/tap.c @@ -179,6 +179,11 @@ static void tap_put_queue(struct tap_queue *q) sock_put(&q->sk); } =20 +static const struct virtio_net_hash *tap_find_hash(const struct sk_buff *s= kb) +{ + return NULL; +} + /* * Select a queue based on the rxq of the device on which this packet * arrived. If the incoming device is not mq, calculate a flow hash @@ -711,11 +716,12 @@ static ssize_t tap_put_user(struct tap_queue *q, int total; =20 if (q->flags & IFF_VNET_HDR) { - struct virtio_net_hdr vnet_hdr; + struct virtio_net_hdr_v1_hash vnet_hdr; =20 vnet_hdr_len =3D READ_ONCE(q->vnet_hdr_sz); =20 - ret =3D tun_vnet_hdr_from_skb(q->flags, NULL, skb, &vnet_hdr); + ret =3D tun_vnet_hdr_from_skb(vnet_hdr_len, q->flags, NULL, skb, + tap_find_hash, &vnet_hdr); if (ret) return ret; =20 diff --git a/drivers/net/tun.c b/drivers/net/tun.c index 9133ab9ed3f5..03d47799e9bd 100644 --- a/drivers/net/tun.c +++ b/drivers/net/tun.c @@ -451,6 +451,11 @@ static inline void tun_flow_save_rps_rxhash(struct tun= _flow_entry *e, u32 hash) e->rps_rxhash =3D hash; } =20 +static const struct virtio_net_hash *tun_find_hash(const struct sk_buff *s= kb) +{ + return NULL; +} + /* We try to identify a flow through its rxhash. The reason that * we do not check rxq no. is because some cards(e.g 82599), chooses * the rxq based on the txq where the last packet of the flow comes. As @@ -1993,7 +1998,7 @@ static ssize_t tun_put_user_xdp(struct tun_struct *tu= n, ssize_t ret; =20 if (tun->flags & IFF_VNET_HDR) { - struct virtio_net_hdr gso =3D { 0 }; + struct virtio_net_hdr_v1_hash gso =3D { 0 }; =20 vnet_hdr_sz =3D READ_ONCE(tun->vnet_hdr_sz); ret =3D tun_vnet_hdr_put(vnet_hdr_sz, iter, &gso); @@ -2046,9 +2051,10 @@ static ssize_t tun_put_user(struct tun_struct *tun, } =20 if (vnet_hdr_sz) { - struct virtio_net_hdr gso; + struct virtio_net_hdr_v1_hash gso; =20 - ret =3D tun_vnet_hdr_from_skb(tun->flags, tun->dev, skb, &gso); + ret =3D tun_vnet_hdr_from_skb(vnet_hdr_sz, tun->flags, tun->dev, + skb, tun_find_hash, &gso); if (ret) return ret; =20 diff --git a/drivers/net/tun_vnet.h b/drivers/net/tun_vnet.h index 58b9ac7a5fc4..578adaac0671 100644 --- a/drivers/net/tun_vnet.h +++ b/drivers/net/tun_vnet.h @@ -6,6 +6,16 @@ #define TUN_VNET_LE 0x80000000 #define TUN_VNET_BE 0x40000000 =20 +typedef struct virtio_net_hash *(*tun_vnet_hash_add)(struct sk_buff *); +typedef const struct virtio_net_hash *(*tun_vnet_hash_find)(const struct s= k_buff *); + +struct tun_vnet_hash_container { + struct tun_vnet_hash common; + struct tun_vnet_hash_rss rss; + u32 rss_key[VIRTIO_NET_RSS_MAX_KEY_SIZE]; + u16 rss_indirection_table[]; +}; + static inline bool tun_vnet_legacy_is_little_endian(unsigned int flags) { bool be =3D IS_ENABLED(CONFIG_TUN_VNET_CROSS_LE) && @@ -107,6 +117,119 @@ static inline long tun_vnet_ioctl(int *vnet_hdr_sz, u= nsigned int *flags, } } =20 +static inline long tun_vnet_ioctl_gethashcap(void __user *argp) +{ + static const struct tun_vnet_hash cap =3D { + .flags =3D TUN_VNET_HASH_REPORT | TUN_VNET_HASH_RSS, + .types =3D VIRTIO_NET_SUPPORTED_HASH_TYPES + }; + + return copy_to_user(argp, &cap, sizeof(cap)) ? -EFAULT : 0; +} + +static inline long tun_vnet_ioctl_sethash(struct tun_vnet_hash_container _= _rcu **hashp, + void __user *argp) +{ + struct tun_vnet_hash hash_buf; + struct tun_vnet_hash_container *hash; + + if (copy_from_user(&hash_buf, argp, sizeof(hash_buf))) + return -EFAULT; + argp =3D (struct tun_vnet_hash __user *)argp + 1; + + if (hash_buf.flags & TUN_VNET_HASH_RSS) { + struct tun_vnet_hash_rss rss; + size_t indirection_table_size; + size_t key_size; + size_t size; + + if (copy_from_user(&rss, argp, sizeof(rss))) + return -EFAULT; + 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(hash_buf.types); + size =3D struct_size(hash, rss_indirection_table, + (size_t)rss.indirection_table_mask + 1); + + hash =3D kmalloc(size, GFP_KERNEL); + if (!hash) + return -ENOMEM; + + if (copy_from_user(hash->rss_indirection_table, + argp, indirection_table_size)) { + kfree(hash); + return -EFAULT; + } + argp =3D (u16 __user *)argp + rss.indirection_table_mask + 1; + + if (copy_from_user(hash->rss_key, argp, key_size)) { + kfree(hash); + return -EFAULT; + } + + virtio_net_toeplitz_convert_key(hash->rss_key, key_size); + hash->rss =3D rss; + } else { + hash =3D kmalloc(sizeof(hash->common), GFP_KERNEL); + if (!hash) + return -ENOMEM; + } + + hash->common =3D hash_buf; + kfree_rcu_mightsleep(rcu_replace_pointer_rtnl(*hashp, hash)); + return 0; +} + +static inline void tun_vnet_hash_report(const struct tun_vnet_hash_contain= er *hash, + struct sk_buff *skb, + const struct flow_keys_basic *keys, + u32 value, + tun_vnet_hash_add vnet_hash_add) +{ + struct virtio_net_hash *report; + + if (!hash || !(hash->common.flags & TUN_VNET_HASH_REPORT)) + return; + + report =3D vnet_hash_add(skb); + if (!report) + return; + + *report =3D (struct virtio_net_hash) { + .report =3D virtio_net_hash_report(hash->common.types, keys), + .value =3D value + }; +} + +static inline u16 tun_vnet_rss_select_queue(u32 numqueues, + const struct tun_vnet_hash_container *hash, + struct sk_buff *skb, + tun_vnet_hash_add vnet_hash_add) +{ + struct virtio_net_hash *report; + struct virtio_net_hash ret; + u16 index; + + if (!numqueues) + return 0; + + virtio_net_hash_rss(skb, hash->common.types, hash->rss_key, &ret); + + if (!ret.report) + return hash->rss.unclassified_queue % numqueues; + + if (hash->common.flags & TUN_VNET_HASH_REPORT) { + report =3D vnet_hash_add(skb); + if (report) + *report =3D ret; + } + + index =3D ret.value & hash->rss.indirection_table_mask; + + return hash->rss_indirection_table[index] % numqueues; +} + static inline int tun_vnet_hdr_get(int sz, unsigned int flags, struct iov_iter *from, struct virtio_net_hdr *hdr) @@ -135,15 +258,17 @@ static inline int tun_vnet_hdr_get(int sz, unsigned i= nt flags, } =20 static inline int tun_vnet_hdr_put(int sz, struct iov_iter *iter, - const struct virtio_net_hdr *hdr) + const struct virtio_net_hdr_v1_hash *hdr) { + int content_sz =3D MIN(sizeof(*hdr), sz); + if (unlikely(iov_iter_count(iter) < sz)) return -EINVAL; =20 - if (unlikely(copy_to_iter(hdr, sizeof(*hdr), iter) !=3D sizeof(*hdr))) + if (unlikely(copy_to_iter(hdr, content_sz, iter) !=3D content_sz)) return -EFAULT; =20 - if (iov_iter_zero(sz - sizeof(*hdr), iter) !=3D sz - sizeof(*hdr)) + if (iov_iter_zero(sz - content_sz, iter) !=3D sz - content_sz) return -EFAULT; =20 return 0; @@ -155,26 +280,38 @@ static inline int tun_vnet_hdr_to_skb(unsigned int fl= ags, struct sk_buff *skb, return virtio_net_hdr_to_skb(skb, hdr, tun_vnet_is_little_endian(flags)); } =20 -static inline int tun_vnet_hdr_from_skb(unsigned int flags, +static inline int tun_vnet_hdr_from_skb(int sz, unsigned int flags, const struct net_device *dev, const struct sk_buff *skb, - struct virtio_net_hdr *hdr) + tun_vnet_hash_find vnet_hash_find, + struct virtio_net_hdr_v1_hash *hdr) { int vlan_hlen =3D skb_vlan_tag_present(skb) ? VLAN_HLEN : 0; + const struct virtio_net_hash *report =3D sz < sizeof(struct virtio_net_hd= r_v1_hash) ? + NULL : vnet_hash_find(skb); + + *hdr =3D (struct virtio_net_hdr_v1_hash) { + .hash_report =3D VIRTIO_NET_HASH_REPORT_NONE + }; + + if (report) { + hdr->hash_value =3D cpu_to_le32(report->value); + hdr->hash_report =3D cpu_to_le16(report->report); + } =20 - if (virtio_net_hdr_from_skb(skb, hdr, + if (virtio_net_hdr_from_skb(skb, (struct virtio_net_hdr *)hdr, tun_vnet_is_little_endian(flags), true, vlan_hlen)) { struct skb_shared_info *sinfo =3D skb_shinfo(skb); =20 if (net_ratelimit()) { netdev_err(dev, "unexpected GSO type: 0x%x, gso_size %d, hdr_len %d\n", - sinfo->gso_type, tun_vnet16_to_cpu(flags, hdr->gso_size), - tun_vnet16_to_cpu(flags, hdr->hdr_len)); + sinfo->gso_type, tun_vnet16_to_cpu(flags, hdr->hdr.gso_size), + tun_vnet16_to_cpu(flags, hdr->hdr.hdr_len)); print_hex_dump(KERN_ERR, "tun: ", DUMP_PREFIX_NONE, 16, 1, skb->head, - min(tun_vnet16_to_cpu(flags, hdr->hdr_len), 64), true); + min(tun_vnet16_to_cpu(flags, hdr->hdr.hdr_len), 64), true); } WARN_ON_ONCE(1); return -EINVAL; diff --git a/include/uapi/linux/if_tun.h b/include/uapi/linux/if_tun.h index 980de74724fc..b7b0fe69a652 100644 --- a/include/uapi/linux/if_tun.h +++ b/include/uapi/linux/if_tun.h @@ -62,6 +62,42 @@ #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. + * + * 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 + * + * The %TUN_VNET_HASH_REPORT flag set with this ioctl will be effective on= ly + * after calling the %TUNSETVNETHDRSZ ioctl with a number greater than or = equal + * to the size of &struct virtio_net_hdr_v1_hash. + * + * The members added to the legacy header by %TUN_VNET_HASH_REPORT flag wi= ll + * always be little-endian. + * + * This ioctl results in %EBADFD if the underlying device is deleted. It a= ffects + * all queues attached to the same device. + * + * This ioctl currently has no effect on XDP packets and packets with + * queue_mapping set by TC. + */ +#define TUNSETVNETHASH _IOW('T', 229, struct tun_vnet_hash) + /* TUNSETIFF ifr flags */ #define IFF_TUN 0x0001 #define IFF_TAP 0x0002 @@ -124,4 +160,41 @@ struct tun_filter { */ #define TUN_STEERINGEBPF_FALLBACK -1 =20 +/** + * define TUN_VNET_HASH_REPORT - Request virtio_net hash reporting for vho= st + */ +#define TUN_VNET_HASH_REPORT 0x0001 + +/** + * define TUN_VNET_HASH_RSS - Request virtio_net RSS + */ +#define TUN_VNET_HASH_RSS 0x0002 + +/** + * 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; +}; + +/** + * 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.48.1 From nobody Wed Dec 17 13:46:03 2025 Received: from mail-pl1-f176.google.com (mail-pl1-f176.google.com [209.85.214.176]) (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 CE66923BD04 for ; Mon, 17 Mar 2025 10:58:39 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.214.176 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1742209122; cv=none; b=q0ePpHKD76D8+2Iccnw+mKW1DJqX815TJ5vJeWrZ72bLmBE5adm/VwpCnhpMEF3UTQ3ZXybmOR82V3oC+lXZYY0J3dsLf0sOBmxt49tnuGJgOJhJYMi+HIVn7Bi2DLS1NHGOj5KvKtnDwuLprym95RJUxeiwMmkl0N2ZoRfHx/w= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1742209122; c=relaxed/simple; bh=fAsNygmBH4vEFfwnr1O256Ehqy/tj24JUzQEngxqzTs=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To; b=uAGA8yKEqePhJ6GfuUUsh3Bet7vmYs082y602Bw2MXmrbCLUDpk8mPXm22Znc4fIqqvDwIelOJ27eHsQ3Gu6PO1w+hHGId3BiIId3STFzdANXl+JTjoclVUtqtSYJMop1M8ldjC5bxQOgXHXz1D6gUmN8D2OAN4GSPTZ4dYY+mo= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=daynix.com; spf=pass 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=Tqy/NZ61; arc=none smtp.client-ip=209.85.214.176 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=daynix.com Authentication-Results: smtp.subspace.kernel.org; spf=pass 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="Tqy/NZ61" Received: by mail-pl1-f176.google.com with SMTP id d9443c01a7336-225a28a511eso66891625ad.1 for ; Mon, 17 Mar 2025 03:58:39 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=daynix-com.20230601.gappssmtp.com; s=20230601; t=1742209119; x=1742813919; 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=iEx1oB+WR7O6v2TIINfyTS8xxjNqfeRuV0OaAnQT/3s=; b=Tqy/NZ61rI7ApMk1xalcVcd0wmH7ifXVgMH9+3JmaJxwYApsTu+p904ABYNA/eMGyR GCadMhcYlulL0HIcKtojDyCV5UYEYG8zaEbAbxAVlTmIDkqDyDiGWxUSPNdskTDA6nT4 vSPhUH3uLdj1qK8lMrNi1SulCvNEsZyoDwODiWpM+K5ZdCXlhrpNLDsH2UnCOxbJ54iz 8bcuOCT4Upfr9RUuy02tYp1UekDuvmh/mZWHa8VB9PkEpSsXpitmg+m8Cf8wBwN0zd0Q a9yUCoOkHtianBCk+PorQwfrkfbKMjnTtZW6c5tYb9MEkBzBO0VVDrc4xTk7cM6EL6bE duMA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1742209119; x=1742813919; 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=iEx1oB+WR7O6v2TIINfyTS8xxjNqfeRuV0OaAnQT/3s=; b=OBaIHo0vt5dkkBr0TbkV+zq8gcyufBvLosLB9+rEhVMl2UUjgp4kcTP3O0IxpnIG2E uclOUtGcxr7eF6g07MJdXYQtdK8B60gnZsVX7FcoMdxdtJ1BbXPW1FeQv/Ly6Fndq/f9 +g6ahDltSz6qq7F06kXvsuNCzvOGnSeSZRM1nTi7rBbN+IEm1NoMmns71A707uZKsqTN JbotNxkzEnJc/aWgpMO2VAmFUUTE4aRX9AB3OTTay02NVgPeopmq3b4vVF0zRz35chDQ LDp9g8Yd+auf26qv/3TKV8ztoERLFFYZibbtUAj8LX/3lyQXgavgaH7LrvLAid95hRAC 3e/Q== X-Forwarded-Encrypted: i=1; AJvYcCWkQBGmqytxuQTKpBn64ykffEp3sAlCnI77GTwjBduxYEyTiNdoEi/JLxQSUQ4f98/ERAkkQLc3MnbGLvI=@vger.kernel.org X-Gm-Message-State: AOJu0YwWFELrSvScMF2TsLUJ/wWcsi3Hva70QdJKfPscJ14laUkNTWma 43Z8yUpZ6WEuJGwsZeYYBnfxMHUHZUtrLNOPZ1k8erJyPPa3XbvuAvX2VbGYxJs= X-Gm-Gg: ASbGncvKPjJapeAHq+oAbNFkeZiYh74FyydhX+XXoBAitOix0VfiuFitltETzpYy4aa M4F4oRVWWQtEOHRMabWjL32chYYXi5TxfLs4JU7KaFlF++92VRWDFC2BKQk8QwYz+66GhPh8FlR 0sQQLCAG56Cyzqd212aHLkZlYkOpAajoY2YLYXkseedn/oe0rZItnmub4iiQwSV33mOJe3Ah4uS ChV/LZWUQYwyUaMWfve2CLpApp6+eDxmIC+JQqtV0LkynLSVSQAuPWlZzl+CzvoF8EWuh4IL0zK Lq2Of6FQotW68yXOhzIdNOcWEjeIHPtj1DXN4VbA3mSXLQxm X-Google-Smtp-Source: AGHT+IHX4HyK1k//tjemW3f4I2XPhHcKoJYNfaunw3BDHkKS92XkMFCdfmRLmOxFS0Kbm0S3BYpFzQ== X-Received: by 2002:a05:6a21:6f12:b0:1f5:5807:13c7 with SMTP id adf61e73a8af0-1f5c118e6abmr15940192637.17.1742209118936; Mon, 17 Mar 2025 03:58:38 -0700 (PDT) Received: from localhost ([157.82.207.107]) by smtp.gmail.com with UTF8SMTPSA id d2e1a72fcca58-737115294besm7237748b3a.21.2025.03.17.03.58.34 (version=TLS1_3 cipher=TLS_AES_128_GCM_SHA256 bits=128/128); Mon, 17 Mar 2025 03:58:38 -0700 (PDT) From: Akihiko Odaki Date: Mon, 17 Mar 2025 19:57:55 +0900 Subject: [PATCH net-next v11 05/10] tun: Introduce virtio-net hash 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: <20250317-rss-v11-5-4cacca92f31f@daynix.com> References: <20250317-rss-v11-0-4cacca92f31f@daynix.com> In-Reply-To: <20250317-rss-v11-0-4cacca92f31f@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, Lei Yang , Simon Horman , Akihiko Odaki X-Mailer: b4 0.15-dev-edae6 Add ioctls and storage required for the virtio-net hash feature to TUN. Signed-off-by: Akihiko Odaki Tested-by: Lei Yang --- drivers/net/Kconfig | 1 + drivers/net/tun.c | 54 ++++++++++++++++++++++++++++++++++++++++++----= ---- include/linux/skbuff.h | 3 +++ net/core/skbuff.c | 4 ++++ 4 files changed, 54 insertions(+), 8 deletions(-) diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig index 1fd5acdc73c6..aecfd244dd83 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 03d47799e9bd..b2d74e0ec932 100644 --- a/drivers/net/tun.c +++ b/drivers/net/tun.c @@ -209,6 +209,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_container __rcu *vnet_hash; struct ethtool_link_ksettings link_ksettings; /* init args */ struct file *file; @@ -451,9 +452,14 @@ static inline void tun_flow_save_rps_rxhash(struct tun= _flow_entry *e, u32 hash) e->rps_rxhash =3D hash; } =20 +static struct virtio_net_hash *tun_add_hash(struct sk_buff *skb) +{ + return skb_ext_add(skb, SKB_EXT_TUN_VNET_HASH); +} + static const struct virtio_net_hash *tun_find_hash(const struct sk_buff *s= kb) { - return NULL; + return skb_ext_find(skb, SKB_EXT_TUN_VNET_HASH); } =20 /* We try to identify a flow through its rxhash. The reason that @@ -462,14 +468,21 @@ static const struct virtio_net_hash *tun_find_hash(co= nst struct sk_buff *skb) * 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, + const struct tun_vnet_hash_container *vnet_hash, + struct sk_buff *skb) { + struct flow_keys keys; + struct flow_keys_basic keys_basic; 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); @@ -478,6 +491,13 @@ static u16 tun_automq_select_queue(struct tun_struct *= tun, struct sk_buff *skb) txq =3D reciprocal_scale(txq, numqueues); } =20 + keys_basic =3D (struct flow_keys_basic) { + .control =3D keys.control, + .basic =3D keys.basic + }; + tun_vnet_hash_report(vnet_hash, skb, &keys_basic, skb->l4_hash ? skb->has= h : txq, + tun_add_hash); + return txq; } =20 @@ -513,8 +533,15 @@ static u16 tun_select_queue(struct net_device *dev, st= ruct sk_buff *skb, u16 ret; =20 rcu_read_lock(); - if (!tun_ebpf_select_queue(tun, skb, &ret)) - ret =3D tun_automq_select_queue(tun, skb); + if (!tun_ebpf_select_queue(tun, skb, &ret)) { + 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(READ_ONCE(tun->numqueues), vnet_hash, + skb, tun_add_hash); + else + ret =3D tun_automq_select_queue(tun, vnet_hash, skb); + } rcu_read_unlock(); =20 return ret; @@ -2235,6 +2262,7 @@ 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); + kfree_rcu_mightsleep(rcu_access_pointer(tun->vnet_hash)); } =20 static void tun_setup(struct net_device *dev) @@ -3014,16 +3042,22 @@ static long __tun_chr_ioctl(struct file *file, unsi= gned int cmd, } else { memset(&ifr, 0, sizeof(ifr)); } - if (cmd =3D=3D TUNGETFEATURES) { + switch (cmd) { + case TUNGETFEATURES: /* Currently this just means: "what IFF flags are valid?". * This is needed because we never checked for invalid flags on * TUNSETIFF. */ return put_user(IFF_TUN | IFF_TAP | IFF_NO_CARRIER | TUN_FEATURES, (unsigned int __user*)argp); - } else if (cmd =3D=3D TUNSETQUEUE) { + + case TUNSETQUEUE: return tun_set_queue(file, &ifr); - } else if (cmd =3D=3D SIOCGSKNS) { + + case TUNGETVNETHASHCAP: + return tun_vnet_ioctl_gethashcap(argp); + + case SIOCGSKNS: if (!ns_capable(net->user_ns, CAP_NET_ADMIN)) return -EPERM; return open_related_ns(&net->ns, get_net_ns); @@ -3264,6 +3298,10 @@ 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: + ret =3D tun_vnet_ioctl_sethash(&tun->vnet_hash, argp); + break; + default: ret =3D tun_vnet_ioctl(&tun->vnet_hdr_sz, &tun->flags, cmd, argp); break; diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h index bb2b751d274a..cdd793f1c360 100644 --- a/include/linux/skbuff.h +++ b/include/linux/skbuff.h @@ -4842,6 +4842,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 7b03b64fdcb2..aa2a091b649f 100644 --- a/net/core/skbuff.c +++ b/net/core/skbuff.c @@ -64,6 +64,7 @@ #include #include #include +#include =20 #include #include @@ -4969,6 +4970,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 virtio_net_hash), +#endif }; =20 static __always_inline unsigned int skb_ext_total_length(void) --=20 2.48.1 From nobody Wed Dec 17 13:46:03 2025 Received: from mail-pl1-f180.google.com (mail-pl1-f180.google.com [209.85.214.180]) (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 4B201237180 for ; Mon, 17 Mar 2025 10:58:45 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.214.180 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1742209127; cv=none; b=csXx8wH00ksxW4S50RnXyi3U38j/unMpXrG0Qf7xFLtkIFGzus1OFA7+Myobg+StXdLB9CIYqcXm1NYh9/VAYR3mLJBrSfZc/mmuCcQRJQzlU5hdRI3xF4993s2LtR1qdqTgK9refZWmDFz+DdsQSZsraDxjvziGaT9EEnledqU= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1742209127; c=relaxed/simple; bh=NS1jt1Spbqe/VfrMauqyXz8DgcdsegUNVM2kZauxHEk=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To; b=S5fJ0zpFC3BKcs8TO/6R7Sa7gACQ9wIwvci0q3A1g4yazZM6PriwjkqPaj2mdFrKtwjtQO7iu3TRHCzVKPchHpCCCuhCdQD1Ku+B9q1UHSCDxIw4HnznUEw/E4lIj+EajWSZbiu+2a8SvybpGt/1e9x82D+thNW6L+2c3jrLr28= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=daynix.com; spf=pass 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=X7ui4gUM; arc=none smtp.client-ip=209.85.214.180 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=daynix.com Authentication-Results: smtp.subspace.kernel.org; spf=pass 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="X7ui4gUM" Received: by mail-pl1-f180.google.com with SMTP id d9443c01a7336-2243803b776so30748865ad.0 for ; Mon, 17 Mar 2025 03:58:45 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=daynix-com.20230601.gappssmtp.com; s=20230601; t=1742209125; x=1742813925; 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=ps001jy6gq6KEYC80iaJaFVG/ugufazJsC0DDLWZiHk=; b=X7ui4gUM53QdwrrfcnYZHGQfoow3U7XxNoS0TwENXFM3Z/DfQ2WtHgnoUVR4AH5MDI Y+NaR2hmHplBkIQDQthrNRdq4MZvAr1Q7htDv5LDJKtKyThDy2A9nRkkfWgbylSac9vb LeAekfaPCxacOtf2AWcFmdGbi9trAUQMTBQ2OJ3AKkAB8YpHzM163hzZS6bJkpVYuv+u yBrnjekK05E91ZE0NdjhKAzOlG9ZBfSUhBV/hKimxQWK7U/jTuipWnKt0jYODxHpKhT1 3D2zMz/EVJGJQD5nzOWpw7z9rShCZO0xUj/XHrbOT/Qu2+2T0wv3MQzYLm3X2bfYVGNP pdpA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1742209125; x=1742813925; 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=ps001jy6gq6KEYC80iaJaFVG/ugufazJsC0DDLWZiHk=; b=ZP+FWxZydP2QOzYUjfJhLhwCppD0mN/3HxapPTcnPvnL0XnPU9bZlVakccZyovzfuv 1mxd0TkFmJrQAYE1kcYuhVZtrPkzO5WoRwDNlnPcGPy+I/U2KovhlMT4eOlu9CrR1knN WI2A1AhAICD9K08Zx2TFsqhKbQlMHFdhnY+Uncm3x6z6a0WEmATf58M4m3fehf0JFKUf M/wNLhNbc0YSZJ49+UAVBv+0uNpdJWV5o+RqDzZLsWvUdidvNwLt/iGWJIrPdFqhvIsk f/Hu0dihWthyDJ1wn4jClrakmTa0NT65eGxOzsHQpRvha+YIzK9qBHJrEapYA0uL46KA zyUg== X-Forwarded-Encrypted: i=1; AJvYcCW4RtWvjEn3MIm89eayqE4dRyrTQ4rpJ13wTYkToU+9aAYu4lTKfR4AOl7hic5wwEOHr5FSDfsaNYLEf2o=@vger.kernel.org X-Gm-Message-State: AOJu0Yyp7dLGUIEPxZHNHsb5IbWPOxnoV0tH5vpLMBoTFebiTTIekP1k 8ji3wwSk8VDbLfGd6GIW/RG7BceAQHCuPH3vb67rZGhMtSIcR2Tzxrmh/BLLME8= X-Gm-Gg: ASbGncueiTZjk8kkoFn5WJ8mmNN9dJ4CUGwmKxuSC0kjmJmqmu+WVhzEd8LLOYWeZ2w 6vh7tXCUmwSSkQveDJxhM7mRGSvYFxQfefa/a833aenn56jxjEcDeUOO0SwLSr6MKBGkAPz4v8m vrJx0LcBdRWdTIqg792K9YdXs56Q/dSruUp+ntdzbZLhvoPT4PXQtOvIqReg2VHc7QzogpESduB /2IfDX9Mg00vOVKnz2c09zDsMvAEX+yfNFtkTbZIeJXZZxJWDNYjOTvGeNa4vnBPlbkx2HXpPfC SYQPnae6qyCwQUc1kTA4Ly0uOnC6XOf5hw8LLwzIXO+0MSYB X-Google-Smtp-Source: AGHT+IG4tqeuOPRgYJpRA3znbIb40OfzfCTZrtqtBmMDFB3f6jddrhuXu4ka83knBKzypM1vMA3jXQ== X-Received: by 2002:a17:902:cecd:b0:223:5ca8:5ecb with SMTP id d9443c01a7336-225e0aff4e1mr149551595ad.42.1742209124818; Mon, 17 Mar 2025 03:58:44 -0700 (PDT) Received: from localhost ([157.82.207.107]) by smtp.gmail.com with UTF8SMTPSA id d9443c01a7336-225c6ba70d2sm72331995ad.136.2025.03.17.03.58.40 (version=TLS1_3 cipher=TLS_AES_128_GCM_SHA256 bits=128/128); Mon, 17 Mar 2025 03:58:44 -0700 (PDT) From: Akihiko Odaki Date: Mon, 17 Mar 2025 19:57:56 +0900 Subject: [PATCH net-next v11 06/10] tap: Introduce virtio-net hash 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: <20250317-rss-v11-6-4cacca92f31f@daynix.com> References: <20250317-rss-v11-0-4cacca92f31f@daynix.com> In-Reply-To: <20250317-rss-v11-0-4cacca92f31f@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, Lei Yang , Simon Horman , Akihiko Odaki X-Mailer: b4 0.15-dev-edae6 Add ioctls and storage required for the virtio-net hash feature to TAP. Signed-off-by: Akihiko Odaki Tested-by: Lei Yang --- drivers/net/ipvlan/ipvtap.c | 2 +- drivers/net/macvtap.c | 2 +- drivers/net/tap.c | 70 +++++++++++++++++++++++++++++++++++++++++= ---- include/linux/if_tap.h | 4 ++- 4 files changed, 69 insertions(+), 9 deletions(-) diff --git a/drivers/net/ipvlan/ipvtap.c b/drivers/net/ipvlan/ipvtap.c index 1afc4c47be73..305438abf7ae 100644 --- a/drivers/net/ipvlan/ipvtap.c +++ b/drivers/net/ipvlan/ipvtap.c @@ -114,7 +114,7 @@ static void ipvtap_dellink(struct net_device *dev, struct ipvtap_dev *vlan =3D netdev_priv(dev); =20 netdev_rx_handler_unregister(dev); - tap_del_queues(&vlan->tap); + tap_del(&vlan->tap); ipvlan_link_delete(dev, head); } =20 diff --git a/drivers/net/macvtap.c b/drivers/net/macvtap.c index 29a5929d48e5..e72144d05ef4 100644 --- a/drivers/net/macvtap.c +++ b/drivers/net/macvtap.c @@ -122,7 +122,7 @@ static void macvtap_dellink(struct net_device *dev, struct macvtap_dev *vlantap =3D netdev_priv(dev); =20 netdev_rx_handler_unregister(dev); - tap_del_queues(&vlantap->tap); + tap_del(&vlantap->tap); macvlan_dellink(dev, head); } =20 diff --git a/drivers/net/tap.c b/drivers/net/tap.c index 25c60ff2d3f2..2213a2aa83a8 100644 --- a/drivers/net/tap.c +++ b/drivers/net/tap.c @@ -49,6 +49,10 @@ struct major_info { struct list_head next; }; =20 +struct tap_skb_cb { + struct virtio_net_hash hash; +}; + #define GOODCOPY_LEN 128 =20 static const struct proto_ops tap_socket_ops; @@ -179,9 +183,20 @@ static void tap_put_queue(struct tap_queue *q) sock_put(&q->sk); } =20 +static struct tap_skb_cb *tap_skb_cb(const struct sk_buff *skb) +{ + BUILD_BUG_ON(sizeof(skb->cb) < sizeof(struct tap_skb_cb)); + return (struct tap_skb_cb *)skb->cb; +} + +static struct virtio_net_hash *tap_add_hash(struct sk_buff *skb) +{ + return &tap_skb_cb(skb)->hash; +} + static const struct virtio_net_hash *tap_find_hash(const struct sk_buff *s= kb) { - return NULL; + return &tap_skb_cb(skb)->hash; } =20 /* @@ -194,6 +209,7 @@ static const struct virtio_net_hash *tap_find_hash(cons= t struct sk_buff *skb) static struct tap_queue *tap_get_queue(struct tap_dev *tap, struct sk_buff *skb) { + struct flow_keys_basic keys_basic; struct tap_queue *queue =3D NULL; /* Access to taps array is protected by rcu, but access to numvtaps * isn't. Below we use it to lookup a queue, but treat it as a hint @@ -201,17 +217,47 @@ static struct tap_queue *tap_get_queue(struct tap_dev= *tap, * racing against queue removal. */ int numvtaps =3D READ_ONCE(tap->numvtaps); + struct tun_vnet_hash_container *vnet_hash =3D rcu_dereference(tap->vnet_h= ash); __u32 rxq; =20 + *tap_skb_cb(skb) =3D (struct tap_skb_cb) { + .hash =3D { .report =3D VIRTIO_NET_HASH_REPORT_NONE } + }; + if (!numvtaps) goto out; =20 if (numvtaps =3D=3D 1) goto single; =20 + if (vnet_hash) { + if ((vnet_hash->common.flags & TUN_VNET_HASH_RSS)) { + rxq =3D tun_vnet_rss_select_queue(numvtaps, vnet_hash, skb, tap_add_has= h); + queue =3D rcu_dereference(tap->taps[rxq]); + goto out; + } + + if (!skb->l4_hash && !skb->sw_hash) { + struct flow_keys keys; + + skb_flow_dissect_flow_keys(skb, &keys, FLOW_DISSECTOR_F_STOP_AT_FLOW_LA= BEL); + rxq =3D flow_hash_from_keys(&keys); + keys_basic =3D (struct flow_keys_basic) { + .control =3D keys.control, + .basic =3D keys.basic + }; + } else { + skb_flow_dissect_flow_keys_basic(NULL, skb, &keys_basic, NULL, 0, 0, 0, + FLOW_DISSECTOR_F_STOP_AT_FLOW_LABEL); + rxq =3D skb->hash; + } + } else { + rxq =3D skb_get_hash(skb); + } + /* Check if we can use flow to select a queue */ - rxq =3D skb_get_hash(skb); if (rxq) { + tun_vnet_hash_report(vnet_hash, skb, &keys_basic, rxq, tap_add_hash); queue =3D rcu_dereference(tap->taps[rxq % numvtaps]); goto out; } @@ -234,10 +280,10 @@ static struct tap_queue *tap_get_queue(struct tap_dev= *tap, =20 /* * The net_device is going away, give up the reference - * that it holds on all queues and safely set the pointer - * from the queues to NULL. + * that it holds on all queues, safely set the pointer + * from the queues to NULL, and free vnet_hash. */ -void tap_del_queues(struct tap_dev *tap) +void tap_del(struct tap_dev *tap) { struct tap_queue *q, *tmp; =20 @@ -254,8 +300,10 @@ void tap_del_queues(struct tap_dev *tap) BUG_ON(tap->numqueues); /* guarantee that any future tap_set_queue will fail */ tap->numvtaps =3D MAX_TAP_QUEUES; + + kfree_rcu_mightsleep(rtnl_dereference(tap->vnet_hash)); } -EXPORT_SYMBOL_GPL(tap_del_queues); +EXPORT_SYMBOL_GPL(tap_del); =20 rx_handler_result_t tap_handle_frame(struct sk_buff **pskb) { @@ -998,6 +1046,16 @@ static long tap_ioctl(struct file *file, unsigned int= cmd, rtnl_unlock(); return ret; =20 + case TUNGETVNETHASHCAP: + return tun_vnet_ioctl_gethashcap(argp); + + case TUNSETVNETHASH: + rtnl_lock(); + tap =3D rtnl_dereference(q->tap); + ret =3D tap ? tun_vnet_ioctl_sethash(&tap->vnet_hash, argp) : -EBADFD; + rtnl_unlock(); + return ret; + case SIOCGIFHWADDR: rtnl_lock(); tap =3D tap_get_tap_dev(q); diff --git a/include/linux/if_tap.h b/include/linux/if_tap.h index 553552fa635c..9e8e02822d9c 100644 --- a/include/linux/if_tap.h +++ b/include/linux/if_tap.h @@ -31,6 +31,7 @@ static inline struct ptr_ring *tap_get_ptr_ring(struct fi= le *f) #define MAX_TAP_QUEUES 256 =20 struct tap_queue; +struct tun_vnet_hash_container; =20 struct tap_dev { struct net_device *dev; @@ -43,6 +44,7 @@ struct tap_dev { int numqueues; netdev_features_t tap_features; int minor; + struct tun_vnet_hash_container __rcu *vnet_hash; =20 void (*update_features)(struct tap_dev *tap, netdev_features_t features); void (*count_tx_dropped)(struct tap_dev *tap); @@ -74,7 +76,7 @@ struct tap_queue { }; =20 rx_handler_result_t tap_handle_frame(struct sk_buff **pskb); -void tap_del_queues(struct tap_dev *tap); +void tap_del(struct tap_dev *tap); int tap_get_minor(dev_t major, struct tap_dev *tap); void tap_free_minor(dev_t major, struct tap_dev *tap); int tap_queue_resize(struct tap_dev *tap); --=20 2.48.1 From nobody Wed Dec 17 13:46:03 2025 Received: from mail-pl1-f169.google.com (mail-pl1-f169.google.com [209.85.214.169]) (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 24B312376F7 for ; Mon, 17 Mar 2025 10:58:51 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.214.169 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1742209133; cv=none; b=qwLp9BRZ6Okud0vmo361o48R3ymhYzOseA7GC9OKdOew1syJFPepg0mpxyUMNP6aqMK8cLuC5EmB6lP5ekoXfRyVkFTJo5K0prVOLCzhQSUE6BTHW96z/UUHpFTn5PAn9lQPzs85FkOpLKSrcHxAyS3ix1S+FD8+TYQt4PY4IqM= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1742209133; c=relaxed/simple; bh=GneHmk/qL//iBdk3HQU3hkToakkrBvwUGgglHdEvMAI=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To; b=utGAAc9HZxhNKrug7LAm5ldiUkMY1jUdhbKippqX1h6gV7e6/dCOnOV0UMq/YWdPiB+cFnR6aU5XVBhhI0xaKx7cdspLQFdajYrqn+zF1nk+GPq5QwC0PPDSu3xhHBzwu3pb+WwlBH2xI951cSNnYRj3sNKYDEmi7KbvpU/SJiI= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=daynix.com; spf=pass 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=glPhiQEb; arc=none smtp.client-ip=209.85.214.169 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=daynix.com Authentication-Results: smtp.subspace.kernel.org; spf=pass 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="glPhiQEb" Received: by mail-pl1-f169.google.com with SMTP id d9443c01a7336-22401f4d35aso75368265ad.2 for ; Mon, 17 Mar 2025 03:58:51 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=daynix-com.20230601.gappssmtp.com; s=20230601; t=1742209131; x=1742813931; 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=Tr9XV/m9Yn0vfZS8el5Q1nXWgm/+NfgkMX4LFmMiC1g=; b=glPhiQEbgprPRJIAaiPPvdrEwy1JnHyYY/PfrZ1UIgFW6PYWjiCN+VgwzUkIeZeQo2 oiBCFqtQ///+RLLqhC7bp6SOd0h+dteZdvIehfwMmI1ZJW5VsTPpPd6AMGFap+XTJEol 8mrzc9YV88uSmHx5Y3kjCJhtyvS2vqE01jMQx72ZPzxWJuHNA9T2OxU1mB5LdWWkyDRi NP28ThgMdDZmaUpB/7DWGV0cRgj4XWXRN5qZGN2ljs6NpyRzq9dAVKSzMjMznNRvy4dD xIe3vopWjWCCAW9lPw/h7zqJYQtrpbaEjhJYyA1378KFroxAv/9Km4bFY3vSCeqBdGQg VsWQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1742209131; x=1742813931; 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=Tr9XV/m9Yn0vfZS8el5Q1nXWgm/+NfgkMX4LFmMiC1g=; b=F1y+hdBlmQf/gutymMlJUXJue0ZOMNWq0880PfQrSKT99rpOs4rShTwdqBe5B0RKl9 Jhc9mf4FcUdYBseZusH92jfV/uW33+v546zzpRm0YHX0GgpvOgGXAGL6WuR2cqQS92ST WgVt5Pb2ulCWjRzp/SiqzA/PquUUGdciXbnZjVO+9OTf31+uG+uIpW3R04LHvLTgC6tT JJoeu7t5XQsIEe1UOm6ZYPhXffp6CUUZdf2YbOE5JRbX63MgBLY3hSvPb7us769Olcu+ hV0uexxphBNtYSSXHS5yU+PGmBNh0ZJ1uraBsjMpvlSxA2fvppqZmcva4+hFSJqyjgcu eb/w== X-Forwarded-Encrypted: i=1; AJvYcCXeH+WYBeS/8OzMrMKX5H3ZysoKDUfAN8RhEDxjzVY5fVo/+YEPY2tnyrKsOwtj3Qg/d94i/hrdqNWXHe8=@vger.kernel.org X-Gm-Message-State: AOJu0YxSpPYx9AilvbA0L8r7HVBDOPMnjyab/SPWQnveUYl8pfJRgD36 4xK6Cc07dBXIwJuYwgtiybVTKsiJ5eJwIOHRRpKskKUFGAZ53tIDsvd3ECh2yOQ= X-Gm-Gg: ASbGncs2ARniRuZkQjpB7lwm7+3hBxtDpCo2F7hxytGdKHN3xfJzySPMWta2mfXPT/I YuDZ897AexdK7ffZb9AsJIZ9Bh8eG/xrGrIAVs8xdLkFkQyZT22Itlv6IhHor+HMpMfdwpDJ+5o CxIap2niH4GRSLF7VOwdVp6S8HYo6GSMEO0CX5ONqZ89XL8GO//rO0mNXlGYHArns4Dp4iY5w+0 g+Lw5sxZq9OnsaLeUGIiNfu+cMf1wtOCxc5agKlXi7slGGP1JnRbNEahYKpt6sCLZcc/QMJXWbl Ova4yJW923fghbHTMrKLTQ2aStdD0qmUcnflzRhtla2XeLGy X-Google-Smtp-Source: AGHT+IG+ei/lg8cM5wfrSZJXqZa9osmFd7Sc/z8/9LCogmJrZABRCUzflnBMKqILkfW838r3yRiXfA== X-Received: by 2002:a05:6a00:2e25:b0:730:9801:d3e2 with SMTP id d2e1a72fcca58-7372238e7d9mr16744723b3a.8.1742209131380; Mon, 17 Mar 2025 03:58:51 -0700 (PDT) Received: from localhost ([157.82.207.107]) by smtp.gmail.com with UTF8SMTPSA id d2e1a72fcca58-7371167dfa2sm7533712b3a.107.2025.03.17.03.58.47 (version=TLS1_3 cipher=TLS_AES_128_GCM_SHA256 bits=128/128); Mon, 17 Mar 2025 03:58:51 -0700 (PDT) From: Akihiko Odaki Date: Mon, 17 Mar 2025 19:57:57 +0900 Subject: [PATCH net-next v11 07/10] selftest: tun: Test vnet ioctls without device 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: <20250317-rss-v11-7-4cacca92f31f@daynix.com> References: <20250317-rss-v11-0-4cacca92f31f@daynix.com> In-Reply-To: <20250317-rss-v11-0-4cacca92f31f@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, Lei Yang , Simon Horman , Akihiko Odaki X-Mailer: b4 0.15-dev-edae6 Ensure that vnet ioctls result in EBADFD when the underlying device is deleted. Signed-off-by: Akihiko Odaki Tested-by: Lei Yang --- tools/testing/selftests/net/tun.c | 38 +++++++++++++++++++++++++++++++++++= +++ 1 file changed, 38 insertions(+) diff --git a/tools/testing/selftests/net/tun.c b/tools/testing/selftests/ne= t/tun.c index fa83918b62d1..ad168c15c02d 100644 --- a/tools/testing/selftests/net/tun.c +++ b/tools/testing/selftests/net/tun.c @@ -159,4 +159,42 @@ TEST_F(tun, reattach_close_delete) { EXPECT_EQ(tun_delete(self->ifname), 0); } =20 +FIXTURE(tun_deleted) +{ + char ifname[IFNAMSIZ]; + int fd; +}; + +FIXTURE_SETUP(tun_deleted) +{ + self->ifname[0] =3D 0; + self->fd =3D tun_alloc(self->ifname); + ASSERT_LE(0, self->fd); + + ASSERT_EQ(0, tun_delete(self->ifname)) + EXPECT_EQ(0, close(self->fd)); +} + +FIXTURE_TEARDOWN(tun_deleted) +{ + EXPECT_EQ(0, close(self->fd)); +} + +TEST_F(tun_deleted, getvnethdrsz) +{ + ASSERT_EQ(-1, ioctl(self->fd, TUNGETVNETHDRSZ)); + EXPECT_EQ(EBADFD, errno); +} + +TEST_F(tun_deleted, getvnethashcap) +{ + struct tun_vnet_hash cap; + int i =3D ioctl(self->fd, TUNGETVNETHASHCAP, &cap); + + if (i =3D=3D -1 && errno =3D=3D EBADFD) + SKIP(return, "TUNGETVNETHASHCAP not supported"); + + EXPECT_EQ(0, i); +} + TEST_HARNESS_MAIN --=20 2.48.1 From nobody Wed Dec 17 13:46:03 2025 Received: from mail-pl1-f175.google.com (mail-pl1-f175.google.com [209.85.214.175]) (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 2066623ED7B for ; Mon, 17 Mar 2025 10:58:57 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.214.175 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1742209140; cv=none; b=pFNE3wn6uw6CvBQtIT+FsHmF3i3A0TweUkYJtTk4PGeO/D7gbr6sTvriCFQkPNX8BN+4oZeJDh29/BtvSk7dg1h1g3xEAWZqhOxA4nVZMiQT0uR0+RbzZCvUrvo83pU92MVT4HyP+HrXBsUfUSCPGylWb3tIhC/43ETKzaYmo/Y= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1742209140; c=relaxed/simple; bh=lN6+uLr4YpWJFlGsF93rg99nxoQ2xyOlduljX4096YQ=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To; b=Slu9oqVVcDJ1u8OdEietUuFVMO8zaYHf8aMzKlfbXicJizY8zRW6S5rVlcHTR8cM0fuSVzmgF1ICZSyiRMCB9SXAP6qeOTl/norlQ0qxDJhAx7VZHs4OjRig/5zOKgtXTwm0+S1/955JVS7WlmiwAxOb4k8t7PHZ+8Ye98WO2yo= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=daynix.com; spf=pass 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=ZPWmokfb; arc=none smtp.client-ip=209.85.214.175 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=daynix.com Authentication-Results: smtp.subspace.kernel.org; spf=pass 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="ZPWmokfb" Received: by mail-pl1-f175.google.com with SMTP id d9443c01a7336-225e3002dffso36560795ad.1 for ; Mon, 17 Mar 2025 03:58:57 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=daynix-com.20230601.gappssmtp.com; s=20230601; t=1742209137; x=1742813937; 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=yuCKs6/yWaq7hp5qKF+oZHxstBPYJ3gUDKOwyUJw0c0=; b=ZPWmokfbai8bt5YrCgaXsJ8H14yv82DCRc3UjNn8y6zUCKuv8wRX7s1hmAs1TQ0wib SsdqlGhZc30Rp600Y36ghA7mWRtvP2ccLl0xK6g/oOUq1wE3BJconooqaUIY/fsmDrSM XaaqZnmTsk303U+Oa63JaaCkg6/HGXWghsXtVSPJUPArs5acgKJv9h9NPlts6Q/N5oQT PAPnVwaOjTb+WNfrSTKuMqpeMYeEfqr2QgZlwl1QECLA90xsvkAXpo1BiRzSpEp3ZiuI a/Td1UIn1EC4pEC3auW6UChp5oZFEI32O7bpqT7Y+jPxmyGfyPuqD7+PBsicpVtOCazA DDgQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1742209137; x=1742813937; 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=yuCKs6/yWaq7hp5qKF+oZHxstBPYJ3gUDKOwyUJw0c0=; b=xLtFWzaM7OIji7zGYMgpXdmn8xBYzuOqRTScpXgvtOkXHOaKTgoHT43Z7MpQXyiivE qQ/frghnlixt3byE7lUExEEzJf+285cGXfX2QMiTzdnwchicpYmq1kKkhbuqleAB9ucO 9OHRII+/VfzWxa8w8gJq7nZR75LrNZfOwir1GwAzvJA9sA16ioPHfIm3veq3DZgXHjed DvDjZ+l8U8YbXEP05Zn5iNIlUHBxSLnEpu+R/zRVoPAMpiRmiYYQ+IY/jBSTfUsAweAe +E0oIFEilZ75Tn/7vvD8mj1fhMqeOyUDCLm5koeiJPlYGn7qKbmMGFvaff+w4PyMMlk0 odSg== X-Forwarded-Encrypted: i=1; AJvYcCXqBdIQlrLiVZHGzpuJTpYqqoVAUR0TWpyZLzxy6qLYCynZ83nuGgzxGn62PE7f+MihtBABvR7gvMTmrpE=@vger.kernel.org X-Gm-Message-State: AOJu0YxRqUXGp9GZhQ+vp2qOe3zk5tZl3/uU3jUf6R2s4y2AtXKTldrD eZvhbStHY9EsyZyyorhVRDDqWJ1p6V7P9dC/l5q1VBuiV+qYf4FxCHvMplPef1A= X-Gm-Gg: ASbGncuTmGSixM7Mc8OVsCFRsEj5ZF/qFI8SJN4ay4kEGCjq1QQBmClWlaoHXhbegpL a9DPOGP2wiPZZe+Vy2+8Tv4HmWF8GjjiXQyV0LHx+Z1WhiUEoeOTKEWjQcZqoPfAOuvdJyjUlMO QDE4jotzuB4cqqgCw3vvJS2djEGhNTyCTDx9B4ROo9XaAoaIEeQPlZsGL4hADS7wXmc0tU9b5z7 crQymWNPRIJ+ABfqbqTKM+YWsrGKYeAEtjXnjtkTL0krFgWpQ/p9Q9BWbBvuGnM7oBGdxIHtd9Y SBdTUZJ2gn/ZnEf49ekxk5pf2pJORALyZCOKew22LpFjXWC/ X-Google-Smtp-Source: AGHT+IGmh+wlYLU6Dm5L8FlVHO2yhosTkmig11zRjfv1fKJv5Tr5Do4rX2LYb8ms+AEuq8hbttkjaQ== X-Received: by 2002:a05:6a20:e613:b0:1f5:5aac:f345 with SMTP id adf61e73a8af0-1f5c13287b1mr18198565637.36.1742209137372; Mon, 17 Mar 2025 03:58:57 -0700 (PDT) Received: from localhost ([157.82.207.107]) by smtp.gmail.com with UTF8SMTPSA id 41be03b00d2f7-af56ea7bcc0sm6884416a12.56.2025.03.17.03.58.52 (version=TLS1_3 cipher=TLS_AES_128_GCM_SHA256 bits=128/128); Mon, 17 Mar 2025 03:58:57 -0700 (PDT) From: Akihiko Odaki Date: Mon, 17 Mar 2025 19:57:58 +0900 Subject: [PATCH net-next v11 08/10] 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: <20250317-rss-v11-8-4cacca92f31f@daynix.com> References: <20250317-rss-v11-0-4cacca92f31f@daynix.com> In-Reply-To: <20250317-rss-v11-0-4cacca92f31f@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, Lei Yang , Simon Horman , Akihiko Odaki X-Mailer: b4 0.15-dev-edae6 The added tests confirm tun can perform RSS for all supported hash types to select the receive queue and report hash values. Signed-off-by: Akihiko Odaki Tested-by: Lei Yang --- tools/testing/selftests/net/Makefile | 2 +- tools/testing/selftests/net/tun.c | 455 +++++++++++++++++++++++++++++++= +++- 2 files changed, 447 insertions(+), 10 deletions(-) diff --git a/tools/testing/selftests/net/Makefile b/tools/testing/selftests= /net/Makefile index 73ee88d6b043..9772f691a9a0 100644 --- a/tools/testing/selftests/net/Makefile +++ b/tools/testing/selftests/net/Makefile @@ -123,6 +123,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 ad168c15c02d..dfb84da50d91 100644 --- a/tools/testing/selftests/net/tun.c +++ b/tools/testing/selftests/net/tun.c @@ -2,21 +2,38 @@ =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 +#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 +56,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 +69,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 +82,20 @@ static int tun_alloc(char *dev) return fd; } =20 +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 +134,107 @@ 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_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)); +} + FIXTURE(tun) { char ifname[IFNAMSIZ]; @@ -112,10 +245,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 @@ -168,7 +301,7 @@ FIXTURE(tun_deleted) FIXTURE_SETUP(tun_deleted) { self->ifname[0] =3D 0; - self->fd =3D tun_alloc(self->ifname); + self->fd =3D tun_alloc(self->ifname, 0); ASSERT_LE(0, self->fd); =20 ASSERT_EQ(0, tun_delete(self->ifname)) @@ -197,4 +330,308 @@ TEST_F(tun_deleted, getvnethashcap) EXPECT_EQ(0, i); } =20 -TEST_HARNESS_MAIN +FIXTURE(tun_vnet_hash) +{ + int dest_fds[3]; + unsigned int dest_ifindex; + int source_fd; + char buffer[sizeof(struct ipv6hdr) + sizeof(struct tcphdr)]; + uint16_t len; +}; + +FIXTURE_VARIANT(tun_vnet_hash) +{ + uint16_t eth_p; + uint8_t ipproto; + uint8_t flags; + uint16_t hash_report; + uint32_t hash_value; +}; + +FIXTURE_VARIANT_ADD(tun_vnet_hash, unclassified) +{ + .eth_p =3D ETH_P_LOOPBACK +}; + +FIXTURE_VARIANT_ADD(tun_vnet_hash, ipv4) +{ + .eth_p =3D ETH_P_IP, + .ipproto =3D 253, + .hash_report =3D VIRTIO_NET_HASH_REPORT_IPv4, + .hash_value =3D 0x6e45d952 +}; + +FIXTURE_VARIANT_ADD(tun_vnet_hash, tcpv4) +{ + .eth_p =3D ETH_P_IP, + .ipproto =3D IPPROTO_TCP, + .hash_report =3D VIRTIO_NET_HASH_REPORT_TCPv4, + .hash_value =3D 0xfb63539a +}; + +FIXTURE_VARIANT_ADD(tun_vnet_hash, udpv4) +{ + .eth_p =3D ETH_P_IP, + .ipproto =3D IPPROTO_UDP, + .hash_report =3D VIRTIO_NET_HASH_REPORT_UDPv4, + .hash_value =3D 0xfb63539a +}; + +FIXTURE_VARIANT_ADD(tun_vnet_hash, ipv6) +{ + .eth_p =3D ETH_P_IPV6, + .ipproto =3D 253, + .hash_report =3D VIRTIO_NET_HASH_REPORT_IPv6, + .hash_value =3D 0xd6eb560f +}; + +FIXTURE_VARIANT_ADD(tun_vnet_hash, tcpv6) +{ + .eth_p =3D ETH_P_IPV6, + .ipproto =3D IPPROTO_TCP, + .hash_report =3D VIRTIO_NET_HASH_REPORT_TCPv6, + .hash_value =3D 0xc2b9f251 +}; + +FIXTURE_VARIANT_ADD(tun_vnet_hash, udpv6) +{ + .eth_p =3D ETH_P_IPV6, + .ipproto =3D IPPROTO_UDP, + .hash_report =3D VIRTIO_NET_HASH_REPORT_UDPv6, + .hash_value =3D 0xc2b9f251 +}; + +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 + }; + + struct tun_vnet_hash cap; + char dest_ifname[IFNAMSIZ] =3D ""; + int i, local_fd; + uint16_t ip_payload_len; + uint32_t ip_sum; + + self->dest_fds[0] =3D tun_alloc(dest_ifname, IFF_VNET_HDR); + ASSERT_LE(0, self->dest_fds[0]) { + EXPECT_EQ(0, close(self->dest_fds[0])); + } + + i =3D ioctl(self->dest_fds[0], TUNGETVNETHASHCAP, &cap); + if (i =3D=3D -1 && errno =3D=3D EINVAL) { + EXPECT_EQ(0, close(self->dest_fds[0])); + SKIP(return, "TUNGETVNETHASHCAP not supported"); + } + + ASSERT_EQ(0, i) + EXPECT_EQ(0, close(self->dest_fds[0])); + + if ((cap.flags & vnet_hash.hdr.flags) !=3D vnet_hash.hdr.flags) { + EXPECT_EQ(0, close(self->dest_fds[0])); + SKIP(return, "Lacks some hash flag support"); + } + + if ((cap.types & vnet_hash.hdr.types) !=3D vnet_hash.hdr.types) { + EXPECT_EQ(0, close(self->dest_fds[0])); + SKIP(return, "Lacks some hash type support"); + } + + self->dest_ifindex =3D if_nametoindex(dest_ifname); + ASSERT_TRUE(self->dest_ifindex) + EXPECT_EQ(0, close(self->dest_fds[0])); + + i =3D sizeof(struct virtio_net_hdr_v1_hash); + ASSERT_EQ(0, ioctl(self->dest_fds[0], TUNSETVNETHDRSZ, &i)) + EXPECT_EQ(0, close(self->dest_fds[0])); + + i =3D 1; + ASSERT_EQ(0, ioctl(self->dest_fds[0], TUNSETVNETLE, &i)) + EXPECT_EQ(0, close(self->dest_fds[0])); + + local_fd =3D socket(AF_LOCAL, SOCK_STREAM, 0); + ASSERT_LE(0, local_fd) + EXPECT_EQ(0, close(self->dest_fds[0])); + + i =3D tun_set_flags(local_fd, dest_ifname, IFF_UP); + EXPECT_EQ(0, close(local_fd)); + ASSERT_TRUE(i) + EXPECT_EQ(0, close(self->dest_fds[0])); + + ASSERT_EQ(sizeof(packet), + write(self->dest_fds[0], &packet, sizeof(packet))) + EXPECT_EQ(0, close(self->dest_fds[0])); + + ASSERT_EQ(0, ioctl(self->dest_fds[0], TUNSETVNETHASH, &vnet_hash)) + EXPECT_EQ(0, close(self->dest_fds[0])); + + self->source_fd =3D socket(AF_PACKET, SOCK_DGRAM, 0); + ASSERT_LE(0, self->source_fd) + EXPECT_EQ(0, close(self->dest_fds[0])); + + 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->dest_fds[i])); + } + } + } + + if (variant->eth_p =3D=3D ETH_P_IP || variant->eth_p =3D=3D ETH_P_IPV6) { + switch (variant->ipproto) { + case IPPROTO_TCP: + ip_payload_len =3D sizeof(struct tcphdr); + break; + + case IPPROTO_UDP: + ip_payload_len =3D sizeof(struct udphdr); + break; + + default: + ip_payload_len =3D 0; + } + + switch (variant->eth_p) { + case ETH_P_IP: + tun_build_iphdr(self->buffer, ip_payload_len, variant->ipproto); + self->len =3D sizeof(struct iphdr); + ip_sum =3D tun_build_ip_pseudo_sum(self->buffer); + break; + + case ETH_P_IPV6: + tun_build_ipv6hdr(self->buffer, ip_payload_len, variant->ipproto); + self->len =3D sizeof(struct ipv6hdr); + ip_sum =3D tun_build_ipv6_pseudo_sum(self->buffer); + break; + } + + switch (variant->ipproto) { + case IPPROTO_TCP: + tun_build_tcphdr(self->buffer + self->len, ip_sum); + break; + + case IPPROTO_UDP: + tun_build_udphdr(self->buffer + self->len, ip_sum); + break; + } + + self->len +=3D ip_payload_len; + } +} + +FIXTURE_TEARDOWN(tun_vnet_hash) +{ + EXPECT_EQ(0, close(self->source_fd)); + + for (size_t i =3D 0; i < ARRAY_SIZE(self->dest_fds); i++) + EXPECT_EQ(0, close(self->dest_fds[i])); +} + +TEST_F(tun_vnet_hash, rx) +{ + size_t len =3D sizeof(struct virtio_net_hdr_v1_hash) + ETH_HLEN + self->l= en; + struct { + struct virtio_net_hdr_v1_hash vnet_hdr; + struct ethhdr ethhdr; + char payload[sizeof(self->buffer)]; + } buffer; + struct virtio_net_hdr_v1_hash hdr =3D { + .hdr =3D { .flags =3D variant->flags }, + .hash_value =3D htole32(variant->hash_value), + .hash_report =3D htole16(variant->hash_report) + }; + int txq =3D variant->hash_report ? variant->hash_value & 1 : 2; + struct sockaddr_ll ll =3D { + .sll_family =3D AF_PACKET, + .sll_addr =3D TUN_HWADDR_DEST, + .sll_halen =3D ETH_ALEN, + .sll_ifindex =3D self->dest_ifindex, + .sll_protocol =3D htons(variant->eth_p), + }; + + EXPECT_EQ(self->len, + sendto(self->source_fd, self->buffer, self->len, 0, + (struct sockaddr *)&ll, sizeof(ll))); + EXPECT_EQ(len, read(self->dest_fds[txq], &buffer, len)); + ASSERT_FALSE(memcmp(&buffer, &hdr, sizeof(hdr))); + ASSERT_FALSE(memcmp(buffer.payload, self->buffer, self->len)); +} + +int main(int argc, char **argv) +{ + FILE *file; + + if (unshare(CLONE_NEWNET)) { + perror("unshare"); + return KSFT_FAIL; + } + + /* Disable IPv6 to eliminate IPv6 Neighbor Discovery messages. */ + file =3D fopen("/proc/sys/net/ipv6/conf/default/disable_ipv6", "w"); + if (file) { + if (fputc('1', file) !=3D '1') { + perror("fputc"); + return KSFT_FAIL; + } + + if (fclose(file)) { + perror("fclose"); + return KSFT_FAIL; + } + } else if (errno !=3D ENOENT) { + perror("fopen"); + return KSFT_FAIL; + } + + return test_harness_run(argc, argv); +} --=20 2.48.1 From nobody Wed Dec 17 13:46:03 2025 Received: from mail-pl1-f178.google.com (mail-pl1-f178.google.com [209.85.214.178]) (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 00AB623FC59 for ; Mon, 17 Mar 2025 10:59:03 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.214.178 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1742209145; cv=none; b=JWoFDpeX/FoxmsL77MF4c1XkSghU4CHyUeyTE8vNVLoqWT8k1cuZeqoUcPoUnzGwkxbBNysQY735xWFuZ8+/DaZIA/QJsLSqLMjeSJDoO0lNDDVWYZpPLpPXIp+2wzF2p4Q658lvbso+wEZwM/9aySY+eIx+LWsVaiu1BXl/86s= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1742209145; c=relaxed/simple; bh=ccfXZvxiSAaG5MPb2w/JWrekNXtLfO8PT1kfNykthKs=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To; b=Nu5aKrXJrOtqBoivCYlbYh0VS0gudh4rX0CT4RFBFtSJ4KLU8ashiHCEfYghChl7wJSaOshi5PmBLS0lGbBU5ut3zEBNJmlKupgYQNz2Y59qdZ/mNWHlpeYnMGVV9U7lecaH3NP7n+KV88tlm7aBmkt9KrgQUxj74ehZbUcqyPE= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=daynix.com; spf=pass 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=c1CDWCed; arc=none smtp.client-ip=209.85.214.178 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=daynix.com Authentication-Results: smtp.subspace.kernel.org; spf=pass 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="c1CDWCed" Received: by mail-pl1-f178.google.com with SMTP id d9443c01a7336-225e3002dffso36561895ad.1 for ; Mon, 17 Mar 2025 03:59:03 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=daynix-com.20230601.gappssmtp.com; s=20230601; t=1742209143; x=1742813943; 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=e3BkVPEmJoa+6yr2vocUy5kvhLH0cmr2yCWFD5W/C7U=; b=c1CDWCedPdAaOwlP1q8hJPZKsmOkK4Xj1sUYqPL8e+3+DLupbzF3zRV6yDcpYPOwaS 8VI48468PeJQG6NCjB8pZLV/5kO2mPpURfJZiBLkRhHH+2qQJlQ3TTE5sDHZqUZ5U5TF ZCMBkvEhLW+Cf38uEQiAuh1esJ6DUlOv245Xi7NHTqTJptZFmfMQN4b1LbjjZ4JHLeLY c0faq2d/l4xwY+zORy/sbiRqxU23c12LCgYZBfcmDx3bU2fXniobyukEbSkAODvyzr+S itTOxu+1pOm0BpnQ/RWsFBfH0IT8Z+CnrZz5RwhVN2d3vyTLhoalqkSL47zZ4M2neCQr IeHw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1742209143; x=1742813943; 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=e3BkVPEmJoa+6yr2vocUy5kvhLH0cmr2yCWFD5W/C7U=; b=IAGod6or5TxA9Lcs2bwKBu0V0k+b6/pZ8lvXPFBpId0TDZrAMRqoxqDFU1SEZbQUHb hlEbP5lh+H583eJj8cM+NF8f5aEcRQZhRoCjbqXG/baD3RNnwo7o5a8UAnTg7RDUMEig QE97O5iyTAV5VpdP0C+l9nRnkgDw/nrde1h4GNHPGM3Fu8BmojayulADNUmAa0nhGRhC 9xessQdPBmexr8L+9220Er4KMX74TQjR+uUzcDFE7YABtKaBcAAMKSz0WwNEAneFGhih SdwrpARE6EHEsQzUj+f88RhsoiLLON9o6o8TS6NvyscR9BXV0lDwSUDOVQPWQ9zS7kMR lF8g== X-Forwarded-Encrypted: i=1; AJvYcCVIMRX3z7ujNvgEICS0bS6AsB5FcGidnAxW6WQ2Y100Gq3D9gIjuS95ugqdmWb8DOzx+qDyIGDrDeEPXyE=@vger.kernel.org X-Gm-Message-State: AOJu0YxkRx9w1+w3XRg5yt62C0gmCdsu8OliF7FfDpzwWYE1bJwLbyAw 22fPSp+w36inrHyaKDuMtkj7mW0xw7YIFIU4AXHY09smRLoJDDEbwZGDqtwY6Ng= X-Gm-Gg: ASbGncvaSOVIOg49xAAiN4UQsHydGjGgFNSOhdZM+cYpsklDfLa83O1wJzA4VXnGEtk yLXyoIcqESYkh128OifAu3w0drUmBT5rVlNS2JBbHQ6h5Mj9L8arz1VNrp1vFy4Objmc3ReL+Zb 1qk5YzYIeMa62k79ATMuspcwJZynfv3KAIZ962siGx1pE3JohdLJx426jiPQukrF9jZwYOMoQFS HPiitKRgNreQBr5Pv8p0clRTA/7QB5kcQLvb1cOoB+NHP1TNeguHnigiMeW5OXdFWezreVXPrkA 6dI0VK1Z+rqNdOhTG1mbzCMKybAoSyNuIl44VlJ+ZL7NhI37 X-Google-Smtp-Source: AGHT+IGOao21bnQoF8f7GMJyK43XLi/BXMCK2hiBw4ypcEkYOkj5BsLms/4g5Wmz+GYI5JTnjSMvyg== X-Received: by 2002:a17:902:dac3:b0:224:1ec0:8a0c with SMTP id d9443c01a7336-225e0a79f54mr144040315ad.29.1742209143268; Mon, 17 Mar 2025 03:59:03 -0700 (PDT) Received: from localhost ([157.82.207.107]) by smtp.gmail.com with UTF8SMTPSA id d9443c01a7336-225c6bbcd4asm72044005ad.164.2025.03.17.03.58.58 (version=TLS1_3 cipher=TLS_AES_128_GCM_SHA256 bits=128/128); Mon, 17 Mar 2025 03:59:03 -0700 (PDT) From: Akihiko Odaki Date: Mon, 17 Mar 2025 19:57:59 +0900 Subject: [PATCH net-next v11 09/10] selftest: tap: Add tests for virtio-net ioctls 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: <20250317-rss-v11-9-4cacca92f31f@daynix.com> References: <20250317-rss-v11-0-4cacca92f31f@daynix.com> In-Reply-To: <20250317-rss-v11-0-4cacca92f31f@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, Lei Yang , Simon Horman , Akihiko Odaki X-Mailer: b4 0.15-dev-edae6 They only test the ioctls are wired up to the implementation common with tun as it is already tested for tun. Signed-off-by: Akihiko Odaki Tested-by: Lei Yang --- tools/testing/selftests/net/tap.c | 97 +++++++++++++++++++++++++++++++++++= +++- 1 file changed, 95 insertions(+), 2 deletions(-) diff --git a/tools/testing/selftests/net/tap.c b/tools/testing/selftests/ne= t/tap.c index 247c3b3ac1c9..fbd38b08fdfa 100644 --- a/tools/testing/selftests/net/tap.c +++ b/tools/testing/selftests/net/tap.c @@ -363,6 +363,7 @@ size_t build_test_packet_crash_tap_invalid_eth_proto(ui= nt8_t *buf, FIXTURE(tap) { int fd; + bool deleted; }; =20 FIXTURE_SETUP(tap) @@ -387,8 +388,10 @@ FIXTURE_TEARDOWN(tap) if (self->fd !=3D -1) close(self->fd); =20 - ret =3D dev_delete(param_dev_tap_name); - EXPECT_EQ(ret, 0); + if (!self->deleted) { + ret =3D dev_delete(param_dev_tap_name); + EXPECT_EQ(ret, 0); + } =20 ret =3D dev_delete(param_dev_dummy_name); EXPECT_EQ(ret, 0); @@ -431,4 +434,94 @@ TEST_F(tap, test_packet_crash_tap_invalid_eth_proto) ASSERT_EQ(errno, EINVAL); } =20 +TEST_F(tap, test_vnethdrsz) +{ + int sz =3D sizeof(struct virtio_net_hdr_v1_hash); + + ASSERT_FALSE(dev_delete(param_dev_tap_name)); + self->deleted =3D true; + + ASSERT_FALSE(ioctl(self->fd, TUNSETVNETHDRSZ, &sz)); + sz =3D 0; + ASSERT_FALSE(ioctl(self->fd, TUNGETVNETHDRSZ, &sz)); + EXPECT_EQ(sizeof(struct virtio_net_hdr_v1_hash), sz); +} + +TEST_F(tap, test_vnetle) +{ + int le =3D 1; + + ASSERT_FALSE(dev_delete(param_dev_tap_name)); + self->deleted =3D true; + + ASSERT_FALSE(ioctl(self->fd, TUNSETVNETLE, &le)); + le =3D 0; + ASSERT_FALSE(ioctl(self->fd, TUNGETVNETLE, &le)); + EXPECT_EQ(1, le); +} + +TEST_F(tap, test_vnetbe) +{ + int be =3D 1; + int ret; + + ASSERT_FALSE(dev_delete(param_dev_tap_name)); + self->deleted =3D true; + + ret =3D ioctl(self->fd, TUNSETVNETBE, &be); + if (ret =3D=3D -1 && errno =3D=3D EINVAL) + SKIP(return, "TUNSETVNETBE not supported"); + + ASSERT_FALSE(ret); + be =3D 0; + ASSERT_FALSE(ioctl(self->fd, TUNGETVNETBE, &be)); + EXPECT_EQ(1, be); +} + +TEST_F(tap, test_getvnethashcap) +{ + static const struct tun_vnet_hash expected =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 + }; + struct tun_vnet_hash seen; + int ret; + + ASSERT_FALSE(dev_delete(param_dev_tap_name)); + self->deleted =3D true; + + ret =3D ioctl(self->fd, TUNGETVNETHASHCAP, &seen); + + if (ret =3D=3D -1 && errno =3D=3D EINVAL) + SKIP(return, "TUNGETVNETHASHCAP not supported"); + + EXPECT_FALSE(ret); + EXPECT_FALSE(memcmp(&expected, &seen, sizeof(expected))); +} + +TEST_F(tap, test_setvnethash_alive) +{ + struct tun_vnet_hash hash =3D { .flags =3D 0 }; + + EXPECT_FALSE(ioctl(self->fd, TUNSETVNETHASH, &hash)); +} + +TEST_F(tap, test_setvnethash_deleted) +{ + ASSERT_FALSE(dev_delete(param_dev_tap_name)); + self->deleted =3D true; + + ASSERT_EQ(-1, ioctl(self->fd, TUNSETVNETHASH)); + + if (errno =3D=3D EINVAL) + SKIP(return, "TUNSETVNETHASH not supported"); + + EXPECT_EQ(EBADFD, errno); +} + TEST_HARNESS_MAIN --=20 2.48.1 From nobody Wed Dec 17 13:46:03 2025 Received: from mail-pj1-f51.google.com (mail-pj1-f51.google.com [209.85.216.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 A8C8C241669 for ; Mon, 17 Mar 2025 10:59:10 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.216.51 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1742209152; cv=none; b=XNwmO5W7asT8Co8RMCKjW81NFLmViTlB51NLNbEGeElXjAl3CgUB4oiCEsSYqh+ct3v76Zyu1nDVPEJX5tyfCBJE1WHbKJOLSQA/vW3LED+bFZko5npJywcVyAsz62ntNPY+H4Ir/G7ed34LgBUv0ZIPOBd7L+oCmNXWJMn07Bg= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1742209152; c=relaxed/simple; bh=QysKwJMoIqaKFtrng8JoZjRW/Qn7QIvbuXMh0UY/638=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To; b=DHZ+HBOt6mlFXOz3eCLhwjLVb8WxWwL/5gUyv8OoLykh+1lHZkkFbxTzfl17UeoGoHk3s9yvX7iys2dwC5FKp0+8L8Q3MXg/bgYq5vdy8Dn+PDXsDevHYaAJOpR5DHMgAQsAP+BRzV9ol1C1075VX17A+P+Miwpkr7XD0AcFeY0= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=daynix.com; spf=pass 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=LoD68JKl; arc=none smtp.client-ip=209.85.216.51 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=daynix.com Authentication-Results: smtp.subspace.kernel.org; spf=pass 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="LoD68JKl" Received: by mail-pj1-f51.google.com with SMTP id 98e67ed59e1d1-30155bbbed9so2151285a91.1 for ; Mon, 17 Mar 2025 03:59:10 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=daynix-com.20230601.gappssmtp.com; s=20230601; t=1742209150; x=1742813950; 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=jXhv781+liPB0AwwevhkbIFrQwob4kiywxMETbO/hoM=; b=LoD68JKl8vo/f2E53adWY+nT0lJpYRv7solt6X2M90zVKUCGQ5miR5UzpTebBm96kW juy3XY+96hrDCHov9P+9mXpeV5MU9KtxFtm73dHz9S0s9ZNCVJram1rWphZNkzP4psT0 XrGHY6zAL4xuapVEWyLA86OdW149Gs1foDmlREc3uuAxlcIX7JPGTScIiT6NSdZrKjfJ NgYU1JlFtSU0jomtYVVN8BAqqZvJ16QQA4LiN0gBNYCnPfVJTIHMAXGwRPIA/n+jKYoW X4yKAWamOIJY/xFuHZX/eUEFwM3ig8oS0zzaNveOrZJLpIPv+ID2kMEDPPQF/1j1wPW0 s8lg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1742209150; x=1742813950; 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=jXhv781+liPB0AwwevhkbIFrQwob4kiywxMETbO/hoM=; b=XhHWHJwM1thZh7KPB2QOIBBqyDyFr9eEhMDia79xyvhdakyoqgg2uhR9EoVwr8SBLQ z9iLMhmW06kUIf2iP/SrBsZB8ZvXin4DO4+LoVcX+5klWrvMpKF5J7plgHEsYqAIH8uD AqEGVlkm36wywbRoMNeTFcQA5qyLrUrFVCrUJdq5X/1GMHo0paqAKe1CNvy8Sy5WS0lx r1Tz+HzjKCPejdIfhwHmjBZB6LfDtrsgK8GuAobeulNH29x9gAGP0mr3AS270vOwMBUO xpmOfmhwRzGNcSbWx6fvxptopFxKSe/frqXytPLeIDzxsfUqlqWUsMoud/ycPCWqWvoe vZww== X-Forwarded-Encrypted: i=1; AJvYcCWKXzDPM9sBS17yNnUYFLPiApjO+TcHNYmGhz3zq2F3mvWB341xuH+RdJJs9c6zubBQqlREUPwNM0h8Ct0=@vger.kernel.org X-Gm-Message-State: AOJu0YzfzVy1jxN6cQ26zNnFrBbMtGz5gR2VHxeLlCgEkAA1wZKFRil7 HUIyhCdiqnLZoqLZul7nGB9h2cWi3dvwbYKcJO3t2fVny7R3pCKZiZkn80tz65c= X-Gm-Gg: ASbGncvxGLAEQhs9vdJkqTOdFAglmDDLwO4CV26bkG+KnuR0MyY1V94ilTeB6KGSw/z 8YKh6HlKJQpSd5fd9Audc2Z4FNXR1J+1Z5+zXgAKKgQPI4JAkHuoU4JIg93q2zYrkJPHBVf8XkH KDx0ItL+AdQvFgsLHe4RPNnoRxHtdJmko7nR9GO+0HjJFrTsa0PsvXPEyQGNKCzKgRf17L11OPM PqcVAGB3VVk8Tskg/fVVuQLRBPXFoV4eIVfD846P5a5mhbNgT16yjjGTCuFt1WzmsM4L9blz6Oz jdG8OlrRfp6UbooiFBoPDblRGfbFsOQgvTIMO0zyDXFx5A+n X-Google-Smtp-Source: AGHT+IFBTzBt4W91RO9hEmwf21fzT3s8Bp70zxhXco8GCOaNp4xUeMJNMRSu3auEGTPJcF2HKgGT2A== X-Received: by 2002:a17:90b:5347:b0:2ff:58c7:a71f with SMTP id 98e67ed59e1d1-30151dc7588mr13016176a91.32.1742209149802; Mon, 17 Mar 2025 03:59:09 -0700 (PDT) Received: from localhost ([157.82.207.107]) by smtp.gmail.com with UTF8SMTPSA id 98e67ed59e1d1-3015364ec6esm5760309a91.49.2025.03.17.03.59.05 (version=TLS1_3 cipher=TLS_AES_128_GCM_SHA256 bits=128/128); Mon, 17 Mar 2025 03:59:09 -0700 (PDT) From: Akihiko Odaki Date: Mon, 17 Mar 2025 19:58:00 +0900 Subject: [PATCH net-next v11 10/10] 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: <20250317-rss-v11-10-4cacca92f31f@daynix.com> References: <20250317-rss-v11-0-4cacca92f31f@daynix.com> In-Reply-To: <20250317-rss-v11-0-4cacca92f31f@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, Lei Yang , Simon Horman , Akihiko Odaki X-Mailer: b4 0.15-dev-edae6 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 Tested-by: Lei Yang --- drivers/vhost/net.c | 68 +++++++++++++++++++++++++++----------------------= ---- 1 file changed, 35 insertions(+), 33 deletions(-) diff --git a/drivers/vhost/net.c b/drivers/vhost/net.c index b9b9e9d40951..fc5b43e43a06 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) }; @@ -1097,10 +1098,6 @@ static void handle_rx(struct vhost_net *net) .msg_controllen =3D 0, .msg_flags =3D MSG_DONTWAIT, }; - struct virtio_net_hdr hdr =3D { - .flags =3D 0, - .gso_type =3D VIRTIO_NET_HDR_GSO_NONE - }; size_t total_len =3D 0; int err, mergeable; s16 headcount; @@ -1174,11 +1171,15 @@ static void handle_rx(struct vhost_net *net) /* We don't need to be notified again. */ iov_iter_init(&msg.msg_iter, ITER_DEST, vq->iov, in, vhost_len); fixup =3D msg.msg_iter; - if (unlikely((vhost_hlen))) { - /* We will supply the header ourselves - * TODO: support TSO. - */ - iov_iter_advance(&msg.msg_iter, vhost_hlen); + /* + * Supply virtio_net_hdr if VHOST_NET_F_VIRTIO_NET_HDR + * TODO: support TSO. + */ + if (unlikely(vhost_hlen) && + iov_iter_zero(vhost_hlen, &msg.msg_iter) !=3D vhost_hlen) { + vq_err(vq, "Unable to write vnet_hdr at addr %p\n", + vq->iov->iov_base); + goto out; } err =3D sock->ops->recvmsg(sock, &msg, sock_len, MSG_DONTWAIT | MSG_TRUNC); @@ -1191,30 +1192,24 @@ static void handle_rx(struct vhost_net *net) vhost_discard_vq_desc(vq, headcount); continue; } - /* Supply virtio_net_hdr if VHOST_NET_F_VIRTIO_NET_HDR */ - if (unlikely(vhost_hlen)) { - if (copy_to_iter(&hdr, sizeof(hdr), - &fixup) !=3D sizeof(hdr)) { - vq_err(vq, "Unable to write vnet_hdr " - "at addr %p\n", vq->iov->iov_base); - goto out; - } - } else { - /* Header came from socket; we'll need to patch - * ->num_buffers over if VIRTIO_NET_F_MRG_RXBUF - */ - iov_iter_advance(&fixup, sizeof(hdr)); - } /* TODO: Should check and handle checksum. */ =20 + /* + * We'll need to patch ->num_buffers over if + * VIRTIO_NET_F_MRG_RXBUF or VIRTIO_F_VERSION_1 + */ num_buffers =3D cpu_to_vhost16(vq, headcount); - if (likely(set_num_buffers) && - copy_to_iter(&num_buffers, sizeof num_buffers, - &fixup) !=3D sizeof num_buffers) { - vq_err(vq, "Failed num_buffers write"); - vhost_discard_vq_desc(vq, headcount); - goto out; + if (likely(set_num_buffers)) { + iov_iter_advance(&fixup, offsetof(struct virtio_net_hdr_v1, num_buffers= )); + + if (copy_to_iter(&num_buffers, sizeof(num_buffers), + &fixup) !=3D sizeof(num_buffers)) { + vq_err(vq, "Failed num_buffers write"); + vhost_discard_vq_desc(vq, headcount); + goto out; + } } + nvq->done_idx +=3D headcount; if (nvq->done_idx > VHOST_NET_BATCH) vhost_net_signal_used(nvq); @@ -1607,10 +1602,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; @@ -1691,6 +1689,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.48.1