1/* $OpenBSD: if_pflow.h,v 1.19 2022/11/23 15:12:27 mvs Exp $ */
2
3/*
4 * Copyright (c) 2008 Henning Brauer <henning@openbsd.org>
5 * Copyright (c) 2008 Joerg Goltermann <jg@osn.de>
6 *
7 * Permission to use, copy, modify, and distribute this software for any
8 * purpose with or without fee is hereby granted, provided that the above
9 * copyright notice and this permission notice appear in all copies.
10 *
11 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
12 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
13 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
14 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
15 * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER IN
16 * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
17 * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
18 */
19
20#ifndef _NET_IF_PFLOW_H_
21#define _NET_IF_PFLOW_H_
22
23#include <sys/cdefs.h>
24#include <sys/types.h>
25#include <sys/socket.h>
26
27#include <netinet/in.h>
28
29#ifdef _KERNEL
30#include <sys/param.h>
31#include <sys/lock.h>
32#include <sys/rmlock.h>
33#include <sys/interrupt.h>
34#include <net/if.h>
35#include <net/if_var.h>
36#include <net/if_private.h>
37#include <net/pfvar.h>
38
39#include <netinet/ip.h>
40#endif
41
42#define PFLOW_MAX_ENTRIES 128
43
44#define PFLOW_ID_LEN sizeof(u_int64_t)
45
46#define PFLOW_MAXFLOWS 30
47#define PFLOW_ENGINE_TYPE 42
48#define PFLOW_ENGINE_ID 42
49#define PFLOW_MAXBYTES 0xffffffff
50#define PFLOW_TIMEOUT 30
51#define PFLOW_TMPL_TIMEOUT 30 /* rfc 5101 10.3.6 (p.40) recommends 600 */
52
53#define PFLOW_IPFIX_TMPL_SET_ID 2
54
55/* RFC 5102 Information Element Identifiers */
56
57#define PFIX_IE_octetDeltaCount 1
58#define PFIX_IE_packetDeltaCount 2
59#define PFIX_IE_protocolIdentifier 4
60#define PFIX_IE_ipClassOfService 5
61#define PFIX_IE_sourceTransportPort 7
62#define PFIX_IE_sourceIPv4Address 8
63#define PFIX_IE_ingressInterface 10
64#define PFIX_IE_destinationTransportPort 11
65#define PFIX_IE_destinationIPv4Address 12
66#define PFIX_IE_egressInterface 14
67#define PFIX_IE_flowEndSysUpTime 21
68#define PFIX_IE_flowStartSysUpTime 22
69#define PFIX_IE_sourceIPv6Address 27
70#define PFIX_IE_destinationIPv6Address 28
71#define PFIX_IE_flowStartMilliseconds 152
72#define PFIX_IE_flowEndMilliseconds 153
73#define PFIX_IE_postNATSourceIPv4Address 225
74#define PFIX_IE_postNATDestinationIPv4Address 226
75#define PFIX_IE_postNAPTSourceTransportPort 227
76#define PFIX_IE_postNAPTDestinationTransportPort 228
77#define PFIX_IE_natEvent 230
78#define PFIX_NAT_EVENT_SESSION_CREATE 4
79#define PFIX_NAT_EVENT_SESSION_DELETE 5
80#define PFIX_IE_timeStamp 323
81
82struct pflow_flow {
83 u_int32_t src_ip;
84 u_int32_t dest_ip;
85 u_int32_t nexthop_ip;
86 u_int16_t if_index_in;
87 u_int16_t if_index_out;
88 u_int32_t flow_packets;
89 u_int32_t flow_octets;
90 u_int32_t flow_start;
91 u_int32_t flow_finish;
92 u_int16_t src_port;
93 u_int16_t dest_port;
94 u_int8_t pad1;
95 u_int8_t tcp_flags;
96 u_int8_t protocol;
97 u_int8_t tos;
98 u_int16_t src_as;
99 u_int16_t dest_as;
100 u_int8_t src_mask;
101 u_int8_t dest_mask;
102 u_int16_t pad2;
103} __packed;
104
105struct pflow_set_header {
106 u_int16_t set_id;
107 u_int16_t set_length; /* total length of the set,
108 in octets, including the set header */
109} __packed;
110
111#define PFLOW_SET_HDRLEN sizeof(struct pflow_set_header)
112
113struct pflow_tmpl_hdr {
114 u_int16_t tmpl_id;
115 u_int16_t field_count;
116} __packed;
117
118struct pflow_tmpl_fspec {
119 u_int16_t field_id;
120 u_int16_t len;
121} __packed;
122
123/* update pflow_clone_create() when changing pflow_ipfix_tmpl_ipv4 */
124struct pflow_ipfix_tmpl_ipv4 {
125 struct pflow_tmpl_hdr h;
126 struct pflow_tmpl_fspec src_ip;
127 struct pflow_tmpl_fspec dest_ip;
128 struct pflow_tmpl_fspec if_index_in;
129 struct pflow_tmpl_fspec if_index_out;
130 struct pflow_tmpl_fspec packets;
131 struct pflow_tmpl_fspec octets;
132 struct pflow_tmpl_fspec start;
133 struct pflow_tmpl_fspec finish;
134 struct pflow_tmpl_fspec src_port;
135 struct pflow_tmpl_fspec dest_port;
136 struct pflow_tmpl_fspec tos;
137 struct pflow_tmpl_fspec protocol;
138#define PFLOW_IPFIX_TMPL_IPV4_FIELD_COUNT 12
139#define PFLOW_IPFIX_TMPL_IPV4_ID 256
140} __packed;
141
142/* update pflow_clone_create() when changing pflow_ipfix_tmpl_v6 */
143struct pflow_ipfix_tmpl_ipv6 {
144 struct pflow_tmpl_hdr h;
145 struct pflow_tmpl_fspec src_ip;
146 struct pflow_tmpl_fspec dest_ip;
147 struct pflow_tmpl_fspec if_index_in;
148 struct pflow_tmpl_fspec if_index_out;
149 struct pflow_tmpl_fspec packets;
150 struct pflow_tmpl_fspec octets;
151 struct pflow_tmpl_fspec start;
152 struct pflow_tmpl_fspec finish;
153 struct pflow_tmpl_fspec src_port;
154 struct pflow_tmpl_fspec dest_port;
155 struct pflow_tmpl_fspec tos;
156 struct pflow_tmpl_fspec protocol;
157#define PFLOW_IPFIX_TMPL_IPV6_FIELD_COUNT 12
158#define PFLOW_IPFIX_TMPL_IPV6_ID 257
159} __packed;
160
161struct pflow_ipfix_tmpl_nat44 {
162 struct pflow_tmpl_hdr h;
163 struct pflow_tmpl_fspec timestamp;
164 struct pflow_tmpl_fspec nat_event;
165 struct pflow_tmpl_fspec protocol;
166 struct pflow_tmpl_fspec src_ip;
167 struct pflow_tmpl_fspec src_port;
168 struct pflow_tmpl_fspec postnat_src_ip;
169 struct pflow_tmpl_fspec postnat_src_port;
170 struct pflow_tmpl_fspec dst_ip;
171 struct pflow_tmpl_fspec dst_port;
172 struct pflow_tmpl_fspec postnat_dst_ip;
173 struct pflow_tmpl_fspec postnat_dst_port;
174#define PFLOW_IPFIX_TMPL_NAT44_FIELD_COUNT 11
175#define PFLOW_IPFIX_TMPL_NAT44_ID 258
176};
177
178struct pflow_ipfix_tmpl {
179 struct pflow_set_header set_header;
180 struct pflow_ipfix_tmpl_ipv4 ipv4_tmpl;
181 struct pflow_ipfix_tmpl_ipv6 ipv6_tmpl;
182 struct pflow_ipfix_tmpl_nat44 nat44_tmpl;
183} __packed;
184
185struct pflow_ipfix_flow4 {
186 u_int32_t src_ip; /* sourceIPv4Address*/
187 u_int32_t dest_ip; /* destinationIPv4Address */
188 u_int32_t if_index_in; /* ingressInterface */
189 u_int32_t if_index_out; /* egressInterface */
190 u_int64_t flow_packets; /* packetDeltaCount */
191 u_int64_t flow_octets; /* octetDeltaCount */
192 int64_t flow_start; /* flowStartMilliseconds */
193 int64_t flow_finish; /* flowEndMilliseconds */
194 u_int16_t src_port; /* sourceTransportPort */
195 u_int16_t dest_port; /* destinationTransportPort */
196 u_int8_t tos; /* ipClassOfService */
197 u_int8_t protocol; /* protocolIdentifier */
198 /* XXX padding needed? */
199} __packed;
200
201struct pflow_ipfix_flow6 {
202 struct in6_addr src_ip; /* sourceIPv6Address */
203 struct in6_addr dest_ip; /* destinationIPv6Address */
204 u_int32_t if_index_in; /* ingressInterface */
205 u_int32_t if_index_out; /* egressInterface */
206 u_int64_t flow_packets; /* packetDeltaCount */
207 u_int64_t flow_octets; /* octetDeltaCount */
208 int64_t flow_start; /* flowStartMilliseconds */
209 int64_t flow_finish; /* flowEndMilliseconds */
210 u_int16_t src_port; /* sourceTransportPort */
211 u_int16_t dest_port; /* destinationTransportPort */
212 u_int8_t tos; /* ipClassOfService */
213 u_int8_t protocol; /* protocolIdentifier */
214 /* XXX padding needed? */
215} __packed;
216
217struct pflow_ipfix_nat4 {
218 u_int64_t timestamp; /* timeStamp */
219 u_int8_t nat_event; /* natEvent */
220 u_int8_t protocol; /* protocolIdentifier */
221 u_int32_t src_ip; /* sourceIPv4Address */
222 u_int16_t src_port; /* sourceTransportPort */
223 u_int32_t postnat_src_ip; /* postNATSourceIPv4Address */
224 u_int16_t postnat_src_port;/* postNAPTSourceTransportPort */
225 u_int32_t dest_ip; /* destinationIPv4Address */
226 u_int16_t dest_port; /* destinationTransportPort */
227 u_int32_t postnat_dest_ip;/* postNATDestinationIPv4Address */
228 u_int16_t postnat_dest_port;/* postNAPTDestinationTransportPort */
229} __packed;
230
231#ifdef _KERNEL
232
233struct pflow_softc {
234 int sc_id;
235
236 struct mtx sc_lock;
237
238 int sc_dying; /* [N] */
239 struct vnet *sc_vnet;
240
241 unsigned int sc_count;
242 unsigned int sc_count4;
243 unsigned int sc_count6;
244 unsigned int sc_count_nat4;
245 unsigned int sc_maxcount;
246 unsigned int sc_maxcount4;
247 unsigned int sc_maxcount6;
248 unsigned int sc_maxcount_nat4;
249 u_int32_t sc_gcounter;
250 u_int32_t sc_sequence;
251 struct callout sc_tmo;
252 struct callout sc_tmo6;
253 struct callout sc_tmo_nat4;
254 struct callout sc_tmo_tmpl;
255 struct intr_event *sc_swi_ie;
256 void *sc_swi_cookie;
257 struct mbufq sc_outputqueue;
258 struct task sc_outputtask;
259 struct socket *so; /* [p] */
260 struct sockaddr *sc_flowsrc;
261 struct sockaddr *sc_flowdst;
262 struct pflow_ipfix_tmpl sc_tmpl_ipfix;
263 u_int8_t sc_version;
264 u_int32_t sc_observation_dom;
265 struct mbuf *sc_mbuf; /* current cumulative mbuf */
266 struct mbuf *sc_mbuf6; /* current cumulative mbuf */
267 struct mbuf *sc_mbuf_nat4;
268 CK_LIST_ENTRY(pflow_softc) sc_next;
269 struct epoch_context sc_epoch_ctx;
270};
271
272#endif /* _KERNEL */
273
274struct pflow_header {
275 u_int16_t version;
276 u_int16_t count;
277 u_int32_t uptime_ms;
278 u_int32_t time_sec;
279 u_int32_t time_nanosec;
280 u_int32_t flow_sequence;
281 u_int8_t engine_type;
282 u_int8_t engine_id;
283 u_int8_t reserved1;
284 u_int8_t reserved2;
285} __packed;
286
287#define PFLOW_HDRLEN sizeof(struct pflow_header)
288
289struct pflow_v10_header {
290 u_int16_t version;
291 u_int16_t length;
292 u_int32_t time_sec;
293 u_int32_t flow_sequence;
294 u_int32_t observation_dom;
295} __packed;
296
297#define PFLOW_IPFIX_HDRLEN sizeof(struct pflow_v10_header)
298
299struct pflowstats {
300 u_int64_t pflow_flows;
301 u_int64_t pflow_packets;
302 u_int64_t pflow_onomem;
303 u_int64_t pflow_oerrors;
304};
305
306/* Supported flow protocols */
307#define PFLOW_PROTO_5 5 /* original pflow */
308#define PFLOW_PROTO_10 10 /* ipfix */
309#define PFLOW_PROTO_MAX 11
310
311#define PFLOW_PROTO_DEFAULT PFLOW_PROTO_5
312
313struct pflow_protos {
314 const char *ppr_name;
315 u_int8_t ppr_proto;
316};
317
318#define PFLOW_PROTOS { \
319 { "5", PFLOW_PROTO_5 }, \
320 { "10", PFLOW_PROTO_10 }, \
321}
322
323#define PFLOWNL_FAMILY_NAME "pflow"
324
325enum {
326 PFLOWNL_CMD_UNSPEC = 0,
327 PFLOWNL_CMD_LIST = 1,
328 PFLOWNL_CMD_CREATE = 2,
329 PFLOWNL_CMD_DEL = 3,
330 PFLOWNL_CMD_SET = 4,
331 PFLOWNL_CMD_GET = 5,
332 __PFLOWNL_CMD_MAX,
333};
334#define PFLOWNL_CMD_MAX (__PFLOWNL_CMD_MAX - 1)
335
336enum pflow_list_type_t {
337 PFLOWNL_L_UNSPEC,
338 PFLOWNL_L_ID = 1, /* u32 */
339};
340
341enum pflow_create_type_t {
342 PFLOWNL_CREATE_UNSPEC,
343 PFLOWNL_CREATE_ID = 1, /* u32 */
344};
345
346enum pflow_del_type_t {
347 PFLOWNL_DEL_UNSPEC,
348 PFLOWNL_DEL_ID = 1, /* u32 */
349};
350
351enum pflow_addr_type_t {
352 PFLOWNL_ADDR_UNSPEC,
353 PFLOWNL_ADDR_FAMILY = 1, /* u8 */
354 PFLOWNL_ADDR_PORT = 2, /* u16 */
355 PFLOWNL_ADDR_IP = 3, /* struct in_addr */
356 PFLOWNL_ADDR_IP6 = 4, /* struct in6_addr */
357};
358
359enum pflow_get_type_t {
360 PFLOWNL_GET_UNSPEC,
361 PFLOWNL_GET_ID = 1, /* u32 */
362 PFLOWNL_GET_VERSION = 2, /* u16 */
363 PFLOWNL_GET_SRC = 3, /* struct sockaddr_storage */
364 PFLOWNL_GET_DST = 4, /* struct sockaddr_storage */
365 PFLOWNL_GET_OBSERVATION_DOMAIN = 5, /* u32 */
366 PFLOWNL_GET_SOCKET_STATUS = 6, /* u8 */
367};
368
369enum pflow_set_type_t {
370 PFLOWNL_SET_UNSPEC,
371 PFLOWNL_SET_ID = 1, /* u32 */
372 PFLOWNL_SET_VERSION = 2, /* u16 */
373 PFLOWNL_SET_SRC = 3, /* struct sockaddr_storage */
374 PFLOWNL_SET_DST = 4, /* struct sockaddr_storage */
375 PFLOWNL_SET_OBSERVATION_DOMAIN = 5, /* u32 */
376};
377
378#ifdef _KERNEL
379int pflow_sysctl(int *, u_int, void *, size_t *, void *, size_t);
380#endif /* _KERNEL */
381
382#endif /* _NET_IF_PFLOW_H_ */