xref: /openbsd-src/sys/net/if_pflow.c (revision c7e8ea31cd41a963f06f0a8ba93948b06aa6b4a4)
1 /*	$OpenBSD: if_pflow.c,v 1.83 2017/08/12 20:27:28 mpi 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/types.h>
23 #include <sys/malloc.h>
24 #include <sys/param.h>
25 #include <sys/systm.h>
26 #include <sys/mbuf.h>
27 #include <sys/socket.h>
28 #include <sys/timeout.h>
29 #include <sys/ioctl.h>
30 #include <sys/kernel.h>
31 #include <sys/socket.h>
32 #include <sys/socketvar.h>
33 #include <sys/sysctl.h>
34 
35 #include <net/if.h>
36 #include <net/if_types.h>
37 #include <net/bpf.h>
38 #include <net/route.h>
39 #include <netinet/in.h>
40 #include <netinet/if_ether.h>
41 #include <netinet/tcp.h>
42 
43 #include <netinet/ip.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/if_pflow.h>
51 
52 #include "bpfilter.h"
53 #include "pflow.h"
54 
55 #define PFLOW_MINMTU	\
56     (sizeof(struct pflow_header) + sizeof(struct pflow_flow))
57 
58 #ifdef PFLOWDEBUG
59 #define DPRINTF(x)	do { printf x ; } while (0)
60 #else
61 #define DPRINTF(x)
62 #endif
63 
64 SLIST_HEAD(, pflow_softc) pflowif_list;
65 struct pflowstats	 pflowstats;
66 
67 void	pflowattach(int);
68 int	pflow_output(struct ifnet *ifp, struct mbuf *m, struct sockaddr *dst,
69 	struct rtentry *rt);
70 void	pflow_output_process(void *);
71 int	pflow_clone_create(struct if_clone *, int);
72 int	pflow_clone_destroy(struct ifnet *);
73 int	pflow_set(struct pflow_softc *, struct pflowreq *);
74 void	pflow_init_timeouts(struct pflow_softc *);
75 int	pflow_calc_mtu(struct pflow_softc *, int, int);
76 void	pflow_setmtu(struct pflow_softc *, int);
77 int	pflowvalidsockaddr(const struct sockaddr *, int);
78 int	pflowioctl(struct ifnet *, u_long, caddr_t);
79 
80 struct mbuf	*pflow_get_mbuf(struct pflow_softc *, u_int16_t);
81 void	pflow_flush(struct pflow_softc *);
82 int	pflow_sendout_v5(struct pflow_softc *);
83 int	pflow_sendout_ipfix(struct pflow_softc *, sa_family_t);
84 int	pflow_sendout_ipfix_tmpl(struct pflow_softc *);
85 int	pflow_sendout_mbuf(struct pflow_softc *, struct mbuf *);
86 void	pflow_timeout(void *);
87 void	pflow_timeout6(void *);
88 void	pflow_timeout_tmpl(void *);
89 void	copy_flow_data(struct pflow_flow *, struct pflow_flow *,
90 	struct pf_state *, struct pf_state_key *, int, int);
91 void	copy_flow_ipfix_4_data(struct pflow_ipfix_flow4 *,
92 	struct pflow_ipfix_flow4 *, struct pf_state *, struct pf_state_key *,
93 	struct pflow_softc *, int, int);
94 void	copy_flow_ipfix_6_data(struct pflow_ipfix_flow6 *,
95 	struct pflow_ipfix_flow6 *, struct pf_state *, struct pf_state_key *,
96 	struct pflow_softc *, int, int);
97 int	pflow_pack_flow(struct pf_state *, struct pf_state_key *,
98 	struct pflow_softc *);
99 int	pflow_pack_flow_ipfix(struct pf_state *, struct pf_state_key *,
100 	struct pflow_softc *);
101 int	export_pflow_if(struct pf_state*, struct pf_state_key *,
102 	struct pflow_softc *);
103 int	copy_flow_to_m(struct pflow_flow *flow, struct pflow_softc *sc);
104 int	copy_flow_ipfix_4_to_m(struct pflow_ipfix_flow4 *flow,
105 	struct pflow_softc *sc);
106 int	copy_flow_ipfix_6_to_m(struct pflow_ipfix_flow6 *flow,
107 	struct pflow_softc *sc);
108 
109 struct if_clone	pflow_cloner =
110     IF_CLONE_INITIALIZER("pflow", pflow_clone_create,
111     pflow_clone_destroy);
112 
113 void
114 pflowattach(int npflow)
115 {
116 	SLIST_INIT(&pflowif_list);
117 	if_clone_attach(&pflow_cloner);
118 }
119 
120 int
121 pflow_output(struct ifnet *ifp, struct mbuf *m, struct sockaddr *dst,
122 	struct rtentry *rt)
123 {
124 	m_freem(m);	/* drop packet */
125 	return (EAFNOSUPPORT);
126 }
127 
128 void
129 pflow_output_process(void *arg)
130 {
131 	struct mbuf_list ml;
132 	struct pflow_softc *sc = arg;
133 	struct mbuf *m;
134 
135 	mq_delist(&sc->sc_outputqueue, &ml);
136 	KERNEL_LOCK();
137 	while ((m = ml_dequeue(&ml)) != NULL) {
138 		pflow_sendout_mbuf(sc, m);
139 	}
140 	KERNEL_UNLOCK();
141 }
142 
143 int
144 pflow_clone_create(struct if_clone *ifc, int unit)
145 {
146 	struct ifnet		*ifp;
147 	struct pflow_softc	*pflowif;
148 
149 	if ((pflowif = malloc(sizeof(*pflowif),
150 	    M_DEVBUF, M_NOWAIT|M_ZERO)) == NULL)
151 		return (ENOMEM);
152 
153 	MGET(pflowif->send_nam, M_WAIT, MT_SONAME);
154 
155 	pflowif->sc_version = PFLOW_PROTO_DEFAULT;
156 
157 	/* ipfix template init */
158 	bzero(&pflowif->sc_tmpl_ipfix,sizeof(pflowif->sc_tmpl_ipfix));
159 	pflowif->sc_tmpl_ipfix.set_header.set_id =
160 	    htons(PFLOW_IPFIX_TMPL_SET_ID);
161 	pflowif->sc_tmpl_ipfix.set_header.set_length =
162 	    htons(sizeof(struct pflow_ipfix_tmpl));
163 
164 	/* ipfix IPv4 template */
165 	pflowif->sc_tmpl_ipfix.ipv4_tmpl.h.tmpl_id =
166 	    htons(PFLOW_IPFIX_TMPL_IPV4_ID);
167 	pflowif->sc_tmpl_ipfix.ipv4_tmpl.h.field_count
168 	    = htons(PFLOW_IPFIX_TMPL_IPV4_FIELD_COUNT);
169 	pflowif->sc_tmpl_ipfix.ipv4_tmpl.src_ip.field_id =
170 	    htons(PFIX_IE_sourceIPv4Address);
171 	pflowif->sc_tmpl_ipfix.ipv4_tmpl.src_ip.len = htons(4);
172 	pflowif->sc_tmpl_ipfix.ipv4_tmpl.dest_ip.field_id =
173 	    htons(PFIX_IE_destinationIPv4Address);
174 	pflowif->sc_tmpl_ipfix.ipv4_tmpl.dest_ip.len = htons(4);
175 	pflowif->sc_tmpl_ipfix.ipv4_tmpl.if_index_in.field_id =
176 	    htons(PFIX_IE_ingressInterface);
177 	pflowif->sc_tmpl_ipfix.ipv4_tmpl.if_index_in.len = htons(4);
178 	pflowif->sc_tmpl_ipfix.ipv4_tmpl.if_index_out.field_id =
179 	    htons(PFIX_IE_egressInterface);
180 	pflowif->sc_tmpl_ipfix.ipv4_tmpl.if_index_out.len = htons(4);
181 	pflowif->sc_tmpl_ipfix.ipv4_tmpl.packets.field_id =
182 	    htons(PFIX_IE_packetDeltaCount);
183 	pflowif->sc_tmpl_ipfix.ipv4_tmpl.packets.len = htons(8);
184 	pflowif->sc_tmpl_ipfix.ipv4_tmpl.octets.field_id =
185 	    htons(PFIX_IE_octetDeltaCount);
186 	pflowif->sc_tmpl_ipfix.ipv4_tmpl.octets.len = htons(8);
187 	pflowif->sc_tmpl_ipfix.ipv4_tmpl.start.field_id =
188 	    htons(PFIX_IE_flowStartMilliseconds);
189 	pflowif->sc_tmpl_ipfix.ipv4_tmpl.start.len = htons(8);
190 	pflowif->sc_tmpl_ipfix.ipv4_tmpl.finish.field_id =
191 	    htons(PFIX_IE_flowEndMilliseconds);
192 	pflowif->sc_tmpl_ipfix.ipv4_tmpl.finish.len = htons(8);
193 	pflowif->sc_tmpl_ipfix.ipv4_tmpl.src_port.field_id =
194 	    htons(PFIX_IE_sourceTransportPort);
195 	pflowif->sc_tmpl_ipfix.ipv4_tmpl.src_port.len = htons(2);
196 	pflowif->sc_tmpl_ipfix.ipv4_tmpl.dest_port.field_id =
197 	    htons(PFIX_IE_destinationTransportPort);
198 	pflowif->sc_tmpl_ipfix.ipv4_tmpl.dest_port.len = htons(2);
199 	pflowif->sc_tmpl_ipfix.ipv4_tmpl.tos.field_id =
200 	    htons(PFIX_IE_ipClassOfService);
201 	pflowif->sc_tmpl_ipfix.ipv4_tmpl.tos.len = htons(1);
202 	pflowif->sc_tmpl_ipfix.ipv4_tmpl.protocol.field_id =
203 	    htons(PFIX_IE_protocolIdentifier);
204 	pflowif->sc_tmpl_ipfix.ipv4_tmpl.protocol.len = htons(1);
205 
206 	/* ipfix IPv6 template */
207 	pflowif->sc_tmpl_ipfix.ipv6_tmpl.h.tmpl_id =
208 	    htons(PFLOW_IPFIX_TMPL_IPV6_ID);
209 	pflowif->sc_tmpl_ipfix.ipv6_tmpl.h.field_count =
210 	    htons(PFLOW_IPFIX_TMPL_IPV6_FIELD_COUNT);
211 	pflowif->sc_tmpl_ipfix.ipv6_tmpl.src_ip.field_id =
212 	    htons(PFIX_IE_sourceIPv6Address);
213 	pflowif->sc_tmpl_ipfix.ipv6_tmpl.src_ip.len = htons(16);
214 	pflowif->sc_tmpl_ipfix.ipv6_tmpl.dest_ip.field_id =
215 	    htons(PFIX_IE_destinationIPv6Address);
216 	pflowif->sc_tmpl_ipfix.ipv6_tmpl.dest_ip.len = htons(16);
217 	pflowif->sc_tmpl_ipfix.ipv6_tmpl.if_index_in.field_id =
218 	    htons(PFIX_IE_ingressInterface);
219 	pflowif->sc_tmpl_ipfix.ipv6_tmpl.if_index_in.len = htons(4);
220 	pflowif->sc_tmpl_ipfix.ipv6_tmpl.if_index_out.field_id =
221 	    htons(PFIX_IE_egressInterface);
222 	pflowif->sc_tmpl_ipfix.ipv6_tmpl.if_index_out.len = htons(4);
223 	pflowif->sc_tmpl_ipfix.ipv6_tmpl.packets.field_id =
224 	    htons(PFIX_IE_packetDeltaCount);
225 	pflowif->sc_tmpl_ipfix.ipv6_tmpl.packets.len = htons(8);
226 	pflowif->sc_tmpl_ipfix.ipv6_tmpl.octets.field_id =
227 	    htons(PFIX_IE_octetDeltaCount);
228 	pflowif->sc_tmpl_ipfix.ipv6_tmpl.octets.len = htons(8);
229 	pflowif->sc_tmpl_ipfix.ipv6_tmpl.start.field_id =
230 	    htons(PFIX_IE_flowStartMilliseconds);
231 	pflowif->sc_tmpl_ipfix.ipv6_tmpl.start.len = htons(8);
232 	pflowif->sc_tmpl_ipfix.ipv6_tmpl.finish.field_id =
233 	    htons(PFIX_IE_flowEndMilliseconds);
234 	pflowif->sc_tmpl_ipfix.ipv6_tmpl.finish.len = htons(8);
235 	pflowif->sc_tmpl_ipfix.ipv6_tmpl.src_port.field_id =
236 	    htons(PFIX_IE_sourceTransportPort);
237 	pflowif->sc_tmpl_ipfix.ipv6_tmpl.src_port.len = htons(2);
238 	pflowif->sc_tmpl_ipfix.ipv6_tmpl.dest_port.field_id =
239 	    htons(PFIX_IE_destinationTransportPort);
240 	pflowif->sc_tmpl_ipfix.ipv6_tmpl.dest_port.len = htons(2);
241 	pflowif->sc_tmpl_ipfix.ipv6_tmpl.tos.field_id =
242 	    htons(PFIX_IE_ipClassOfService);
243 	pflowif->sc_tmpl_ipfix.ipv6_tmpl.tos.len = htons(1);
244 	pflowif->sc_tmpl_ipfix.ipv6_tmpl.protocol.field_id =
245 	    htons(PFIX_IE_protocolIdentifier);
246 	pflowif->sc_tmpl_ipfix.ipv6_tmpl.protocol.len = htons(1);
247 
248 	ifp = &pflowif->sc_if;
249 	snprintf(ifp->if_xname, sizeof ifp->if_xname, "pflow%d", unit);
250 	ifp->if_softc = pflowif;
251 	ifp->if_ioctl = pflowioctl;
252 	ifp->if_output = pflow_output;
253 	ifp->if_start = NULL;
254 	ifp->if_xflags = IFXF_CLONED;
255 	ifp->if_type = IFT_PFLOW;
256 	IFQ_SET_MAXLEN(&ifp->if_snd, IFQ_MAXLEN);
257 	ifp->if_hdrlen = PFLOW_HDRLEN;
258 	ifp->if_flags = IFF_UP;
259 	ifp->if_flags &= ~IFF_RUNNING;	/* not running, need receiver */
260 	mq_init(&pflowif->sc_outputqueue, 8192, IPL_SOFTNET);
261 	pflow_setmtu(pflowif, ETHERMTU);
262 	pflow_init_timeouts(pflowif);
263 	if_attach(ifp);
264 	if_alloc_sadl(ifp);
265 
266 	task_set(&pflowif->sc_outputtask, pflow_output_process, pflowif);
267 
268 	/* Insert into list of pflows */
269 	NET_LOCK();
270 	SLIST_INSERT_HEAD(&pflowif_list, pflowif, sc_next);
271 	NET_UNLOCK();
272 	return (0);
273 }
274 
275 int
276 pflow_clone_destroy(struct ifnet *ifp)
277 {
278 	struct pflow_softc	*sc = ifp->if_softc;
279 	int			 error;
280 
281 	error = 0;
282 
283 	if (timeout_initialized(&sc->sc_tmo))
284 		timeout_del(&sc->sc_tmo);
285 	if (timeout_initialized(&sc->sc_tmo6))
286 		timeout_del(&sc->sc_tmo6);
287 	if (timeout_initialized(&sc->sc_tmo_tmpl))
288 		timeout_del(&sc->sc_tmo_tmpl);
289 	pflow_flush(sc);
290 	task_del(softnettq, &sc->sc_outputtask);
291 	mq_purge(&sc->sc_outputqueue);
292 	m_freem(sc->send_nam);
293 	if (sc->so != NULL) {
294 		error = soclose(sc->so);
295 		sc->so = NULL;
296 	}
297 	if (sc->sc_flowdst != NULL)
298 		free(sc->sc_flowdst, M_DEVBUF, sc->sc_flowdst->sa_len);
299 	if (sc->sc_flowsrc != NULL)
300 		free(sc->sc_flowsrc, M_DEVBUF, sc->sc_flowsrc->sa_len);
301 	if_detach(ifp);
302 	NET_LOCK();
303 	SLIST_REMOVE(&pflowif_list, sc, pflow_softc, sc_next);
304 	NET_UNLOCK();
305 	free(sc, M_DEVBUF, sizeof(*sc));
306 	return (error);
307 }
308 
309 int
310 pflowvalidsockaddr(const struct sockaddr *sa, int ignore_port)
311 {
312 	struct sockaddr_in6	*sin6;
313 	struct sockaddr_in	*sin;
314 
315 	if (sa == NULL)
316 		return (0);
317 	switch(sa->sa_family) {
318 	case AF_INET:
319 		sin = (struct sockaddr_in*) sa;
320 		return (sin->sin_addr.s_addr != INADDR_ANY &&
321 		    (ignore_port || sin->sin_port != 0));
322 	case AF_INET6:
323 		sin6 = (struct sockaddr_in6*) sa;
324 		return (!IN6_IS_ADDR_UNSPECIFIED(&sin6->sin6_addr) &&
325 		    (ignore_port || sin6->sin6_port != 0));
326 	default:
327 		return (0);
328 	}
329 }
330 
331 int
332 pflow_set(struct pflow_softc *sc, struct pflowreq *pflowr)
333 {
334 	struct proc		*p = curproc;
335 	struct socket		*so;
336 	struct sockaddr		*sa;
337 	int			 error = 0;
338 
339 	if (pflowr->addrmask & PFLOW_MASK_VERSION) {
340 		switch(pflowr->version) {
341 		case PFLOW_PROTO_5:
342 		case PFLOW_PROTO_10:
343 			break;
344 		default:
345 			return(EINVAL);
346 		}
347 	}
348 
349 	pflow_flush(sc);
350 
351 	if (pflowr->addrmask & PFLOW_MASK_DSTIP) {
352 		if (sc->sc_flowdst != NULL &&
353 		    sc->sc_flowdst->sa_family != pflowr->flowdst.ss_family) {
354 			free(sc->sc_flowdst, M_DEVBUF, sc->sc_flowdst->sa_len);
355 			sc->sc_flowdst = NULL;
356 			if (sc->so != NULL) {
357 				soclose(sc->so);
358 				sc->so = NULL;
359 			}
360 		}
361 
362 		switch (pflowr->flowdst.ss_family) {
363 		case AF_INET:
364 			if (sc->sc_flowdst == NULL) {
365 				if ((sc->sc_flowdst = malloc(
366 				    sizeof(struct sockaddr_in),
367 				    M_DEVBUF,  M_NOWAIT)) == NULL)
368 					return (ENOMEM);
369 			}
370 			memcpy(sc->sc_flowdst, &pflowr->flowdst,
371 			    sizeof(struct sockaddr_in));
372 			sc->sc_flowdst->sa_len = sizeof(struct
373 			    sockaddr_in);
374 			break;
375 		case AF_INET6:
376 			if (sc->sc_flowdst == NULL) {
377 				if ((sc->sc_flowdst = malloc(
378 				    sizeof(struct sockaddr_in6),
379 				    M_DEVBUF, M_NOWAIT)) == NULL)
380 					return (ENOMEM);
381 			}
382 			memcpy(sc->sc_flowdst, &pflowr->flowdst,
383 			    sizeof(struct sockaddr_in6));
384 			sc->sc_flowdst->sa_len = sizeof(struct
385 			    sockaddr_in6);
386 			break;
387 		default:
388 			break;
389 		}
390 
391 		if (sc->sc_flowdst != NULL) {
392 			sc->send_nam->m_len = sc->sc_flowdst->sa_len;
393 			sa = mtod(sc->send_nam, struct sockaddr *);
394 			memcpy(sa, sc->sc_flowdst, sc->sc_flowdst->sa_len);
395 		}
396 	}
397 
398 	if (pflowr->addrmask & PFLOW_MASK_SRCIP) {
399 		if (sc->sc_flowsrc != NULL)
400 			free(sc->sc_flowsrc, M_DEVBUF, sc->sc_flowsrc->sa_len);
401 		sc->sc_flowsrc = NULL;
402 		if (sc->so != NULL) {
403 			soclose(sc->so);
404 			sc->so = NULL;
405 		}
406 		switch(pflowr->flowsrc.ss_family) {
407 		case AF_INET:
408 			if ((sc->sc_flowsrc = malloc(
409 			    sizeof(struct sockaddr_in),
410 			    M_DEVBUF, M_NOWAIT)) == NULL)
411 				return (ENOMEM);
412 			memcpy(sc->sc_flowsrc, &pflowr->flowsrc,
413 			    sizeof(struct sockaddr_in));
414 			sc->sc_flowsrc->sa_len = sizeof(struct
415 			    sockaddr_in);
416 			break;
417 		case AF_INET6:
418 			if ((sc->sc_flowsrc = malloc(
419 			    sizeof(struct sockaddr_in6),
420 			    M_DEVBUF, M_NOWAIT)) == NULL)
421 				return (ENOMEM);
422 			memcpy(sc->sc_flowsrc, &pflowr->flowsrc,
423 			    sizeof(struct sockaddr_in6));
424 			sc->sc_flowsrc->sa_len = sizeof(struct
425 			    sockaddr_in6);
426 			break;
427 		default:
428 			break;
429 		}
430 	}
431 
432 	if (sc->so == NULL) {
433 		if (pflowvalidsockaddr(sc->sc_flowdst, 0)) {
434 			error = socreate(sc->sc_flowdst->sa_family,
435 			    &so, SOCK_DGRAM, 0);
436 			if (error)
437 				return (error);
438 			if (pflowvalidsockaddr(sc->sc_flowsrc, 1)) {
439 				struct mbuf *m;
440 				int s;
441 
442 				MGET(m, M_WAIT, MT_SONAME);
443 				m->m_len = sc->sc_flowsrc->sa_len;
444 				sa = mtod(m, struct sockaddr *);
445 				memcpy(sa, sc->sc_flowsrc,
446 				    sc->sc_flowsrc->sa_len);
447 
448 				s = solock(so);
449 				error = sobind(so, m, p);
450 				sounlock(s);
451 				m_freem(m);
452 				if (error) {
453 					soclose(so);
454 					return (error);
455 				}
456 			}
457 			sc->so = so;
458 		}
459 	} else if (!pflowvalidsockaddr(sc->sc_flowdst, 0)) {
460 		soclose(sc->so);
461 		sc->so = NULL;
462 	}
463 
464 	/* error check is above */
465 	if (pflowr->addrmask & PFLOW_MASK_VERSION)
466 		sc->sc_version = pflowr->version;
467 
468 	pflow_setmtu(sc, ETHERMTU);
469 	pflow_init_timeouts(sc);
470 
471 	return (0);
472 }
473 
474 int
475 pflowioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
476 {
477 	struct proc		*p = curproc;
478 	struct pflow_softc	*sc = ifp->if_softc;
479 	struct ifreq		*ifr = (struct ifreq *)data;
480 	struct pflowreq		 pflowr;
481 	int			 error;
482 
483 	switch (cmd) {
484 	case SIOCSIFADDR:
485 	case SIOCSIFDSTADDR:
486 	case SIOCSIFFLAGS:
487 		if ((ifp->if_flags & IFF_UP) && sc->so != NULL) {
488 			ifp->if_flags |= IFF_RUNNING;
489 			sc->sc_gcounter=pflowstats.pflow_flows;
490 			/* send templates on startup */
491 			if (sc->sc_version == PFLOW_PROTO_10)
492 				pflow_sendout_ipfix_tmpl(sc);
493 		} else
494 			ifp->if_flags &= ~IFF_RUNNING;
495 		break;
496 	case SIOCSIFMTU:
497 		if (ifr->ifr_mtu < PFLOW_MINMTU)
498 			return (EINVAL);
499 		if (ifr->ifr_mtu > MCLBYTES)
500 			ifr->ifr_mtu = MCLBYTES;
501 		if (ifr->ifr_mtu < ifp->if_mtu)
502 			pflow_flush(sc);
503 		pflow_setmtu(sc, ifr->ifr_mtu);
504 		break;
505 
506 	case SIOCGETPFLOW:
507 		bzero(&pflowr, sizeof(pflowr));
508 
509 		if (sc->sc_flowsrc != NULL)
510 			memcpy(&pflowr.flowsrc, sc->sc_flowsrc,
511 			    sc->sc_flowsrc->sa_len);
512 		if (sc->sc_flowdst != NULL)
513 			memcpy(&pflowr.flowdst, sc->sc_flowdst,
514 			    sc->sc_flowdst->sa_len);
515 		pflowr.version = sc->sc_version;
516 
517 		if ((error = copyout(&pflowr, ifr->ifr_data,
518 		    sizeof(pflowr))))
519 			return (error);
520 		break;
521 
522 	case SIOCSETPFLOW:
523 		if ((error = suser(p, 0)) != 0)
524 			return (error);
525 		if ((error = copyin(ifr->ifr_data, &pflowr,
526 		    sizeof(pflowr))))
527 			return (error);
528 
529 		/* XXXSMP breaks atomicity */
530 		NET_UNLOCK();
531 		error = pflow_set(sc, &pflowr);
532 		NET_LOCK();
533 		if (error != 0)
534 			return (error);
535 
536 		if ((ifp->if_flags & IFF_UP) && sc->so != NULL) {
537 			ifp->if_flags |= IFF_RUNNING;
538 			sc->sc_gcounter=pflowstats.pflow_flows;
539 			if (sc->sc_version == PFLOW_PROTO_10)
540 				pflow_sendout_ipfix_tmpl(sc);
541 		} else
542 			ifp->if_flags &= ~IFF_RUNNING;
543 
544 		break;
545 
546 	default:
547 		return (ENOTTY);
548 	}
549 	return (0);
550 }
551 
552 void
553 pflow_init_timeouts(struct pflow_softc *sc)
554 {
555 	switch (sc->sc_version) {
556 	case PFLOW_PROTO_5:
557 		if (timeout_initialized(&sc->sc_tmo6))
558 			timeout_del(&sc->sc_tmo6);
559 		if (timeout_initialized(&sc->sc_tmo_tmpl))
560 			timeout_del(&sc->sc_tmo_tmpl);
561 		if (!timeout_initialized(&sc->sc_tmo))
562 			timeout_set_proc(&sc->sc_tmo, pflow_timeout, sc);
563 		break;
564 	case PFLOW_PROTO_10:
565 		if (!timeout_initialized(&sc->sc_tmo_tmpl))
566 			timeout_set_proc(&sc->sc_tmo_tmpl, pflow_timeout_tmpl,
567 			    sc);
568 		if (!timeout_initialized(&sc->sc_tmo))
569 			timeout_set_proc(&sc->sc_tmo, pflow_timeout, sc);
570 		if (!timeout_initialized(&sc->sc_tmo6))
571 			timeout_set_proc(&sc->sc_tmo6, pflow_timeout6, sc);
572 
573 		timeout_add_sec(&sc->sc_tmo_tmpl, PFLOW_TMPL_TIMEOUT);
574 		break;
575 	default: /* NOTREACHED */
576 		break;
577 	}
578 }
579 
580 int
581 pflow_calc_mtu(struct pflow_softc *sc, int mtu, int hdrsz)
582 {
583 
584 	sc->sc_maxcount4 = (mtu - hdrsz -
585 	    sizeof(struct udpiphdr)) / sizeof(struct pflow_ipfix_flow4);
586 	sc->sc_maxcount6 = (mtu - hdrsz -
587 	    sizeof(struct udpiphdr)) / sizeof(struct pflow_ipfix_flow6);
588 	if (sc->sc_maxcount4 > PFLOW_MAXFLOWS)
589 		sc->sc_maxcount4 = PFLOW_MAXFLOWS;
590 	if (sc->sc_maxcount6 > PFLOW_MAXFLOWS)
591 		sc->sc_maxcount6 = PFLOW_MAXFLOWS;
592 	return (hdrsz + sizeof(struct udpiphdr) +
593 	    MIN(sc->sc_maxcount4 * sizeof(struct pflow_ipfix_flow4),
594 	    sc->sc_maxcount6 * sizeof(struct pflow_ipfix_flow6)));
595 }
596 
597 void
598 pflow_setmtu(struct pflow_softc *sc, int mtu_req)
599 {
600 	int	mtu;
601 
602 	if (sc->sc_pflow_ifp && sc->sc_pflow_ifp->if_mtu < mtu_req)
603 		mtu = sc->sc_pflow_ifp->if_mtu;
604 	else
605 		mtu = mtu_req;
606 
607 	switch (sc->sc_version) {
608 	case PFLOW_PROTO_5:
609 		sc->sc_maxcount = (mtu - sizeof(struct pflow_header) -
610 		    sizeof(struct udpiphdr)) / sizeof(struct pflow_flow);
611 		if (sc->sc_maxcount > PFLOW_MAXFLOWS)
612 		    sc->sc_maxcount = PFLOW_MAXFLOWS;
613 		sc->sc_if.if_mtu = sizeof(struct pflow_header) +
614 		    sizeof(struct udpiphdr) +
615 		    sc->sc_maxcount * sizeof(struct pflow_flow);
616 		break;
617 	case PFLOW_PROTO_10:
618 		sc->sc_if.if_mtu =
619 		    pflow_calc_mtu(sc, mtu, sizeof(struct pflow_v10_header));
620 		break;
621 	default: /* NOTREACHED */
622 		break;
623 	}
624 }
625 
626 struct mbuf *
627 pflow_get_mbuf(struct pflow_softc *sc, u_int16_t set_id)
628 {
629 	struct pflow_set_header	 set_hdr;
630 	struct pflow_header	 h;
631 	struct mbuf		*m;
632 
633 	MGETHDR(m, M_DONTWAIT, MT_DATA);
634 	if (m == NULL) {
635 		pflowstats.pflow_onomem++;
636 		return (NULL);
637 	}
638 
639 	MCLGET(m, M_DONTWAIT);
640 	if ((m->m_flags & M_EXT) == 0) {
641 		m_free(m);
642 		pflowstats.pflow_onomem++;
643 		return (NULL);
644 	}
645 
646 	m->m_len = m->m_pkthdr.len = 0;
647 	m->m_pkthdr.ph_ifidx = 0;
648 
649 	if (sc == NULL)		/* get only a new empty mbuf */
650 		return (m);
651 
652 	if (sc->sc_version == PFLOW_PROTO_5) {
653 		/* populate pflow_header */
654 		h.reserved1 = 0;
655 		h.reserved2 = 0;
656 		h.count = 0;
657 		h.version = htons(PFLOW_PROTO_5);
658 		h.flow_sequence = htonl(sc->sc_gcounter);
659 		h.engine_type = PFLOW_ENGINE_TYPE;
660 		h.engine_id = PFLOW_ENGINE_ID;
661 		m_copyback(m, 0, PFLOW_HDRLEN, &h, M_NOWAIT);
662 
663 		sc->sc_count = 0;
664 		timeout_add_sec(&sc->sc_tmo, PFLOW_TIMEOUT);
665 	} else {
666 		/* populate pflow_set_header */
667 		set_hdr.set_length = 0;
668 		set_hdr.set_id = htons(set_id);
669 		m_copyback(m, 0, PFLOW_SET_HDRLEN, &set_hdr, M_NOWAIT);
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((time_second -
738 		    time_uptime)*1000);
739 	else
740 		flow1->flow_start = flow2->flow_start = htobe64((time_second -
741 		    (time_uptime - st->creation))*1000);
742 	flow1->flow_finish = flow2->flow_finish = htobe64((time_second -
743 	    (time_uptime - 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((time_second -
777 		    time_uptime)*1000);
778 	else
779 		flow1->flow_start = flow2->flow_start = htobe64((time_second -
780 		    (time_uptime - st->creation))*1000);
781 	flow1->flow_finish = flow2->flow_finish = htobe64((time_second -
782 	    (time_uptime - 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(time_uptime * 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(softnettq, &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(time_second);		/* 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(softnettq, &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(time_second);		/* 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(softnettq, &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