diff options
| author | Max Laier <mlaier@FreeBSD.org> | 2008-12-10 21:21:09 +0000 |
|---|---|---|
| committer | Max Laier <mlaier@FreeBSD.org> | 2008-12-10 21:21:09 +0000 |
| commit | c6c4fc3df17fc4a3e8022fd276c04e834febe004 (patch) | |
| tree | 1234a402203555380207dd549c340886206eaa57 /net/if_pfsync.c | |
| parent | c48a03d37af67495ce1d7b9904ea01fb524ced57 (diff) | |
Diffstat (limited to 'net/if_pfsync.c')
| -rw-r--r-- | net/if_pfsync.c | 111 |
1 files changed, 67 insertions, 44 deletions
diff --git a/net/if_pfsync.c b/net/if_pfsync.c index 11063397e3e4..da42c20a689a 100644 --- a/net/if_pfsync.c +++ b/net/if_pfsync.c @@ -1,4 +1,4 @@ -/* $OpenBSD: if_pfsync.c,v 1.73 2006/11/16 13:13:38 henning Exp $ */ +/* $OpenBSD: if_pfsync.c,v 1.83 2007/06/26 14:44:12 mcbride Exp $ */ /* * Copyright (c) 2002 Michael Shalayeff @@ -106,7 +106,6 @@ void pfsync_bulk_update(void *); void pfsync_bulkfail(void *); int pfsync_sync_ok; -extern int ifqmaxlen; struct if_clone pfsync_cloner = IF_CLONE_INITIALIZER("pfsync", pfsync_clone_create, pfsync_clone_destroy); @@ -221,6 +220,7 @@ int pfsync_insert_net_state(struct pfsync_state *sp, u_int8_t chksum_flag) { struct pf_state *st = NULL; + struct pf_state_key *sk = NULL; struct pf_rule *r = NULL; struct pfi_kif *kif; @@ -243,7 +243,9 @@ pfsync_insert_net_state(struct pfsync_state *sp, u_int8_t chksum_flag) * If the ruleset checksums match, it's safe to associate the state * with the rule of that number. */ - if (sp->rule != htonl(-1) && sp->anchor == htonl(-1) && chksum_flag) + if (sp->rule != htonl(-1) && sp->anchor == htonl(-1) && chksum_flag && + ntohl(sp->rule) < + pf_main_ruleset.rules[PF_RULESET_FILTER].active.rcount) r = pf_main_ruleset.rules[ PF_RULESET_FILTER].active.ptr_array[ntohl(sp->rule)]; else @@ -257,6 +259,12 @@ pfsync_insert_net_state(struct pfsync_state *sp, u_int8_t chksum_flag) } bzero(st, sizeof(*st)); + if ((sk = pf_alloc_state_key(st)) == NULL) { + pool_put(&pf_state_pl, st); + pfi_kif_unref(kif, PFI_KIF_REF_NONE); + return (ENOMEM); + } + /* allocate memory for scrub info */ if (pfsync_alloc_scrub_memory(&sp->src, &st->src) || pfsync_alloc_scrub_memory(&sp->dst, &st->dst)) { @@ -264,6 +272,7 @@ pfsync_insert_net_state(struct pfsync_state *sp, u_int8_t chksum_flag) if (st->src.scrub) pool_put(&pf_state_scrub_pl, st->src.scrub); pool_put(&pf_state_pl, st); + pool_put(&pf_state_key_pl, sk); return (ENOMEM); } @@ -274,9 +283,9 @@ pfsync_insert_net_state(struct pfsync_state *sp, u_int8_t chksum_flag) r->states++; /* fill in the rest of the state entry */ - pf_state_host_ntoh(&sp->lan, &st->lan); - pf_state_host_ntoh(&sp->gwy, &st->gwy); - pf_state_host_ntoh(&sp->ext, &st->ext); + pf_state_host_ntoh(&sp->lan, &sk->lan); + pf_state_host_ntoh(&sp->gwy, &sk->gwy); + pf_state_host_ntoh(&sp->ext, &sk->ext); pf_state_peer_ntoh(&sp->src, &st->src); pf_state_peer_ntoh(&sp->dst, &st->dst); @@ -285,9 +294,9 @@ pfsync_insert_net_state(struct pfsync_state *sp, u_int8_t chksum_flag) st->creation = time_second - ntohl(sp->creation); st->expire = ntohl(sp->expire) + time_second; - st->af = sp->af; - st->proto = sp->proto; - st->direction = sp->direction; + sk->af = sp->af; + sk->proto = sp->proto; + sk->direction = sp->direction; st->log = sp->log; st->timeout = sp->timeout; st->allow_opts = sp->allow_opts; @@ -318,14 +327,17 @@ pfsync_input(struct mbuf *m, ...) struct pfsync_header *ph; struct pfsync_softc *sc = pfsyncif; struct pf_state *st; - struct pf_state_cmp key; + struct pf_state_key *sk; + struct pf_state_cmp id_key; struct pfsync_state *sp; struct pfsync_state_upd *up; struct pfsync_state_del *dp; struct pfsync_state_clr *cp; struct pfsync_state_upd_req *rup; struct pfsync_state_bus *bus; +#ifdef IPSEC struct pfsync_tdb *pt; +#endif struct in_addr src; struct mbuf *mp; int iplen, action, error, i, s, count, offp, sfail, stale = 0; @@ -389,7 +401,8 @@ pfsync_input(struct mbuf *m, ...) switch (action) { case PFSYNC_ACT_CLR: { struct pf_state *nexts; - struct pfi_kif *kif; + struct pf_state_key *nextsk; + struct pfi_kif *kif; u_int32_t creatorid; if ((mp = m_pulldown(m, iplen + sizeof(*ph), sizeof(*cp), &offp)) == NULL) { @@ -414,13 +427,16 @@ pfsync_input(struct mbuf *m, ...) splx(s); return; } - for (st = RB_MIN(pf_state_tree_lan_ext, - &kif->pfik_lan_ext); st; st = nexts) { - nexts = RB_NEXT(pf_state_tree_lan_ext, - &kif->pfik_lan_ext, st); - if (st->creatorid == creatorid) { - st->sync_flags |= PFSTATE_FROMSYNC; - pf_unlink_state(st); + for (sk = RB_MIN(pf_state_tree_lan_ext, + &pf_statetbl_lan_ext); sk; sk = nextsk) { + nextsk = RB_NEXT(pf_state_tree_lan_ext, + &pf_statetbl_lan_ext, sk); + TAILQ_FOREACH(st, &sk->states, next) { + if (st->creatorid == creatorid) { + st->sync_flags |= + PFSTATE_FROMSYNC; + pf_unlink_state(st); + } } } } @@ -485,18 +501,19 @@ pfsync_input(struct mbuf *m, ...) continue; } - bcopy(sp->id, &key.id, sizeof(key.id)); - key.creatorid = sp->creatorid; + bcopy(sp->id, &id_key.id, sizeof(id_key.id)); + id_key.creatorid = sp->creatorid; - st = pf_find_state_byid(&key); + st = pf_find_state_byid(&id_key); if (st == NULL) { /* insert the update */ if (pfsync_insert_net_state(sp, chksum_flag)) pfsyncstats.pfsyncs_badstate++; continue; } + sk = st->state_key; sfail = 0; - if (st->proto == IPPROTO_TCP) { + if (sk->proto == IPPROTO_TCP) { /* * The state should never go backwards except * for syn-proxy states. Neither should the @@ -579,10 +596,10 @@ pfsync_input(struct mbuf *m, ...) s = splsoftnet(); for (i = 0, sp = (struct pfsync_state *)(mp->m_data + offp); i < count; i++, sp++) { - bcopy(sp->id, &key.id, sizeof(key.id)); - key.creatorid = sp->creatorid; + bcopy(sp->id, &id_key.id, sizeof(id_key.id)); + id_key.creatorid = sp->creatorid; - st = pf_find_state_byid(&key); + st = pf_find_state_byid(&id_key); if (st == NULL) { pfsyncstats.pfsyncs_badstate++; continue; @@ -616,10 +633,10 @@ pfsync_input(struct mbuf *m, ...) continue; } - bcopy(up->id, &key.id, sizeof(key.id)); - key.creatorid = up->creatorid; + bcopy(up->id, &id_key.id, sizeof(id_key.id)); + id_key.creatorid = up->creatorid; - st = pf_find_state_byid(&key); + st = pf_find_state_byid(&id_key); if (st == NULL) { /* We don't have this state. Ask for it. */ error = pfsync_request_update(up, &src); @@ -631,8 +648,9 @@ pfsync_input(struct mbuf *m, ...) pfsyncstats.pfsyncs_badstate++; continue; } + sk = st->state_key; sfail = 0; - if (st->proto == IPPROTO_TCP) { + if (sk->proto == IPPROTO_TCP) { /* * The state should never go backwards except * for syn-proxy states. Neither should the @@ -702,10 +720,10 @@ pfsync_input(struct mbuf *m, ...) s = splsoftnet(); for (i = 0, dp = (struct pfsync_state_del *)(mp->m_data + offp); i < count; i++, dp++) { - bcopy(dp->id, &key.id, sizeof(key.id)); - key.creatorid = dp->creatorid; + bcopy(dp->id, &id_key.id, sizeof(id_key.id)); + id_key.creatorid = dp->creatorid; - st = pf_find_state_byid(&key); + st = pf_find_state_byid(&id_key); if (st == NULL) { pfsyncstats.pfsyncs_badstate++; continue; @@ -732,10 +750,10 @@ pfsync_input(struct mbuf *m, ...) for (i = 0, rup = (struct pfsync_state_upd_req *)(mp->m_data + offp); i < count; i++, rup++) { - bcopy(rup->id, &key.id, sizeof(key.id)); - key.creatorid = rup->creatorid; + bcopy(rup->id, &id_key.id, sizeof(id_key.id)); + id_key.creatorid = rup->creatorid; - if (key.id == 0 && key.creatorid == 0) { + if (id_key.id == 0 && id_key.creatorid == 0) { sc->sc_ureq_received = time_uptime; if (sc->sc_bulk_send_next == NULL) sc->sc_bulk_send_next = @@ -747,7 +765,7 @@ pfsync_input(struct mbuf *m, ...) pfsync_send_bus(sc, PFSYNC_BUS_START); timeout_add(&sc->sc_bulk_tmo, 1 * hz); } else { - st = pf_find_state_byid(&key); + st = pf_find_state_byid(&id_key); if (st == NULL) { pfsyncstats.pfsyncs_badstate++; continue; @@ -804,6 +822,7 @@ pfsync_input(struct mbuf *m, ...) break; } break; +#ifdef IPSEC case PFSYNC_ACT_TDB_UPD: if ((mp = m_pulldown(m, iplen + sizeof(*ph), count * sizeof(*pt), &offp)) == NULL) { @@ -816,6 +835,7 @@ pfsync_input(struct mbuf *m, ...) pfsync_update_net_tdb(pt); splx(s); break; +#endif } done: @@ -1080,6 +1100,7 @@ pfsync_pack_state(u_int8_t action, struct pf_state *st, int flags) struct pfsync_state *sp = NULL; struct pfsync_state_upd *up = NULL; struct pfsync_state_del *dp = NULL; + struct pf_state_key *sk = st->state_key; struct pf_rule *r; u_long secs; int s, ret = 0; @@ -1164,10 +1185,10 @@ pfsync_pack_state(u_int8_t action, struct pf_state *st, int flags) bcopy(&st->id, sp->id, sizeof(sp->id)); sp->creatorid = st->creatorid; - strlcpy(sp->ifname, st->u.s.kif->pfik_name, sizeof(sp->ifname)); - pf_state_host_hton(&st->lan, &sp->lan); - pf_state_host_hton(&st->gwy, &sp->gwy); - pf_state_host_hton(&st->ext, &sp->ext); + strlcpy(sp->ifname, st->kif->pfik_name, sizeof(sp->ifname)); + pf_state_host_hton(&sk->lan, &sp->lan); + pf_state_host_hton(&sk->gwy, &sp->gwy); + pf_state_host_hton(&sk->ext, &sp->ext); bcopy(&st->rt_addr, &sp->rt_addr, sizeof(sp->rt_addr)); @@ -1184,9 +1205,9 @@ pfsync_pack_state(u_int8_t action, struct pf_state *st, int flags) sp->anchor = htonl(-1); else sp->anchor = htonl(r->nr); - sp->af = st->af; - sp->proto = st->proto; - sp->direction = st->direction; + sp->af = sk->af; + sp->proto = sk->proto; + sp->direction = sk->direction; sp->log = st->log; sp->allow_opts = st->allow_opts; sp->timeout = st->timeout; @@ -1418,7 +1439,7 @@ pfsync_bulk_update(void *v) } /* figure next state to send */ - state = TAILQ_NEXT(state, u.s.entry_list); + state = TAILQ_NEXT(state, entry_list); /* wrap to start of list if we hit the end */ if (!state) @@ -1577,6 +1598,7 @@ pfsync_sendout_mbuf(struct pfsync_softc *sc, struct mbuf *m) return (0); } +#ifdef IPSEC /* Update an in-kernel tdb. Silently fail if no tdb is found. */ void pfsync_update_net_tdb(struct pfsync_tdb *pt) @@ -1727,3 +1749,4 @@ pfsync_update_tdb(struct tdb *tdb, int output) splx(s); return (ret); } +#endif |
