Howdy.

Attached is a patch from my work that started at g2k18 on adding
administrative knobs to our LACP driver.

The driver now has a new ioctl (SIOCxTRUNKOPTS), which for now only
has options for LACP:
* Mode - Active or Passive (default Active)
* Timeout - Fast or Slow (default Slow)
* System Priority - 1(high) to 65535(low) (default 32768)
* Port Priority - 1(high) to 65535(low) (default 32768)
* IFQ Priority - 0 to NUM_QUEUES (default 6)

At the moment, ifconfig only has options for lacpmode and lacptimeout
plumbed as those are the immediate need.

The approach taken for the options was to make them on a "trunk" vs a
"port" as what's typically seen on various NOSes (JunOS, NXOS, etc...)
as it's uncommon for a host to have one link "Passive" and the other
"Active" in a given trunk.

Just like on a NOS, when applying lacpmode or lacptimeout, the settings
are immediately applied to all existing ports in the trunk and to all
future ports brought into the trunk.

When using lacpmode/lacptimeout, they can be used on the same line
creating the trunk.

Here's an example hostname.trunk0:
trunkproto lacp lacptimeout fast
trunkport em0
trunkport em1
dhcp
inet6 autoconf

Testing done:
Arch - amd64
- Kernel: bsd.rd and GENERIC.MP
- NIC Driver: em and oce
- NOS: JunOS 18.1
- MLAG-SETUP: No

I would like to solicit testers with additional NIC drivers, NOSes, and
MLAG setups to ensure there's no regressions.

Comments? Ok?

+--+
Carlos
Index: sbin/ifconfig/ifconfig.8
===================================================================
RCS file: /home/los/cvs/src/sbin/ifconfig/ifconfig.8,v
retrieving revision 1.312
diff -u -p -r1.312 ifconfig.8
--- sbin/ifconfig/ifconfig.8    19 Jul 2018 19:16:36 -0000      1.312
+++ sbin/ifconfig/ifconfig.8    6 Aug 2018 18:24:11 -0000
@@ -1627,6 +1627,16 @@ Set the trunk protocol.
 Refer to
 .Xr trunk 4
 for a complete list of the available protocols.
+.It Cm lacpmode Ar mode
+Set the LACP trunk mode to either
+.Ar active
+or
+.Ar passive .
+.It Cm lacptimeout Ar speed
+Set the LACP timeout speed to either
+.Ar fast
+or
+.Ar slow .
 .El
 .Sh TUNNEL
 .nr nS 1
Index: sbin/ifconfig/ifconfig.c
===================================================================
RCS file: /home/los/cvs/src/sbin/ifconfig/ifconfig.c,v
retrieving revision 1.369
diff -u -p -r1.369 ifconfig.c
--- sbin/ifconfig/ifconfig.c    13 Jul 2018 08:41:32 -0000      1.369
+++ sbin/ifconfig/ifconfig.c    6 Aug 2018 18:24:11 -0000
@@ -170,7 +170,12 @@ int        shownet80211chans;
 int    shownet80211nodes;
 int    showclasses;
 
-struct ifencap;
+struct ifencap;
+
+const  char *lacpmodeactive = "active";
+const  char *lacpmodepassive = "passive";
+const  char *lacptimeoutfast = "fast";
+const  char *lacptimeoutslow = "slow";
 
 void   notealias(const char *, int);
 void   setifaddr(const char *, int);
@@ -252,6 +257,8 @@ void        setautoconf(const char *, int);
 void   settrunkport(const char *, int);
 void   unsettrunkport(const char *, int);
 void   settrunkproto(const char *, int);
+void   settrunklacpmode(const char *, int);
+void   settrunklacptimeout(const char *, int);
 void   trunk_status(void);
 void   list_cloners(void);
 
