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