summaryrefslogtreecommitdiff
path: root/sys/netinet6
diff options
context:
space:
mode:
authorAlexander Bluhm <bluhm@cvs.openbsd.org>2024-04-14 20:46:28 +0000
committerAlexander Bluhm <bluhm@cvs.openbsd.org>2024-04-14 20:46:28 +0000
commit5c6d6b35e40181740a26e9b53e8c934b8f820e5d (patch)
tree1406a2b67b327c4dde0521608fad64bb439002c7 /sys/netinet6
parentcf13447ce05de37c8d9cbd1c36f316eb371b7eab (diff)
Run raw IP input in parallel.
Running raw IPv4 input with shared net lock in parallel is less complex than UDP. Especially there is no socket splicing. New ip_deliver() may run with shared or exclusive net lock. The last parameter indicates the mode. If is is running with shared netlock and encounters a protocol that needs exclusive lock, the packet is queued. Old ip_ours() always queued the packet. Now it calls ip_deliver() with shared net lock, and if that cannot handle the packet completely, the packet is queued and later processed with exclusive net lock. In case of an IPv6 header chain, that switches from shared to exclusive processing, the next protocol and mbuf offset are stored in a mbuf tag. OK mvs@
Diffstat (limited to 'sys/netinet6')
-rw-r--r--sys/netinet6/ip6_input.c21
1 files changed, 10 insertions, 11 deletions
diff --git a/sys/netinet6/ip6_input.c b/sys/netinet6/ip6_input.c
index 112fe60376d..5f4e991e0f8 100644
--- a/sys/netinet6/ip6_input.c
+++ b/sys/netinet6/ip6_input.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ip6_input.c,v 1.259 2024/02/28 10:57:20 bluhm Exp $ */
+/* $OpenBSD: ip6_input.c,v 1.260 2024/04/14 20:46:27 bluhm Exp $ */
/* $KAME: ip6_input.c,v 1.188 2001/03/29 05:34:31 itojun Exp $ */
/*
@@ -166,11 +166,6 @@ ip6_init(void)
#endif
}
-struct ip6_offnxt {
- int ion_off;
- int ion_nxt;
-};
-
/*
* Enqueue packet for local delivery. Queuing is used as a boundary
* between the network layer (input/forward path) running with
@@ -190,10 +185,14 @@ ip6_ours(struct mbuf **mp, int *offp, int nxt, int af)
if (af != AF_UNSPEC)
return nxt;
+ nxt = ip_deliver(mp, offp, nxt, AF_INET6, 1);
+ if (nxt == IPPROTO_DONE)
+ return IPPROTO_DONE;
+
/* save values for later, use after dequeue */
if (*offp != sizeof(struct ip6_hdr)) {
struct m_tag *mtag;
- struct ip6_offnxt *ion;
+ struct ipoffnxt *ion;
/* mbuf tags are expensive, but only used for header options */
mtag = m_tag_get(PACKET_TAG_IP6_OFFNXT, sizeof(*ion),
@@ -203,7 +202,7 @@ ip6_ours(struct mbuf **mp, int *offp, int nxt, int af)
m_freemp(mp);
return IPPROTO_DONE;
}
- ion = (struct ip6_offnxt *)(mtag + 1);
+ ion = (struct ipoffnxt *)(mtag + 1);
ion->ion_off = *offp;
ion->ion_nxt = nxt;
@@ -234,9 +233,9 @@ ip6intr(void)
#endif
mtag = m_tag_find(m, PACKET_TAG_IP6_OFFNXT, NULL);
if (mtag != NULL) {
- struct ip6_offnxt *ion;
+ struct ipoffnxt *ion;
- ion = (struct ip6_offnxt *)(mtag + 1);
+ ion = (struct ipoffnxt *)(mtag + 1);
off = ion->ion_off;
nxt = ion->ion_nxt;
@@ -248,7 +247,7 @@ ip6intr(void)
off = sizeof(struct ip6_hdr);
nxt = ip6->ip6_nxt;
}
- nxt = ip_deliver(&m, &off, nxt, AF_INET6);
+ nxt = ip_deliver(&m, &off, nxt, AF_INET6, 0);
KASSERT(nxt == IPPROTO_DONE);
}
}