@@ -408,6 +415,8 @@ const struct        cmd {
        { "trunkport",  NEXTARG,        0,              settrunkport },
        { "-trunkport", NEXTARG,        0,              unsettrunkport },
        { "trunkproto", NEXTARG,        0,              settrunkproto },
+       { "lacpmode",   NEXTARG,        0,              settrunklacpmode },
+       { "lacptimeout", NEXTARG,       0,              settrunklacptimeout },
        { "anycast",    IN6_IFF_ANYCAST,        0,      setia6flags },
        { "-anycast",   -IN6_IFF_ANYCAST,       0,      setia6flags },
        { "tentative",  IN6_IFF_TENTATIVE,      0,      setia6flags },
@@ -3990,6 +3999,77 @@ settrunkproto(const char *val, int d)
        strlcpy(ra.ra_ifname, name, sizeof(ra.ra_ifname));
        if (ioctl(s, SIOCSTRUNK, &ra) != 0)
                err(1, "SIOCSTRUNK");
+}
+
+void
+settrunklacpmode(const char *val, int d)
+{
+       struct trunk_reqall ra;
+       struct trunk_opts tops;
+
+       bzero(&ra, sizeof(ra));
+       strlcpy(ra.ra_ifname, name, sizeof(ra.ra_ifname));
+
+       if (ioctl(s, SIOCGTRUNK, &ra) != 0)
+               err(1, "SIOCGTRUNK");
+
+       if (ra.ra_proto != TRUNK_PROTO_LACP) {
+               printf("proto: %d\n", ra.ra_proto);
+               errx(1, "Invalid option for trunk: %s", name);
+       } else {
+               if (strcmp(val, lacpmodeactive) != 0 &&
+                   strcmp(val, lacpmodepassive) != 0) {
+                       errx(1, "Invalid lacpmode option for trunk: %s", name);
+               }
+
+               bzero(&tops, sizeof(tops));
+               strlcpy(tops.to_ifname, name, sizeof(tops.to_ifname));
+               tops.to_proto = TRUNK_PROTO_LACP;
+               tops.to_opts |= TRUNK_OPT_LACP_MODE;
+               if (strcmp(val, lacpmodeactive) == 0)
+                       tops.to_lacpopts.lacp_mode = 1;
+               else
+                       tops.to_lacpopts.lacp_mode = 0;
+
+               if (ioctl(s, SIOCSTRUNKOPTS, &tops) != 0)
+                       err(1, "SIOCSTRUNKOPTS");
+       }
+}
+
+void
+settrunklacptimeout(const char *val, int d)
+{
+       struct trunk_reqall ra;
+       struct trunk_opts tops;
+
+       bzero(&ra, sizeof(ra));
+       strlcpy(ra.ra_ifname, name, sizeof(ra.ra_ifname));
+
+       if (ioctl(s, SIOCGTRUNK, &ra) != 0)
+               err(1, "SIOCGTRUNK");
+
+       if (ra.ra_proto != TRUNK_PROTO_LACP) {
+               printf("proto: %d\n", ra.ra_proto);
+               errx(1, "Invalid option for trunk: %s", name);
+       } else {
+               if (strcmp(val, lacptimeoutfast) != 0 &&
+                   strcmp(val, lacptimeoutslow) != 0) {
+                       errx(1, "Invalid lacptimeout option for trunk: %s",
+                           name);
+               }
+
+               bzero(&tops, sizeof(tops));
+               strlcpy(tops.to_ifname, name, sizeof(tops.to_ifname));
+               tops.to_proto = TRUNK_PROTO_LACP;
+               tops.to_opts |= TRUNK_OPT_LACP_TIMEOUT;
+               if (strcmp(val, lacptimeoutfast) == 0)
+                       tops.to_lacpopts.lacp_timeout = 1;
+               else
+                       tops.to_lacpopts.lacp_timeout = 0;
+
+               if (ioctl(s, SIOCSTRUNKOPTS, &tops) != 0)
+                       err(1, "SIOCSTRUNKOPTS");
+       }
 }
 
 void
