Deleted Added
full compact
59c59
< __FBSDID("$FreeBSD: head/sys/contrib/pf/net/if_pfsync.c 229777 2012-01-07 14:39:45Z glebius $");
---
> __FBSDID("$FreeBSD: head/sys/contrib/pf/net/if_pfsync.c 229850 2012-01-09 08:50:22Z glebius $");
89a90
> #include <sys/protosw.h>
298,301d298
< #ifdef __FreeBSD__
< eventhandler_tag sc_detachtag;
< #endif
<
304a302
> static MALLOC_DEFINE(M_PFSYNC, "pfsync", "pfsync data");
307c305,306
<
---
> static VNET_DEFINE(void *, pfsync_swi_cookie) = NULL;
> #define V_pfsync_swi_cookie VNET(pfsync_swi_cookie)
312a312,317
> static void pfsyncintr(void *);
> static int pfsync_multicast_setup(struct pfsync_softc *);
> static void pfsync_multicast_cleanup(struct pfsync_softc *);
> static int pfsync_init(void);
> static void pfsync_uninit(void);
>
325,334d329
< #ifdef __FreeBSD__
< static void pfsyncintr(void *);
< struct pfsync_swi {
< void * pfsync_swi_cookie;
< };
< static struct pfsync_swi pfsync_swi;
< #define schednetisr(p) swi_sched(pfsync_swi.pfsync_swi_cookie, 0)
< #define NETISR_PFSYNC
< #endif
<
380,381d374
< void pfsync_ifdetach(void *, struct ifnet *);
<
392a386,389
> VNET_DEFINE(struct ifc_simple_data, pfsync_cloner_data);
> VNET_DEFINE(struct if_clone, pfsync_cloner);
> #define V_pfsync_cloner_data VNET(pfsync_cloner_data)
> #define V_pfsync_cloner VNET(pfsync_cloner)
418c415,418
< #ifndef __FreeBSD__
---
> #ifdef __FreeBSD__
> sc = malloc(sizeof(struct pfsync_softc), M_PFSYNC, M_WAITOK | M_ZERO);
> sc->pfsync_sync_ok = 1;
> #else
419a420
> sc = malloc(sizeof(*pfsyncif), M_DEVBUF, M_NOWAIT | M_ZERO);
422,425d422
< sc = malloc(sizeof(struct pfsync_softc), M_DEVBUF, M_NOWAIT | M_ZERO);
< if (sc == NULL)
< return (ENOMEM);
<
430,436c427,428
< sc->pfsync_sync_ok = 1;
< sc->sc_pool = uma_zcreate("pfsync", PFSYNC_PLSIZE,
< NULL, NULL, NULL, NULL, UMA_ALIGN_PTR, 0);
< if (sc->sc_pool == NULL) {
< free(sc, M_DEVBUF);
< return (ENOMEM);
< }
---
> sc->sc_pool = uma_zcreate("pfsync", PFSYNC_PLSIZE, NULL, NULL, NULL,
> NULL, UMA_ALIGN_PTR, 0);
449c441
< #ifdef __FreeBSD__
---
> #ifndef __FreeBSD__
451,456d442
< (sizeof(struct in_multi *) * IP_MIN_MEMBERSHIPS), M_DEVBUF,
< M_NOWAIT | M_ZERO);
< sc->sc_imo.imo_max_memberships = IP_MIN_MEMBERSHIPS;
< sc->sc_imo.imo_multicast_vif = -1;
< #else
< sc->sc_imo.imo_membership = (struct in_multi **)malloc(
465d450
< free(sc->sc_imo.imo_membership, M_DEVBUF);
467c452
< free(sc, M_DEVBUF);
---
> free(sc, M_PFSYNC);
471,474d455
<
< sc->sc_detachtag = EVENTHANDLER_REGISTER(ifnet_departure_event,
< #ifdef __FreeBSD__
< pfsync_ifdetach, V_pfsyncif, EVENTHANDLER_PRI_ANY);
476,485d456
< pfsync_ifdetach, pfsyncif, EVENTHANDLER_PRI_ANY);
< #endif
< if (sc->sc_detachtag == NULL) {
< if_free(ifp);
< free(sc->sc_imo.imo_membership, M_DEVBUF);
< uma_zdestroy(sc->sc_pool);
< free(sc, M_DEVBUF);
< return (ENOSPC);
< }
< #else
543d513
< EVENTHANDLER_DEREGISTER(ifnet_departure_event, sc->sc_detachtag);
576c546,548
< free(sc->sc_imo.imo_membership, M_DEVBUF);
---
> if (sc->sc_imo.imo_membership)
> pfsync_multicast_cleanup(sc);
> free(sc, M_PFSYNC);
579d550
< #endif
580a552
> #endif
1889c1861,1863
< #endif
---
> if (imo->imo_membership)
> pfsync_multicast_cleanup(sc);
> #else
1894a1869
> #endif
1919d1893
< if (imo->imo_num_memberships > 0) {
1920a1895
> if (imo->imo_membership) {
1922,1924c1897
< #endif
< in_delmulti(imo->imo_membership[--imo->imo_num_memberships]);
< #ifdef __FreeBSD__
---
> pfsync_multicast_cleanup(sc);
1926c1899,1902
< #endif
---
> }
> #else
> if (imo->imo_num_memberships > 0) {
> in_delmulti(imo->imo_membership[--imo->imo_num_memberships]);
1928a1905
> #endif
1930d1906
< if (sc->sc_sync_if &&
1931a1908
> if (sc->sc_sync_if &&
1932a1910,1915
> PF_UNLOCK();
> error = pfsync_multicast_setup(sc);
> if (error)
> return (error);
> PF_LOCK();
> }
1933a1917
> if (sc->sc_sync_if &&
1935d1918
< #endif
1940,1942d1922
< #ifdef __FreeBSD__
< PF_UNLOCK();
< #endif
1947,1949d1926
< #ifdef __FreeBSD__
< addr.s_addr = htonl(INADDR_PFSYNC_GROUP);
< #else
1951d1927
< #endif
1953,1955d1928
< #ifdef __FreeBSD__
< PF_UNLOCK();
< #endif
1962,1964d1934
< #ifdef __FreeBSD__
< PF_LOCK();
< #endif
1969a1940
> #endif /* !__FreeBSD__ */
2368c2339
< schednetisr(NETISR_PFSYNC);
---
> swi_sched(V_pfsync_swi_cookie, 0);
3345,3346c3316,3317
< void
< pfsync_ifdetach(void *arg, struct ifnet *ifp)
---
> static int
> pfsync_multicast_setup(struct pfsync_softc *sc)
3348,3349c3319,3320
< struct pfsync_softc *sc = (struct pfsync_softc *)arg;
< struct ip_moptions *imo;
---
> struct ip_moptions *imo = &sc->sc_imo;
> int error;
3351,3352c3322,3325
< if (sc == NULL || sc->sc_sync_if != ifp)
< return; /* not for us; unlocked read */
---
> if (!(sc->sc_sync_if->if_flags & IFF_MULTICAST)) {
> sc->sc_sync_if = NULL;
> return (EADDRNOTAVAIL);
> }
3354c3327,3331
< CURVNET_SET(sc->sc_ifp->if_vnet);
---
> imo->imo_membership = (struct in_multi **)malloc(
> (sizeof(struct in_multi *) * IP_MIN_MEMBERSHIPS), M_PFSYNC,
> M_WAITOK | M_ZERO);
> imo->imo_max_memberships = IP_MIN_MEMBERSHIPS;
> imo->imo_multicast_vif = -1;
3356,3373c3333,3336
< PF_LOCK();
<
< /* Deal with a member interface going away from under us. */
< sc->sc_sync_if = NULL;
< imo = &sc->sc_imo;
< if (imo->imo_num_memberships > 0) {
< KASSERT(imo->imo_num_memberships == 1,
< ("%s: imo_num_memberships != 1", __func__));
< /*
< * Our event handler is always called after protocol
< * domains have been detached from the underlying ifnet.
< * Do not call in_delmulti(); we held a single reference
< * which the protocol domain has purged in in_purgemaddrs().
< */
< PF_UNLOCK();
< imo->imo_membership[--imo->imo_num_memberships] = NULL;
< PF_LOCK();
< imo->imo_multicast_ifp = NULL;
---
> if ((error = in_joingroup(sc->sc_sync_if, &sc->sc_sync_peer, NULL,
> &imo->imo_membership[0])) != 0) {
> free(imo->imo_membership, M_PFSYNC);
> return (error);
3374a3338,3341
> imo->imo_num_memberships++;
> imo->imo_multicast_ifp = sc->sc_sync_if;
> imo->imo_multicast_ttl = PFSYNC_DFLTTL;
> imo->imo_multicast_loop = 0;
3376,3378c3343
< PF_UNLOCK();
<
< CURVNET_RESTORE();
---
> return (0);
3380a3346,3370
> static void
> pfsync_multicast_cleanup(struct pfsync_softc *sc)
> {
> struct ip_moptions *imo = &sc->sc_imo;
>
> in_leavegroup(imo->imo_membership[0], NULL);
> free(imo->imo_membership, M_PFSYNC);
> imo->imo_membership = NULL;
> imo->imo_multicast_ifp = NULL;
> }
>
> #ifdef INET
> extern struct domain inetdomain;
> static struct protosw in_pfsync_protosw = {
> .pr_type = SOCK_RAW,
> .pr_domain = &inetdomain,
> .pr_protocol = IPPROTO_PFSYNC,
> .pr_flags = PR_ATOMIC|PR_ADDR,
> .pr_input = pfsync_input,
> .pr_output = (pr_output_t *)rip_output,
> .pr_ctloutput = rip_ctloutput,
> .pr_usrreqs = &rip_usrreqs
> };
> #endif
>
3382c3372
< vnet_pfsync_init(const void *unused)
---
> pfsync_init()
3383a3374
> VNET_ITERATOR_DECL(vnet_iter);
3386,3389c3377,3392
< pfsyncattach(0);
<
< error = swi_add(NULL, "pfsync", pfsyncintr, V_pfsyncif,
< SWI_NET, INTR_MPSAFE, &pfsync_swi.pfsync_swi_cookie);
---
> VNET_LIST_RLOCK();
> VNET_FOREACH(vnet_iter) {
> CURVNET_SET(vnet_iter);
> V_pfsync_cloner = pfsync_cloner;
> V_pfsync_cloner_data = pfsync_cloner_data;
> V_pfsync_cloner.ifc_data = &V_pfsync_cloner_data;
> if_clone_attach(&V_pfsync_cloner);
> error = swi_add(NULL, "pfsync", pfsyncintr, V_pfsyncif,
> SWI_NET, INTR_MPSAFE, &V_pfsync_swi_cookie);
> CURVNET_RESTORE();
> if (error)
> goto fail_locked;
> }
> VNET_LIST_RUNLOCK();
> #ifdef INET
> error = pf_proto_register(PF_INET, &in_pfsync_protosw);
3391,3392c3394,3400
< panic("%s: swi_add %d", __func__, error);
<
---
> goto fail;
> error = ipproto_register(IPPROTO_PFSYNC);
> if (error) {
> pf_proto_unregister(PF_INET, IPPROTO_PFSYNC, SOCK_RAW);
> goto fail;
> }
> #endif
3404a3413,3427
>
> fail:
> VNET_LIST_RLOCK();
> fail_locked:
> VNET_FOREACH(vnet_iter) {
> CURVNET_SET(vnet_iter);
> if (V_pfsync_swi_cookie) {
> swi_remove(V_pfsync_swi_cookie);
> if_clone_detach(&V_pfsync_cloner);
> }
> CURVNET_RESTORE();
> }
> VNET_LIST_RUNLOCK();
>
> return (error);
3407,3408c3430,3431
< static int
< vnet_pfsync_uninit(const void *unused)
---
> static void
> pfsync_uninit()
3409a3433
> VNET_ITERATOR_DECL(vnet_iter);
3411,3412d3434
< swi_remove(pfsync_swi.pfsync_swi_cookie);
<
3424,3426c3446,3455
< if_clone_detach(&pfsync_cloner);
<
< return (0);
---
> ipproto_unregister(IPPROTO_PFSYNC);
> pf_proto_unregister(PF_INET, IPPROTO_PFSYNC, SOCK_RAW);
> VNET_LIST_RLOCK();
> VNET_FOREACH(vnet_iter) {
> CURVNET_SET(vnet_iter);
> swi_remove(V_pfsync_swi_cookie);
> if_clone_detach(&V_pfsync_cloner);
> CURVNET_RESTORE();
> }
> VNET_LIST_RUNLOCK();
3429,3447d3457
< /* Define startup order. */
< #define PFSYNC_SYSINIT_ORDER SI_SUB_PROTO_IF
< #define PFSYNC_MODEVENT_ORDER (SI_ORDER_FIRST) /* On boot slot in here. */
< #define PFSYNC_VNET_ORDER (PFSYNC_MODEVENT_ORDER + 2) /* Later still. */
<
< /*
< * Starting up.
< * VNET_SYSINIT is called for each existing vnet and each new vnet.
< */
< VNET_SYSINIT(vnet_pfsync_init, PFSYNC_SYSINIT_ORDER, PFSYNC_VNET_ORDER,
< vnet_pfsync_init, NULL);
<
< /*
< * Closing up shop. These are done in REVERSE ORDER,
< * Not called on reboot.
< * VNET_SYSUNINIT is called for each exiting vnet as it exits.
< */
< VNET_SYSUNINIT(vnet_pfsync_uninit, PFSYNC_SYSINIT_ORDER, PFSYNC_VNET_ORDER,
< vnet_pfsync_uninit, NULL);
3455,3457c3465
< #ifndef __FreeBSD__
< pfsyncattach(0);
< #endif
---
> error = pfsync_init();
3458a3467,3472
> case MOD_QUIESCE:
> /*
> * Module should not be unloaded due to race conditions.
> */
> error = EPERM;
> break;
3460,3462c3474
< #ifndef __FreeBSD__
< if_clone_detach(&pfsync_cloner);
< #endif
---
> pfsync_uninit();
3469c3481
< return error;
---
> return (error);
3480c3492
< DECLARE_MODULE(pfsync, pfsync_mod, SI_SUB_PSEUDO, SI_ORDER_ANY);
---
> DECLARE_MODULE(pfsync, pfsync_mod, SI_SUB_PROTO_DOMAIN, SI_ORDER_ANY);