summaryrefslogtreecommitdiff
path: root/sys/net/if_pfsync.c
diff options
context:
space:
mode:
Diffstat (limited to 'sys/net/if_pfsync.c')
-rw-r--r--sys/net/if_pfsync.c38
1 files changed, 25 insertions, 13 deletions
diff --git a/sys/net/if_pfsync.c b/sys/net/if_pfsync.c
index 9b6bebae796..28720ef3ab7 100644
--- a/sys/net/if_pfsync.c
+++ b/sys/net/if_pfsync.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: if_pfsync.c,v 1.55 2005/09/28 01:46:32 pascoe Exp $ */
+/* $OpenBSD: if_pfsync.c,v 1.56 2005/10/27 12:34:40 mcbride Exp $ */
/*
* Copyright (c) 2002 Michael Shalayeff
@@ -26,8 +26,6 @@
* THE POSSIBILITY OF SUCH DAMAGE.
*/
-#include "bpfilter.h"
-#include "pfsync.h"
#include <sys/param.h>
#include <sys/proc.h>
@@ -67,6 +65,9 @@ extern int carp_suppress_preempt;
#include <net/pfvar.h>
#include <net/if_pfsync.h>
+#include "bpfilter.h"
+#include "pfsync.h"
+
#define PFSYNC_MINMTU \
(sizeof(struct pfsync_header) + sizeof(struct pf_state))
@@ -84,7 +85,7 @@ void pfsyncattach(int);
void pfsync_setmtu(struct pfsync_softc *, int);
int pfsync_alloc_scrub_memory(struct pfsync_state_peer *,
struct pf_state_peer *);
-int pfsync_insert_net_state(struct pfsync_state *);
+int pfsync_insert_net_state(struct pfsync_state *, u_int8_t);
void pfsync_update_net_tdb(struct pfsync_tdb *);
int pfsyncoutput(struct ifnet *, struct mbuf *, struct sockaddr *,
struct rtentry *);
@@ -184,7 +185,7 @@ pfsync_alloc_scrub_memory(struct pfsync_state_peer *s,
}
int
-pfsync_insert_net_state(struct pfsync_state *sp)
+pfsync_insert_net_state(struct pfsync_state *sp, u_int8_t rmatch)
{
struct pf_state *st = NULL;
struct pf_rule *r = NULL;
@@ -206,10 +207,14 @@ pfsync_insert_net_state(struct pfsync_state *sp)
}
/*
- * Just use the default rule until we have infrastructure to find the
- * best matching rule.
+ * If the ruleset checksums match, it's safe to associate the state
+ * with the rule of that number.
*/
- r = &pf_default_rule;
+ if (sp->rule != htonl(-1) && sp->anchor == htonl(-1) && rmatch)
+ r = pf_main_ruleset.rules[
+ PF_RULESET_FILTER].active.ptr_array[ntohl(sp->rule)];
+ else
+ r = &pf_default_rule;
if (!r->max_states || r->states < r->max_states)
st = pool_get(&pf_state_pl, PR_NOWAIT);
@@ -291,6 +296,7 @@ pfsync_input(struct mbuf *m, ...)
struct in_addr src;
struct mbuf *mp;
int iplen, action, error, i, s, count, offp, sfail, stale = 0;
+ u_int8_t rmatch = 0;
pfsyncstats.pfsyncs_ipackets++;
@@ -344,6 +350,9 @@ pfsync_input(struct mbuf *m, ...)
/* Cheaper to grab this now than having to mess with mbufs later */
src = ip->ip_src;
+ if (!bcmp(&ph->pf_chksum, &pf_status.pf_chksum, PF_MD5_DIGEST_LENGTH))
+ rmatch++;
+
switch (action) {
case PFSYNC_ACT_CLR: {
struct pf_state *nexts;
@@ -409,7 +418,7 @@ pfsync_input(struct mbuf *m, ...)
continue;
}
- if ((error = pfsync_insert_net_state(sp))) {
+ if ((error = pfsync_insert_net_state(sp, rmatch))) {
if (error == ENOMEM) {
splx(s);
goto done;
@@ -448,7 +457,7 @@ pfsync_input(struct mbuf *m, ...)
st = pf_find_state_byid(&key);
if (st == NULL) {
/* insert the update */
- if (pfsync_insert_net_state(sp))
+ if (pfsync_insert_net_state(sp, rmatch))
pfsyncstats.pfsyncs_badstate++;
continue;
}
@@ -1014,6 +1023,9 @@ pfsync_get_mbuf(struct pfsync_softc *sc, u_int8_t action, void **sp)
h->af = 0;
h->count = 0;
h->action = action;
+ if (action != PFSYNC_ACT_TDB_UPD)
+ bcopy(&pf_status.pf_chksum, &h->pf_chksum,
+ PF_MD5_DIGEST_LENGTH);
*sp = (void *)((char *)h + PFSYNC_HDRLEN);
if (action == PFSYNC_ACT_TDB_UPD)
@@ -1476,7 +1488,7 @@ pfsync_sendout_mbuf(struct pfsync_softc *sc, struct mbuf *m)
{
struct sockaddr sa;
struct ip *ip;
-
+
if (sc->sc_sync_ifp ||
sc->sc_sync_peer.s_addr != INADDR_PFSYNC_GROUP) {
M_PREPEND(m, sizeof(struct ip), M_DONTWAIT);
@@ -1567,12 +1579,12 @@ pfsync_update_net_tdb(struct pfsync_tdb *pt)
splx(s);
return;
- bad:
+ bad:
if (pf_status.debug >= PF_DEBUG_MISC)
printf("pfsync_insert: PFSYNC_ACT_TDB_UPD: "
"invalid value\n");
pfsyncstats.pfsyncs_badstate++;
- return;
+ return;
}
/* One of our local tdbs have been updated, need to sync rpl with others */