if_pfsync.h revision 145836
1126261Smlaier/*	$FreeBSD: head/sys/contrib/pf/net/if_pfsync.h 145836 2005-05-03 16:43:32Z mlaier $	*/
2145836Smlaier/*	$OpenBSD: if_pfsync.h,v 1.19 2005/01/20 17:47:38 mcbride Exp $	*/
3126258Smlaier
4126258Smlaier/*
5126258Smlaier * Copyright (c) 2001 Michael Shalayeff
6126258Smlaier * All rights reserved.
7126258Smlaier *
8126258Smlaier * Redistribution and use in source and binary forms, with or without
9126258Smlaier * modification, are permitted provided that the following conditions
10126258Smlaier * are met:
11126258Smlaier * 1. Redistributions of source code must retain the above copyright
12126258Smlaier *    notice, this list of conditions and the following disclaimer.
13126258Smlaier * 2. Redistributions in binary form must reproduce the above copyright
14126258Smlaier *    notice, this list of conditions and the following disclaimer in the
15126258Smlaier *    documentation and/or other materials provided with the distribution.
16126258Smlaier *
17126258Smlaier * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18126258Smlaier * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19126258Smlaier * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20126258Smlaier * IN NO EVENT SHALL THE AUTHOR OR HIS RELATIVES BE LIABLE FOR ANY DIRECT,
21126258Smlaier * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
22126258Smlaier * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
23126258Smlaier * SERVICES; LOSS OF MIND, USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24126258Smlaier * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
25126258Smlaier * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
26126258Smlaier * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
27126258Smlaier * THE POSSIBILITY OF SUCH DAMAGE.
28126258Smlaier */
29126258Smlaier
30126258Smlaier#ifndef _NET_IF_PFSYNC_H_
31126258Smlaier#define _NET_IF_PFSYNC_H_
32126258Smlaier
33130613Smlaier
34130613Smlaier#define PFSYNC_ID_LEN	sizeof(u_int64_t)
35130613Smlaier
36130613Smlaierstruct pfsync_state_scrub {
37130613Smlaier	u_int16_t	pfss_flags;
38130613Smlaier	u_int8_t	pfss_ttl;	/* stashed TTL		*/
39130613Smlaier	u_int8_t	scrub_flag;
40130613Smlaier	u_int32_t	pfss_ts_mod;	/* timestamp modulation	*/
41130613Smlaier} __packed;
42130613Smlaier
43130613Smlaierstruct pfsync_state_host {
44130613Smlaier	struct pf_addr	addr;
45130613Smlaier	u_int16_t	port;
46130613Smlaier	u_int16_t	pad[3];
47130613Smlaier} __packed;
48130613Smlaier
49130613Smlaierstruct pfsync_state_peer {
50130613Smlaier	struct pfsync_state_scrub scrub;	/* state is scrubbed	*/
51130613Smlaier	u_int32_t	seqlo;		/* Max sequence number sent	*/
52130613Smlaier	u_int32_t	seqhi;		/* Max the other end ACKd + win	*/
53130613Smlaier	u_int32_t	seqdiff;	/* Sequence number modulator	*/
54130613Smlaier	u_int16_t	max_win;	/* largest window (pre scaling)	*/
55130613Smlaier	u_int16_t	mss;		/* Maximum segment size option	*/
56130613Smlaier	u_int8_t	state;		/* active state level		*/
57130613Smlaier	u_int8_t	wscale;		/* window scaling factor	*/
58130613Smlaier	u_int8_t	scrub_flag;
59130613Smlaier	u_int8_t	pad[5];
60130613Smlaier} __packed;
61130613Smlaier
62130613Smlaierstruct pfsync_state {
63130613Smlaier	u_int32_t	 id[2];
64130613Smlaier	char		 ifname[IFNAMSIZ];
65130613Smlaier	struct pfsync_state_host lan;
66130613Smlaier	struct pfsync_state_host gwy;
67130613Smlaier	struct pfsync_state_host ext;
68130613Smlaier	struct pfsync_state_peer src;
69130613Smlaier	struct pfsync_state_peer dst;
70130613Smlaier	struct pf_addr	 rt_addr;
71130613Smlaier	u_int32_t	 rule;
72130613Smlaier	u_int32_t	 anchor;
73130613Smlaier	u_int32_t	 nat_rule;
74130613Smlaier	u_int32_t	 creation;
75130613Smlaier	u_int32_t	 expire;
76130613Smlaier	u_int32_t	 packets[2];
77130613Smlaier	u_int32_t	 bytes[2];
78130613Smlaier	u_int32_t	 creatorid;
79130613Smlaier	sa_family_t	 af;
80130613Smlaier	u_int8_t	 proto;
81130613Smlaier	u_int8_t	 direction;
82130613Smlaier	u_int8_t	 log;
83130613Smlaier	u_int8_t	 allow_opts;
84130613Smlaier	u_int8_t	 timeout;
85130613Smlaier	u_int8_t	 sync_flags;
86130613Smlaier	u_int8_t	 updates;
87130613Smlaier} __packed;
88130613Smlaier
89145836Smlaier#define PFSYNC_FLAG_COMPRESS 	0x01
90145836Smlaier#define PFSYNC_FLAG_STALE	0x02
91145836Smlaier
92130613Smlaierstruct pfsync_state_upd {
93130613Smlaier	u_int32_t		id[2];
94130613Smlaier	struct pfsync_state_peer	src;
95130613Smlaier	struct pfsync_state_peer	dst;
96130613Smlaier	u_int32_t		creatorid;
97130613Smlaier	u_int32_t		expire;
98130613Smlaier	u_int8_t		timeout;
99130613Smlaier	u_int8_t		updates;
100130613Smlaier	u_int8_t		pad[6];
101130613Smlaier} __packed;
102130613Smlaier
103130613Smlaierstruct pfsync_state_del {
104130613Smlaier	u_int32_t		id[2];
105130613Smlaier	u_int32_t		creatorid;
106130613Smlaier	struct {
107130613Smlaier		u_int8_t	state;
108130613Smlaier	} src;
109130613Smlaier	struct {
110130613Smlaier		u_int8_t	state;
111130613Smlaier	} dst;
112130613Smlaier	u_int8_t		pad[2];
113130613Smlaier} __packed;
114130613Smlaier
115130613Smlaierstruct pfsync_state_upd_req {
116130613Smlaier	u_int32_t		id[2];
117130613Smlaier	u_int32_t		creatorid;
118130613Smlaier	u_int32_t		pad;
119130613Smlaier} __packed;
120130613Smlaier
121130613Smlaierstruct pfsync_state_clr {
122130613Smlaier	char			ifname[IFNAMSIZ];
123130613Smlaier	u_int32_t		creatorid;
124130613Smlaier	u_int32_t		pad;
125130613Smlaier} __packed;
126130613Smlaier
127130613Smlaierstruct pfsync_state_bus {
128130613Smlaier	u_int32_t		creatorid;
129130613Smlaier	u_int32_t		endtime;
130130613Smlaier	u_int8_t		status;
131130613Smlaier#define PFSYNC_BUS_START	1
132130613Smlaier#define PFSYNC_BUS_END		2
133130613Smlaier	u_int8_t		pad[7];
134130613Smlaier} __packed;
135130613Smlaier
136126258Smlaier#ifdef _KERNEL
137130613Smlaier
138130613Smlaierunion sc_statep {
139130613Smlaier	struct pfsync_state	*s;
140130613Smlaier	struct pfsync_state_upd	*u;
141130613Smlaier	struct pfsync_state_del	*d;
142130613Smlaier	struct pfsync_state_clr	*c;
143130613Smlaier	struct pfsync_state_bus	*b;
144130613Smlaier	struct pfsync_state_upd_req	*r;
145130613Smlaier};
146130613Smlaier
147130613Smlaierextern int	pfsync_sync_ok;
148130613Smlaier
149126258Smlaierstruct pfsync_softc {
150130613Smlaier	struct ifnet		 sc_if;
151130613Smlaier	struct ifnet		*sc_sync_ifp;
152126258Smlaier
153130613Smlaier	struct ip_moptions	 sc_imo;
154127145Smlaier#ifdef __FreeBSD__
155130613Smlaier	struct callout		 sc_tmo;
156130613Smlaier	struct callout		 sc_bulk_tmo;
157130613Smlaier	struct callout		 sc_bulkfail_tmo;
158126261Smlaier#else
159130613Smlaier	struct timeout		 sc_tmo;
160130613Smlaier	struct timeout		 sc_bulk_tmo;
161130613Smlaier	struct timeout		 sc_bulkfail_tmo;
162126261Smlaier#endif
163145836Smlaier	struct in_addr		 sc_sync_peer;
164130613Smlaier	struct in_addr		 sc_sendaddr;
165145836Smlaier	struct mbuf		*sc_mbuf;	/* current cumulative mbuf */
166145836Smlaier	struct mbuf		*sc_mbuf_net;	/* current cumulative mbuf */
167130613Smlaier	union sc_statep		 sc_statep;
168130613Smlaier	union sc_statep		 sc_statep_net;
169130613Smlaier	u_int32_t		 sc_ureq_received;
170130613Smlaier	u_int32_t		 sc_ureq_sent;
171130613Smlaier	int			 sc_bulk_tries;
172130613Smlaier	int			 sc_maxcount;	/* number of states in mtu */
173130613Smlaier	int			 sc_maxupdates;	/* number of updates/state */
174127145Smlaier#ifdef __FreeBSD__
175126261Smlaier	LIST_ENTRY(pfsync_softc) sc_next;
176126261Smlaier#endif
177126258Smlaier};
178126258Smlaier#endif
179126258Smlaier
180130613Smlaier
181126258Smlaierstruct pfsync_header {
182126258Smlaier	u_int8_t version;
183130613Smlaier#define	PFSYNC_VERSION	2
184126258Smlaier	u_int8_t af;
185126258Smlaier	u_int8_t action;
186130613Smlaier#define	PFSYNC_ACT_CLR		0	/* clear all states */
187130613Smlaier#define	PFSYNC_ACT_INS		1	/* insert state */
188130613Smlaier#define	PFSYNC_ACT_UPD		2	/* update state */
189130613Smlaier#define	PFSYNC_ACT_DEL		3	/* delete state */
190130613Smlaier#define	PFSYNC_ACT_UPD_C	4	/* "compressed" state update */
191130613Smlaier#define	PFSYNC_ACT_DEL_C	5	/* "compressed" state delete */
192130613Smlaier#define	PFSYNC_ACT_INS_F	6	/* insert fragment */
193130613Smlaier#define	PFSYNC_ACT_DEL_F	7	/* delete fragments */
194130613Smlaier#define	PFSYNC_ACT_UREQ		8	/* request "uncompressed" state */
195130613Smlaier#define PFSYNC_ACT_BUS		9	/* Bulk Update Status */
196130613Smlaier#define	PFSYNC_ACT_MAX		10
197126258Smlaier	u_int8_t count;
198130613Smlaier} __packed;
199126258Smlaier
200130613Smlaier#define PFSYNC_BULKPACKETS	1	/* # of packets per timeout */
201145836Smlaier#define PFSYNC_MAX_BULKTRIES	12
202126258Smlaier#define PFSYNC_HDRLEN	sizeof(struct pfsync_header)
203126258Smlaier#define	PFSYNC_ACTIONS \
204130613Smlaier	"CLR ST", "INS ST", "UPD ST", "DEL ST", \
205130613Smlaier	"UPD ST COMP", "DEL ST COMP", "INS FR", "DEL FR", \
206130613Smlaier	"UPD REQ", "BLK UPD STAT"
207126258Smlaier
208130613Smlaier#define PFSYNC_DFLTTL		255
209130613Smlaier
210130613Smlaierstruct pfsyncstats {
211145836Smlaier	u_int64_t	pfsyncs_ipackets;	/* total input packets, IPv4 */
212145836Smlaier	u_int64_t	pfsyncs_ipackets6;	/* total input packets, IPv6 */
213145836Smlaier	u_int64_t	pfsyncs_badif;		/* not the right interface */
214145836Smlaier	u_int64_t	pfsyncs_badttl;		/* TTL is not PFSYNC_DFLTTL */
215145836Smlaier	u_int64_t	pfsyncs_hdrops;		/* packets shorter than hdr */
216145836Smlaier	u_int64_t	pfsyncs_badver;		/* bad (incl unsupp) version */
217145836Smlaier	u_int64_t	pfsyncs_badact;		/* bad action */
218145836Smlaier	u_int64_t	pfsyncs_badlen;		/* data length does not match */
219145836Smlaier	u_int64_t	pfsyncs_badauth;	/* bad authentication */
220145836Smlaier	u_int64_t	pfsyncs_stale;		/* stale state */
221145836Smlaier	u_int64_t	pfsyncs_badval;		/* bad values */
222145836Smlaier	u_int64_t	pfsyncs_badstate;	/* insert/lookup failed */
223130613Smlaier
224145836Smlaier	u_int64_t	pfsyncs_opackets;	/* total output packets, IPv4 */
225145836Smlaier	u_int64_t	pfsyncs_opackets6;	/* total output packets, IPv6 */
226145836Smlaier	u_int64_t	pfsyncs_onomem;		/* no memory for an mbuf */
227145836Smlaier	u_int64_t	pfsyncs_oerrors;	/* ip output error */
228130613Smlaier};
229130613Smlaier
230130613Smlaier/*
231130613Smlaier * Configuration structure for SIOCSETPFSYNC SIOCGETPFSYNC
232130613Smlaier */
233130613Smlaierstruct pfsyncreq {
234145836Smlaier	char		 pfsyncr_syncdev[IFNAMSIZ];
235145836Smlaier	struct in_addr	 pfsyncr_syncpeer;
236145836Smlaier	int		 pfsyncr_maxupdates;
237145836Smlaier	int		 pfsyncr_authlevel;
238130613Smlaier};
239130613Smlaier
240145836Smlaier#ifdef __FreeBSD__
241145836Smlaier#define	SIOCSETPFSYNC	_IOW('i', 247, struct ifreq)
242145836Smlaier#define	SIOCGETPFSYNC	_IOWR('i', 248, struct ifreq)
243145836Smlaier#endif
244130613Smlaier
245126258Smlaier#define pf_state_peer_hton(s,d) do {		\
246126258Smlaier	(d)->seqlo = htonl((s)->seqlo);		\
247126258Smlaier	(d)->seqhi = htonl((s)->seqhi);		\
248126258Smlaier	(d)->seqdiff = htonl((s)->seqdiff);	\
249126258Smlaier	(d)->max_win = htons((s)->max_win);	\
250130613Smlaier	(d)->mss = htons((s)->mss);		\
251126258Smlaier	(d)->state = (s)->state;		\
252130613Smlaier	(d)->wscale = (s)->wscale;		\
253126258Smlaier} while (0)
254126258Smlaier
255126258Smlaier#define pf_state_peer_ntoh(s,d) do {		\
256126258Smlaier	(d)->seqlo = ntohl((s)->seqlo);		\
257126258Smlaier	(d)->seqhi = ntohl((s)->seqhi);		\
258126258Smlaier	(d)->seqdiff = ntohl((s)->seqdiff);	\
259126258Smlaier	(d)->max_win = ntohs((s)->max_win);	\
260130613Smlaier	(d)->mss = ntohs((s)->mss);		\
261126258Smlaier	(d)->state = (s)->state;		\
262130613Smlaier	(d)->wscale = (s)->wscale;		\
263126258Smlaier} while (0)
264126258Smlaier
265130613Smlaier#define pf_state_host_hton(s,d) do {				\
266130613Smlaier	bcopy(&(s)->addr, &(d)->addr, sizeof((d)->addr));	\
267130613Smlaier	(d)->port = (s)->port;					\
268130613Smlaier} while (0)
269130613Smlaier
270130613Smlaier#define pf_state_host_ntoh(s,d) do {				\
271130613Smlaier	bcopy(&(s)->addr, &(d)->addr, sizeof((d)->addr));	\
272130613Smlaier	(d)->port = (s)->port;					\
273130613Smlaier} while (0)
274130613Smlaier
275126258Smlaier#ifdef _KERNEL
276130613Smlaier#ifdef __FreeBSD__
277130613Smlaiervoid pfsync_input(struct mbuf *, __unused int);
278130613Smlaier#else
279130613Smlaiervoid pfsync_input(struct mbuf *, ...);
280126258Smlaier#endif
281130613Smlaierint pfsync_clear_states(u_int32_t, char *);
282130613Smlaierint pfsync_pack_state(u_int8_t, struct pf_state *, int);
283130613Smlaier#define pfsync_insert_state(st)	do {				\
284130613Smlaier	if ((st->rule.ptr->rule_flag & PFRULE_NOSYNC) ||	\
285130613Smlaier	    (st->proto == IPPROTO_PFSYNC))			\
286130613Smlaier		st->sync_flags |= PFSTATE_NOSYNC;		\
287130613Smlaier	else if (!st->sync_flags)				\
288130613Smlaier		pfsync_pack_state(PFSYNC_ACT_INS, (st), 1);	\
289130613Smlaier	st->sync_flags &= ~PFSTATE_FROMSYNC;			\
290130613Smlaier} while (0)
291130613Smlaier#define pfsync_update_state(st) do {				\
292130613Smlaier	if (!st->sync_flags)					\
293145836Smlaier		pfsync_pack_state(PFSYNC_ACT_UPD, (st), 	\
294145836Smlaier		    PFSYNC_FLAG_COMPRESS);			\
295130613Smlaier	st->sync_flags &= ~PFSTATE_FROMSYNC;			\
296130613Smlaier} while (0)
297130613Smlaier#define pfsync_delete_state(st) do {				\
298130613Smlaier	if (!st->sync_flags)					\
299145836Smlaier		pfsync_pack_state(PFSYNC_ACT_DEL, (st),		\
300145836Smlaier		    PFSYNC_FLAG_COMPRESS);			\
301130613Smlaier	st->sync_flags &= ~PFSTATE_FROMSYNC;			\
302130613Smlaier} while (0)
303130613Smlaier#endif
304126258Smlaier
305126258Smlaier#endif /* _NET_IF_PFSYNC_H_ */
306