Deleted Added
full compact
if_pfsync.c (229777) if_pfsync.c (229850)
1/* $OpenBSD: if_pfsync.c,v 1.110 2009/02/24 05:39:19 dlg Exp $ */
2
3/*
4 * Copyright (c) 2002 Michael Shalayeff
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions

--- 42 unchanged lines hidden (view full) ---

51 */
52
53#ifdef __FreeBSD__
54#include "opt_inet.h"
55#include "opt_inet6.h"
56#include "opt_pf.h"
57
58#include <sys/cdefs.h>
1/* $OpenBSD: if_pfsync.c,v 1.110 2009/02/24 05:39:19 dlg Exp $ */
2
3/*
4 * Copyright (c) 2002 Michael Shalayeff
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions

--- 42 unchanged lines hidden (view full) ---

51 */
52
53#ifdef __FreeBSD__
54#include "opt_inet.h"
55#include "opt_inet6.h"
56#include "opt_pf.h"
57
58#include <sys/cdefs.h>
59__FBSDID("$FreeBSD: head/sys/contrib/pf/net/if_pfsync.c 229777 2012-01-07 14:39:45Z glebius $");
59__FBSDID("$FreeBSD: head/sys/contrib/pf/net/if_pfsync.c 229850 2012-01-09 08:50:22Z glebius $");
60
61#define NBPFILTER 1
62
63#ifdef DEV_PFSYNC
64#define NPFSYNC DEV_PFSYNC
65#else
66#define NPFSYNC 0
67#endif

--- 14 unchanged lines hidden (view full) ---

82#ifdef __FreeBSD__
83#include <sys/endian.h>
84#include <sys/malloc.h>
85#include <sys/module.h>
86#include <sys/sockio.h>
87#include <sys/taskqueue.h>
88#include <sys/lock.h>
89#include <sys/mutex.h>
60
61#define NBPFILTER 1
62
63#ifdef DEV_PFSYNC
64#define NPFSYNC DEV_PFSYNC
65#else
66#define NPFSYNC 0
67#endif

--- 14 unchanged lines hidden (view full) ---

82#ifdef __FreeBSD__
83#include <sys/endian.h>
84#include <sys/malloc.h>
85#include <sys/module.h>
86#include <sys/sockio.h>
87#include <sys/taskqueue.h>
88#include <sys/lock.h>
89#include <sys/mutex.h>
90#include <sys/protosw.h>
90#else
91#include <sys/ioctl.h>
92#include <sys/timeout.h>
93#endif
94#include <sys/sysctl.h>
95#ifndef __FreeBSD__
96#include <sys/pool.h>
97#endif

--- 192 unchanged lines hidden (view full) ---

290
291 TAILQ_HEAD(, tdb) sc_tdb_q;
292
293#ifdef __FreeBSD__
294 struct callout sc_tmo;
295#else
296 struct timeout sc_tmo;
297#endif
91#else
92#include <sys/ioctl.h>
93#include <sys/timeout.h>
94#endif
95#include <sys/sysctl.h>
96#ifndef __FreeBSD__
97#include <sys/pool.h>
98#endif

--- 192 unchanged lines hidden (view full) ---

