diff options
author | Ryan Thomas McBride <mcbride@cvs.openbsd.org> | 2003-12-15 07:11:32 +0000 |
---|---|---|
committer | Ryan Thomas McBride <mcbride@cvs.openbsd.org> | 2003-12-15 07:11:32 +0000 |
commit | 3f6ecdcf7bf4d1a9f842f454e434a0f834bc9338 (patch) | |
tree | a34c50e86533706da38cd062ce07e20342bfe726 /sys/net/if_pfsync.h | |
parent | 9b4a7db3efb0a8f50c08258e2f5a3353e1ee210e (diff) |
Add initial support for pf state synchronization over the network.
Implemented as an in-kernel multicast IP protocol.
Turn it on like this:
# ifconfig pfsync0 up syncif fxp0
There is not yet any authentication on this protocol, so the syncif
must be on a trusted network. ie, a crossover cable between the two
firewalls.
NOTABLE CHANGES:
- A new index based on a unique (creatorid, stateid) tuple has been
added to the state tree.
- Updates now appear on the pfsync(4) interface; multiple updates may
be compressed into a single update.
- Applications which use bpf on pfsync(4) will need modification;
packets on pfsync no longer contains regular pf_state structs,
but pfsync_state structs which contain no pointers.
Much more to come.
ok deraadt@
Diffstat (limited to 'sys/net/if_pfsync.h')
-rw-r--r-- | sys/net/if_pfsync.h | 184 |
1 files changed, 167 insertions, 17 deletions
diff --git a/sys/net/if_pfsync.h b/sys/net/if_pfsync.h index cbeebcd9adf..6d6ad601dd0 100644 --- a/sys/net/if_pfsync.h +++ b/sys/net/if_pfsync.h @@ -1,4 +1,4 @@ -/* $OpenBSD: if_pfsync.h,v 1.3 2003/11/08 00:45:34 mcbride Exp $ */ +/* $OpenBSD: if_pfsync.h,v 1.4 2003/12/15 07:11:30 mcbride Exp $ */ /* * Copyright (c) 2001 Michael Shalayeff @@ -29,40 +29,172 @@ #ifndef _NET_IF_PFSYNC_H_ #define _NET_IF_PFSYNC_H_ +struct pfsync_state_scrub { + u_int16_t pfss_flags; + u_int8_t pfss_ttl; /* stashed TTL */ + u_int8_t scrub_flag; + u_int32_t pfss_ts_mod; /* timestamp modulation */ +} __packed; + +struct pfsync_state_host { + struct pf_addr addr; + u_int16_t port; + u_int16_t pad[3]; +} __packed; + +struct pfsync_state_peer { + struct pfsync_state_scrub scrub; /* state is scrubbed */ + u_int32_t seqlo; /* Max sequence number sent */ + u_int32_t seqhi; /* Max the other end ACKd + win */ + u_int32_t seqdiff; /* Sequence number modulator */ + u_int16_t max_win; /* largest window (pre scaling) */ + u_int16_t mss; /* Maximum segment size option */ + u_int8_t state; /* active state level */ + u_int8_t wscale; /* window scaling factor */ + u_int8_t scrub_flag; + u_int8_t pad[5]; +} __packed; + +struct pfsync_state { + u_int64_t id; + struct pfsync_state_host lan; + struct pfsync_state_host gwy; + struct pfsync_state_host ext; + struct pfsync_state_peer src; + struct pfsync_state_peer dst; + struct pf_addr rt_addr; + u_int32_t rule; + u_int32_t anchor; + u_int32_t nat_rule; + u_int32_t creation; + u_int32_t expire; + u_int32_t packets[2]; + u_int32_t bytes[2]; + u_int32_t creatorid; + sa_family_t af; + u_int8_t proto; + u_int8_t direction; + u_int8_t log; + u_int8_t allow_opts; + u_int8_t timeout; + u_int8_t sync_flags; + u_int8_t updates; +} __packed; + +struct pfsync_state_upd { + u_int64_t id; + struct pfsync_state_peer src; + struct pfsync_state_peer dst; + u_int32_t creatorid; + u_int32_t expire; + u_int8_t updates; + u_int8_t pad[7]; +} __packed; + +struct pfsync_state_del { + u_int64_t id; + u_int32_t creatorid; + struct { + u_int8_t state; + } src; + struct { + u_int8_t state; + } dst; + u_int8_t pad[2]; +} __packed; + +struct pfsync_state_clr { + u_int32_t creatorid; + u_int32_t pad; +} __packed; + #ifdef _KERNEL + +union sc_sp { + struct pfsync_state *s; + struct pfsync_state_upd *u; + struct pfsync_state_del *d; + struct pfsync_state_clr *c; +}; + struct pfsync_softc { - struct ifnet sc_if; + struct ifnet sc_if; + struct ifnet *sc_sync_ifp; - struct timeout sc_tmo; - struct mbuf *sc_mbuf; /* current cummulative mbuf */ - struct pf_state *sc_ptr; /* current ongoing state */ - int sc_count; /* number of states in one mtu */ + struct ip_moptions sc_imo; + struct timeout sc_tmo; + struct mbuf *sc_mbuf; /* current cummulative mbuf */ + struct mbuf *sc_mbuf_net; /* current cummulative mbuf */ + union sc_sp sc_sp; + union sc_sp sc_sp_net; + int sc_maxcount; /* number of states in mtu */ + int sc_maxupdates; /* number of updates/state */ }; #endif + struct pfsync_header { u_int8_t version; #define PFSYNC_VERSION 1 u_int8_t af; u_int8_t action; -#define PFSYNC_ACT_CLR 0 -#define PFSYNC_ACT_INS 1 -#define PFSYNC_ACT_UPD 2 -#define PFSYNC_ACT_DEL 3 -#define PFSYNC_ACT_MAX 4 +#define PFSYNC_ACT_CLR 0 /* clear all states */ +#define PFSYNC_ACT_INS 1 /* insert state */ +#define PFSYNC_ACT_UPD 2 /* update state */ +#define PFSYNC_ACT_DEL 3 /* delete state */ +#define PFSYNC_ACT_UPD_C 4 /* "compressed" state update */ +#define PFSYNC_ACT_DEL_C 5 /* "compressed" state delete */ +#define PFSYNC_ACT_INS_F 6 /* insert fragment */ +#define PFSYNC_ACT_DEL_F 7 /* delete fragments */ +#define PFSYNC_ACT_MAX 8 u_int8_t count; -}; +} __packed; #define PFSYNC_HDRLEN sizeof(struct pfsync_header) #define PFSYNC_ACTIONS \ - "CLR ST", "INS ST", "UPD ST", "DEL ST" + "CLR ST", "INS ST", "UPD ST", "DEL ST", \ + "UPD ST COMP", "DEL ST COMP", "INS FR", "DEL FR" + +#define PFSYNC_DFLTTL 255 + +struct pfsyncstats { + u_long pfsyncs_ipackets; /* total input packets, IPv4 */ + u_long pfsyncs_ipackets6; /* total input packets, IPv6 */ + u_long pfsyncs_badif; /* not the right interface */ + u_long pfsyncs_badttl; /* TTL is not PFSYNC_DFLTTL */ + u_long pfsyncs_hdrops; /* packets shorter than header */ + u_long pfsyncs_badver; /* bad (incl unsupp) version */ + u_long pfsyncs_badact; /* bad action */ + u_long pfsyncs_badlen; /* data length does not match */ + u_long pfsyncs_badauth; /* bad authentication */ + u_long pfsyncs_badstate; /* insert/lookup failed */ + + u_long pfsyncs_opackets; /* total output packets, IPv4 */ + u_long pfsyncs_opackets6; /* total output packets, IPv6 */ + u_long pfsyncs_onomem; /* no memory for an mbuf for a send */ + u_long pfsyncs_oerrors; /* ip output error */ +}; + +/* + * Configuration structure for SIOCSETPFSYNC SIOCGETPFSYNC + */ +struct pfsyncreq { + char pfsyncr_syncif[IFNAMSIZ]; + int pfsyncr_maxupdates; + int pfsyncr_authlevel; +}; +#define SIOCSETPFSYNC _IOW('i', 247, struct ifreq) +#define SIOCGETPFSYNC _IOWR('i', 248, struct ifreq) + #define pf_state_peer_hton(s,d) do { \ (d)->seqlo = htonl((s)->seqlo); \ (d)->seqhi = htonl((s)->seqhi); \ (d)->seqdiff = htonl((s)->seqdiff); \ (d)->max_win = htons((s)->max_win); \ + (d)->mss = htons((s)->mss); \ (d)->state = (s)->state; \ + (d)->wscale = (s)->wscale; \ } while (0) #define pf_state_peer_ntoh(s,d) do { \ @@ -70,23 +202,41 @@ struct pfsync_header { (d)->seqhi = ntohl((s)->seqhi); \ (d)->seqdiff = ntohl((s)->seqdiff); \ (d)->max_win = ntohs((s)->max_win); \ + (d)->mss = ntohs((s)->mss); \ (d)->state = (s)->state; \ + (d)->wscale = (s)->wscale; \ +} while (0) + +#define pf_state_host_hton(s,d) do { \ + bcopy(&(s)->addr, &(d)->addr, sizeof((d)->addr)); \ + (d)->port = htons((s)->port); \ +} while (0) + +#define pf_state_host_ntoh(s,d) do { \ + bcopy(&(s)->addr, &(d)->addr, sizeof((d)->addr)); \ + (d)->port = ntohs((s)->port); \ } while (0) #ifdef _KERNEL -int pfsync_clear_state(struct pf_state *); +void pfsync_input(struct mbuf *, ...); +int pfsync_clear_states(u_int32_t); int pfsync_pack_state(u_int8_t, struct pf_state *); #define pfsync_insert_state(st) do { \ - if (!(st->rule.ptr->rule_flag & PFRULE_NOSYNC)) \ + if (st->rule.ptr->rule_flag & PFRULE_NOSYNC) \ + st->sync_flags |= PFSTATE_NOSYNC; \ + else if (!st->sync_flags) \ pfsync_pack_state(PFSYNC_ACT_INS, (st));\ + st->sync_flags &= ~PFSTATE_FROMSYNC; \ } while (0) #define pfsync_update_state(st) do { \ - if (!(st->rule.ptr->rule_flag & PFRULE_NOSYNC)) \ + if (!st->sync_flags) \ pfsync_pack_state(PFSYNC_ACT_UPD, (st));\ + st->sync_flags &= ~PFSTATE_FROMSYNC; \ } while (0) #define pfsync_delete_state(st) do { \ - if (!(st->rule.ptr->rule_flag & PFRULE_NOSYNC)) \ + if (!st->sync_flags) \ pfsync_pack_state(PFSYNC_ACT_DEL, (st));\ + st->sync_flags &= ~PFSTATE_FROMSYNC; \ } while (0) #endif |