bridge: Remove members when assigned to a new vnet

When the bridge is moved to a different vnet we must remove all of its
member interfaces (and span interfaces), because we don't know if those
will be moved along with it. We don't want to hold references to
interfaces not in our vnet.

Reviewed by:	donner@
MFC after:	1 week
Sponsored by:	Orange Business Services
Differential Revision:	https://reviews.freebsd.org/D28859
This commit is contained in:
Kristof Provost 2021-02-21 21:20:32 +01:00
parent 89fa9c34d7
commit 38c0951386
3 changed files with 29 additions and 3 deletions

View File

@ -437,6 +437,10 @@ extern uint32_t ether_crc32_be(const uint8_t *, size_t);
extern void ether_demux(struct ifnet *, struct mbuf *);
extern void ether_ifattach(struct ifnet *, const u_int8_t *);
extern void ether_ifdetach(struct ifnet *);
#ifdef VIMAGE
struct vnet;
extern void ether_reassign(struct ifnet *, struct vnet *, char *);
#endif
extern int ether_ioctl(struct ifnet *, u_long, caddr_t);
extern int ether_output(struct ifnet *, struct mbuf *,
const struct sockaddr *, struct route *);

View File

@ -670,6 +670,28 @@ SYSCTL_PROC(_net_link_bridge, OID_AUTO, ipfw,
&VNET_NAME(pfil_ipfw), 0, &sysctl_pfil_ipfw, "I",
"Layer2 filter with IPFW");
#ifdef VIMAGE
static void
bridge_reassign(struct ifnet *ifp, struct vnet *newvnet, char *arg)
{
struct bridge_softc *sc = ifp->if_softc;
struct bridge_iflist *bif;
BRIDGE_LOCK(sc);
while ((bif = CK_LIST_FIRST(&sc->sc_iflist)) != NULL)
bridge_delete_member(sc, bif, 0);
while ((bif = CK_LIST_FIRST(&sc->sc_spanlist)) != NULL) {
bridge_delete_span(sc, bif);
}
BRIDGE_UNLOCK(sc);
ether_reassign(ifp, newvnet, arg);
}
#endif
/*
* bridge_clone_create:
*
@ -716,6 +738,9 @@ bridge_clone_create(struct if_clone *ifc, int unit, caddr_t params)
/* Now undo some of the damage... */
ifp->if_baudrate = 0;
ifp->if_type = IFT_BRIDGE;
#ifdef VIMAGE
ifp->if_reassign = bridge_reassign;
#endif
BRIDGE_LIST_LOCK();
LIST_INSERT_HEAD(&V_bridge_list, sc, sc_list);

View File

@ -117,9 +117,6 @@ static const u_char etherbroadcastaddr[ETHER_ADDR_LEN] =
static int ether_resolvemulti(struct ifnet *, struct sockaddr **,
struct sockaddr *);
#ifdef VIMAGE
static void ether_reassign(struct ifnet *, struct vnet *, char *);
#endif
static int ether_requestencap(struct ifnet *, struct if_encap_req *);
#define senderr(e) do { error = (e); goto bad;} while (0)