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 <ivansprun...@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 */
 };
 
_______________________________________________
svn-src-head@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-head
To unsubscribe, send any mail to "svn-src-head-unsubscr...@freebsd.org"

Reply via email to