xref: /openbsd-src/sys/net/if_pflow.h (revision 0b9ea2785a44171b5f54de1d7806f4a554e50e47)
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