svn commit: r356029 - in head: sbin/ifconfig share/man/man4 sys/net

Mark Johnston markj at FreeBSD.org
Sun Dec 22 21:56:48 UTC 2019


Author: markj
Date: Sun Dec 22 21:56:47 2019
New Revision: 356029
URL: https://svnweb.freebsd.org/changeset/base/356029

Log:
  lagg: Clean up handling of the rr_limit option.
  
  - Don't allow an unprivileged user to set the stride. [1]
  - Only set the stride under the softc lock.
  - Rename the internal fields to accurately reflect their use.  Keep
    ro_bkt to avoid changing the user API.
  - Simplify the implementation.  The port index is just sc_seq / stride.
  - Document rr_limit in ifconfig.8.
  
  Reported by:	Ilja Van Sprundel <ivansprundel at ioactive.com> [1]
  MFC after:	1 week
  Sponsored by:	The FreeBSD Foundation
  Differential Revision:	https://reviews.freebsd.org/D22857

Modified:
  head/sbin/ifconfig/ifconfig.8
  head/share/man/man4/lagg.4
  head/sys/net/if_lagg.c
  head/sys/net/if_lagg.h

Modified: head/sbin/ifconfig/ifconfig.8
==============================================================================
--- head/sbin/ifconfig/ifconfig.8	Sun Dec 22 21:53:05 2019	(r356028)
+++ head/sbin/ifconfig/ifconfig.8	Sun Dec 22 21:56:47 2019	(r356029)
@@ -28,7 +28,7 @@
 .\"     From: @(#)ifconfig.8	8.3 (Berkeley) 1/5/94
 .\" $FreeBSD$
 .\"
-.Dd August 26, 2019
+.Dd December 17, 2019
 .Dt IFCONFIG 8
 .Os
 .Sh NAME
@@ -2567,6 +2567,9 @@ means
 .Dq enabled .
 .It Cm -lacp_strict
 Disable lacp strict compliance on the interface.
+.It Cm rr_limit Ar number
+Configure a stride for an interface in round-robin mode.
+The default stride is 1.
 .El
 .Pp
 The following parameters apply to IP tunnel interfaces,

Modified: head/share/man/man4/lagg.4
==============================================================================
--- head/share/man/man4/lagg.4	Sun Dec 22 21:53:05 2019	(r356028)
+++ head/share/man/man4/lagg.4	Sun Dec 22 21:56:47 2019	(r356029)
@@ -166,7 +166,7 @@ Gigabit Ethernet interfaces:
 .Pp
 Create a link aggregation using ROUNDROBIN with two
 .Xr bge 4
-Gigabit Ethernet interfaces and set the limit of 500 packets
+Gigabit Ethernet interfaces and set a stride of 500 packets
 per interface:
 .Bd -literal -offset indent
 # ifconfig bge0 up

Modified: head/sys/net/if_lagg.c
==============================================================================
--- head/sys/net/if_lagg.c	Sun Dec 22 21:53:05 2019	(r356028)
+++ head/sys/net/if_lagg.c	Sun Dec 22 21:56:47 2019	(r356029)
@@ -1245,23 +1245,38 @@ lagg_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data
 			CK_SLIST_FOREACH(lp, &sc->sc_ports, lp_entries)
 				ro->ro_active += LAGG_PORTACTIVE(lp);
 		}
-		ro->ro_bkt = sc->sc_bkt;
+		ro->ro_bkt = sc->sc_stride;
 		ro->ro_flapping = sc->sc_flapping;
 		ro->ro_flowid_shift = sc->flowid_shift;
 		LAGG_XUNLOCK(sc);
 		break;
 	case SIOCSLAGGOPTS:
-		if (sc->sc_proto == LAGG_PROTO_ROUNDROBIN) {
-			if (ro->ro_bkt == 0)
-				sc->sc_bkt = 1; // Minimum 1 packet per iface.
-			else
-				sc->sc_bkt = ro->ro_bkt;
-		}
 		error = priv_check(td, PRIV_NET_LAGG);
 		if (error)
 			break;
