Index | Thread | Search

From:
Alexander Bluhm <bluhm@openbsd.org>
Subject:
shared net lock for vxlan
To:
tech@openbsd.org
Date:
Fri, 14 Feb 2025 15:25:22 +0100

Download raw body.

Thread
Hi,

Shared net lock and socket lock should be sufficient for vxlan.

While there, check if mbuf list is empty before grabbing lock.  This
way is done in multiple places.

Also do not pass around uninitialized structures from the stack.
Use memset() to start with clean memory.

ok?

bluhm

Index: net/if_vxlan.c
===================================================================
RCS file: /data/mirror/openbsd/cvs/src/sys/net/if_vxlan.c,v
diff -u -p -r1.100 if_vxlan.c
--- net/if_vxlan.c	31 Oct 2024 11:41:31 -0000	1.100
+++ net/if_vxlan.c	13 Feb 2025 14:36:19 -0000
@@ -514,16 +514,19 @@ vxlan_send_ipv4(struct vxlan_softc *sc, 
 	struct mbuf *m;
 	uint64_t oerrors = 0;
 
+	if (ml_empty(ml))
+		return (0);
+
+	memset(&imo, 0, sizeof(struct ip_moptions));
 	imo.imo_ifidx = sc->sc_if_index0;
 	imo.imo_ttl = sc->sc_ttl;
-	imo.imo_loop = 0;
 
-	NET_LOCK();
+	NET_LOCK_SHARED();
 	while ((m = ml_dequeue(ml)) != NULL) {
 		if (ip_output(m, NULL, NULL, IP_RAWOUTPUT, &imo, NULL, 0) != 0)
 			oerrors++;
 	}
-	NET_UNLOCK();
+	NET_UNLOCK_SHARED();
 
 	return (oerrors);
 }
@@ -536,16 +539,19 @@ vxlan_send_ipv6(struct vxlan_softc *sc, 
 	struct mbuf *m;
 	uint64_t oerrors = 0;
 
+	if (ml_empty(ml))
+		return (0);
+
+	memset(&im6o, 0, sizeof(struct ip6_moptions));
 	im6o.im6o_ifidx = sc->sc_if_index0;
 	im6o.im6o_hlim = sc->sc_ttl;
-	im6o.im6o_loop = 0;
 
-	NET_LOCK();
+	NET_LOCK_SHARED();
 	while ((m = ml_dequeue(ml)) != NULL) {
 		if (ip6_output(m, NULL, NULL, 0, &im6o, NULL) != 0)
 			oerrors++;
 	}
-	NET_UNLOCK();
+	NET_UNLOCK_SHARED();
 
 	return (oerrors);
 }
@@ -932,10 +938,10 @@ vxlan_tep_add_addr(struct vxlan_softc *s
 	if (error != 0)
 		goto free;
 
-	solock(so);
+	solock_shared(so);
 	sotoinpcb(so)->inp_upcall = vxlan_input;
 	sotoinpcb(so)->inp_upcall_arg = vt;
-	sounlock(so);
+	sounlock_shared(so);
 
 	m_inithdr(&m);
 	m.m_len = sizeof(vt->vt_rdomain);
@@ -972,9 +978,9 @@ vxlan_tep_add_addr(struct vxlan_softc *s
 		unhandled_af(vt->vt_af);
 	}
 
-	solock(so);
+	solock_shared(so);
 	error = sobind(so, &m, curproc);
-	sounlock(so);
+	sounlock_shared(so);
 	if (error != 0)
 		goto close;