1*0b9ea278Smvs /* $OpenBSD: if_pflow.h,v 1.23 2023/12/16 22:16:02 mvs Exp $ */ 218ae10f7Shenning 318ae10f7Shenning /* 418ae10f7Shenning * Copyright (c) 2008 Henning Brauer <henning@openbsd.org> 518ae10f7Shenning * Copyright (c) 2008 Joerg Goltermann <jg@osn.de> 618ae10f7Shenning * 718ae10f7Shenning * Permission to use, copy, modify, and distribute this software for any 818ae10f7Shenning * purpose with or without fee is hereby granted, provided that the above 918ae10f7Shenning * copyright notice and this permission notice appear in all copies. 1018ae10f7Shenning * 1118ae10f7Shenning * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 1218ae10f7Shenning * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 1318ae10f7Shenning * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 1418ae10f7Shenning * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 1518ae10f7Shenning * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER IN 1618ae10f7Shenning * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT 1718ae10f7Shenning * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 1818ae10f7Shenning */ 1918ae10f7Shenning 2018ae10f7Shenning #ifndef _NET_IF_PFLOW_H_ 2118ae10f7Shenning #define _NET_IF_PFLOW_H_ 2218ae10f7Shenning 2318ae10f7Shenning #define PFLOW_ID_LEN sizeof(u_int64_t) 2418ae10f7Shenning 2518ae10f7Shenning #define PFLOW_MAXFLOWS 30 2618ae10f7Shenning #define PFLOW_ENGINE_TYPE 42 2718ae10f7Shenning #define PFLOW_ENGINE_ID 42 2818ae10f7Shenning #define PFLOW_MAXBYTES 0xffffffff 2918ae10f7Shenning #define PFLOW_TIMEOUT 30 30fa1d79b8Sbenno #define PFLOW_TMPL_TIMEOUT 30 /* rfc 5101 10.3.6 (p.40) recommends 600 */ 31fa1d79b8Sbenno 3258354163Sflorian #define PFLOW_IPFIX_TMPL_SET_ID 2 33fa1d79b8Sbenno 34fa1d79b8Sbenno /* RFC 5102 Information Element Identifiers */ 35fa1d79b8Sbenno 36fa1d79b8Sbenno #define PFIX_IE_octetDeltaCount 1 37fa1d79b8Sbenno #define PFIX_IE_packetDeltaCount 2 38fa1d79b8Sbenno #define PFIX_IE_protocolIdentifier 4 39fa1d79b8Sbenno #define PFIX_IE_ipClassOfService 5 40fa1d79b8Sbenno #define PFIX_IE_sourceTransportPort 7 41fa1d79b8Sbenno #define PFIX_IE_sourceIPv4Address 8 426e55bf81Sflorian #define PFIX_IE_ingressInterface 10 43fa1d79b8Sbenno #define PFIX_IE_destinationTransportPort 11 44fa1d79b8Sbenno #define PFIX_IE_destinationIPv4Address 12 456e55bf81Sflorian #define PFIX_IE_egressInterface 14 46fa1d79b8Sbenno #define PFIX_IE_flowEndSysUpTime 21 47fa1d79b8Sbenno #define PFIX_IE_flowStartSysUpTime 22 48fa1d79b8Sbenno #define PFIX_IE_sourceIPv6Address 27 49fa1d79b8Sbenno #define PFIX_IE_destinationIPv6Address 28 5058354163Sflorian #define PFIX_IE_flowStartMilliseconds 152 5158354163Sflorian #define PFIX_IE_flowEndMilliseconds 153 5218ae10f7Shenning 5318ae10f7Shenning struct pflow_flow { 5418ae10f7Shenning u_int32_t src_ip; 5518ae10f7Shenning u_int32_t dest_ip; 5618ae10f7Shenning u_int32_t nexthop_ip; 5718ae10f7Shenning u_int16_t if_index_in; 5818ae10f7Shenning u_int16_t if_index_out; 5918ae10f7Shenning u_int32_t flow_packets; 6018ae10f7Shenning u_int32_t flow_octets; 6118ae10f7Shenning u_int32_t flow_start; 6218ae10f7Shenning u_int32_t flow_finish; 6318ae10f7Shenning u_int16_t src_port; 6418ae10f7Shenning u_int16_t dest_port; 6518ae10f7Shenning u_int8_t pad1; 6618ae10f7Shenning u_int8_t tcp_flags; 6718ae10f7Shenning u_int8_t protocol; 6818ae10f7Shenning u_int8_t tos; 6918ae10f7Shenning u_int16_t src_as; 7018ae10f7Shenning u_int16_t dest_as; 7118ae10f7Shenning u_int8_t src_mask; 7218ae10f7Shenning u_int8_t dest_mask; 7318ae10f7Shenning u_int16_t pad2; 7418ae10f7Shenning } __packed; 7518ae10f7Shenning 76fa1d79b8Sbenno struct pflow_set_header { 77fa1d79b8Sbenno u_int16_t set_id; 78fa1d79b8Sbenno u_int16_t set_length; /* total length of the set, 79fa1d79b8Sbenno in octets, including the set header */ 80fa1d79b8Sbenno } __packed; 81fa1d79b8Sbenno 82fa1d79b8Sbenno #define PFLOW_SET_HDRLEN sizeof(struct pflow_set_header) 83fa1d79b8Sbenno 84fa1d79b8Sbenno struct pflow_tmpl_hdr { 85fa1d79b8Sbenno u_int16_t tmpl_id; 86fa1d79b8Sbenno u_int16_t field_count; 87fa1d79b8Sbenno } __packed; 88fa1d79b8Sbenno 89fa1d79b8Sbenno struct pflow_tmpl_fspec { 90fa1d79b8Sbenno u_int16_t field_id; 91fa1d79b8Sbenno u_int16_t len; 92fa1d79b8Sbenno } __packed; 93fa1d79b8Sbenno 9458354163Sflorian /* update pflow_clone_create() when changing pflow_ipfix_tmpl_ipv4 */ 9558354163Sflorian struct pflow_ipfix_tmpl_ipv4 { 9658354163Sflorian struct pflow_tmpl_hdr h; 9758354163Sflorian struct pflow_tmpl_fspec src_ip; 9858354163Sflorian struct pflow_tmpl_fspec dest_ip; 9958354163Sflorian struct pflow_tmpl_fspec if_index_in; 10058354163Sflorian struct pflow_tmpl_fspec if_index_out; 10158354163Sflorian struct pflow_tmpl_fspec packets; 10258354163Sflorian struct pflow_tmpl_fspec octets; 10358354163Sflorian struct pflow_tmpl_fspec start; 10458354163Sflorian struct pflow_tmpl_fspec finish; 10558354163Sflorian struct pflow_tmpl_fspec src_port; 10658354163Sflorian struct pflow_tmpl_fspec dest_port; 10758354163Sflorian struct pflow_tmpl_fspec tos; 10858354163Sflorian struct pflow_tmpl_fspec protocol; 10958354163Sflorian #define PFLOW_IPFIX_TMPL_IPV4_FIELD_COUNT 12 11058354163Sflorian #define PFLOW_IPFIX_TMPL_IPV4_ID 256 11158354163Sflorian } __packed; 11258354163Sflorian 11358354163Sflorian /* update pflow_clone_create() when changing pflow_ipfix_tmpl_v6 */ 11458354163Sflorian struct pflow_ipfix_tmpl_ipv6 { 11558354163Sflorian struct pflow_tmpl_hdr h; 11658354163Sflorian struct pflow_tmpl_fspec src_ip; 11758354163Sflorian struct pflow_tmpl_fspec dest_ip; 11858354163Sflorian struct pflow_tmpl_fspec if_index_in; 11958354163Sflorian struct pflow_tmpl_fspec if_index_out; 12058354163Sflorian struct pflow_tmpl_fspec packets; 12158354163Sflorian struct pflow_tmpl_fspec octets; 12258354163Sflorian struct pflow_tmpl_fspec start; 12358354163Sflorian struct pflow_tmpl_fspec finish; 12458354163Sflorian struct pflow_tmpl_fspec src_port; 12558354163Sflorian struct pflow_tmpl_fspec dest_port; 12658354163Sflorian struct pflow_tmpl_fspec tos; 12758354163Sflorian struct pflow_tmpl_fspec protocol; 12858354163Sflorian #define PFLOW_IPFIX_TMPL_IPV6_FIELD_COUNT 12 12958354163Sflorian #define PFLOW_IPFIX_TMPL_IPV6_ID 257 13058354163Sflorian } __packed; 13158354163Sflorian 13258354163Sflorian struct pflow_ipfix_tmpl { 13358354163Sflorian struct pflow_set_header set_header; 13458354163Sflorian struct pflow_ipfix_tmpl_ipv4 ipv4_tmpl; 13558354163Sflorian struct pflow_ipfix_tmpl_ipv6 ipv6_tmpl; 13658354163Sflorian } __packed; 13758354163Sflorian 13858354163Sflorian struct pflow_ipfix_flow4 { 13958354163Sflorian u_int32_t src_ip; /* sourceIPv4Address*/ 14058354163Sflorian u_int32_t dest_ip; /* destinationIPv4Address */ 14158354163Sflorian u_int32_t if_index_in; /* ingressInterface */ 14258354163Sflorian u_int32_t if_index_out; /* egressInterface */ 14358354163Sflorian u_int64_t flow_packets; /* packetDeltaCount */ 14458354163Sflorian u_int64_t flow_octets; /* octetDeltaCount */ 14558354163Sflorian int64_t flow_start; /* flowStartMilliseconds */ 14658354163Sflorian int64_t flow_finish; /* flowEndMilliseconds */ 14758354163Sflorian u_int16_t src_port; /* sourceTransportPort */ 14858354163Sflorian u_int16_t dest_port; /* destinationTransportPort */ 14958354163Sflorian u_int8_t tos; /* ipClassOfService */ 15058354163Sflorian u_int8_t protocol; /* protocolIdentifier */ 15158354163Sflorian /* XXX padding needed? */ 15258354163Sflorian } __packed; 15358354163Sflorian 15458354163Sflorian struct pflow_ipfix_flow6 { 15558354163Sflorian struct in6_addr src_ip; /* sourceIPv6Address */ 15658354163Sflorian struct in6_addr dest_ip; /* destinationIPv6Address */ 15758354163Sflorian u_int32_t if_index_in; /* ingressInterface */ 15858354163Sflorian u_int32_t if_index_out; /* egressInterface */ 15958354163Sflorian u_int64_t flow_packets; /* packetDeltaCount */ 16058354163Sflorian u_int64_t flow_octets; /* octetDeltaCount */ 16158354163Sflorian int64_t flow_start; /* flowStartMilliseconds */ 16258354163Sflorian int64_t flow_finish; /* flowEndMilliseconds */ 163fa1d79b8Sbenno u_int16_t src_port; /* sourceTransportPort */ 164fa1d79b8Sbenno u_int16_t dest_port; /* destinationTransportPort */ 165fa1d79b8Sbenno u_int8_t tos; /* ipClassOfService */ 166fa1d79b8Sbenno u_int8_t protocol; /* protocolIdentifier */ 167fa1d79b8Sbenno /* XXX padding needed? */ 168fa1d79b8Sbenno } __packed; 169fa1d79b8Sbenno 17018ae10f7Shenning #ifdef _KERNEL 17118ae10f7Shenning 17263a0cdecSmvs #include <sys/smr.h> 17363a0cdecSmvs 174f0d16c93Smvs /* 175f0d16c93Smvs * Locks used to protect struct members and global data 176339bbf62Smvs * I immutable after creation 177339bbf62Smvs * m this pflow_softc' `sc_mtx' 178f0d16c93Smvs * p this pflow_softc' `sc_lock' 179f0d16c93Smvs */ 180f0d16c93Smvs 18118ae10f7Shenning struct pflow_softc { 182339bbf62Smvs struct mutex sc_mtx; 183f0d16c93Smvs struct rwlock sc_lock; 184f0d16c93Smvs 185*0b9ea278Smvs int sc_dying; /* [p] */ 18618ae10f7Shenning struct ifnet sc_if; 18718ae10f7Shenning 188339bbf62Smvs unsigned int sc_count; /* [m] */ 189339bbf62Smvs unsigned int sc_count4; /* [m] */ 190339bbf62Smvs unsigned int sc_count6; /* [m] */ 191339bbf62Smvs unsigned int sc_maxcount; /* [m] */ 192339bbf62Smvs unsigned int sc_maxcount4; /* [m] */ 193339bbf62Smvs unsigned int sc_maxcount6; /* [m] */ 194ccf5da69Smvs u_int32_t sc_gcounter; /* [m] */ 195339bbf62Smvs u_int32_t sc_sequence; /* [m] */ 19618ae10f7Shenning struct timeout sc_tmo; 197fa1d79b8Sbenno struct timeout sc_tmo6; 198fa1d79b8Sbenno struct timeout sc_tmo_tmpl; 199b52009cbSvisa struct mbuf_queue sc_outputqueue; 2008818ef4eSbenno struct task sc_outputtask; 201f0d16c93Smvs struct socket *so; /* [p] */ 202339bbf62Smvs struct mbuf *send_nam; /* [p] */ 203339bbf62Smvs struct sockaddr *sc_flowsrc; /* [p] */ 204339bbf62Smvs struct sockaddr *sc_flowdst; /* [p] */ 205339bbf62Smvs struct pflow_ipfix_tmpl sc_tmpl_ipfix; /* [I] */ 206339bbf62Smvs u_int8_t sc_version; /* [m] */ 207339bbf62Smvs struct mbuf *sc_mbuf; /* [m] current cumulative 208339bbf62Smvs mbuf */ 209339bbf62Smvs struct mbuf *sc_mbuf6; /* [m] current cumulative 210339bbf62Smvs mbuf */ 21163a0cdecSmvs SMR_SLIST_ENTRY(pflow_softc) sc_next; 21218ae10f7Shenning }; 21318ae10f7Shenning 21418ae10f7Shenning extern struct pflow_softc *pflowif; 21518ae10f7Shenning 21618ae10f7Shenning #endif /* _KERNEL */ 21718ae10f7Shenning 21818ae10f7Shenning struct pflow_header { 21918ae10f7Shenning u_int16_t version; 22018ae10f7Shenning u_int16_t count; 22118ae10f7Shenning u_int32_t uptime_ms; 22218ae10f7Shenning u_int32_t time_sec; 22318ae10f7Shenning u_int32_t time_nanosec; 22418ae10f7Shenning u_int32_t flow_sequence; 22518ae10f7Shenning u_int8_t engine_type; 22618ae10f7Shenning u_int8_t engine_id; 22718ae10f7Shenning u_int8_t reserved1; 22818ae10f7Shenning u_int8_t reserved2; 22918ae10f7Shenning } __packed; 23018ae10f7Shenning 23118ae10f7Shenning #define PFLOW_HDRLEN sizeof(struct pflow_header) 23218ae10f7Shenning 233fa1d79b8Sbenno struct pflow_v10_header { 234fa1d79b8Sbenno u_int16_t version; 235fa1d79b8Sbenno u_int16_t length; 236fa1d79b8Sbenno u_int32_t time_sec; 237fa1d79b8Sbenno u_int32_t flow_sequence; 238fa1d79b8Sbenno u_int32_t observation_dom; 239fa1d79b8Sbenno } __packed; 240fa1d79b8Sbenno 24158354163Sflorian #define PFLOW_IPFIX_HDRLEN sizeof(struct pflow_v10_header) 242fa1d79b8Sbenno 24318ae10f7Shenning struct pflowstats { 24418ae10f7Shenning u_int64_t pflow_flows; 24518ae10f7Shenning u_int64_t pflow_packets; 24618ae10f7Shenning u_int64_t pflow_onomem; 24718ae10f7Shenning u_int64_t pflow_oerrors; 24818ae10f7Shenning }; 24918ae10f7Shenning 250fa1d79b8Sbenno /* Supported flow protocols */ 251fa1d79b8Sbenno #define PFLOW_PROTO_5 5 /* original pflow */ 252fa1d79b8Sbenno #define PFLOW_PROTO_10 10 /* ipfix */ 253fa1d79b8Sbenno #define PFLOW_PROTO_MAX 11 254fa1d79b8Sbenno 255fa1d79b8Sbenno #define PFLOW_PROTO_DEFAULT PFLOW_PROTO_5 256fa1d79b8Sbenno 257fa1d79b8Sbenno struct pflow_protos { 258fa1d79b8Sbenno const char *ppr_name; 259fa1d79b8Sbenno u_int8_t ppr_proto; 260fa1d79b8Sbenno }; 261fa1d79b8Sbenno 262fa1d79b8Sbenno #define PFLOW_PROTOS { \ 263fa1d79b8Sbenno { "5", PFLOW_PROTO_5 }, \ 264fa1d79b8Sbenno { "10", PFLOW_PROTO_10 }, \ 265fa1d79b8Sbenno } 266fa1d79b8Sbenno 26718ae10f7Shenning /* 26818ae10f7Shenning * Configuration structure for SIOCSETPFLOW SIOCGETPFLOW 26918ae10f7Shenning */ 27018ae10f7Shenning struct pflowreq { 2713baed77aSflorian struct sockaddr_storage flowsrc; 2723baed77aSflorian struct sockaddr_storage flowdst; 27318ae10f7Shenning u_int16_t addrmask; 274fa1d79b8Sbenno u_int8_t version; 27518ae10f7Shenning #define PFLOW_MASK_SRCIP 0x01 27618ae10f7Shenning #define PFLOW_MASK_DSTIP 0x02 2773baed77aSflorian #define PFLOW_MASK_VERSION 0x04 27818ae10f7Shenning }; 27918ae10f7Shenning 28018ae10f7Shenning #ifdef _KERNEL 28118ae10f7Shenning int export_pflow(struct pf_state *); 2820aaca726Sgollo int pflow_sysctl(int *, u_int, void *, size_t *, void *, size_t); 28318ae10f7Shenning #endif /* _KERNEL */ 28418ae10f7Shenning 28518ae10f7Shenning #endif /* _NET_IF_PFLOW_H_ */ 286