xref: /openbsd/sys/net/if_pflow.c (revision 938ff1ae)
1 /*	$OpenBSD: if_pflow.c,v 1.109 2023/12/23 10:52:54 bluhm Exp $	*/
2 
3 /*
4  * Copyright (c) 2011 Florian Obser <florian@narrans.de>
5  * Copyright (c) 2011 Sebastian Benoit <benoit-lists@fb12.de>
6  * Copyright (c) 2008 Henning Brauer <henning@openbsd.org>
7  * Copyright (c) 2008 Joerg Goltermann <jg@osn.de>
8  *
9  * Permission to use, copy, modify, and distribute this software for any
10  * purpose with or without fee is hereby granted, provided that the above
11  * copyright notice and this permission notice appear in all copies.
12  *
13  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
14  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
15  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
16  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
17  * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER IN
18  * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
19  * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
20  */
21 
22 #include <sys/param.h>
23 #include <sys/malloc.h>
24 #include <sys/systm.h>
25 #include <sys/mbuf.h>
26 #include <sys/socket.h>
27 #include <sys/timeout.h>
28 #include <sys/ioctl.h>
29 #include <sys/kernel.h>
30 #include <sys/socketvar.h>
31 #include <sys/sysctl.h>
32 #include <sys/mutex.h>
33 
34 #include <net/if.h>
35 #include <net/if_types.h>
36 #include <net/bpf.h>
37 #include <net/route.h>
38 #include <netinet/in.h>
39 #include <netinet/if_ether.h>
40 #include <netinet/tcp.h>
41 
42 #include <netinet/ip.h>
43 #include <netinet/ip_icmp.h>
44 #include <netinet/ip_var.h>
45 #include <netinet/udp.h>
46 #include <netinet/udp_var.h>
47 #include <netinet/in_pcb.h>
48 
49 #include <net/pfvar.h>
50 #include <net/pfvar_priv.h>
51 #include <net/if_pflow.h>
52 
53 #include "bpfilter.h"
54 #include "pflow.h"
55 
56 #define PFLOW_MINMTU	\
57     (sizeof(struct pflow_header) + sizeof(struct pflow_flow))
58 
59 #ifdef PFLOWDEBUG
60 #define DPRINTF(x)	do { printf x ; } while (0)
61 #else
62 #define DPRINTF(x)
63 #endif
64 
65 SMR_SLIST_HEAD(, pflow_softc) pflowif_list;
66 
67 enum pflowstat_counters {
68 	pflow_flows,
69 	pflow_packets,
70 	pflow_onomem,
71 	pflow_oerrors,
72 	pflow_ncounters,
73 };
74 
75 struct cpumem *pflow_counters;
76 
77 static inline void
pflowstat_inc(enum pflowstat_counters c)78 pflowstat_inc(enum pflowstat_counters c)
79 {
80 	counters_inc(pflow_counters, c);
81 }
82 
83 void	pflowattach(int);
84 int	pflow_output(struct ifnet *ifp, struct mbuf *m, struct sockaddr *dst,
85 	struct rtentry *rt);
86 void	pflow_output_process(void *);
87 int	pflow_clone_create(struct if_clone *, int);
88 int	pflow_clone_destroy(struct ifnet *);
89 int	pflow_set(struct pflow_softc *, struct pflowreq *);
90 int	pflow_calc_mtu(struct pflow_softc *, int, int);
91 void	pflow_setmtu(struct pflow_softc *, int);
92 int	pflowvalidsockaddr(const struct sockaddr *, int);
93 int	pflowioctl(struct ifnet *, u_long, caddr_t);
94 
95 struct mbuf	*pflow_get_mbuf(struct pflow_softc *, u_int16_t);
96 void	pflow_flush(struct pflow_softc *);
97 int	pflow_sendout_v5(struct pflow_softc *);
98 int	pflow_sendout_ipfix(struct pflow_softc *, sa_family_t);
99 int	pflow_sendout_ipfix_tmpl(struct pflow_softc *);
100 int	pflow_sendout_mbuf(struct pflow_softc *, struct mbuf *);
101 void	pflow_timeout(void *);
102 void	pflow_timeout6(void *);
103 void	pflow_timeout_tmpl(void *);
104 void	copy_flow_data(struct pflow_flow *, struct pflow_flow *,
105 	struct pf_state *, struct pf_state_key *, int, int);
106 void	copy_flow_ipfix_4_data(struct pflow_ipfix_flow4 *,
107 	struct pflow_ipfix_flow4 *, struct pf_state *, struct pf_state_key *,
108 	struct pflow_softc *, int, int);
109 void	copy_flow_ipfix_6_data(struct pflow_ipfix_flow6 *,
110 	struct pflow_ipfix_flow6 *, struct pf_state *, struct pf_state_key *,
111 	struct pflow_softc *, int, int);
112 int	pflow_pack_flow(struct pf_state *, struct pf_state_key *,
113 	struct pflow_softc *);
114 int	pflow_pack_flow_ipfix(struct pf_state *, struct pf_state_key *,
115 	struct pflow_softc *);
116 int	export_pflow_if(struct pf_state*, struct pf_state_key *,
117 	struct pflow_softc *);
118 int	copy_flow_to_m(struct pflow_flow *flow, struct pflow_softc *sc);
119 int	copy_flow_ipfix_4_to_m(struct pflow_ipfix_flow4 *flow,
120 	struct pflow_softc *sc);
121 int	copy_flow_ipfix_6_to_m(struct pflow_ipfix_flow6 *flow,
122 	struct pflow_softc *sc);
123 
124 struct if_clone	pflow_cloner =
125     IF_CLONE_INITIALIZER("pflow", pflow_clone_create,
126     pflow_clone_destroy);
127 
128 void
pflowattach(int npflow)129 pflowattach(int npflow)
130 {
131 	SMR_SLIST_INIT(&pflowif_list);
132 	pflow_counters = counters_alloc(pflow_ncounters);
133 	if_clone_attach(&pflow_cloner);
134 }
135 
136 int
pflow_output(struct ifnet * ifp,struct mbuf * m,struct sockaddr * dst,struct rtentry * rt)137 pflow_output(struct ifnet *ifp, struct mbuf *m, struct sockaddr *dst,
138 	struct rtentry *rt)
139 {
140 	m_freem(m);	/* drop packet */
141 	return (EAFNOSUPPORT);
142 }
143 
144 void
pflow_output_process(void * arg)145 pflow_output_process(void *arg)
146 {
147 	struct mbuf_list ml;
148 	struct pflow_softc *sc = arg;
149 	struct mbuf *m;
150 
151 	mq_delist(&sc->sc_outputqueue, &ml);
152 	rw_enter_read(&sc->sc_lock);
153 	while ((m = ml_dequeue(&ml)) != NULL) {
154 		pflow_sendout_mbuf(sc, m);
155 	}
156 	rw_exit_read(&sc->sc_lock);
157 }
158 
159 int
pflow_clone_create(struct if_clone * ifc,int unit)160 pflow_clone_create(struct if_clone *ifc, int unit)
161 {
162 	struct ifnet		*ifp;
163 	struct pflow_softc	*pflowif;
164 
165 	pflowif = malloc(sizeof(*pflowif), M_DEVBUF, M_WAITOK|M_ZERO);
166 	rw_init(&pflowif->sc_lock, "pflowlk");
167 	mtx_init(&pflowif->sc_mtx, IPL_MPFLOOR);
168 	MGET(pflowif->send_nam, M_WAIT, MT_SONAME);
169 	pflowif->sc_version = PFLOW_PROTO_DEFAULT;
170 
171 	/* ipfix template init */
172 	bzero(&pflowif->sc_tmpl_ipfix,sizeof(pflowif->sc_tmpl_ipfix));
173 	pflowif->sc_tmpl_ipfix.set_header.set_id =
174 	    htons(PFLOW_IPFIX_TMPL_SET_ID);
175 	pflowif->sc_tmpl_ipfix.set_header.set_length =
176 	    htons(sizeof(struct pflow_ipfix_tmpl));
177 
178 	/* ipfix IPv4 template */
179 	pflowif->sc_tmpl_ipfix.ipv4_tmpl.h.tmpl_id =
180 	    htons(PFLOW_IPFIX_TMPL_IPV4_ID);
181 	pflowif->sc_tmpl_ipfix.ipv4_tmpl.h.field_count
182 	    = htons(PFLOW_IPFIX_TMPL_IPV4_FIELD_COUNT);
183 	pflowif->sc_tmpl_ipfix.ipv4_tmpl.src_ip.field_id =
184 	    htons(PFIX_IE_sourceIPv4Address);
185 	pflowif->sc_tmpl_ipfix.ipv4_tmpl.src_ip.len = htons(4);
186 	pflowif->sc_tmpl_ipfix.ipv4_tmpl.dest_ip.field_id =
187 	    htons(PFIX_IE_destinationIPv4Address);
188 	pflowif->sc_tmpl_ipfix.ipv4_tmpl.dest_ip.len = htons(4);
189 	pflowif->sc_tmpl_ipfix.ipv4_tmpl.if_index_in.field_id =
190 	    htons(PFIX_IE_ingressInterface);
191 	pflowif->sc_tmpl_ipfix.ipv4_tmpl.if_index_in.len = htons(4);
192 	pflowif->sc_tmpl_ipfix.ipv4_tmpl.if_index_out.field_id =
193 	    htons(PFIX_IE_egressInterface);
194 	pflowif->sc_tmpl_ipfix.ipv4_tmpl.if_index_out.len = htons(4);
195 	pflowif->sc_tmpl_ipfix.ipv4_tmpl.packets.field_id =
196 	    htons(PFIX_IE_packetDeltaCount);
197 	pflowif->sc_tmpl_ipfix.ipv4_tmpl.packets.len = htons(8);
198 	pflowif->sc_tmpl_ipfix.ipv4_tmpl.octets.field_id =
199 	    htons(PFIX_IE_octetDeltaCount);
200 	pflowif->sc_tmpl_ipfix.ipv4_tmpl.octets.len = htons(8);
201 	pflowif->sc_tmpl_ipfix.ipv4_tmpl.start.field_id =
202 	    htons(PFIX_IE_flowStartMilliseconds);
203 	pflowif->sc_tmpl_ipfix.ipv4_tmpl.start.len = htons(8);
204 	pflowif->sc_tmpl_ipfix.ipv4_tmpl.finish.field_id =
205 	    htons(PFIX_IE_flowEndMilliseconds);
206 	pflowif->sc_tmpl_ipfix.ipv4_tmpl.finish.len = htons(8);
207 	pflowif->sc_tmpl_ipfix.ipv4_tmpl.src_port.field_id =
208 	    htons(PFIX_IE_sourceTransportPort);
209 	pflowif->sc_tmpl_ipfix.ipv4_tmpl.src_port.len = htons(2);
210 	pflowif->sc_tmpl_ipfix.ipv4_tmpl.dest_port.field_id =
211 	    htons(PFIX_IE_destinationTransportPort);
212 	pflowif->sc_tmpl_ipfix.ipv4_tmpl.dest_port.len = htons(2);
213 	pflowif->sc_tmpl_ipfix.ipv4_tmpl.tos.field_id =
214 	    htons(PFIX_IE_ipClassOfService);
215 	pflowif->sc_tmpl_ipfix.ipv4_tmpl.tos.len = htons(1);
216 	pflowif->sc_tmpl_ipfix.ipv4_tmpl.protocol.field_id =
217 	    htons(PFIX_IE_protocolIdentifier);
218 	pflowif->sc_tmpl_ipfix.ipv4_tmpl.protocol.len = htons(1);
219 
220 	/* ipfix IPv6 template */
221 	pflowif->sc_tmpl_ipfix.ipv6_tmpl.h.tmpl_id =
222 	    htons(PFLOW_IPFIX_TMPL_IPV6_ID);
223 	pflowif->sc_tmpl_ipfix.ipv6_tmpl.h.field_count =
224 	    htons(PFLOW_IPFIX_TMPL_IPV6_FIELD_COUNT);
225 	pflowif->sc_tmpl_ipfix.ipv6_tmpl.src_ip.field_id =
226 	    htons(PFIX_IE_sourceIPv6Address);
227 	pflowif->sc_tmpl_ipfix.ipv6_tmpl.src_ip.len = htons(16);
228 	pflowif->sc_tmpl_ipfix.ipv6_tmpl.dest_ip.field_id =
229 	    htons(PFIX_IE_destinationIPv6Address);
230 	pflowif->sc_tmpl_ipfix.ipv6_tmpl.dest_ip.len = htons(16);
231 	pflowif->sc_tmpl_ipfix.ipv6_tmpl.if_index_in.field_id =
232 	    htons(PFIX_IE_ingressInterface);
233 	pflowif->sc_tmpl_ipfix.ipv6_tmpl.if_index_in.len = htons(4);
234 	pflowif->sc_tmpl_ipfix.ipv6_tmpl.if_index_out.field_id =
235 	    htons(PFIX_IE_egressInterface);
236 	pflowif->sc_tmpl_ipfix.ipv6_tmpl.if_index_out.len = htons(4);
237 	pflowif->sc_tmpl_ipfix.ipv6_tmpl.packets.field_id =
238 	    htons(PFIX_IE_packetDeltaCount);
239 	pflowif->sc_tmpl_ipfix.ipv6_tmpl.packets.len = htons(8);
240 	pflowif->sc_tmpl_ipfix.ipv6_tmpl.octets.field_id =
241 	    htons(PFIX_IE_octetDeltaCount);
242 	pflowif->sc_tmpl_ipfix.ipv6_tmpl.octets.len = htons(8);
243 	pflowif->sc_tmpl_ipfix.ipv6_tmpl.start.field_id =
244 	    htons(PFIX_IE_flowStartMilliseconds);
245 	pflowif->sc_tmpl_ipfix.ipv6_tmpl.start.len = htons(8);
246 	pflowif->sc_tmpl_ipfix.ipv6_tmpl.finish.field_id =
247 	    htons(PFIX_IE_flowEndMilliseconds);
248 	pflowif->sc_tmpl_ipfix.ipv6_tmpl.finish.len = htons(8);
249 	pflowif->sc_tmpl_ipfix.ipv6_tmpl.src_port.field_id =
250 	    htons(PFIX_IE_sourceTransportPort);
251 	pflowif->sc_tmpl_ipfix.ipv6_tmpl.src_port.len = htons(2);
252 	pflowif->sc_tmpl_ipfix.ipv6_tmpl.dest_port.field_id =
253 	    htons(PFIX_IE_destinationTransportPort);
254 	pflowif->sc_tmpl_ipfix.ipv6_tmpl.dest_port.len = htons(2);
255 	pflowif->sc_tmpl_ipfix.ipv6_tmpl.tos.field_id =
256 	    htons(PFIX_IE_ipClassOfService);
257 	pflowif->sc_tmpl_ipfix.ipv6_tmpl.tos.len = htons(1);
258 	pflowif->sc_tmpl_ipfix.ipv6_tmpl.protocol.field_id =
259 	    htons(PFIX_IE_protocolIdentifier);
260 	pflowif->sc_tmpl_ipfix.ipv6_tmpl.protocol.len = htons(1);
261 
262 	ifp = &pflowif->sc_if;
263 	snprintf(ifp->if_xname, sizeof ifp->if_xname, "pflow%d", unit);
264 	ifp->if_softc = pflowif;
265 	ifp->if_ioctl = pflowioctl;
266 	ifp->if_output = pflow_output;
267 	ifp->if_start = NULL;
268 	ifp->if_xflags = IFXF_CLONED;
269 	ifp->if_type = IFT_PFLOW;
270 	ifp->if_hdrlen = PFLOW_HDRLEN;
271 	ifp->if_flags = IFF_UP;
272 	ifp->if_flags &= ~IFF_RUNNING;	/* not running, need receiver */
273 	mq_init(&pflowif->sc_outputqueue, 8192, IPL_SOFTNET);
274 	pflow_setmtu(pflowif, ETHERMTU);
275 
276 	timeout_set_proc(&pflowif->sc_tmo, pflow_timeout, pflowif);
277 	timeout_set_proc(&pflowif->sc_tmo6, pflow_timeout6, pflowif);
278 	timeout_set_proc(&pflowif->sc_tmo_tmpl, pflow_timeout_tmpl, pflowif);
279 
280 	task_set(&pflowif->sc_outputtask, pflow_output_process, pflowif);
281 
282 	if_counters_alloc(ifp);
283 	if_attach(ifp);
284 	if_alloc_sadl(ifp);
285 
286 	/* Insert into list of pflows */
287 	KERNEL_ASSERT_LOCKED();
288 	SMR_SLIST_INSERT_HEAD_LOCKED(&pflowif_list, pflowif, sc_next);
289 	return (0);
290 }
291 
292 int
pflow_clone_destroy(struct ifnet * ifp)293 pflow_clone_destroy(struct ifnet *ifp)
294 {
295 	struct pflow_softc	*sc = ifp->if_softc;
296 	int			 error;
297 
298 	error = 0;
299 
300 	rw_enter_write(&sc->sc_lock);
301 	sc->sc_dying = 1;
302 	rw_exit_write(&sc->sc_lock);
303 
304 	KERNEL_ASSERT_LOCKED();
305 	SMR_SLIST_REMOVE_LOCKED(&pflowif_list, sc, pflow_softc, sc_next);
306 	smr_barrier();
307 
308 	timeout_del(&sc->sc_tmo);
309 	timeout_del(&sc->sc_tmo6);
310 	timeout_del(&sc->sc_tmo_tmpl);
311 
312 	pflow_flush(sc);
313 	task_del(net_tq(ifp->if_index), &sc->sc_outputtask);
314 	taskq_barrier(net_tq(ifp->if_index));
315 	mq_purge(&sc->sc_outputqueue);
316 	m_freem(sc->send_nam);
317 	if (sc->so != NULL) {
318 		error = soclose(sc->so, MSG_DONTWAIT);
319 		sc->so = NULL;
320 	}
321 	if (sc->sc_flowdst != NULL)
322 		free(sc->sc_flowdst, M_DEVBUF, sc->sc_flowdst->sa_len);
323 	if (sc->sc_flowsrc != NULL)
324 		free(sc->sc_flowsrc, M_DEVBUF, sc->sc_flowsrc->sa_len);
325 	if_detach(ifp);
326 	free(sc, M_DEVBUF, sizeof(*sc));
327 	return (error);
328 }
329 
330 int
pflowvalidsockaddr(const struct sockaddr * sa,int ignore_port)331 pflowvalidsockaddr(const struct sockaddr *sa, int ignore_port)
332 {
333 	struct sockaddr_in6	*sin6;
334 	struct sockaddr_in	*sin;
335 
336 	if (sa == NULL)
337 		return (0);
338 	switch(sa->sa_family) {
339 	case AF_INET:
340 		sin = (struct sockaddr_in*) sa;
341 		return (sin->sin_addr.s_addr != INADDR_ANY &&
342 		    (ignore_port || sin->sin_port != 0));
343 	case AF_INET6:
344 		sin6 = (struct sockaddr_in6*) sa;
345 		return (!IN6_IS_ADDR_UNSPECIFIED(&sin6->sin6_addr) &&
346 		    (ignore_port || sin6->sin6_port != 0));
347 	default:
348 		return (0);
349 	}
350 }
351 
352 int
pflow_set(struct pflow_softc * sc,struct pflowreq * pflowr)353 pflow_set(struct pflow_softc *sc, struct pflowreq *pflowr)
354 {
355 	struct proc		*p = curproc;
356 	struct socket		*so;
357 	struct sockaddr		*sa;
358 	int			 error = 0;
359 
360 	if (pflowr->addrmask & PFLOW_MASK_VERSION) {
361 		switch(pflowr->version) {
362 		case PFLOW_PROTO_5:
363 		case PFLOW_PROTO_10:
364 			break;
365 		default:
366 			return(EINVAL);
367 		}
368 	}
369 
370 	rw_assert_wrlock(&sc->sc_lock);
371 
372 	pflow_flush(sc);
373 
374 	if (pflowr->addrmask & PFLOW_MASK_DSTIP) {
375 		if (sc->sc_flowdst != NULL &&
376 		    sc->sc_flowdst->sa_family != pflowr->flowdst.ss_family) {
377 			free(sc->sc_flowdst, M_DEVBUF, sc->sc_flowdst->sa_len);
378 			sc->sc_flowdst = NULL;
379 			if (sc->so != NULL) {
380 				soclose(sc->so, MSG_DONTWAIT);
381 				sc->so = NULL;
382 			}
383 		}
384 
385 		switch (pflowr->flowdst.ss_family) {
386 		case AF_INET:
387 			if (sc->sc_flowdst == NULL) {
388 				if ((sc->sc_flowdst = malloc(
389 				    sizeof(struct sockaddr_in),
390 				    M_DEVBUF,  M_NOWAIT)) == NULL)
391 					return (ENOMEM);
392 			}
393 			memcpy(sc->sc_flowdst, &pflowr->flowdst,
394 			    sizeof(struct sockaddr_in));
395 			sc->sc_flowdst->sa_len = sizeof(struct
396 			    sockaddr_in);
397 			break;
398 		case AF_INET6:
399 			if (sc->sc_flowdst == NULL) {
400 				if ((sc->sc_flowdst = malloc(
401 				    sizeof(struct sockaddr_in6),
402 				    M_DEVBUF, M_NOWAIT)) == NULL)
403 					return (ENOMEM);
404 			}
405 			memcpy(sc->sc_flowdst, &pflowr->flowdst,
406 			    sizeof(struct sockaddr_in6));
407 			sc->sc_flowdst->sa_len = sizeof(struct
408 			    sockaddr_in6);
409 			break;
410 		default:
411 			break;
412 		}
413 
414 		if (sc->sc_flowdst != NULL) {
415 			sc->send_nam->m_len = sc->sc_flowdst->sa_len;
416 			sa = mtod(sc->send_nam, struct sockaddr *);
417 			memcpy(sa, sc->sc_flowdst, sc->sc_flowdst->sa_len);
418 		}
419 	}
420 
421 	if (pflowr->addrmask & PFLOW_MASK_SRCIP) {
422 		if (sc->sc_flowsrc != NULL)
423 			free(sc->sc_flowsrc, M_DEVBUF, sc->sc_flowsrc->sa_len);
424 		sc->sc_flowsrc = NULL;
425 		if (sc->so != NULL) {
426 			soclose(sc->so, MSG_DONTWAIT);
427 			sc->so = NULL;
428 		}
429 		switch(pflowr->flowsrc.ss_family) {
430 		case AF_INET:
431 			if ((sc->sc_flowsrc = malloc(
432 			    sizeof(struct sockaddr_in),
433 			    M_DEVBUF, M_NOWAIT)) == NULL)
434 				return (ENOMEM);
435 			memcpy(sc->sc_flowsrc, &pflowr->flowsrc,
436 			    sizeof(struct sockaddr_in));
437 			sc->sc_flowsrc->sa_len = sizeof(struct
438 			    sockaddr_in);
439 			break;
440 		case AF_INET6:
441 			if ((sc->sc_flowsrc = malloc(
442 			    sizeof(struct sockaddr_in6),
443 			    M_DEVBUF, M_NOWAIT)) == NULL)
444 				return (ENOMEM);
445 			memcpy(sc->sc_flowsrc, &pflowr->flowsrc,
446 			    sizeof(struct sockaddr_in6));
447 			sc->sc_flowsrc->sa_len = sizeof(struct
448 			    sockaddr_in6);
449 			break;
450 		default:
451 			break;
452 		}
453 	}
454 
455 	if (sc->so == NULL) {
456 		if (pflowvalidsockaddr(sc->sc_flowdst, 0)) {
457 			error = socreate(sc->sc_flowdst->sa_family,
458 			    &so, SOCK_DGRAM, 0);
459 			if (error)
460 				return (error);
461 			if (pflowvalidsockaddr(sc->sc_flowsrc, 1)) {
462 				struct mbuf *m;
463 
464 				MGET(m, M_WAIT, MT_SONAME);
465 				m->m_len = sc->sc_flowsrc->sa_len;
466 				sa = mtod(m, struct sockaddr *);
467 				memcpy(sa, sc->sc_flowsrc,
468 				    sc->sc_flowsrc->sa_len);
469 
470 				solock(so);
471 				error = sobind(so, m, p);
472 				sounlock(so);
473 				m_freem(m);
474 				if (error) {
475 					soclose(so, MSG_DONTWAIT);
476 					return (error);
477 				}
478 			}
479 			sc->so = so;
480 		}
481 	} else if (!pflowvalidsockaddr(sc->sc_flowdst, 0)) {
482 		soclose(sc->so, MSG_DONTWAIT);
483 		sc->so = NULL;
484 	}
485 
486 	NET_LOCK();
487 	mtx_enter(&sc->sc_mtx);
488 
489 	/* error check is above */
490 	if (pflowr->addrmask & PFLOW_MASK_VERSION)
491 		sc->sc_version = pflowr->version;
492 
493 	pflow_setmtu(sc, ETHERMTU);
494 
495 	switch (sc->sc_version) {
496 	case PFLOW_PROTO_5:
497 		timeout_del(&sc->sc_tmo6);
498 		timeout_del(&sc->sc_tmo_tmpl);
499 		break;
500 	case PFLOW_PROTO_10:
501 		timeout_add_sec(&sc->sc_tmo_tmpl, PFLOW_TMPL_TIMEOUT);
502 		break;
503 	default: /* NOTREACHED */
504 		break;
505 	}
506 
507 	mtx_leave(&sc->sc_mtx);
508 	NET_UNLOCK();
509 
510 	return (0);
511 }
512 
513 int
pflowioctl(struct ifnet * ifp,u_long cmd,caddr_t data)514 pflowioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
515 {
516 	struct proc		*p = curproc;
517 	struct pflow_softc	*sc = ifp->if_softc;
518 	struct ifreq		*ifr = (struct ifreq *)data;
519 	struct pflowreq		 pflowr;
520 	int			 error = 0;
521 
522 	switch (cmd) {
523 	case SIOCSIFADDR:
524 	case SIOCSIFDSTADDR:
525 	case SIOCSIFFLAGS:
526 	case SIOCSIFMTU:
527 	case SIOCGETPFLOW:
528 	case SIOCSETPFLOW:
529 		break;
530 	default:
531 		return (ENOTTY);
532 	}
533 
534 	/* XXXSMP: enforce lock order */
535 	NET_UNLOCK();
536 	rw_enter_write(&sc->sc_lock);
537 
538 	if (sc->sc_dying) {
539 		error = ENXIO;
540 		goto out;
541 	}
542 
543 	switch (cmd) {
544 	case SIOCSIFADDR:
545 	case SIOCSIFDSTADDR:
546 	case SIOCSIFFLAGS:
547 		NET_LOCK();
548 		if ((ifp->if_flags & IFF_UP) && sc->so != NULL) {
549 			ifp->if_flags |= IFF_RUNNING;
550 			mtx_enter(&sc->sc_mtx);
551 			/* send templates on startup */
552 			if (sc->sc_version == PFLOW_PROTO_10)
553 				pflow_sendout_ipfix_tmpl(sc);
554 			mtx_leave(&sc->sc_mtx);
555 		} else
556 			ifp->if_flags &= ~IFF_RUNNING;
557 		NET_UNLOCK();
558 		break;
559 
560 	case SIOCSIFMTU:
561 		if (ifr->ifr_mtu < PFLOW_MINMTU) {
562 			error = EINVAL;
563 			goto out;
564 		}
565 		if (ifr->ifr_mtu > MCLBYTES)
566 			ifr->ifr_mtu = MCLBYTES;
567 		NET_LOCK();
568 		if (ifr->ifr_mtu < ifp->if_mtu)
569 			pflow_flush(sc);
570 		mtx_enter(&sc->sc_mtx);
571 		pflow_setmtu(sc, ifr->ifr_mtu);
572 		mtx_leave(&sc->sc_mtx);
573 		NET_UNLOCK();
574 		break;
575 
576 	case SIOCGETPFLOW:
577 		bzero(&pflowr, sizeof(pflowr));
578 
579 		if (sc->sc_flowsrc != NULL)
580 			memcpy(&pflowr.flowsrc, sc->sc_flowsrc,
581 			    sc->sc_flowsrc->sa_len);
582 		if (sc->sc_flowdst != NULL)
583 			memcpy(&pflowr.flowdst, sc->sc_flowdst,
584 			    sc->sc_flowdst->sa_len);
585 		mtx_enter(&sc->sc_mtx);
586 		pflowr.version = sc->sc_version;
587 		mtx_leave(&sc->sc_mtx);
588 
589 		if ((error = copyout(&pflowr, ifr->ifr_data, sizeof(pflowr))))
590 			goto out;
591 		break;
592 
593 	case SIOCSETPFLOW:
594 		if ((error = suser(p)) != 0)
595 			goto out;
596 		if ((error = copyin(ifr->ifr_data, &pflowr, sizeof(pflowr))))
597 			goto out;
598 
599 		error = pflow_set(sc, &pflowr);
600 		if (error != 0)
601 			goto out;
602 
603 		NET_LOCK();
604 		if ((ifp->if_flags & IFF_UP) && sc->so != NULL) {
605 			ifp->if_flags |= IFF_RUNNING;
606 			mtx_enter(&sc->sc_mtx);
607 			if (sc->sc_version == PFLOW_PROTO_10)
608 				pflow_sendout_ipfix_tmpl(sc);
609 			mtx_leave(&sc->sc_mtx);
610 		} else
611 			ifp->if_flags &= ~IFF_RUNNING;
612 		NET_UNLOCK();
613 
614 		break;
615 	}
616 
617 out:
618 	rw_exit_write(&sc->sc_lock);
619 	NET_LOCK();
620 
621 	return (error);
622 }
623 
624 int
pflow_calc_mtu(struct pflow_softc * sc,int mtu,int hdrsz)625 pflow_calc_mtu(struct pflow_softc *sc, int mtu, int hdrsz)
626 {
627 	sc->sc_maxcount4 = (mtu - hdrsz -
628 	    sizeof(struct udpiphdr)) / sizeof(struct pflow_ipfix_flow4);
629 	sc->sc_maxcount6 = (mtu - hdrsz -
630 	    sizeof(struct udpiphdr)) / sizeof(struct pflow_ipfix_flow6);
631 	if (sc->sc_maxcount4 > PFLOW_MAXFLOWS)
632 		sc->sc_maxcount4 = PFLOW_MAXFLOWS;
633 	if (sc->sc_maxcount6 > PFLOW_MAXFLOWS)
634 		sc->sc_maxcount6 = PFLOW_MAXFLOWS;
635 	return (hdrsz + sizeof(struct udpiphdr) +
636 	    MIN(sc->sc_maxcount4 * sizeof(struct pflow_ipfix_flow4),
637 	    sc->sc_maxcount6 * sizeof(struct pflow_ipfix_flow6)));
638 }
639 
640 void
pflow_setmtu(struct pflow_softc * sc,int mtu_req)641 pflow_setmtu(struct pflow_softc *sc, int mtu_req)
642 {
643 	int	mtu;
644 
645 	mtu = mtu_req;
646 
647 	switch (sc->sc_version) {
648 	case PFLOW_PROTO_5:
649 		sc->sc_maxcount = (mtu - sizeof(struct pflow_header) -
650 		    sizeof(struct udpiphdr)) / sizeof(struct pflow_flow);
651 		if (sc->sc_maxcount > PFLOW_MAXFLOWS)
652 		    sc->sc_maxcount = PFLOW_MAXFLOWS;
653 		sc->sc_if.if_mtu = sizeof(struct pflow_header) +
654 		    sizeof(struct udpiphdr) +
655 		    sc->sc_maxcount * sizeof(struct pflow_flow);
656 		break;
657 	case PFLOW_PROTO_10:
658 		sc->sc_if.if_mtu =
659 		    pflow_calc_mtu(sc, mtu, sizeof(struct pflow_v10_header));
660 		break;
661 	default: /* NOTREACHED */
662 		break;
663 	}
664 }
665 
666 struct mbuf *
pflow_get_mbuf(struct pflow_softc * sc,u_int16_t set_id)667 pflow_get_mbuf(struct pflow_softc *sc, u_int16_t set_id)
668 {
669 	struct pflow_set_header	 set_hdr;
670 	struct pflow_header	 h;
671 	struct mbuf		*m;
672 
673 	MUTEX_ASSERT_LOCKED(&sc->sc_mtx);
674 
675 	MGETHDR(m, M_DONTWAIT, MT_DATA);
676 	if (m == NULL) {
677 		pflowstat_inc(pflow_onomem);
678 		return (NULL);
679 	}
680 
681 	MCLGET(m, M_DONTWAIT);
682 	if ((m->m_flags & M_EXT) == 0) {
683 		m_free(m);
684 		pflowstat_inc(pflow_onomem);
685 		return (NULL);
686 	}
687 
688 	m->m_len = m->m_pkthdr.len = 0;
689 	m->m_pkthdr.ph_ifidx = 0;
690 
691 	if (sc == NULL)		/* get only a new empty mbuf */
692 		return (m);
693 
694 	switch (sc->sc_version) {
695 	case PFLOW_PROTO_5:
696 		/* populate pflow_header */
697 		h.reserved1 = 0;
698 		h.reserved2 = 0;
699 		h.count = 0;
700 		h.version = htons(PFLOW_PROTO_5);
701 		h.flow_sequence = htonl(sc->sc_gcounter);
702 		h.engine_type = PFLOW_ENGINE_TYPE;
703 		h.engine_id = PFLOW_ENGINE_ID;
704 		m_copyback(m, 0, PFLOW_HDRLEN, &h, M_NOWAIT);
705 
706 		sc->sc_count = 0;
707 		timeout_add_sec(&sc->sc_tmo, PFLOW_TIMEOUT);
708 		break;
709 	case PFLOW_PROTO_10:
710 		/* populate pflow_set_header */
711 		set_hdr.set_length = 0;
712 		set_hdr.set_id = htons(set_id);
713 		m_copyback(m, 0, PFLOW_SET_HDRLEN, &set_hdr, M_NOWAIT);
714 		break;
715 	default: /* NOTREACHED */
716 		break;
717 	}
718 
719 	return (m);
720 }
721 
722 void
copy_flow_data(struct pflow_flow * flow1,struct pflow_flow * flow2,struct pf_state * st,struct pf_state_key * sk,int src,int dst)723 copy_flow_data(struct pflow_flow *flow1, struct pflow_flow *flow2,
724     struct pf_state *st, struct pf_state_key *sk, int src, int dst)
725 {
726 	flow1->src_ip = flow2->dest_ip = sk->addr[src].v4.s_addr;
727 	flow1->src_port = flow2->dest_port = sk->port[src];
728 	flow1->dest_ip = flow2->src_ip = sk->addr[dst].v4.s_addr;
729 	flow1->dest_port = flow2->src_port = sk->port[dst];
730 
731 	flow1->dest_as = flow2->src_as =
732 	    flow1->src_as = flow2->dest_as = 0;
733 	flow1->if_index_in = htons(st->if_index_in);
734 	flow1->if_index_out = htons(st->if_index_out);
735 	flow2->if_index_in = htons(st->if_index_out);
736 	flow2->if_index_out = htons(st->if_index_in);
737 	flow1->dest_mask = flow2->src_mask =
738 	    flow1->src_mask = flow2->dest_mask = 0;
739 
740 	flow1->flow_packets = htonl(st->packets[0]);
741 	flow2->flow_packets = htonl(st->packets[1]);
742 	flow1->flow_octets = htonl(st->bytes[0]);
743 	flow2->flow_octets = htonl(st->bytes[1]);
744 
745 	/*
746 	 * Pretend the flow was created or expired when the machine came up
747 	 * when creation is in the future of the last time a package was seen
748 	 * or was created / expired before this machine came up due to pfsync.
749 	 */
750 	flow1->flow_start = flow2->flow_start = st->creation < 0 ||
751 	    st->creation > st->expire ? htonl(0) : htonl(st->creation * 1000);
752 	flow1->flow_finish = flow2->flow_finish = st->expire < 0 ? htonl(0) :
753 	    htonl(st->expire * 1000);
754 	flow1->tcp_flags = flow2->tcp_flags = 0;
755 	flow1->protocol = flow2->protocol = sk->proto;
756 	flow1->tos = flow2->tos = st->rule.ptr->tos;
757 }
758 
759 void
copy_flow_ipfix_4_data(struct pflow_ipfix_flow4 * flow1,struct pflow_ipfix_flow4 * flow2,struct pf_state * st,struct pf_state_key * sk,struct pflow_softc * sc,int src,int dst)760 copy_flow_ipfix_4_data(struct pflow_ipfix_flow4 *flow1,
761     struct pflow_ipfix_flow4 *flow2, struct pf_state *st,
762     struct pf_state_key *sk, struct pflow_softc *sc, int src, int dst)
763 {
764 	flow1->src_ip = flow2->dest_ip = sk->addr[src].v4.s_addr;
765 	flow1->src_port = flow2->dest_port = sk->port[src];
766 	flow1->dest_ip = flow2->src_ip = sk->addr[dst].v4.s_addr;
767 	flow1->dest_port = flow2->src_port = sk->port[dst];
768 
769 	flow1->if_index_in = htonl(st->if_index_in);
770 	flow1->if_index_out = htonl(st->if_index_out);
771 	flow2->if_index_in = htonl(st->if_index_out);
772 	flow2->if_index_out = htonl(st->if_index_in);
773 
774 	flow1->flow_packets = htobe64(st->packets[0]);
775 	flow2->flow_packets = htobe64(st->packets[1]);
776 	flow1->flow_octets = htobe64(st->bytes[0]);
777 	flow2->flow_octets = htobe64(st->bytes[1]);
778 
779 	/*
780 	 * Pretend the flow was created when the machine came up when creation
781 	 * is in the future of the last time a package was seen due to pfsync.
782 	 */
783 	if (st->creation > st->expire)
784 		flow1->flow_start = flow2->flow_start = htobe64((gettime() -
785 		    getuptime())*1000);
786 	else
787 		flow1->flow_start = flow2->flow_start = htobe64((gettime() -
788 		    (getuptime() - st->creation))*1000);
789 	flow1->flow_finish = flow2->flow_finish = htobe64((gettime() -
790 	    (getuptime() - st->expire))*1000);
791 
792 	flow1->protocol = flow2->protocol = sk->proto;
793 	flow1->tos = flow2->tos = st->rule.ptr->tos;
794 }
795 
796 void
copy_flow_ipfix_6_data(struct pflow_ipfix_flow6 * flow1,struct pflow_ipfix_flow6 * flow2,struct pf_state * st,struct pf_state_key * sk,struct pflow_softc * sc,int src,int dst)797 copy_flow_ipfix_6_data(struct pflow_ipfix_flow6 *flow1,
798     struct pflow_ipfix_flow6 *flow2, struct pf_state *st,
799     struct pf_state_key *sk, struct pflow_softc *sc, int src, int dst)
800 {
801 	bcopy(&sk->addr[src].v6, &flow1->src_ip, sizeof(flow1->src_ip));
802 	bcopy(&sk->addr[src].v6, &flow2->dest_ip, sizeof(flow2->dest_ip));
803 	flow1->src_port = flow2->dest_port = sk->port[src];
804 	bcopy(&sk->addr[dst].v6, &flow1->dest_ip, sizeof(flow1->dest_ip));
805 	bcopy(&sk->addr[dst].v6, &flow2->src_ip, sizeof(flow2->src_ip));
806 	flow1->dest_port = flow2->src_port = sk->port[dst];
807 
808 	flow1->if_index_in = htonl(st->if_index_in);
809 	flow1->if_index_out = htonl(st->if_index_out);
810 	flow2->if_index_in = htonl(st->if_index_out);
811 	flow2->if_index_out = htonl(st->if_index_in);
812 
813 	flow1->flow_packets = htobe64(st->packets[0]);
814 	flow2->flow_packets = htobe64(st->packets[1]);
815 	flow1->flow_octets = htobe64(st->bytes[0]);
816 	flow2->flow_octets = htobe64(st->bytes[1]);
817 
818 	/*
819 	 * Pretend the flow was created when the machine came up when creation
820 	 * is in the future of the last time a package was seen due to pfsync.
821 	 */
822 	if (st->creation > st->expire)
823 		flow1->flow_start = flow2->flow_start = htobe64((gettime() -
824 		    getuptime())*1000);
825 	else
826 		flow1->flow_start = flow2->flow_start = htobe64((gettime() -
827 		    (getuptime() - st->creation))*1000);
828 	flow1->flow_finish = flow2->flow_finish = htobe64((gettime() -
829 	    (getuptime() - st->expire))*1000);
830 
831 	flow1->protocol = flow2->protocol = sk->proto;
832 	flow1->tos = flow2->tos = st->rule.ptr->tos;
833 }
834 
835 int
export_pflow(struct pf_state * st)836 export_pflow(struct pf_state *st)
837 {
838 	struct pflow_softc	*sc = NULL;
839 	struct pf_state_key	*sk;
840 
841 	sk = st->key[st->direction == PF_IN ? PF_SK_WIRE : PF_SK_STACK];
842 
843 	SMR_SLIST_FOREACH(sc, &pflowif_list, sc_next) {
844 		mtx_enter(&sc->sc_mtx);
845 		switch (sc->sc_version) {
846 		case PFLOW_PROTO_5:
847 			if (sk->af == AF_INET)
848 				export_pflow_if(st, sk, sc);
849 			break;
850 		case PFLOW_PROTO_10:
851 			if (sk->af == AF_INET || sk->af == AF_INET6)
852 				export_pflow_if(st, sk, sc);
853 			break;
854 		default: /* NOTREACHED */
855 			break;
856 		}
857 		mtx_leave(&sc->sc_mtx);
858 	}
859 
860 	return (0);
861 }
862 
863 int
export_pflow_if(struct pf_state * st,struct pf_state_key * sk,struct pflow_softc * sc)864 export_pflow_if(struct pf_state *st, struct pf_state_key *sk,
865     struct pflow_softc *sc)
866 {
867 	struct pf_state		 pfs_copy;
868 	struct ifnet		*ifp = &sc->sc_if;
869 	u_int64_t		 bytes[2];
870 	int			 ret = 0;
871 
872 	if (!(ifp->if_flags & IFF_RUNNING))
873 		return (0);
874 
875 	if (sc->sc_version == PFLOW_PROTO_10)
876 		return (pflow_pack_flow_ipfix(st, sk, sc));
877 
878 	/* PFLOW_PROTO_5 */
879 	if ((st->bytes[0] < (u_int64_t)PFLOW_MAXBYTES)
880 	    && (st->bytes[1] < (u_int64_t)PFLOW_MAXBYTES))
881 		return (pflow_pack_flow(st, sk, sc));
882 
883 	/* flow > PFLOW_MAXBYTES need special handling */
884 	bcopy(st, &pfs_copy, sizeof(pfs_copy));
885 	bytes[0] = pfs_copy.bytes[0];
886 	bytes[1] = pfs_copy.bytes[1];
887 
888 	while (bytes[0] > PFLOW_MAXBYTES) {
889 		pfs_copy.bytes[0] = PFLOW_MAXBYTES;
890 		pfs_copy.bytes[1] = 0;
891 
892 		if ((ret = pflow_pack_flow(&pfs_copy, sk, sc)) != 0)
893 			return (ret);
894 		if ((bytes[0] - PFLOW_MAXBYTES) > 0)
895 			bytes[0] -= PFLOW_MAXBYTES;
896 	}
897 
898 	while (bytes[1] > (u_int64_t)PFLOW_MAXBYTES) {
899 		pfs_copy.bytes[1] = PFLOW_MAXBYTES;
900 		pfs_copy.bytes[0] = 0;
901 
902 		if ((ret = pflow_pack_flow(&pfs_copy, sk, sc)) != 0)
903 			return (ret);
904 		if ((bytes[1] - PFLOW_MAXBYTES) > 0)
905 			bytes[1] -= PFLOW_MAXBYTES;
906 	}
907 
908 	pfs_copy.bytes[0] = bytes[0];
909 	pfs_copy.bytes[1] = bytes[1];
910 
911 	return (pflow_pack_flow(&pfs_copy, sk, sc));
912 }
913 
914 int
copy_flow_to_m(struct pflow_flow * flow,struct pflow_softc * sc)915 copy_flow_to_m(struct pflow_flow *flow, struct pflow_softc *sc)
916 {
917 	int		ret = 0;
918 
919 	MUTEX_ASSERT_LOCKED(&sc->sc_mtx);
920 
921 	if (sc->sc_mbuf == NULL) {
922 		if ((sc->sc_mbuf = pflow_get_mbuf(sc, 0)) == NULL)
923 			return (ENOBUFS);
924 	}
925 	m_copyback(sc->sc_mbuf, PFLOW_HDRLEN +
926 	    (sc->sc_count * sizeof(struct pflow_flow)),
927 	    sizeof(struct pflow_flow), flow, M_NOWAIT);
928 
929 	pflowstat_inc(pflow_flows);
930 	sc->sc_gcounter++;
931 	sc->sc_count++;
932 
933 	if (sc->sc_count >= sc->sc_maxcount)
934 		ret = pflow_sendout_v5(sc);
935 
936 	return(ret);
937 }
938 
939 int
copy_flow_ipfix_4_to_m(struct pflow_ipfix_flow4 * flow,struct pflow_softc * sc)940 copy_flow_ipfix_4_to_m(struct pflow_ipfix_flow4 *flow, struct pflow_softc *sc)
941 {
942 	int		ret = 0;
943 
944 	MUTEX_ASSERT_LOCKED(&sc->sc_mtx);
945 
946 	if (sc->sc_mbuf == NULL) {
947 		if ((sc->sc_mbuf =
948 		    pflow_get_mbuf(sc, PFLOW_IPFIX_TMPL_IPV4_ID)) == NULL) {
949 			return (ENOBUFS);
950 		}
951 		sc->sc_count4 = 0;
952 		timeout_add_sec(&sc->sc_tmo, PFLOW_TIMEOUT);
953 	}
954 	m_copyback(sc->sc_mbuf, PFLOW_SET_HDRLEN +
955 	    (sc->sc_count4 * sizeof(struct pflow_ipfix_flow4)),
956 	    sizeof(struct pflow_ipfix_flow4), flow, M_NOWAIT);
957 
958 	pflowstat_inc(pflow_flows);
959 	sc->sc_gcounter++;
960 	sc->sc_count4++;
961 
962 	if (sc->sc_count4 >= sc->sc_maxcount4)
963 		ret = pflow_sendout_ipfix(sc, AF_INET);
964 	return(ret);
965 }
966 
967 int
copy_flow_ipfix_6_to_m(struct pflow_ipfix_flow6 * flow,struct pflow_softc * sc)968 copy_flow_ipfix_6_to_m(struct pflow_ipfix_flow6 *flow, struct pflow_softc *sc)
969 {
970 	int		ret = 0;
971 
972 	MUTEX_ASSERT_LOCKED(&sc->sc_mtx);
973 
974 	if (sc->sc_mbuf6 == NULL) {
975 		if ((sc->sc_mbuf6 =
976 		    pflow_get_mbuf(sc, PFLOW_IPFIX_TMPL_IPV6_ID)) == NULL) {
977 			return (ENOBUFS);
978 		}
979 		sc->sc_count6 = 0;
980 		timeout_add_sec(&sc->sc_tmo6, PFLOW_TIMEOUT);
981 	}
982 	m_copyback(sc->sc_mbuf6, PFLOW_SET_HDRLEN +
983 	    (sc->sc_count6 * sizeof(struct pflow_ipfix_flow6)),
984 	    sizeof(struct pflow_ipfix_flow6), flow, M_NOWAIT);
985 
986 	pflowstat_inc(pflow_flows);
987 	sc->sc_gcounter++;
988 	sc->sc_count6++;
989 
990 	if (sc->sc_count6 >= sc->sc_maxcount6)
991 		ret = pflow_sendout_ipfix(sc, AF_INET6);
992 
993 	return(ret);
994 }
995 
996 int
pflow_pack_flow(struct pf_state * st,struct pf_state_key * sk,struct pflow_softc * sc)997 pflow_pack_flow(struct pf_state *st, struct pf_state_key *sk,
998     struct pflow_softc *sc)
999 {
1000 	struct pflow_flow	 flow1;
1001 	struct pflow_flow	 flow2;
1002 	int			 ret = 0;
1003 
1004 	bzero(&flow1, sizeof(flow1));
1005 	bzero(&flow2, sizeof(flow2));
1006 
1007 	if (st->direction == PF_OUT)
1008 		copy_flow_data(&flow1, &flow2, st, sk, 1, 0);
1009 	else
1010 		copy_flow_data(&flow1, &flow2, st, sk, 0, 1);
1011 
1012 	if (st->bytes[0] != 0) /* first flow from state */
1013 		ret = copy_flow_to_m(&flow1, sc);
1014 
1015 	if (st->bytes[1] != 0) /* second flow from state */
1016 		ret = copy_flow_to_m(&flow2, sc);
1017 
1018 	return (ret);
1019 }
1020 
1021 int
pflow_pack_flow_ipfix(struct pf_state * st,struct pf_state_key * sk,struct pflow_softc * sc)1022 pflow_pack_flow_ipfix(struct pf_state *st, struct pf_state_key *sk,
1023     struct pflow_softc *sc)
1024 {
1025 	struct pflow_ipfix_flow4	 flow4_1, flow4_2;
1026 	struct pflow_ipfix_flow6	 flow6_1, flow6_2;
1027 	int				 ret = 0;
1028 	if (sk->af == AF_INET) {
1029 		bzero(&flow4_1, sizeof(flow4_1));
1030 		bzero(&flow4_2, sizeof(flow4_2));
1031 
1032 		if (st->direction == PF_OUT)
1033 			copy_flow_ipfix_4_data(&flow4_1, &flow4_2, st, sk, sc,
1034 			    1, 0);
1035 		else
1036 			copy_flow_ipfix_4_data(&flow4_1, &flow4_2, st, sk, sc,
1037 			    0, 1);
1038 
1039 		if (st->bytes[0] != 0) /* first flow from state */
1040 			ret = copy_flow_ipfix_4_to_m(&flow4_1, sc);
1041 
1042 		if (st->bytes[1] != 0) /* second flow from state */
1043 			ret = copy_flow_ipfix_4_to_m(&flow4_2, sc);
1044 	} else if (sk->af == AF_INET6) {
1045 		bzero(&flow6_1, sizeof(flow6_1));
1046 		bzero(&flow6_2, sizeof(flow6_2));
1047 
1048 		if (st->direction == PF_OUT)
1049 			copy_flow_ipfix_6_data(&flow6_1, &flow6_2, st, sk, sc,
1050 			    1, 0);
1051 		else
1052 			copy_flow_ipfix_6_data(&flow6_1, &flow6_2, st, sk, sc,
1053 			    0, 1);
1054 
1055 		if (st->bytes[0] != 0) /* first flow from state */
1056 			ret = copy_flow_ipfix_6_to_m(&flow6_1, sc);
1057 
1058 		if (st->bytes[1] != 0) /* second flow from state */
1059 			ret = copy_flow_ipfix_6_to_m(&flow6_2, sc);
1060 	}
1061 	return (ret);
1062 }
1063 
1064 void
pflow_timeout(void * v)1065 pflow_timeout(void *v)
1066 {
1067 	struct pflow_softc	*sc = v;
1068 
1069 	mtx_enter(&sc->sc_mtx);
1070 	switch (sc->sc_version) {
1071 	case PFLOW_PROTO_5:
1072 		pflow_sendout_v5(sc);
1073 		break;
1074 	case PFLOW_PROTO_10:
1075 		pflow_sendout_ipfix(sc, AF_INET);
1076 		break;
1077 	default: /* NOTREACHED */
1078 		break;
1079 	}
1080 	mtx_leave(&sc->sc_mtx);
1081 }
1082 
1083 void
pflow_timeout6(void * v)1084 pflow_timeout6(void *v)
1085 {
1086 	struct pflow_softc	*sc = v;
1087 
1088 	mtx_enter(&sc->sc_mtx);
1089 	pflow_sendout_ipfix(sc, AF_INET6);
1090 	mtx_leave(&sc->sc_mtx);
1091 }
1092 
1093 void
pflow_timeout_tmpl(void * v)1094 pflow_timeout_tmpl(void *v)
1095 {
1096 	struct pflow_softc	*sc = v;
1097 
1098 	mtx_enter(&sc->sc_mtx);
1099 	pflow_sendout_ipfix_tmpl(sc);
1100 	mtx_leave(&sc->sc_mtx);
1101 }
1102 
1103 void
pflow_flush(struct pflow_softc * sc)1104 pflow_flush(struct pflow_softc *sc)
1105 {
1106 	mtx_enter(&sc->sc_mtx);
1107 	switch (sc->sc_version) {
1108 	case PFLOW_PROTO_5:
1109 		pflow_sendout_v5(sc);
1110 		break;
1111 	case PFLOW_PROTO_10:
1112 		pflow_sendout_ipfix(sc, AF_INET);
1113 		pflow_sendout_ipfix(sc, AF_INET6);
1114 		break;
1115 	default: /* NOTREACHED */
1116 		break;
1117 	}
1118 	mtx_leave(&sc->sc_mtx);
1119 }
1120 
1121 int
pflow_sendout_v5(struct pflow_softc * sc)1122 pflow_sendout_v5(struct pflow_softc *sc)
1123 {
1124 	struct mbuf		*m = sc->sc_mbuf;
1125 	struct pflow_header	*h;
1126 	struct ifnet		*ifp = &sc->sc_if;
1127 	struct timespec		tv;
1128 
1129 	MUTEX_ASSERT_LOCKED(&sc->sc_mtx);
1130 
1131 	timeout_del(&sc->sc_tmo);
1132 
1133 	if (m == NULL)
1134 		return (0);
1135 
1136 	sc->sc_mbuf = NULL;
1137 	if (!(ifp->if_flags & IFF_RUNNING)) {
1138 		m_freem(m);
1139 		return (0);
1140 	}
1141 
1142 	pflowstat_inc(pflow_packets);
1143 	h = mtod(m, struct pflow_header *);
1144 	h->count = htons(sc->sc_count);
1145 
1146 	/* populate pflow_header */
1147 	h->uptime_ms = htonl(getuptime() * 1000);
1148 
1149 	getnanotime(&tv);
1150 	h->time_sec = htonl(tv.tv_sec);			/* XXX 2038 */
1151 	h->time_nanosec = htonl(tv.tv_nsec);
1152 	if (mq_enqueue(&sc->sc_outputqueue, m) == 0)
1153 		task_add(net_tq(ifp->if_index), &sc->sc_outputtask);
1154 	return (0);
1155 }
1156 
1157 int
pflow_sendout_ipfix(struct pflow_softc * sc,sa_family_t af)1158 pflow_sendout_ipfix(struct pflow_softc *sc, sa_family_t af)
1159 {
1160 	struct mbuf			*m;
1161 	struct pflow_v10_header		*h10;
1162 	struct pflow_set_header		*set_hdr;
1163 	struct ifnet			*ifp = &sc->sc_if;
1164 	u_int32_t			 count;
1165 	int				 set_length;
1166 
1167 	MUTEX_ASSERT_LOCKED(&sc->sc_mtx);
1168 
1169 	switch (af) {
1170 	case AF_INET:
1171 		m = sc->sc_mbuf;
1172 		timeout_del(&sc->sc_tmo);
1173 		if (m == NULL)
1174 			return (0);
1175 		sc->sc_mbuf = NULL;
1176 		count = sc->sc_count4;
1177 		set_length = sizeof(struct pflow_set_header)
1178 		    + sc->sc_count4 * sizeof(struct pflow_ipfix_flow4);
1179 		break;
1180 	case AF_INET6:
1181 		m = sc->sc_mbuf6;
1182 		timeout_del(&sc->sc_tmo6);
1183 		if (m == NULL)
1184 			return (0);
1185 		sc->sc_mbuf6 = NULL;
1186 		count = sc->sc_count6;
1187 		set_length = sizeof(struct pflow_set_header)
1188 		    + sc->sc_count6 * sizeof(struct pflow_ipfix_flow6);
1189 		break;
1190 	default:
1191 		unhandled_af(af);
1192 	}
1193 
1194 	if (!(ifp->if_flags & IFF_RUNNING)) {
1195 		m_freem(m);
1196 		return (0);
1197 	}
1198 
1199 	pflowstat_inc(pflow_packets);
1200 	set_hdr = mtod(m, struct pflow_set_header *);
1201 	set_hdr->set_length = htons(set_length);
1202 
1203 	/* populate pflow_header */
1204 	M_PREPEND(m, sizeof(struct pflow_v10_header), M_DONTWAIT);
1205 	if (m == NULL) {
1206 		pflowstat_inc(pflow_onomem);
1207 		return (ENOBUFS);
1208 	}
1209 	h10 = mtod(m, struct pflow_v10_header *);
1210 	h10->version = htons(PFLOW_PROTO_10);
1211 	h10->length = htons(PFLOW_IPFIX_HDRLEN + set_length);
1212 	h10->time_sec = htonl(gettime());		/* XXX 2038 */
1213 	h10->flow_sequence = htonl(sc->sc_sequence);
1214 	sc->sc_sequence += count;
1215 	h10->observation_dom = htonl(PFLOW_ENGINE_TYPE);
1216 	if (mq_enqueue(&sc->sc_outputqueue, m) == 0)
1217 		task_add(net_tq(ifp->if_index), &sc->sc_outputtask);
1218 	return (0);
1219 }
1220 
1221 int
pflow_sendout_ipfix_tmpl(struct pflow_softc * sc)1222 pflow_sendout_ipfix_tmpl(struct pflow_softc *sc)
1223 {
1224 	struct mbuf			*m;
1225 	struct pflow_v10_header		*h10;
1226 	struct ifnet			*ifp = &sc->sc_if;
1227 
1228 	MUTEX_ASSERT_LOCKED(&sc->sc_mtx);
1229 
1230 	timeout_del(&sc->sc_tmo_tmpl);
1231 
1232 	if (!(ifp->if_flags & IFF_RUNNING)) {
1233 		return (0);
1234 	}
1235 	m = pflow_get_mbuf(sc, 0);
1236 	if (m == NULL)
1237 		return (0);
1238 	if (m_copyback(m, 0, sizeof(struct pflow_ipfix_tmpl),
1239 	    &sc->sc_tmpl_ipfix, M_NOWAIT)) {
1240 		m_freem(m);
1241 		return (0);
1242 	}
1243 	pflowstat_inc(pflow_packets);
1244 
1245 	/* populate pflow_header */
1246 	M_PREPEND(m, sizeof(struct pflow_v10_header), M_DONTWAIT);
1247 	if (m == NULL) {
1248 		pflowstat_inc(pflow_onomem);
1249 		return (ENOBUFS);
1250 	}
1251 	h10 = mtod(m, struct pflow_v10_header *);
1252 	h10->version = htons(PFLOW_PROTO_10);
1253 	h10->length = htons(PFLOW_IPFIX_HDRLEN + sizeof(struct
1254 	    pflow_ipfix_tmpl));
1255 	h10->time_sec = htonl(gettime());		/* XXX 2038 */
1256 	h10->flow_sequence = htonl(sc->sc_sequence);
1257 	h10->observation_dom = htonl(PFLOW_ENGINE_TYPE);
1258 
1259 	timeout_add_sec(&sc->sc_tmo_tmpl, PFLOW_TMPL_TIMEOUT);
1260 	if (mq_enqueue(&sc->sc_outputqueue, m) == 0)
1261 		task_add(net_tq(ifp->if_index), &sc->sc_outputtask);
1262 	return (0);
1263 }
1264 
1265 int
pflow_sendout_mbuf(struct pflow_softc * sc,struct mbuf * m)1266 pflow_sendout_mbuf(struct pflow_softc *sc, struct mbuf *m)
1267 {
1268 	rw_assert_anylock(&sc->sc_lock);
1269 
1270 	counters_pkt(sc->sc_if.if_counters,
1271 	            ifc_opackets, ifc_obytes, m->m_pkthdr.len);
1272 
1273 	if (sc->so == NULL) {
1274 		m_freem(m);
1275 		return (EINVAL);
1276 	}
1277 	return (sosend(sc->so, sc->send_nam, NULL, m, NULL, 0));
1278 }
1279 
1280 int
pflow_sysctl(int * name,u_int namelen,void * oldp,size_t * oldlenp,void * newp,size_t newlen)1281 pflow_sysctl(int *name, u_int namelen, void *oldp, size_t *oldlenp,
1282     void *newp, size_t newlen)
1283 {
1284 	if (namelen != 1)
1285 		return (ENOTDIR);
1286 
1287 	switch (name[0]) {
1288 	case NET_PFLOW_STATS: {
1289 		uint64_t counters[pflow_ncounters];
1290 		struct pflowstats pflowstats;
1291 
1292 		if (newp != NULL)
1293 			return (EPERM);
1294 
1295 		counters_read(pflow_counters, counters, pflow_ncounters, NULL);
1296 
1297 		pflowstats.pflow_flows = counters[pflow_flows];
1298 		pflowstats.pflow_packets = counters[pflow_packets];
1299 		pflowstats.pflow_onomem = counters[pflow_onomem];
1300 		pflowstats.pflow_oerrors = counters[pflow_oerrors];
1301 
1302 		return (sysctl_struct(oldp, oldlenp, newp, newlen,
1303 		    &pflowstats, sizeof(pflowstats)));
1304 	}
1305 	default:
1306 		return (EOPNOTSUPP);
1307 	}
1308 	return (0);
1309 }
1310