]> CyberLeo.Net >> Repos - FreeBSD/releng/8.1.git/blob - sys/contrib/pf/net/if_pfsync.h
Copy stable/8 to releng/8.1 in preparation for 8.1-RC1.
[FreeBSD/releng/8.1.git] / sys / contrib / pf / net / if_pfsync.h
1 /*      $FreeBSD$       */
2 /*      $OpenBSD: if_pfsync.h,v 1.30 2006/10/31 14:49:01 henning 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
36 struct pfsync_state_scrub {
37         u_int16_t       pfss_flags;
38         u_int8_t        pfss_ttl;       /* stashed TTL          */
39 #define PFSYNC_SCRUB_FLAG_VALID         0x01
40         u_int8_t        scrub_flag;
41         u_int32_t       pfss_ts_mod;    /* timestamp modulation */
42 } __packed;
43
44 struct pfsync_state_host {
45         struct pf_addr  addr;
46         u_int16_t       port;
47         u_int16_t       pad[3];
48 } __packed;
49
50 struct pfsync_state_peer {
51         struct pfsync_state_scrub scrub;        /* state is scrubbed    */
52         u_int32_t       seqlo;          /* Max sequence number sent     */
53         u_int32_t       seqhi;          /* Max the other end ACKd + win */
54         u_int32_t       seqdiff;        /* Sequence number modulator    */
55         u_int16_t       max_win;        /* largest window (pre scaling) */
56         u_int16_t       mss;            /* Maximum segment size option  */
57         u_int8_t        state;          /* active state level           */
58         u_int8_t        wscale;         /* window scaling factor        */
59         u_int8_t        pad[6];
60 } __packed;
61
62 struct 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][2];
77         u_int32_t        bytes[2][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         state_flags;
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
92 #ifdef PFSYNC_TDB
93 struct pfsync_tdb {
94         u_int32_t       spi;
95         union sockaddr_union dst;
96         u_int32_t       rpl;
97         u_int64_t       cur_bytes;
98         u_int8_t        sproto;
99         u_int8_t        updates;
100         u_int8_t        pad[2];
101 } __packed;
102 #endif
103
104 struct pfsync_state_upd {
105         u_int32_t               id[2];
106         struct pfsync_state_peer        src;
107         struct pfsync_state_peer        dst;
108         u_int32_t               creatorid;
109         u_int32_t               expire;
110         u_int8_t                timeout;
111         u_int8_t                updates;
112         u_int8_t                pad[6];
113 } __packed;
114
115 struct pfsync_state_del {
116         u_int32_t               id[2];
117         u_int32_t               creatorid;
118         struct {
119                 u_int8_t        state;
120         } src;
121         struct {
122                 u_int8_t        state;
123         } dst;
124         u_int8_t                pad[2];
125 } __packed;
126
127 struct pfsync_state_upd_req {
128         u_int32_t               id[2];
129         u_int32_t               creatorid;
130         u_int32_t               pad;
131 } __packed;
132
133 struct pfsync_state_clr {
134         char                    ifname[IFNAMSIZ];
135         u_int32_t               creatorid;
136         u_int32_t               pad;
137 } __packed;
138
139 struct pfsync_state_bus {
140         u_int32_t               creatorid;
141         u_int32_t               endtime;
142         u_int8_t                status;
143 #define PFSYNC_BUS_START        1
144 #define PFSYNC_BUS_END          2
145         u_int8_t                pad[7];
146 } __packed;
147
148 #ifdef _KERNEL
149
150 union sc_statep {
151         struct pfsync_state     *s;
152         struct pfsync_state_upd *u;
153         struct pfsync_state_del *d;
154         struct pfsync_state_clr *c;
155         struct pfsync_state_bus *b;
156         struct pfsync_state_upd_req     *r;
157 };
158
159 #ifdef PFSYNC_TDB
160 union sc_tdb_statep {
161         struct pfsync_tdb       *t;
162 };
163 #endif
164
165 extern int      pfsync_sync_ok;
166
167 struct pfsync_softc {
168 #ifdef __FreeBSD__
169         struct ifnet            *sc_ifp;
170 #else
171         struct ifnet             sc_if;
172 #endif
173         struct ifnet            *sc_sync_ifp;
174
175         struct ip_moptions       sc_imo;
176 #ifdef __FreeBSD__
177         struct callout           sc_tmo;
178 #ifdef PFSYNC_TDB
179         struct callout           sc_tdb_tmo;
180 #endif
181         struct callout           sc_bulk_tmo;
182         struct callout           sc_bulkfail_tmo;
183 #else
184         struct timeout           sc_tmo;
185         struct timeout           sc_tdb_tmo;
186         struct timeout           sc_bulk_tmo;
187         struct timeout           sc_bulkfail_tmo;
188 #endif
189         struct in_addr           sc_sync_peer;
190         struct in_addr           sc_sendaddr;
191         struct mbuf             *sc_mbuf;       /* current cumulative mbuf */
192         struct mbuf             *sc_mbuf_net;   /* current cumulative mbuf */
193 #ifdef PFSYNC_TDB
194         struct mbuf             *sc_mbuf_tdb;   /* dito for TDB updates */
195 #endif
196 #ifdef __FreeBSD__
197         struct ifqueue           sc_ifq;
198         struct task              sc_send_task;
199 #endif
200         union sc_statep          sc_statep;
201         union sc_statep          sc_statep_net;
202 #ifdef PFSYNC_TDB
203         union sc_tdb_statep      sc_statep_tdb;
204 #endif
205         u_int32_t                sc_ureq_received;
206         u_int32_t                sc_ureq_sent;
207         struct pf_state         *sc_bulk_send_next;
208         struct pf_state         *sc_bulk_terminator;
209         int                      sc_bulk_tries;
210         int                      sc_maxcount;   /* number of states in mtu */
211         int                      sc_maxupdates; /* number of updates/state */
212 #ifdef __FreeBSD__
213         eventhandler_tag         sc_detachtag;
214 #endif
215 };
216
217 extern struct pfsync_softc      *pfsyncif;
218 #endif
219
220
221 struct pfsync_header {
222         u_int8_t version;
223 #define PFSYNC_VERSION  3
224         u_int8_t af;
225         u_int8_t action;
226 #define PFSYNC_ACT_CLR          0       /* clear all states */
227 #define PFSYNC_ACT_INS          1       /* insert state */
228 #define PFSYNC_ACT_UPD          2       /* update state */
229 #define PFSYNC_ACT_DEL          3       /* delete state */
230 #define PFSYNC_ACT_UPD_C        4       /* "compressed" state update */
231 #define PFSYNC_ACT_DEL_C        5       /* "compressed" state delete */
232 #define PFSYNC_ACT_INS_F        6       /* insert fragment */
233 #define PFSYNC_ACT_DEL_F        7       /* delete fragments */
234 #define PFSYNC_ACT_UREQ         8       /* request "uncompressed" state */
235 #define PFSYNC_ACT_BUS          9       /* Bulk Update Status */
236 #define PFSYNC_ACT_TDB_UPD      10      /* TDB replay counter update */
237 #define PFSYNC_ACT_MAX          11
238         u_int8_t count;
239         u_int8_t pf_chksum[PF_MD5_DIGEST_LENGTH];
240 } __packed;
241
242 #define PFSYNC_BULKPACKETS      1       /* # of packets per timeout */
243 #define PFSYNC_MAX_BULKTRIES    12
244 #define PFSYNC_HDRLEN   sizeof(struct pfsync_header)
245 #define PFSYNC_ACTIONS \
246         "CLR ST", "INS ST", "UPD ST", "DEL ST", \
247         "UPD ST COMP", "DEL ST COMP", "INS FR", "DEL FR", \
248         "UPD REQ", "BLK UPD STAT", "TDB UPD"
249
250 #define PFSYNC_DFLTTL           255
251
252 struct pfsyncstats {
253         u_int64_t       pfsyncs_ipackets;       /* total input packets, IPv4 */
254         u_int64_t       pfsyncs_ipackets6;      /* total input packets, IPv6 */
255         u_int64_t       pfsyncs_badif;          /* not the right interface */
256         u_int64_t       pfsyncs_badttl;         /* TTL is not PFSYNC_DFLTTL */
257         u_int64_t       pfsyncs_hdrops;         /* packets shorter than hdr */
258         u_int64_t       pfsyncs_badver;         /* bad (incl unsupp) version */
259         u_int64_t       pfsyncs_badact;         /* bad action */
260         u_int64_t       pfsyncs_badlen;         /* data length does not match */
261         u_int64_t       pfsyncs_badauth;        /* bad authentication */
262         u_int64_t       pfsyncs_stale;          /* stale state */
263         u_int64_t       pfsyncs_badval;         /* bad values */
264         u_int64_t       pfsyncs_badstate;       /* insert/lookup failed */
265
266         u_int64_t       pfsyncs_opackets;       /* total output packets, IPv4 */
267         u_int64_t       pfsyncs_opackets6;      /* total output packets, IPv6 */
268         u_int64_t       pfsyncs_onomem;         /* no memory for an mbuf */
269         u_int64_t       pfsyncs_oerrors;        /* ip output error */
270 };
271
272 /*
273  * Configuration structure for SIOCSETPFSYNC SIOCGETPFSYNC
274  */
275 struct pfsyncreq {
276         char             pfsyncr_syncdev[IFNAMSIZ];
277         struct in_addr   pfsyncr_syncpeer;
278         int              pfsyncr_maxupdates;
279         int              pfsyncr_authlevel;
280 };
281
282 #ifdef __FreeBSD__
283 #define SIOCSETPFSYNC   _IOW('i', 247, struct ifreq)
284 #define SIOCGETPFSYNC   _IOWR('i', 248, struct ifreq)
285 #endif
286
287 #define pf_state_peer_hton(s,d) do {            \
288         (d)->seqlo = htonl((s)->seqlo);         \
289         (d)->seqhi = htonl((s)->seqhi);         \
290         (d)->seqdiff = htonl((s)->seqdiff);     \
291         (d)->max_win = htons((s)->max_win);     \
292         (d)->mss = htons((s)->mss);             \
293         (d)->state = (s)->state;                \
294         (d)->wscale = (s)->wscale;              \
295         if ((s)->scrub) {                                               \
296                 (d)->scrub.pfss_flags =                                 \
297                     htons((s)->scrub->pfss_flags & PFSS_TIMESTAMP);     \
298                 (d)->scrub.pfss_ttl = (s)->scrub->pfss_ttl;             \
299                 (d)->scrub.pfss_ts_mod = htonl((s)->scrub->pfss_ts_mod);\
300                 (d)->scrub.scrub_flag = PFSYNC_SCRUB_FLAG_VALID;        \
301         }                                                               \
302 } while (0)
303
304 #define pf_state_peer_ntoh(s,d) do {            \
305         (d)->seqlo = ntohl((s)->seqlo);         \
306         (d)->seqhi = ntohl((s)->seqhi);         \
307         (d)->seqdiff = ntohl((s)->seqdiff);     \
308         (d)->max_win = ntohs((s)->max_win);     \
309         (d)->mss = ntohs((s)->mss);             \
310         (d)->state = (s)->state;                \
311         (d)->wscale = (s)->wscale;              \
312         if ((s)->scrub.scrub_flag == PFSYNC_SCRUB_FLAG_VALID &&         \
313             (d)->scrub != NULL) {                                       \
314                 (d)->scrub->pfss_flags =                                \
315                     ntohs((s)->scrub.pfss_flags) & PFSS_TIMESTAMP;      \
316                 (d)->scrub->pfss_ttl = (s)->scrub.pfss_ttl;             \
317                 (d)->scrub->pfss_ts_mod = ntohl((s)->scrub.pfss_ts_mod);\
318         }                                                               \
319 } while (0)
320
321 #define pf_state_host_hton(s,d) do {                            \
322         bcopy(&(s)->addr, &(d)->addr, sizeof((d)->addr));       \
323         (d)->port = (s)->port;                                  \
324 } while (0)
325
326 #define pf_state_host_ntoh(s,d) do {                            \
327         bcopy(&(s)->addr, &(d)->addr, sizeof((d)->addr));       \
328         (d)->port = (s)->port;                                  \
329 } while (0)
330
331 #define pf_state_counter_hton(s,d) do {                         \
332         d[0] = htonl((s>>32)&0xffffffff);                       \
333         d[1] = htonl(s&0xffffffff);                             \
334 } while (0)
335
336 #define pf_state_counter_ntoh(s,d) do {                         \
337         d = ntohl(s[0]);                                        \
338         d = d<<32;                                              \
339         d += ntohl(s[1]);                                       \
340 } while (0)
341
342 #ifdef _KERNEL
343 #ifdef __FreeBSD__
344 void pfsync_input(struct mbuf *, __unused int);
345 #else
346 void pfsync_input(struct mbuf *, ...);
347 #endif
348 int pfsync_clear_states(u_int32_t, char *);
349 int pfsync_pack_state(u_int8_t, struct pf_state *, int);
350 #define pfsync_insert_state(st) do {                            \
351         if ((st->rule.ptr->rule_flag & PFRULE_NOSYNC) ||        \
352             (st->proto == IPPROTO_PFSYNC))                      \
353                 st->sync_flags |= PFSTATE_NOSYNC;               \
354         else if (!st->sync_flags)                               \
355                 pfsync_pack_state(PFSYNC_ACT_INS, (st),         \
356                     PFSYNC_FLAG_COMPRESS);                      \
357         st->sync_flags &= ~PFSTATE_FROMSYNC;                    \
358 } while (0)
359 #define pfsync_update_state(st) do {                            \
360         if (!st->sync_flags)                                    \
361                 pfsync_pack_state(PFSYNC_ACT_UPD, (st),         \
362                     PFSYNC_FLAG_COMPRESS);                      \
363         st->sync_flags &= ~PFSTATE_FROMSYNC;                    \
364 } while (0)
365 #define pfsync_delete_state(st) do {                            \
366         if (!st->sync_flags)                                    \
367                 pfsync_pack_state(PFSYNC_ACT_DEL, (st),         \
368                     PFSYNC_FLAG_COMPRESS);                      \
369 } while (0)
370 #ifdef PFSYNC_TDB
371 int pfsync_update_tdb(struct tdb *, int);
372 #endif
373 #endif
374
375 #endif /* _NET_IF_PFSYNC_H_ */