| @@ -1,14 +1,14 @@ | | | @@ -1,14 +1,14 @@ |
1 | /* $NetBSD: if_bridge.c,v 1.110 2016/03/23 05:44:01 ozaki-r Exp $ */ | | 1 | /* $NetBSD: if_bridge.c,v 1.111 2016/03/28 04:38:04 ozaki-r Exp $ */ |
2 | | | 2 | |
3 | /* | | 3 | /* |
4 | * Copyright 2001 Wasabi Systems, Inc. | | 4 | * Copyright 2001 Wasabi Systems, Inc. |
5 | * All rights reserved. | | 5 | * All rights reserved. |
6 | * | | 6 | * |
7 | * Written by Jason R. Thorpe for Wasabi Systems, Inc. | | 7 | * Written by Jason R. Thorpe for Wasabi Systems, Inc. |
8 | * | | 8 | * |
9 | * Redistribution and use in source and binary forms, with or without | | 9 | * Redistribution and use in source and binary forms, with or without |
10 | * modification, are permitted provided that the following conditions | | 10 | * modification, are permitted provided that the following conditions |
11 | * are met: | | 11 | * are met: |
12 | * 1. Redistributions of source code must retain the above copyright | | 12 | * 1. Redistributions of source code must retain the above copyright |
13 | * notice, this list of conditions and the following disclaimer. | | 13 | * notice, this list of conditions and the following disclaimer. |
14 | * 2. Redistributions in binary form must reproduce the above copyright | | 14 | * 2. Redistributions in binary form must reproduce the above copyright |
| @@ -70,27 +70,27 @@ | | | @@ -70,27 +70,27 @@ |
70 | | | 70 | |
71 | /* | | 71 | /* |
72 | * Network interface bridge support. | | 72 | * Network interface bridge support. |
73 | * | | 73 | * |
74 | * TODO: | | 74 | * TODO: |
75 | * | | 75 | * |
76 | * - Currently only supports Ethernet-like interfaces (Ethernet, | | 76 | * - Currently only supports Ethernet-like interfaces (Ethernet, |
77 | * 802.11, VLANs on Ethernet, etc.) Figure out a nice way | | 77 | * 802.11, VLANs on Ethernet, etc.) Figure out a nice way |
78 | * to bridge other types of interfaces (FDDI-FDDI, and maybe | | 78 | * to bridge other types of interfaces (FDDI-FDDI, and maybe |
79 | * consider heterogenous bridges). | | 79 | * consider heterogenous bridges). |
80 | */ | | 80 | */ |
81 | | | 81 | |
82 | #include <sys/cdefs.h> | | 82 | #include <sys/cdefs.h> |
83 | __KERNEL_RCSID(0, "$NetBSD: if_bridge.c,v 1.110 2016/03/23 05:44:01 ozaki-r Exp $"); | | 83 | __KERNEL_RCSID(0, "$NetBSD: if_bridge.c,v 1.111 2016/03/28 04:38:04 ozaki-r Exp $"); |
84 | | | 84 | |
85 | #ifdef _KERNEL_OPT | | 85 | #ifdef _KERNEL_OPT |
86 | #include "opt_bridge_ipf.h" | | 86 | #include "opt_bridge_ipf.h" |
87 | #include "opt_inet.h" | | 87 | #include "opt_inet.h" |
88 | #endif /* _KERNEL_OPT */ | | 88 | #endif /* _KERNEL_OPT */ |
89 | | | 89 | |
90 | #include <sys/param.h> | | 90 | #include <sys/param.h> |
91 | #include <sys/kernel.h> | | 91 | #include <sys/kernel.h> |
92 | #include <sys/mbuf.h> | | 92 | #include <sys/mbuf.h> |
93 | #include <sys/queue.h> | | 93 | #include <sys/queue.h> |
94 | #include <sys/socket.h> | | 94 | #include <sys/socket.h> |
95 | #include <sys/socketvar.h> /* for softnet_lock */ | | 95 | #include <sys/socketvar.h> /* for softnet_lock */ |
96 | #include <sys/sockio.h> | | 96 | #include <sys/sockio.h> |
| @@ -331,46 +331,41 @@ static const struct bridge_control bridg | | | @@ -331,46 +331,41 @@ static const struct bridge_control bridg |
331 | [BRDGSIFPRIO] = {bridge_ioctl_sifprio, sizeof(struct ifbreq), BC_F_COPYIN|BC_F_SUSER}, | | 331 | [BRDGSIFPRIO] = {bridge_ioctl_sifprio, sizeof(struct ifbreq), BC_F_COPYIN|BC_F_SUSER}, |
332 | | | 332 | |
333 | [BRDGSIFCOST] = {bridge_ioctl_sifcost, sizeof(struct ifbreq), BC_F_COPYIN|BC_F_SUSER}, | | 333 | [BRDGSIFCOST] = {bridge_ioctl_sifcost, sizeof(struct ifbreq), BC_F_COPYIN|BC_F_SUSER}, |
334 | #if defined(BRIDGE_IPF) | | 334 | #if defined(BRIDGE_IPF) |
335 | [BRDGGFILT] = {bridge_ioctl_gfilt, sizeof(struct ifbrparam), BC_F_COPYOUT}, | | 335 | [BRDGGFILT] = {bridge_ioctl_gfilt, sizeof(struct ifbrparam), BC_F_COPYOUT}, |
336 | [BRDGSFILT] = {bridge_ioctl_sfilt, sizeof(struct ifbrparam), BC_F_COPYIN|BC_F_SUSER}, | | 336 | [BRDGSFILT] = {bridge_ioctl_sfilt, sizeof(struct ifbrparam), BC_F_COPYIN|BC_F_SUSER}, |
337 | #endif /* BRIDGE_IPF */ | | 337 | #endif /* BRIDGE_IPF */ |
338 | [BRDGGIFS] = {bridge_ioctl_gifs, sizeof(struct ifbifconf), BC_F_XLATEIN|BC_F_XLATEOUT}, | | 338 | [BRDGGIFS] = {bridge_ioctl_gifs, sizeof(struct ifbifconf), BC_F_XLATEIN|BC_F_XLATEOUT}, |
339 | [BRDGRTS] = {bridge_ioctl_rts, sizeof(struct ifbaconf), BC_F_XLATEIN|BC_F_XLATEOUT}, | | 339 | [BRDGRTS] = {bridge_ioctl_rts, sizeof(struct ifbaconf), BC_F_XLATEIN|BC_F_XLATEOUT}, |
340 | }; | | 340 | }; |
341 | | | 341 | |
342 | static const int bridge_control_table_size = __arraycount(bridge_control_table); | | 342 | static const int bridge_control_table_size = __arraycount(bridge_control_table); |
343 | | | 343 | |
344 | static LIST_HEAD(, bridge_softc) bridge_list; | | | |
345 | static kmutex_t bridge_list_lock; | | | |
346 | | | | |
347 | static struct if_clone bridge_cloner = | | 344 | static struct if_clone bridge_cloner = |
348 | IF_CLONE_INITIALIZER("bridge", bridge_clone_create, bridge_clone_destroy); | | 345 | IF_CLONE_INITIALIZER("bridge", bridge_clone_create, bridge_clone_destroy); |
349 | | | 346 | |
350 | /* | | 347 | /* |
351 | * bridgeattach: | | 348 | * bridgeattach: |
352 | * | | 349 | * |
353 | * Pseudo-device attach routine. | | 350 | * Pseudo-device attach routine. |
354 | */ | | 351 | */ |
355 | void | | 352 | void |
356 | bridgeattach(int n) | | 353 | bridgeattach(int n) |
357 | { | | 354 | { |
358 | | | 355 | |
359 | pool_init(&bridge_rtnode_pool, sizeof(struct bridge_rtnode), | | 356 | pool_init(&bridge_rtnode_pool, sizeof(struct bridge_rtnode), |
360 | 0, 0, 0, "brtpl", NULL, IPL_NET); | | 357 | 0, 0, 0, "brtpl", NULL, IPL_NET); |
361 | | | 358 | |
362 | LIST_INIT(&bridge_list); | | | |
363 | mutex_init(&bridge_list_lock, MUTEX_DEFAULT, IPL_NET); | | | |
364 | if_clone_attach(&bridge_cloner); | | 359 | if_clone_attach(&bridge_cloner); |
365 | } | | 360 | } |
366 | | | 361 | |
367 | /* | | 362 | /* |
368 | * bridge_clone_create: | | 363 | * bridge_clone_create: |
369 | * | | 364 | * |
370 | * Create a new bridge instance. | | 365 | * Create a new bridge instance. |
371 | */ | | 366 | */ |
372 | static int | | 367 | static int |
373 | bridge_clone_create(struct if_clone *ifc, int unit) | | 368 | bridge_clone_create(struct if_clone *ifc, int unit) |
374 | { | | 369 | { |
375 | struct bridge_softc *sc; | | 370 | struct bridge_softc *sc; |
376 | struct ifnet *ifp; | | 371 | struct ifnet *ifp; |
| @@ -422,58 +417,50 @@ bridge_clone_create(struct if_clone *ifc | | | @@ -422,58 +417,50 @@ bridge_clone_create(struct if_clone *ifc |
422 | ifp->if_start = bridge_start; | | 417 | ifp->if_start = bridge_start; |
423 | ifp->if_stop = bridge_stop; | | 418 | ifp->if_stop = bridge_stop; |
424 | ifp->if_init = bridge_init; | | 419 | ifp->if_init = bridge_init; |
425 | ifp->if_type = IFT_BRIDGE; | | 420 | ifp->if_type = IFT_BRIDGE; |
426 | ifp->if_addrlen = 0; | | 421 | ifp->if_addrlen = 0; |
427 | ifp->if_dlt = DLT_EN10MB; | | 422 | ifp->if_dlt = DLT_EN10MB; |
428 | ifp->if_hdrlen = ETHER_HDR_LEN; | | 423 | ifp->if_hdrlen = ETHER_HDR_LEN; |
429 | | | 424 | |
430 | if_initialize(ifp); | | 425 | if_initialize(ifp); |
431 | if_register(ifp); | | 426 | if_register(ifp); |
432 | | | 427 | |
433 | if_alloc_sadl(ifp); | | 428 | if_alloc_sadl(ifp); |
434 | | | 429 | |
435 | mutex_enter(&bridge_list_lock); | | | |
436 | LIST_INSERT_HEAD(&bridge_list, sc, sc_list); | | | |
437 | mutex_exit(&bridge_list_lock); | | | |
438 | | | | |
439 | return (0); | | 430 | return (0); |
440 | } | | 431 | } |
441 | | | 432 | |
442 | /* | | 433 | /* |
443 | * bridge_clone_destroy: | | 434 | * bridge_clone_destroy: |
444 | * | | 435 | * |
445 | * Destroy a bridge instance. | | 436 | * Destroy a bridge instance. |
446 | */ | | 437 | */ |
447 | static int | | 438 | static int |
448 | bridge_clone_destroy(struct ifnet *ifp) | | 439 | bridge_clone_destroy(struct ifnet *ifp) |
449 | { | | 440 | { |
450 | struct bridge_softc *sc = ifp->if_softc; | | 441 | struct bridge_softc *sc = ifp->if_softc; |
451 | struct bridge_iflist *bif; | | 442 | struct bridge_iflist *bif; |
452 | int s; | | 443 | int s; |
453 | | | 444 | |
454 | s = splnet(); | | 445 | s = splnet(); |
455 | | | 446 | |
456 | bridge_stop(ifp, 1); | | 447 | bridge_stop(ifp, 1); |
457 | | | 448 | |
458 | BRIDGE_LOCK(sc); | | 449 | BRIDGE_LOCK(sc); |
459 | while ((bif = LIST_FIRST(&sc->sc_iflist)) != NULL) | | 450 | while ((bif = LIST_FIRST(&sc->sc_iflist)) != NULL) |
460 | bridge_delete_member(sc, bif); | | 451 | bridge_delete_member(sc, bif); |
461 | BRIDGE_UNLOCK(sc); | | 452 | BRIDGE_UNLOCK(sc); |
462 | | | 453 | |
463 | mutex_enter(&bridge_list_lock); | | | |
464 | LIST_REMOVE(sc, sc_list); | | | |
465 | mutex_exit(&bridge_list_lock); | | | |
466 | | | | |
467 | splx(s); | | 454 | splx(s); |
468 | | | 455 | |
469 | if_detach(ifp); | | 456 | if_detach(ifp); |
470 | | | 457 | |
471 | /* Tear down the routing table. */ | | 458 | /* Tear down the routing table. */ |
472 | bridge_rtable_fini(sc); | | 459 | bridge_rtable_fini(sc); |
473 | | | 460 | |
474 | cv_destroy(&sc->sc_iflist_cv); | | 461 | cv_destroy(&sc->sc_iflist_cv); |
475 | | | 462 | |
476 | if (sc->sc_iflist_psz) | | 463 | if (sc->sc_iflist_psz) |
477 | pserialize_destroy(sc->sc_iflist_psz); | | 464 | pserialize_destroy(sc->sc_iflist_psz); |
478 | if (sc->sc_iflist_lock) | | 465 | if (sc->sc_iflist_lock) |
479 | mutex_obj_free(sc->sc_iflist_lock); | | 466 | mutex_obj_free(sc->sc_iflist_lock); |