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