On Mon, Aug 06, 2018 at 08:18:23PM -0700, Carlos Cardenas wrote:
> 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?
I've updated the ifconfig piece to be a bit cleaner (prompted by
deraadt).
+--+
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 8 Aug 2018 17:42:56 -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 8 Aug 2018 17:42:56 -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,72 @@ 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)
+ errx(1, "Invalid option for trunk: %s", name);
+
+ 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)
+ errx(1, "Invalid option for trunk: %s", name);
+
+ 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 8 Aug 2018 17:42:56 -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 8 Aug 2018 17:42:56 -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 8 Aug 2018 17:42:56 -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 8 Aug 2018 17:42:56 -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 8 Aug 2018 17:42:56 -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