if_lagg.c (272386) | if_lagg.c (272446) |
---|---|
1/* $OpenBSD: if_trunk.c,v 1.30 2007/01/31 06:20:19 reyk Exp $ */ 2 3/* 4 * Copyright (c) 2005, 2006 Reyk Floeter <reyk@openbsd.org> 5 * Copyright (c) 2007 Andrew Thompson <thompsa@FreeBSD.org> 6 * Copyright (c) 2014 Marcelo Araujo <araujo@FreeBSD.org> 7 * 8 * Permission to use, copy, modify, and distribute this software for any --- 5 unchanged lines hidden (view full) --- 14 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 15 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 16 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 17 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 18 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 19 */ 20 21#include <sys/cdefs.h> | 1/* $OpenBSD: if_trunk.c,v 1.30 2007/01/31 06:20:19 reyk Exp $ */ 2 3/* 4 * Copyright (c) 2005, 2006 Reyk Floeter <reyk@openbsd.org> 5 * Copyright (c) 2007 Andrew Thompson <thompsa@FreeBSD.org> 6 * Copyright (c) 2014 Marcelo Araujo <araujo@FreeBSD.org> 7 * 8 * Permission to use, copy, modify, and distribute this software for any --- 5 unchanged lines hidden (view full) --- 14 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 15 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 16 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 17 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 18 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 19 */ 20 21#include <sys/cdefs.h> |
22__FBSDID("$FreeBSD: head/sys/net/if_lagg.c 272386 2014-10-01 21:37:32Z hrs $"); | 22__FBSDID("$FreeBSD: head/sys/net/if_lagg.c 272446 2014-10-02 20:01:13Z hrs $"); |
23 24#include "opt_inet.h" 25#include "opt_inet6.h" 26 27#include <sys/param.h> 28#include <sys/kernel.h> 29#include <sys/malloc.h> 30#include <sys/mbuf.h> --- 1153 unchanged lines hidden (view full) --- 1184 lagg_proto_stop(sc); 1185} 1186 1187static int 1188lagg_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data) 1189{ 1190 struct lagg_softc *sc = (struct lagg_softc *)ifp->if_softc; 1191 struct lagg_reqall *ra = (struct lagg_reqall *)data; | 23 24#include "opt_inet.h" 25#include "opt_inet6.h" 26 27#include <sys/param.h> 28#include <sys/kernel.h> 29#include <sys/malloc.h> 30#include <sys/mbuf.h> --- 1153 unchanged lines hidden (view full) --- 1184 lagg_proto_stop(sc); 1185} 1186 1187static int 1188lagg_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data) 1189{ 1190 struct lagg_softc *sc = (struct lagg_softc *)ifp->if_softc; 1191 struct lagg_reqall *ra = (struct lagg_reqall *)data; |
1192 struct lagg_reqopts *ro = (struct lagg_reqopts *)data; |
|
1192 struct lagg_reqport *rp = (struct lagg_reqport *)data, rpbuf; 1193 struct lagg_reqflags *rf = (struct lagg_reqflags *)data; 1194 struct ifreq *ifr = (struct ifreq *)data; 1195 struct lagg_port *lp; 1196 struct ifnet *tpif; 1197 struct thread *td = curthread; 1198 char *buf, *outbuf; 1199 int count, buflen, len, error = 0; --- 10 unchanged lines hidden (view full) --- 1210 buflen = count * sizeof(struct lagg_reqport); 1211 LAGG_RUNLOCK(sc, &tracker); 1212 1213 outbuf = malloc(buflen, M_TEMP, M_WAITOK | M_ZERO); 1214 1215 LAGG_RLOCK(sc, &tracker); 1216 ra->ra_proto = sc->sc_proto; 1217 lagg_proto_request(sc, &ra->ra_psc); | 1193 struct lagg_reqport *rp = (struct lagg_reqport *)data, rpbuf; 1194 struct lagg_reqflags *rf = (struct lagg_reqflags *)data; 1195 struct ifreq *ifr = (struct ifreq *)data; 1196 struct lagg_port *lp; 1197 struct ifnet *tpif; 1198 struct thread *td = curthread; 1199 char *buf, *outbuf; 1200 int count, buflen, len, error = 0; --- 10 unchanged lines hidden (view full) --- 1211 buflen = count * sizeof(struct lagg_reqport); 1212 LAGG_RUNLOCK(sc, &tracker); 1213 1214 outbuf = malloc(buflen, M_TEMP, M_WAITOK | M_ZERO); 1215 1216 LAGG_RLOCK(sc, &tracker); 1217 ra->ra_proto = sc->sc_proto; 1218 lagg_proto_request(sc, &ra->ra_psc); |
1218 ra->ra_opts = sc->sc_opts; 1219 if (sc->sc_proto == LAGG_PROTO_LACP) { 1220 struct lacp_softc *lsc; 1221 1222 lsc = (struct lacp_softc *)sc->sc_psc; 1223 if (lsc->lsc_debug.lsc_tx_test != 0) 1224 ra->ra_opts |= LAGG_OPT_LACP_TXTEST; 1225 if (lsc->lsc_debug.lsc_rx_test != 0) 1226 ra->ra_opts |= LAGG_OPT_LACP_RXTEST; 1227 if (lsc->lsc_strict_mode != 0) 1228 ra->ra_opts |= LAGG_OPT_LACP_STRICT; 1229 1230 ra->ra_active = sc->sc_active; 1231 } else { 1232 /* 1233 * LACP tracks active links automatically, 1234 * the others do not. 1235 */ 1236 ra->ra_active = 0; 1237 SLIST_FOREACH(lp, &sc->sc_ports, lp_entries) 1238 ra->ra_active += LAGG_PORTACTIVE(lp); 1239 } 1240 ra->ra_flapping = sc->sc_flapping; 1241 ra->ra_flowid_shift = sc->flowid_shift; 1242 | |
1243 count = 0; 1244 buf = outbuf; 1245 len = min(ra->ra_size, buflen); 1246 SLIST_FOREACH(lp, &sc->sc_ports, lp_entries) { 1247 if (len < sizeof(rpbuf)) 1248 break; 1249 1250 lagg_port2req(lp, &rpbuf); --- 4 unchanged lines hidden (view full) --- 1255 } 1256 LAGG_RUNLOCK(sc, &tracker); 1257 ra->ra_ports = count; 1258 ra->ra_size = count * sizeof(rpbuf); 1259 error = copyout(outbuf, ra->ra_port, ra->ra_size); 1260 free(outbuf, M_TEMP); 1261 break; 1262 case SIOCSLAGG: | 1219 count = 0; 1220 buf = outbuf; 1221 len = min(ra->ra_size, buflen); 1222 SLIST_FOREACH(lp, &sc->sc_ports, lp_entries) { 1223 if (len < sizeof(rpbuf)) 1224 break; 1225 1226 lagg_port2req(lp, &rpbuf); --- 4 unchanged lines hidden (view full) --- 1231 } 1232 LAGG_RUNLOCK(sc, &tracker); 1233 ra->ra_ports = count; 1234 ra->ra_size = count * sizeof(rpbuf); 1235 error = copyout(outbuf, ra->ra_port, ra->ra_size); 1236 free(outbuf, M_TEMP); 1237 break; 1238 case SIOCSLAGG: |
1263 /* 1264 * Set options or protocol depending on 1265 * ra->ra_opts and ra->ra_proto. 1266 */ | |
1267 error = priv_check(td, PRIV_NET_LAGG); 1268 if (error) 1269 break; | 1239 error = priv_check(td, PRIV_NET_LAGG); 1240 if (error) 1241 break; |
1270 if (ra->ra_opts != 0) { 1271 /* 1272 * Set options. LACP options are stored in sc->sc_psc, 1273 * not in sc_opts. 1274 */ 1275 int valid, lacp; | 1242 if (ra->ra_proto < 1 || ra->ra_proto >= LAGG_PROTO_MAX) { 1243 error = EPROTONOSUPPORT; 1244 break; 1245 } |
1276 | 1246 |
1277 switch (ra->ra_opts) { 1278 case LAGG_OPT_USE_FLOWID: 1279 case -LAGG_OPT_USE_FLOWID: 1280 case LAGG_OPT_FLOWIDSHIFT: 1281 valid = 1; 1282 lacp = 0; 1283 break; | 1247 LAGG_WLOCK(sc); 1248 lagg_proto_detach(sc); 1249 lagg_proto_attach(sc, ra->ra_proto); 1250 break; 1251 case SIOCGLAGGOPTS: 1252 ro->ro_opts = sc->sc_opts; 1253 if (sc->sc_proto == LAGG_PROTO_LACP) { 1254 struct lacp_softc *lsc; 1255 1256 lsc = (struct lacp_softc *)sc->sc_psc; 1257 if (lsc->lsc_debug.lsc_tx_test != 0) 1258 ro->ro_opts |= LAGG_OPT_LACP_TXTEST; 1259 if (lsc->lsc_debug.lsc_rx_test != 0) 1260 ro->ro_opts |= LAGG_OPT_LACP_RXTEST; 1261 if (lsc->lsc_strict_mode != 0) 1262 ro->ro_opts |= LAGG_OPT_LACP_STRICT; 1263 1264 ro->ro_active = sc->sc_active; 1265 } else { 1266 ro->ro_active = 0; 1267 SLIST_FOREACH(lp, &sc->sc_ports, lp_entries) 1268 ro->ro_active += LAGG_PORTACTIVE(lp); 1269 } 1270 ro->ro_flapping = sc->sc_flapping; 1271 ro->ro_flowid_shift = sc->flowid_shift; 1272 break; 1273 case SIOCSLAGGOPTS: 1274 error = priv_check(td, PRIV_NET_LAGG); 1275 if (error) 1276 break; 1277 if (ro->ro_opts == 0) 1278 break; 1279 /* 1280 * Set options. LACP options are stored in sc->sc_psc, 1281 * not in sc_opts. 1282 */ 1283 int valid, lacp; 1284 1285 switch (ro->ro_opts) { 1286 case LAGG_OPT_USE_FLOWID: 1287 case -LAGG_OPT_USE_FLOWID: 1288 case LAGG_OPT_FLOWIDSHIFT: 1289 valid = 1; 1290 lacp = 0; 1291 break; 1292 case LAGG_OPT_LACP_TXTEST: 1293 case -LAGG_OPT_LACP_TXTEST: 1294 case LAGG_OPT_LACP_RXTEST: 1295 case -LAGG_OPT_LACP_RXTEST: 1296 case LAGG_OPT_LACP_STRICT: 1297 case -LAGG_OPT_LACP_STRICT: 1298 valid = lacp = 1; 1299 break; 1300 default: 1301 valid = lacp = 0; 1302 break; 1303 } 1304 1305 LAGG_WLOCK(sc); 1306 if (valid == 0 || 1307 (lacp == 1 && sc->sc_proto != LAGG_PROTO_LACP)) { 1308 /* Invalid combination of options specified. */ 1309 error = EINVAL; 1310 LAGG_WUNLOCK(sc); 1311 break; /* Return from SIOCSLAGGOPTS. */ 1312 } 1313 /* 1314 * Store new options into sc->sc_opts except for 1315 * FLOWIDSHIFT and LACP options. 1316 */ 1317 if (lacp == 0) { 1318 if (ro->ro_opts == LAGG_OPT_FLOWIDSHIFT) 1319 sc->flowid_shift = ro->ro_flowid_shift; 1320 else if (ro->ro_opts > 0) 1321 sc->sc_opts |= ro->ro_opts; 1322 else 1323 sc->sc_opts &= ~ro->ro_opts; 1324 } else { 1325 struct lacp_softc *lsc; 1326 1327 lsc = (struct lacp_softc *)sc->sc_psc; 1328 1329 switch (ro->ro_opts) { |
1284 case LAGG_OPT_LACP_TXTEST: | 1330 case LAGG_OPT_LACP_TXTEST: |
1331 lsc->lsc_debug.lsc_tx_test = 1; 1332 break; |
|
1285 case -LAGG_OPT_LACP_TXTEST: | 1333 case -LAGG_OPT_LACP_TXTEST: |
1334 lsc->lsc_debug.lsc_tx_test = 0; 1335 break; |
|
1286 case LAGG_OPT_LACP_RXTEST: | 1336 case LAGG_OPT_LACP_RXTEST: |
1337 lsc->lsc_debug.lsc_rx_test = 1; 1338 break; |
|
1287 case -LAGG_OPT_LACP_RXTEST: | 1339 case -LAGG_OPT_LACP_RXTEST: |
1340 lsc->lsc_debug.lsc_rx_test = 0; 1341 break; |
|
1288 case LAGG_OPT_LACP_STRICT: | 1342 case LAGG_OPT_LACP_STRICT: |
1343 lsc->lsc_strict_mode = 1; 1344 break; |
|
1289 case -LAGG_OPT_LACP_STRICT: | 1345 case -LAGG_OPT_LACP_STRICT: |
1290 valid = lacp = 1; | 1346 lsc->lsc_strict_mode = 0; |
1291 break; | 1347 break; |
1292 default: 1293 valid = lacp = 0; 1294 break; | |
1295 } | 1348 } |
1296 1297 LAGG_WLOCK(sc); 1298 if (valid == 0 || 1299 (lacp == 1 && sc->sc_proto != LAGG_PROTO_LACP)) { 1300 /* Invalid combination of options specified. */ 1301 error = EINVAL; 1302 LAGG_WUNLOCK(sc); 1303 break; /* Return from SIOCSLAGG. */ 1304 } 1305 /* 1306 * Store new options into sc->sc_opts except for 1307 * FLOWIDSHIFT and LACP options. 1308 */ 1309 if (lacp == 0) { 1310 if (ra->ra_opts == LAGG_OPT_FLOWIDSHIFT) 1311 sc->flowid_shift = ra->ra_flowid_shift; 1312 else if (ra->ra_opts > 0) 1313 sc->sc_opts |= ra->ra_opts; 1314 else 1315 sc->sc_opts &= ~ra->ra_opts; 1316 } else { 1317 struct lacp_softc *lsc; 1318 1319 lsc = (struct lacp_softc *)sc->sc_psc; 1320 1321 switch (ra->ra_opts) { 1322 case LAGG_OPT_LACP_TXTEST: 1323 lsc->lsc_debug.lsc_tx_test = 1; 1324 break; 1325 case -LAGG_OPT_LACP_TXTEST: 1326 lsc->lsc_debug.lsc_tx_test = 0; 1327 break; 1328 case LAGG_OPT_LACP_RXTEST: 1329 lsc->lsc_debug.lsc_rx_test = 1; 1330 break; 1331 case -LAGG_OPT_LACP_RXTEST: 1332 lsc->lsc_debug.lsc_rx_test = 0; 1333 break; 1334 case LAGG_OPT_LACP_STRICT: 1335 lsc->lsc_strict_mode = 1; 1336 break; 1337 case -LAGG_OPT_LACP_STRICT: 1338 lsc->lsc_strict_mode = 0; 1339 break; 1340 } 1341 } 1342 LAGG_WUNLOCK(sc); 1343 break; /* Return from SIOCSLAGG. */ | |
1344 } | 1349 } |
1345 if (ra->ra_proto < 1 || ra->ra_proto >= LAGG_PROTO_MAX) { 1346 error = EPROTONOSUPPORT; 1347 break; 1348 } 1349 1350 LAGG_WLOCK(sc); 1351 lagg_proto_detach(sc); 1352 lagg_proto_attach(sc, ra->ra_proto); | 1350 LAGG_WUNLOCK(sc); |
1353 break; 1354 case SIOCGLAGGFLAGS: 1355 rf->rf_flags = sc->sc_flags; 1356 break; 1357 case SIOCSLAGGHASH: 1358 error = priv_check(td, PRIV_NET_LAGG); 1359 if (error) 1360 break; --- 897 unchanged lines hidden --- | 1351 break; 1352 case SIOCGLAGGFLAGS: 1353 rf->rf_flags = sc->sc_flags; 1354 break; 1355 case SIOCSLAGGHASH: 1356 error = priv_check(td, PRIV_NET_LAGG); 1357 if (error) 1358 break; --- 897 unchanged lines hidden --- |