Allow the LACP state to be queried from userland which at the moment is the

actor and partner peer info. Print out the active aggregator and per port data
in verbose mode from ifconfig.

Approved by:	re (mux)
This commit is contained in:
Andrew Thompson 2007-07-05 09:18:57 +00:00
parent 53bf725ae1
commit b3d37ca5f8
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=171247
5 changed files with 133 additions and 3 deletions

View File

@ -29,6 +29,8 @@ static const char rcsid[] =
#include "ifconfig.h"
char lacpbuf[120]; /* LACP peer '[(a,a,a),(p,p,p)]' */
static void
setlaggport(const char *val, int d, int s, const struct afswtch *afp)
{
@ -79,12 +81,41 @@ setlaggproto(const char *val, int d, int s, const struct afswtch *afp)
err(1, "SIOCSLAGG");
}
static char *
lacp_format_mac(const uint8_t *mac, char *buf, size_t buflen)
{
snprintf(buf, buflen, "%02X-%02X-%02X-%02X-%02X-%02X",
(int)mac[0], (int)mac[1], (int)mac[2], (int)mac[3],
(int)mac[4], (int)mac[5]);
return (buf);
}
static char *
lacp_format_peer(struct lacp_opreq *req, const char *sep)
{
char macbuf1[20];
char macbuf2[20];
snprintf(lacpbuf, sizeof(lacpbuf),
"[(%04X,%s,%04X,%04X,%04X),%s(%04X,%s,%04X,%04X,%04X)]",
req->actor_prio,
lacp_format_mac(req->actor_mac, macbuf1, sizeof(macbuf1)),
req->actor_key, req->actor_portprio, req->actor_portno, sep,
req->partner_prio,
lacp_format_mac(req->partner_mac, macbuf2, sizeof(macbuf2)),
req->partner_key, req->partner_portprio, req->partner_portno);
return(lacpbuf);
}
static void
lagg_status(int s)
{
struct lagg_protos lpr[] = LAGG_PROTOS;
struct lagg_reqport rp, rpbuf[LAGG_MAX_PORTS];
struct lagg_reqall ra;
struct lacp_opreq *lp;
const char *proto = "<unknown>";
int i, isport = 0;
@ -102,6 +133,8 @@ lagg_status(int s)
ra.ra_port = rpbuf;
if (ioctl(s, SIOCGLAGG, &ra) == 0) {
lp = (struct lacp_opreq *)&ra.ra_lacpreq;
for (i = 0; i < (sizeof(lpr) / sizeof(lpr[0])); i++) {
if (ra.ra_proto == lpr[i].lpr_proto) {
proto = lpr[i].lpr_name;
@ -109,15 +142,24 @@ lagg_status(int s)
}
}
printf("\tlagg: laggproto %s", proto);
printf("\tlaggproto %s", proto);
if (isport)
printf(" laggdev %s", rp.rp_ifname);
putchar('\n');
if (verbose && ra.ra_proto == LAGG_PROTO_LACP)
printf("\tlag id: %s\n",
lacp_format_peer(lp, "\n\t\t "));
for (i = 0; i < ra.ra_ports; i++) {
printf("\t\tlaggport %s ", rpbuf[i].rp_portname);
printb("", rpbuf[i].rp_flags, LAGG_PORT_BITS);
lp = (struct lacp_opreq *)&rpbuf[i].rp_lacpreq;
printf("\tlaggport: %s ", rpbuf[i].rp_portname);
printb("flags", rpbuf[i].rp_flags, LAGG_PORT_BITS);
if (verbose && ra.ra_proto == LAGG_PROTO_LACP)
printf(" state=%X", lp->actor_state);
putchar('\n');
if (verbose && ra.ra_proto == LAGG_PROTO_LACP)
printf("\t\t%s\n",
lacp_format_peer(lp, "\n\t\t "));
}
if (0 /* XXX */) {

View File

@ -611,6 +611,56 @@ lacp_port_isactive(struct lagg_port *lgp)
return (0);
}
void
lacp_req(struct lagg_softc *sc, caddr_t data)
{
struct lacp_opreq *req = (struct lacp_opreq *)data;
struct lacp_softc *lsc = LACP_SOFTC(sc);
struct lacp_aggregator *la = lsc->lsc_active_aggregator;
bzero(req, sizeof(struct lacp_opreq));
if (la != NULL) {
req->actor_prio = ntohs(la->la_actor.lip_systemid.lsi_prio);
memcpy(&req->actor_mac, &la->la_actor.lip_systemid.lsi_mac,
ETHER_ADDR_LEN);
req->actor_key = ntohs(la->la_actor.lip_key);
req->actor_portprio = ntohs(la->la_actor.lip_portid.lpi_prio);
req->actor_portno = ntohs(la->la_actor.lip_portid.lpi_portno);
req->actor_state = la->la_actor.lip_state;
req->partner_prio = ntohs(la->la_partner.lip_systemid.lsi_prio);
memcpy(&req->partner_mac, &la->la_partner.lip_systemid.lsi_mac,
ETHER_ADDR_LEN);
req->partner_key = ntohs(la->la_partner.lip_key);
req->partner_portprio = ntohs(la->la_partner.lip_portid.lpi_prio);
req->partner_portno = ntohs(la->la_partner.lip_portid.lpi_portno);
req->partner_state = la->la_partner.lip_state;
}
}
void
lacp_portreq(struct lagg_port *lgp, caddr_t data)
{
struct lacp_opreq *req = (struct lacp_opreq *)data;
struct lacp_port *lp = LACP_PORT(lgp);
req->actor_prio = ntohs(lp->lp_actor.lip_systemid.lsi_prio);
memcpy(&req->actor_mac, &lp->lp_actor.lip_systemid.lsi_mac,
ETHER_ADDR_LEN);
req->actor_key = ntohs(lp->lp_actor.lip_key);
req->actor_portprio = ntohs(lp->lp_actor.lip_portid.lpi_prio);
req->actor_portno = ntohs(lp->lp_actor.lip_portid.lpi_portno);
req->actor_state = lp->lp_actor.lip_state;
req->partner_prio = ntohs(lp->lp_partner.lip_systemid.lsi_prio);
memcpy(&req->partner_mac, &lp->lp_partner.lip_systemid.lsi_mac,
ETHER_ADDR_LEN);
req->partner_key = ntohs(lp->lp_partner.lip_key);
req->partner_portprio = ntohs(lp->lp_partner.lip_portid.lpi_prio);
req->partner_portno = ntohs(lp->lp_partner.lip_portid.lpi_portno);
req->partner_state = lp->lp_partner.lip_state;
}
static void
lacp_disable_collecting(struct lacp_port *lp)
{

View File

@ -270,6 +270,8 @@ int lacp_port_create(struct lagg_port *);
void lacp_port_destroy(struct lagg_port *);
void lacp_linkstate(struct lagg_port *);
int lacp_port_isactive(struct lagg_port *);
void lacp_req(struct lagg_softc *, caddr_t);
void lacp_portreq(struct lagg_port *, caddr_t);
/* following constants don't include terminating NUL */
#define LACP_MACSTR_MAX (2*6 + 5)

View File

@ -686,6 +686,8 @@ lagg_port2req(struct lagg_port *lp, struct lagg_reqport *rp)
strlcpy(rp->rp_portname, lp->lp_ifp->if_xname, sizeof(rp->rp_portname));
rp->rp_prio = lp->lp_prio;
rp->rp_flags = lp->lp_flags;
if (sc->sc_portreq != NULL)
(*sc->sc_portreq)(lp, (caddr_t)&rp->rp_psc);
/* Add protocol specific flags */
switch (sc->sc_proto) {
@ -768,6 +770,8 @@ lagg_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
case SIOCGLAGG:
ra->ra_proto = sc->sc_proto;
ra->ra_ports = i = 0;
if (sc->sc_req != NULL)
(*sc->sc_req)(sc, (caddr_t)&ra->ra_psc);
lp = SLIST_FIRST(&sc->sc_ports);
while (lp && ra->ra_size >=
i + sizeof(struct lagg_reqport)) {
@ -802,6 +806,8 @@ lagg_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
sc->sc_init = NULL;
sc->sc_stop = NULL;
sc->sc_lladdr = NULL;
sc->sc_req = NULL;
sc->sc_portreq = NULL;
}
if (error != 0)
break;
@ -1532,6 +1538,8 @@ lagg_lacp_attach(struct lagg_softc *sc)
sc->sc_init = lacp_init;
sc->sc_stop = lacp_stop;
sc->sc_lladdr = lagg_lacp_lladdr;
sc->sc_req = lacp_req;
sc->sc_portreq = lacp_portreq;
error = lacp_attach(sc);
if (error)

View File

@ -69,12 +69,34 @@ struct lagg_protos {
* lagg ioctls.
*/
/*
* LACP current operational parameters structure.
*/
struct lacp_opreq {
uint16_t actor_prio;
uint8_t actor_mac[ETHER_ADDR_LEN];
uint16_t actor_key;
uint16_t actor_portprio;
uint16_t actor_portno;
uint8_t actor_state;
uint16_t partner_prio;
uint8_t partner_mac[ETHER_ADDR_LEN];
uint16_t partner_key;
uint16_t partner_portprio;
uint16_t partner_portno;
uint8_t partner_state;
};
/* lagg port settings */
struct lagg_reqport {
char rp_ifname[IFNAMSIZ]; /* name of the lagg */
char rp_portname[IFNAMSIZ]; /* name of the port */
u_int32_t rp_prio; /* port priority */
u_int32_t rp_flags; /* port flags */
union {
struct lacp_opreq rpsc_lacp;
} rp_psc;
#define rp_lacpreq rp_psc.rpsc_lacp
};
#define SIOCGLAGGPORT _IOWR('i', 140, struct lagg_reqport)
@ -89,6 +111,10 @@ struct lagg_reqall {
size_t ra_size; /* size of buffer */
struct lagg_reqport *ra_port; /* allocated buffer */
int ra_ports; /* total port count */
union {
struct lacp_opreq rpsc_lacp;
} ra_psc;
#define ra_lacpreq ra_psc.rpsc_lacp
};
#define SIOCGLAGG _IOWR('i', 143, struct lagg_reqall)
@ -170,6 +196,8 @@ struct lagg_softc {
void (*sc_init)(struct lagg_softc *);
void (*sc_stop)(struct lagg_softc *);
void (*sc_lladdr)(struct lagg_softc *);
void (*sc_req)(struct lagg_softc *, caddr_t);
void (*sc_portreq)(struct lagg_port *, caddr_t);
};
struct lagg_port {