summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRyan Thomas McBride <mcbride@cvs.openbsd.org>2004-08-03 05:32:29 +0000
committerRyan Thomas McBride <mcbride@cvs.openbsd.org>2004-08-03 05:32:29 +0000
commita5d7a223fc330982c47af1f4bfde48edd6b2ce2c (patch)
treea4de4ca370a8c023da52f302159a5c0da4fb9683
parent6e990f22928e1eb514d3d458fa9120463b3459f5 (diff)
Allow a unicast ip address to be specified for pfsync to send it's state
updates to; this allows pairs of pfsync firewalls to protect the traffic with IPSec.
-rw-r--r--sys/net/if_pfsync.c41
-rw-r--r--sys/net/if_pfsync.h12
2 files changed, 34 insertions, 19 deletions
diff --git a/sys/net/if_pfsync.c b/sys/net/if_pfsync.c
index afc07b30add..01d4ef824c2 100644
--- a/sys/net/if_pfsync.c
+++ b/sys/net/if_pfsync.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: if_pfsync.c,v 1.35 2004/06/21 23:50:36 tholo Exp $ */
+/* $OpenBSD: if_pfsync.c,v 1.36 2004/08/03 05:32:28 mcbride Exp $ */
/*
* Copyright (c) 2002 Michael Shalayeff
@@ -113,6 +113,7 @@ pfsyncattach(int npfsync)
pfsyncif.sc_statep.s = NULL;
pfsyncif.sc_statep_net.s = NULL;
pfsyncif.sc_maxupdates = 128;
+ pfsyncif.sc_sync_peer.s_addr = INADDR_PFSYNC_GROUP;
pfsyncif.sc_sendaddr.s_addr = INADDR_PFSYNC_GROUP;
pfsyncif.sc_ureq_received = 0;
pfsyncif.sc_ureq_sent = 0;
@@ -742,6 +743,7 @@ pfsyncioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
if (sc->sc_sync_ifp)
strlcpy(pfsyncr.pfsyncr_syncif,
sc->sc_sync_ifp->if_xname, IFNAMSIZ);
+ pfsyncr.pfsyncr_syncpeer = sc->sc_sync_peer;
pfsyncr.pfsyncr_maxupdates = sc->sc_maxupdates;
if ((error = copyout(&pfsyncr, ifr->ifr_data, sizeof(pfsyncr))))
return (error);
@@ -752,6 +754,12 @@ pfsyncioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
if ((error = copyin(ifr->ifr_data, &pfsyncr, sizeof(pfsyncr))))
return (error);
+ if (pfsyncr.pfsyncr_syncpeer.s_addr == 0)
+ sc->sc_sync_peer.s_addr = INADDR_PFSYNC_GROUP;
+ else
+ sc->sc_sync_peer.s_addr =
+ pfsyncr.pfsyncr_syncpeer.s_addr;
+
if (pfsyncr.pfsyncr_maxupdates > 255)
return (EINVAL);
sc->sc_maxupdates = pfsyncr.pfsyncr_maxupdates;
@@ -772,10 +780,9 @@ pfsyncioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
}
break;
}
+
if ((sifp = ifunit(pfsyncr.pfsyncr_syncif)) == NULL)
return (EINVAL);
- else if (sifp == sc->sc_sync_ifp)
- break;
s = splnet();
if (sifp->if_mtu < sc->sc_if.if_mtu ||
@@ -792,10 +799,17 @@ pfsyncioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
imo->imo_multicast_ifp = NULL;
}
- if (sc->sc_sync_ifp) {
+ if (sc->sc_sync_ifp &&
+ sc->sc_sync_peer.s_addr == INADDR_PFSYNC_GROUP) {
struct in_addr addr;
+ if (!(sc->sc_sync_ifp->if_flags & IFF_MULTICAST)) {
+ splx(s);
+ return (EADDRNOTAVAIL);
+ }
+
addr.s_addr = INADDR_PFSYNC_GROUP;
+
if ((imo->imo_membership[0] =
in_addmulti(&addr, sc->sc_sync_ifp)) == NULL) {
splx(s);
@@ -805,7 +819,10 @@ pfsyncioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
imo->imo_multicast_ifp = sc->sc_sync_ifp;
imo->imo_multicast_ttl = PFSYNC_DFLTTL;
imo->imo_multicast_loop = 0;
+ }
+ if (sc->sc_sync_ifp ||
+ sc->sc_sendaddr.s_addr != INADDR_PFSYNC_GROUP) {
/* Request a full state table update. */
sc->sc_ureq_sent = time_uptime;
#if NCARP > 0
@@ -819,7 +836,7 @@ pfsyncioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
error = pfsync_request_update(NULL, NULL);
if (error == ENOMEM) {
splx(s);
- return(ENOMEM);
+ return (ENOMEM);
}
pfsync_sendout(sc);
}
@@ -934,7 +951,8 @@ pfsync_pack_state(u_int8_t action, struct pf_state *st, int compress)
* If a packet falls in the forest and there's nobody around to
* hear, does it make a sound?
*/
- if (ifp->if_bpf == NULL && sc->sc_sync_ifp == NULL) {
+ if (ifp->if_bpf == NULL && sc->sc_sync_ifp == NULL &&
+ sc->sc_sync_peer.s_addr == INADDR_PFSYNC_GROUP) {
/* Don't leave any stale pfsync packets hanging around. */
if (sc->sc_mbuf != NULL) {
m_freem(sc->sc_mbuf);
@@ -1318,9 +1336,8 @@ pfsync_sendout(sc)
sc->sc_statep_net.s = NULL;
}
- if (sc->sc_sync_ifp) {
+ if (sc->sc_sync_ifp || sc->sc_sync_peer.s_addr != INADDR_PFSYNC_GROUP) {
struct ip *ip;
- struct ifaddr *ifa;
struct sockaddr sa;
M_PREPEND(m, sizeof(struct ip), M_DONTWAIT);
@@ -1340,16 +1357,12 @@ pfsync_sendout(sc)
ip->ip_sum = 0;
bzero(&sa, sizeof(sa));
- sa.sa_family = AF_INET;
- ifa = ifaof_ifpforaddr(&sa, sc->sc_sync_ifp);
- if (ifa == NULL)
- return (0);
- ip->ip_src.s_addr = ifatoia(ifa)->ia_addr.sin_addr.s_addr;
+ ip->ip_src.s_addr = INADDR_ANY;
if (sc->sc_sendaddr.s_addr == INADDR_PFSYNC_GROUP)
m->m_flags |= M_MCAST;
ip->ip_dst = sc->sc_sendaddr;
- sc->sc_sendaddr.s_addr = INADDR_PFSYNC_GROUP;
+ sc->sc_sendaddr.s_addr = sc->sc_sync_peer.s_addr;
pfsyncstats.pfsyncs_opackets++;
diff --git a/sys/net/if_pfsync.h b/sys/net/if_pfsync.h
index cab1f69b167..76cebbe7d2b 100644
--- a/sys/net/if_pfsync.h
+++ b/sys/net/if_pfsync.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: if_pfsync.h,v 1.15 2004/07/13 22:51:48 deraadt Exp $ */
+/* $OpenBSD: if_pfsync.h,v 1.16 2004/08/03 05:32:28 mcbride Exp $ */
/*
* Copyright (c) 2001 Michael Shalayeff
@@ -150,6 +150,7 @@ struct pfsync_softc {
struct timeout sc_tmo;
struct timeout sc_bulk_tmo;
struct timeout sc_bulkfail_tmo;
+ struct in_addr sc_sync_peer;
struct in_addr sc_sendaddr;
struct mbuf *sc_mbuf; /* current cumulative mbuf */
struct mbuf *sc_mbuf_net; /* current cumulative mbuf */
@@ -184,7 +185,7 @@ struct pfsync_header {
} __packed;
#define PFSYNC_BULKPACKETS 1 /* # of packets per timeout */
-#define PFSYNC_MAX_BULKTRIES 12
+#define PFSYNC_MAX_BULKTRIES 12
#define PFSYNC_HDRLEN sizeof(struct pfsync_header)
#define PFSYNC_ACTIONS \
"CLR ST", "INS ST", "UPD ST", "DEL ST", \
@@ -217,9 +218,10 @@ struct pfsyncstats {
* Configuration structure for SIOCSETPFSYNC SIOCGETPFSYNC
*/
struct pfsyncreq {
- char pfsyncr_syncif[IFNAMSIZ];
- int pfsyncr_maxupdates;
- int pfsyncr_authlevel;
+ char pfsyncr_syncif[IFNAMSIZ];
+ struct in_addr pfsyncr_syncpeer;
+ int pfsyncr_maxupdates;
+ int pfsyncr_authlevel;
};
#define SIOCSETPFSYNC _IOW('i', 247, struct ifreq)
#define SIOCGETPFSYNC _IOWR('i', 248, struct ifreq)