Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F107791169
D31729.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
11 KB
Referenced Files
None
Subscribers
None
D31729.diff
View Options
diff --git a/sys/netpfil/pf/pf.h b/sys/netpfil/pf/pf.h
--- a/sys/netpfil/pf/pf.h
+++ b/sys/netpfil/pf/pf.h
@@ -61,6 +61,7 @@
PF_CHANGE_REMOVE, PF_CHANGE_GET_TICKET };
enum { PF_GET_NONE, PF_GET_CLR_CNTR };
enum { PF_SK_WIRE, PF_SK_STACK, PF_SK_BOTH };
+enum { PF_PEER_SRC, PF_PEER_DST, PF_PEER_BOTH };
/*
* Note about PFTM_*: real indices into pf_rule.timeout[] come before
diff --git a/sys/netpfil/pf/pf.c b/sys/netpfil/pf/pf.c
--- a/sys/netpfil/pf/pf.c
+++ b/sys/netpfil/pf/pf.c
@@ -277,12 +277,10 @@
struct pfi_kkif *, struct mbuf *, void *,
struct pf_pdesc *, struct pf_krule **,
struct pf_kruleset **);
-static int pf_tcp_track_full(struct pf_state_peer *,
- struct pf_state_peer *, struct pf_kstate **,
+static int pf_tcp_track_full(struct pf_kstate **,
struct pfi_kkif *, struct mbuf *, int,
struct pf_pdesc *, u_short *, int *);
-static int pf_tcp_track_sloppy(struct pf_state_peer *,
- struct pf_state_peer *, struct pf_kstate **,
+static int pf_tcp_track_sloppy(struct pf_kstate **,
struct pf_pdesc *, u_short *);
static int pf_test_state_tcp(struct pf_kstate **, int,
struct pfi_kkif *, struct mbuf *, int,
@@ -327,6 +325,7 @@
struct ifnet *, struct pf_kstate *,
struct pf_pdesc *, struct inpcb *);
#endif /* INET6 */
+static __inline void pf_set_protostate(struct pf_kstate *, int, u_int8_t);
int in4_cksum(struct mbuf *m, u_int8_t nxt, int off, int len);
@@ -487,6 +486,17 @@
}
#endif
+static __inline void
+pf_set_protostate(struct pf_kstate *s, int which, u_int8_t newstate)
+{
+ if (which == PF_PEER_DST || which == PF_PEER_BOTH)
+ s->dst.state = newstate;
+ if (which == PF_PEER_DST)
+ return;
+
+ s->src.state = newstate;
+}
+
#ifdef INET6
void
pf_addrcpy(struct pf_addr *dst, struct pf_addr *src, sa_family_t af)
@@ -567,7 +577,7 @@
/* Kill this state. */
(*state)->timeout = PFTM_PURGE;
- (*state)->src.state = (*state)->dst.state = TCPS_CLOSED;
+ pf_set_protostate(*state, PF_PEER_BOTH, TCPS_CLOSED);
if ((*state)->rule.ptr->overload_tbl == NULL)
return (1);
@@ -668,7 +678,7 @@
(pfoe->dir == PF_IN &&
PF_AEQ(&pfoe->addr, &sk->addr[0], sk->af)))) {
s->timeout = PFTM_PURGE;
- s->src.state = s->dst.state = TCPS_CLOSED;
+ pf_set_protostate(s, PF_PEER_BOTH, TCPS_CLOSED);
killed++;
}
}
@@ -1084,8 +1094,8 @@
* of the slot TAILQ, so that it won't
* conflict with our new state.
*/
- si->src.state = si->dst.state =
- TCPS_CLOSED;
+ pf_set_protostate(si, PF_PEER_BOTH,
+ TCPS_CLOSED);
si->timeout = PFTM_PURGE;
olds = si;
} else {
@@ -3945,13 +3955,13 @@
s->src.seqhi++;
s->dst.seqhi = 1;
s->dst.max_win = 1;
- s->src.state = TCPS_SYN_SENT;
- s->dst.state = TCPS_CLOSED;
+ pf_set_protostate(s, PF_PEER_SRC, TCPS_SYN_SENT);
+ pf_set_protostate(s, PF_PEER_DST, TCPS_CLOSED);
s->timeout = PFTM_TCP_FIRST_PACKET;
break;
case IPPROTO_UDP:
- s->src.state = PFUDPS_SINGLE;
- s->dst.state = PFUDPS_NO_TRAFFIC;
+ pf_set_protostate(s, PF_PEER_SRC, PFUDPS_SINGLE);
+ pf_set_protostate(s, PF_PEER_DST, PFUDPS_NO_TRAFFIC);
s->timeout = PFTM_UDP_FIRST_PACKET;
break;
case IPPROTO_ICMP:
@@ -3961,8 +3971,8 @@
s->timeout = PFTM_ICMP_FIRST_PACKET;
break;
default:
- s->src.state = PFOTHERS_SINGLE;
- s->dst.state = PFOTHERS_NO_TRAFFIC;
+ pf_set_protostate(s, PF_PEER_SRC, PFOTHERS_SINGLE);
+ pf_set_protostate(s, PF_PEER_DST, PFOTHERS_NO_TRAFFIC);
s->timeout = PFTM_OTHER_FIRST_PACKET;
}
@@ -4041,7 +4051,7 @@
s->tag = tag;
if (pd->proto == IPPROTO_TCP && (th->th_flags & (TH_SYN|TH_ACK)) ==
TH_SYN && r->keep_state == PF_STATE_SYNPROXY) {
- s->src.state = PF_TCPS_PROXY_SRC;
+ pf_set_protostate(s, PF_PEER_SRC, PF_TCPS_PROXY_SRC);
/* undo NAT changes, if they have taken place */
if (nr != NULL) {
struct pf_state_key *skt = s->key[PF_SK_WIRE];
@@ -4223,16 +4233,29 @@
}
static int
-pf_tcp_track_full(struct pf_state_peer *src, struct pf_state_peer *dst,
- struct pf_kstate **state, struct pfi_kkif *kif, struct mbuf *m, int off,
- struct pf_pdesc *pd, u_short *reason, int *copyback)
+pf_tcp_track_full(struct pf_kstate **state, struct pfi_kkif *kif,
+ struct mbuf *m, int off, struct pf_pdesc *pd, u_short *reason,
+ int *copyback)
{
struct tcphdr *th = &pd->hdr.tcp;
+ struct pf_state_peer *src, *dst;
u_int16_t win = ntohs(th->th_win);
u_int32_t ack, end, seq, orig_seq;
- u_int8_t sws, dws;
+ u_int8_t sws, dws, psrc, pdst;
int ackskew;
+ if (pd->dir == (*state)->direction) {
+ src = &(*state)->src;
+ dst = &(*state)->dst;
+ psrc = PF_PEER_SRC;
+ pdst = PF_PEER_DST;
+ } else {
+ src = &(*state)->dst;
+ dst = &(*state)->src;
+ psrc = PF_PEER_DST;
+ pdst = PF_PEER_SRC;
+ }
+
if (src->wscale && dst->wscale && !(th->th_flags & TH_SYN)) {
sws = src->wscale & PF_WSCALE_MASK;
dws = dst->wscale & PF_WSCALE_MASK;
@@ -4298,7 +4321,7 @@
src->seqlo = seq;
if (src->state < TCPS_SYN_SENT)
- src->state = TCPS_SYN_SENT;
+ pf_set_protostate(*state, psrc, TCPS_SYN_SENT);
/*
* May need to slide the window (seqhi may have been set by
@@ -4399,13 +4422,14 @@
/* update states */
if (th->th_flags & TH_SYN)
if (src->state < TCPS_SYN_SENT)
- src->state = TCPS_SYN_SENT;
+ pf_set_protostate(*state, psrc, TCPS_SYN_SENT);
if (th->th_flags & TH_FIN)
if (src->state < TCPS_CLOSING)
- src->state = TCPS_CLOSING;
+ pf_set_protostate(*state, psrc, TCPS_CLOSING);
if (th->th_flags & TH_ACK) {
if (dst->state == TCPS_SYN_SENT) {
- dst->state = TCPS_ESTABLISHED;
+ pf_set_protostate(*state, pdst,
+ TCPS_ESTABLISHED);
if (src->state == TCPS_ESTABLISHED &&
(*state)->src_node != NULL &&
pf_src_connlimit(state)) {
@@ -4413,10 +4437,11 @@
return (PF_DROP);
}
} else if (dst->state == TCPS_CLOSING)
- dst->state = TCPS_FIN_WAIT_2;
+ pf_set_protostate(*state, pdst,
+ TCPS_FIN_WAIT_2);
}
if (th->th_flags & TH_RST)
- src->state = dst->state = TCPS_TIME_WAIT;
+ pf_set_protostate(*state, PF_PEER_BOTH, TCPS_TIME_WAIT);
/* update expire time */
(*state)->expire = time_uptime;
@@ -4501,9 +4526,9 @@
if (th->th_flags & TH_FIN)
if (src->state < TCPS_CLOSING)
- src->state = TCPS_CLOSING;
+ pf_set_protostate(*state, psrc, TCPS_CLOSING);
if (th->th_flags & TH_RST)
- src->state = dst->state = TCPS_TIME_WAIT;
+ pf_set_protostate(*state, PF_PEER_BOTH, TCPS_TIME_WAIT);
/* Fall through to PASS packet */
@@ -4548,20 +4573,33 @@
}
static int
-pf_tcp_track_sloppy(struct pf_state_peer *src, struct pf_state_peer *dst,
- struct pf_kstate **state, struct pf_pdesc *pd, u_short *reason)
+pf_tcp_track_sloppy(struct pf_kstate **state, struct pf_pdesc *pd, u_short *reason)
{
struct tcphdr *th = &pd->hdr.tcp;
+ struct pf_state_peer *src, *dst;
+ u_int8_t psrc, pdst;
+
+ if (pd->dir == (*state)->direction) {
+ src = &(*state)->src;
+ dst = &(*state)->dst;
+ psrc = PF_PEER_SRC;
+ pdst = PF_PEER_DST;
+ } else {
+ src = &(*state)->dst;
+ dst = &(*state)->src;
+ psrc = PF_PEER_DST;
+ pdst = PF_PEER_SRC;
+ }
if (th->th_flags & TH_SYN)
if (src->state < TCPS_SYN_SENT)
- src->state = TCPS_SYN_SENT;
+ pf_set_protostate(*state, psrc, TCPS_SYN_SENT);
if (th->th_flags & TH_FIN)
if (src->state < TCPS_CLOSING)
- src->state = TCPS_CLOSING;
+ pf_set_protostate(*state, psrc, TCPS_CLOSING);
if (th->th_flags & TH_ACK) {
if (dst->state == TCPS_SYN_SENT) {
- dst->state = TCPS_ESTABLISHED;
+ pf_set_protostate(*state, pdst, TCPS_ESTABLISHED);
if (src->state == TCPS_ESTABLISHED &&
(*state)->src_node != NULL &&
pf_src_connlimit(state)) {
@@ -4569,7 +4607,7 @@
return (PF_DROP);
}
} else if (dst->state == TCPS_CLOSING) {
- dst->state = TCPS_FIN_WAIT_2;
+ pf_set_protostate(*state, pdst, TCPS_FIN_WAIT_2);
} else if (src->state == TCPS_SYN_SENT &&
dst->state < TCPS_SYN_SENT) {
/*
@@ -4578,6 +4616,8 @@
* the initial SYN without ever seeing a packet from
* the destination, set the connection to established.
*/
+ pf_set_protostate(*state, PF_PEER_BOTH,
+ TCPS_ESTABLISHED);
dst->state = src->state = TCPS_ESTABLISHED;
if ((*state)->src_node != NULL &&
pf_src_connlimit(state)) {
@@ -4592,11 +4632,11 @@
* don't see the full bidirectional FIN/ACK+ACK
* handshake.
*/
- dst->state = TCPS_CLOSING;
+ pf_set_protostate(*state, pdst, TCPS_CLOSING);
}
}
if (th->th_flags & TH_RST)
- src->state = dst->state = TCPS_TIME_WAIT;
+ pf_set_protostate(*state, PF_PEER_BOTH, TCPS_TIME_WAIT);
/* update expire time */
(*state)->expire = time_uptime;
@@ -4650,7 +4690,8 @@
REASON_SET(reason, PFRES_SRCLIMIT);
return (PF_DROP);
} else
- (*state)->src.state = PF_TCPS_PROXY_DST;
+ pf_set_protostate(*state, PF_PEER_SRC,
+ PF_TCPS_PROXY_DST);
}
if ((*state)->src.state == PF_TCPS_PROXY_DST) {
if (pd->dir == (*state)->direction) {
@@ -4697,8 +4738,8 @@
(*state)->dst.seqhi = (*state)->dst.seqlo +
(*state)->src.max_win;
(*state)->src.wscale = (*state)->dst.wscale = 0;
- (*state)->src.state = (*state)->dst.state =
- TCPS_ESTABLISHED;
+ pf_set_protostate(*state, PF_PEER_BOTH,
+ TCPS_ESTABLISHED);
REASON_SET(reason, PFRES_SYNPROXY);
return (PF_SYNPROXY_DROP);
}
@@ -4759,17 +4800,17 @@
printf("\n");
}
/* XXX make sure it's the same direction ?? */
- (*state)->src.state = (*state)->dst.state = TCPS_CLOSED;
+ pf_set_protostate(*state, PF_PEER_BOTH, TCPS_CLOSED);
pf_unlink_state(*state, PF_ENTER_LOCKED);
*state = NULL;
return (PF_DROP);
}
if ((*state)->state_flags & PFSTATE_SLOPPY) {
- if (pf_tcp_track_sloppy(src, dst, state, pd, reason) == PF_DROP)
+ if (pf_tcp_track_sloppy(state, pd, reason) == PF_DROP)
return (PF_DROP);
} else {
- if (pf_tcp_track_full(src, dst, state, kif, m, off, pd, reason,
+ if (pf_tcp_track_full(state, kif, m, off, pd, reason,
©back) == PF_DROP)
return (PF_DROP);
}
@@ -4806,6 +4847,7 @@
struct pf_state_peer *src, *dst;
struct pf_state_key_cmp key;
struct udphdr *uh = &pd->hdr.udp;
+ uint8_t psrc, pdst;
bzero(&key, sizeof(key));
key.af = pd->af;
@@ -4827,16 +4869,20 @@
if (direction == (*state)->direction) {
src = &(*state)->src;
dst = &(*state)->dst;
+ psrc = PF_PEER_SRC;
+ pdst = PF_PEER_DST;
} else {
src = &(*state)->dst;
dst = &(*state)->src;
+ psrc = PF_PEER_DST;
+ pdst = PF_PEER_SRC;
}
/* update states */
if (src->state < PFUDPS_SINGLE)
- src->state = PFUDPS_SINGLE;
+ pf_set_protostate(*state, psrc, PFUDPS_SINGLE);
if (dst->state == PFUDPS_SINGLE)
- dst->state = PFUDPS_MULTIPLE;
+ pf_set_protostate(*state, pdst, PFUDPS_MULTIPLE);
/* update expire time */
(*state)->expire = time_uptime;
@@ -5476,6 +5522,7 @@
{
struct pf_state_peer *src, *dst;
struct pf_state_key_cmp key;
+ uint8_t psrc, pdst;
bzero(&key, sizeof(key));
key.af = pd->af;
@@ -5495,16 +5542,20 @@
if (direction == (*state)->direction) {
src = &(*state)->src;
dst = &(*state)->dst;
+ psrc = PF_PEER_SRC;
+ pdst = PF_PEER_DST;
} else {
src = &(*state)->dst;
dst = &(*state)->src;
+ psrc = PF_PEER_DST;
+ pdst = PF_PEER_SRC;
}
/* update states */
if (src->state < PFOTHERS_SINGLE)
- src->state = PFOTHERS_SINGLE;
+ pf_set_protostate(*state, psrc, PFOTHERS_SINGLE);
if (dst->state == PFOTHERS_SINGLE)
- dst->state = PFOTHERS_MULTIPLE;
+ pf_set_protostate(*state, pdst, PFOTHERS_MULTIPLE);
/* update expire time */
(*state)->expire = time_uptime;
@@ -6266,7 +6317,8 @@
- 1;
s->src.seqlo = ntohl(pd.hdr.tcp.th_seq)
- 1;
- s->src.state = PF_TCPS_PROXY_DST;
+ pf_set_protostate(s, PF_PEER_SRC,
+ PF_TCPS_PROXY_DST);
action = pf_synproxy(&pd, &s, &reason);
if (action != PF_PASS)
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Sun, Jan 19, 5:39 AM (20 h, 22 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
15927258
Default Alt Text
D31729.diff (11 KB)
Attached To
Mode
D31729: pf: import pf_set_protostate() from OpenBSD
Attached
Detach File
Event Timeline
Log In to Comment