xref: /freebsd/sys/netgraph/netflow/ng_netflow.h (revision 830940567b49bb0c08dfaed40418999e76616909)
1 /*-
2  * Copyright (c) 2004-2005 Gleb Smirnoff <glebius@FreeBSD.org>
3  * Copyright (c) 2001-2003 Roman V. Palagin <romanp@unshadow.net>
4  * All rights reserved.
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions
8  * are met:
9  * 1. Redistributions of source code must retain the above copyright
10  *    notice, this list of conditions and the following disclaimer.
11  * 2. Redistributions in binary form must reproduce the above copyright
12  *    notice, this list of conditions and the following disclaimer in the
13  *    documentation and/or other materials provided with the distribution.
14  *
15  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
16  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
19  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
21  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
25  * SUCH DAMAGE.
26  *
27  *	 $SourceForge: ng_netflow.h,v 1.26 2004/09/04 15:44:55 glebius Exp $
28  *	 $FreeBSD$
29  */
30 
31 #ifndef	_NG_NETFLOW_H_
32 #define	_NG_NETFLOW_H_
33 
34 #define NG_NETFLOW_NODE_TYPE	"netflow"
35 #define NGM_NETFLOW_COOKIE	1137078102
36 
37 #define	NG_NETFLOW_MAXIFACES	USHRT_MAX
38 
39 /* Hook names */
40 
41 #define	NG_NETFLOW_HOOK_DATA	"iface"
42 #define	NG_NETFLOW_HOOK_OUT	"out"
43 #define NG_NETFLOW_HOOK_EXPORT	"export"
44 
45 /* Netgraph commands understood by netflow node */
46 enum {
47     NGM_NETFLOW_INFO = 1|NGM_READONLY|NGM_HASREPLY,	/* get node info */
48     NGM_NETFLOW_IFINFO = 2|NGM_READONLY|NGM_HASREPLY,	/* get iface info */
49     NGM_NETFLOW_SHOW = 3|NGM_READONLY|NGM_HASREPLY,	/* show ip cache flow */
50     NGM_NETFLOW_SETDLT		= 4,	/* set data-link type */
51     NGM_NETFLOW_SETIFINDEX	= 5, 	/* set interface index */
52     NGM_NETFLOW_SETTIMEOUTS	= 6, 	/* set active/inactive flow timeouts */
53     NGM_NETFLOW_SETCONFIG	= 7, 	/* set flow generation options */
54 };
55 
56 /* This structure is returned by the NGM_NETFLOW_INFO message */
57 struct ng_netflow_info {
58 	uint64_t	nfinfo_bytes;		/* accounted bytes */
59 	uint32_t	nfinfo_packets;		/* accounted packets */
60 	uint32_t	nfinfo_used;		/* used cache records */
61 	uint32_t	nfinfo_alloc_failed;	/* failed allocations */
62 	uint32_t	nfinfo_export_failed;	/* failed exports */
63 	uint32_t	nfinfo_act_exp;		/* active expiries */
64 	uint32_t	nfinfo_inact_exp;	/* inactive expiries */
65 	uint32_t	nfinfo_inact_t;		/* flow inactive timeout */
66 	uint32_t	nfinfo_act_t;		/* flow active timeout */
67 };
68 
69 /* This structure is returned by the NGM_NETFLOW_IFINFO message */
70 struct ng_netflow_ifinfo {
71 	uint32_t	ifinfo_packets;	/* number of packets for this iface */
72 	uint8_t		ifinfo_dlt;	/* Data Link Type, DLT_XXX */
73 #define	MAXDLTNAMELEN	20
74 	u_int16_t	ifinfo_index;	/* connected iface index */
75 	uint32_t	conf;
76 };
77 
78 
79 /* This structure is passed to NGM_NETFLOW_SETDLT message */
80 struct ng_netflow_setdlt {
81 	uint16_t iface;		/* which iface dlt change */
82 	uint8_t  dlt;			/* DLT_XXX from bpf.h */
83 };
84 
85 /* This structure is passed to NGM_NETFLOW_SETIFINDEX */
86 struct ng_netflow_setifindex {
87 	u_int16_t iface;		/* which iface index change */
88 	u_int16_t index;		/* new index */
89 };
90 
91 /* This structure is passed to NGM_NETFLOW_SETTIMEOUTS */
92 struct ng_netflow_settimeouts {
93 	uint32_t	inactive_timeout;	/* flow inactive timeout */
94 	uint32_t	active_timeout;		/* flow active timeout */
95 };
96 
97 #define NG_NETFLOW_CONF_INGRESS		1
98 #define NG_NETFLOW_CONF_EGRESS		2
99 #define NG_NETFLOW_CONF_ONCE		4
100 #define NG_NETFLOW_CONF_THISONCE	8
101 
102 /* This structure is passed to NGM_NETFLOW_SETCONFIG */
103 struct ng_netflow_setconfig {
104 	u_int16_t iface;		/* which iface config change */
105 	u_int32_t conf;			/* new config */
106 };
107 
108 /* This is unique data, which identifies flow */
109 struct flow_rec {
110 	struct in_addr	r_src;
111 	struct in_addr	r_dst;
112 	union {
113 		struct {
114 			uint16_t	s_port;	/* source TCP/UDP port */
115 			uint16_t	d_port; /* destination TCP/UDP port */
116 		} dir;
117 		uint32_t both;
118 	} ports;
119 	union {
120 		struct {
121 			u_char		prot;	/* IP protocol */
122 			u_char		tos;	/* IP TOS */
123 			uint16_t	i_ifx;	/* input interface index */
124 		} i;
125 		uint32_t all;
126 	} misc;
127 };
128 
129 #define	r_ip_p	misc.i.prot
130 #define	r_tos	misc.i.tos
131 #define	r_i_ifx	misc.i.i_ifx
132 #define r_misc	misc.all
133 #define r_ports	ports.both
134 #define r_sport	ports.dir.s_port
135 #define r_dport	ports.dir.d_port
136 
137 /* A flow entry which accumulates statistics */
138 struct flow_entry_data {
139 	struct flow_rec		r;
140 	struct in_addr		next_hop;
141 	uint16_t		fle_o_ifx;	/* output interface index */
142 #define				fle_i_ifx	r.misc.i.i_ifx
143 	uint8_t		dst_mask;	/* destination route mask bits */
144 	uint8_t		src_mask;	/* source route mask bits */
145 	u_long			packets;
146 	u_long			bytes;
147 	long			first;	/* uptime on first packet */
148 	long			last;	/* uptime on last packet */
149 	u_char			tcp_flags;	/* cumulative OR */
150 };
151 
152 /*
153  * How many flow records we will transfer at once
154  * without overflowing socket receive buffer
155  */
156 #define NREC_AT_ONCE		1000
157 #define NGRESP_SIZE		(sizeof(struct ngnf_flows) + (NREC_AT_ONCE * \
158 				sizeof(struct flow_entry_data)))
159 #define SORCVBUF_SIZE		(NGRESP_SIZE + 2 * sizeof(struct ng_mesg))
160 
161 /* This struct is returned to userland, when "show cache ip flow" */
162 struct ngnf_flows {
163 	uint32_t		nentries;
164 	uint32_t		last;
165 	struct flow_entry_data	entries[0];
166 };
167 
168 /* Everything below is for kernel */
169 
170 #ifdef _KERNEL
171 
172 struct flow_entry {
173 	struct flow_entry_data	f;
174 	TAILQ_ENTRY(flow_entry)	fle_hash;	/* entries in hash slot */
175 };
176 
177 /* Parsing declarations */
178 
179 /* Parse the info structure */
180 #define	NG_NETFLOW_INFO_TYPE	{			\
181 	{ "Bytes",	&ng_parse_uint64_type },	\
182 	{ "Packets",	&ng_parse_uint32_type },	\
183 	{ "Records used",	&ng_parse_uint32_type },\
184 	{ "Failed allocations",	&ng_parse_uint32_type },\
185 	{ "Failed exports",	&ng_parse_uint32_type },\
186 	{ "Active expiries",	&ng_parse_uint32_type },\
187 	{ "Inactive expiries",	&ng_parse_uint32_type },\
188 	{ "Inactive timeout",	&ng_parse_uint32_type },\
189 	{ "Active timeout",	&ng_parse_uint32_type },\
190 	{ NULL }					\
191 }
192 
193 /* Parse the ifinfo structure */
194 #define NG_NETFLOW_IFINFO_TYPE	{			\
195 	{ "packets",	&ng_parse_uint32_type },	\
196 	{ "data link type", &ng_parse_uint8_type },	\
197 	{ "index", &ng_parse_uint16_type },		\
198 	{ "conf", &ng_parse_uint32_type },		\
199 	{ NULL }					\
200 }
201 
202 /* Parse the setdlt structure */
203 #define	NG_NETFLOW_SETDLT_TYPE {			\
204 	{ "iface",	&ng_parse_uint16_type },	\
205 	{ "dlt",	&ng_parse_uint8_type  },	\
206 	{ NULL }					\
207 }
208 
209 /* Parse the setifindex structure */
210 #define	NG_NETFLOW_SETIFINDEX_TYPE {			\
211 	{ "iface",	&ng_parse_uint16_type },	\
212 	{ "index",	&ng_parse_uint16_type },	\
213 	{ NULL }					\
214 }
215 
216 /* Parse the settimeouts structure */
217 #define NG_NETFLOW_SETTIMEOUTS_TYPE {			\
218 	{ "inactive",	&ng_parse_uint32_type },	\
219 	{ "active",	&ng_parse_uint32_type },	\
220 	{ NULL }					\
221 }
222 
223 /* Parse the setifindex structure */
224 #define	NG_NETFLOW_SETCONFIG_TYPE {			\
225 	{ "iface",	&ng_parse_uint16_type },	\
226 	{ "conf",	&ng_parse_uint32_type },	\
227 	{ NULL }					\
228 }
229 
230 /* Private hook data */
231 struct ng_netflow_iface {
232 	hook_p		hook;		/* NULL when disconnected */
233 	hook_p		out;		/* NULL when no bypass hook */
234 	struct ng_netflow_ifinfo	info;
235 };
236 
237 typedef struct ng_netflow_iface *iface_p;
238 typedef struct ng_netflow_ifinfo *ifinfo_p;
239 
240 /* Structure describing our flow engine */
241 struct netflow {
242 	node_p			node;		/* link to the node itself */
243 	hook_p			export;		/* export data goes there */
244 
245 	struct ng_netflow_info	info;
246 	struct callout		exp_callout;	/* expiry periodic job */
247 
248 	/*
249 	 * Flow entries are allocated in uma(9) zone zone. They are
250 	 * indexed by hash hash. Each hash element consist of tailqueue
251 	 * head and mutex to protect this element.
252 	 */
253 #define	CACHESIZE			(65536*4)
254 #define	CACHELOWAT			(CACHESIZE * 3/4)
255 #define	CACHEHIGHWAT			(CACHESIZE * 9/10)
256 	uma_zone_t		zone;
257 	struct flow_hash_entry	*hash;
258 
259 	/*
260 	 * NetFlow data export
261 	 *
262 	 * export_item is a data item, it has an mbuf with cluster
263 	 * attached to it. A thread detaches export_item from priv
264 	 * and works with it. If the export is full it is sent, and
265 	 * a new one is allocated. Before exiting thread re-attaches
266 	 * its current item back to priv. If there is item already,
267 	 * current incomplete datagram is sent.
268 	 * export_mtx is used for attaching/detaching.
269 	 */
270 	item_p			export_item;
271 	struct mtx		export_mtx;
272 	uint32_t		flow_seq;	/* current flow sequence */
273 
274 	struct ng_netflow_iface	ifaces[NG_NETFLOW_MAXIFACES];
275 };
276 
277 typedef struct netflow *priv_p;
278 
279 /* Header of a small list in hash cell */
280 struct flow_hash_entry {
281 	struct mtx		mtx;
282 	TAILQ_HEAD(fhead, flow_entry) head;
283 };
284 
285 #define	ERROUT(x)	{ error = (x); goto done; }
286 
287 #define MTAG_NETFLOW		1221656444
288 #define MTAG_NETFLOW_CALLED	0
289 
290 /* Prototypes for netflow.c */
291 int	ng_netflow_cache_init(priv_p);
292 void	ng_netflow_cache_flush(priv_p);
293 void	ng_netflow_copyinfo(priv_p, struct ng_netflow_info *);
294 timeout_t ng_netflow_expire;
295 int	ng_netflow_flow_add(priv_p, struct ip *, unsigned int src_if_index);
296 int	ng_netflow_flow_show(priv_p, uint32_t last, struct ng_mesg *);
297 
298 #endif	/* _KERNEL */
299 #endif	/* _NG_NETFLOW_H_ */
300