Separate option handling from SIOC[SG]LAGG to SIOC[SG]LAGGOPTS for
backward compatibility with old ifconfig(8).
This commit is contained in:
parent
a85f6c3043
commit
9732189ca9
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=272446
@ -85,27 +85,27 @@ setlaggproto(const char *val, int d, int s, const struct afswtch *afp)
|
||||
static void
|
||||
setlaggflowidshift(const char *val, int d, int s, const struct afswtch *afp)
|
||||
{
|
||||
struct lagg_reqall ra;
|
||||
struct lagg_reqopts ro;
|
||||
|
||||
bzero(&ra, sizeof(ra));
|
||||
ra.ra_opts = LAGG_OPT_FLOWIDSHIFT;
|
||||
strlcpy(ra.ra_ifname, name, sizeof(ra.ra_ifname));
|
||||
ra.ra_flowid_shift = (int)strtol(val, NULL, 10);
|
||||
if (ra.ra_flowid_shift & ~LAGG_OPT_FLOWIDSHIFT_MASK)
|
||||
bzero(&ro, sizeof(ro));
|
||||
ro.ro_opts = LAGG_OPT_FLOWIDSHIFT;
|
||||
strlcpy(ro.ro_ifname, name, sizeof(ro.ro_ifname));
|
||||
ro.ro_flowid_shift = (int)strtol(val, NULL, 10);
|
||||
if (ro.ro_flowid_shift & ~LAGG_OPT_FLOWIDSHIFT_MASK)
|
||||
errx(1, "Invalid flowid_shift option: %s", val);
|
||||
|
||||
if (ioctl(s, SIOCSLAGG, &ra) != 0)
|
||||
err(1, "SIOCSLAGG");
|
||||
if (ioctl(s, SIOCSLAGGOPTS, &ro) != 0)
|
||||
err(1, "SIOCSLAGGOPTS");
|
||||
}
|
||||
|
||||
static void
|
||||
setlaggsetopt(const char *val, int d, int s, const struct afswtch *afp)
|
||||
{
|
||||
struct lagg_reqall ra;
|
||||
struct lagg_reqopts ro;
|
||||
|
||||
bzero(&ra, sizeof(ra));
|
||||
ra.ra_opts = d;
|
||||
switch (ra.ra_opts) {
|
||||
bzero(&ro, sizeof(ro));
|
||||
ro.ro_opts = d;
|
||||
switch (ro.ro_opts) {
|
||||
case LAGG_OPT_USE_FLOWID:
|
||||
case -LAGG_OPT_USE_FLOWID:
|
||||
case LAGG_OPT_LACP_STRICT:
|
||||
@ -118,10 +118,10 @@ setlaggsetopt(const char *val, int d, int s, const struct afswtch *afp)
|
||||
default:
|
||||
err(1, "Invalid lagg option");
|
||||
}
|
||||
strlcpy(ra.ra_ifname, name, sizeof(ra.ra_ifname));
|
||||
strlcpy(ro.ro_ifname, name, sizeof(ro.ro_ifname));
|
||||
|
||||
if (ioctl(s, SIOCSLAGG, &ra) != 0)
|
||||
err(1, "SIOCSLAGG");
|
||||
if (ioctl(s, SIOCSLAGGOPTS, &ro) != 0)
|
||||
err(1, "SIOCSLAGGOPTS");
|
||||
}
|
||||
|
||||
static void
|
||||
@ -186,6 +186,7 @@ lagg_status(int s)
|
||||
struct lagg_protos lpr[] = LAGG_PROTOS;
|
||||
struct lagg_reqport rp, rpbuf[LAGG_MAX_PORTS];
|
||||
struct lagg_reqall ra;
|
||||
struct lagg_reqopts ro;
|
||||
struct lagg_reqflags rf;
|
||||
struct lacp_opreq *lp;
|
||||
const char *proto = "<unknown>";
|
||||
@ -193,6 +194,7 @@ lagg_status(int s)
|
||||
|
||||
bzero(&rp, sizeof(rp));
|
||||
bzero(&ra, sizeof(ra));
|
||||
bzero(&ro, sizeof(ro));
|
||||
|
||||
strlcpy(rp.rp_ifname, name, sizeof(rp.rp_ifname));
|
||||
strlcpy(rp.rp_portname, name, sizeof(rp.rp_portname));
|
||||
@ -204,6 +206,9 @@ lagg_status(int s)
|
||||
ra.ra_size = sizeof(rpbuf);
|
||||
ra.ra_port = rpbuf;
|
||||
|
||||
strlcpy(ro.ro_ifname, name, sizeof(ro.ro_ifname));
|
||||
ioctl(s, SIOCGLAGGOPTS, &ro);
|
||||
|
||||
strlcpy(rf.rf_ifname, name, sizeof(rf.rf_ifname));
|
||||
if (ioctl(s, SIOCGLAGGFLAGS, &rf) != 0)
|
||||
rf.rf_flags = 0;
|
||||
@ -242,20 +247,20 @@ lagg_status(int s)
|
||||
if (verbose) {
|
||||
printf("\tlagg options:\n");
|
||||
printf("\t\tuse_flowid: %d\n",
|
||||
(ra.ra_opts & LAGG_OPT_USE_FLOWID) ? 1 : 0);
|
||||
printf("\t\tflowid_shift: %d\n", ra.ra_flowid_shift);
|
||||
(ro.ro_opts & LAGG_OPT_USE_FLOWID) ? 1 : 0);
|
||||
printf("\t\tflowid_shift: %d\n", ro.ro_flowid_shift);
|
||||
switch (ra.ra_proto) {
|
||||
case LAGG_PROTO_LACP:
|
||||
printf("\t\tlacp_strict: %d\n",
|
||||
(ra.ra_opts & LAGG_OPT_LACP_STRICT) ? 1 : 0);
|
||||
(ro.ro_opts & LAGG_OPT_LACP_STRICT) ? 1 : 0);
|
||||
printf("\t\tlacp_rxtest: %d\n",
|
||||
(ra.ra_opts & LAGG_OPT_LACP_RXTEST) ? 1 : 0);
|
||||
(ro.ro_opts & LAGG_OPT_LACP_RXTEST) ? 1 : 0);
|
||||
printf("\t\tlacp_txtest: %d\n",
|
||||
(ra.ra_opts & LAGG_OPT_LACP_TXTEST) ? 1 : 0);
|
||||
(ro.ro_opts & LAGG_OPT_LACP_TXTEST) ? 1 : 0);
|
||||
}
|
||||
printf("\tlagg statistics:\n");
|
||||
printf("\t\tactive ports: %d\n", ra.ra_active);
|
||||
printf("\t\tflapping: %u\n", ra.ra_flapping);
|
||||
printf("\t\tactive ports: %d\n", ro.ro_active);
|
||||
printf("\t\tflapping: %u\n", ro.ro_flapping);
|
||||
if (ra.ra_proto == LAGG_PROTO_LACP) {
|
||||
printf("\tlag id: %s\n",
|
||||
lacp_format_peer(lp, "\n\t\t "));
|
||||
|
@ -1189,6 +1189,7 @@ lagg_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
|
||||
{
|
||||
struct lagg_softc *sc = (struct lagg_softc *)ifp->if_softc;
|
||||
struct lagg_reqall *ra = (struct lagg_reqall *)data;
|
||||
struct lagg_reqopts *ro = (struct lagg_reqopts *)data;
|
||||
struct lagg_reqport *rp = (struct lagg_reqport *)data, rpbuf;
|
||||
struct lagg_reqflags *rf = (struct lagg_reqflags *)data;
|
||||
struct ifreq *ifr = (struct ifreq *)data;
|
||||
@ -1215,31 +1216,6 @@ lagg_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
|
||||
LAGG_RLOCK(sc, &tracker);
|
||||
ra->ra_proto = sc->sc_proto;
|
||||
lagg_proto_request(sc, &ra->ra_psc);
|
||||
ra->ra_opts = sc->sc_opts;
|
||||
if (sc->sc_proto == LAGG_PROTO_LACP) {
|
||||
struct lacp_softc *lsc;
|
||||
|
||||
lsc = (struct lacp_softc *)sc->sc_psc;
|
||||
if (lsc->lsc_debug.lsc_tx_test != 0)
|
||||
ra->ra_opts |= LAGG_OPT_LACP_TXTEST;
|
||||
if (lsc->lsc_debug.lsc_rx_test != 0)
|
||||
ra->ra_opts |= LAGG_OPT_LACP_RXTEST;
|
||||
if (lsc->lsc_strict_mode != 0)
|
||||
ra->ra_opts |= LAGG_OPT_LACP_STRICT;
|
||||
|
||||
ra->ra_active = sc->sc_active;
|
||||
} else {
|
||||
/*
|
||||
* LACP tracks active links automatically,
|
||||
* the others do not.
|
||||
*/
|
||||
ra->ra_active = 0;
|
||||
SLIST_FOREACH(lp, &sc->sc_ports, lp_entries)
|
||||
ra->ra_active += LAGG_PORTACTIVE(lp);
|
||||
}
|
||||
ra->ra_flapping = sc->sc_flapping;
|
||||
ra->ra_flowid_shift = sc->flowid_shift;
|
||||
|
||||
count = 0;
|
||||
buf = outbuf;
|
||||
len = min(ra->ra_size, buflen);
|
||||
@ -1260,21 +1236,53 @@ lagg_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
|
||||
free(outbuf, M_TEMP);
|
||||
break;
|
||||
case SIOCSLAGG:
|
||||
/*
|
||||
* Set options or protocol depending on
|
||||
* ra->ra_opts and ra->ra_proto.
|
||||
*/
|
||||
error = priv_check(td, PRIV_NET_LAGG);
|
||||
if (error)
|
||||
break;
|
||||
if (ra->ra_opts != 0) {
|
||||
if (ra->ra_proto < 1 || ra->ra_proto >= LAGG_PROTO_MAX) {
|
||||
error = EPROTONOSUPPORT;
|
||||
break;
|
||||
}
|
||||
|
||||
LAGG_WLOCK(sc);
|
||||
lagg_proto_detach(sc);
|
||||
lagg_proto_attach(sc, ra->ra_proto);
|
||||
break;
|
||||
case SIOCGLAGGOPTS:
|
||||
ro->ro_opts = sc->sc_opts;
|
||||
if (sc->sc_proto == LAGG_PROTO_LACP) {
|
||||
struct lacp_softc *lsc;
|
||||
|
||||
lsc = (struct lacp_softc *)sc->sc_psc;
|
||||
if (lsc->lsc_debug.lsc_tx_test != 0)
|
||||
ro->ro_opts |= LAGG_OPT_LACP_TXTEST;
|
||||
if (lsc->lsc_debug.lsc_rx_test != 0)
|
||||
ro->ro_opts |= LAGG_OPT_LACP_RXTEST;
|
||||
if (lsc->lsc_strict_mode != 0)
|
||||
ro->ro_opts |= LAGG_OPT_LACP_STRICT;
|
||||
|
||||
ro->ro_active = sc->sc_active;
|
||||
} else {
|
||||
ro->ro_active = 0;
|
||||
SLIST_FOREACH(lp, &sc->sc_ports, lp_entries)
|
||||
ro->ro_active += LAGG_PORTACTIVE(lp);
|
||||
}
|
||||
ro->ro_flapping = sc->sc_flapping;
|
||||
ro->ro_flowid_shift = sc->flowid_shift;
|
||||
break;
|
||||
case SIOCSLAGGOPTS:
|
||||
error = priv_check(td, PRIV_NET_LAGG);
|
||||
if (error)
|
||||
break;
|
||||
if (ro->ro_opts == 0)
|
||||
break;
|
||||
/*
|
||||
* Set options. LACP options are stored in sc->sc_psc,
|
||||
* not in sc_opts.
|
||||
*/
|
||||
int valid, lacp;
|
||||
|
||||
switch (ra->ra_opts) {
|
||||
switch (ro->ro_opts) {
|
||||
case LAGG_OPT_USE_FLOWID:
|
||||
case -LAGG_OPT_USE_FLOWID:
|
||||
case LAGG_OPT_FLOWIDSHIFT:
|
||||
@ -1300,25 +1308,25 @@ lagg_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
|
||||
/* Invalid combination of options specified. */
|
||||
error = EINVAL;
|
||||
LAGG_WUNLOCK(sc);
|
||||
break; /* Return from SIOCSLAGG. */
|
||||
break; /* Return from SIOCSLAGGOPTS. */
|
||||
}
|
||||
/*
|
||||
* Store new options into sc->sc_opts except for
|
||||
* FLOWIDSHIFT and LACP options.
|
||||
*/
|
||||
if (lacp == 0) {
|
||||
if (ra->ra_opts == LAGG_OPT_FLOWIDSHIFT)
|
||||
sc->flowid_shift = ra->ra_flowid_shift;
|
||||
else if (ra->ra_opts > 0)
|
||||
sc->sc_opts |= ra->ra_opts;
|
||||
if (ro->ro_opts == LAGG_OPT_FLOWIDSHIFT)
|
||||
sc->flowid_shift = ro->ro_flowid_shift;
|
||||
else if (ro->ro_opts > 0)
|
||||
sc->sc_opts |= ro->ro_opts;
|
||||
else
|
||||
sc->sc_opts &= ~ra->ra_opts;
|
||||
sc->sc_opts &= ~ro->ro_opts;
|
||||
} else {
|
||||
struct lacp_softc *lsc;
|
||||
|
||||
lsc = (struct lacp_softc *)sc->sc_psc;
|
||||
|
||||
switch (ra->ra_opts) {
|
||||
switch (ro->ro_opts) {
|
||||
case LAGG_OPT_LACP_TXTEST:
|
||||
lsc->lsc_debug.lsc_tx_test = 1;
|
||||
break;
|
||||
@ -1340,16 +1348,6 @@ lagg_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
|
||||
}
|
||||
}
|
||||
LAGG_WUNLOCK(sc);
|
||||
break; /* Return from SIOCSLAGG. */
|
||||
}
|
||||
if (ra->ra_proto < 1 || ra->ra_proto >= LAGG_PROTO_MAX) {
|
||||
error = EPROTONOSUPPORT;
|
||||
break;
|
||||
}
|
||||
|
||||
LAGG_WLOCK(sc);
|
||||
lagg_proto_detach(sc);
|
||||
lagg_proto_attach(sc, ra->ra_proto);
|
||||
break;
|
||||
case SIOCGLAGGFLAGS:
|
||||
rf->rf_flags = sc->sc_flags;
|
||||
|
@ -125,19 +125,6 @@ struct lagg_reqall {
|
||||
struct lacp_opreq rpsc_lacp;
|
||||
} ra_psc;
|
||||
#define ra_lacpreq ra_psc.rpsc_lacp
|
||||
int ra_opts; /* Option bitmap */
|
||||
#define LAGG_OPT_NONE 0x00
|
||||
#define LAGG_OPT_USE_FLOWID 0x01 /* use M_FLOWID */
|
||||
/* Pseudo flags which are used in ra_opts but not stored into sc_opts. */
|
||||
#define LAGG_OPT_FLOWIDSHIFT 0x02 /* Set flowid */
|
||||
#define LAGG_OPT_FLOWIDSHIFT_MASK 0x1f /* flowid is uint32_t */
|
||||
#define LAGG_OPT_LACP_STRICT 0x10 /* LACP strict mode */
|
||||
#define LAGG_OPT_LACP_TXTEST 0x20 /* LACP debug: txtest */
|
||||
#define LAGG_OPT_LACP_RXTEST 0x40 /* LACP debug: rxtest */
|
||||
u_int ra_count; /* number of ports */
|
||||
u_int ra_active; /* active port count */
|
||||
u_int ra_flapping; /* number of flapping */
|
||||
int ra_flowid_shift; /* shift the flowid */
|
||||
};
|
||||
|
||||
#define SIOCGLAGG _IOWR('i', 143, struct lagg_reqall)
|
||||
@ -151,6 +138,27 @@ struct lagg_reqflags {
|
||||
#define SIOCGLAGGFLAGS _IOWR('i', 145, struct lagg_reqflags)
|
||||
#define SIOCSLAGGHASH _IOW('i', 146, struct lagg_reqflags)
|
||||
|
||||
struct lagg_reqopts {
|
||||
char ro_ifname[IFNAMSIZ]; /* name of the lagg */
|
||||
|
||||
int ro_opts; /* Option bitmap */
|
||||
#define LAGG_OPT_NONE 0x00
|
||||
#define LAGG_OPT_USE_FLOWID 0x01 /* use M_FLOWID */
|
||||
/* Pseudo flags which are used in ro_opts but not stored into sc_opts. */
|
||||
#define LAGG_OPT_FLOWIDSHIFT 0x02 /* Set flowid */
|
||||
#define LAGG_OPT_FLOWIDSHIFT_MASK 0x1f /* flowid is uint32_t */
|
||||
#define LAGG_OPT_LACP_STRICT 0x10 /* LACP strict mode */
|
||||
#define LAGG_OPT_LACP_TXTEST 0x20 /* LACP debug: txtest */
|
||||
#define LAGG_OPT_LACP_RXTEST 0x40 /* LACP debug: rxtest */
|
||||
u_int ro_count; /* number of ports */
|
||||
u_int ro_active; /* active port count */
|
||||
u_int ro_flapping; /* number of flapping */
|
||||
int ro_flowid_shift; /* shift the flowid */
|
||||
};
|
||||
|
||||
#define SIOCGLAGGOPTS _IOWR('i', 152, struct lagg_reqopts)
|
||||
#define SIOCSLAGGOPTS _IOW('i', 153, struct lagg_reqopts)
|
||||
|
||||
#ifdef _KERNEL
|
||||
|
||||
/*
|
||||
|
Loading…
Reference in New Issue
Block a user