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