iflagg.c revision 168793
1168793Sthompsa/*-
2168793Sthompsa */
3168793Sthompsa
4168793Sthompsa#ifndef lint
5168793Sthompsastatic const char rcsid[] =
6168793Sthompsa  "$FreeBSD: head/sbin/ifconfig/iflagg.c 168793 2007-04-17 00:35:11Z thompsa $";
7168793Sthompsa#endif /* not lint */
8168793Sthompsa
9168793Sthompsa#include <sys/param.h>
10168793Sthompsa#include <sys/ioctl.h>
11168793Sthompsa#include <sys/socket.h>
12168793Sthompsa#include <sys/sockio.h>
13168793Sthompsa
14168793Sthompsa#include <stdlib.h>
15168793Sthompsa#include <unistd.h>
16168793Sthompsa
17168793Sthompsa#include <net/ethernet.h>
18168793Sthompsa#include <net/if.h>
19168793Sthompsa#include <net/if_lagg.h>
20168793Sthompsa#include <net/route.h>
21168793Sthompsa
22168793Sthompsa#include <ctype.h>
23168793Sthompsa#include <stdio.h>
24168793Sthompsa#include <string.h>
25168793Sthompsa#include <stdlib.h>
26168793Sthompsa#include <unistd.h>
27168793Sthompsa#include <err.h>
28168793Sthompsa#include <errno.h>
29168793Sthompsa
30168793Sthompsa#include "ifconfig.h"
31168793Sthompsa
32168793Sthompsastatic void
33168793Sthompsasetlaggport(const char *val, int d, int s, const struct afswtch *afp)
34168793Sthompsa{
35168793Sthompsa	struct lagg_reqport rp;
36168793Sthompsa
37168793Sthompsa	bzero(&rp, sizeof(rp));
38168793Sthompsa	strlcpy(rp.rp_ifname, name, sizeof(rp.rp_ifname));
39168793Sthompsa	strlcpy(rp.rp_portname, val, sizeof(rp.rp_portname));
40168793Sthompsa
41168793Sthompsa	if (ioctl(s, SIOCSLAGGPORT, &rp))
42168793Sthompsa		err(1, "SIOCSLAGGPORT");
43168793Sthompsa}
44168793Sthompsa
45168793Sthompsastatic void
46168793Sthompsaunsetlaggport(const char *val, int d, int s, const struct afswtch *afp)
47168793Sthompsa{
48168793Sthompsa	struct lagg_reqport rp;
49168793Sthompsa
50168793Sthompsa	bzero(&rp, sizeof(rp));
51168793Sthompsa	strlcpy(rp.rp_ifname, name, sizeof(rp.rp_ifname));
52168793Sthompsa	strlcpy(rp.rp_portname, val, sizeof(rp.rp_portname));
53168793Sthompsa
54168793Sthompsa	if (ioctl(s, SIOCSLAGGDELPORT, &rp))
55168793Sthompsa		err(1, "SIOCSLAGGDELPORT");
56168793Sthompsa}
57168793Sthompsa
58168793Sthompsastatic void
59168793Sthompsasetlaggproto(const char *val, int d, int s, const struct afswtch *afp)
60168793Sthompsa{
61168793Sthompsa	struct lagg_protos tpr[] = LAGG_PROTOS;
62168793Sthompsa	struct lagg_reqall ra;
63168793Sthompsa	int i;
64168793Sthompsa
65168793Sthompsa	bzero(&ra, sizeof(ra));
66168793Sthompsa	ra.ra_proto = LAGG_PROTO_MAX;
67168793Sthompsa
68168793Sthompsa	for (i = 0; i < (sizeof(tpr) / sizeof(tpr[0])); i++) {
69168793Sthompsa		if (strcmp(val, tpr[i].tpr_name) == 0) {
70168793Sthompsa			ra.ra_proto = tpr[i].tpr_proto;
71168793Sthompsa			break;
72168793Sthompsa		}
73168793Sthompsa	}
74168793Sthompsa	if (ra.ra_proto == LAGG_PROTO_MAX)
75168793Sthompsa		errx(1, "Invalid aggregation protocol: %s", val);
76168793Sthompsa
77168793Sthompsa	strlcpy(ra.ra_ifname, name, sizeof(ra.ra_ifname));
78168793Sthompsa	if (ioctl(s, SIOCSLAGG, &ra) != 0)
79168793Sthompsa		err(1, "SIOCSLAGG");
80168793Sthompsa}
81168793Sthompsa
82168793Sthompsastatic void
83168793Sthompsalagg_status(int s)
84168793Sthompsa{
85168793Sthompsa	struct lagg_protos tpr[] = LAGG_PROTOS;
86168793Sthompsa	struct lagg_reqport rp, rpbuf[LAGG_MAX_PORTS];
87168793Sthompsa	struct lagg_reqall ra;
88168793Sthompsa	const char *proto = "<unknown>";
89168793Sthompsa	int i, isport = 0;
90168793Sthompsa
91168793Sthompsa	bzero(&rp, sizeof(rp));
92168793Sthompsa	bzero(&ra, sizeof(ra));
93168793Sthompsa
94168793Sthompsa	strlcpy(rp.rp_ifname, name, sizeof(rp.rp_ifname));
95168793Sthompsa	strlcpy(rp.rp_portname, name, sizeof(rp.rp_portname));
96168793Sthompsa
97168793Sthompsa	if (ioctl(s, SIOCGLAGGPORT, &rp) == 0)
98168793Sthompsa		isport = 1;
99168793Sthompsa
100168793Sthompsa	strlcpy(ra.ra_ifname, name, sizeof(ra.ra_ifname));
101168793Sthompsa	ra.ra_size = sizeof(rpbuf);
102168793Sthompsa	ra.ra_port = rpbuf;
103168793Sthompsa
104168793Sthompsa	if (ioctl(s, SIOCGLAGG, &ra) == 0) {
105168793Sthompsa		for (i = 0; i < (sizeof(tpr) / sizeof(tpr[0])); i++) {
106168793Sthompsa			if (ra.ra_proto == tpr[i].tpr_proto) {
107168793Sthompsa				proto = tpr[i].tpr_name;
108168793Sthompsa				break;
109168793Sthompsa			}
110168793Sthompsa		}
111168793Sthompsa
112168793Sthompsa		printf("\tlagg: laggproto %s", proto);
113168793Sthompsa		if (isport)
114168793Sthompsa			printf(" laggdev %s", rp.rp_ifname);
115168793Sthompsa		putchar('\n');
116168793Sthompsa
117168793Sthompsa		for (i = 0; i < ra.ra_ports; i++) {
118168793Sthompsa			printf("\t\tlaggport %s ", rpbuf[i].rp_portname);
119168793Sthompsa			printb("", rpbuf[i].rp_flags, LAGG_PORT_BITS);
120168793Sthompsa			putchar('\n');
121168793Sthompsa		}
122168793Sthompsa
123168793Sthompsa		if (0 /* XXX */) {
124168793Sthompsa			printf("\tsupported aggregation protocols:\n");
125168793Sthompsa			for (i = 0; i < (sizeof(tpr) / sizeof(tpr[0])); i++)
126168793Sthompsa				printf("\t\tlaggproto %s\n", tpr[i].tpr_name);
127168793Sthompsa		}
128168793Sthompsa	} else if (isport)
129168793Sthompsa		printf("\tlagg: laggdev %s\n", rp.rp_ifname);
130168793Sthompsa}
131168793Sthompsa
132168793Sthompsastatic struct cmd lagg_cmds[] = {
133168793Sthompsa	DEF_CMD_ARG("laggport",		setlaggport),
134168793Sthompsa	DEF_CMD_ARG("-laggport",	unsetlaggport),
135168793Sthompsa	DEF_CMD_ARG("laggproto",	setlaggproto),
136168793Sthompsa};
137168793Sthompsastatic struct afswtch af_lagg = {
138168793Sthompsa	.af_name	= "af_lagg",
139168793Sthompsa	.af_af		= AF_UNSPEC,
140168793Sthompsa	.af_other_status = lagg_status,
141168793Sthompsa};
142168793Sthompsa
143168793Sthompsastatic __constructor void
144168793Sthompsalagg_ctor(void)
145168793Sthompsa{
146168793Sthompsa#define	N(a)	(sizeof(a) / sizeof(a[0]))
147168793Sthompsa	int i;
148168793Sthompsa
149168793Sthompsa	for (i = 0; i < N(lagg_cmds);  i++)
150168793Sthompsa		cmd_register(&lagg_cmds[i]);
151168793Sthompsa	af_register(&af_lagg);
152168793Sthompsa#undef N
153168793Sthompsa}
154