Add administrative options to LACP trunk implementation.
authorccardenas <ccardenas@openbsd.org>
Sun, 12 Aug 2018 23:50:31 +0000 (23:50 +0000)
committerccardenas <ccardenas@openbsd.org>
Sun, 12 Aug 2018 23:50:31 +0000 (23:50 +0000)
The trunk 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/0x8000)
* Port Priority - 1(high) to 65535(low) (default 32768/0x8000)
* 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.

Tested by many on a plethora of NIC drivers and switches.

Ok remi@

sbin/ifconfig/ifconfig.8
sbin/ifconfig/ifconfig.c
share/man/man4/trunk.4
sys/net/if_trunk.c
sys/net/if_trunk.h
sys/net/trunklacp.c
sys/net/trunklacp.h

index 8ea1446..bb7dc78 100644 (file)
@@ -1,4 +1,4 @@
-.\"    $OpenBSD: ifconfig.8,v 1.315 2018/08/12 12:40:25 jmc Exp $
+.\"    $OpenBSD: ifconfig.8,v 1.316 2018/08/12 23:50:31 ccardenas Exp $
 .\"    $NetBSD: ifconfig.8,v 1.11 1996/01/04 21:27:29 pk Exp $
 .\"     $FreeBSD: ifconfig.8,v 1.16 1998/02/01 07:03:29 steve Exp $
 .\"
@@ -1616,6 +1616,16 @@ The following options are available for a
 .Xr trunk 4
 interface:
 .Bl -tag -width Ds
+.It Cm lacpmode Cm active Ns | Ns Cm passive
+Set the LACP trunk mode to either
+.Ar active
+or
+.Ar passive .
+.It Cm lacptimeout Cm fast Ns | Ns Cm slow
+Set the LACP timeout speed to either
+.Ar fast
+or
+.Ar slow .
 .It Cm trunkport Ar child-iface
 Add
 .Ar child-iface
index 6bc7276..f36de28 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: ifconfig.c,v 1.374 2018/08/12 18:33:55 stsp Exp $     */
+/*     $OpenBSD: ifconfig.c,v 1.375 2018/08/12 23:50:31 ccardenas Exp $        */
 /*     $NetBSD: ifconfig.c,v 1.40 1997/10/01 02:19:43 enami Exp $      */
 
 /*
@@ -171,7 +171,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);
@@ -254,6 +259,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);
 
@@ -412,6 +419,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 },
@@ -4062,6 +4071,72 @@ settrunkproto(const char *val, int d)
                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
 trunk_status(void)
 {
index e50cca4..26bedbc 100644 (file)
@@ -1,4 +1,4 @@
-.\"    $OpenBSD: trunk.4,v 1.29 2015/03/13 19:58:41 jmc Exp $
+.\"    $OpenBSD: trunk.4,v 1.30 2018/08/12 23:50:31 ccardenas Exp $
 .\"
 .\" Copyright (c) 2005, 2006 Reyk Floeter <reyk@openbsd.org>
 .\"
@@ -14,7 +14,7 @@
 .\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
 .\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 .\"
-.Dd $Mdocdate: March 13 2015 $
+.Dd $Mdocdate: August 12 2018 $
 .Dt TRUNK 4
 .Os
 .Sh NAME
@@ -68,12 +68,16 @@ the next active port is used.
 The first interface added is the master port;
 any interfaces added after that are used as failover devices.
 .It Ic lacp
-Uses the IEEE 802.3ad Link Aggregation Control Protocol (LACP)
+Uses the IEEE 802.3ad (renamed to 802.1AX in 2014)
+Link Aggregation Control Protocol (LACP)
 and the Marker Protocol
 to increase link speed and provide redundancy.
 LACP trunk groups are composed of ports of the same speed,
 set to full-duplex operation.
 This protocol requires a switch which supports LACP.
+By default, the LACP implementation uses active-mode LACP,
+slow timeout, and 0x8000 (medium) priority as system and port
+priorities.
 .It Ic loadbalance
 Distributes outgoing traffic through all active ports
 and accepts incoming traffic from any active port.
@@ -144,11 +148,6 @@ 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.
-.Pp
 The
 .Nm
 interface takes its MTU from the first
index 49d2dbe..6887002 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: if_trunk.c,v 1.136 2018/02/19 08:59:52 mpi Exp $      */
+/*     $OpenBSD: if_trunk.c,v 1.137 2018/08/12 23:50:31 ccardenas Exp $        */
 
 /*
  * Copyright (c) 2005, 2006, 2007 Reyk Floeter <reyk@openbsd.org>
@@ -604,8 +604,11 @@ trunk_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
        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;
 
@@ -671,6 +674,94 @@ trunk_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
                }
                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' ||
                    (tpif = ifunit(rp->rp_portname)) == NULL) {
index 05d731a..c4408dc 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: if_trunk.h,v 1.25 2015/09/23 12:40:12 mikeb Exp $     */
+/*     $OpenBSD: if_trunk.h,v 1.26 2018/08/12 23:50:31 ccardenas Exp $ */
 
 /*
  * Copyright (c) 2005, 2006, 2007 Reyk Floeter <reyk@openbsd.org>
@@ -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 52ca84f..8d5b7bc 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: trunklacp.c,v 1.29 2017/01/24 10:08:30 krw Exp $ */
+/*     $OpenBSD: trunklacp.c,v 1.30 2018/08/12 23:50:31 ccardenas Exp $ */
 /*     $NetBSD: ieee8023ad_lacp.c,v 1.3 2005/12/11 12:24:54 christos Exp $ */
 /*     $FreeBSD:ieee8023ad_lacp.c,v 1.15 2008/03/16 19:25:30 thompsa Exp $ */
 
 #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_response_tlv_template[] = {
 
 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_port *, const char *, ...)
 #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 *lp, struct lacp_markerinfo *info)
 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 *lp, const struct lacpdu *du)
 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_port *lp, const struct lacpdu *du)
 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 869076a..1abc67f 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: trunklacp.h,v 1.13 2018/05/12 02:02:34 ccardenas Exp $        */
+/*     $OpenBSD: trunklacp.h,v 1.14 2018/08/12 23:50:31 ccardenas Exp $        */
 /*     $NetBSD: ieee8023ad_impl.h,v 1.2 2005/12/10 23:21:39 elad Exp $ */
 
 /*
 #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