-/* $OpenBSD: pf.c,v 1.1188 2023/10/10 16:26:06 bluhm Exp $ */
+/* $OpenBSD: pf.c,v 1.1189 2023/12/01 10:28:32 sashan Exp $ */
/*
* Copyright (c) 2001 Daniel Hartmeier
pf_state_unref(st); /* list no longer references the state */
}
+void
+pf_update_state_timeout(struct pf_state *st, int to)
+{
+ mtx_enter(&st->mtx);
+ if (st->timeout != PFTM_UNLINKED)
+ st->timeout = to;
+ mtx_leave(&st->mtx);
+}
+
int
pf_src_connlimit(struct pf_state **stp)
{
((*stp)->rule.ptr->flush &
PF_FLUSH_GLOBAL ||
(*stp)->rule.ptr == st->rule.ptr)) {
- st->timeout = PFTM_PURGE;
+ pf_update_state_timeout(st, PFTM_PURGE);
pf_set_protostate(st, PF_PEER_BOTH,
TCPS_CLOSED);
killed++;
}
/* kill this state */
- (*stp)->timeout = PFTM_PURGE;
+ pf_update_state_timeout(*stp, PFTM_PURGE);
pf_set_protostate(*stp, PF_PEER_BOTH, TCPS_CLOSED);
return (1);
}
{
PF_ASSERT_LOCKED();
- if (st->timeout == PFTM_UNLINKED)
+ mtx_enter(&st->mtx);
+ if (st->timeout == PFTM_UNLINKED) {
+ mtx_leave(&st->mtx);
return;
-
+ }
st->timeout = PFTM_UNLINKED;
+ mtx_leave(&st->mtx);
/* handle load balancing related tasks */
pf_postprocess_addr(st);
sist->dst.state < TCPS_FIN_WAIT_2) {
pf_set_protostate(sist, PF_PEER_BOTH,
TCPS_TIME_WAIT);
- sist->timeout = PFTM_TCP_CLOSED;
+ pf_update_state_timeout(sist,
+ PFTM_TCP_CLOSED);
sist->expire = getuptime();
}
sist->state_flags |= PFSTATE_INP_UNLINKED;
(*stp)->expire = getuptime();
if (src->state >= TCPS_FIN_WAIT_2 &&
dst->state >= TCPS_FIN_WAIT_2)
- (*stp)->timeout = PFTM_TCP_CLOSED;
+ pf_update_state_timeout(*stp, PFTM_TCP_CLOSED);
else if (src->state >= TCPS_CLOSING &&
dst->state >= TCPS_CLOSING)
- (*stp)->timeout = PFTM_TCP_FIN_WAIT;
+ pf_update_state_timeout(*stp, PFTM_TCP_FIN_WAIT);
else if (src->state < TCPS_ESTABLISHED ||
dst->state < TCPS_ESTABLISHED)
- (*stp)->timeout = PFTM_TCP_OPENING;
+ pf_update_state_timeout(*stp, PFTM_TCP_OPENING);
else if (src->state >= TCPS_CLOSING ||
dst->state >= TCPS_CLOSING)
- (*stp)->timeout = PFTM_TCP_CLOSING;
+ pf_update_state_timeout(*stp, PFTM_TCP_CLOSING);
else
- (*stp)->timeout = PFTM_TCP_ESTABLISHED;
+ pf_update_state_timeout(*stp, PFTM_TCP_ESTABLISHED);
/* Fall through to PASS packet */
} else if ((dst->state < TCPS_SYN_SENT ||
(*stp)->expire = getuptime();
if (src->state >= TCPS_FIN_WAIT_2 &&
dst->state >= TCPS_FIN_WAIT_2)
- (*stp)->timeout = PFTM_TCP_CLOSED;
+ pf_update_state_timeout(*stp, PFTM_TCP_CLOSED);
else if (src->state >= TCPS_CLOSING &&
dst->state >= TCPS_CLOSING)
- (*stp)->timeout = PFTM_TCP_FIN_WAIT;
+ pf_update_state_timeout(*stp, PFTM_TCP_FIN_WAIT);
else if (src->state < TCPS_ESTABLISHED ||
dst->state < TCPS_ESTABLISHED)
- (*stp)->timeout = PFTM_TCP_OPENING;
+ pf_update_state_timeout(*stp, PFTM_TCP_OPENING);
else if (src->state >= TCPS_CLOSING ||
dst->state >= TCPS_CLOSING)
- (*stp)->timeout = PFTM_TCP_CLOSING;
+ pf_update_state_timeout(*stp, PFTM_TCP_CLOSING);
else
- (*stp)->timeout = PFTM_TCP_ESTABLISHED;
+ pf_update_state_timeout(*stp, PFTM_TCP_ESTABLISHED);
return (PF_PASS);
}
addlog("\n");
}
/* XXX make sure it's the same direction ?? */
- (*stp)->timeout = PFTM_PURGE;
+ pf_update_state_timeout(*stp, PFTM_PURGE);
pf_state_unref(*stp);
*stp = NULL;
pf_mbuf_link_inpcb(pd->m, inp);
(*stp)->expire = getuptime();
if (src->state == PFUDPS_MULTIPLE &&
dst->state == PFUDPS_MULTIPLE)
- (*stp)->timeout = PFTM_UDP_MULTIPLE;
+ pf_update_state_timeout(*stp, PFTM_UDP_MULTIPLE);
else
- (*stp)->timeout = PFTM_UDP_SINGLE;
+ pf_update_state_timeout(*stp, PFTM_UDP_SINGLE);
break;
default:
/* update states */
(*stp)->expire = getuptime();
if (src->state == PFOTHERS_MULTIPLE &&
dst->state == PFOTHERS_MULTIPLE)
- (*stp)->timeout = PFTM_OTHER_MULTIPLE;
+ pf_update_state_timeout(*stp, PFTM_OTHER_MULTIPLE);
else
- (*stp)->timeout = PFTM_OTHER_SINGLE;
+ pf_update_state_timeout(*stp, PFTM_OTHER_SINGLE);
break;
}
return (ret);
(*stp)->expire = getuptime();
- (*stp)->timeout = PFTM_ICMP_ERROR_REPLY;
+ pf_update_state_timeout(*stp, PFTM_ICMP_ERROR_REPLY);
/* translate source/destination address, if necessary */
if ((*stp)->key[PF_SK_WIRE] != (*stp)->key[PF_SK_STACK]) {