if_pfsync.h revision 145836
1/*	$FreeBSD: head/sys/contrib/pf/net/if_pfsync.h 145836 2005-05-03 16:43:32Z mlaier $	*/
2/*	$OpenBSD: if_pfsync.h,v 1.19 2005/01/20 17:47:38 mcbride Exp $	*/
3
4/*
5 * Copyright (c) 2001 Michael Shalayeff
6 * All rights reserved.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 * 1. Redistributions of source code must retain the above copyright
12 *    notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 *    notice, this list of conditions and the following disclaimer in the
15 *    documentation and/or other materials provided with the distribution.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20 * IN NO EVENT SHALL THE AUTHOR OR HIS RELATIVES BE LIABLE FOR ANY DIRECT,
21 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
22 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
23 * SERVICES; LOSS OF MIND, USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
25 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
26 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
27 * THE POSSIBILITY OF SUCH DAMAGE.
28 */
29
30#ifndef _NET_IF_PFSYNC_H_
31#define _NET_IF_PFSYNC_H_
32
33
34#define PFSYNC_ID_LEN	sizeof(u_int64_t)
35
36struct pfsync_state_scrub {
37	u_int16_t	pfss_flags;
38	u_int8_t	pfss_ttl;	/* stashed TTL		*/
39	u_int8_t	scrub_flag;
40	u_int32_t	pfss_ts_mod;	/* timestamp modulation	*/
41} __packed;
42
43struct pfsync_state_host {
44	struct pf_addr	addr;
45	u_int16_t	port;
46	u_int16_t	pad[3];
47} __packed;
48
49struct pfsync_state_peer {
50	struct pfsync_state_scrub scrub;	/* state is scrubbed	*/
51	u_int32_t	seqlo;		/* Max sequence number sent	*/
52	u_int32_t	seqhi;		/* Max the other end ACKd + win	*/
53	u_int32_t	seqdiff;	/* Sequence number modulator	*/
54	u_int16_t	max_win;	/* largest window (pre scaling)	*/
55	u_int16_t	mss;		/* Maximum segment size option	*/
56	u_int8_t	state;		/* active state level		*/
57	u_int8_t	wscale;		/* window scaling factor	*/
58	u_int8_t	scrub_flag;
59	u_int8_t	pad[5];
60} __packed;
61
62struct pfsync_state {
63	u_int32_t	 id[2];
64	char		 ifname[IFNAMSIZ];
65	struct pfsync_state_host lan;
66	struct pfsync_state_host gwy;
67	struct pfsync_state_host ext;
68	struct pfsync_state_peer src;
69	struct pfsync_state_peer dst;
70	struct pf_addr	 rt_addr;
71	u_int32_t	 rule;
72	u_int32_t	 anchor;
73	u_int32_t	 nat_rule;
74	u_int32_t	 creation;
75	u_int32_t	 expire;
76	u_int32_t	 packets[2];
77	u_int32_t	 bytes[2];
78	u_int32_t	 creatorid;
79	sa_family_t	 af;
80	u_int8_t	 proto;
81	u_int8_t	 direction;
82	u_int8_t	 log;
83	u_int8_t	 allow_opts;
84	u_int8_t	 timeout;
85	u_int8_t	 sync_flags;
86	u_int8_t	 updates;
87} __packed;
88
89#define PFSYNC_FLAG_COMPRESS 	0x01
90#define PFSYNC_FLAG_STALE	0x02
91
92struct pfsync_state_upd {
93	u_int32_t		id[2];
94	struct pfsync_state_peer	src;
95	struct pfsync_state_peer	dst;
96	u_int32_t		creatorid;
97	u_int32_t		expire;
98	u_int8_t		timeout;
99	u_int8_t		updates;
100	u_int8_t		pad[6];
101} __packed;
102
103struct pfsync_state_del {
104	u_int32_t		id[2];
105	u_int32_t		creatorid;
106	struct {
107		u_int8_t	state;
108	} src;
109	struct {
110		u_int8_t	state;
111	} dst;
112	u_int8_t		pad[2];
113} __packed;
114
115struct pfsync_state_upd_req {
116	u_int32_t		id[2];
117	u_int32_t		creatorid;
118	u_int32_t		pad;
119} __packed;
120
121struct pfsync_state_clr {
122	char			ifname[IFNAMSIZ];
123	u_int32_t		creatorid;
124	u_int32_t		pad;
125} __packed;
126
127struct pfsync_state_bus {
128	u_int32_t		creatorid;
129	u_int32_t		endtime;
130	u_int8_t		status;
131#define PFSYNC_BUS_START	1
132#define PFSYNC_BUS_END		2
133	u_int8_t		pad[7];
134} __packed;
135
136#ifdef _KERNEL
137
138union sc_statep {
139	struct pfsync_state	*s;
140	struct pfsync_state_upd	*u;
141	struct pfsync_state_del	*d;
142	struct pfsync_state_clr	*c;
143	struct pfsync_state_bus	*b;
144	struct pfsync_state_upd_req	*r;
145};
146
147extern int	pfsync_sync_ok;
148
149struct pfsync_softc {
150	struct ifnet		 sc_if;
151	struct ifnet		*sc_sync_ifp;
152
153	struct ip_moptions	 sc_imo;
154#ifdef __FreeBSD__
155	struct callout		 sc_tmo;
156	struct callout		 sc_bulk_tmo;
157	struct callout		 sc_bulkfail_tmo;
158#else
159	struct timeout		 sc_tmo;
160	struct timeout		 sc_bulk_tmo;
161	struct timeout		 sc_bulkfail_tmo;
162#endif
163	struct in_addr		 sc_sync_peer;
164	struct in_addr		 sc_sendaddr;
165	struct mbuf		*sc_mbuf;	/* current cumulative mbuf */
166	struct mbuf		*sc_mbuf_net;	/* current cumulative mbuf */
167	union sc_statep		 sc_statep;
168	union sc_statep		 sc_statep_net;
169	u_int32_t		 sc_ureq_received;
170	u_int32_t		 sc_ureq_sent;
171	int			 sc_bulk_tries;
172	int			 sc_maxcount;	/* number of states in mtu */
173	int			 sc_maxupdates;	/* number of updates/state */
174#ifdef __FreeBSD__
175	LIST_ENTRY(pfsync_softc) sc_next;
176#endif
177};
178#endif
179
180
181struct pfsync_header {
182	u_int8_t version;
183#define	PFSYNC_VERSION	2
184	u_int8_t af;
185	u_int8_t action;
186#define	PFSYNC_ACT_CLR		0	/* clear all states */
187#define	PFSYNC_ACT_INS		1	/* insert state */
188#define	PFSYNC_ACT_UPD		2	/* update state */
189#define	PFSYNC_ACT_DEL		3	/* delete state */
190#define	PFSYNC_ACT_UPD_C	4	/* "compressed" state update */
191#define	PFSYNC_ACT_DEL_C	5	/* "compressed" state delete */
192#define	PFSYNC_ACT_INS_F	6	/* insert fragment */
193#define	PFSYNC_ACT_DEL_F	7	/* delete fragments */
194#define	PFSYNC_ACT_UREQ		8	/* request "uncompressed" state */
195#define PFSYNC_ACT_BUS		9	/* Bulk Update Status */
196#define	PFSYNC_ACT_MAX		10
197	u_int8_t count;
198} __packed;
199
200#define PFSYNC_BULKPACKETS	1	/* # of packets per timeout */
201#define PFSYNC_MAX_BULKTRIES	12
202#define PFSYNC_HDRLEN	sizeof(struct pfsync_header)
203#define	PFSYNC_ACTIONS \
204	"CLR ST", "INS ST", "UPD ST", "DEL ST", \
205	"UPD ST COMP", "DEL ST COMP", "INS FR", "DEL FR", \
206	"UPD REQ", "BLK UPD STAT"
207
208#define PFSYNC_DFLTTL		255
209
210struct pfsyncstats {
211	u_int64_t	pfsyncs_ipackets;	/* total input packets, IPv4 */
212	u_int64_t	pfsyncs_ipackets6;	/* total input packets, IPv6 */
213	u_int64_t	pfsyncs_badif;		/* not the right interface */
214	u_int64_t	pfsyncs_badttl;		/* TTL is not PFSYNC_DFLTTL */
215	u_int64_t	pfsyncs_hdrops;		/* packets shorter than hdr */
216	u_int64_t	pfsyncs_badver;		/* bad (incl unsupp) version */
217	u_int64_t	pfsyncs_badact;		/* bad action */
218	u_int64_t	pfsyncs_badlen;		/* data length does not match */
219	u_int64_t	pfsyncs_badauth;	/* bad authentication */
220	u_int64_t	pfsyncs_stale;		/* stale state */
221	u_int64_t	pfsyncs_badval;		/* bad values */
222	u_int64_t	pfsyncs_badstate;	/* insert/lookup failed */
223
224	u_int64_t	pfsyncs_opackets;	/* total output packets, IPv4 */
225	u_int64_t	pfsyncs_opackets6;	/* total output packets, IPv6 */
226	u_int64_t	pfsyncs_onomem;		/* no memory for an mbuf */
227	u_int64_t	pfsyncs_oerrors;	/* ip output error */
228};
229
230/*
231 * Configuration structure for SIOCSETPFSYNC SIOCGETPFSYNC
232 */
233struct pfsyncreq {
234	char		 pfsyncr_syncdev[IFNAMSIZ];
235	struct in_addr	 pfsyncr_syncpeer;
236	int		 pfsyncr_maxupdates;
237	int		 pfsyncr_authlevel;
238};
239
240#ifdef __FreeBSD__
241#define	SIOCSETPFSYNC	_IOW('i', 247, struct ifreq)
242#define	SIOCGETPFSYNC	_IOWR('i', 248, struct ifreq)
243#endif
244
245#define pf_state_peer_hton(s,d) do {		\
246	(d)->seqlo = htonl((s)->seqlo);		\
247	(d)->seqhi = htonl((s)->seqhi);		\
248	(d)->seqdiff = htonl((s)->seqdiff);	\
249	(d)->max_win = htons((s)->max_win);	\
250	(d)->mss = htons((s)->mss);		\
251	(d)->state = (s)->state;		\
252	(d)->wscale = (s)->wscale;		\
253} while (0)
254
255#define pf_state_peer_ntoh(s,d) do {		\
256	(d)->seqlo = ntohl((s)->seqlo);		\
257	(d)->seqhi = ntohl((s)->seqhi);		\
258	(d)->seqdiff = ntohl((s)->seqdiff);	\
259	(d)->max_win = ntohs((s)->max_win);	\
260	(d)->mss = ntohs((s)->mss);		\
261	(d)->state = (s)->state;		\
262	(d)->wscale = (s)->wscale;		\
263} while (0)
264
265#define pf_state_host_hton(s,d) do {				\
266	bcopy(&(s)->addr, &(d)->addr, sizeof((d)->addr));	\
267	(d)->port = (s)->port;					\
268} while (0)
269
270#define pf_state_host_ntoh(s,d) do {				\
271	bcopy(&(s)->addr, &(d)->addr, sizeof((d)->addr));	\
272	(d)->port = (s)->port;					\
273} while (0)
274
275#ifdef _KERNEL
276#ifdef __FreeBSD__
277void pfsync_input(struct mbuf *, __unused int);
278#else
279void pfsync_input(struct mbuf *, ...);
280#endif
281int pfsync_clear_states(u_int32_t, char *);
282int pfsync_pack_state(u_int8_t, struct pf_state *, int);
283#define pfsync_insert_state(st)	do {				\
284	if ((st->rule.ptr->rule_flag & PFRULE_NOSYNC) ||	\
285	    (st->proto == IPPROTO_PFSYNC))			\
286		st->sync_flags |= PFSTATE_NOSYNC;		\
287	else if (!st->sync_flags)				\
288		pfsync_pack_state(PFSYNC_ACT_INS, (st), 1);	\
289	st->sync_flags &= ~PFSTATE_FROMSYNC;			\
290} while (0)
291#define pfsync_update_state(st) do {				\
292	if (!st->sync_flags)					\
293		pfsync_pack_state(PFSYNC_ACT_UPD, (st), 	\
294		    PFSYNC_FLAG_COMPRESS);			\
295	st->sync_flags &= ~PFSTATE_FROMSYNC;			\
296} while (0)
297#define pfsync_delete_state(st) do {				\
298	if (!st->sync_flags)					\
299		pfsync_pack_state(PFSYNC_ACT_DEL, (st),		\
300		    PFSYNC_FLAG_COMPRESS);			\
301	st->sync_flags &= ~PFSTATE_FROMSYNC;			\
302} while (0)
303#endif
304
305#endif /* _NET_IF_PFSYNC_H_ */
306