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:
parent
53bf725ae1
commit
b3d37ca5f8
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=171247
@ -29,6 +29,8 @@ static const char rcsid[] =
|
|||||||
|
|
||||||
#include "ifconfig.h"
|
#include "ifconfig.h"
|
||||||
|
|
||||||
|
char lacpbuf[120]; /* LACP peer '[(a,a,a),(p,p,p)]' */
|
||||||
|
|
||||||
static void
|
static void
|
||||||
setlaggport(const char *val, int d, int s, const struct afswtch *afp)
|
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");
|
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
|
static void
|
||||||
lagg_status(int s)
|
lagg_status(int s)
|
||||||
{
|
{
|
||||||
struct lagg_protos lpr[] = LAGG_PROTOS;
|
struct lagg_protos lpr[] = LAGG_PROTOS;
|
||||||
struct lagg_reqport rp, rpbuf[LAGG_MAX_PORTS];
|
struct lagg_reqport rp, rpbuf[LAGG_MAX_PORTS];
|
||||||
struct lagg_reqall ra;
|
struct lagg_reqall ra;
|
||||||
|
struct lacp_opreq *lp;
|
||||||
const char *proto = "<unknown>";
|
const char *proto = "<unknown>";
|
||||||
int i, isport = 0;
|
int i, isport = 0;
|
||||||
|
|
||||||
@ -102,6 +133,8 @@ lagg_status(int s)
|
|||||||
ra.ra_port = rpbuf;
|
ra.ra_port = rpbuf;
|
||||||
|
|
||||||
if (ioctl(s, SIOCGLAGG, &ra) == 0) {
|
if (ioctl(s, SIOCGLAGG, &ra) == 0) {
|
||||||
|
lp = (struct lacp_opreq *)&ra.ra_lacpreq;
|
||||||
|
|
||||||
for (i = 0; i < (sizeof(lpr) / sizeof(lpr[0])); i++) {
|
for (i = 0; i < (sizeof(lpr) / sizeof(lpr[0])); i++) {
|
||||||
if (ra.ra_proto == lpr[i].lpr_proto) {
|
if (ra.ra_proto == lpr[i].lpr_proto) {
|
||||||
proto = lpr[i].lpr_name;
|
proto = lpr[i].lpr_name;
|
||||||
@ -109,15 +142,24 @@ lagg_status(int s)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
printf("\tlagg: laggproto %s", proto);
|
printf("\tlaggproto %s", proto);
|
||||||
if (isport)
|
if (isport)
|
||||||
printf(" laggdev %s", rp.rp_ifname);
|
printf(" laggdev %s", rp.rp_ifname);
|
||||||
putchar('\n');
|
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++) {
|
for (i = 0; i < ra.ra_ports; i++) {
|
||||||
printf("\t\tlaggport %s ", rpbuf[i].rp_portname);
|
lp = (struct lacp_opreq *)&rpbuf[i].rp_lacpreq;
|
||||||
printb("", rpbuf[i].rp_flags, LAGG_PORT_BITS);
|
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');
|
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 */) {
|
if (0 /* XXX */) {
|
||||||
|
@ -611,6 +611,56 @@ lacp_port_isactive(struct lagg_port *lgp)
|
|||||||
return (0);
|
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
|
static void
|
||||||
lacp_disable_collecting(struct lacp_port *lp)
|
lacp_disable_collecting(struct lacp_port *lp)
|
||||||
{
|
{
|
||||||
|
@ -270,6 +270,8 @@ int lacp_port_create(struct lagg_port *);
|
|||||||
void lacp_port_destroy(struct lagg_port *);
|
void lacp_port_destroy(struct lagg_port *);
|
||||||
void lacp_linkstate(struct lagg_port *);
|
void lacp_linkstate(struct lagg_port *);
|
||||||
int lacp_port_isactive(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 */
|
/* following constants don't include terminating NUL */
|
||||||
#define LACP_MACSTR_MAX (2*6 + 5)
|
#define LACP_MACSTR_MAX (2*6 + 5)
|
||||||
|
@ -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));
|
strlcpy(rp->rp_portname, lp->lp_ifp->if_xname, sizeof(rp->rp_portname));
|
||||||
rp->rp_prio = lp->lp_prio;
|
rp->rp_prio = lp->lp_prio;
|
||||||
rp->rp_flags = lp->lp_flags;
|
rp->rp_flags = lp->lp_flags;
|
||||||
|
if (sc->sc_portreq != NULL)
|
||||||
|
(*sc->sc_portreq)(lp, (caddr_t)&rp->rp_psc);
|
||||||
|
|
||||||
/* Add protocol specific flags */
|
/* Add protocol specific flags */
|
||||||
switch (sc->sc_proto) {
|
switch (sc->sc_proto) {
|
||||||
@ -768,6 +770,8 @@ lagg_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
|
|||||||
case SIOCGLAGG:
|
case SIOCGLAGG:
|
||||||
ra->ra_proto = sc->sc_proto;
|
ra->ra_proto = sc->sc_proto;
|
||||||
ra->ra_ports = i = 0;
|
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);
|
lp = SLIST_FIRST(&sc->sc_ports);
|
||||||
while (lp && ra->ra_size >=
|
while (lp && ra->ra_size >=
|
||||||
i + sizeof(struct lagg_reqport)) {
|
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_init = NULL;
|
||||||
sc->sc_stop = NULL;
|
sc->sc_stop = NULL;
|
||||||
sc->sc_lladdr = NULL;
|
sc->sc_lladdr = NULL;
|
||||||
|
sc->sc_req = NULL;
|
||||||
|
sc->sc_portreq = NULL;
|
||||||
}
|
}
|
||||||
if (error != 0)
|
if (error != 0)
|
||||||
break;
|
break;
|
||||||
@ -1532,6 +1538,8 @@ lagg_lacp_attach(struct lagg_softc *sc)
|
|||||||
sc->sc_init = lacp_init;
|
sc->sc_init = lacp_init;
|
||||||
sc->sc_stop = lacp_stop;
|
sc->sc_stop = lacp_stop;
|
||||||
sc->sc_lladdr = lagg_lacp_lladdr;
|
sc->sc_lladdr = lagg_lacp_lladdr;
|
||||||
|
sc->sc_req = lacp_req;
|
||||||
|
sc->sc_portreq = lacp_portreq;
|
||||||
|
|
||||||
error = lacp_attach(sc);
|
error = lacp_attach(sc);
|
||||||
if (error)
|
if (error)
|
||||||
|
@ -69,12 +69,34 @@ struct lagg_protos {
|
|||||||
* lagg ioctls.
|
* 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 */
|
/* lagg port settings */
|
||||||
struct lagg_reqport {
|
struct lagg_reqport {
|
||||||
char rp_ifname[IFNAMSIZ]; /* name of the lagg */
|
char rp_ifname[IFNAMSIZ]; /* name of the lagg */
|
||||||
char rp_portname[IFNAMSIZ]; /* name of the port */
|
char rp_portname[IFNAMSIZ]; /* name of the port */
|
||||||
u_int32_t rp_prio; /* port priority */
|
u_int32_t rp_prio; /* port priority */
|
||||||
u_int32_t rp_flags; /* port flags */
|
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)
|
#define SIOCGLAGGPORT _IOWR('i', 140, struct lagg_reqport)
|
||||||
@ -89,6 +111,10 @@ struct lagg_reqall {
|
|||||||
size_t ra_size; /* size of buffer */
|
size_t ra_size; /* size of buffer */
|
||||||
struct lagg_reqport *ra_port; /* allocated buffer */
|
struct lagg_reqport *ra_port; /* allocated buffer */
|
||||||
int ra_ports; /* total port count */
|
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)
|
#define SIOCGLAGG _IOWR('i', 143, struct lagg_reqall)
|
||||||
@ -170,6 +196,8 @@ struct lagg_softc {
|
|||||||
void (*sc_init)(struct lagg_softc *);
|
void (*sc_init)(struct lagg_softc *);
|
||||||
void (*sc_stop)(struct lagg_softc *);
|
void (*sc_stop)(struct lagg_softc *);
|
||||||
void (*sc_lladdr)(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 {
|
struct lagg_port {
|
||||||
|
Loading…
Reference in New Issue
Block a user