-		if (ro->ro_opts == 0)
+
+		/*
+		 * The stride option was added without defining a corresponding
+		 * LAGG_OPT flag, so we must handle it before processing any
+		 * remaining options.
+		 */
+		LAGG_XLOCK(sc);
+		if (ro->ro_bkt != 0) {
+			if (sc->sc_proto != LAGG_PROTO_ROUNDROBIN) {
+				LAGG_XUNLOCK(sc);
+				error = EINVAL;
+				break;
+			}
+			sc->sc_stride = ro->ro_bkt;
+		} else {
+			sc->sc_stride = 0;
+		}
+
+		if (ro->ro_opts == 0) {
+			LAGG_XUNLOCK(sc);
 			break;
+		}
+
 		/*
 		 * Set options.  LACP options are stored in sc->sc_psc,
 		 * not in sc_opts.
@@ -1292,8 +1307,6 @@ lagg_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data
 			break;
 		}
 
-		LAGG_XLOCK(sc);
-
 		if (valid == 0 ||
 		    (lacp == 1 && sc->sc_proto != LAGG_PROTO_LACP)) {
 			/* Invalid combination of options specified. */
@@ -2033,7 +2046,6 @@ static void
 lagg_rr_attach(struct lagg_softc *sc)
 {
 	sc->sc_seq = 0;
-	sc->sc_bkt_count = sc->sc_bkt;
 }
 
 static int
@@ -2042,17 +2054,9 @@ lagg_rr_start(struct lagg_softc *sc, struct mbuf *m)
 	struct lagg_port *lp;
 	uint32_t p;
 
-	if (sc->sc_bkt_count == 0 && sc->sc_bkt > 0)
-		sc->sc_bkt_count = sc->sc_bkt;
-
-	if (sc->sc_bkt > 0) {
-		atomic_subtract_int(&sc->sc_bkt_count, 1);
-	if (atomic_cmpset_int(&sc->sc_bkt_count, 0, sc->sc_bkt))
-		p = atomic_fetchadd_32(&sc->sc_seq, 1);
-	else
-		p = sc->sc_seq; 
-	} else
-		p = atomic_fetchadd_32(&sc->sc_seq, 1);
+	p = atomic_fetchadd_32(&sc->sc_seq, 1);
+	if (sc->sc_stride > 0)
+		p /= sc->sc_stride;
 
 	p %= sc->sc_count;
 	lp = CK_SLIST_FIRST(&sc->sc_ports);

Modified: head/sys/net/if_lagg.h
==============================================================================
--- head/sys/net/if_lagg.h	Sun Dec 22 21:53:05 2019	(r356028)
+++ head/sys/net/if_lagg.h	Sun Dec 22 21:56:47 2019	(r356029)
@@ -153,7 +153,7 @@ struct lagg_reqopts {
 	u_int			ro_active;		/* active port count */
 	u_int			ro_flapping;		/* number of flapping */
 	int			ro_flowid_shift;	/* shift the flowid */
-	uint32_t		ro_bkt;			/* packet bucket for roundrobin */
+	uint32_t		ro_bkt;			/* stride for RR */
 };
 
 #define	SIOCGLAGGOPTS		_IOWR('i', 152, struct lagg_reqopts)
@@ -216,6 +216,7 @@ struct lagg_softc {
 	struct ifmedia			sc_media;	/* media config */
 	void				*sc_psc;	/* protocol data */
 	uint32_t			sc_seq;		/* sequence counter */
+	uint32_t			sc_stride;	/* stride for RR */
 	uint32_t			sc_flags;
 	int				sc_destroying;	/* destroying lagg */
 
@@ -227,8 +228,6 @@ struct lagg_softc {
 	struct callout			sc_callout;
 	u_int				sc_opts;
 	int				flowid_shift;	/* shift the flowid */
-	uint32_t			sc_bkt;		/* packates bucket for roundrobin */
-	uint32_t			sc_bkt_count;	/* packates bucket count for roundrobin */
 	struct lagg_counters		detached_counters; /* detached ports sum */
 };
 


More information about the svn-src-head mailing list