svn commit: r232386 - projects/pf/head/sys/contrib/pf/net
Gleb Smirnoff
glebius at FreeBSD.org
Fri Mar 2 11:27:08 UTC 2012
Author: glebius
Date: Fri Mar 2 11:27:07 2012
New Revision: 232386
URL: http://svn.freebsd.org/changeset/base/232386
Log:
- Add separate mutex to lock state keys rbtree.
- Add separate mutex to lock state IDs rbtree.
- Add separate rwlock to lock the global states list.
Modified:
projects/pf/head/sys/contrib/pf/net/if_pfsync.c
projects/pf/head/sys/contrib/pf/net/pf.c
projects/pf/head/sys/contrib/pf/net/pf_ioctl.c
projects/pf/head/sys/contrib/pf/net/pfvar.h
Modified: projects/pf/head/sys/contrib/pf/net/if_pfsync.c
==============================================================================
--- projects/pf/head/sys/contrib/pf/net/if_pfsync.c Fri Mar 2 10:03:38 2012 (r232385)
+++ projects/pf/head/sys/contrib/pf/net/if_pfsync.c Fri Mar 2 11:27:07 2012 (r232386)
@@ -698,18 +698,23 @@ pfsync_in_clr(struct pfsync_pkt *pkt, st
creatorid = clr[i].creatorid;
if (clr[i].ifname[0] == '\0') {
+ PF_KEYS_LOCK();
+ PF_IDS_LOCK();
for (st = RB_MIN(pf_state_tree_id, &V_tree_id);
st; st = nexts) {
nexts = RB_NEXT(pf_state_tree_id, &V_tree_id, st);
if (st->creatorid == creatorid) {
SET(st->state_flags, PFSTATE_NOSYNC);
- pf_unlink_state(st);
+ pf_unlink_state(st, 1);
}
}
+ PF_IDS_UNLOCK();
+ PF_KEYS_UNLOCK();
} else {
if (pfi_kif_get(clr[i].ifname) == NULL)
continue;
+ PF_KEYS_LOCK();
/* XXX correct? */
for (sk = RB_MIN(pf_state_tree, &V_pf_statetbl);
sk; sk = nextsk) {
@@ -719,10 +724,11 @@ pfsync_in_clr(struct pfsync_pkt *pkt, st
if (si->creatorid == creatorid) {
SET(si->state_flags,
PFSTATE_NOSYNC);
- pf_unlink_state(si);
+ pf_unlink_state(si, 0);
}
}
}
+ PF_KEYS_UNLOCK();
}
}
PF_UNLOCK();
@@ -1104,7 +1110,7 @@ pfsync_in_del(struct pfsync_pkt *pkt, st
continue;
}
SET(st->state_flags, PFSTATE_NOSYNC);
- pf_unlink_state(st);
+ pf_unlink_state(st, 0);
}
PF_UNLOCK();
@@ -1142,7 +1148,7 @@ pfsync_in_del_c(struct pfsync_pkt *pkt,
}
SET(st->state_flags, PFSTATE_NOSYNC);
- pf_unlink_state(st);
+ pf_unlink_state(st, 0);
}
PF_UNLOCK();
@@ -2212,9 +2218,11 @@ pfsync_bulk_update(void *arg)
i++;
}
+ PF_LIST_RLOCK();
st = TAILQ_NEXT(st, entry_list);
if (st == NULL)
st = TAILQ_FIRST(&V_state_list);
+ PF_LIST_RUNLOCK();
if (st == sc->sc_bulk_last) {
/* we're done */
Modified: projects/pf/head/sys/contrib/pf/net/pf.c
==============================================================================
--- projects/pf/head/sys/contrib/pf/net/pf.c Fri Mar 2 10:03:38 2012 (r232385)
+++ projects/pf/head/sys/contrib/pf/net/pf.c Fri Mar 2 11:27:07 2012 (r232386)
@@ -489,6 +489,8 @@ pf_src_connlimit(struct pf_state **state
struct pf_state *st;
V_pf_status.lcounters[LCNT_OVERLOAD_FLUSH]++;
+ PF_IDS_LOCK();
+ /* XXXGL: this cycle should go into a separate taskq */
RB_FOREACH(st, pf_state_tree_id, &V_tree_id) {
sk = st->key[PF_SK_WIRE];
/*
@@ -513,6 +515,7 @@ pf_src_connlimit(struct pf_state **state
killed++;
}
}
+ PF_IDS_UNLOCK();
if (V_pf_status.debug >= PF_DEBUG_MISC)
printf(", %u states killed", killed);
}
@@ -680,7 +683,8 @@ pf_state_key_attach(struct pf_state_key
struct pf_state_key *cur;
struct pf_state *si, *olds = NULL;
- KASSERT(s->key[idx] == NULL, ("%s: key is null!", __func__));
+ PF_KEYS_ASSERT();
+ KASSERT(s->key[idx] == NULL, ("%s: a key already attached", __func__));
if ((cur = RB_INSERT(pf_state_tree, &V_pf_statetbl, sk)) != NULL) {
/* key exists. check for same kif, if none, add to key */
@@ -730,7 +734,7 @@ pf_state_key_attach(struct pf_state_key
TAILQ_INSERT_HEAD(&s->key[idx]->states, s, key_list);
if (olds)
- pf_unlink_state(olds);
+ pf_unlink_state(olds, 0);
return (0);
}
@@ -738,6 +742,9 @@ pf_state_key_attach(struct pf_state_key
static void
pf_detach_state(struct pf_state *s)
{
+
+ PF_KEYS_ASSERT();
+
if (s->key[PF_SK_WIRE] == s->key[PF_SK_STACK])
s->key[PF_SK_WIRE] = NULL;
@@ -753,6 +760,8 @@ pf_state_key_detach(struct pf_state *s,
{
struct pf_state *si;
+ PF_KEYS_ASSERT();
+
si = TAILQ_FIRST(&s->key[idx]->states);
while (si && si != s)
si = TAILQ_NEXT(si, key_list);
@@ -833,17 +842,22 @@ pf_state_insert(struct pfi_kif *kif, str
s->kif = kif;
+ PF_KEYS_LOCK();
if (skw == sks) {
- if (pf_state_key_attach(skw, s, PF_SK_WIRE))
+ if (pf_state_key_attach(skw, s, PF_SK_WIRE)) {
+ PF_KEYS_UNLOCK();
return (-1);
+ }
s->key[PF_SK_STACK] = s->key[PF_SK_WIRE];
} else {
if (pf_state_key_attach(skw, s, PF_SK_WIRE)) {
+ PF_KEYS_UNLOCK();
uma_zfree(V_pf_state_key_pl, sks);
return (-1);
}
if (pf_state_key_attach(sks, s, PF_SK_STACK)) {
pf_state_key_detach(s, PF_SK_WIRE);
+ PF_KEYS_UNLOCK();
return (-1);
}
}
@@ -852,7 +866,9 @@ pf_state_insert(struct pfi_kif *kif, str
s->id = htobe64(V_pf_status.stateid++);
s->creatorid = V_pf_status.hostid;
}
+ PF_IDS_LOCK();
if (RB_INSERT(pf_state_tree_id, &V_tree_id, s) != NULL) {
+ PF_IDS_UNLOCK();
if (V_pf_status.debug >= PF_DEBUG_MISC) {
printf("pf: state insert failed: "
"id: %016llx creatorid: %08x",
@@ -862,7 +878,11 @@ pf_state_insert(struct pfi_kif *kif, str
pf_detach_state(s);
return (-1);
}
+ PF_IDS_UNLOCK();
+ PF_KEYS_UNLOCK();
+ PF_LIST_WLOCK();
TAILQ_INSERT_TAIL(&V_state_list, s, entry_list);
+ PF_LIST_WUNLOCK();
V_pf_status.fcounters[FCNT_STATE_INSERT]++;
V_pf_status.states++;
pfi_kif_ref(kif, PFI_KIF_REF_STATE);
@@ -875,9 +895,14 @@ pf_state_insert(struct pfi_kif *kif, str
struct pf_state *
pf_find_state_byid(struct pf_state_cmp *key)
{
+ struct pf_state *s;
+
V_pf_status.fcounters[FCNT_STATE_SEARCH]++;
+ PF_IDS_LOCK();
+ s = RB_FIND(pf_state_tree_id, &V_tree_id, (struct pf_state *)key);
+ PF_IDS_UNLOCK();
- return (RB_FIND(pf_state_tree_id, &V_tree_id, (struct pf_state *)key));
+ return (s);
}
/* XXX debug function, intended to be removed one day */
@@ -920,13 +945,16 @@ pf_find_state(struct pfi_kif *kif, struc
V_pf_status.fcounters[FCNT_STATE_SEARCH]++;
+ PF_KEYS_LOCK();
if (dir == PF_OUT && pftag->statekey &&
((struct pf_state_key *)pftag->statekey)->reverse)
sk = ((struct pf_state_key *)pftag->statekey)->reverse;
else {
if ((sk = RB_FIND(pf_state_tree, &V_pf_statetbl,
- (struct pf_state_key *)key)) == NULL)
+ (struct pf_state_key *)key)) == NULL) {
+ PF_KEYS_UNLOCK();
return (NULL);
+ }
if (dir == PF_OUT && pftag->statekey &&
pf_compare_state_keys(pftag->statekey, sk,
kif, dir) == 0) {
@@ -943,8 +971,11 @@ pf_find_state(struct pfi_kif *kif, struc
TAILQ_FOREACH(si, &sk->states, key_list)
if ((si->kif == V_pfi_all || si->kif == kif) &&
sk == (dir == PF_IN ? si->key[PF_SK_WIRE] :
- si->key[PF_SK_STACK]))
+ si->key[PF_SK_STACK])) {
+ PF_KEYS_UNLOCK();
return (si);
+ }
+ PF_KEYS_UNLOCK();
return (NULL);
}
@@ -957,14 +988,17 @@ pf_find_state_all(struct pf_state_key_cm
V_pf_status.fcounters[FCNT_STATE_SEARCH]++;
+ PF_KEYS_LOCK();
sk = RB_FIND(pf_state_tree, &V_pf_statetbl, (struct pf_state_key *)key);
if (sk != NULL) {
TAILQ_FOREACH(s, &sk->states, key_list)
if (dir == PF_INOUT ||
(sk == (dir == PF_IN ? s->key[PF_SK_WIRE] :
s->key[PF_SK_STACK]))) {
- if (more == NULL)
+ if (more == NULL) {
+ PF_KEYS_UNLOCK();
return (s);
+ }
if (ret)
(*more)++;
@@ -972,6 +1006,7 @@ pf_find_state_all(struct pf_state_key_cm
ret = s;
}
}
+ PF_KEYS_UNLOCK();
return (ret);
}
@@ -1145,9 +1180,11 @@ pf_src_tree_remove_state(struct pf_state
}
void
-pf_unlink_state(struct pf_state *cur)
+pf_unlink_state(struct pf_state *cur, int idslocked)
{
+ PF_KEYS_ASSERT();
+
if (cur->src.state == PF_TCPS_PROXY_DST) {
/* XXX wire key the right one? */
pf_send_tcp(NULL, cur->rule.ptr, cur->key[PF_SK_WIRE]->af,
@@ -1158,7 +1195,11 @@ pf_unlink_state(struct pf_state *cur)
cur->src.seqhi, cur->src.seqlo + 1,
TH_RST|TH_ACK, 0, 0, 0, 1, cur->tag, NULL, NULL);
}
+ if (!idslocked)
+ PF_IDS_LOCK();
RB_REMOVE(pf_state_tree_id, &V_tree_id, cur);
+ if (!idslocked)
+ PF_IDS_UNLOCK();
#if NPFLOW > 0
if (cur->state_flags & PFSTATE_PFLOW)
if (export_pflow_ptr != NULL)
@@ -1177,6 +1218,8 @@ static void
pf_free_state(struct pf_state *cur)
{
+ PF_LIST_WASSERT();
+
if (pfsync_state_in_use_ptr != NULL &&
pfsync_state_in_use_ptr(cur))
return;
@@ -1210,6 +1253,7 @@ pf_purge_expired_states(u_int32_t maxche
struct pf_state *next;
int locked = waslocked;
+ PF_LIST_WLOCK();
while (maxcheck--) {
/* wrap to start of list when we hit the end */
if (cur == NULL) {
@@ -1224,23 +1268,30 @@ pf_purge_expired_states(u_int32_t maxche
if (cur->timeout == PFTM_UNLINKED) {
/* free unlinked state */
if (! locked) {
- if (!sx_try_upgrade(&V_pf_consistency_lock))
+ if (!sx_try_upgrade(&V_pf_consistency_lock)) {
+ PF_LIST_WUNLOCK();
return (0); /* XXXGL */
+ }
locked = 1;
}
pf_free_state(cur);
} else if (pf_state_expires(cur) <= time_second) {
+ PF_KEYS_LOCK();
/* unlink and free expired state */
- pf_unlink_state(cur);
+ pf_unlink_state(cur, 0);
+ PF_KEYS_UNLOCK();
if (! locked) {
- if (!sx_try_upgrade(&V_pf_consistency_lock))
+ if (!sx_try_upgrade(&V_pf_consistency_lock)) {
+ PF_LIST_WUNLOCK();
return (0); /* XXXGL */
+ }
locked = 1;
}
pf_free_state(cur);
}
cur = next;
}
+ PF_LIST_WUNLOCK();
if (!waslocked && locked)
sx_downgrade(&V_pf_consistency_lock);
@@ -3877,7 +3928,7 @@ pf_test_state_tcp(struct pf_state **stat
}
/* XXX make sure it's the same direction ?? */
(*state)->src.state = (*state)->dst.state = TCPS_CLOSED;
- pf_unlink_state(*state);
+ pf_unlink_state(*state, 0);
*state = NULL;
return (PF_DROP);
}
Modified: projects/pf/head/sys/contrib/pf/net/pf_ioctl.c
==============================================================================
--- projects/pf/head/sys/contrib/pf/net/pf_ioctl.c Fri Mar 2 10:03:38 2012 (r232385)
+++ projects/pf/head/sys/contrib/pf/net/pf_ioctl.c Fri Mar 2 11:27:07 2012 (r232386)
@@ -172,9 +172,6 @@ struct cdev *pf_dev;
static void pf_clear_states(void);
static int pf_clear_tables(void);
static void pf_clear_srcnodes(void);
-/*
- * XXX - These are new and need to be checked when moveing to a new version
- */
/*
* Wrapper functions for pfil(9) hooks
@@ -209,6 +206,9 @@ static volatile VNET_DEFINE(int, pf_pfil
VNET_DEFINE(int, pf_end_threads);
struct mtx pf_mtx;
+struct mtx pf_state_keys_mtx;
+struct mtx pf_state_ids_mtx;
+struct rwlock pf_state_list_lock;
struct rwlock pf_rules_lock;
/* pfsync */
@@ -235,6 +235,9 @@ init_pf_mutex(void)
{
mtx_init(&pf_mtx, "pf Giant", NULL, MTX_DEF);
+ mtx_init(&pf_state_keys_mtx, "pf state keys", NULL, MTX_DEF);
+ mtx_init(&pf_state_ids_mtx, "pf state ids", NULL, MTX_DEF);
+ rw_init(&pf_state_list_lock, "pf state list");
rw_init(&pf_rules_lock, "pf rulesets");
/* XXXGL: name */
sx_init(&V_pf_consistency_lock, "pf_statetbl_lock");
@@ -245,6 +248,9 @@ destroy_pf_mutex(void)
{
mtx_destroy(&pf_mtx);
+ mtx_destroy(&pf_state_keys_mtx);
+ mtx_destroy(&pf_state_ids_mtx);
+ rw_destroy(&pf_state_list_lock);
rw_destroy(&pf_rules_lock);
sx_destroy(&V_pf_consistency_lock);
}
@@ -1682,6 +1688,8 @@ pfioctl(struct cdev *dev, u_long cmd, ca
struct pfioc_state_kill *psk = (struct pfioc_state_kill *)addr;
u_int killed = 0;
+ PF_KEYS_LOCK();
+ PF_IDS_LOCK();
for (s = RB_MIN(pf_state_tree_id, &V_tree_id); s; s = nexts) {
nexts = RB_NEXT(pf_state_tree_id, &V_tree_id, s);
@@ -1689,10 +1697,12 @@ pfioctl(struct cdev *dev, u_long cmd, ca
s->kif->pfik_name)) {
/* don't send out individual delete messages */
SET(s->state_flags, PFSTATE_NOSYNC);
- pf_unlink_state(s);
+ pf_unlink_state(s, 1);
killed++;
}
}
+ PF_IDS_UNLOCK();
+ PF_KEYS_UNLOCK();
psk->psk_killed = killed;
if (pfsync_clear_states_ptr != NULL)
pfsync_clear_states_ptr(V_pf_status.hostid, psk->psk_ifname);
@@ -1711,12 +1721,14 @@ pfioctl(struct cdev *dev, u_long cmd, ca
if (psk->psk_pfcmp.creatorid == 0)
psk->psk_pfcmp.creatorid = V_pf_status.hostid;
if ((s = pf_find_state_byid(&psk->psk_pfcmp))) {
- pf_unlink_state(s);
+ pf_unlink_state(s, 0);
psk->psk_killed = 1;
}
break;
}
+ PF_KEYS_LOCK();
+ PF_IDS_LOCK();
for (s = RB_MIN(pf_state_tree_id, &V_tree_id); s;
s = nexts) {
nexts = RB_NEXT(pf_state_tree_id, &V_tree_id, s);
@@ -1756,10 +1768,12 @@ pfioctl(struct cdev *dev, u_long cmd, ca
!strcmp(psk->psk_label, s->rule.ptr->label))) &&
(!psk->psk_ifname[0] || !strcmp(psk->psk_ifname,
s->kif->pfik_name))) {
- pf_unlink_state(s);
+ pf_unlink_state(s, 1);
killed++;
}
}
+ PF_IDS_UNLOCK();
+ PF_KEYS_UNLOCK();
psk->psk_killed = killed;
break;
}
@@ -1799,7 +1813,7 @@ pfioctl(struct cdev *dev, u_long cmd, ca
case DIOCGETSTATES: {
struct pfioc_states *ps = (struct pfioc_states *)addr;
struct pf_state *state;
- struct pfsync_state *p, *pstore;
+ struct pfsync_state *p, pstore;
u_int32_t nr = 0;
if (ps->ps_len == 0) {
@@ -1808,32 +1822,31 @@ pfioctl(struct cdev *dev, u_long cmd, ca
break;
}
- PF_UNLOCK();
- pstore = malloc(sizeof(*pstore), M_TEMP, M_WAITOK);
- PF_LOCK();
-
p = ps->ps_states;
+ PF_LIST_RLOCK();
state = TAILQ_FIRST(&V_state_list);
while (state) {
if (state->timeout != PFTM_UNLINKED) {
if ((nr+1) * sizeof(*p) > (unsigned)ps->ps_len)
break;
- pfsync_state_export(pstore, state);
- PF_COPYOUT(pstore, p, sizeof(*p), error);
- if (error) {
- free(pstore, M_TEMP);
+ pfsync_state_export(&pstore, state);
+ PF_LIST_RUNLOCK(); /* XXXGL: ref state? */
+ PF_UNLOCK();
+ error = copyout(&pstore, p, sizeof(*p));
+ PF_LOCK();
+ if (error)
goto fail;
- }
+ PF_LIST_RLOCK();
p++;
nr++;
}
state = TAILQ_NEXT(state, entry_list);
}
+ PF_LIST_RUNLOCK();
ps->ps_len = sizeof(struct pfsync_state) * nr;
- free(pstore, M_TEMP);
break;
}
@@ -2964,14 +2977,18 @@ pfioctl(struct cdev *dev, u_long cmd, ca
struct pf_src_node *n;
struct pf_state *state;
+ PF_IDS_LOCK();
RB_FOREACH(state, pf_state_tree_id, &V_tree_id) {
state->src_node = NULL;
state->nat_src_node = NULL;
}
+ PF_IDS_UNLOCK();
+ PF_KEYS_LOCK();
RB_FOREACH(n, pf_src_tree, &V_tree_src_tracking) {
n->expire = 1;
n->states = 0;
}
+ PF_KEYS_UNLOCK();
pf_purge_expired_src_nodes(1);
V_pf_status.src_nodes = 0;
break;
@@ -2984,6 +3001,7 @@ pfioctl(struct cdev *dev, u_long cmd, ca
(struct pfioc_src_node_kill *)addr;
u_int killed = 0;
+ PF_KEYS_LOCK();
RB_FOREACH(sn, pf_src_tree, &V_tree_src_tracking) {
if (PF_MATCHA(psnk->psnk_src.neg,
&psnk->psnk_src.addr.v.a.addr,
@@ -2995,6 +3013,7 @@ pfioctl(struct cdev *dev, u_long cmd, ca
&sn->raddr, sn->af)) {
/* Handle state to src_node linkage */
if (sn->states != 0) {
+ PF_IDS_LOCK();
RB_FOREACH(s, pf_state_tree_id,
&V_tree_id) {
if (s->src_node == sn)
@@ -3002,12 +3021,14 @@ pfioctl(struct cdev *dev, u_long cmd, ca
if (s->nat_src_node == sn)
s->nat_src_node = NULL;
}
+ PF_IDS_UNLOCK();
sn->states = 0;
}
sn->expire = 1;
killed++;
}
}
+ PF_KEYS_UNLOCK();
if (killed > 0)
pf_purge_expired_src_nodes(1);
@@ -3141,13 +3162,17 @@ static void
pf_clear_states(void)
{
struct pf_state *state;
-
+
+ PF_KEYS_LOCK();
+ PF_IDS_LOCK();
RB_FOREACH(state, pf_state_tree_id, &V_tree_id) {
state->timeout = PFTM_PURGE;
/* don't send out individual delete messages */
state->sync_state = PFSTATE_NOSYNC;
- pf_unlink_state(state);
+ pf_unlink_state(state, 1);
}
+ PF_IDS_UNLOCK();
+ PF_KEYS_UNLOCK();
#if 0 /* NPFSYNC */
/*
@@ -3177,14 +3202,18 @@ pf_clear_srcnodes(void)
struct pf_src_node *n;
struct pf_state *state;
+ PF_IDS_LOCK();
RB_FOREACH(state, pf_state_tree_id, &V_tree_id) {
state->src_node = NULL;
state->nat_src_node = NULL;
}
+ PF_IDS_UNLOCK();
+ PF_KEYS_LOCK();
RB_FOREACH(n, pf_src_tree, &V_tree_src_tracking) {
n->expire = 1;
n->states = 0;
}
+ PF_KEYS_UNLOCK();
}
/*
* XXX - Check for version missmatch!!!
Modified: projects/pf/head/sys/contrib/pf/net/pfvar.h
==============================================================================
--- projects/pf/head/sys/contrib/pf/net/pfvar.h Fri Mar 2 10:03:38 2012 (r232385)
+++ projects/pf/head/sys/contrib/pf/net/pfvar.h Fri Mar 2 11:27:07 2012 (r232386)
@@ -208,6 +208,24 @@ extern struct mtx pf_mtx;
#define PF_LOCK() mtx_lock(&pf_mtx)
#define PF_UNLOCK() mtx_unlock(&pf_mtx)
+extern struct mtx pf_state_keys_mtx;
+#define PF_KEYS_ASSERT() mtx_assert(&pf_state_keys_mtx, MA_OWNED)
+#define PF_KEYS_LOCK() mtx_lock(&pf_state_keys_mtx)
+#define PF_KEYS_UNLOCK() mtx_unlock(&pf_state_keys_mtx)
+
+extern struct mtx pf_state_ids_mtx;
+#define PF_IDS_ASSERT() mtx_assert(&pf_state_ids_mtx, MA_OWNED)
+#define PF_IDS_LOCK() mtx_lock(&pf_state_ids_mtx)
+#define PF_IDS_UNLOCK() mtx_unlock(&pf_state_ids_mtx)
+
+extern struct rwlock pf_state_list_lock;
+#define PF_LIST_RASSERT() rw_assert(&pf_state_list_lock, RA_RLOCKED)
+#define PF_LIST_RLOCK() rw_rlock(&pf_state_list_lock)
+#define PF_LIST_RUNLOCK() rw_runlock(&pf_state_list_lock)
+#define PF_LIST_WASSERT() rw_assert(&pf_state_list_lock, RA_WLOCKED)
+#define PF_LIST_WLOCK() rw_wlock(&pf_state_list_lock)
+#define PF_LIST_WUNLOCK() rw_wunlock(&pf_state_list_lock)
+
extern struct rwlock pf_rules_lock;
#define PF_RULES_RLOCK() rw_rlock(&pf_rules_lock)
#define PF_RULES_RUNLOCK() rw_runlock(&pf_rules_lock)
@@ -1770,7 +1788,7 @@ VNET_DECLARE(uma_zone_t, pfi_addr_pl);
extern void pf_purge_thread(void *);
extern int pf_purge_expired_src_nodes(int);
-extern void pf_unlink_state(struct pf_state *);
+extern void pf_unlink_state(struct pf_state *, int);
extern int pf_state_insert(struct pfi_kif *,
struct pf_state_key *,
struct pf_state_key *,
More information about the svn-src-projects
mailing list