Teach pfsync(4) that its member interfaces may go away.
This change partially resolves the issue in the PR. Further architectural fixes, in the form of reference counting, are needed. PR: 86848 Reviewed by: yar MFC after: 1 month
This commit is contained in:
parent
8071ab55dc
commit
6b47cca2a7
@ -170,6 +170,9 @@ void pfsync_timeout(void *);
|
|||||||
void pfsync_send_bus(struct pfsync_softc *, u_int8_t);
|
void pfsync_send_bus(struct pfsync_softc *, u_int8_t);
|
||||||
void pfsync_bulk_update(void *);
|
void pfsync_bulk_update(void *);
|
||||||
void pfsync_bulkfail(void *);
|
void pfsync_bulkfail(void *);
|
||||||
|
#ifdef __FreeBSD__
|
||||||
|
static void pfsync_ifdetach(void *, struct ifnet *);
|
||||||
|
#endif
|
||||||
|
|
||||||
int pfsync_sync_ok;
|
int pfsync_sync_ok;
|
||||||
#ifndef __FreeBSD__
|
#ifndef __FreeBSD__
|
||||||
@ -191,6 +194,9 @@ pfsync_clone_destroy(struct ifnet *ifp)
|
|||||||
struct pfsync_softc *sc;
|
struct pfsync_softc *sc;
|
||||||
|
|
||||||
sc = ifp->if_softc;
|
sc = ifp->if_softc;
|
||||||
|
#ifdef __FreeBSD__
|
||||||
|
EVENTHANDLER_DEREGISTER(ifnet_departure_event, sc->sc_detachtag);
|
||||||
|
#endif
|
||||||
callout_stop(&sc->sc_tmo);
|
callout_stop(&sc->sc_tmo);
|
||||||
callout_stop(&sc->sc_bulk_tmo);
|
callout_stop(&sc->sc_bulk_tmo);
|
||||||
callout_stop(&sc->sc_bulkfail_tmo);
|
callout_stop(&sc->sc_bulkfail_tmo);
|
||||||
@ -225,6 +231,16 @@ pfsync_clone_create(struct if_clone *ifc, int unit)
|
|||||||
return (ENOSPC);
|
return (ENOSPC);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef __FreeBSD__
|
||||||
|
sc->sc_detachtag = EVENTHANDLER_REGISTER(ifnet_departure_event,
|
||||||
|
pfsync_ifdetach, sc, EVENTHANDLER_PRI_ANY);
|
||||||
|
if (sc->sc_detachtag == NULL) {
|
||||||
|
if_free(ifp);
|
||||||
|
free(sc, M_PFSYNC);
|
||||||
|
return (ENOSPC);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
pfsync_sync_ok = 1;
|
pfsync_sync_ok = 1;
|
||||||
sc->sc_mbuf = NULL;
|
sc->sc_mbuf = NULL;
|
||||||
sc->sc_mbuf_net = NULL;
|
sc->sc_mbuf_net = NULL;
|
||||||
@ -1869,6 +1885,33 @@ pfsync_sendout(sc)
|
|||||||
}
|
}
|
||||||
|
|
||||||
#ifdef __FreeBSD__
|
#ifdef __FreeBSD__
|
||||||
|
static void
|
||||||
|
pfsync_ifdetach(void *arg, struct ifnet *ifp)
|
||||||
|
{
|
||||||
|
struct pfsync_softc *sc = (struct pfsync_softc *)arg;
|
||||||
|
struct ip_moptions *imo;
|
||||||
|
|
||||||
|
if (sc == NULL || sc->sc_sync_ifp != ifp)
|
||||||
|
return; /* not for us; unlocked read */
|
||||||
|
|
||||||
|
PF_LOCK();
|
||||||
|
|
||||||
|
/* Deal with a member interface going away from under us. */
|
||||||
|
sc->sc_sync_ifp = NULL;
|
||||||
|
if (sc->sc_mbuf_net != NULL) {
|
||||||
|
m_freem(sc->sc_mbuf_net);
|
||||||
|
sc->sc_mbuf_net = NULL;
|
||||||
|
sc->sc_statep_net.s = NULL;
|
||||||
|
}
|
||||||
|
imo = &sc->sc_imo;
|
||||||
|
if (imo->imo_num_memberships > 0) {
|
||||||
|
in_delmulti(imo->imo_membership[--imo->imo_num_memberships]);
|
||||||
|
imo->imo_multicast_ifp = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
PF_UNLOCK();
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
pfsync_senddef(void *arg)
|
pfsync_senddef(void *arg)
|
||||||
{
|
{
|
||||||
@ -1879,6 +1922,12 @@ pfsync_senddef(void *arg)
|
|||||||
IF_DEQUEUE(&sc->sc_ifq, m);
|
IF_DEQUEUE(&sc->sc_ifq, m);
|
||||||
if (m == NULL)
|
if (m == NULL)
|
||||||
break;
|
break;
|
||||||
|
/* Deal with a member interface going away from under us. */
|
||||||
|
if (sc->sc_sync_ifp == NULL) {
|
||||||
|
pfsyncstats.pfsyncs_oerrors++;
|
||||||
|
m_freem(m);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
if (ip_output(m, NULL, NULL, IP_RAWOUTPUT, &sc->sc_imo, NULL))
|
if (ip_output(m, NULL, NULL, IP_RAWOUTPUT, &sc->sc_imo, NULL))
|
||||||
pfsyncstats.pfsyncs_oerrors++;
|
pfsyncstats.pfsyncs_oerrors++;
|
||||||
}
|
}
|
||||||
|
@ -181,6 +181,7 @@ struct pfsync_softc {
|
|||||||
int sc_maxupdates; /* number of updates/state */
|
int sc_maxupdates; /* number of updates/state */
|
||||||
#ifdef __FreeBSD__
|
#ifdef __FreeBSD__
|
||||||
LIST_ENTRY(pfsync_softc) sc_next;
|
LIST_ENTRY(pfsync_softc) sc_next;
|
||||||
|
eventhandler_tag sc_detachtag;
|
||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
#endif
|
#endif
|
||||||
|
Loading…
Reference in New Issue
Block a user