Kernel part of PF
[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.1 2004/09/19 22:32:47 joerg 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
37 #define PFSYNC_ID_LEN   sizeof(u_int64_t)
38
39 struct pfsync_state_scrub {
40         u_int16_t       pfss_flags;
41         u_int8_t        pfss_ttl;       /* stashed TTL          */
42         u_int8_t        scrub_flag;
43         u_int32_t       pfss_ts_mod;    /* timestamp modulation */
44 } __packed;
45
46 struct pfsync_state_host {
47         struct pf_addr  addr;
48         u_int16_t       port;
49         u_int16_t       pad[3];
50 } __packed;
51
52 struct pfsync_state_peer {
53         struct pfsync_state_scrub scrub;        /* state is scrubbed    */
54         u_int32_t       seqlo;          /* Max sequence number sent     */
55         u_int32_t       seqhi;          /* Max the other end ACKd + win */
56         u_int32_t       seqdiff;        /* Sequence number modulator    */
57         u_int16_t       max_win;        /* largest window (pre scaling) */
58         u_int16_t       mss;            /* Maximum segment size option  */
59         u_int8_t        state;          /* active state level           */
60         u_int8_t        wscale;         /* window scaling factor        */
61         u_int8_t        scrub_flag;
62         u_int8_t        pad[5];
63 } __packed;
64
65 struct pfsync_state {
66         u_int32_t        id[2];
67         char             ifname[IFNAMSIZ];
68         struct pfsync_state_host lan;
69         struct pfsync_state_host gwy;
70         struct pfsync_state_host ext;
71         struct pfsync_state_peer src;
72         struct pfsync_state_peer dst;
73         struct pf_addr   rt_addr;
74         u_int32_t        rule;
75         u_int32_t        anchor;
76         u_int32_t        nat_rule;
77         u_int32_t        creation;
78         u_int32_t        expire;
79         u_int32_t        packets[2];
80         u_int32_t        bytes[2];
81         u_int32_t        creatorid;
82         sa_family_t      af;
83         u_int8_t         proto;
84         u_int8_t         direction;
85         u_int8_t         log;
86         u_int8_t         allow_opts;
87         u_int8_t         timeout;
88         u_int8_t         sync_flags;
89         u_int8_t         updates;
90 } __packed;
91
92 struct 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
103 struct 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
115 struct pfsync_state_upd_req {
116         u_int32_t               id[2];
117         u_int32_t               creatorid;
118         u_int32_t               pad;
119 } __packed;
120
121 struct pfsync_state_clr {
122         char                    ifname[IFNAMSIZ];
123         u_int32_t               creatorid;
124         u_int32_t               pad;
125 } __packed;
126
127 struct 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
138 union 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
147 extern int      pfsync_sync_ok;
148
149 struct pfsync_softc {
150         struct ifnet             sc_if;
151         struct ifnet            *sc_sync_ifp;
152
153         struct ip_moptions       sc_imo;
154         struct callout           sc_tmo;
155         struct callout           sc_bulk_tmo;
156         struct callout           sc_bulkfail_tmo;
157         struct in_addr           sc_sendaddr;
158         struct mbuf             *sc_mbuf;       /* current cummulative mbuf */
159         struct mbuf             *sc_mbuf_net;   /* current cummulative mbuf */
160         union sc_statep          sc_statep;
161         union sc_statep          sc_statep_net;
162         u_int32_t                sc_ureq_received;
163         u_int32_t                sc_ureq_sent;
164         int                      sc_bulk_tries;
165         int                      sc_maxcount;   /* number of states in mtu */
166         int                      sc_maxupdates; /* number of updates/state */
167         LIST_ENTRY(pfsync_softc) sc_next;
168 };
169 #endif
170
171
172 struct pfsync_header {
173         u_int8_t version;
174 #define PFSYNC_VERSION  2
175         u_int8_t af;
176         u_int8_t action;
177 #define PFSYNC_ACT_CLR          0       /* clear all states */
178 #define PFSYNC_ACT_INS          1       /* insert state */
179 #define PFSYNC_ACT_UPD          2       /* update state */
180 #define PFSYNC_ACT_DEL          3       /* delete state */
181 #define PFSYNC_ACT_UPD_C        4       /* "compressed" state update */
182 #define PFSYNC_ACT_DEL_C        5       /* "compressed" state delete */
183 #define PFSYNC_ACT_INS_F        6       /* insert fragment */
184 #define PFSYNC_ACT_DEL_F        7       /* delete fragments */
185 #define PFSYNC_ACT_UREQ         8       /* request "uncompressed" state */
186 #define PFSYNC_ACT_BUS          9       /* Bulk Update Status */
187 #define PFSYNC_ACT_MAX          10
188         u_int8_t count;
189 } __packed;
190
191 #define PFSYNC_BULKPACKETS      1       /* # of packets per timeout */
192 #define PFSYNC_MAX_BULKTRIES    12      
193 #define PFSYNC_HDRLEN   sizeof(struct pfsync_header)
194 #define PFSYNC_ACTIONS \
195         "CLR ST", "INS ST", "UPD ST", "DEL ST", \
196         "UPD ST COMP", "DEL ST COMP", "INS FR", "DEL FR", \
197         "UPD REQ", "BLK UPD STAT"
198
199 #define PFSYNC_DFLTTL           255
200
201 struct pfsyncstats {
202         u_long  pfsyncs_ipackets;       /* total input packets, IPv4 */
203         u_long  pfsyncs_ipackets6;      /* total input packets, IPv6 */
204         u_long  pfsyncs_badif;          /* not the right interface */
205         u_long  pfsyncs_badttl;         /* TTL is not PFSYNC_DFLTTL */
206         u_long  pfsyncs_hdrops;         /* packets shorter than header */
207         u_long  pfsyncs_badver;         /* bad (incl unsupp) version */
208         u_long  pfsyncs_badact;         /* bad action */
209         u_long  pfsyncs_badlen;         /* data length does not match */
210         u_long  pfsyncs_badauth;        /* bad authentication */
211         u_long  pfsyncs_badstate;       /* insert/lookup failed */
212
213         u_long  pfsyncs_opackets;       /* total output packets, IPv4 */
214         u_long  pfsyncs_opackets6;      /* total output packets, IPv6 */
215         u_long  pfsyncs_onomem;         /* no memory for an mbuf for a send */
216         u_long  pfsyncs_oerrors;        /* ip output error */
217 };
218
219 /*
220  * Configuration structure for SIOCSETPFSYNC SIOCGETPFSYNC
221  */
222 struct pfsyncreq {
223         char    pfsyncr_syncif[IFNAMSIZ];
224         int     pfsyncr_maxupdates;
225         int     pfsyncr_authlevel;
226 };
227 #define SIOCSETPFSYNC   _IOW('i', 247, struct ifreq)
228 #define SIOCGETPFSYNC   _IOWR('i', 248, struct ifreq)
229
230
231 #define pf_state_peer_hton(s,d) do {            \
232         (d)->seqlo = htonl((s)->seqlo);         \
233         (d)->seqhi = htonl((s)->seqhi);         \
234         (d)->seqdiff = htonl((s)->seqdiff);     \
235         (d)->max_win = htons((s)->max_win);     \
236         (d)->mss = htons((s)->mss);             \
237         (d)->state = (s)->state;                \
238         (d)->wscale = (s)->wscale;              \
239 } while (0)
240
241 #define pf_state_peer_ntoh(s,d) do {            \
242         (d)->seqlo = ntohl((s)->seqlo);         \
243         (d)->seqhi = ntohl((s)->seqhi);         \
244         (d)->seqdiff = ntohl((s)->seqdiff);     \
245         (d)->max_win = ntohs((s)->max_win);     \
246         (d)->mss = ntohs((s)->mss);             \
247         (d)->state = (s)->state;                \
248         (d)->wscale = (s)->wscale;              \
249 } while (0)
250
251 #define pf_state_host_hton(s,d) do {                            \
252         bcopy(&(s)->addr, &(d)->addr, sizeof((d)->addr));       \
253         (d)->port = (s)->port;                                  \
254 } while (0)
255
256 #define pf_state_host_ntoh(s,d) do {                            \
257         bcopy(&(s)->addr, &(d)->addr, sizeof((d)->addr));       \
258         (d)->port = (s)->port;                                  \
259 } while (0)
260
261 #ifdef _KERNEL
262 void pfsync_input(struct mbuf *, ...);
263 int pfsync_clear_states(u_int32_t, char *);
264 int pfsync_pack_state(u_int8_t, struct pf_state *, int);
265 #define pfsync_insert_state(st) do {                            \
266         if ((st->rule.ptr->rule_flag & PFRULE_NOSYNC) ||        \
267             (st->proto == IPPROTO_PFSYNC))                      \
268                 st->sync_flags |= PFSTATE_NOSYNC;               \
269         else if (!st->sync_flags)                               \
270                 pfsync_pack_state(PFSYNC_ACT_INS, (st), 1);     \
271         st->sync_flags &= ~PFSTATE_FROMSYNC;                    \
272 } while (0)
273 #define pfsync_update_state(st) do {                            \
274         if (!st->sync_flags)                                    \
275                 pfsync_pack_state(PFSYNC_ACT_UPD, (st), 1);     \
276         st->sync_flags &= ~PFSTATE_FROMSYNC;                    \
277 } while (0)
278 #define pfsync_delete_state(st) do {                            \
279         if (!st->sync_flags)                                    \
280                 pfsync_pack_state(PFSYNC_ACT_DEL, (st), 1);     \
281         st->sync_flags &= ~PFSTATE_FROMSYNC;                    \
282 } while (0)
283 #endif
284
285 #endif /* _NET_IF_PFSYNC_H_ */