291
292 TAILQ_HEAD(, tdb) sc_tdb_q;
293
294#ifdef __FreeBSD__
295 struct callout sc_tmo;
296#else
297 struct timeout sc_tmo;
298#endif
298#ifdef __FreeBSD__
299 eventhandler_tag sc_detachtag;
300#endif
301
302};
303
304#ifdef __FreeBSD__
299};
300
301#ifdef __FreeBSD__
302static MALLOC_DEFINE(M_PFSYNC, "pfsync", "pfsync data");
305static VNET_DEFINE(struct pfsync_softc *, pfsyncif) = NULL;
306#define V_pfsyncif VNET(pfsyncif)
303static VNET_DEFINE(struct pfsync_softc *, pfsyncif) = NULL;
304#define V_pfsyncif VNET(pfsyncif)
307
305static VNET_DEFINE(void *, pfsync_swi_cookie) = NULL;
306#define V_pfsync_swi_cookie VNET(pfsync_swi_cookie)
308static VNET_DEFINE(struct pfsyncstats, pfsyncstats);
309#define V_pfsyncstats VNET(pfsyncstats)
310static VNET_DEFINE(int, pfsync_carp_adj) = CARP_MAXSKEW;
311#define V_pfsync_carp_adj VNET(pfsync_carp_adj)
312
307static VNET_DEFINE(struct pfsyncstats, pfsyncstats);
308#define V_pfsyncstats VNET(pfsyncstats)
309static VNET_DEFINE(int, pfsync_carp_adj) = CARP_MAXSKEW;
310#define V_pfsync_carp_adj VNET(pfsync_carp_adj)
311
312static void pfsyncintr(void *);
313static int pfsync_multicast_setup(struct pfsync_softc *);
314static void pfsync_multicast_cleanup(struct pfsync_softc *);
315static int pfsync_init(void);
316static void pfsync_uninit(void);
317
313SYSCTL_NODE(_net, OID_AUTO, pfsync, CTLFLAG_RW, 0, "PFSYNC");
314SYSCTL_VNET_STRUCT(_net_pfsync, OID_AUTO, stats, CTLFLAG_RW,
315 &VNET_NAME(pfsyncstats), pfsyncstats,
316 "PFSYNC statistics (struct pfsyncstats, net/if_pfsync.h)");
317SYSCTL_INT(_net_pfsync, OID_AUTO, carp_demotion_factor, CTLFLAG_RW,
318 &VNET_NAME(pfsync_carp_adj), 0, "pfsync's CARP demotion factor adjustment");
319#else
320struct pfsync_softc *pfsyncif = NULL;
321struct pfsyncstats pfsyncstats;
322#define V_pfsyncstats pfsyncstats
323#endif
324
318SYSCTL_NODE(_net, OID_AUTO, pfsync, CTLFLAG_RW, 0, "PFSYNC");
319SYSCTL_VNET_STRUCT(_net_pfsync, OID_AUTO, stats, CTLFLAG_RW,
320 &VNET_NAME(pfsyncstats), pfsyncstats,
321 "PFSYNC statistics (struct pfsyncstats, net/if_pfsync.h)");
322SYSCTL_INT(_net_pfsync, OID_AUTO, carp_demotion_factor, CTLFLAG_RW,
323 &VNET_NAME(pfsync_carp_adj), 0, "pfsync's CARP demotion factor adjustment");
324#else
325struct pfsync_softc *pfsyncif = NULL;
326struct pfsyncstats pfsyncstats;
327#define V_pfsyncstats pfsyncstats
328#endif
329
325#ifdef __FreeBSD__
326static void pfsyncintr(void *);
327struct pfsync_swi {
328 void * pfsync_swi_cookie;
329};
330static struct pfsync_swi pfsync_swi;
331#define schednetisr(p) swi_sched(pfsync_swi.pfsync_swi_cookie, 0)
332#define NETISR_PFSYNC
333#endif
334
335void pfsyncattach(int);
336#ifdef __FreeBSD__
337int pfsync_clone_create(struct if_clone *, int, caddr_t);
338void pfsync_clone_destroy(struct ifnet *);
339#else
340int pfsync_clone_create(struct if_clone *, int);
341int pfsync_clone_destroy(struct ifnet *);
342#endif

--- 29 unchanged lines hidden (view full) ---

372void pfsync_send_bus(struct pfsync_softc *, u_int8_t);
373
374void pfsync_bulk_start(void);
375void pfsync_bulk_status(u_int8_t);
376void pfsync_bulk_update(void *);
377void pfsync_bulk_fail(void *);
378
379#ifdef __FreeBSD__
330void pfsyncattach(int);
331#ifdef __FreeBSD__
332int pfsync_clone_create(struct if_clone *, int, caddr_t);
333void pfsync_clone_destroy(struct ifnet *);
334#else
335int pfsync_clone_create(struct if_clone *, int);
336int pfsync_clone_destroy(struct ifnet *);
337#endif

--- 29 unchanged lines hidden (view full) ---

367void pfsync_send_bus(struct pfsync_softc *, u_int8_t);
368
369void pfsync_bulk_start(void);
370void pfsync_bulk_status(u_int8_t);
371void pfsync_bulk_update(void *);
372void pfsync_bulk_fail(void *);
373
374#ifdef __FreeBSD__
380void pfsync_ifdetach(void *, struct ifnet *);
381
382/* XXX: ugly */
383#define betoh64 (unsigned long long)be64toh
384#define timeout_del callout_stop
385#endif
386
387#define PFSYNC_MAX_BULKTRIES 12
388#ifndef __FreeBSD__
389int pfsync_sync_ok;
390#endif
391
392#ifdef __FreeBSD__
375/* XXX: ugly */
376#define betoh64 (unsigned long long)be64toh
377#define timeout_del callout_stop
378#endif
379
380#define PFSYNC_MAX_BULKTRIES 12
381#ifndef __FreeBSD__
382int pfsync_sync_ok;
383#endif
384
385#ifdef __FreeBSD__
386VNET_DEFINE(struct ifc_simple_data, pfsync_cloner_data);
387VNET_DEFINE(struct if_clone, pfsync_cloner);
388#define V_pfsync_cloner_data VNET(pfsync_cloner_data)
389#define V_pfsync_cloner VNET(pfsync_cloner)
393IFC_SIMPLE_DECLARE(pfsync, 1);
394#else
395struct if_clone pfsync_cloner =
396 IF_CLONE_INITIALIZER("pfsync", pfsync_clone_create, pfsync_clone_destroy);
397#endif
398
399void
400pfsyncattach(int npfsync)

--- 9 unchanged lines hidden (view full) ---

