1 /*- 2 */ 3 4 #ifndef lint 5 static const char rcsid[] = 6 "$FreeBSD$"; 7 #endif /* not lint */ 8 9 #include <sys/param.h> 10 #include <sys/ioctl.h> 11 #include <sys/socket.h> 12 #include <sys/sockio.h> 13 14 #include <stdlib.h> 15 #include <unistd.h> 16 17 #include <net/ethernet.h> 18 #include <net/if.h> 19 #include <net/if_lagg.h> 20 #include <net/route.h> 21 22 #include <ctype.h> 23 #include <stdio.h> 24 #include <string.h> 25 #include <stdlib.h> 26 #include <unistd.h> 27 #include <err.h> 28 #include <errno.h> 29 30 #include "ifconfig.h" 31 32 static void 33 setlaggport(const char *val, int d, int s, const struct afswtch *afp) 34 { 35 struct lagg_reqport rp; 36 37 bzero(&rp, sizeof(rp)); 38 strlcpy(rp.rp_ifname, name, sizeof(rp.rp_ifname)); 39 strlcpy(rp.rp_portname, val, sizeof(rp.rp_portname)); 40 41 if (ioctl(s, SIOCSLAGGPORT, &rp)) 42 err(1, "SIOCSLAGGPORT"); 43 } 44 45 static void 46 unsetlaggport(const char *val, int d, int s, const struct afswtch *afp) 47 { 48 struct lagg_reqport rp; 49 50 bzero(&rp, sizeof(rp)); 51 strlcpy(rp.rp_ifname, name, sizeof(rp.rp_ifname)); 52 strlcpy(rp.rp_portname, val, sizeof(rp.rp_portname)); 53 54 if (ioctl(s, SIOCSLAGGDELPORT, &rp)) 55 err(1, "SIOCSLAGGDELPORT"); 56 } 57 58 static void 59 setlaggproto(const char *val, int d, int s, const struct afswtch *afp) 60 { 61 struct lagg_protos lpr[] = LAGG_PROTOS; 62 struct lagg_reqall ra; 63 int i; 64 65 bzero(&ra, sizeof(ra)); 66 ra.ra_proto = LAGG_PROTO_MAX; 67 68 for (i = 0; i < (sizeof(lpr) / sizeof(lpr[0])); i++) { 69 if (strcmp(val, lpr[i].lpr_name) == 0) { 70 ra.ra_proto = lpr[i].lpr_proto; 71 break; 72 } 73 } 74 if (ra.ra_proto == LAGG_PROTO_MAX) 75 errx(1, "Invalid aggregation protocol: %s", val); 76 77 strlcpy(ra.ra_ifname, name, sizeof(ra.ra_ifname)); 78 if (ioctl(s, SIOCSLAGG, &ra) != 0) 79 err(1, "SIOCSLAGG"); 80 } 81 82 static void 83 lagg_status(int s) 84 { 85 struct lagg_protos lpr[] = LAGG_PROTOS; 86 struct lagg_reqport rp, rpbuf[LAGG_MAX_PORTS]; 87 struct lagg_reqall ra; 88 const char *proto = "<unknown>"; 89 int i, isport = 0; 90 91 bzero(&rp, sizeof(rp)); 92 bzero(&ra, sizeof(ra)); 93 94 strlcpy(rp.rp_ifname, name, sizeof(rp.rp_ifname)); 95 strlcpy(rp.rp_portname, name, sizeof(rp.rp_portname)); 96 97 if (ioctl(s, SIOCGLAGGPORT, &rp) == 0) 98 isport = 1; 99 100 strlcpy(ra.ra_ifname, name, sizeof(ra.ra_ifname)); 101 ra.ra_size = sizeof(rpbuf); 102 ra.ra_port = rpbuf; 103 104 if (ioctl(s, SIOCGLAGG, &ra) == 0) { 105 for (i = 0; i < (sizeof(lpr) / sizeof(lpr[0])); i++) { 106 if (ra.ra_proto == lpr[i].lpr_proto) { 107 proto = lpr[i].lpr_name; 108 break; 109 } 110 } 111 112 printf("\tlagg: laggproto %s", proto); 113 if (isport) 114 printf(" laggdev %s", rp.rp_ifname); 115 putchar('\n'); 116 117 for (i = 0; i < ra.ra_ports; i++) { 118 printf("\t\tlaggport %s ", rpbuf[i].rp_portname); 119 printb("", rpbuf[i].rp_flags, LAGG_PORT_BITS); 120 putchar('\n'); 121 } 122 123 if (0 /* XXX */) { 124 printf("\tsupported aggregation protocols:\n"); 125 for (i = 0; i < (sizeof(lpr) / sizeof(lpr[0])); i++) 126 printf("\t\tlaggproto %s\n", lpr[i].lpr_name); 127 } 128 } else if (isport) 129 printf("\tlagg: laggdev %s\n", rp.rp_ifname); 130 } 131 132 static struct cmd lagg_cmds[] = { 133 DEF_CMD_ARG("laggport", setlaggport), 134 DEF_CMD_ARG("-laggport", unsetlaggport), 135 DEF_CMD_ARG("laggproto", setlaggproto), 136 }; 137 static struct afswtch af_lagg = { 138 .af_name = "af_lagg", 139 .af_af = AF_UNSPEC, 140 .af_other_status = lagg_status, 141 }; 142 143 static __constructor void 144 lagg_ctor(void) 145 { 146 #define N(a) (sizeof(a) / sizeof(a[0])) 147 int i; 148 149 for (i = 0; i < N(lagg_cmds); i++) 150 cmd_register(&lagg_cmds[i]); 151 af_register(&af_lagg); 152 #undef N 153 } 154