Index: sys/net/if_trunk.c
===================================================================
RCS file: /home/los/cvs/src/sys/net/if_trunk.c,v
retrieving revision 1.136
diff -u -p -r1.136 if_trunk.c
--- sys/net/if_trunk.c  19 Feb 2018 08:59:52 -0000      1.136
+++ sys/net/if_trunk.c  6 Aug 2018 18:24:11 -0000
@@ -604,8 +604,11 @@ trunk_ioctl(struct ifnet *ifp, u_long cm
        struct trunk_softc *tr = (struct trunk_softc *)ifp->if_softc;
        struct trunk_reqall *ra = (struct trunk_reqall *)data;
        struct trunk_reqport *rp = (struct trunk_reqport *)data, rpbuf;
+       struct trunk_opts *tro = (struct trunk_opts *)data;
        struct ifreq *ifr = (struct ifreq *)data;
+       struct lacp_softc *lsc;
        struct trunk_port *tp;
+       struct lacp_port *lp;
        struct ifnet *tpif;
        int i, error = 0;
 
@@ -670,6 +673,94 @@ trunk_ioctl(struct ifnet *ifp, u_long cm
                        }
                }
                error = EPROTONOSUPPORT;
+               break;
+       case SIOCGTRUNKOPTS:
+               /* Only LACP trunks have options atm */
+               if (tro->to_proto != TRUNK_PROTO_LACP) {
+                       error = EPROTONOSUPPORT;
+                       break;
+               }
+               lsc = LACP_SOFTC(tr);
+               tro->to_lacpopts.lacp_mode = lsc->lsc_mode;
+               tro->to_lacpopts.lacp_timeout = lsc->lsc_timeout;
+               tro->to_lacpopts.lacp_prio = lsc->lsc_sys_prio;
+               tro->to_lacpopts.lacp_portprio = lsc->lsc_port_prio;
+               tro->to_lacpopts.lacp_ifqprio = lsc->lsc_ifq_prio;
+               break;
+       case SIOCSTRUNKOPTS:
+               if ((error = suser(curproc)) != 0) {
+                       error = EPERM;
+                       break;
+               }
+               /* Only LACP trunks have options atm */
+               if (tro->to_proto != TRUNK_PROTO_LACP) {
+                       error = EPROTONOSUPPORT;
+                       break;
+               }
+               lsc = LACP_SOFTC(tr);
+               switch(tro->to_opts) {
+                       case TRUNK_OPT_LACP_MODE:
+                               /*
+                                * Ensure mode changes occur immediately
+                                * on all ports
+                                */
+                               lsc->lsc_mode = tro->to_lacpopts.lacp_mode;
+                               if (lsc->lsc_mode == 0) {
+                                       LIST_FOREACH(lp, &lsc->lsc_ports,
+                                           lp_next)
+                                               lp->lp_state &=
+                                                   ~LACP_STATE_ACTIVITY;
+                               } else {
+                                       LIST_FOREACH(lp, &lsc->lsc_ports,
+                                           lp_next)
+                                               lp->lp_state |=
+                                                   LACP_STATE_ACTIVITY;
+                               }
+                               break;
+                       case TRUNK_OPT_LACP_TIMEOUT:
+                               /*
+                                * Ensure timeout changes occur immediately
+                                * on all ports
+                                */
+                               lsc->lsc_timeout =
+                                   tro->to_lacpopts.lacp_timeout;
+                               if (lsc->lsc_timeout == 0) {
+                                       LIST_FOREACH(lp, &lsc->lsc_ports,
+                                           lp_next)
+                                               lp->lp_state &=
+                                                   ~LACP_STATE_TIMEOUT;
+                               } else {
+                                       LIST_FOREACH(lp, &lsc->lsc_ports,
+                                           lp_next)
+                                               lp->lp_state |=
+                                                   LACP_STATE_TIMEOUT;
+                               }
+                               break;
+                       case TRUNK_OPT_LACP_SYS_PRIO:
+                               if (tro->to_lacpopts.lacp_prio == 0) {
+                                       error = EINVAL; 
+                                       break;
+                               }
+                               lsc->lsc_sys_prio = tro->to_lacpopts.lacp_prio;
+                               break;
+                       case TRUNK_OPT_LACP_PORT_PRIO:
+                               if (tro->to_lacpopts.lacp_portprio == 0) {
+                                       error = EINVAL; 
+                                       break;
+                               }
+                               lsc->lsc_port_prio =
+                                   tro->to_lacpopts.lacp_portprio;
+                               break;
+                       case TRUNK_OPT_LACP_IFQ_PRIO:
+                               if (tro->to_lacpopts.lacp_ifqprio >
+                                   IFQ_MAXPRIO) {
+                                       error = EINVAL; 
+                                       break;
+                               }
+                               lsc->lsc_ifq_prio =
+                                   tro->to_lacpopts.lacp_ifqprio;
+                               break;
+               }
                break;
        case SIOCGTRUNKPORT:
                if (rp->rp_portname[0] == '\0' ||
Index: sys/net/if_trunk.h
===================================================================
RCS file: /home/los/cvs/src/sys/net/if_trunk.h,v
retrieving revision 1.25
diff -u -p -r1.25 if_trunk.h
--- sys/net/if_trunk.h  23 Sep 2015 12:40:12 -0000      1.25
+++ sys/net/if_trunk.h  6 Aug 2018 18:24:11 -0000
@@ -121,6 +121,36 @@ struct trunk_reqall {
 #define SIOCGTRUNK             _IOWR('i', 143, struct trunk_reqall)
 #define SIOCSTRUNK              _IOW('i', 144, struct trunk_reqall)
 
+/* LACP administrative options */
+struct lacp_adminopts {
+       u_int8_t                lacp_mode;              /* active or passive */
+       u_int8_t                lacp_timeout;           /* fast or slow */
+       u_int16_t               lacp_prio;              /* system priority */
+       u_int16_t               lacp_portprio;          /* port priority */
+       u_int8_t                lacp_ifqprio;           /* ifq priority */
+};
+
+/* Trunk administrative options */
+struct trunk_opts {
+       char                    to_ifname[IFNAMSIZ];    /* name of the trunk */
+       u_int                   to_proto;               /* trunk protocol */
+       int                     to_opts;                /* option bitmap */
+#define TRUNK_OPT_NONE                 0x00
+#define TRUNK_OPT_LACP_MODE            0x01            /* set active bit */
+#define TRUNK_OPT_LACP_TIMEOUT         0x02            /* set timeout bit */
+#define TRUNK_OPT_LACP_SYS_PRIO                0x04            /* set sys_prio 
bit */
+#define TRUNK_OPT_LACP_PORT_PRIO       0x08            /* set port_prio bit */
+#define TRUNK_OPT_LACP_IFQ_PRIO                0x10            /* set ifq_prio 
bit */
+
+       union {
+               struct lacp_adminopts rpsc_lacp;
+       } to_psc;
+#define to_lacpopts    to_psc.rpsc_lacp
+};
+
+#define SIOCGTRUNKOPTS         _IOWR('i', 145, struct trunk_opts)
+#define SIOCSTRUNKOPTS          _IOW('i', 146, struct trunk_opts)
+
 #ifdef _KERNEL
 /*
  * Internal kernel part
Index: sys/net/trunklacp.c
===================================================================
RCS file: /home/los/cvs/src/sys/net/trunklacp.c,v
retrieving revision 1.29
diff -u -p -r1.29 trunklacp.c
--- sys/net/trunklacp.c 24 Jan 2017 10:08:30 -0000      1.29
+++ sys/net/trunklacp.c 6 Aug 2018 18:24:11 -0000
@@ -58,14 +58,6 @@
 #include <net/bpf.h>
 #endif
 
-/*
- * actor system priority and port priority.
- * XXX should be configurable.
- */
-#define        LACP_SYSTEM_PRIO        0x8000
-#define        LACP_PORT_PRIO          0x8000
-#define        LACP_IFQ_PRIO           6
-
 const u_int8_t ethermulticastaddr_slowprotocols[ETHER_ADDR_LEN] =
     { 0x01, 0x80, 0xc2, 0x00, 0x00, 0x02 };
 
@@ -93,6 +85,8 @@ const struct tlv_template marker_respons
 
 typedef void (*lacp_timer_func_t)(struct lacp_port *);
 
+void           lacp_default_partner(struct lacp_softc *,
+                   struct lacp_peerinfo *);
 void           lacp_fill_actorinfo(struct lacp_port *, struct lacp_peerinfo *);
 void           lacp_fill_markerinfo(struct lacp_port *,
                    struct lacp_markerinfo *);
@@ -197,31 +191,22 @@ void              lacp_dprintf(const struct lacp_por
 #define LACP_DPRINTF(a) /* nothing */
 #endif
 
-/*
- * partner administration variables.
- * XXX should be configurable.
- */
-
-const struct lacp_peerinfo lacp_partner_admin = {
-       { 0xffff },     /* lip_systemid.lsi_prio */
-       0,              /* lip_key */
-       { 0xffff },     /* lip_portid.lpi_prio */
-#if 1
-       /* optimistic lip_state */
-       LACP_STATE_SYNC | LACP_STATE_AGGREGATION |
-           LACP_STATE_COLLECTING | LACP_STATE_DISTRIBUTING
-#else
-       /* pessimistic lip_state */
-       0
-#endif
-};
-
 const lacp_timer_func_t lacp_timer_funcs[LACP_NTIMER] = {
        [LACP_TIMER_CURRENT_WHILE] = lacp_sm_rx_timer,
        [LACP_TIMER_PERIODIC] = lacp_sm_ptx_timer,
        [LACP_TIMER_WAIT_WHILE] = lacp_sm_mux_timer,
 };
 
+void
+lacp_default_partner(struct lacp_softc *lsc, struct lacp_peerinfo *peer)
+{
+       peer->lip_systemid.lsi_prio = lsc->lsc_sys_prio;
+       peer->lip_key = 0;
+       peer->lip_portid.lpi_prio = lsc->lsc_port_prio;
+       peer->lip_state = LACP_STATE_SYNC | LACP_STATE_AGGREGATION |
+           LACP_STATE_COLLECTING | LACP_STATE_DISTRIBUTING;
+}
+
 int
 lacp_input(struct trunk_port *tp, struct mbuf *m)
 {
@@ -351,13 +336,14 @@ bad:
 void
 lacp_fill_actorinfo(struct lacp_port *lp, struct lacp_peerinfo *info)
 {
+       struct lacp_softc *lsc = lp->lp_lsc;
        struct trunk_port *tp = lp->lp_trunk;
        struct trunk_softc *sc = tp->tp_trunk;
 
-       info->lip_systemid.lsi_prio = htons(LACP_SYSTEM_PRIO);
+       info->lip_systemid.lsi_prio = htons(lsc->lsc_sys_prio);
        memcpy(&info->lip_systemid.lsi_mac,
            sc->tr_ac.ac_enaddr, ETHER_ADDR_LEN);
-       info->lip_portid.lpi_prio = htons(LACP_PORT_PRIO);
+       info->lip_portid.lpi_prio = htons(lsc->lsc_port_prio);
        info->lip_portid.lpi_portno = htons(lp->lp_ifp->if_index);
        info->lip_state = lp->lp_state;
 }
@@ -376,6 +362,7 @@ lacp_fill_markerinfo(struct lacp_port *l
 int
 lacp_xmit_lacpdu(struct lacp_port *lp)
 {
+       struct lacp_softc *lsc = lp->lp_lsc;
        struct trunk_port *tp = lp->lp_trunk;
        struct mbuf *m;
        struct lacpdu *du;
@@ -385,7 +372,7 @@ lacp_xmit_lacpdu(struct lacp_port *lp)
        if (m == NULL)
                return (ENOMEM);
        m->m_len = m->m_pkthdr.len = sizeof(*du);
-       m->m_pkthdr.pf.prio = LACP_IFQ_PRIO;
+       m->m_pkthdr.pf.prio = lsc->lsc_ifq_prio;
 
        du = mtod(m, struct lacpdu *);
        memset(du, 0, sizeof(*du));
@@ -427,6 +414,7 @@ lacp_xmit_lacpdu(struct lacp_port *lp)
 int
 lacp_xmit_marker(struct lacp_port *lp)
 {
+       struct lacp_softc *lsc = lp->lp_lsc;
        struct trunk_port *tp = lp->lp_trunk;
        struct mbuf *m;
        struct markerdu *mdu;
@@ -436,7 +424,7 @@ lacp_xmit_marker(struct lacp_port *lp)
        if (m == NULL)
                return (ENOMEM);
        m->m_len = m->m_pkthdr.len = sizeof(*mdu);
-       m->m_pkthdr.pf.prio = LACP_IFQ_PRIO;
+       m->m_pkthdr.pf.prio = lsc->lsc_ifq_prio;
 
        mdu = mtod(m, struct markerdu *);
        memset(mdu, 0, sizeof(*mdu));
@@ -522,9 +510,6 @@ lacp_port_create(struct trunk_port *tp)
        struct ifreq ifr;
        int error;
 
-       int active = 1; /* XXX should be configurable */
-       int fast = 0; /* XXX should be configurable */
-
        bzero(&ifr, sizeof(ifr));
        ifr.ifr_addr.sa_family = AF_UNSPEC;
        ifr.ifr_addr.sa_len = ETHER_ADDR_LEN;
@@ -554,8 +539,8 @@ lacp_port_create(struct trunk_port *tp)
        lacp_fill_actorinfo(lp, &lp->lp_actor);
        lacp_fill_markerinfo(lp, &lp->lp_marker);
        lp->lp_state =
-           (active ? LACP_STATE_ACTIVITY : 0) |
-           (fast ? LACP_STATE_TIMEOUT : 0);
+           (lsc->lsc_mode ? LACP_STATE_ACTIVITY : 0) |
+           (lsc->lsc_timeout ? LACP_STATE_TIMEOUT : 0);
        lp->lp_aggregator = NULL;
        lacp_sm_rx_set_expired(lp);
 
@@ -764,6 +749,13 @@ lacp_attach(struct trunk_softc *sc)
        TAILQ_INIT(&lsc->lsc_aggregators);
        LIST_INIT(&lsc->lsc_ports);
 
+       /* set default admin values */
+       lsc->lsc_mode = LACP_DEFAULT_MODE;
+       lsc->lsc_timeout = LACP_DEFAULT_TIMEOUT;
+       lsc->lsc_sys_prio = LACP_DEFAULT_SYSTEM_PRIO;
+       lsc->lsc_port_prio = LACP_DEFAULT_PORT_PRIO;
+       lsc->lsc_ifq_prio = LACP_DEFAULT_IFQ_PRIO;
+
        timeout_set(&lsc->lsc_transit_callout, lacp_transit_expire, lsc);
        timeout_set(&lsc->lsc_callout, lacp_tick, lsc);
        task_set(&lsc->lsc_input, lacp_input_process, lsc);
@@ -1555,12 +1547,15 @@ lacp_sm_rx_update_ntt(struct lacp_port *
 void
 lacp_sm_rx_record_default(struct lacp_port *lp)
 {
+       struct lacp_softc *lsc;
        u_int8_t oldpstate;
 
+       lsc = lp->lp_lsc;
+
        /* LACP_DPRINTF((lp, "%s\n", __func__)); */
 
        oldpstate = lp->lp_partner.lip_state;
-       lp->lp_partner = lacp_partner_admin;
+       lacp_default_partner(lsc, &(lp->lp_partner));
        lp->lp_state |= LACP_STATE_DEFAULTED;
        lacp_sm_ptx_update_timeout(lp, oldpstate);
 }
@@ -1590,9 +1585,14 @@ lacp_sm_rx_update_selected(struct lacp_p
 void
 lacp_sm_rx_update_default_selected(struct lacp_port *lp)
 {
+       struct lacp_softc *lsc;
+       struct lacp_peerinfo peer;
+
+       lsc = lp->lp_lsc;
+       lacp_default_partner(lsc, &peer);
        /* LACP_DPRINTF((lp, "%s\n", __func__)); */
 
-       lacp_sm_rx_update_selected_from_peerinfo(lp, &lacp_partner_admin);
+       lacp_sm_rx_update_selected_from_peerinfo(lp, &peer);
 }
 
 /* transmit machine */
Index: sys/net/trunklacp.h
===================================================================
RCS file: /home/los/cvs/src/sys/net/trunklacp.h,v
retrieving revision 1.13
diff -u -p -r1.13 trunklacp.h
--- sys/net/trunklacp.h 12 May 2018 02:02:34 -0000      1.13
+++ sys/net/trunklacp.h 6 Aug 2018 18:24:11 -0000
@@ -39,6 +39,19 @@
 #define        SLOWPROTOCOLS_SUBTYPE_LACP      1
 #define        SLOWPROTOCOLS_SUBTYPE_MARKER    2
 
+/*
+ * default administrative values
+ */
+#define        LACP_DEFAULT_MODE               1 /* Active Mode */
+#define        LACP_DEFAULT_TIMEOUT            0 /* Slow Timeout */
+#define        LACP_DEFAULT_SYSTEM_PRIO        0x8000 /* Medium Priority */
+#define        LACP_LOW_SYSTEM_PRIO            0xffff
+#define        LACP_HIGH_SYSTEM_PRIO           0x0001
+#define        LACP_DEFAULT_PORT_PRIO          0x8000 /* Medium Priority */
+#define        LACP_LOW_PORT_PRIO              0xffff
+#define        LACP_HIGH_PORT_PRIO             0x0001
+#define        LACP_DEFAULT_IFQ_PRIO           6
+
 struct slowprothdr {
        u_int8_t                sph_subtype;
        u_int8_t                sph_version;
@@ -221,6 +234,14 @@ struct lacp_aggregator {
        int                     la_pending; /* number of ports in wait_while */
 };
 
+struct lacp_admin_def {
+       u_int8_t                lad_mode; /* active or passive */
+       u_int8_t                lad_timeout; /* fast or slow */
+       u_int16_t               lad_prio; /* system priority */
+       u_int16_t               lad_portprio; /* port priority */
+       u_int8_t                lad_ifqprio; /* ifq priority */
+};
+
 struct lacp_softc {
        struct trunk_softc      *lsc_softc;
        struct lacp_aggregator  *lsc_active_aggregator;
@@ -233,6 +254,12 @@ struct lacp_softc {
        volatile u_int          lsc_activemap;
        SIPHASH_KEY             lsc_hashkey;
        struct task             lsc_input;
+       struct lacp_admin_def   lsc_admin_defaults;
+#define lsc_mode               lsc_admin_defaults.lad_mode
+#define lsc_timeout            lsc_admin_defaults.lad_timeout
+#define lsc_sys_prio   lsc_admin_defaults.lad_prio
+#define lsc_port_prio  lsc_admin_defaults.lad_portprio
+#define lsc_ifq_prio   lsc_admin_defaults.lad_ifqprio
 };
 
 #define        LACP_TYPE_ACTORINFO     1
Index: share/man/man4/trunk.4
===================================================================
RCS file: /home/los/cvs/src/share/man/man4/trunk.4,v
retrieving revision 1.29
diff -u -p -r1.29 trunk.4
--- share/man/man4/trunk.4      13 Mar 2015 19:58:41 -0000      1.29
+++ share/man/man4/trunk.4      6 Aug 2018 18:24:12 -0000
@@ -144,10 +144,8 @@ such as
 duplicate address detection (DAD)
 cannot properly deal with duplicate packets.
 .Pp
-There is no way to configure LACP administrative variables, including
-system and port priorities.
-The current implementation always performs active-mode LACP and uses
-0x8000 as system and port priorities.
+The current LACP implementation defaults to active-mode LACP, slow timeout,
+and uses 0x8000 (medium priority) as system and port priorities.
 .Pp
 The
 .Nm

Reply via email to