410{
411 struct pfsync_softc *sc;
412 struct ifnet *ifp;
413 int q;
414
415 if (unit != 0)
416 return (EINVAL);
417
390IFC_SIMPLE_DECLARE(pfsync, 1);
391#else
392struct if_clone pfsync_cloner =
393 IF_CLONE_INITIALIZER("pfsync", pfsync_clone_create, pfsync_clone_destroy);
394#endif
395
396void
397pfsyncattach(int npfsync)

--- 9 unchanged lines hidden (view full) ---

407{
408 struct pfsync_softc *sc;
409 struct ifnet *ifp;
410 int q;
411
412 if (unit != 0)
413 return (EINVAL);
414
418#ifndef __FreeBSD__
415#ifdef __FreeBSD__
416 sc = malloc(sizeof(struct pfsync_softc), M_PFSYNC, M_WAITOK | M_ZERO);
417 sc->pfsync_sync_ok = 1;
418#else
419 pfsync_sync_ok = 1;
419 pfsync_sync_ok = 1;
420 sc = malloc(sizeof(*pfsyncif), M_DEVBUF, M_NOWAIT | M_ZERO);
420#endif
421
421#endif
422
422 sc = malloc(sizeof(struct pfsync_softc), M_DEVBUF, M_NOWAIT | M_ZERO);
423 if (sc == NULL)
424 return (ENOMEM);
425
426 for (q = 0; q < PFSYNC_S_COUNT; q++)
427 TAILQ_INIT(&sc->sc_qs[q]);
428
429#ifdef __FreeBSD__
423 for (q = 0; q < PFSYNC_S_COUNT; q++)
424 TAILQ_INIT(&sc->sc_qs[q]);
425
426#ifdef __FreeBSD__
430 sc->pfsync_sync_ok = 1;
431 sc->sc_pool = uma_zcreate("pfsync", PFSYNC_PLSIZE,
432 NULL, NULL, NULL, NULL, UMA_ALIGN_PTR, 0);
433 if (sc->sc_pool == NULL) {
434 free(sc, M_DEVBUF);
435 return (ENOMEM);
436 }
427 sc->sc_pool = uma_zcreate("pfsync", PFSYNC_PLSIZE, NULL, NULL, NULL,
428 NULL, UMA_ALIGN_PTR, 0);
437#else
438 pool_init(&sc->sc_pool, PFSYNC_PLSIZE, 0, 0, 0, "pfsync", NULL);
439#endif
440 TAILQ_INIT(&sc->sc_upd_req_list);
441 TAILQ_INIT(&sc->sc_deferrals);
442 sc->sc_deferred = 0;
443
444 TAILQ_INIT(&sc->sc_tdb_q);
445
446 sc->sc_len = PFSYNC_MINPKT;
447 sc->sc_maxupdates = 128;
448
429#else
430 pool_init(&sc->sc_pool, PFSYNC_PLSIZE, 0, 0, 0, "pfsync", NULL);
431#endif
432 TAILQ_INIT(&sc->sc_upd_req_list);
433 TAILQ_INIT(&sc->sc_deferrals);
434 sc->sc_deferred = 0;
435
436 TAILQ_INIT(&sc->sc_tdb_q);
437
438 sc->sc_len = PFSYNC_MINPKT;
439 sc->sc_maxupdates = 128;
440
449#ifdef __FreeBSD__
441#ifndef __FreeBSD__
450 sc->sc_imo.imo_membership = (struct in_multi **)malloc(
442 sc->sc_imo.imo_membership = (struct in_multi **)malloc(
451 (sizeof(struct in_multi *) * IP_MIN_MEMBERSHIPS), M_DEVBUF,
452 M_NOWAIT | M_ZERO);
453 sc->sc_imo.imo_max_memberships = IP_MIN_MEMBERSHIPS;
454 sc->sc_imo.imo_multicast_vif = -1;
455#else
456 sc->sc_imo.imo_membership = (struct in_multi **)malloc(
457 (sizeof(struct in_multi *) * IP_MIN_MEMBERSHIPS), M_IPMOPTS,
458 M_WAITOK | M_ZERO);
459 sc->sc_imo.imo_max_memberships = IP_MIN_MEMBERSHIPS;
460#endif
461
462#ifdef __FreeBSD__
463 ifp = sc->sc_ifp = if_alloc(IFT_PFSYNC);
464 if (ifp == NULL) {
443 (sizeof(struct in_multi *) * IP_MIN_MEMBERSHIPS), M_IPMOPTS,
444 M_WAITOK | M_ZERO);
445 sc->sc_imo.imo_max_memberships = IP_MIN_MEMBERSHIPS;
446#endif
447
448#ifdef __FreeBSD__
449 ifp = sc->sc_ifp = if_alloc(IFT_PFSYNC);
450 if (ifp == NULL) {
465 free(sc->sc_imo.imo_membership, M_DEVBUF);
466 uma_zdestroy(sc->sc_pool);
451 uma_zdestroy(sc->sc_pool);
467 free(sc, M_DEVBUF);
452 free(sc, M_PFSYNC);
468 return (ENOSPC);
469 }
470 if_initname(ifp, ifc->ifc_name, unit);
453 return (ENOSPC);
454 }
455 if_initname(ifp, ifc->ifc_name, unit);
471
472 sc->sc_detachtag = EVENTHANDLER_REGISTER(ifnet_departure_event,
473#ifdef __FreeBSD__
474 pfsync_ifdetach, V_pfsyncif, EVENTHANDLER_PRI_ANY);
475#else
456#else
476 pfsync_ifdetach, pfsyncif, EVENTHANDLER_PRI_ANY);
477#endif
478 if (sc->sc_detachtag == NULL) {
479 if_free(ifp);
480 free(sc->sc_imo.imo_membership, M_DEVBUF);
481 uma_zdestroy(sc->sc_pool);
482 free(sc, M_DEVBUF);
483 return (ENOSPC);
484 }
485#else
486 ifp = &sc->sc_if;
487 snprintf(ifp->if_xname, sizeof ifp->if_xname, "pfsync%d", unit);
488#endif
489 ifp->if_softc = sc;
490 ifp->if_ioctl = pfsyncioctl;
491 ifp->if_output = pfsyncoutput;
492 ifp->if_start = pfsyncstart;
493 ifp->if_type = IFT_PFSYNC;

--- 41 unchanged lines hidden (view full) ---

535#else
536int
537#endif
538pfsync_clone_destroy(struct ifnet *ifp)
539{
540 struct pfsync_softc *sc = ifp->if_softc;
541
542#ifdef __FreeBSD__
457 ifp = &sc->sc_if;
458 snprintf(ifp->if_xname, sizeof ifp->if_xname, "pfsync%d", unit);
459#endif
460 ifp->if_softc = sc;
461 ifp->if_ioctl = pfsyncioctl;
462 ifp->if_output = pfsyncoutput;
463 ifp->if_start = pfsyncstart;
464 ifp->if_type = IFT_PFSYNC;

--- 41 unchanged lines hidden (view full) ---

506#else
507int
508#endif
509pfsync_clone_destroy(struct ifnet *ifp)
510{
511 struct pfsync_softc *sc = ifp->if_softc;
512
513#ifdef __FreeBSD__
543 EVENTHANDLER_DEREGISTER(ifnet_departure_event, sc->sc_detachtag);
544 PF_LOCK();
545#endif
546 timeout_del(&sc->sc_bulkfail_tmo);
547 timeout_del(&sc->sc_bulk_tmo);
548 timeout_del(&sc->sc_tmo);
549#ifdef __FreeBSD__
550 PF_UNLOCK();
551 if (!sc->pfsync_sync_ok && carp_demote_adj_p)

--- 16 unchanged lines hidden (view full) ---

568
569#ifdef __FreeBSD__
570 UMA_DESTROY(sc->sc_pool);
571#else
572 pool_destroy(&sc->sc_pool);
573#endif
574#ifdef __FreeBSD__
575 if_free(ifp);
514 PF_LOCK();
515#endif
516 timeout_del(&sc->sc_bulkfail_tmo);
517 timeout_del(&sc->sc_bulk_tmo);
518 timeout_del(&sc->sc_tmo);
519#ifdef __FreeBSD__
520 PF_UNLOCK();
521 if (!sc->pfsync_sync_ok && carp_demote_adj_p)

--- 16 unchanged lines hidden (view full) ---

538
539#ifdef __FreeBSD__
540 UMA_DESTROY(sc->sc_pool);
541#else
542 pool_destroy(&sc->sc_pool);
543#endif
544#ifdef __FreeBSD__
545 if_free(ifp);
576 free(sc->sc_imo.imo_membership, M_DEVBUF);
546 if (sc->sc_imo.imo_membership)
547 pfsync_multicast_cleanup(sc);
548 free(sc, M_PFSYNC);
577#else
578 free(sc->sc_imo.imo_membership, M_IPMOPTS);
549#else
550 free(sc->sc_imo.imo_membership, M_IPMOPTS);
579#endif
580 free(sc, M_DEVBUF);
551 free(sc, M_DEVBUF);
552#endif
581
582#ifdef __FreeBSD__
583 V_pfsyncif = NULL;
584#else
585 pfsyncif = NULL;
586#endif
587
588#ifndef __FreeBSD__

--- 1292 unchanged lines hidden (view full) ---

1881 }
1882#endif
1883 sc->sc_maxupdates = pfsyncr.pfsyncr_maxupdates;
1884
1885 if (pfsyncr.pfsyncr_syncdev[0] == 0) {
1886 sc->sc_sync_if = NULL;
1887#ifdef __FreeBSD__
1888 PF_UNLOCK();
553
554#ifdef __FreeBSD__
555 V_pfsyncif = NULL;
556#else
557 pfsyncif = NULL;
558#endif
559
560#ifndef __FreeBSD__

--- 1292 unchanged lines hidden (view full) ---

1853 }
1854#endif
1855 sc->sc_maxupdates = pfsyncr.pfsyncr_maxupdates;
1856
1857 if (pfsyncr.pfsyncr_syncdev[0] == 0) {
1858 sc->sc_sync_if = NULL;
1859#ifdef __FreeBSD__
1860 PF_UNLOCK();
1889#endif
1861 if (imo->imo_membership)
1862 pfsync_multicast_cleanup(sc);
1863#else
1890 if (imo->imo_num_memberships > 0) {
1891 in_delmulti(imo->imo_membership[
1892 --imo->imo_num_memberships]);
1893 imo->imo_multicast_ifp = NULL;
1894 }
1864 if (imo->imo_num_memberships > 0) {
1865 in_delmulti(imo->imo_membership[
1866 --imo->imo_num_memberships]);
1867 imo->imo_multicast_ifp = NULL;
1868 }
1869#endif
1895 break;
1896 }
1897
1898#ifdef __FreeBSD__
1899 PF_UNLOCK();
1900#endif
1901 if ((sifp = ifunit(pfsyncr.pfsyncr_syncdev)) == NULL)
1902 return (EINVAL);

--- 8 unchanged lines hidden (view full) ---

1911 if (sifp->if_mtu < sc->sc_if.if_mtu ||
1912#endif
1913 (sc->sc_sync_if != NULL &&
1914 sifp->if_mtu < sc->sc_sync_if->if_mtu) ||
1915 sifp->if_mtu < MCLBYTES - sizeof(struct ip))
1916 pfsync_sendout();
1917 sc->sc_sync_if = sifp;
1918
1870 break;
1871 }
1872
1873#ifdef __FreeBSD__
1874 PF_UNLOCK();
1875#endif
1876 if ((sifp = ifunit(pfsyncr.pfsyncr_syncdev)) == NULL)
1877 return (EINVAL);

--- 8 unchanged lines hidden (view full) ---

1886 if (sifp->if_mtu < sc->sc_if.if_mtu ||
1887#endif
1888 (sc->sc_sync_if != NULL &&
1889 sifp->if_mtu < sc->sc_sync_if->if_mtu) ||
1890 sifp->if_mtu < MCLBYTES - sizeof(struct ip))
1891 pfsync_sendout();
1892 sc->sc_sync_if = sifp;
1893
1919 if (imo->imo_num_memberships > 0) {
1920#ifdef __FreeBSD__
1894#ifdef __FreeBSD__
1895 if (imo->imo_membership) {
1921 PF_UNLOCK();
1896 PF_UNLOCK();
1922#endif
1923 in_delmulti(imo->imo_membership[--imo->imo_num_memberships]);
1924#ifdef __FreeBSD__
1897 pfsync_multicast_cleanup(sc);
1925 PF_LOCK();
1898 PF_LOCK();
1926#endif
1899 }
1900#else
1901 if (imo->imo_num_memberships > 0) {
1902 in_delmulti(imo->imo_membership[--imo->imo_num_memberships]);
1927 imo->imo_multicast_ifp = NULL;
1928 }
1903 imo->imo_multicast_ifp = NULL;
1904 }
1905#endif
1929
1906
1930 if (sc->sc_sync_if &&
1931#ifdef __FreeBSD__
1907#ifdef __FreeBSD__
1908 if (sc->sc_sync_if &&
1932 sc->sc_sync_peer.s_addr == htonl(INADDR_PFSYNC_GROUP)) {
1909 sc->sc_sync_peer.s_addr == htonl(INADDR_PFSYNC_GROUP)) {
1910 PF_UNLOCK();
1911 error = pfsync_multicast_setup(sc);
1912 if (error)
1913 return (error);
1914 PF_LOCK();
1915 }
1933#else
1916#else
1917 if (sc->sc_sync_if &&
1934 sc->sc_sync_peer.s_addr == INADDR_PFSYNC_GROUP) {
1918 sc->sc_sync_peer.s_addr == INADDR_PFSYNC_GROUP) {
1935#endif
1936 struct in_addr addr;
1937
1938 if (!(sc->sc_sync_if->if_flags & IFF_MULTICAST)) {
1939 sc->sc_sync_if = NULL;
1919 struct in_addr addr;
1920
1921 if (!(sc->sc_sync_if->if_flags & IFF_MULTICAST)) {
1922 sc->sc_sync_if = NULL;
1940#ifdef __FreeBSD__
1941 PF_UNLOCK();
1942#endif
1943 splx(s);
1944 return (EADDRNOTAVAIL);
1945 }
1946
1923 splx(s);
1924 return (EADDRNOTAVAIL);
1925 }
1926
1947#ifdef __FreeBSD__
1948 addr.s_addr = htonl(INADDR_PFSYNC_GROUP);
1949#else
1950 addr.s_addr = INADDR_PFSYNC_GROUP;
1927 addr.s_addr = INADDR_PFSYNC_GROUP;
1951#endif
1952
1928
1953#ifdef __FreeBSD__
1954 PF_UNLOCK();
1955#endif
1956 if ((imo->imo_membership[0] =
1957 in_addmulti(&addr, sc->sc_sync_if)) == NULL) {
1958 sc->sc_sync_if = NULL;
1959 splx(s);
1960 return (ENOBUFS);
1961 }
1929 if ((imo->imo_membership[0] =
1930 in_addmulti(&addr, sc->sc_sync_if)) == NULL) {
1931 sc->sc_sync_if = NULL;
1932 splx(s);
1933 return (ENOBUFS);
1934 }
1962#ifdef __FreeBSD__
1963 PF_LOCK();
1964#endif
1965 imo->imo_num_memberships++;
1966 imo->imo_multicast_ifp = sc->sc_sync_if;
1967 imo->imo_multicast_ttl = PFSYNC_DFLTTL;
1968 imo->imo_multicast_loop = 0;
1969 }
1935 imo->imo_num_memberships++;
1936 imo->imo_multicast_ifp = sc->sc_sync_if;
1937 imo->imo_multicast_ttl = PFSYNC_DFLTTL;
1938 imo->imo_multicast_loop = 0;
1939 }
1940#endif /* !__FreeBSD__ */
1970
1971 ip = &sc->sc_template;
1972 bzero(ip, sizeof(*ip));
1973 ip->ip_v = IPVERSION;
1974 ip->ip_hl = sizeof(sc->sc_template) >> 2;
1975 ip->ip_tos = IPTOS_LOWDELAY;
1976 /* len and id are set later */
1977#ifdef __FreeBSD__

--- 382 unchanged lines hidden (view full) ---

2360#endif
2361
2362#ifdef __FreeBSD__
2363 sc->sc_ifp->if_opackets++;
2364 sc->sc_ifp->if_obytes += m->m_pkthdr.len;
2365 sc->sc_len = PFSYNC_MINPKT;
2366
2367 IFQ_ENQUEUE(&sc->sc_ifp->if_snd, m, dummy_error);
1941
1942 ip = &sc->sc_template;
1943 bzero(ip, sizeof(*ip));
1944 ip->ip_v = IPVERSION;
1945 ip->ip_hl = sizeof(sc->sc_template) >> 2;
1946 ip->ip_tos = IPTOS_LOWDELAY;
1947 /* len and id are set later */
1948#ifdef __FreeBSD__

--- 382 unchanged lines hidden (view full) ---

2331#endif
2332
2333#ifdef __FreeBSD__
2334 sc->sc_ifp->if_opackets++;
2335 sc->sc_ifp->if_obytes += m->m_pkthdr.len;
2336 sc->sc_len = PFSYNC_MINPKT;
2337
2338 IFQ_ENQUEUE(&sc->sc_ifp->if_snd, m, dummy_error);
2368 schednetisr(NETISR_PFSYNC);
2339 swi_sched(V_pfsync_swi_cookie, 0);
2369#else
2370 sc->sc_if.if_opackets++;
2371 sc->sc_if.if_obytes += m->m_pkthdr.len;
2372
2373 if (ip_output(m, NULL, NULL, IP_RAWOUTPUT, &sc->sc_imo, NULL) == 0)
2374 pfsyncstats.pfsyncs_opackets++;
2375 else
2376 pfsyncstats.pfsyncs_oerrors++;

--- 960 unchanged lines hidden (view full) ---

3337 return (sysctl_struct(oldp, oldlenp, newp, newlen,
3338 &V_pfsyncstats, sizeof(V_pfsyncstats)));
3339 }
3340#endif
3341 return (ENOPROTOOPT);
3342}
3343
3344#ifdef __FreeBSD__
2340#else
2341 sc->sc_if.if_opackets++;
2342 sc->sc_if.if_obytes += m->m_pkthdr.len;
2343
2344 if (ip_output(m, NULL, NULL, IP_RAWOUTPUT, &sc->sc_imo, NULL) == 0)
2345 pfsyncstats.pfsyncs_opackets++;
2346 else
2347 pfsyncstats.pfsyncs_oerrors++;

