Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 20 May 2021 05:59:46 GMT
From:      Lutz Donnerhacke <donner@FreeBSD.org>
To:        src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-branches@FreeBSD.org
Subject:   git: 1165cafa0bae - stable/12 - netgraph/ng_bridge: Handle send errors during loop handling
Message-ID:  <202105200559.14K5xkL8079722@gitrepo.freebsd.org>

next in thread | raw e-mail | index | archive | help
The branch stable/12 has been updated by donner:

URL: https://cgit.FreeBSD.org/src/commit/?id=1165cafa0baee55a46459e4cf7c2573ca25a0a1c

commit 1165cafa0baee55a46459e4cf7c2573ca25a0a1c
Author:     Lutz Donnerhacke <donner@FreeBSD.org>
AuthorDate: 2021-04-27 07:49:50 +0000
Commit:     Lutz Donnerhacke <donner@FreeBSD.org>
CommitDate: 2021-05-20 05:58:30 +0000

    netgraph/ng_bridge: Handle send errors during loop handling
    
    If sending out a packet fails during the loop over all links, the
    allocated memory is leaked and not all links receive a copy.  This
    patch fixes those problems, clarifies a premature abort of the loop,
    and fixes a minory style(9) bug.
    
    PR:             255430
    Submitted by:   Dancho Penev
    Tested by:      Dancho Penev
    Differential Revision: https://reviews.freebsd.org/D30008
    
    (cherry picked from commit a56e5ad6903037861457da754574b4903dcb0e7e)
---
 sys/netgraph/ng_bridge.c | 57 ++++++++++++++++++++++++++----------------------
 1 file changed, 31 insertions(+), 26 deletions(-)

diff --git a/sys/netgraph/ng_bridge.c b/sys/netgraph/ng_bridge.c
index 5917c1084527..3243319c99e8 100644
--- a/sys/netgraph/ng_bridge.c
+++ b/sys/netgraph/ng_bridge.c
@@ -707,22 +707,28 @@ ng_bridge_send_data(link_cp dst, int manycast, struct mbuf *m, item_p item) {
 	else
 		NG_SEND_DATA_ONLY(error, dst->hook, m);
 
-	if (error == 0) {
-		counter_u64_add(dst->stats.xmitPackets, 1);
-		counter_u64_add(dst->stats.xmitOctets, len);
-		switch (manycast) {
-		default:		       /* unknown unicast */
-			break;
-		case 1:			       /* multicast */
-			counter_u64_add(dst->stats.xmitMulticasts, 1);
-			break;
-		case 2:			       /* broadcast */
-			counter_u64_add(dst->stats.xmitBroadcasts, 1);
-			break;
-		}
+	if (error) {
+		/* The packet is still ours */
+		if (item != NULL)
+			NG_FREE_ITEM(item);
+		if (m != NULL)
+			NG_FREE_M(m);
+		return (error);
 	}
 
-	return (error);
+	counter_u64_add(dst->stats.xmitPackets, 1);
+	counter_u64_add(dst->stats.xmitOctets, len);
+	switch (manycast) {
+	default:		       /* unknown unicast */
+		break;
+	case 1:			       /* multicast */
+		counter_u64_add(dst->stats.xmitMulticasts, 1);
+		break;
+	case 2:			       /* broadcast */
+		counter_u64_add(dst->stats.xmitBroadcasts, 1);
+		break;
+	}
+	return (0);
 }
 
 /*
@@ -760,16 +766,16 @@ ng_bridge_send_ctx(hook_p dst, void *arg)
 	 * It's usable link but not the reserved (first) one.
 	 * Copy mbuf info for sending.
 	 */
-	m2 = m_dup(ctx->m, M_NOWAIT);	/* XXX m_copypacket() */
+	m2 = m_dup(ctx->m, M_NOWAIT);
 	if (m2 == NULL) {
 		counter_u64_add(ctx->incoming->stats.memoryFailures, 1);
 		ctx->error = ENOBUFS;
-		return (0);	       /* abort loop */
+		return (0);	       /* abort loop, do not try again and again */
 	}
 
 	/* Send packet */
 	error = ng_bridge_send_data(destLink, ctx->manycast, m2, NULL);
-	if(error)
+	if (error)
 	  ctx->error = error;
 	return (1);
 }
@@ -922,18 +928,17 @@ ng_bridge_rcvdata(hook_p hook, item_p item)
 	/* Distribute unknown, multicast, broadcast pkts to all other links */
 	NG_NODE_FOREACH_HOOK(node, ng_bridge_send_ctx, &ctx, ret);
 
-	/* If we never saw a good link, leave. */
-	if (ctx.foundFirst == NULL || ctx.error != 0) {
+	/* Finally send out on the first link found */
+	if (ctx.foundFirst != NULL) {
+		int error = ng_bridge_send_data(ctx.foundFirst, ctx.manycast, ctx.m, item);
+		if (error)
+			ctx.error = error;
+	} else {		       /* nothing to send at all */
 		NG_FREE_ITEM(item);
 		NG_FREE_M(ctx.m);
-		return (ctx.error);
 	}
-	
-	/*
-	 * If we've sent all the others, send the original
-	 * on the first link we found.
-	 */
-	return (ng_bridge_send_data(ctx.foundFirst, ctx.manycast, ctx.m, item));
+
+	return (ctx.error);
 }
 
 /*



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?202105200559.14K5xkL8079722>