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