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