-# $OpenBSD: files,v 1.656 2017/11/16 18:12:27 jcs Exp $
+# $OpenBSD: files,v 1.657 2018/02/06 23:44:48 henning Exp $
# $NetBSD: files,v 1.87 1996/05/19 17:17:50 jonathan Exp $
# @(#)files.newconf 7.5 (Berkeley) 5/10/93
file net/pf_osfp.c pf
file net/pf_if.c pf
file net/pf_lb.c pf
+file net/pf_syncookies.c pf
file net/hfsc.c pf
file net/fq_codel.c pf
-/* $OpenBSD: pf.c,v 1.1059 2018/02/06 09:16:11 henning Exp $ */
+/* $OpenBSD: pf.c,v 1.1060 2018/02/06 23:44:48 henning Exp $ */
/*
* Copyright (c) 2001 Daniel Hartmeier
static __inline int pf_synproxy(struct pf_pdesc *, struct pf_state **,
u_short *);
int pf_test_state(struct pf_pdesc *, struct pf_state **,
- u_short *);
+ u_short *, int);
int pf_icmp_state_lookup(struct pf_pdesc *,
struct pf_state_key_cmp *, struct pf_state **,
u_int16_t, u_int16_t, int, int *, int, int);
}
int
-pf_test_state(struct pf_pdesc *pd, struct pf_state **state, u_short *reason)
+pf_test_state(struct pf_pdesc *pd, struct pf_state **state, u_short *reason,
+ int syncookie)
{
struct pf_state_key_cmp key;
int copyback = 0;
switch (pd->virtual_proto) {
case IPPROTO_TCP:
+ if (syncookie) {
+ pf_set_protostate(*state, PF_PEER_SRC,
+ PF_TCPS_PROXY_DST);
+ (*state)->dst.seqhi = ntohl(pd->hdr.tcp.th_ack) - 1;
+ }
if ((action = pf_synproxy(pd, state, reason)) != PF_PASS)
return (action);
if ((pd->hdr.tcp.th_flags & (TH_SYN|TH_ACK)) == TH_SYN) {
default:
if (pd.virtual_proto == IPPROTO_TCP) {
+ if (pd.dir == PF_IN && (pd.hdr.tcp.th_flags &
+ (TH_SYN|TH_ACK)) == TH_SYN &&
+ pf_synflood_check(&pd)) {
+ pf_syncookie_send(&pd);
+ action = PF_DROP;
+ goto done;
+ }
if ((pd.hdr.tcp.th_flags & TH_ACK) && pd.p_len == 0)
pqid = 1;
action = pf_normalize_tcp(&pd);
if (action == PF_DROP)
goto unlock;
}
- action = pf_test_state(&pd, &s, &reason);
+ action = pf_test_state(&pd, &s, &reason, 0);
+ if (s == NULL && action != PF_PASS && action != PF_AFRT &&
+ pd.dir == PF_IN && pd.virtual_proto == IPPROTO_TCP &&
+ (pd.hdr.tcp.th_flags & (TH_SYN|TH_ACK|TH_RST)) == TH_ACK &&
+ pf_syncookie_validate(&pd)) {
+ struct mbuf *msyn;
+ msyn = pf_syncookie_recreate_syn(&pd);
+ if (msyn) {
+ PF_UNLOCK();
+ action = pf_test(af, fwdir, ifp, &msyn);
+ PF_LOCK();
+ m_freem(msyn);
+ if (action == PF_PASS || action == PF_AFRT) {
+ pf_test_state(&pd, &s, &reason, 1);
+ if (s == NULL) {
+ PF_UNLOCK();
+ return (PF_DROP);
+ }
+ s->src.seqhi =
+ ntohl(pd.hdr.tcp.th_ack) - 1;
+ s->src.seqlo =
+ ntohl(pd.hdr.tcp.th_seq) - 1;
+ pf_set_protostate(s, PF_PEER_SRC,
+ PF_TCPS_PROXY_DST);
+ action = pf_synproxy(&pd, &s, &reason);
+ if (action != PF_PASS) {
+ PF_UNLOCK();
+ return (action);
+ }
+ }
+ } else
+ action = PF_DROP;
+ }
+
+
if (action == PF_PASS || action == PF_AFRT) {
#if NPFSYNC > 0
pfsync_update_state(s);
-/* $OpenBSD: pf_ioctl.c,v 1.328 2018/02/06 09:16:11 henning Exp $ */
+/* $OpenBSD: pf_ioctl.c,v 1.329 2018/02/06 23:44:48 henning Exp $ */
/*
* Copyright (c) 2001 Daniel Hartmeier
pfr_initialize();
pfi_initialize();
pf_osfp_initialize();
+ pf_syncookies_init();
pool_sethardlimit(pf_pool_limits[PF_LIMIT_STATES].pp,
pf_pool_limits[PF_LIMIT_STATES].limit, NULL, 0);
break;
}
+ case DIOCSETSYNFLWATS: {
+ struct pfioc_synflwats *io = (struct pfioc_synflwats *)addr;
+
+ error = pf_syncookies_setwats(io->hiwat, io->lowat);
+ break;
+ }
+
+ case DIOCSETSYNCOOKIES: {
+ u_int8_t *mode = (u_int8_t *)addr;
+
+ error = pf_syncookies_setmode(*mode);
+ break;
+ }
+
default:
error = ENODEV;
break;
-/* $OpenBSD: pfvar.h,v 1.470 2017/12/29 17:05:25 bluhm Exp $ */
+/* $OpenBSD: pfvar.h,v 1.471 2018/02/06 23:44:48 henning Exp $ */
/*
* Copyright (c) 2001 Daniel Hartmeier
u_int64_t pcounters[2][2][3];
u_int64_t bcounters[2][2];
u_int64_t stateid;
+ u_int64_t syncookies_inflight[2]; /* unACKed SYNcookies */
time_t since;
u_int32_t running;
u_int32_t states;
u_int32_t debug;
u_int32_t hostid;
u_int32_t reass; /* reassembly */
+ u_int8_t syncookies_active;
+ u_int8_t syncookies_mode; /* never/always/adaptive */
+ u_int8_t pad[2];
char ifname[IFNAMSIZ];
u_int8_t pf_chksum[PF_MD5_DIGEST_LENGTH];
};
#define PF_REASS_ENABLED 0x01
#define PF_REASS_NODF 0x02
+#define PF_SYNCOOKIES_NEVER 0
+#define PF_SYNCOOKIES_ALWAYS 1
+#define PF_SYNCOOKIES_ADAPTIVE 2
+#define PF_SYNCOOKIES_MODE_MAX PF_SYNCOOKIES_ADAPTIVE
+
#define PF_PRIO_ZERO 0xff /* match "prio 0" packets */
struct pf_queue_bwspec {
int pfiio_flags;
};
+struct pfioc_synflwats {
+ u_int32_t hiwat;
+ u_int32_t lowat;
+};
/*
* ioctl operations
#define DIOCGETQUEUES _IOWR('D', 94, struct pfioc_queue)
#define DIOCGETQUEUE _IOWR('D', 95, struct pfioc_queue)
#define DIOCGETQSTATS _IOWR('D', 96, struct pfioc_qstats)
+#define DIOCSETSYNFLWATS _IOWR('D', 97, struct pfioc_synflwats)
+#define DIOCSETSYNCOOKIES _IOWR('D', 98, u_int8_t)
#ifdef _KERNEL
u_int16_t, u_int16_t, u_int32_t, u_int32_t,
u_int8_t, u_int16_t, u_int16_t, u_int8_t, int,
u_int16_t, u_int);
+void pf_syncookies_init(void);
+int pf_syncookies_setmode(u_int8_t);
+int pf_syncookies_setwats(u_int32_t, u_int32_t);
+int pf_synflood_check(struct pf_pdesc *);
+void pf_syncookie_send(struct pf_pdesc *);
+u_int8_t pf_syncookie_validate(struct pf_pdesc *);
+struct mbuf * pf_syncookie_recreate_syn(struct pf_pdesc *);
#endif /* _KERNEL */
#endif /* _NET_PFVAR_H_ */
-/* $OpenBSD: mbuf.h,v 1.232 2017/10/19 11:02:42 bluhm Exp $ */
+/* $OpenBSD: mbuf.h,v 1.233 2018/02/06 23:44:48 henning Exp $ */
/* $NetBSD: mbuf.h,v 1.19 1996/02/09 18:25:14 christos Exp $ */
/*
/* pkthdr_pf.flags */
#define PF_TAG_GENERATED 0x01
+#define PF_TAG_SYNCOOKIE_RECREATED 0x02
#define PF_TAG_TRANSLATE_LOCALHOST 0x04
#define PF_TAG_DIVERTED 0x08
#define PF_TAG_DIVERTED_PACKET 0x10