Index: sys/net/if.c =================================================================== RCS file: /mount/openbsd/cvs/src/sys/net/if.c,v diff -u -p -u -p -r1.721 if.c --- sys/net/if.c 17 Oct 2024 05:02:12 -0000 1.721 +++ sys/net/if.c 17 Jan 2025 23:31:11 -0000 @@ -981,6 +981,7 @@ void if_input_process(struct ifnet *ifp, struct mbuf_list *ml) { struct mbuf *m; + struct softnet_storage thread_storage; if (ml_empty(ml)) return; @@ -995,10 +996,32 @@ if_input_process(struct ifnet *ifp, stru * read only or MP safe. Usually they hold the exclusive net lock. */ + ml_init(&thread_storage.sns_ml_tcp); + ml_init(&thread_storage.sns_ml_tcp6); + NET_LOCK_SHARED(); - while ((m = ml_dequeue(ml)) != NULL) + while ((m = ml_dequeue(ml)) != NULL) { + m->m_pkthdr.ph_cookie = &thread_storage; (*ifp->if_input)(ifp, m); + } NET_UNLOCK_SHARED(); + + NET_LOCK(); + while ((m = ml_dequeue(&thread_storage.sns_ml_tcp)) != NULL) { + int off, nxt; + + off = (long)m->m_pkthdr.ph_cookie; + nxt = tcp_input(&m, &off, IPPROTO_TCP, AF_INET); + KASSERT(nxt == IPPROTO_DONE); + } + while ((m = ml_dequeue(&thread_storage.sns_ml_tcp6)) != NULL) { + int off, nxt; + + off = (long)m->m_pkthdr.ph_cookie; + nxt = tcp_input(&m, &off, IPPROTO_TCP, AF_INET6); + KASSERT(nxt == IPPROTO_DONE); + } + NET_UNLOCK(); } void Index: sys/net/if_var.h =================================================================== RCS file: /mount/openbsd/cvs/src/sys/net/if_var.h,v diff -u -p -u -p -r1.133 if_var.h --- sys/net/if_var.h 12 Oct 2024 23:18:10 -0000 1.133 +++ sys/net/if_var.h 17 Jan 2025 23:31:11 -0000 @@ -292,6 +292,11 @@ struct ifg_list { #define IF_WWAN_DEFAULT_PRIORITY 6 #define IF_CARP_DEFAULT_PRIORITY 15 +struct softnet_storage { + struct mbuf_list sns_ml_tcp; + struct mbuf_list sns_ml_tcp6; +}; + /* * Network stack input queues. */ Index: sys/netinet/in_proto.c =================================================================== RCS file: /mount/openbsd/cvs/src/sys/netinet/in_proto.c,v diff -u -p -u -p -r1.121 in_proto.c --- sys/netinet/in_proto.c 5 Jan 2025 12:36:48 -0000 1.121 +++ sys/netinet/in_proto.c 17 Jan 2025 23:31:11 -0000 @@ -197,7 +197,8 @@ const struct protosw inetsw[] = { .pr_type = SOCK_STREAM, .pr_domain = &inetdomain, .pr_protocol = IPPROTO_TCP, - .pr_flags = PR_CONNREQUIRED|PR_WANTRCVD|PR_ABRTACPTDIS|PR_SPLICE, + .pr_flags = PR_CONNREQUIRED|PR_WANTRCVD|PR_ABRTACPTDIS|PR_SPLICE| + PR_MPINPUT, .pr_input = tcp_input, .pr_ctlinput = tcp_ctlinput, .pr_ctloutput = tcp_ctloutput, Index: sys/netinet/ip_input.c =================================================================== RCS file: /mount/openbsd/cvs/src/sys/netinet/ip_input.c,v diff -u -p -u -p -r1.403 ip_input.c --- sys/netinet/ip_input.c 3 Jan 2025 21:27:40 -0000 1.403 +++ sys/netinet/ip_input.c 17 Jan 2025 23:31:11 -0000 @@ -825,6 +825,20 @@ ip_deliver(struct mbuf **mp, int *offp, naf = af; break; } + if (nxt == IPPROTO_TCP) { + struct softnet_storage *thread_storage; + struct mbuf_list *ml; + + thread_storage = (*mp)->m_pkthdr.ph_cookie; + (*mp)->m_pkthdr.ph_cookie = (void *)(long)(*offp); + if (af == AF_INET) + ml = &thread_storage->sns_ml_tcp; + if (af == AF_INET6) + ml = &thread_storage->sns_ml_tcp6; + ml_enqueue(ml, *mp); + *mp = NULL; + return IPPROTO_DONE; + } nxt = (*psw->pr_input)(mp, offp, nxt, af); af = naf; } Index: sys/netinet6/in6_proto.c =================================================================== RCS file: /mount/openbsd/cvs/src/sys/netinet6/in6_proto.c,v diff -u -p -u -p -r1.124 in6_proto.c --- sys/netinet6/in6_proto.c 5 Jan 2025 12:36:48 -0000 1.124 +++ sys/netinet6/in6_proto.c 17 Jan 2025 23:31:11 -0000 @@ -147,7 +147,8 @@ const struct protosw inet6sw[] = { .pr_type = SOCK_STREAM, .pr_domain = &inet6domain, .pr_protocol = IPPROTO_TCP, - .pr_flags = PR_CONNREQUIRED|PR_WANTRCVD|PR_ABRTACPTDIS|PR_SPLICE, + .pr_flags = PR_CONNREQUIRED|PR_WANTRCVD|PR_ABRTACPTDIS|PR_SPLICE| + PR_MPINPUT, .pr_input = tcp_input, .pr_ctlinput = tcp6_ctlinput, .pr_ctloutput = tcp_ctloutput,