freebsd-dev/sbin/ifconfig/iflagg.c
Andrew Thompson 18242d3b09 Rename the trunk(4) driver to lagg(4) as it is too similar to vlan trunking.
The name trunk is misused as the networking term trunk means carrying multiple
VLANs over a single connection. The IEEE standard for link aggregation (802.3
section 3) does not talk about 'trunk' at all while it is used throughout IEEE
802.1Q in describing vlans.

The lagg(4) driver provides link aggregation, failover and fault tolerance.

Discussed on:	current@
2007-04-17 00:35:11 +00:00

154 lines
3.3 KiB
C

/*-
*/
#ifndef lint
static const char rcsid[] =
"$FreeBSD$";
#endif /* not lint */
#include <sys/param.h>
#include <sys/ioctl.h>
#include <sys/socket.h>
#include <sys/sockio.h>
#include <stdlib.h>
#include <unistd.h>
#include <net/ethernet.h>
#include <net/if.h>
#include <net/if_lagg.h>
#include <net/route.h>
#include <ctype.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <err.h>
#include <errno.h>
#include "ifconfig.h"
static void
setlaggport(const char *val, int d, int s, const struct afswtch *afp)
{
struct lagg_reqport rp;
bzero(&rp, sizeof(rp));
strlcpy(rp.rp_ifname, name, sizeof(rp.rp_ifname));
strlcpy(rp.rp_portname, val, sizeof(rp.rp_portname));
if (ioctl(s, SIOCSLAGGPORT, &rp))
err(1, "SIOCSLAGGPORT");
}
static void
unsetlaggport(const char *val, int d, int s, const struct afswtch *afp)
{
struct lagg_reqport rp;
bzero(&rp, sizeof(rp));
strlcpy(rp.rp_ifname, name, sizeof(rp.rp_ifname));
strlcpy(rp.rp_portname, val, sizeof(rp.rp_portname));
if (ioctl(s, SIOCSLAGGDELPORT, &rp))
err(1, "SIOCSLAGGDELPORT");
}
static void
setlaggproto(const char *val, int d, int s, const struct afswtch *afp)
{
struct lagg_protos tpr[] = LAGG_PROTOS;
struct lagg_reqall ra;
int i;
bzero(&ra, sizeof(ra));
ra.ra_proto = LAGG_PROTO_MAX;
for (i = 0; i < (sizeof(tpr) / sizeof(tpr[0])); i++) {
if (strcmp(val, tpr[i].tpr_name) == 0) {
ra.ra_proto = tpr[i].tpr_proto;
break;
}
}
if (ra.ra_proto == LAGG_PROTO_MAX)
errx(1, "Invalid aggregation protocol: %s", val);
strlcpy(ra.ra_ifname, name, sizeof(ra.ra_ifname));
if (ioctl(s, SIOCSLAGG, &ra) != 0)
err(1, "SIOCSLAGG");
}
static void
lagg_status(int s)
{
struct lagg_protos tpr[] = LAGG_PROTOS;
struct lagg_reqport rp, rpbuf[LAGG_MAX_PORTS];
struct lagg_reqall ra;
const char *proto = "<unknown>";
int i, isport = 0;
bzero(&rp, sizeof(rp));
bzero(&ra, sizeof(ra));
strlcpy(rp.rp_ifname, name, sizeof(rp.rp_ifname));
strlcpy(rp.rp_portname, name, sizeof(rp.rp_portname));
if (ioctl(s, SIOCGLAGGPORT, &rp) == 0)
isport = 1;
strlcpy(ra.ra_ifname, name, sizeof(ra.ra_ifname));
ra.ra_size = sizeof(rpbuf);
ra.ra_port = rpbuf;
if (ioctl(s, SIOCGLAGG, &ra) == 0) {
for (i = 0; i < (sizeof(tpr) / sizeof(tpr[0])); i++) {
if (ra.ra_proto == tpr[i].tpr_proto) {
proto = tpr[i].tpr_name;
break;
}
}
printf("\tlagg: laggproto %s", proto);
if (isport)
printf(" laggdev %s", rp.rp_ifname);
putchar('\n');
for (i = 0; i < ra.ra_ports; i++) {
printf("\t\tlaggport %s ", rpbuf[i].rp_portname);
printb("", rpbuf[i].rp_flags, LAGG_PORT_BITS);
putchar('\n');
}
if (0 /* XXX */) {
printf("\tsupported aggregation protocols:\n");
for (i = 0; i < (sizeof(tpr) / sizeof(tpr[0])); i++)
printf("\t\tlaggproto %s\n", tpr[i].tpr_name);
}
} else if (isport)
printf("\tlagg: laggdev %s\n", rp.rp_ifname);
}
static struct cmd lagg_cmds[] = {
DEF_CMD_ARG("laggport", setlaggport),
DEF_CMD_ARG("-laggport", unsetlaggport),
DEF_CMD_ARG("laggproto", setlaggproto),
};
static struct afswtch af_lagg = {
.af_name = "af_lagg",
.af_af = AF_UNSPEC,
.af_other_status = lagg_status,
};
static __constructor void
lagg_ctor(void)
{
#define N(a) (sizeof(a) / sizeof(a[0]))
int i;
for (i = 0; i < N(lagg_cmds); i++)
cmd_register(&lagg_cmds[i]);
af_register(&af_lagg);
#undef N
}