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__ */ |