From nobody Tue Dec 16 11:07:29 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 DCFA61EA7C8 for ; Fri, 30 May 2025 04:50:31 +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=1748580634; cv=none; b=VXJ5do7mWQlAeAEM+3QaTB9joY01huJrMOjilKJ85SzdVTt6EL+TmHXsNRIaU/0qu1gvvQ2s2Vgne6xjPPpm3SWUa4+VGL8MjX+9IP9jCJFmgQrDcmvZbC2QucAqdsBb0oYus3wCQSbjgOryZufUacwx3zFyAa5kz1qkOfOkFFo= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1748580634; c=relaxed/simple; bh=CpwWOgMsm/OZT3937W9rk6eOzhNasmHSrd3RW1OTmJg=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To; b=fFjQmJDMj1jXxiujiHylsUxdNfbQV/j1Db1AhHciOV9fwFjc5iStCTKIeZPmDyhh/BFfv1SYizue90GTfkUDuFDLbXWdD72vXDmZL9HPNyQvsVtHpYMs0SStChezm9IY4QQCuR+W6NTgUDQAQcUS9hR4T8ZpZEPTU+0N7d7o9c4= 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=VfNyqvUJ; 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="VfNyqvUJ" Received: by mail-pl1-f176.google.com with SMTP id d9443c01a7336-234ade5a819so15737045ad.1 for ; Thu, 29 May 2025 21:50:31 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=daynix-com.20230601.gappssmtp.com; s=20230601; t=1748580631; x=1749185431; 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=mHnfvnG+4Uo3t8TPfZRHr3K4Ni/XzCT0y+M5pUCTpQQ=; b=VfNyqvUJGYq6JevizohHg1C6k8daLCA0AUbBLcVvYZ7iomfw48cdxRPA/jMtgstdkH 2YxiRcMV+CU5JCYzHyQ9yjA/bp40GYMNHl11Sk/5k7JFLDa+c84BpMmalrx+Hjaj6HfZ Bqfdw3FOKQWXpc073szCOUjDZY++RsdlixH2YreGoUJqDZ+2osqKmTNMx9s9xq5AouiJ XfWWmiVA6bwbvwZDrpXHdHdX32Atl0o4rkyzjcDxIe7As9YTAkt2WxCHhMT+cdHTa9GB psIAsiXk6ajOIQv7KpGUHT+I5XEYT16b4w/5a0x2lxrtxvqPDEuTK/G5ahWPZwHsEPl/ Opvg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1748580631; x=1749185431; 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=mHnfvnG+4Uo3t8TPfZRHr3K4Ni/XzCT0y+M5pUCTpQQ=; b=ixfB/bTCJRghdKTMHo3/MMWdwmE7ZKb40wl+uM/550j1/bbP7KCDryI/rIkPRZQHNu J/wtPUQTJclLNT134WniYlQ+Ky2o0L2tJWkfSaEmgKbbzwqV0GvYZjoteSttsRA/FUlp c3mnW7FCHFI6BOvx40NhMVT7d1le1lCj42TwClqqUxZC/K/TYrZu6AJHPAxKdKrTTLac cW0fD02idS/lmT/2NmqZmM4bbVQDTDTXKdSZoFcOBPcXKMTC+UNGarlCCUyFkBOmfw5v YwejhdUyFldBRBew3x7qmEz83GlpIRJlWPx7Ucudgh7kbYpPjXQ8y1G6cj+dON3UFgVJ 1XBw== X-Forwarded-Encrypted: i=1; AJvYcCUmzf3Hho79MgpUvy9rykwCA5xojt6JkHIyzRWU7DqngSURBZdCCT6hUIK/6l3ehznyamtpi5kiR2Rardk=@vger.kernel.org X-Gm-Message-State: AOJu0YyzG6yHUoIloWrTVoYcO2VGk2raFX1zgTS8nAF8sysvZRnRdW4S obFgF/xkSjiPlQCWK63oKxqxLFl0UySzZNROVKpkSkErDdtFqziDFYVHSgb1VxoGuqc= X-Gm-Gg: ASbGncuFPv+9uQzM8hbLs2euyK6r81qiOqZ3M939anX9v1YwVy9Ytfq2YueNjYEGDjl 5iorC/QTYb5pSZjI8CzUf0QPGoM2zVh20xiuyyr/nscaBvuFOxqxv75WgWcQOYrfcPUU00LFcDD Turz42dvZFV88W1OHxHShazye7CC9+6T9NVqWkkVqZx9NIJH/WON7d0F5ICRzRVv+6UcGD1LIN8 44y+boOswr3YzvKJQz2ys9V5rTTlItLppecGq2rqjS8pg5bid3RX8TKMIliCL/XFbIkAy9jWk8m rw6ivb+dibMDJfQmtHn1tWlegT2hi99WT1GrRAM06gPP3HqgQnm8 X-Google-Smtp-Source: AGHT+IHdRfH8fCi0v3+1OrVYLvC/V/phLFEiiBn6Jqn306OPc5AEWzU0GjWHNjTZTDzuRLLVt3QlaA== X-Received: by 2002:a17:902:cf03:b0:234:a734:4ac8 with SMTP id d9443c01a7336-23529d7c296mr31091015ad.36.1748580631147; Thu, 29 May 2025 21:50:31 -0700 (PDT) Received: from localhost ([157.82.128.1]) by smtp.gmail.com with UTF8SMTPSA id d9443c01a7336-23506cd372esm20038285ad.128.2025.05.29.21.50.28 (version=TLS1_3 cipher=TLS_AES_128_GCM_SHA256 bits=128/128); Thu, 29 May 2025 21:50:30 -0700 (PDT) From: Akihiko Odaki Date: Fri, 30 May 2025 13:50:05 +0900 Subject: [PATCH net-next v12 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: <20250530-rss-v12-1-95d8b348de91@daynix.com> References: <20250530-rss-v12-0-95d8b348de91@daynix.com> In-Reply-To: <20250530-rss-v12-0-95d8b348de91@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.49.0 From nobody Tue Dec 16 11:07:29 2025 Received: from mail-pf1-f170.google.com (mail-pf1-f170.google.com [209.85.210.170]) (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 D6BE52010EE for ; Fri, 30 May 2025 04:50:35 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.210.170 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1748580638; cv=none; b=jYcmJDgPXPg1sHD09peZ8PDr08QvSLPBvOr6rJXllFrHpKplBD/9HSruYfJP+8w9ig4hc/KmRB1mZXC2YHiRd37DsfXWdpZON2QOlKDOQijtL/Cy33SEMOPBAn69yyUSijPuZfcx6RGPF15qPznE1d/ZtJk0b9+PfuoPqeEPTHo= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1748580638; c=relaxed/simple; bh=2oUMDnIBYoOmxLZqcn3thZSyZ/SbegpNqOzQC+cCzEg=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To; b=IWOK6ePIv2s2/8UIrHlkR6xyUWR1sN6dE0E3mI6mVrV5jtgxlkyUnNZ44k8Ck5TxGrevpt+Ai9ALelq28DtdnC0Ul/H0DEq8qDR7fIuvapVVyle2devedggthNmrZctDvWwErgYbOf3YqQRQE/beHrwMx9UVa5uOZRc3Zp7iVY4= 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=p0jMeCwR; arc=none smtp.client-ip=209.85.210.170 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="p0jMeCwR" Received: by mail-pf1-f170.google.com with SMTP id d2e1a72fcca58-74264d1832eso1687101b3a.0 for ; Thu, 29 May 2025 21:50:35 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=daynix-com.20230601.gappssmtp.com; s=20230601; t=1748580635; x=1749185435; 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=RTqe1YGUMZdFRvXBjnIPkdBxtf7RTeZ/o279FoAQM6o=; b=p0jMeCwRTCl3QbpKCZ0PeAx4iBbKOypHeipYJ1LbfO5JLAbEZH7aXtAZI4aV4tPGs0 AGujK3Dx23/n/XtwrMEFpH+Cvg5VWG9OrmMDsldqPzqEN/8i/EZKWu1Vta75nj8BUq3V g2DEZoI15jzk2MOqK7mMoJVEf+aev6sa2KsOlBi+xuVf7lhm7FdzoycMqLMsRzWojcZU Oeo7hFtAGGlQNIYuNurIAVyHXawBLnnNpvaLQyFrCbP5tF3KLQiFWSHZiK4I/YRa5XDw Qe0AFjJPjzZicbMyddnsG85mDrb2o2pOrEeewQ/kCHnsx3oN9x5F7oq7vPtsYfIUu968 9BAQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1748580635; x=1749185435; 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=RTqe1YGUMZdFRvXBjnIPkdBxtf7RTeZ/o279FoAQM6o=; b=TTLmfD1O4O8xtU+mPinlgPlLQfazddY2O0Jv89vcQZ9MvZLvWvYROALW8OvWoNoTEx qsOJoAfTsLy5gm/zTDZofJXYNQ/0SH6YIXxAeU/883im8Wl5xqh32VwH1NZWQFvmV2NO 6+MjHEEpkU2iYcAUa/IQfN26oRMKE58qyOYWYjC8CYCe7T2GEGvQZIM86ANF9evI9q1B wrmOAF0VbrVPOllDa8cUFaTaZGpIGgeMU4+LQxoFrTyX4R8d5iZ+1mw/kaWgpiqDVOB9 wMMrZyPLcZCFE0HzbtYBh4TO7I1cXpEQewO/YuneiadD14QF56mw2C6891Uah2cYu527 l4rg== X-Forwarded-Encrypted: i=1; AJvYcCUUf5Sogy8JZEUfuMHMH7+uYy8Q7D89gfUTcWv/EhBEit9uzZoHN46B+gGFGsRxdcjQech0SH2oHEvnjEw=@vger.kernel.org X-Gm-Message-State: AOJu0YxcT7zuIHorTja6BbrOw0+23WlAk9tJzGX+2kaiL+zREGrXCKLF BGMmibAy1DKRwgsgbW1i5DH3Qw5GmjOTpGyaKbPsLyxULOx5MXtdbzSwkmAV3xogfKE= X-Gm-Gg: ASbGncuMlvXeXh+UdGex3vwexT4YaUbcGsplAGzSNpZJ+jdHZPvRJQgPhE7ucg3y/C+ VAeLvmeZAX0bbrFOWO3goinGwMnmRsxelhH9GXStUV7pJ4Dh5HVgJAfoWPtBnvtYumYh98HDC8r +/veWQEbfiy1ttXEEHx8nUofyEluRMveOEyTKbXxanCJrE6cUmTRLo5/mpyAZK/4qYDr8cogOcX crsRMR2SubacdPOgVn0aFq9NC6XBEyoXII/Fto0XATsOzHHQ8gloa0HbbLPb74Pczn7lHqqrFf3 9aD6f/+37ePeyRwnNAOCQTOZOsyD+aO7Rt/EQru4Ljs+uWOT5Z90VapX2p99auU= X-Google-Smtp-Source: AGHT+IECFVZeba3N9ihXZ5rbjNszUdlvoohjDNehjvfvwHvZL080L1tWJfpWoXRRwXkMbrFpkWtKqw== X-Received: by 2002:a05:6a00:4b54:b0:736:5e6f:295b with SMTP id d2e1a72fcca58-747bd97b301mr2912852b3a.12.1748580635197; Thu, 29 May 2025 21:50:35 -0700 (PDT) Received: from localhost ([157.82.128.1]) by smtp.gmail.com with UTF8SMTPSA id d2e1a72fcca58-747afeab6bdsm2179867b3a.37.2025.05.29.21.50.32 (version=TLS1_3 cipher=TLS_AES_128_GCM_SHA256 bits=128/128); Thu, 29 May 2025 21:50:34 -0700 (PDT) From: Akihiko Odaki Date: Fri, 30 May 2025 13:50:06 +0900 Subject: [PATCH net-next v12 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: <20250530-rss-v12-2-95d8b348de91@daynix.com> References: <20250530-rss-v12-0-95d8b348de91@daynix.com> In-Reply-To: <20250530-rss-v12-0-95d8b348de91@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 Acked-by: Jason Wang --- 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.49.0 From nobody Tue Dec 16 11:07:29 2025 Received: from mail-pl1-f174.google.com (mail-pl1-f174.google.com [209.85.214.174]) (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 2BCD220E715 for ; Fri, 30 May 2025 04:50:39 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.214.174 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1748580641; cv=none; b=Fnm/XfDyMfK+RZ58DlJCVuIEVbaYGMOi/nWAGvauvPArdiC4c8n6EiugOVTseJ8NLUK2BPjHuGykJgXskdA/rWloLgNO+s3w5/sPv1VBOtuKP3fFw2wAobfonsnhVkF+GI8r6niD/CjJvxwF8DMDKbqfbaALnaQcWbR7kz1PfYE= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1748580641; c=relaxed/simple; bh=z6KshIl6HGgt4ZleKE35r87QcaFqdHr3p/xqcA1UR5o=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To; b=rL9PK3QmEexJt7L+F7c6mfYjGEU9M4UCk+JKRFCoaSIRE6OkpO2w/+9knnEzF8HITgugj9chwSRXy1jEsMhxhdC5BVZCQj70A4CQRa9ol8TL8jJGxK4wxMqTZCnsdmqxZVQmuTztVxKsOlYT6922dJvov3jGGCqgNfyMqJWyHmo= 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=br4sWy7K; arc=none smtp.client-ip=209.85.214.174 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="br4sWy7K" Received: by mail-pl1-f174.google.com with SMTP id d9443c01a7336-2350b1b9129so8445435ad.0 for ; Thu, 29 May 2025 21:50:39 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=daynix-com.20230601.gappssmtp.com; s=20230601; t=1748580639; x=1749185439; 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=2NOE/sRdLPMAnoL0j8jc6LLcC7i1+AiTcrUdSGiZf/w=; b=br4sWy7KqNVoAgmcfCZJRLKTceBgSCS3Ojitq6wElltSfRuLU1olzE7rjNrzZ37fMG M9JdZpXgGc3qHrXSVASAuFp8aPiCuwnqde3PWJW2Q7iEnwY8LaQATGX9XcHJQ2pbSdlo 1Lry4qaLIhiFZUtFSjRUpQvhH5Fvi+TNQNo5ABN6uhXH916k67P6jgKZnGzUZtgpJBtn +DZKsITiQOcROBxpM1cCjX11Ag0B0jyNRKxb1zlmb61dHNfWEw3sKdU/waD414CmZVqe YNmnpKlnH2MQp1Kq8z7GKWGuWk32hLhaoxbHjm+E8Y7Db9kuKYt8fzwXbH4KrXIJWWPv sOcA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1748580639; x=1749185439; 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=2NOE/sRdLPMAnoL0j8jc6LLcC7i1+AiTcrUdSGiZf/w=; b=AZidkhncf0D9is43h9XKypqs4oyQRtC7BYabT1dHYzwLHPaHsAlsO9lWSlPmmKksDE 6cjwjtd2YJQQUvW48WDq9VBTyN3Bn9JYrJEInTcGKp5VvtyC63rihkeA9STee+C4r7Wq 9rsOrGYGnG5QLbyW5tQVJ9IIjJe6wupJZXkqnYaYkQCG/hpGiQN2ybKg4AUDSvMMrUJi FbS71yc4AICCAT/v5UpHIJuIddBnhgy6dtJrBVuoWrlYo185iA+PB6bQrle9hSLDqWXk alOGJRojoBBTbuVB2EWkJ3vE+gj+bEl0SjCkf6lG8t+xXh7nu5RkQElUQefbVzGTvz3Y Oizg== X-Forwarded-Encrypted: i=1; AJvYcCXTRanSFqqeTBX3ECxaxZU5yXqjHcBiC/wS5oNHbs78Pg5n2Sp7BtRfujhbvRTCmV0s9ku4sDnlI/uFo8I=@vger.kernel.org X-Gm-Message-State: AOJu0YyPaQhysResBhL7h7V81hU+E495dv7ZAfkvyBsVwJW8dGh0y6B9 bX4i22AlgpiMNJoQwmnJ0uoC+yLTOI+jQcj6kv1bc8x6yQi3tbVhf26aK3Een0wzOrg= X-Gm-Gg: ASbGncv9JqQKWlgkqezTxCPtirktTHxNChFtjepD4OQGFyP0IdSqOa4DMGa4kFQj5aa h+pTsqrMCmTF07KGhsChjVl9yYEFtC2/x2tKoBkGyly99lw2MD7uq1grgUO552hJAi8RHYjAPrI /hchv/dyubGyB6itX3isEEr2yiQqWy9Dc+qxuazi6c52780feD6C2vMUUwC2XG9Njv2nbb4lKtc ihbaBgTI9UL6Kvs7xkbZ39lFxBd99wwr1MAnoVYryYUAp10FzaZEJW+jLJVrLyvVAPPx2GMmo1C fkA/6/1h3fzvxETRGAZjwrzjLqxObhtvuEzRBSPEoL445nSGooyy X-Google-Smtp-Source: AGHT+IEeXcvMFrg0nyBJT3UCjMm5zR9avBrulDbs9crdoWtGa6Ob/x7/c2QyfE4WnvmKLh1jLX4/8w== X-Received: by 2002:a17:903:2f89:b0:234:eb6:a35b with SMTP id d9443c01a7336-235396e2b3amr13431015ad.44.1748580639345; Thu, 29 May 2025 21:50:39 -0700 (PDT) Received: from localhost ([157.82.128.1]) by smtp.gmail.com with UTF8SMTPSA id d9443c01a7336-23506cf9181sm20055655ad.187.2025.05.29.21.50.36 (version=TLS1_3 cipher=TLS_AES_128_GCM_SHA256 bits=128/128); Thu, 29 May 2025 21:50:39 -0700 (PDT) From: Akihiko Odaki Date: Fri, 30 May 2025 13:50:07 +0900 Subject: [PATCH net-next v12 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: <20250530-rss-v12-3-95d8b348de91@daynix.com> References: <20250530-rss-v12-0-95d8b348de91@daynix.com> In-Reply-To: <20250530-rss-v12-0-95d8b348de91@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 --- 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.49.0 From nobody Tue Dec 16 11:07:29 2025 Received: from mail-pf1-f175.google.com (mail-pf1-f175.google.com [209.85.210.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 6ECB621421F for ; Fri, 30 May 2025 04:50:44 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.210.175 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1748580646; cv=none; b=kQxDqp5yccBNhHqsvByqV7pVNDDEEctA2VaFlOz01ovxnaPkwkjWU91hQgdh10j2BLVDtsozzzwYXdPLjadjMe582P7+Gupoi1rKocbALOBHlbhhwF0eTbBqX7CdypVrXjioOH+03zPsk/+gWtivAiJTA+qTfiatZct7FPhaMCg= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1748580646; c=relaxed/simple; bh=pLf6jUwMzbKvS7onpumYZPr9TV4M8Ko3oz3le5/fTkA=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To; b=T07CsLfMhCb4//JMrMEaPaUdkVrW133FmrLwPQZyjP6IVxIh8f3GlLQ3kLYpbDETpM9zpqrMAgBg2e7R9SzYOqYIbsKTIDI1Ni07I2UHw/LB17v2KfKehaawAAzLXNG3f6s7XLUU1vCmxoFn9Wthgy5g+PZpSptYF/FZoae0t5Y= 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=mij+rkFN; arc=none smtp.client-ip=209.85.210.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="mij+rkFN" Received: by mail-pf1-f175.google.com with SMTP id d2e1a72fcca58-742c5f3456fso1272142b3a.0 for ; Thu, 29 May 2025 21:50:44 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=daynix-com.20230601.gappssmtp.com; s=20230601; t=1748580644; x=1749185444; 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=1bliiQKeeAnovPvWkPG7+CPn/Ly6UtOvnXFU0X7rvR8=; b=mij+rkFNp0HJj3XM9Xj5sLEydn4ir+dv+2vztZ+qhlMRREfJJC16mOzpNcWkepd9LA HQ5b2J1FDfjsIMtibapWIk25orvloZ76gxe89+p2lLDsDLxY3+lpNpDrQRpfhQONoGof XWuDZoycTSW+UceX3Te5bvJ9cT1rXFNvM7erZ592t/UpDlM0XTv07VqCZNKewdzLbQbp Re9Ed33I83ule+U/QRulNVdmXM3u4rvxqOqlPbsNS42P3z+N1jpqsQl8XbsYkmMmEFsR 8Fhru9y+qInJsVZxPAL+K0Iyp+qpwg71ivQQxMYy00V1/LM3BmvUeZ6lI3iTO+MEpOQ4 U2CQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1748580644; x=1749185444; 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=1bliiQKeeAnovPvWkPG7+CPn/Ly6UtOvnXFU0X7rvR8=; b=VR4e/JfA7vwDieL6whnfAGkm7VbL9uLrpEXcwiooleylrBQGr7MTHexpXGFH3ZMWXI GQ93v7cg6oJpLW65q8r0UCGODOwhtwru4GiH7yMmMw8rE/XyW7acjmHRz9i6gl5e7wzv ng08zyNbB03dKGbylSC7txqFNJOvluN7gRyVjICxP2ElmPUsPyt9DI/O+PF3vXk7eYMg EGrpBmwMsd9+YsFgXKRduqs1XkLY3OGlLJMqqswdl6EhmYl1Q903zqTYxUAvSiwmMjlO 42J9roB6FkhEadS1KiqQd9Hl3wgNKlrABME12mmx8dwPXEdPGJuGzTizIkQH4YRZ7512 pd9w== X-Forwarded-Encrypted: i=1; AJvYcCXG2JxdRd1NWTtCSxDaKhxJsVIb9nknkAIofVHiDrOoRvFOg45xxkFfSxf6pm3SdMk0obum7bUYX2QyeJk=@vger.kernel.org X-Gm-Message-State: AOJu0Yy3QRT8O1JcNBpUM+VnyuKAdznl7x7Na8fcLwjw2dQeHcNnp2wx sc9a/LZWpUPvru+DZvGWMFKp1Ck1o6vga9VPsCdfGU5MnzgYI5bu+90nptjrn406XU8= X-Gm-Gg: ASbGnctGZuibD8nzYQQGJ4FZ1gTmYKUMtAvKX/ekdbuFw/7r+jmvvY3WYgAcX2LRfKC rHnjRoLZ6PWkZlZKES2SG6woxMKr3qkElHX1zIHogPbp5QT0sf+hpd49yBzakksxuGBAYxbF7Vf qg138uuiE5BWj0Ft/RFXbe8XqmC6ba4rX5Kk9jLtCYycoTRI4eV6WSvXuLF0Z0DZwwFw04w4G+T jB/KaB6VdTCVpZhdKIZYHcnA844LKWJJBFHCwmIWEy5I39Tk2LjdoTjZJp6iTcatFVXUf+DABuk TqF1mKQcAvDwKNz9vuKtZklMJUibKrwHlVNUC96uZfrYWTORLVV6 X-Google-Smtp-Source: AGHT+IH6w6wgJ+lEr9cseVqB9SEtKbAXzFrBj+vCbQrpLi9MlTf7rPogj7hu0BIsDE96/NgNWbZVcg== X-Received: by 2002:a05:6a00:2d08:b0:742:9fea:a2d1 with SMTP id d2e1a72fcca58-747bda1ad23mr2619324b3a.23.1748580643683; Thu, 29 May 2025 21:50:43 -0700 (PDT) Received: from localhost ([157.82.128.1]) by smtp.gmail.com with UTF8SMTPSA id d2e1a72fcca58-747afeab6bdsm2180078b3a.37.2025.05.29.21.50.40 (version=TLS1_3 cipher=TLS_AES_128_GCM_SHA256 bits=128/128); Thu, 29 May 2025 21:50:43 -0700 (PDT) From: Akihiko Odaki Date: Fri, 30 May 2025 13:50:08 +0900 Subject: [PATCH net-next v12 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: <20250530-rss-v12-4-95d8b348de91@daynix.com> References: <20250530-rss-v12-0-95d8b348de91@daynix.com> In-Reply-To: <20250530-rss-v12-0-95d8b348de91@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. TUNGETVNETHASHTYPES ------------------- This ioctl tells supported hash types. It is useful to check if a VM can be migrated to the current host. TUNSETVNETREPORTINGAUTOMQ, TUNSETVNETREPORTINGRSS, and TUNSETVNETRSS -------------------------------------------------------------------- These ioctls configures a steering algorithm and, if needed, hash reporting. Signed-off-by: Akihiko Odaki Tested-by: Lei Yang --- drivers/net/tap.c | 10 ++- drivers/net/tun.c | 12 +++- drivers/net/tun_vnet.h | 165 ++++++++++++++++++++++++++++++++++++++++= +--- include/uapi/linux/if_tun.h | 71 +++++++++++++++++++ 4 files changed, 244 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..45d0533efc8d 100644 --- a/drivers/net/tun_vnet.h +++ b/drivers/net/tun_vnet.h @@ -6,6 +6,17 @@ #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 { + bool report; + bool rss; + struct tun_vnet_rss common; + 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 +118,128 @@ static inline long tun_vnet_ioctl(int *vnet_hdr_sz, u= nsigned int *flags, } } =20 +static inline long tun_vnet_ioctl_gethashtypes(u32 __user *argp) +{ + return put_user(VIRTIO_NET_SUPPORTED_HASH_TYPES, argp) ? -EFAULT : 0; +} + +static inline long tun_vnet_ioctl_sethash(struct tun_vnet_hash __rcu **has= hp, + unsigned int cmd, + void __user *argp) +{ + struct tun_vnet_rss common; + struct tun_vnet_hash *hash; + size_t indirection_table_size; + size_t key_size; + size_t size; + + switch (cmd) { + case TUNSETVNETREPORTINGAUTOMQ: + if (get_user(common.hash_types, (u32 __user *)argp)) + return -EFAULT; + + if (common.hash_types) { + hash =3D kzalloc(sizeof(*hash), GFP_KERNEL); + if (!hash) + return -ENOMEM; + + hash->report =3D true; + hash->common.hash_types =3D common.hash_types; + } else { + hash =3D NULL; + } + break; + + case TUNSETVNETREPORTINGRSS: + case TUNSETVNETRSS: + if (copy_from_user(&common, argp, sizeof(common))) + return -EFAULT; + argp =3D (struct tun_vnet_rss __user *)argp + 1; + + indirection_table_size =3D ((size_t)common.indirection_table_mask + 1) *= 2; + key_size =3D virtio_net_hash_key_length(common.hash_types); + size =3D struct_size(hash, rss_indirection_table, + (size_t)common.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 + common.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->report =3D cmd =3D=3D TUNSETVNETREPORTINGRSS; + hash->rss =3D true; + hash->common =3D common; + break; + + default: + return -EINVAL; + } + + kfree_rcu_mightsleep(rcu_replace_pointer_rtnl(*hashp, hash)); + return 0; +} + +static inline void tun_vnet_hash_report(const struct tun_vnet_hash *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->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.hash_types, keys), + .value =3D value + }; +} + +static inline u16 tun_vnet_rss_select_queue(u32 numqueues, + const struct tun_vnet_hash *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.hash_types, hash->rss_key, &ret); + + if (!ret.report) + return hash->common.unclassified_queue % numqueues; + + if (hash->report) { + report =3D vnet_hash_add(skb); + if (report) + *report =3D ret; + } + + index =3D ret.value & hash->common.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 +268,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 +290,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..fe4b984d3bbb 100644 --- a/include/uapi/linux/if_tun.h +++ b/include/uapi/linux/if_tun.h @@ -62,6 +62,62 @@ #define TUNSETCARRIER _IOW('T', 226, int) #define TUNGETDEVNETNS _IO('T', 227) =20 +/** + * define TUNGETVNETHASHTYPES - ioctl to get supported virtio_net hashing = types + * + * The argument is a pointer to __u32 which will store the supported virti= o_net + * hashing types. + */ +#define TUNGETVNETHASHTYPES _IOR('T', 228, __u32) + +/** + * define TUNSETVNETREPORTINGAUTOMQ - ioctl to enable automq with hash rep= orting + * + * Disable RSS and enable automatic receive steering with hash reporting. + * + * The argument is a pointer to __u32 that contains a bitmask of hash types + * allowed to be reported. + * + * 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 TUNSETVNETREPORTINGAUTOMQ _IOR('T', 229, __u32) + +/** + * define TUNSETVNETREPORTINGRSS - ioctl to enable RSS with hash reporting + * + * Disable automatic receive steering and enable RSS with hash reporting. + * + * 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 TUNSETVNETREPORTINGRSS _IOR('T', 230, struct tun_vnet_rss) + +/** + * define TUNSETVNETRSS - ioctl to enable RSS without hash reporting + * + * Disable automatic receive steering and enable RSS without hash reportin= g. + * + * The argument is a pointer to the compound of the following in order: + * + * 1. &struct tun_vnet_rss + * 3. Indirection table + * 4. Key + * + * 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 TUNSETVNETRSS _IOR('T', 231, struct tun_vnet_rss) + /* TUNSETIFF ifr flags */ #define IFF_TUN 0x0001 #define IFF_TAP 0x0002 @@ -124,4 +180,19 @@ struct tun_filter { */ #define TUN_STEERINGEBPF_FALLBACK -1 =20 +/** + * struct tun_vnet_rss - virtio_net RSS configuration + * @hash_types: + * Bitmask of allowed hash types + * @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_rss { + __u32 hash_types; + __u16 indirection_table_mask; + __u16 unclassified_queue; +}; + #endif /* _UAPI__IF_TUN_H */ --=20 2.49.0 From nobody Tue Dec 16 11:07:29 2025 Received: from mail-pg1-f173.google.com (mail-pg1-f173.google.com [209.85.215.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 E94761E9B0D for ; Fri, 30 May 2025 04:50:48 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.215.173 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1748580650; cv=none; b=QAdb3j+3dsg0ejnYGDqgJ6WPRAP64bGLypdxVBEEZwOK3TumVJ3L88L/2yUmIfFpFB7ezgT/Wr+m03CkUV34HTVJ5DLiNDLu4p+bYnBPwWBc/tG7wiYDn0MBnIzSrS+Bn1EvhjjuM7RFKxwLznPCQnS2rAEqTEhGG09oR2W03u8= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1748580650; c=relaxed/simple; bh=vXBLYAWx+KT8NixkiW+nmAmAP6uEmWPDiyypcFhaZWY=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To; b=MVIK+aznsyEx4zgk21kyFabi4Od/ppnGlUawBU06wPnfBP8/0IBef4iK9G1zTwbFRQv3MEVoMZAZFSalAHVzRSuh3w346A8IkCQQkBRecrqBsW2d2RsVLmifM2Ku0OsyeDDX9mZ3ZUepmNK4M1CjszSe0+hP7Jh4mVaclk3qRaI= 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=CV3TSHii; arc=none smtp.client-ip=209.85.215.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="CV3TSHii" Received: by mail-pg1-f173.google.com with SMTP id 41be03b00d2f7-b2c4476d381so1483626a12.0 for ; Thu, 29 May 2025 21:50:48 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=daynix-com.20230601.gappssmtp.com; s=20230601; t=1748580648; x=1749185448; 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=Bke5K22c3HD9w23wmyNQv3eteVxt8661CPm0yQIUlGQ=; b=CV3TSHiiy/PAYpWIwEH4fxABUSk2ozOglgsCzJ5B+QhWFdPkhbXu8pvJ47F+fvzf6e faa3uU2PqLAUudehmtn25v+SsRFuCqhOI7jz5RAjVc+ntgtFvIqtCqN4yg4OARgOqgYa 7J7rjdrNgmBiuXmseqFZmhjDetvjuSna7G4TE/NCRaEU5Eiaw01Qgh8xe7HN89W7U4Ek 8q8kQBTiT2fbUKeXV0w9EYJ0NgsUeZqSOC8msWP5S2glVfVgU51WQRSOV0K19BwrJeKg VMc1UxRBdSbqvVAF6SlxFcnOBJL0+d6OR7CIgS1DiIJbVkUigDlF15RoYjbm3sxaChTT zx4A== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1748580648; x=1749185448; 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=Bke5K22c3HD9w23wmyNQv3eteVxt8661CPm0yQIUlGQ=; b=EW6odWwctvlDkr+TDZP4ztI7xd9MENm7tOdN5SWiMUNTb6FyOss+Vl1ZhV9iGZ+noN x24GUasZxvEnBpyGNIpDfsERe+eOEtkzTVvBAwnETop6HEUqGL3ll40a9i7HNpXlykgb 1jgD3mExibxmhjn4OcvjjIE8nxZCCodtnVMH4OrxPVY1aqwkfOPNi7pJCEA2ZQymb6kV CR4nNcWGbyAsQs4UYmgGv2UV+8MBnpf7brkW7+hZUAbGomL5W8vXHJKvT1XIMd6HjFIT 64coMfn7YrgTI5xvFaSe5QQIdEPlETyJHcteDSmZ3KGXqvzkk6ItSmdCnVAEbv8JRtTu f6/w== X-Forwarded-Encrypted: i=1; AJvYcCVYVjPWbxa59+SJWDz4h1j/GiPvAGxbXpg+IQuT3n3e4vBs4t+UAJbhPErwKr38/8SjVeeGiVZVR9SZC9Q=@vger.kernel.org X-Gm-Message-State: AOJu0YxuBdvMPPefMZYS00KrgOBPQQeH5vczz3qu1orhvXG1hajtRfqh PgxV2/bqgWck+s8LDagcVGftfq/TulE3/A0+Q21nL3tYFE6Y5w+mrYVXvcQwCXNXTp0= X-Gm-Gg: ASbGncsEG7KXpDhWa139R1FgsAkuJjq5df7nShchoPJPmOEY3fB4SiH+zvkN2VBkN0c AwllwTnX0hbOU0dV6pGX0dN4vQfl2aLVjjBpm5ZILoJz1xV2jX9L0qV26leHC4NQWee8wAkIvd6 S2c3U1D83DRTq1pjQalofNVLhxCwA4lcjmZAF90YR93JNmhHT+LD38jrG5lCJLNtLqPhxw9mMLQ VCEZIwvqth2p+xP4+zeM/mzeahnOjmKRKLgUgGJ9NvqFX9maMP25CUb8Zp4l3ou8wwXcJRC+JZQ zTKu56EaqWhw2sv3eOWKVUK5fjn05fTL2fsI+9kibS5rpoyJArsRnI3+/WoXoig= X-Google-Smtp-Source: AGHT+IGSd69oFRRuK4lTduVM0ZF5zNmM4jyAvZgQPgB6jq6cdPe4LXym+7JQTROU4ygX8AexHC9tJQ== X-Received: by 2002:a17:902:e84a:b0:215:58be:3349 with SMTP id d9443c01a7336-2352b06d218mr31860065ad.14.1748580648014; Thu, 29 May 2025 21:50:48 -0700 (PDT) Received: from localhost ([157.82.128.1]) by smtp.gmail.com with UTF8SMTPSA id d9443c01a7336-23506bc889csm20244645ad.15.2025.05.29.21.50.44 (version=TLS1_3 cipher=TLS_AES_128_GCM_SHA256 bits=128/128); Thu, 29 May 2025 21:50:47 -0700 (PDT) From: Akihiko Odaki Date: Fri, 30 May 2025 13:50:09 +0900 Subject: [PATCH net-next v12 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: <20250530-rss-v12-5-95d8b348de91@daynix.com> References: <20250530-rss-v12-0-95d8b348de91@daynix.com> In-Reply-To: <20250530-rss-v12-0-95d8b348de91@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 --- drivers/net/Kconfig | 1 + drivers/net/tun.c | 56 ++++++++++++++++++++++++++++++++++++++++++----= ---- include/linux/skbuff.h | 3 +++ net/core/skbuff.c | 4 ++++ 4 files changed, 56 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..0a34db248e03 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 __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 *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 *vnet_hash =3D rcu_dereference(tun->vnet_hash); + + if (vnet_hash && 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 TUNGETVNETHASHTYPES: + return tun_vnet_ioctl_gethashtypes(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,12 @@ 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 TUNSETVNETREPORTINGAUTOMQ: + case TUNSETVNETREPORTINGRSS: + case TUNSETVNETRSS: + ret =3D tun_vnet_ioctl_sethash(&tun->vnet_hash, cmd, 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 b1c81687e9d8..75d48217a20f 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.49.0 From nobody Tue Dec 16 11:07:29 2025 Received: from mail-pg1-f181.google.com (mail-pg1-f181.google.com [209.85.215.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 1393621B9D6 for ; Fri, 30 May 2025 04:50:52 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.215.181 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1748580654; cv=none; b=bp1kYKNzf1go7ggdmPkdrrdFttoxfaC+EAb/rZI4CFlUFJc2V9XILR6c6YxhwzMnqnhm4qKY6LfnSGme453PUNN02Drprp69onqkdivLW/g1l0q5ZF4E/b8z/YhFYw4hf5VsKUJL7wQr2bEUXhaxl8+UwCJit3pzDB8szXK6llI= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1748580654; c=relaxed/simple; bh=A8mykslZWwIG4FNXV3Lm1NuXd/xH3TVuhPhWYtSjv/A=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To; b=Y0sVOzKVate1TDh1CUg6U1EsIng3qrDtq7atTqZ29ABgdPb+Y99O9IQe69vHbupcm3TnKwrabj4ZarbX0iaMbspM+tz4ar2zjkbQmrDy7ZlnRqMfRSJoEFDg7Ea5xRPX1uxYUjX/isYRBx469bKhb7dqFsmXCngUeFag0FlevnE= 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=oLEXeZTY; arc=none smtp.client-ip=209.85.215.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="oLEXeZTY" Received: by mail-pg1-f181.google.com with SMTP id 41be03b00d2f7-b1f7357b5b6so1057951a12.0 for ; Thu, 29 May 2025 21:50:52 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=daynix-com.20230601.gappssmtp.com; s=20230601; t=1748580652; x=1749185452; 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=G36+4ZP77wTYjNEOu/qcKvp0kJ+h6b0T8zIdMEmaFXg=; b=oLEXeZTYALbN8LFRgFP2VADJkzayCKk2AJAAiMe8Y+9o3dr3k02sbXHYqNiqRgq/zH rdvVz6aU/2t6VskVJEWfziAExSFExMXqsU6FYsKIDuMdxmhPI44G/f3BgKCcla9ULf02 zhrpP+7bZXgw2gryH28qJpHV5dKciwrM2o9F7YnWKYa6+/7GsrR10nTybAAftkw/zf09 A2rD5uZDyqo/NdrMKh47Hq/7DjVM/ETfBa2BWjVEEk8xKaAfZ8kxVhpK/zai5lHuMbVw EFXMrzg4bXJgPgE4ZMgBb8bVTpkhQfv0+jobnPHEsN6fqcZmZvmyC8Zu55DxjcBe7bGa pjHA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1748580652; x=1749185452; 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=G36+4ZP77wTYjNEOu/qcKvp0kJ+h6b0T8zIdMEmaFXg=; b=lM30XhO8xPM0mbCYEmv/hc5xztqlOtJ0E6OFo9FKDXmNkdIDpdocEtaHK0zIgelHrd 5s+E4rE9Wf4zvru01bD0BFQVcM+zLa62olMnn+KbaNkZAjz1ACp04PTnvtD68yOEY0Ck VxmWy6BbihiMTsm8J12WaY4f3MeI3kUy3c9jp1JyY2siFxEfKZ+4w2lgm4HoI1G8/+k1 n0nwHJWy1mQwtL3kXC6VEW4D2DXo8mcOh71oRfgTqjkFp9vmya7fXG3eWm+PppLlcqqM zh/tk57/LrxbrKH/TMZmXYOfi+D7vQeEPU2q3kKhn+GF0mVyCh02jyUe/SRRR2+GMG/V gltw== X-Forwarded-Encrypted: i=1; AJvYcCU4cY5XyCCdnX5rDWdP7aIrHtpc2TXg3Z+QkCUso+ABhfhTVbFwWAO+ilCAonZOQVFjIPb0Ng/4ThExQOA=@vger.kernel.org X-Gm-Message-State: AOJu0YyhZ2jYRKoeHRbMo7DQ2AqatmY0vw8XN793UNvVLfYRfl16dsi6 MewvKpZLAXRh1XtSkDMLcqskLkgbhXO7ITmnw2xf2tKhJsvQc4weedX0MkbdCUARQtw= X-Gm-Gg: ASbGncsYNkZm4XKNa5SNDN+eFfk8s2iSpupIGnnoblSoRZWsVG6DZmTPKieYWO2+QRI JeF5ddwLJv/AlhZAvelPqimj7aqK4tEt9tYT2+eemJAkN7yijOmTbmKpXfzN8BViNvMOzJyQpX5 yvgpuPe+hwCQm9cNdVHPxg9RNYjav/bndyDTukT5hO4Oo7W/1ZS0gEmPWBsAevwyAeLXVEiVt/h /bMDUy8zmi/N2rhNDrZwnqREaIx+hyUP7WvuMLF2QB/wTeX24gUpPbfGBlHOSN4WW22Va4wfrXR 9Rk9M9oFjp+h63nQ6DNxw8ghagYLw/1mACZojHgWKDB/7lBcN6IuoUfl/NaV67A= X-Google-Smtp-Source: AGHT+IGEoKVWjQvlEBQztN2LsXcTxfvwZkaCujBOiYLFoWDDJ4OZ1o9Irvn0v8iXfsBShaZWmZtyaw== X-Received: by 2002:a17:902:d4cd:b0:234:f580:9f5 with SMTP id d9443c01a7336-235289c818bmr28919365ad.9.1748580652210; Thu, 29 May 2025 21:50:52 -0700 (PDT) Received: from localhost ([157.82.128.1]) by smtp.gmail.com with UTF8SMTPSA id d9443c01a7336-23506cd342dsm20124795ad.148.2025.05.29.21.50.49 (version=TLS1_3 cipher=TLS_AES_128_GCM_SHA256 bits=128/128); Thu, 29 May 2025 21:50:51 -0700 (PDT) From: Akihiko Odaki Date: Fri, 30 May 2025 13:50:10 +0900 Subject: [PATCH net-next v12 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: <20250530-rss-v12-6-95d8b348de91@daynix.com> References: <20250530-rss-v12-0-95d8b348de91@daynix.com> In-Reply-To: <20250530-rss-v12-0-95d8b348de91@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 --- drivers/net/ipvlan/ipvtap.c | 2 +- drivers/net/macvtap.c | 2 +- drivers/net/tap.c | 72 +++++++++++++++++++++++++++++++++++++++++= ---- include/linux/if_tap.h | 4 ++- 4 files changed, 71 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..15f056d7f632 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 *vnet_hash =3D rcu_dereference(tap->vnet_hash); __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->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,18 @@ static long tap_ioctl(struct file *file, unsigned int= cmd, rtnl_unlock(); return ret; =20 + case TUNGETVNETHASHTYPES: + return tun_vnet_ioctl_gethashtypes(argp); + + case TUNSETVNETREPORTINGAUTOMQ: + case TUNSETVNETREPORTINGRSS: + case TUNSETVNETRSS: + rtnl_lock(); + tap =3D rtnl_dereference(q->tap); + ret =3D tap ? tun_vnet_ioctl_sethash(&tap->vnet_hash, cmd, argp) : -EBAD= FD; + 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..6647a7a9e956 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; =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 __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.49.0 From nobody Tue Dec 16 11:07:29 2025 Received: from mail-pg1-f171.google.com (mail-pg1-f171.google.com [209.85.215.171]) (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 1222321D596 for ; Fri, 30 May 2025 04:50:56 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.215.171 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1748580658; cv=none; b=SiaW1bbt1sy+HJYJ3ANH3uiH/SGzhHmupBHj6QRFYehDdNXU/KTaG3xIBLIgtYt+G+znzSkqvYq4UY7jADlFE87lQF7205RKE6Bc5sYvuzDGGoBSNeDt2FVO5gGvBsY84UTyiOy3FspToFIJTbDwLjM2+ye79q5qN8D0syr0bXQ= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1748580658; c=relaxed/simple; bh=Y+hugblmAxgmRkyn2fxyuMLaQgzvEXZBlnk8Jh/v8UM=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To; b=uxIPub2mS82pOK7X7USSK59LMJ4eBgsX+KESszeEJoyaeTbjv6WO1lT8xdxYqh7AN2D2C0O18gdN2Cgu8XGnSL7ODW+X3yrbC+RNPKu/FAfr3pkI6d5n9ECskoZeutVQAnfoIQXvW/dNRK/AbFctTe9SaxuWnzrC13q3FbIsdYo= 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=HBii2iHP; arc=none smtp.client-ip=209.85.215.171 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="HBii2iHP" Received: by mail-pg1-f171.google.com with SMTP id 41be03b00d2f7-b2c384b2945so1377641a12.0 for ; Thu, 29 May 2025 21:50:56 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=daynix-com.20230601.gappssmtp.com; s=20230601; t=1748580656; x=1749185456; 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=S/6gL7uu88i7p+1Fmf1z5Sh293hU0sJzRplicMeiOvs=; b=HBii2iHPzoj9jJ/IffKhV0roKmT29z+48zVvaXIBgN+JH0g/9B8VdOlUXh0CcHBWgV fNbChmEtmX0xPgGFoDX+th4mj21BdMXBc7o11Uyi+Rk30i54khWidHIk5Sg4/C4Kr1xG fuCIXBdMx0LmdeSRs1HLQjY67prBjyMOpReJ9PsPO/+UJjyRRowIzbLzb0cYtHLLgf4E H2J7MC3Cz4cjzR7Squ3QiLiMjw20Z03sTa7aCO8b5T/3IHoj9YHpE/2ZAd/XtLFi9FOX WSQ7ZdKIi7HZN5YALumYb6Kwh8+UIcrxmFazHhR4XP0R41rKbWWgjQshZl2KZ+iK3+zw Kacw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1748580656; x=1749185456; 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=S/6gL7uu88i7p+1Fmf1z5Sh293hU0sJzRplicMeiOvs=; b=Jlm0XXkgukU/Mq89FKDCW2DX52k3zKly73poPvG8lqKsFJ3C03RvW18fsX6DfDWW/P IaYky9Ol0syyvbuCerBEFpbeF5OTp1j4xKOAVWzLuEwVkzje/VMKXrbb0B+UOkTSDjMd 5JBBmS40xbCsRtnMMjLKHxVCgw4wXjtIrspqc1ho9bkq31KEHb8r1EnH0x4GvvzdWvpW UxFXqhbt8XhfGSKR5oMmgY+hu1pIwusaBVugrM+I1JzqsXnoC8H9MlGEzpHeHQdBNkTA 9pQalEaGWkDCEpAxHGHArioR9DH9g4qVABxpB073jrxxtaytOOAbAhQgUSowd68Y4/kq W0/Q== X-Forwarded-Encrypted: i=1; AJvYcCWubZAr2flTBGs0f43AXILQEbO05mpMuTfLPwpDtX04iN4lSWpQE2xdDbtrrEOB5JsoLSNLj3KVIYZu7uU=@vger.kernel.org X-Gm-Message-State: AOJu0YzwWD+GuMca6E6Igx4DoMPjtsDr3DNiPZ0cZuGWUWTdFLisL4/Q n6STRjzdvn3Y/kCAlvvXERzpotmbyA6ar/4rR7nhVw/IjVmBqXIJc4h3CXpbUxtdrWY= X-Gm-Gg: ASbGncvyjBn5p2pvP1K1rHnpcadq5LL7w5ugTcZrPxNzun3mnobvH3Z+YpKFpK0BLRA EH5JKD9KeyQvL9Yp3t5TqPnjoOxiIWCsln1skMFXt1tsoEYDIHbiEafGb5a1/pq5Ot65bIRUFa8 KRLqjdh86FGyeXWHIfVmZXfJiUU9H7WMejmw65A5+3OK1eJW5Ai24BBui5H42RCZDdQami5mpTM dvSnktA4q+1DxOsSaw8tQWghvrrik7dtrl0jmH+NvBuSBnekEXm0NA7hMjX7ID913S765HXud6q qPR93cVJdXneHd6ixfC4EPFLnPsFibDP2eIlMyKCk7uNND/vl6sm X-Google-Smtp-Source: AGHT+IEvyG17b9tHV2YruoiWIXuiS1hBS4XsYuWorEH+zYiLpcrIZIgqXit2l5cDU5DJsN67WvzC9g== X-Received: by 2002:a17:90b:17c8:b0:311:c939:c848 with SMTP id 98e67ed59e1d1-3123efae69fmr3575677a91.0.1748580656408; Thu, 29 May 2025 21:50:56 -0700 (PDT) Received: from localhost ([157.82.128.1]) by smtp.gmail.com with UTF8SMTPSA id 98e67ed59e1d1-3124e2b67ffsm426290a91.5.2025.05.29.21.50.53 (version=TLS1_3 cipher=TLS_AES_128_GCM_SHA256 bits=128/128); Thu, 29 May 2025 21:50:56 -0700 (PDT) From: Akihiko Odaki Date: Fri, 30 May 2025 13:50:11 +0900 Subject: [PATCH net-next v12 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: <20250530-rss-v12-7-95d8b348de91@daynix.com> References: <20250530-rss-v12-0-95d8b348de91@daynix.com> In-Reply-To: <20250530-rss-v12-0-95d8b348de91@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 | 39 +++++++++++++++++++++++++++++++++++= ++++ 1 file changed, 39 insertions(+) diff --git a/tools/testing/selftests/net/tun.c b/tools/testing/selftests/ne= t/tun.c index fa83918b62d1..41747e1728a6 100644 --- a/tools/testing/selftests/net/tun.c +++ b/tools/testing/selftests/net/tun.c @@ -12,6 +12,7 @@ #include #include #include +#include #include #include =20 @@ -159,4 +160,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, getvnethashtypes) +{ + uint32_t hash_types; + int ret =3D ioctl(self->fd, TUNGETVNETHASHTYPES, &hash_types); + + if (ret =3D=3D -1 && errno =3D=3D EBADFD) + SKIP(return, "TUNGETVNETHASHTYPES not supported"); + + EXPECT_FALSE(ret); +} + TEST_HARNESS_MAIN --=20 2.49.0 From nobody Tue Dec 16 11:07:29 2025 Received: from mail-pg1-f181.google.com (mail-pg1-f181.google.com [209.85.215.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 655CF22128E for ; Fri, 30 May 2025 04:51:01 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.215.181 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1748580664; cv=none; b=Y7CYqYideK2xDcXMNB/Z+FPNAnftbHIzVYwoneR3V3qziDFYIKqSd2tA44bEGP+a0HsoXH8SOQ/JXwaS2g1oCB/zIP97j8lqpgH6Yau32xRh4EqxH1f2EDTgb49KwKjZo2Dfj2/97Cz07IEZUItLGChJklK8t7pVSjbZby2NFXY= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1748580664; c=relaxed/simple; bh=YQItB9nnj6hKVEiTN5VN5RPeLE70Gu/ADDjEtuVW+fQ=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To; b=uxz1Xt66Mni1VPd02olanmjAu2xZ6J2AKF1rwlm9V4hLuVDPOt2BrcSUzUEVn/+x2RbxWC4qMMPz0uGbUwxo9tjbwUU28eHSH1B7mjhWmt7OC8JSlDT7epIv2NlkQtQdJrdBhEv2ZmReBzHKu+0hpSygJfm+6MZ8dAJQxiQVH3w= 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=3BbsueNC; arc=none smtp.client-ip=209.85.215.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="3BbsueNC" Received: by mail-pg1-f181.google.com with SMTP id 41be03b00d2f7-b0b2d0b2843so1227372a12.2 for ; Thu, 29 May 2025 21:51:01 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=daynix-com.20230601.gappssmtp.com; s=20230601; t=1748580661; x=1749185461; 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=tCKIobPRPiLYjLUStXTbEBKwYXDKx02vMARERXcXaVw=; b=3BbsueNCf1LNVjw/voJvEIghN8F0dr7HRUd/OQPSuBhJivN6FTm2l0JOoQGGBtqV4V 95eXlbNJnmUI5gzlLMAJ3IXcWYgvcX6yqWvVN5Ki2duSdcootGqDUwG7z5RfNlms8+lz mDVv8jpStObALpBPkTJbAulwdW+7Mu0JICrC9wJUpbZTZrPCXUPa2wOjz/MA37cavOz4 wtTyFZx2a/WJpyz4zL24zYmlOn5Spye3cspys2dSvn8AEQp2O6//Y1uJflE9IB8PdepU oP/KzAIjBQF69VurURFdQJIXthEmS98MmCMf7BH3aTb101sfDm4OCAWa4Ik6BUZ88zGK aWKA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1748580661; x=1749185461; 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=tCKIobPRPiLYjLUStXTbEBKwYXDKx02vMARERXcXaVw=; b=vUa1YMA6Q2ao9WLjM+8ZGIerVfYN639iKkJNsurXheRFsi+YsD0Uu+P/2EX+2wRXlO CWYHsIhfsnbi+VaE/bGGsU5fR5cVb2njGpibAYkQSH4HY1vNHNsu7DTgFItphFlLTmbe vBsAJewqWp72D0tg6wVgiB5yqbWrBuzYy5/awSMereXF1s9TKnK2M4YazhwfB5VJn4yK J2hPHMEPInT3tDpIdvG5v+2CDS50+fwwn5B5xdf2SJDKe1aGYgvu0z2sdWkuIvzMoTFH AnvNsGqtJBWSnfdUleQM0UgRUiQXSZ5Dq3wg+mEXJaF6n3gED6BoeIWxmFLQ3gfSE3vp nSMA== X-Forwarded-Encrypted: i=1; AJvYcCUA+zR4mNvdw6BN2T4CZT2Hs2rbqUCIx2urNrkMZAejL5uYkxE5TPUfm1pn9My8g7r0HKiEpYl4NThhKQQ=@vger.kernel.org X-Gm-Message-State: AOJu0Yzn+wpW9n20Iv0CfvfAR8qoSZZB0TZtiuLZvBhDADV0c85FzYS4 MNWFfg6o1XMFlFg30CQZxhN5Y1/dk/+j0PhldPiN9w+Gq8cpEEAE5Ddnowofmnnkc9wios3eF77 q7wwz X-Gm-Gg: ASbGncuWlHk4N3YhdaR+JnlC3LaC0HOgpc4pnqszRJd2HPJq4zOvNpN6sZuPrmRAL+H S6/Qk05WtOeVvP4hcpNyfh+P0nSLDbP/D7w+CKmC6COWGn88yA1ZumuMLgsr0ZVe6C8it70VnzV aYHuH5UNn1p0cxNuvrmfaqNdBimTzfz+s2vnlOs3/dV8r0Dz4YI3pn6hR53E1eKbuCnuheuUnRf skuno0vszYyJEAnac/NKEHS0YSBPqjV51SGpDjV0hZ40Z++IU8uYHh2bdTVuE0D+beFFWB8iDvo 0JpSxQcpZgwb506+FS6LxW3WYZxJaMGXowdYQ5ekzDrInAIex65xAfA0K7f+Lrs= X-Google-Smtp-Source: AGHT+IF0Xexx+o0YLMP2CtFiytDsYd7L3YzQVhJ8V4VCPSE1vDAu1MgzFGnOS1mzdV3guLRLSi71Pw== X-Received: by 2002:a17:903:46c8:b0:233:fbb3:c5bc with SMTP id d9443c01a7336-235291f5ea1mr34375645ad.19.1748580660699; Thu, 29 May 2025 21:51:00 -0700 (PDT) Received: from localhost ([157.82.128.1]) by smtp.gmail.com with UTF8SMTPSA id d9443c01a7336-23506bc86a1sm20253655ad.16.2025.05.29.21.50.57 (version=TLS1_3 cipher=TLS_AES_128_GCM_SHA256 bits=128/128); Thu, 29 May 2025 21:51:00 -0700 (PDT) From: Akihiko Odaki Date: Fri, 30 May 2025 13:50:12 +0900 Subject: [PATCH net-next v12 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: <20250530-rss-v12-8-95d8b348de91@daynix.com> References: <20250530-rss-v12-0-95d8b348de91@daynix.com> In-Reply-To: <20250530-rss-v12-0-95d8b348de91@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 | 448 +++++++++++++++++++++++++++++++= +++- 2 files changed, 440 insertions(+), 10 deletions(-) diff --git a/tools/testing/selftests/net/Makefile b/tools/testing/selftests= /net/Makefile index 8f32b4f01aee..0e0c751a4691 100644 --- a/tools/testing/selftests/net/Makefile +++ b/tools/testing/selftests/net/Makefile @@ -124,6 +124,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 41747e1728a6..79ae65ae934a 100644 --- a/tools/testing/selftests/net/tun.c +++ b/tools/testing/selftests/net/tun.c @@ -2,22 +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; @@ -40,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; @@ -53,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) { @@ -65,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 { @@ -103,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]; @@ -113,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 @@ -169,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)) @@ -198,4 +330,302 @@ TEST_F(tun_deleted, getvnethashtypes) EXPECT_FALSE(ret); } =20 -TEST_HARNESS_MAIN +FIXTURE(tun_vnet_rss) +{ + 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_rss) +{ + uint16_t eth_p; + uint8_t ipproto; + uint8_t flags; + uint16_t hash_report; + uint32_t hash_value; +}; + +FIXTURE_VARIANT_ADD(tun_vnet_rss, unclassified) +{ + .eth_p =3D ETH_P_LOOPBACK +}; + +FIXTURE_VARIANT_ADD(tun_vnet_rss, 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_rss, 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_rss, 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_rss, 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_rss, 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_rss, 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_rss) +{ + static const struct { + struct tun_vnet_rss hdr; + uint16_t indirection_table[2]; + uint8_t key[40]; + } vnet_rss =3D { + .hdr =3D { + .hash_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, + .indirection_table_mask =3D 1, + .unclassified_queue =3D 5 + }, + .indirection_table =3D { 3, 4 }, + .key =3D { + 0x6d, 0x5a, 0x56, 0xda, 0x25, 0x5b, 0x0e, 0xc2, + 0x41, 0x67, 0x25, 0x3d, 0x43, 0xa3, 0x8f, 0xb0, + 0xd0, 0xca, 0x2b, 0xcb, 0xae, 0x7b, 0x30, 0xb4, + 0x77, 0xcb, 0x2d, 0xa3, 0x80, 0x30, 0xf2, 0x0c, + 0x6a, 0x42, 0xb7, 0x3b, 0xbe, 0xac, 0x01, 0xfa + } + }; + + struct { + struct virtio_net_hdr_v1_hash vnet_hdr; + struct ethhdr ethhdr; + struct arphdr arphdr; + unsigned char sender_hwaddr[6]; + uint32_t sender_ipaddr; + unsigned char target_hwaddr[6]; + uint32_t target_ipaddr; + } __packed packet =3D { + .ethhdr =3D { + .h_source =3D TUN_HWADDR_SOURCE, + .h_dest =3D { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }, + .h_proto =3D htons(ETH_P_ARP) + }, + .arphdr =3D { + .ar_hrd =3D htons(ARPHRD_ETHER), + .ar_pro =3D htons(ETH_P_IP), + .ar_hln =3D ETH_ALEN, + .ar_pln =3D 4, + .ar_op =3D htons(ARPOP_REQUEST) + }, + .sender_hwaddr =3D TUN_HWADDR_DEST, + .sender_ipaddr =3D TUN_IPADDR_DEST, + .target_ipaddr =3D TUN_IPADDR_DEST + }; + + char dest_ifname[IFNAMSIZ] =3D ""; + int i, local_fd; + uint16_t ip_payload_len; + uint32_t hash_types; + 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], TUNGETVNETHASHTYPES, &hash_types); + if (i =3D=3D -1 && errno =3D=3D EINVAL) { + EXPECT_EQ(0, close(self->dest_fds[0])); + SKIP(return, "TUNGETVNETHASHTYPES not supported"); + } + + ASSERT_EQ(0, i) + EXPECT_EQ(0, close(self->dest_fds[0])); + + if ((hash_types & vnet_rss.hdr.hash_types) !=3D vnet_rss.hdr.hash_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], TUNSETVNETREPORTINGRSS, &vnet_rss)) + 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_rss) +{ + 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_rss, 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.49.0 From nobody Tue Dec 16 11:07:29 2025 Received: from mail-pf1-f178.google.com (mail-pf1-f178.google.com [209.85.210.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 B7F601F4191 for ; Fri, 30 May 2025 04:51:05 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.210.178 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1748580667; cv=none; b=EXqANMkKtA2WhCE9sB9q7cZ02BQ6t5sNgnwR2bPaoqo7+/CPEzLkz10laP7xGCVn2TRV5IhIqXZ0VK3b96NQTi1PiQI58NyVgfJy5cI2oNVwImFFTQsDjZquKZgRGnx6g+k0DMTH3TUQSlED/ERWhfBOTTG6vR498/GgI5ctx+8= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1748580667; c=relaxed/simple; bh=8QZ3Y17huIwvFuKYxGqjjNV9gzRi3SV/EMTE+e4j/s4=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To; b=bNRmxMWKZQeszhalMLSMIRBuv6NUILVKcaCR8dP4MGgZI0qYRo3fwwVa+Kx8p8E+VNaor3lXfZ7YVeTWrZU3gKbrK6AQXs+S7j5RAz17dgsI0pFMLT2kM7MzWowcz3jA85xszmzww0/eATBu/cKdKAmBS9vnRtRmXY/Nal+YHNs= 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=qxK5LkC2; arc=none smtp.client-ip=209.85.210.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="qxK5LkC2" Received: by mail-pf1-f178.google.com with SMTP id d2e1a72fcca58-74019695377so985397b3a.3 for ; Thu, 29 May 2025 21:51:05 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=daynix-com.20230601.gappssmtp.com; s=20230601; t=1748580665; x=1749185465; 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=6kg49tLaS0z1IHYonGafIguL3mgiSEk4xR/nFylD2io=; b=qxK5LkC2DVB0dYvE/5pN+icN9wP4bhzrrBuDTB69R2C0vaEqqECOq08QDZZdixunwy ravpjfFDJsy0E9EXEezXCMzeISk1PXqmD78evKIkZgildwI6t7XrYoXG1KGGM6FUBQcR 2Td1OlJGf+YKouksaSeFP/kYW4rUFoWKy+AKRxU/+7U7/c6nVp1/ZKCcF0fiUJQfBNmj +UWyOXN1/oVXIn11kiEmFie8JOUFJ1p+x/+kYhJLtRPnFKtLOddyRQ/5m1489PvhzeCj c6PemcxaIzKBn4Hla9hhHmS7AfLmmNSDWiHc8NCTcOA3H8MPx1/fIkFdZgz4SB6rQain tyCw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1748580665; x=1749185465; 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=6kg49tLaS0z1IHYonGafIguL3mgiSEk4xR/nFylD2io=; b=JgWgJiHQXJd+kJmWoVWalnWi62dt7Wn55/ViuhvBna2E6a9Ngh72xkqHWYh0JQO+x9 AYHDoyCV9K616NYu5b34P2Cn/lnhkf/NNKK0FZECjEOu8W7s+4dDWLXKwH2c4YIt2GMQ WRMYmlgKJ+TNpOdqhIt1/5Aqu63Et7yJUoR1IdgdexGJ1yKscS/JidatdbnWxevqZE47 FW1JdYH8ExpDte3ghekKBpV05uScWcKcDfv85If5nQamCo02RC7nYRin08Dg7T7rp2oq NgR9nBXeTTL/76E+VGGzAPsl9MZpW+JrQ16facxW/GGwmJz5AVxT9Uzwp6IL0UmdZ+PP VMvQ== X-Forwarded-Encrypted: i=1; AJvYcCV3Za2V/uMl8EBrAF0G+07hObGQ7naOSJ9DikDHvIZM/riaD/JiO/GzNjHAML1V6+oT118X9Ir4aIrhxfM=@vger.kernel.org X-Gm-Message-State: AOJu0YyjtTyM+vt6/zKFgm8Brmz214SH2DcBbdpenQrSRbvGmYVxqg5P whKkH5KB1tqZ1PPhxnH/mpNFABC/wx6TwL/kzibIFfGtefYg5IuDpJ4VZW0/96gKfNk= X-Gm-Gg: ASbGncse/mSKwD39wpI73zjZpBdiH4bGvdNFLUYO0AUXkE9ST9IXJwQ8wx0OQ0Nu6Ez gMrUMXHZkkwCMrJFSueK6cl3qoKMC1gnMydVfma80wCnNoTgFSz0b46TpRa7bofjppTv2lwYloK +3+v3lL5PZnua9+DsQMkLsyaMxnPp6AZ/KSOSY3Y6IkG8rIMTXKIASKtuNQhyyMXIbo6OUEeaRa 4+WuZiBbCLAZ0H8Jaz7F4c9B4HCDmY2aEL7swlO9cO75RobKGv6JsORX32CbfRWp5CNWWBWaYp1 n9uLX20/rYJ28Fzlw1ZvIV29ZV1v2dUz7lgUmH9KOnFjOQFAUrc3rPGrCl61IlQ= X-Google-Smtp-Source: AGHT+IH9+BHJNIoXbgVGyUoI7SrCOCtJTbLtcbCTAW+31fagg/7EMzO3Z6Fm63/CoKEr+0ydoICMHQ== X-Received: by 2002:a05:6a00:2389:b0:740:9abe:4d94 with SMTP id d2e1a72fcca58-747bda192e1mr2706018b3a.21.1748580664899; Thu, 29 May 2025 21:51:04 -0700 (PDT) Received: from localhost ([157.82.128.1]) by smtp.gmail.com with UTF8SMTPSA id d2e1a72fcca58-747afff71eesm2159761b3a.159.2025.05.29.21.51.01 (version=TLS1_3 cipher=TLS_AES_128_GCM_SHA256 bits=128/128); Thu, 29 May 2025 21:51:04 -0700 (PDT) From: Akihiko Odaki Date: Fri, 30 May 2025 13:50:13 +0900 Subject: [PATCH net-next v12 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: <20250530-rss-v12-9-95d8b348de91@daynix.com> References: <20250530-rss-v12-0-95d8b348de91@daynix.com> In-Reply-To: <20250530-rss-v12-0-95d8b348de91@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 --- tools/testing/selftests/net/config | 1 + tools/testing/selftests/net/tap.c | 131 +++++++++++++++++++++++++++++++++= +++- 2 files changed, 129 insertions(+), 3 deletions(-) diff --git a/tools/testing/selftests/net/config b/tools/testing/selftests/n= et/config index 61e5116987f3..00cb1e65b392 100644 --- a/tools/testing/selftests/net/config +++ b/tools/testing/selftests/net/config @@ -99,6 +99,7 @@ CONFIG_IPV6_IOAM6_LWTUNNEL=3Dy CONFIG_CRYPTO_SM4_GENERIC=3Dy CONFIG_AMT=3Dm CONFIG_TUN=3Dy +CONFIG_TUN_VNET_CROSS_LE=3Dy CONFIG_VXLAN=3Dm CONFIG_IP_SCTP=3Dm CONFIG_NETFILTER_XT_MATCH_POLICY=3Dm diff --git a/tools/testing/selftests/net/tap.c b/tools/testing/selftests/ne= t/tap.c index 247c3b3ac1c9..0decbc338965 100644 --- a/tools/testing/selftests/net/tap.c +++ b/tools/testing/selftests/net/tap.c @@ -387,9 +387,6 @@ FIXTURE_TEARDOWN(tap) if (self->fd !=3D -1) close(self->fd); =20 - ret =3D dev_delete(param_dev_tap_name); - EXPECT_EQ(ret, 0); - ret =3D dev_delete(param_dev_dummy_name); EXPECT_EQ(ret, 0); } @@ -431,4 +428,132 @@ 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)); + + 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)); + + 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)); + + 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_getvnethashtypes) +{ + uint32_t hash_types; + int ret; + + ASSERT_FALSE(dev_delete(param_dev_tap_name)); + + ret =3D ioctl(self->fd, TUNGETVNETHASHTYPES, &hash_types); + if (ret =3D=3D -1 && errno =3D=3D EINVAL) + SKIP(return, "TUNGETVNETHASHTYPES not supported"); + + EXPECT_FALSE(ret); +} + +FIXTURE(tap_setvnethash) +{ + int fd; +}; + +FIXTURE_VARIANT(tap_setvnethash) +{ + unsigned int cmd; +}; + +FIXTURE_VARIANT_ADD(tap_setvnethash, reportingautomq) +{ + .cmd =3D TUNSETVNETREPORTINGAUTOMQ +}; + +FIXTURE_VARIANT_ADD(tap_setvnethash, reportingrss) +{ + .cmd =3D TUNSETVNETREPORTINGRSS +}; + +FIXTURE_VARIANT_ADD(tap_setvnethash, rss) +{ + .cmd =3D TUNSETVNETRSS +}; + +FIXTURE_SETUP(tap_setvnethash) +{ + int ret; + + ret =3D dev_create(param_dev_dummy_name, "dummy", NULL, NULL); + ASSERT_FALSE(ret); + + ret =3D dev_create(param_dev_tap_name, "macvtap", macvtap_fill_rtattr, + NULL); + ASSERT_FALSE(ret) + EXPECT_FALSE(dev_delete(param_dev_dummy_name)); + + self->fd =3D opentap(param_dev_tap_name); + ASSERT_LT(0, self->fd) + EXPECT_FALSE(dev_delete(param_dev_dummy_name)); +} + +FIXTURE_TEARDOWN(tap_setvnethash) +{ + EXPECT_FALSE(close(self->fd)); + EXPECT_FALSE(dev_delete(param_dev_dummy_name)); +} + +TEST_F(tap_setvnethash, test_alive) +{ + struct tun_vnet_rss rss =3D { .hash_types =3D 0 }; + int ret; + + ret =3D ioctl(self->fd, variant->cmd, &rss); + + if (ret =3D=3D -1 && errno =3D=3D EINVAL) + SKIP(return, "not supported"); + + EXPECT_FALSE(ret); +} + +TEST_F(tap_setvnethash, test_deleted) +{ + ASSERT_FALSE(dev_delete(param_dev_tap_name)); + + ASSERT_EQ(-1, ioctl(self->fd, variant->cmd)); + + if (errno =3D=3D EINVAL) + SKIP(return, "not supported"); + + EXPECT_EQ(EBADFD, errno); +} + TEST_HARNESS_MAIN --=20 2.49.0 From nobody Tue Dec 16 11:07:29 2025 Received: from mail-pf1-f173.google.com (mail-pf1-f173.google.com [209.85.210.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 DA8F1223DE8 for ; Fri, 30 May 2025 04:51:09 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.210.173 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1748580671; cv=none; b=GFg6/8DX2nrEMkRtQTmLIjE2YMGmPG+RjzkaYLRCc9o2uXF+1B2yyijQ6mcxzYBqvyfoY3wUEjYlzOqcuyRjz84dYMRZY5CDQkZJ1kl8R5um5n1ohkKuge7HEed+xg/k8sAMeQ+7E2S4V5RVwp62B+9dr0qGFq4rX/j69fU19nw= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1748580671; c=relaxed/simple; bh=lWGVKyybSScfvzAgnxZfdPakMV9WV+eXSxEJF4cb1lY=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To; b=Ibs397dOjAxr1N7Hxdjby3KdNFboIFNiT+n4NYJdZcjmRCARWglzOBESepD+urtyGXgCz2wwlYv+GgbQnDN7yj1SzlPQfl8et1QSts2wvHq+U2YrF9UM9o7TdJyYOwB8mxBWg6NP6TVWe66EGEhRTtjFqbA2nz6XbvAAsLeaQOU= 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=AWkz7vON; arc=none smtp.client-ip=209.85.210.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="AWkz7vON" Received: by mail-pf1-f173.google.com with SMTP id d2e1a72fcca58-7376e311086so1651663b3a.3 for ; Thu, 29 May 2025 21:51:09 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=daynix-com.20230601.gappssmtp.com; s=20230601; t=1748580669; x=1749185469; 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=Z15gseFrGsCaLlozqKPcH2zd7I0guJGS0A9lc7pAtL0=; b=AWkz7vONAUKHEJ1BTAsIGd6+oLDDkSLczPChdvQu5ORyUjUBYLo06jokq4YNudLMd0 cZFWXtDlVdc5pzmsSve234WgkjNFvOezh9bjRcCR+paKjqvLBv2m+BgkJ30lu3+0vbJD 2AMhCM4e8rCFp6xoWniyyggyVCvKBOoO8EOXONeAVfHyP6iJq2aYs4i7gDstIaEK52Cp pHfacsIBbZtr2Gqp11V8OXkI40tcMRcs7SF6QMBCJ344XKw6pxNUDD3r/jTNCpV4CKxo 9lVs9n/6bFHCm81RS8tI+KQzLTk31WH98vmjTi8kDnoCWzPzPGevHa/P8qio4ArxfuuR sVmw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1748580669; x=1749185469; 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=Z15gseFrGsCaLlozqKPcH2zd7I0guJGS0A9lc7pAtL0=; b=HmtxAWUfPc0X6xzpbJhpen57gvgx2lPmnwQSkrNTzEG+OoPglkRWyFN7PJA2c3h9Pd i2sJqgDsgmRFFKmZOeO3GdgebVAg5XGhfhUvOK/qlB5cvydmAY7LIVDD8KI9o2dNOrxt ug0D5Ne0VDTAoNQP1UMeHGQSCYmxOkuBNcu6hRBBwXxea9OLnHmlVEAsztg1eXwMOGGe tN5aUuKq6DrPlD4LfX+PJhnBCObjFlz3wDokkxyjB5n+MdINUhwn/M48c3x7U2KhU47H ZdFAi9jOaxhOWirQSvg4Rs9DMrcWjudkrrAgKDab3GahaFPoHpVidcdFPkvaefQcpjaZ 2Jrw== X-Forwarded-Encrypted: i=1; AJvYcCVD7a7Zme94e4XpdWcokRvI6iOU4oqEWkAac2T4aR8pfBHE/DMJn7Q5DU1x1KzZxG0RMs6clWBqRyFSU/Q=@vger.kernel.org X-Gm-Message-State: AOJu0YxHqHUyaJNVGbwIdt1mWk/Hs+7dap5j2rdJFHPHjJM5raXFx13e wy4PW5usKY954uPNk6XrC71NTtVUG83UN7m742MLhJh5hiIlYcSlZW0qTixm7sGdzCQ= X-Gm-Gg: ASbGncvsvtwvfmpH8kXCH7NCk6QBHVZ+qprFksrxhyp0BryNJMtRukrgXDi7oAVfDGT Q72TLQY5Cl+EkodT9rsUZDlTGG3EAAraAd/blw0v+uTtbynlhx3MGWTMiMUJXXFHSWA9thpL4cK UcVMzI0DbM4QUAswo86wcajZCMSlCDKw31/R4ch9QMkPtYSFs7XwUbK9xW+B5z2mj3qvpF9IctC m3HaebhSAJCVUhfBWdh/3jsjJnVnFSMxHvuc7caXw1Td9vnD/SR+XgfIpmxqQBwtOfNNturYpTm pDmb7tl9NjuwZk14V+1Cqo5tO+mG2GdK8ZmTJaNJRYLc+LldSsvu X-Google-Smtp-Source: AGHT+IFEAyvdh+gmFNHHDHekWEQMYLOTZZa1DYZNnrPSAK+MYRW4HLZI96PlWLiwNkqJ19TNscPw2g== X-Received: by 2002:a05:6a00:805:b0:736:5b85:a911 with SMTP id d2e1a72fcca58-747bd9658a0mr3200511b3a.8.1748580669233; Thu, 29 May 2025 21:51:09 -0700 (PDT) Received: from localhost ([157.82.128.1]) by smtp.gmail.com with UTF8SMTPSA id d2e1a72fcca58-747affafa42sm2231166b3a.92.2025.05.29.21.51.06 (version=TLS1_3 cipher=TLS_AES_128_GCM_SHA256 bits=128/128); Thu, 29 May 2025 21:51:08 -0700 (PDT) From: Akihiko Odaki Date: Fri, 30 May 2025 13:50:14 +0900 Subject: [PATCH net-next v12 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: <20250530-rss-v12-10-95d8b348de91@daynix.com> References: <20250530-rss-v12-0-95d8b348de91@daynix.com> In-Reply-To: <20250530-rss-v12-0-95d8b348de91@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.49.0