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