From 05d10b89c55208c6c740c11baaeaa730f95f650b Mon Sep 17 00:00:00 2001 From: purplerain Date: Fri, 24 Jan 2025 19:21:17 +0000 Subject: [PATCH] sync with OpenBSD -current --- lib/libcrypto/arch/amd64/Makefile.inc | 4 +- lib/libcrypto/md5/asm/md5-586.pl | 2 +- lib/libcrypto/md5/asm/md5-x86_64.pl | 265 -------------------------- lib/libcrypto/md5/md5.c | 5 +- lib/libcrypto/md5/md5_amd64_generic.S | 237 +++++++++++++++++++++++ regress/lib/libcrypto/ec/ectest.c | 4 +- sys/dev/pci/if_vmx.c | 12 +- sys/net/if.c | 143 +++++++++++--- sys/net/if_var.h | 7 +- sys/net/rtsock.c | 26 ++- 10 files changed, 389 insertions(+), 316 deletions(-) delete mode 100755 lib/libcrypto/md5/asm/md5-x86_64.pl create mode 100644 lib/libcrypto/md5/md5_amd64_generic.S diff --git a/lib/libcrypto/arch/amd64/Makefile.inc b/lib/libcrypto/arch/amd64/Makefile.inc index f8f829cca..f4410e805 100644 --- a/lib/libcrypto/arch/amd64/Makefile.inc +++ b/lib/libcrypto/arch/amd64/Makefile.inc @@ -1,4 +1,4 @@ -# $OpenBSD: Makefile.inc,v 1.35 2024/12/06 11:57:17 jsing Exp $ +# $OpenBSD: Makefile.inc,v 1.36 2025/01/24 13:35:04 jsing Exp $ # amd64-specific libcrypto build rules @@ -40,7 +40,7 @@ SRCS += word_clz.S # md5 CFLAGS+= -DMD5_ASM -SSLASM+= md5 md5-x86_64 +SRCS+= md5_amd64_generic.S # modes CFLAGS+= -DGHASH_ASM SSLASM+= modes ghash-x86_64 diff --git a/lib/libcrypto/md5/asm/md5-586.pl b/lib/libcrypto/md5/asm/md5-586.pl index ec7f1772f..8e592388a 100644 --- a/lib/libcrypto/md5/asm/md5-586.pl +++ b/lib/libcrypto/md5/asm/md5-586.pl @@ -30,7 +30,7 @@ $X="esi"; 0, 7, 14, 5, 12, 3, 10, 1, 8, 15, 6, 13, 4, 11, 2, 9, # R3 ); -&md5_block("md5_block_asm_data_order"); +&md5_block("md5_block_data_order"); &asm_finish(); sub Np diff --git a/lib/libcrypto/md5/asm/md5-x86_64.pl b/lib/libcrypto/md5/asm/md5-x86_64.pl deleted file mode 100755 index 5001c3472..000000000 --- a/lib/libcrypto/md5/asm/md5-x86_64.pl +++ /dev/null @@ -1,265 +0,0 @@ -#!/usr/bin/perl -w -# -# MD5 optimized for AMD64. -# -# Author: Marc Bevand -# Licence: I hereby disclaim the copyright on this code and place it -# in the public domain. -# - -use strict; - -my $code; - -# round1_step() does: -# dst = x + ((dst + F(x,y,z) + X[k] + T_i) <<< s) -# %r10d = X[k_next] -# %r11d = z' (copy of z for the next step) -# Each round1_step() takes about 5.3 clocks (9 instructions, 1.7 IPC) -sub round1_step -{ - my ($pos, $dst, $x, $y, $z, $k_next, $T_i, $s) = @_; - $code .= " mov 0*4(%rsi), %r10d /* (NEXT STEP) X[0] */\n" if ($pos == -1); - $code .= " mov %edx, %r11d /* (NEXT STEP) z' = %edx */\n" if ($pos == -1); - $code .= <A - mov 1*4(%rbp), %ebx # ebx = ctx->B - mov 2*4(%rbp), %ecx # ecx = ctx->C - mov 3*4(%rbp), %edx # edx = ctx->D - # end is 'rdi' - # ptr is 'rsi' - # A is 'eax' - # B is 'ebx' - # C is 'ecx' - # D is 'edx' - - cmp %rdi, %rsi # cmp end with ptr - je .Lend # jmp if ptr == end - - # BEGIN of loop over 16-word blocks -.Lloop: # save old values of A, B, C, D - mov %eax, %r8d - mov %ebx, %r9d - mov %ecx, %r14d - mov %edx, %r15d -EOF -round1_step(-1,'%eax','%ebx','%ecx','%edx', '1','0xd76aa478', '7'); -round1_step( 0,'%edx','%eax','%ebx','%ecx', '2','0xe8c7b756','12'); -round1_step( 0,'%ecx','%edx','%eax','%ebx', '3','0x242070db','17'); -round1_step( 0,'%ebx','%ecx','%edx','%eax', '4','0xc1bdceee','22'); -round1_step( 0,'%eax','%ebx','%ecx','%edx', '5','0xf57c0faf', '7'); -round1_step( 0,'%edx','%eax','%ebx','%ecx', '6','0x4787c62a','12'); -round1_step( 0,'%ecx','%edx','%eax','%ebx', '7','0xa8304613','17'); -round1_step( 0,'%ebx','%ecx','%edx','%eax', '8','0xfd469501','22'); -round1_step( 0,'%eax','%ebx','%ecx','%edx', '9','0x698098d8', '7'); -round1_step( 0,'%edx','%eax','%ebx','%ecx','10','0x8b44f7af','12'); -round1_step( 0,'%ecx','%edx','%eax','%ebx','11','0xffff5bb1','17'); -round1_step( 0,'%ebx','%ecx','%edx','%eax','12','0x895cd7be','22'); -round1_step( 0,'%eax','%ebx','%ecx','%edx','13','0x6b901122', '7'); -round1_step( 0,'%edx','%eax','%ebx','%ecx','14','0xfd987193','12'); -round1_step( 0,'%ecx','%edx','%eax','%ebx','15','0xa679438e','17'); -round1_step( 1,'%ebx','%ecx','%edx','%eax', '0','0x49b40821','22'); - -round2_step(-1,'%eax','%ebx','%ecx','%edx', '6','0xf61e2562', '5'); -round2_step( 0,'%edx','%eax','%ebx','%ecx','11','0xc040b340', '9'); -round2_step( 0,'%ecx','%edx','%eax','%ebx', '0','0x265e5a51','14'); -round2_step( 0,'%ebx','%ecx','%edx','%eax', '5','0xe9b6c7aa','20'); -round2_step( 0,'%eax','%ebx','%ecx','%edx','10','0xd62f105d', '5'); -round2_step( 0,'%edx','%eax','%ebx','%ecx','15', '0x2441453', '9'); -round2_step( 0,'%ecx','%edx','%eax','%ebx', '4','0xd8a1e681','14'); -round2_step( 0,'%ebx','%ecx','%edx','%eax', '9','0xe7d3fbc8','20'); -round2_step( 0,'%eax','%ebx','%ecx','%edx','14','0x21e1cde6', '5'); -round2_step( 0,'%edx','%eax','%ebx','%ecx', '3','0xc33707d6', '9'); -round2_step( 0,'%ecx','%edx','%eax','%ebx', '8','0xf4d50d87','14'); -round2_step( 0,'%ebx','%ecx','%edx','%eax','13','0x455a14ed','20'); -round2_step( 0,'%eax','%ebx','%ecx','%edx', '2','0xa9e3e905', '5'); -round2_step( 0,'%edx','%eax','%ebx','%ecx', '7','0xfcefa3f8', '9'); -round2_step( 0,'%ecx','%edx','%eax','%ebx','12','0x676f02d9','14'); -round2_step( 1,'%ebx','%ecx','%edx','%eax', '0','0x8d2a4c8a','20'); - -round3_step(-1,'%eax','%ebx','%ecx','%edx', '8','0xfffa3942', '4'); -round3_step( 0,'%edx','%eax','%ebx','%ecx','11','0x8771f681','11'); -round3_step( 0,'%ecx','%edx','%eax','%ebx','14','0x6d9d6122','16'); -round3_step( 0,'%ebx','%ecx','%edx','%eax', '1','0xfde5380c','23'); -round3_step( 0,'%eax','%ebx','%ecx','%edx', '4','0xa4beea44', '4'); -round3_step( 0,'%edx','%eax','%ebx','%ecx', '7','0x4bdecfa9','11'); -round3_step( 0,'%ecx','%edx','%eax','%ebx','10','0xf6bb4b60','16'); -round3_step( 0,'%ebx','%ecx','%edx','%eax','13','0xbebfbc70','23'); -round3_step( 0,'%eax','%ebx','%ecx','%edx', '0','0x289b7ec6', '4'); -round3_step( 0,'%edx','%eax','%ebx','%ecx', '3','0xeaa127fa','11'); -round3_step( 0,'%ecx','%edx','%eax','%ebx', '6','0xd4ef3085','16'); -round3_step( 0,'%ebx','%ecx','%edx','%eax', '9', '0x4881d05','23'); -round3_step( 0,'%eax','%ebx','%ecx','%edx','12','0xd9d4d039', '4'); -round3_step( 0,'%edx','%eax','%ebx','%ecx','15','0xe6db99e5','11'); -round3_step( 0,'%ecx','%edx','%eax','%ebx', '2','0x1fa27cf8','16'); -round3_step( 1,'%ebx','%ecx','%edx','%eax', '0','0xc4ac5665','23'); - -round4_step(-1,'%eax','%ebx','%ecx','%edx', '7','0xf4292244', '6'); -round4_step( 0,'%edx','%eax','%ebx','%ecx','14','0x432aff97','10'); -round4_step( 0,'%ecx','%edx','%eax','%ebx', '5','0xab9423a7','15'); -round4_step( 0,'%ebx','%ecx','%edx','%eax','12','0xfc93a039','21'); -round4_step( 0,'%eax','%ebx','%ecx','%edx', '3','0x655b59c3', '6'); -round4_step( 0,'%edx','%eax','%ebx','%ecx','10','0x8f0ccc92','10'); -round4_step( 0,'%ecx','%edx','%eax','%ebx', '1','0xffeff47d','15'); -round4_step( 0,'%ebx','%ecx','%edx','%eax', '8','0x85845dd1','21'); -round4_step( 0,'%eax','%ebx','%ecx','%edx','15','0x6fa87e4f', '6'); -round4_step( 0,'%edx','%eax','%ebx','%ecx', '6','0xfe2ce6e0','10'); -round4_step( 0,'%ecx','%edx','%eax','%ebx','13','0xa3014314','15'); -round4_step( 0,'%ebx','%ecx','%edx','%eax', '4','0x4e0811a1','21'); -round4_step( 0,'%eax','%ebx','%ecx','%edx','11','0xf7537e82', '6'); -round4_step( 0,'%edx','%eax','%ebx','%ecx', '2','0xbd3af235','10'); -round4_step( 0,'%ecx','%edx','%eax','%ebx', '9','0x2ad7d2bb','15'); -round4_step( 1,'%ebx','%ecx','%edx','%eax', '0','0xeb86d391','21'); -$code .= <A = A - mov %ebx, 1*4(%rbp) # ctx->B = B - mov %ecx, 2*4(%rbp) # ctx->C = C - mov %edx, 3*4(%rbp) # ctx->D = D - - mov (%rsp),%r15 - mov 8(%rsp),%r14 - mov 16(%rsp),%r12 - mov 24(%rsp),%rbx - mov 32(%rsp),%rbp - add \$40,%rsp -.Lepilogue: - ret -.size md5_block_asm_data_order,.-md5_block_asm_data_order -EOF - -print $code; - -close STDOUT; diff --git a/lib/libcrypto/md5/md5.c b/lib/libcrypto/md5/md5.c index 3bc558f0f..f1c9223d8 100644 --- a/lib/libcrypto/md5/md5.c +++ b/lib/libcrypto/md5/md5.c @@ -1,4 +1,4 @@ -/* $OpenBSD: md5.c,v 1.24 2025/01/19 07:51:41 jsing Exp $ */ +/* $OpenBSD: md5.c,v 1.25 2025/01/24 13:35:04 jsing Exp $ */ /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) * All rights reserved. * @@ -71,8 +71,7 @@ CTASSERT(sizeof(MD5_LONG) == sizeof(uint32_t)); #ifdef MD5_ASM -void md5_block_asm_data_order(MD5_CTX *c, const void *p, size_t num); -#define md5_block_data_order md5_block_asm_data_order +void md5_block_data_order(MD5_CTX *c, const void *p, size_t num); #endif #ifndef MD5_ASM diff --git a/lib/libcrypto/md5/md5_amd64_generic.S b/lib/libcrypto/md5/md5_amd64_generic.S new file mode 100644 index 000000000..e282d56ad --- /dev/null +++ b/lib/libcrypto/md5/md5_amd64_generic.S @@ -0,0 +1,237 @@ +/* $OpenBSD: md5_amd64_generic.S,v 1.1 2025/01/24 13:35:04 jsing Exp $ */ +/* + * Copyright (c) 2025 Joel Sing + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#ifdef __CET__ +#include +#else +#define _CET_ENDBR +#endif + +#define ctx %rdi +#define in %rsi +#define num %rdx + +#define end %rbp + +#define A %eax +#define B %ebx +#define C %ecx +#define D %edx + +#define AA %r8d +#define BB %r9d +#define CC %r10d +#define DD %r11d + +#define tmp0 %r12d +#define tmp1 %r13d + +/* + * Compute MD5 round 1 as: + * + * a = b + rol(a + F(b, c, d) + x + t, s) + * F(x, y, z) = (x & y) | (~x & z) + * = ((y ^ z) & x) ^ z + */ +#define md5_round1(a, b, c, d, x, t, s) \ + addl (x*4)(in), a; \ + movl c, tmp0; \ + xorl d, tmp0; \ + andl b, tmp0; \ + xorl d, tmp0; \ + leal t(tmp0, a), a; \ + roll $s, a; \ + addl b, a; + +/* + * Compute MD5 round 2 as: + * + * a = b + rol(a + G(b, c, d) + x + t, s) + * G(x, y, z) = (x & z) | (y & ~z) + */ +#define md5_round2(a, b, c, d, x, t, s) \ + addl (x*4)(in), a; \ + movl d, tmp0; \ + xorl $-1, tmp0; \ + andl c, tmp0; \ + addl tmp0, a; \ + movl d, tmp1; \ + andl b, tmp1; \ + leal t(tmp1, a), a; \ + roll $s, a; \ + addl b, a; + +/* + * Compute MD5 round 3 as: + * + * a = b + rol(a + H(b, c, d) + x + t, s) + * H(x, y, z) = x ^ y ^ z; + */ +#define md5_round3(a, b, c, d, x, t, s) \ + addl (x*4)(in), a; \ + movl d, tmp0; \ + xorl c, tmp0; \ + xorl b, tmp0; \ + leal t(tmp0, a), a; \ + roll $s, a; \ + addl b, a; + +/* + * Compute MD5 round 4 as: + * + * a = b + rol(a + I(b, c, d) + x + t, s) + * I(x, y, z) = y ^ (x | ~z) + */ +#define md5_round4(a, b, c, d, x, t, s) \ + addl (x*4)(in), a; \ + movl d, tmp0; \ + xorl $-1, tmp0; \ + orl b, tmp0; \ + xorl c, tmp0; \ + leal t(tmp0, a), a; \ + roll $s, a; \ + addl b, a; + +.text + +/* + * void md5_block_data_order(MD5_CTX *ctx, const void *in, size_t num); + * + * Standard x86-64 ABI: rdi = ctx, rsi = in, rdx = num + */ +.align 16 +.globl md5_block_data_order +.type md5_block_data_order,@function +md5_block_data_order: + _CET_ENDBR + + /* Save callee save registers. */ + pushq %rbx + pushq %rbp + pushq %r12 + pushq %r13 + + /* Compute end of message. */ + shlq $6, num + leaq (in, num, 1), end + + /* Load current hash state from context. */ + movl (0*4)(ctx), AA + movl (1*4)(ctx), BB + movl (2*4)(ctx), CC + movl (3*4)(ctx), DD + + jmp .Lblock_loop + +.align 16 +.Lblock_loop: + movl AA, A + movl BB, B + movl CC, C + movl DD, D + + md5_round1(A, B, C, D, 0, 0xd76aa478L, 7); + md5_round1(D, A, B, C, 1, 0xe8c7b756L, 12); + md5_round1(C, D, A, B, 2, 0x242070dbL, 17); + md5_round1(B, C, D, A, 3, 0xc1bdceeeL, 22); + md5_round1(A, B, C, D, 4, 0xf57c0fafL, 7); + md5_round1(D, A, B, C, 5, 0x4787c62aL, 12); + md5_round1(C, D, A, B, 6, 0xa8304613L, 17); + md5_round1(B, C, D, A, 7, 0xfd469501L, 22); + md5_round1(A, B, C, D, 8, 0x698098d8L, 7); + md5_round1(D, A, B, C, 9, 0x8b44f7afL, 12); + md5_round1(C, D, A, B, 10, 0xffff5bb1L, 17); + md5_round1(B, C, D, A, 11, 0x895cd7beL, 22); + md5_round1(A, B, C, D, 12, 0x6b901122L, 7); + md5_round1(D, A, B, C, 13, 0xfd987193L, 12); + md5_round1(C, D, A, B, 14, 0xa679438eL, 17); + md5_round1(B, C, D, A, 15, 0x49b40821L, 22); + + md5_round2(A, B, C, D, 1, 0xf61e2562L, 5); + md5_round2(D, A, B, C, 6, 0xc040b340L, 9); + md5_round2(C, D, A, B, 11, 0x265e5a51L, 14); + md5_round2(B, C, D, A, 0, 0xe9b6c7aaL, 20); + md5_round2(A, B, C, D, 5, 0xd62f105dL, 5); + md5_round2(D, A, B, C, 10, 0x02441453L, 9); + md5_round2(C, D, A, B, 15, 0xd8a1e681L, 14); + md5_round2(B, C, D, A, 4, 0xe7d3fbc8L, 20); + md5_round2(A, B, C, D, 9, 0x21e1cde6L, 5); + md5_round2(D, A, B, C, 14, 0xc33707d6L, 9); + md5_round2(C, D, A, B, 3, 0xf4d50d87L, 14); + md5_round2(B, C, D, A, 8, 0x455a14edL, 20); + md5_round2(A, B, C, D, 13, 0xa9e3e905L, 5); + md5_round2(D, A, B, C, 2, 0xfcefa3f8L, 9); + md5_round2(C, D, A, B, 7, 0x676f02d9L, 14); + md5_round2(B, C, D, A, 12, 0x8d2a4c8aL, 20); + + md5_round3(A, B, C, D, 5, 0xfffa3942L, 4); + md5_round3(D, A, B, C, 8, 0x8771f681L, 11); + md5_round3(C, D, A, B, 11, 0x6d9d6122L, 16); + md5_round3(B, C, D, A, 14, 0xfde5380cL, 23); + md5_round3(A, B, C, D, 1, 0xa4beea44L, 4); + md5_round3(D, A, B, C, 4, 0x4bdecfa9L, 11); + md5_round3(C, D, A, B, 7, 0xf6bb4b60L, 16); + md5_round3(B, C, D, A, 10, 0xbebfbc70L, 23); + md5_round3(A, B, C, D, 13, 0x289b7ec6L, 4); + md5_round3(D, A, B, C, 0, 0xeaa127faL, 11); + md5_round3(C, D, A, B, 3, 0xd4ef3085L, 16); + md5_round3(B, C, D, A, 6, 0x04881d05L, 23); + md5_round3(A, B, C, D, 9, 0xd9d4d039L, 4); + md5_round3(D, A, B, C, 12, 0xe6db99e5L, 11); + md5_round3(C, D, A, B, 15, 0x1fa27cf8L, 16); + md5_round3(B, C, D, A, 2, 0xc4ac5665L, 23); + + md5_round4(A, B, C, D, 0, 0xf4292244L, 6); + md5_round4(D, A, B, C, 7, 0x432aff97L, 10); + md5_round4(C, D, A, B, 14, 0xab9423a7L, 15); + md5_round4(B, C, D, A, 5, 0xfc93a039L, 21); + md5_round4(A, B, C, D, 12, 0x655b59c3L, 6); + md5_round4(D, A, B, C, 3, 0x8f0ccc92L, 10); + md5_round4(C, D, A, B, 10, 0xffeff47dL, 15); + md5_round4(B, C, D, A, 1, 0x85845dd1L, 21); + md5_round4(A, B, C, D, 8, 0x6fa87e4fL, 6); + md5_round4(D, A, B, C, 15, 0xfe2ce6e0L, 10); + md5_round4(C, D, A, B, 6, 0xa3014314L, 15); + md5_round4(B, C, D, A, 13, 0x4e0811a1L, 21); + md5_round4(A, B, C, D, 4, 0xf7537e82L, 6); + md5_round4(D, A, B, C, 11, 0xbd3af235L, 10); + md5_round4(C, D, A, B, 2, 0x2ad7d2bbL, 15); + md5_round4(B, C, D, A, 9, 0xeb86d391L, 21); + + /* Add intermediate state to hash state. */ + addl A, AA + addl B, BB + addl C, CC + addl D, DD + + addq $64, in + cmpq end, in + jb .Lblock_loop + + /* Store new hash state to context. */ + movl AA, (0*4)(ctx) + movl BB, (1*4)(ctx) + movl CC, (2*4)(ctx) + movl DD, (3*4)(ctx) + + /* Restore callee save registers. */ + popq %r13 + popq %r12 + popq %rbp + popq %rbx + + ret diff --git a/regress/lib/libcrypto/ec/ectest.c b/regress/lib/libcrypto/ec/ectest.c index 1aa6b1717..fc44f9c88 100644 --- a/regress/lib/libcrypto/ec/ectest.c +++ b/regress/lib/libcrypto/ec/ectest.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ectest.c,v 1.34 2025/01/22 15:38:25 tb Exp $ */ +/* $OpenBSD: ectest.c,v 1.35 2025/01/24 11:49:13 tb Exp $ */ /* * Originally written by Bodo Moeller for the OpenSSL project. */ @@ -117,8 +117,6 @@ group_order_tests(EC_GROUP *group, BN_CTX *ctx) ABORT; fprintf(stdout, "."); fflush(stdout); - if (!EC_GROUP_precompute_mult(group, ctx)) - ABORT; if (!EC_POINT_mul(group, Q, order, NULL, NULL, ctx)) ABORT; if (!EC_POINT_is_at_infinity(group, Q)) diff --git a/sys/dev/pci/if_vmx.c b/sys/dev/pci/if_vmx.c index a66d8a3c2..64b3eec35 100644 --- a/sys/dev/pci/if_vmx.c +++ b/sys/dev/pci/if_vmx.c @@ -1,4 +1,4 @@ -/* $OpenBSD: if_vmx.c,v 1.89 2024/09/01 03:08:59 jsg Exp $ */ +/* $OpenBSD: if_vmx.c,v 1.90 2025/01/24 10:29:43 yasuoka Exp $ */ /* * Copyright (c) 2013 Tsubai Masanari @@ -1621,10 +1621,8 @@ vmxnet3_start(struct ifqueue *ifq) for (;;) { int hdrlen; - if (free <= NTXSEGS) { - ifq_set_oactive(ifq); + if (free <= NTXSEGS) break; - } m = ifq_dequeue(ifq); if (m == NULL) @@ -1672,6 +1670,11 @@ vmxnet3_start(struct ifqueue *ifq) bus_dmamap_sync(sc->sc_dmat, map, 0, map->dm_mapsize, BUS_DMASYNC_PREWRITE); + free -= map->dm_nsegs; + /* set oactive here since txintr may be triggered in parallel */ + if (free <= NTXSEGS) + ifq_set_oactive(ifq); + gen = rgen ^ VMX_TX_GEN; sop = &ring->txd[prod]; for (i = 0; i < map->dm_nsegs; i++) { @@ -1699,7 +1702,6 @@ vmxnet3_start(struct ifqueue *ifq) BUS_DMASYNC_PREWRITE|BUS_DMASYNC_POSTWRITE); sop->tx_word2 ^= VMX_TX_GEN; - free -= i; post = 1; } diff --git a/sys/net/if.c b/sys/net/if.c index de2e823c1..78bfeaa1b 100644 --- a/sys/net/if.c +++ b/sys/net/if.c @@ -1,4 +1,4 @@ -/* $OpenBSD: if.c,v 1.723 2025/01/21 17:40:57 mvs Exp $ */ +/* $OpenBSD: if.c,v 1.724 2025/01/24 09:19:07 mvs Exp $ */ /* $NetBSD: if.c,v 1.35 1996/05/07 05:26:04 thorpej Exp $ */ /* @@ -235,6 +235,7 @@ LIST_HEAD(, if_clone) if_cloners = int if_cloners_count; /* [I] number of clonable interfaces */ struct rwlock if_cloners_lock = RWLOCK_INITIALIZER("clonelk"); +struct rwlock if_tmplist_lock = RWLOCK_INITIALIZER("iftmplk"); /* hooks should only be added, deleted, and run from a process context */ struct mutex if_hooks_mtx = MUTEX_INITIALIZER(IPL_NONE); @@ -2506,9 +2507,7 @@ ifioctl_get(u_long cmd, caddr_t data) error = if_clone_list((struct if_clonereq *)data); return (error); case SIOCGIFGMEMB: - NET_LOCK_SHARED(); error = if_getgroupmembers(data); - NET_UNLOCK_SHARED(); return (error); case SIOCGIFGATTR: NET_LOCK_SHARED(); @@ -2516,9 +2515,7 @@ ifioctl_get(u_long cmd, caddr_t data) NET_UNLOCK_SHARED(); return (error); case SIOCGIFGLIST: - NET_LOCK_SHARED(); error = if_getgrouplist(data); - NET_UNLOCK_SHARED(); return (error); } @@ -2596,9 +2593,7 @@ ifioctl_get(u_long cmd, caddr_t data) break; case SIOCGIFGROUP: - NET_LOCK_SHARED(); error = if_getgroup(data, ifp); - NET_UNLOCK_SHARED(); break; case SIOCGIFLLPRIO: @@ -2871,6 +2866,19 @@ if_detached_ioctl(struct ifnet *ifp, u_long a, caddr_t b) return ENODEV; } +static inline void +ifgroup_icref(struct ifg_group *ifg) +{ + refcnt_take(&ifg->ifg_tmprefcnt); +} + +static inline void +ifgroup_icrele(struct ifg_group *ifg) +{ + if (refcnt_rele(&ifg->ifg_tmprefcnt) != 0) + free(ifg, M_IFGROUP, sizeof(*ifg)); +} + /* * Create interface group without members */ @@ -2886,6 +2894,7 @@ if_creategroup(const char *groupname) ifg->ifg_refcnt = 1; ifg->ifg_carp_demoted = 0; TAILQ_INIT(&ifg->ifg_members); + refcnt_init(&ifg->ifg_tmprefcnt); #if NPF > 0 pfi_attach_ifgroup(ifg); #endif @@ -2986,7 +2995,7 @@ if_delgroup(struct ifnet *ifp, const char *groupname) #if NPF > 0 pfi_detach_ifgroup(ifgl->ifgl_group); #endif - free(ifgl->ifgl_group, M_IFGROUP, sizeof(*ifgl->ifgl_group)); + ifgroup_icrele(ifgl->ifgl_group); } free(ifgl, M_IFGROUP, sizeof(*ifgl)); @@ -3001,33 +3010,57 @@ if_delgroup(struct ifnet *ifp, const char *groupname) int if_getgroup(caddr_t data, struct ifnet *ifp) { - int len, error; + TAILQ_HEAD(, ifg_group) ifg_tmplist = + TAILQ_HEAD_INITIALIZER(ifg_tmplist); struct ifg_list *ifgl; struct ifg_req ifgrq, *ifgp; struct ifgroupreq *ifgr = (struct ifgroupreq *)data; + struct ifg_group *ifg; + int len, error = 0; if (ifgr->ifgr_len == 0) { + NET_LOCK_SHARED(); TAILQ_FOREACH(ifgl, &ifp->if_groups, ifgl_next) ifgr->ifgr_len += sizeof(struct ifg_req); + NET_UNLOCK_SHARED(); return (0); } len = ifgr->ifgr_len; ifgp = ifgr->ifgr_groups; + + rw_enter_write(&if_tmplist_lock); + + NET_LOCK_SHARED(); TAILQ_FOREACH(ifgl, &ifp->if_groups, ifgl_next) { - if (len < sizeof(ifgrq)) - return (EINVAL); + ifgroup_icref(ifgl->ifgl_group); + TAILQ_INSERT_TAIL(&ifg_tmplist, ifgl->ifgl_group, ifg_tmplist); + } + NET_UNLOCK_SHARED(); + + TAILQ_FOREACH(ifg, &ifg_tmplist, ifg_tmplist) { + if (len < sizeof(ifgrq)) { + error = EINVAL; + break; + } bzero(&ifgrq, sizeof ifgrq); - strlcpy(ifgrq.ifgrq_group, ifgl->ifgl_group->ifg_group, + strlcpy(ifgrq.ifgrq_group, ifg->ifg_group, sizeof(ifgrq.ifgrq_group)); if ((error = copyout((caddr_t)&ifgrq, (caddr_t)ifgp, sizeof(struct ifg_req)))) - return (error); + break; len -= sizeof(ifgrq); ifgp++; } - return (0); + while ((ifg = TAILQ_FIRST(&ifg_tmplist))){ + TAILQ_REMOVE(&ifg_tmplist, ifg, ifg_tmplist); + ifgroup_icrele(ifg); + } + + rw_exit_write(&if_tmplist_lock); + + return (error); } /* @@ -3036,40 +3069,69 @@ if_getgroup(caddr_t data, struct ifnet *ifp) int if_getgroupmembers(caddr_t data) { + TAILQ_HEAD(, ifnet) if_tmplist = + TAILQ_HEAD_INITIALIZER(if_tmplist); + struct ifnet *ifp; struct ifgroupreq *ifgr = (struct ifgroupreq *)data; struct ifg_group *ifg; struct ifg_member *ifgm; struct ifg_req ifgrq, *ifgp; - int len, error; + int len, error = 0; + + rw_enter_write(&if_tmplist_lock); + NET_LOCK_SHARED(); TAILQ_FOREACH(ifg, &ifg_head, ifg_next) if (!strcmp(ifg->ifg_group, ifgr->ifgr_name)) break; - if (ifg == NULL) - return (ENOENT); + if (ifg == NULL) { + error = ENOENT; + goto unlock; + } if (ifgr->ifgr_len == 0) { TAILQ_FOREACH(ifgm, &ifg->ifg_members, ifgm_next) ifgr->ifgr_len += sizeof(ifgrq); - return (0); + goto unlock; } + TAILQ_FOREACH (ifgm, &ifg->ifg_members, ifgm_next) { + if_ref(ifgm->ifgm_ifp); + TAILQ_INSERT_TAIL(&if_tmplist, ifgm->ifgm_ifp, if_tmplist); + } + NET_UNLOCK_SHARED(); + len = ifgr->ifgr_len; ifgp = ifgr->ifgr_groups; - TAILQ_FOREACH(ifgm, &ifg->ifg_members, ifgm_next) { - if (len < sizeof(ifgrq)) - return (EINVAL); + + TAILQ_FOREACH (ifp, &if_tmplist, if_tmplist) { + if (len < sizeof(ifgrq)) { + error = EINVAL; + break; + } bzero(&ifgrq, sizeof ifgrq); - strlcpy(ifgrq.ifgrq_member, ifgm->ifgm_ifp->if_xname, + strlcpy(ifgrq.ifgrq_member, ifp->if_xname, sizeof(ifgrq.ifgrq_member)); if ((error = copyout((caddr_t)&ifgrq, (caddr_t)ifgp, sizeof(struct ifg_req)))) - return (error); + break; len -= sizeof(ifgrq); ifgp++; } - return (0); + while ((ifp = TAILQ_FIRST(&if_tmplist))) { + TAILQ_REMOVE(&if_tmplist, ifp, if_tmplist); + if_put(ifp); + } + rw_exit_write(&if_tmplist_lock); + + return (error); + +unlock: + NET_UNLOCK_SHARED(); + rw_exit_write(&if_tmplist_lock); + + return (error); } int @@ -3122,33 +3184,56 @@ if_setgroupattribs(caddr_t data) int if_getgrouplist(caddr_t data) { + TAILQ_HEAD(, ifg_group) ifg_tmplist = + TAILQ_HEAD_INITIALIZER(ifg_tmplist); struct ifgroupreq *ifgr = (struct ifgroupreq *)data; struct ifg_group *ifg; struct ifg_req ifgrq, *ifgp; - int len, error; + int len, error = 0; if (ifgr->ifgr_len == 0) { + NET_LOCK_SHARED(); TAILQ_FOREACH(ifg, &ifg_head, ifg_next) ifgr->ifgr_len += sizeof(ifgrq); + NET_LOCK_SHARED(); return (0); } len = ifgr->ifgr_len; ifgp = ifgr->ifgr_groups; + + rw_enter_write(&if_tmplist_lock); + + NET_LOCK_SHARED(); TAILQ_FOREACH(ifg, &ifg_head, ifg_next) { - if (len < sizeof(ifgrq)) - return (EINVAL); + ifgroup_icref(ifg); + TAILQ_INSERT_TAIL(&ifg_tmplist, ifg, ifg_tmplist); + } + NET_UNLOCK_SHARED(); + + TAILQ_FOREACH(ifg, &ifg_tmplist, ifg_tmplist) { + if (len < sizeof(ifgrq)) { + error = EINVAL; + break; + } bzero(&ifgrq, sizeof ifgrq); strlcpy(ifgrq.ifgrq_group, ifg->ifg_group, sizeof(ifgrq.ifgrq_group)); if ((error = copyout((caddr_t)&ifgrq, (caddr_t)ifgp, sizeof(struct ifg_req)))) - return (error); + break; len -= sizeof(ifgrq); ifgp++; } - return (0); + while ((ifg = TAILQ_FIRST(&ifg_tmplist))){ + TAILQ_REMOVE(&ifg_tmplist, ifg, ifg_tmplist); + ifgroup_icrele(ifg); + } + + rw_exit_write(&if_tmplist_lock); + + return (error); } void diff --git a/sys/net/if_var.h b/sys/net/if_var.h index 01b4e6e38..2fb33e2a2 100644 --- a/sys/net/if_var.h +++ b/sys/net/if_var.h @@ -1,4 +1,4 @@ -/* $OpenBSD: if_var.h,v 1.134 2025/01/21 17:40:57 mvs Exp $ */ +/* $OpenBSD: if_var.h,v 1.135 2025/01/24 09:19:07 mvs Exp $ */ /* $NetBSD: if.h,v 1.23 1996/05/07 02:40:27 thorpej Exp $ */ /* @@ -79,6 +79,7 @@ * c only used in ioctl or routing socket contexts (kernel lock) * K kernel lock * N net lock + * T if_tmplist_lock * * For SRP related structures that allow lock-free reads, the write lock * is indicated below. @@ -138,6 +139,7 @@ struct ifnet { /* and the entries */ void *if_softc; /* [I] lower-level data for this if */ struct refcnt if_refcnt; TAILQ_ENTRY(ifnet) if_list; /* [NK] all struct ifnets are chained */ + TAILQ_ENTRY(ifnet) if_tmplist; /* [T] temporary list */ TAILQ_HEAD(, ifaddr) if_addrlist; /* [N] list of addresses per if */ TAILQ_HEAD(, ifmaddr) if_maddrlist; /* [N] list of multicast records */ TAILQ_HEAD(, ifg_list) if_groups; /* [N] list of groups per if */ @@ -273,6 +275,9 @@ struct ifg_group { int ifg_carp_demoted; /* [K] carp demotion counter */ TAILQ_HEAD(, ifg_member) ifg_members; /* [N] list of members per group */ TAILQ_ENTRY(ifg_group) ifg_next; /* [N] all groups are chained */ + + struct refcnt ifg_tmprefcnt; + TAILQ_ENTRY(ifg_group) ifg_tmplist; /* [T] temporary list */ }; struct ifg_member { diff --git a/sys/net/rtsock.c b/sys/net/rtsock.c index 78e87c273..966123aa0 100644 --- a/sys/net/rtsock.c +++ b/sys/net/rtsock.c @@ -1,4 +1,4 @@ -/* $OpenBSD: rtsock.c,v 1.377 2025/01/09 18:20:29 bluhm Exp $ */ +/* $OpenBSD: rtsock.c,v 1.378 2025/01/24 09:16:55 mvs Exp $ */ /* $NetBSD: rtsock.c,v 1.18 1996/03/29 00:32:10 cgd Exp $ */ /* @@ -2136,11 +2136,17 @@ sysctl_ifnames(struct walkarg *w) int sysctl_source(int af, u_int tableid, struct walkarg *w) { + union { + struct sockaddr_in in; +#ifdef INET6 + struct sockaddr_in6 in6; +#endif + } buf; struct sockaddr *sa; int size, error = 0; - sa = rtable_getsource(tableid, af); - if (sa) { + NET_LOCK_SHARED(); + if ((sa = rtable_getsource(tableid, af)) != NULL) { switch (sa->sa_family) { case AF_INET: size = sizeof(struct sockaddr_in); @@ -2151,11 +2157,19 @@ sysctl_source(int af, u_int tableid, struct walkarg *w) break; #endif default: - return (0); + sa = NULL; + break; } + + } + if (sa != NULL) + memcpy(&buf, sa, size); + NET_UNLOCK_SHARED(); + + if (sa != NULL) { w->w_needed += size; if (w->w_where && w->w_needed <= w->w_given) { - if ((error = copyout(sa, w->w_where, size))) + if ((error = copyout(&buf, w->w_where, size))) return (error); w->w_where += size; } @@ -2236,7 +2250,6 @@ sysctl_rtable(int *name, u_int namelen, void *where, size_t *given, void *new, tableid = w.w_arg; if (!rtable_exists(tableid)) return (ENOENT); - NET_LOCK_SHARED(); for (i = 1; i <= AF_MAX; i++) { if (af != 0 && af != i) continue; @@ -2247,7 +2260,6 @@ sysctl_rtable(int *name, u_int namelen, void *where, size_t *given, void *new, if (error) break; } - NET_UNLOCK_SHARED(); break; } free(w.w_tmem, M_RTABLE, w.w_tmemsize);