--- 960 unchanged lines hidden (view full) ---

3308 return (sysctl_struct(oldp, oldlenp, newp, newlen,
3309 &V_pfsyncstats, sizeof(V_pfsyncstats)));
3310 }
3311#endif
3312 return (ENOPROTOOPT);
3313}
3314
3315#ifdef __FreeBSD__
3345void
3346pfsync_ifdetach(void *arg, struct ifnet *ifp)
3316static int
3317pfsync_multicast_setup(struct pfsync_softc *sc)
3347{
3318{
3348 struct pfsync_softc *sc = (struct pfsync_softc *)arg;
3349 struct ip_moptions *imo;
3319 struct ip_moptions *imo = &sc->sc_imo;
3320 int error;
3350
3321
3351 if (sc == NULL || sc->sc_sync_if != ifp)
3352 return; /* not for us; unlocked read */
3322 if (!(sc->sc_sync_if->if_flags & IFF_MULTICAST)) {
3323 sc->sc_sync_if = NULL;
3324 return (EADDRNOTAVAIL);
3325 }
3353
3326
3354 CURVNET_SET(sc->sc_ifp->if_vnet);
3327 imo->imo_membership = (struct in_multi **)malloc(
3328 (sizeof(struct in_multi *) * IP_MIN_MEMBERSHIPS), M_PFSYNC,
3329 M_WAITOK | M_ZERO);
3330 imo->imo_max_memberships = IP_MIN_MEMBERSHIPS;
3331 imo->imo_multicast_vif = -1;
3355
3332
3356 PF_LOCK();
3357
3358 /* Deal with a member interface going away from under us. */
3359 sc->sc_sync_if = NULL;
3360 imo = &sc->sc_imo;
3361 if (imo->imo_num_memberships > 0) {
3362 KASSERT(imo->imo_num_memberships == 1,
3363 ("%s: imo_num_memberships != 1", __func__));
3364 /*
3365 * Our event handler is always called after protocol
3366 * domains have been detached from the underlying ifnet.
3367 * Do not call in_delmulti(); we held a single reference
3368 * which the protocol domain has purged in in_purgemaddrs().
3369 */
3370 PF_UNLOCK();
3371 imo->imo_membership[--imo->imo_num_memberships] = NULL;
3372 PF_LOCK();
3373 imo->imo_multicast_ifp = NULL;
3333 if ((error = in_joingroup(sc->sc_sync_if, &sc->sc_sync_peer, NULL,
3334 &imo->imo_membership[0])) != 0) {
3335 free(imo->imo_membership, M_PFSYNC);
3336 return (error);
3374 }
3337 }
3338 imo->imo_num_memberships++;
3339 imo->imo_multicast_ifp = sc->sc_sync_if;
3340 imo->imo_multicast_ttl = PFSYNC_DFLTTL;
3341 imo->imo_multicast_loop = 0;
3375
3342
3376 PF_UNLOCK();
3377
3378 CURVNET_RESTORE();
3343 return (0);
3379}
3380
3344}
3345
3346static void
3347pfsync_multicast_cleanup(struct pfsync_softc *sc)
3348{
3349 struct ip_moptions *imo = &sc->sc_imo;
3350
3351 in_leavegroup(imo->imo_membership[0], NULL);
3352 free(imo->imo_membership, M_PFSYNC);
3353 imo->imo_membership = NULL;
3354 imo->imo_multicast_ifp = NULL;
3355}
3356
3357#ifdef INET
3358extern struct domain inetdomain;
3359static struct protosw in_pfsync_protosw = {
3360 .pr_type = SOCK_RAW,
3361 .pr_domain = &inetdomain,
3362 .pr_protocol = IPPROTO_PFSYNC,
3363 .pr_flags = PR_ATOMIC|PR_ADDR,
3364 .pr_input = pfsync_input,
3365 .pr_output = (pr_output_t *)rip_output,
3366 .pr_ctloutput = rip_ctloutput,
3367 .pr_usrreqs = &rip_usrreqs
3368};
3369#endif
3370
3381static int
3371static int
3382vnet_pfsync_init(const void *unused)
3372pfsync_init()
3383{
3373{
3374 VNET_ITERATOR_DECL(vnet_iter);
3384 int error = 0;
3385
3375 int error = 0;
3376
3386 pfsyncattach(0);
3387
3388 error = swi_add(NULL, "pfsync", pfsyncintr, V_pfsyncif,
3389 SWI_NET, INTR_MPSAFE, &pfsync_swi.pfsync_swi_cookie);
3377 VNET_LIST_RLOCK();
3378 VNET_FOREACH(vnet_iter) {
3379 CURVNET_SET(vnet_iter);
3380 V_pfsync_cloner = pfsync_cloner;
3381 V_pfsync_cloner_data = pfsync_cloner_data;
3382 V_pfsync_cloner.ifc_data = &V_pfsync_cloner_data;
3383 if_clone_attach(&V_pfsync_cloner);
3384 error = swi_add(NULL, "pfsync", pfsyncintr, V_pfsyncif,
3385 SWI_NET, INTR_MPSAFE, &V_pfsync_swi_cookie);
3386 CURVNET_RESTORE();
3387 if (error)
3388 goto fail_locked;
3389 }
3390 VNET_LIST_RUNLOCK();
3391#ifdef INET
3392 error = pf_proto_register(PF_INET, &in_pfsync_protosw);
3390 if (error)
3393 if (error)
3391 panic("%s: swi_add %d", __func__, error);
3392
3394 goto fail;
3395 error = ipproto_register(IPPROTO_PFSYNC);
3396 if (error) {
3397 pf_proto_unregister(PF_INET, IPPROTO_PFSYNC, SOCK_RAW);
3398 goto fail;
3399 }
3400#endif
3393 PF_LOCK();
3394 pfsync_state_import_ptr = pfsync_state_import;
3395 pfsync_up_ptr = pfsync_up;
3396 pfsync_insert_state_ptr = pfsync_insert_state;
3397 pfsync_update_state_ptr = pfsync_update_state;
3398 pfsync_delete_state_ptr = pfsync_delete_state;
3399 pfsync_clear_states_ptr = pfsync_clear_states;
3400 pfsync_state_in_use_ptr = pfsync_state_in_use;
3401 pfsync_defer_ptr = pfsync_defer;
3402 PF_UNLOCK();
3403
3404 return (0);
3401 PF_LOCK();
3402 pfsync_state_import_ptr = pfsync_state_import;
3403 pfsync_up_ptr = pfsync_up;
3404 pfsync_insert_state_ptr = pfsync_insert_state;
3405 pfsync_update_state_ptr = pfsync_update_state;
3406 pfsync_delete_state_ptr = pfsync_delete_state;
3407 pfsync_clear_states_ptr = pfsync_clear_states;
3408 pfsync_state_in_use_ptr = pfsync_state_in_use;
3409 pfsync_defer_ptr = pfsync_defer;
3410 PF_UNLOCK();
3411
3412 return (0);
3413
3414fail:
3415 VNET_LIST_RLOCK();
3416fail_locked:
3417 VNET_FOREACH(vnet_iter) {
3418 CURVNET_SET(vnet_iter);
3419 if (V_pfsync_swi_cookie) {
3420 swi_remove(V_pfsync_swi_cookie);
3421 if_clone_detach(&V_pfsync_cloner);
3422 }
3423 CURVNET_RESTORE();
3424 }
3425 VNET_LIST_RUNLOCK();
3426
3427 return (error);
3405}
3406
3428}
3429
3407static int
3408vnet_pfsync_uninit(const void *unused)
3430static void
3431pfsync_uninit()
3409{
3432{
3433 VNET_ITERATOR_DECL(vnet_iter);
3410
3434
3411 swi_remove(pfsync_swi.pfsync_swi_cookie);
3412
3413 PF_LOCK();
3414 pfsync_state_import_ptr = NULL;
3415 pfsync_up_ptr = NULL;
3416 pfsync_insert_state_ptr = NULL;
3417 pfsync_update_state_ptr = NULL;
3418 pfsync_delete_state_ptr = NULL;
3419 pfsync_clear_states_ptr = NULL;
3420 pfsync_state_in_use_ptr = NULL;
3421 pfsync_defer_ptr = NULL;
3422 PF_UNLOCK();
3423
3435 PF_LOCK();
3436 pfsync_state_import_ptr = NULL;
3437 pfsync_up_ptr = NULL;
3438 pfsync_insert_state_ptr = NULL;
3439 pfsync_update_state_ptr = NULL;
3440 pfsync_delete_state_ptr = NULL;
3441 pfsync_clear_states_ptr = NULL;
3442 pfsync_state_in_use_ptr = NULL;
3443 pfsync_defer_ptr = NULL;
3444 PF_UNLOCK();
3445
3424 if_clone_detach(&pfsync_cloner);
3425
3426 return (0);
3446 ipproto_unregister(IPPROTO_PFSYNC);
3447 pf_proto_unregister(PF_INET, IPPROTO_PFSYNC, SOCK_RAW);
3448 VNET_LIST_RLOCK();
3449 VNET_FOREACH(vnet_iter) {
3450 CURVNET_SET(vnet_iter);
3451 swi_remove(V_pfsync_swi_cookie);
3452 if_clone_detach(&V_pfsync_cloner);
3453 CURVNET_RESTORE();
3454 }
3455 VNET_LIST_RUNLOCK();
3427}
3428
3456}
3457
3429/* Define startup order. */
3430#define PFSYNC_SYSINIT_ORDER SI_SUB_PROTO_IF
3431#define PFSYNC_MODEVENT_ORDER (SI_ORDER_FIRST) /* On boot slot in here. */
3432#define PFSYNC_VNET_ORDER (PFSYNC_MODEVENT_ORDER + 2) /* Later still. */
3433
3434/*
3435 * Starting up.
3436 * VNET_SYSINIT is called for each existing vnet and each new vnet.
3437 */
3438VNET_SYSINIT(vnet_pfsync_init, PFSYNC_SYSINIT_ORDER, PFSYNC_VNET_ORDER,
3439 vnet_pfsync_init, NULL);
3440
3441/*
3442 * Closing up shop. These are done in REVERSE ORDER,
3443 * Not called on reboot.
3444 * VNET_SYSUNINIT is called for each exiting vnet as it exits.
3445 */
3446VNET_SYSUNINIT(vnet_pfsync_uninit, PFSYNC_SYSINIT_ORDER, PFSYNC_VNET_ORDER,
3447 vnet_pfsync_uninit, NULL);
3448static int
3449pfsync_modevent(module_t mod, int type, void *data)
3450{
3451 int error = 0;
3452
3453 switch (type) {
3454 case MOD_LOAD:
3458static int
3459pfsync_modevent(module_t mod, int type, void *data)
3460{
3461 int error = 0;
3462
3463 switch (type) {
3464 case MOD_LOAD:
3455#ifndef __FreeBSD__
3456 pfsyncattach(0);
3457#endif
3465 error = pfsync_init();
3458 break;
3466 break;
3467 case MOD_QUIESCE:
3468 /*
3469 * Module should not be unloaded due to race conditions.
3470 */
3471 error = EPERM;
3472 break;
3459 case MOD_UNLOAD:
3473 case MOD_UNLOAD:
3460#ifndef __FreeBSD__
3461 if_clone_detach(&pfsync_cloner);
3462#endif
3474 pfsync_uninit();
3463 break;
3464 default:
3465 error = EINVAL;
3466 break;
3467 }
3468
3475 break;
3476 default:
3477 error = EINVAL;
3478 break;
3479 }
3480
3469 return error;
3481 return (error);
3470}
3471
3472static moduledata_t pfsync_mod = {
3473 "pfsync",
3474 pfsync_modevent,
3475 0
3476};
3477
3478#define PFSYNC_MODVER 1
3479
3482}
3483
3484static moduledata_t pfsync_mod = {
3485 "pfsync",
3486 pfsync_modevent,
3487 0
3488};
3489
3490#define PFSYNC_MODVER 1
3491
3480DECLARE_MODULE(pfsync, pfsync_mod, SI_SUB_PSEUDO, SI_ORDER_ANY);
3492DECLARE_MODULE(pfsync, pfsync_mod, SI_SUB_PROTO_DOMAIN, SI_ORDER_ANY);
3481MODULE_VERSION(pfsync, PFSYNC_MODVER);
3482MODULE_DEPEND(pfsync, pf, PF_MODVER, PF_MODVER, PF_MODVER);
3483#endif /* __FreeBSD__ */
3493MODULE_VERSION(pfsync, PFSYNC_MODVER);
3494MODULE_DEPEND(pfsync, pf, PF_MODVER, PF_MODVER, PF_MODVER);
3495#endif /* __FreeBSD__ */