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