1 /* $OpenBSD: if_pflow.c,v 1.99 2023/04/13 02:19:05 jsg Exp $ */ 2 3 /* 4 * Copyright (c) 2011 Florian Obser <florian@narrans.de> 5 * Copyright (c) 2011 Sebastian Benoit <benoit-lists@fb12.de> 6 * Copyright (c) 2008 Henning Brauer <henning@openbsd.org> 7 * Copyright (c) 2008 Joerg Goltermann <jg@osn.de> 8 * 9 * Permission to use, copy, modify, and distribute this software for any 10 * purpose with or without fee is hereby granted, provided that the above 11 * copyright notice and this permission notice appear in all copies. 12 * 13 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 14 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 15 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 16 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 17 * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER IN 18 * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT 19 * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 20 */ 21 22 #include <sys/param.h> 23 #include <sys/malloc.h> 24 #include <sys/systm.h> 25 #include <sys/mbuf.h> 26 #include <sys/socket.h> 27 #include <sys/timeout.h> 28 #include <sys/ioctl.h> 29 #include <sys/kernel.h> 30 #include <sys/socketvar.h> 31 #include <sys/sysctl.h> 32 33 #include <net/if.h> 34 #include <net/if_types.h> 35 #include <net/bpf.h> 36 #include <net/route.h> 37 #include <netinet/in.h> 38 #include <netinet/if_ether.h> 39 #include <netinet/tcp.h> 40 41 #include <netinet/ip.h> 42 #include <netinet/ip_icmp.h> 43 #include <netinet/ip_var.h> 44 #include <netinet/udp.h> 45 #include <netinet/udp_var.h> 46 #include <netinet/in_pcb.h> 47 48 #include <net/pfvar.h> 49 #include <net/pfvar_priv.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 rw_enter_read(&sc->sc_lock); 137 while ((m = ml_dequeue(&ml)) != NULL) { 138 pflow_sendout_mbuf(sc, m); 139 } 140 rw_exit_read(&sc->sc_lock); 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 pflowif = malloc(sizeof(*pflowif), M_DEVBUF, M_WAITOK|M_ZERO); 150 rw_init(&pflowif->sc_lock, "pflowlk"); 151 MGET(pflowif->send_nam, M_WAIT, MT_SONAME); 152 pflowif->sc_version = PFLOW_PROTO_DEFAULT; 153 154 /* ipfix template init */ 155 bzero(&pflowif->sc_tmpl_ipfix,sizeof(pflowif->sc_tmpl_ipfix)); 156 pflowif->sc_tmpl_ipfix.set_header.set_id = 157 htons(PFLOW_IPFIX_TMPL_SET_ID); 158 pflowif->sc_tmpl_ipfix.set_header.set_length = 159 htons(sizeof(struct pflow_ipfix_tmpl)); 160 161 /* ipfix IPv4 template */ 162 pflowif->sc_tmpl_ipfix.ipv4_tmpl.h.tmpl_id = 163 htons(PFLOW_IPFIX_TMPL_IPV4_ID); 164 pflowif->sc_tmpl_ipfix.ipv4_tmpl.h.field_count 165 = htons(PFLOW_IPFIX_TMPL_IPV4_FIELD_COUNT); 166 pflowif->sc_tmpl_ipfix.ipv4_tmpl.src_ip.field_id = 167 htons(PFIX_IE_sourceIPv4Address); 168 pflowif->sc_tmpl_ipfix.ipv4_tmpl.src_ip.len = htons(4); 169 pflowif->sc_tmpl_ipfix.ipv4_tmpl.dest_ip.field_id = 170 htons(PFIX_IE_destinationIPv4Address); 171 pflowif->sc_tmpl_ipfix.ipv4_tmpl.dest_ip.len = htons(4); 172 pflowif->sc_tmpl_ipfix.ipv4_tmpl.if_index_in.field_id = 173 htons(PFIX_IE_ingressInterface); 174 pflowif->sc_tmpl_ipfix.ipv4_tmpl.if_index_in.len = htons(4); 175 pflowif->sc_tmpl_ipfix.ipv4_tmpl.if_index_out.field_id = 176 htons(PFIX_IE_egressInterface); 177 pflowif->sc_tmpl_ipfix.ipv4_tmpl.if_index_out.len = htons(4); 178 pflowif->sc_tmpl_ipfix.ipv4_tmpl.packets.field_id = 179 htons(PFIX_IE_packetDeltaCount); 180 pflowif->sc_tmpl_ipfix.ipv4_tmpl.packets.len = htons(8); 181 pflowif->sc_tmpl_ipfix.ipv4_tmpl.octets.field_id = 182 htons(PFIX_IE_octetDeltaCount); 183 pflowif->sc_tmpl_ipfix.ipv4_tmpl.octets.len = htons(8); 184 pflowif->sc_tmpl_ipfix.ipv4_tmpl.start.field_id = 185 htons(PFIX_IE_flowStartMilliseconds); 186 pflowif->sc_tmpl_ipfix.ipv4_tmpl.start.len = htons(8); 187 pflowif->sc_tmpl_ipfix.ipv4_tmpl.finish.field_id = 188 htons(PFIX_IE_flowEndMilliseconds); 189 pflowif->sc_tmpl_ipfix.ipv4_tmpl.finish.len = htons(8); 190 pflowif->sc_tmpl_ipfix.ipv4_tmpl.src_port.field_id = 191 htons(PFIX_IE_sourceTransportPort); 192 pflowif->sc_tmpl_ipfix.ipv4_tmpl.src_port.len = htons(2); 193 pflowif->sc_tmpl_ipfix.ipv4_tmpl.dest_port.field_id = 194 htons(PFIX_IE_destinationTransportPort); 195 pflowif->sc_tmpl_ipfix.ipv4_tmpl.dest_port.len = htons(2); 196 pflowif->sc_tmpl_ipfix.ipv4_tmpl.tos.field_id = 197 htons(PFIX_IE_ipClassOfService); 198 pflowif->sc_tmpl_ipfix.ipv4_tmpl.tos.len = htons(1); 199 pflowif->sc_tmpl_ipfix.ipv4_tmpl.protocol.field_id = 200 htons(PFIX_IE_protocolIdentifier); 201 pflowif->sc_tmpl_ipfix.ipv4_tmpl.protocol.len = htons(1); 202 203 /* ipfix IPv6 template */ 204 pflowif->sc_tmpl_ipfix.ipv6_tmpl.h.tmpl_id = 205 htons(PFLOW_IPFIX_TMPL_IPV6_ID); 206 pflowif->sc_tmpl_ipfix.ipv6_tmpl.h.field_count = 207 htons(PFLOW_IPFIX_TMPL_IPV6_FIELD_COUNT); 208 pflowif->sc_tmpl_ipfix.ipv6_tmpl.src_ip.field_id = 209 htons(PFIX_IE_sourceIPv6Address); 210 pflowif->sc_tmpl_ipfix.ipv6_tmpl.src_ip.len = htons(16); 211 pflowif->sc_tmpl_ipfix.ipv6_tmpl.dest_ip.field_id = 212 htons(PFIX_IE_destinationIPv6Address); 213 pflowif->sc_tmpl_ipfix.ipv6_tmpl.dest_ip.len = htons(16); 214 pflowif->sc_tmpl_ipfix.ipv6_tmpl.if_index_in.field_id = 215 htons(PFIX_IE_ingressInterface); 216 pflowif->sc_tmpl_ipfix.ipv6_tmpl.if_index_in.len = htons(4); 217 pflowif->sc_tmpl_ipfix.ipv6_tmpl.if_index_out.field_id = 218 htons(PFIX_IE_egressInterface); 219 pflowif->sc_tmpl_ipfix.ipv6_tmpl.if_index_out.len = htons(4); 220 pflowif->sc_tmpl_ipfix.ipv6_tmpl.packets.field_id = 221 htons(PFIX_IE_packetDeltaCount); 222 pflowif->sc_tmpl_ipfix.ipv6_tmpl.packets.len = htons(8); 223 pflowif->sc_tmpl_ipfix.ipv6_tmpl.octets.field_id = 224 htons(PFIX_IE_octetDeltaCount); 225 pflowif->sc_tmpl_ipfix.ipv6_tmpl.octets.len = htons(8); 226 pflowif->sc_tmpl_ipfix.ipv6_tmpl.start.field_id = 227 htons(PFIX_IE_flowStartMilliseconds); 228 pflowif->sc_tmpl_ipfix.ipv6_tmpl.start.len = htons(8); 229 pflowif->sc_tmpl_ipfix.ipv6_tmpl.finish.field_id = 230 htons(PFIX_IE_flowEndMilliseconds); 231 pflowif->sc_tmpl_ipfix.ipv6_tmpl.finish.len = htons(8); 232 pflowif->sc_tmpl_ipfix.ipv6_tmpl.src_port.field_id = 233 htons(PFIX_IE_sourceTransportPort); 234 pflowif->sc_tmpl_ipfix.ipv6_tmpl.src_port.len = htons(2); 235 pflowif->sc_tmpl_ipfix.ipv6_tmpl.dest_port.field_id = 236 htons(PFIX_IE_destinationTransportPort); 237 pflowif->sc_tmpl_ipfix.ipv6_tmpl.dest_port.len = htons(2); 238 pflowif->sc_tmpl_ipfix.ipv6_tmpl.tos.field_id = 239 htons(PFIX_IE_ipClassOfService); 240 pflowif->sc_tmpl_ipfix.ipv6_tmpl.tos.len = htons(1); 241 pflowif->sc_tmpl_ipfix.ipv6_tmpl.protocol.field_id = 242 htons(PFIX_IE_protocolIdentifier); 243 pflowif->sc_tmpl_ipfix.ipv6_tmpl.protocol.len = htons(1); 244 245 ifp = &pflowif->sc_if; 246 snprintf(ifp->if_xname, sizeof ifp->if_xname, "pflow%d", unit); 247 ifp->if_softc = pflowif; 248 ifp->if_ioctl = pflowioctl; 249 ifp->if_output = pflow_output; 250 ifp->if_start = NULL; 251 ifp->if_xflags = IFXF_CLONED; 252 ifp->if_type = IFT_PFLOW; 253 ifp->if_hdrlen = PFLOW_HDRLEN; 254 ifp->if_flags = IFF_UP; 255 ifp->if_flags &= ~IFF_RUNNING; /* not running, need receiver */ 256 mq_init(&pflowif->sc_outputqueue, 8192, IPL_SOFTNET); 257 pflow_setmtu(pflowif, ETHERMTU); 258 pflow_init_timeouts(pflowif); 259 if_counters_alloc(ifp); 260 if_attach(ifp); 261 if_alloc_sadl(ifp); 262 263 task_set(&pflowif->sc_outputtask, pflow_output_process, pflowif); 264 265 /* Insert into list of pflows */ 266 NET_LOCK(); 267 SLIST_INSERT_HEAD(&pflowif_list, pflowif, sc_next); 268 NET_UNLOCK(); 269 return (0); 270 } 271 272 int 273 pflow_clone_destroy(struct ifnet *ifp) 274 { 275 struct pflow_softc *sc = ifp->if_softc; 276 int error; 277 278 error = 0; 279 280 NET_LOCK(); 281 sc->sc_dying = 1; 282 SLIST_REMOVE(&pflowif_list, sc, pflow_softc, sc_next); 283 NET_UNLOCK(); 284 285 if (timeout_initialized(&sc->sc_tmo)) 286 timeout_del(&sc->sc_tmo); 287 if (timeout_initialized(&sc->sc_tmo6)) 288 timeout_del(&sc->sc_tmo6); 289 if (timeout_initialized(&sc->sc_tmo_tmpl)) 290 timeout_del(&sc->sc_tmo_tmpl); 291 pflow_flush(sc); 292 task_del(net_tq(ifp->if_index), &sc->sc_outputtask); 293 taskq_barrier(net_tq(ifp->if_index)); 294 mq_purge(&sc->sc_outputqueue); 295 m_freem(sc->send_nam); 296 if (sc->so != NULL) { 297 error = soclose(sc->so, MSG_DONTWAIT); 298 sc->so = NULL; 299 } 300 if (sc->sc_flowdst != NULL) 301 free(sc->sc_flowdst, M_DEVBUF, sc->sc_flowdst->sa_len); 302 if (sc->sc_flowsrc != NULL) 303 free(sc->sc_flowsrc, M_DEVBUF, sc->sc_flowsrc->sa_len); 304 if_detach(ifp); 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, MSG_DONTWAIT); 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, MSG_DONTWAIT); 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 441 MGET(m, M_WAIT, MT_SONAME); 442 m->m_len = sc->sc_flowsrc->sa_len; 443 sa = mtod(m, struct sockaddr *); 444 memcpy(sa, sc->sc_flowsrc, 445 sc->sc_flowsrc->sa_len); 446 447 solock(so); 448 error = sobind(so, m, p); 449 sounlock(so); 450 m_freem(m); 451 if (error) { 452 soclose(so, MSG_DONTWAIT); 453 return (error); 454 } 455 } 456 sc->so = so; 457 } 458 } else if (!pflowvalidsockaddr(sc->sc_flowdst, 0)) { 459 soclose(sc->so, MSG_DONTWAIT); 460 sc->so = NULL; 461 } 462 463 /* error check is above */ 464 if (pflowr->addrmask & PFLOW_MASK_VERSION) 465 sc->sc_version = pflowr->version; 466 467 pflow_setmtu(sc, ETHERMTU); 468 pflow_init_timeouts(sc); 469 470 return (0); 471 } 472 473 int 474 pflowioctl(struct ifnet *ifp, u_long cmd, caddr_t data) 475 { 476 struct proc *p = curproc; 477 struct pflow_softc *sc = ifp->if_softc; 478 struct ifreq *ifr = (struct ifreq *)data; 479 struct pflowreq pflowr; 480 int error; 481 482 if (sc->sc_dying) 483 return ENXIO; 484 485 switch (cmd) { 486 case SIOCSIFADDR: 487 case SIOCSIFDSTADDR: 488 case SIOCSIFFLAGS: 489 /* XXXSMP: enforce lock order */ 490 NET_UNLOCK(); 491 rw_enter_read(&sc->sc_lock); 492 NET_LOCK(); 493 if ((ifp->if_flags & IFF_UP) && sc->so != NULL) { 494 ifp->if_flags |= IFF_RUNNING; 495 sc->sc_gcounter=pflowstats.pflow_flows; 496 /* send templates on startup */ 497 if (sc->sc_version == PFLOW_PROTO_10) 498 pflow_sendout_ipfix_tmpl(sc); 499 } else 500 ifp->if_flags &= ~IFF_RUNNING; 501 rw_exit_read(&sc->sc_lock); 502 break; 503 case SIOCSIFMTU: 504 if (ifr->ifr_mtu < PFLOW_MINMTU) 505 return (EINVAL); 506 if (ifr->ifr_mtu > MCLBYTES) 507 ifr->ifr_mtu = MCLBYTES; 508 if (ifr->ifr_mtu < ifp->if_mtu) 509 pflow_flush(sc); 510 pflow_setmtu(sc, ifr->ifr_mtu); 511 break; 512 513 case SIOCGETPFLOW: 514 bzero(&pflowr, sizeof(pflowr)); 515 516 if (sc->sc_flowsrc != NULL) 517 memcpy(&pflowr.flowsrc, sc->sc_flowsrc, 518 sc->sc_flowsrc->sa_len); 519 if (sc->sc_flowdst != NULL) 520 memcpy(&pflowr.flowdst, sc->sc_flowdst, 521 sc->sc_flowdst->sa_len); 522 pflowr.version = sc->sc_version; 523 524 if ((error = copyout(&pflowr, ifr->ifr_data, 525 sizeof(pflowr)))) 526 return (error); 527 break; 528 529 case SIOCSETPFLOW: 530 if ((error = suser(p)) != 0) 531 return (error); 532 if ((error = copyin(ifr->ifr_data, &pflowr, 533 sizeof(pflowr)))) 534 return (error); 535 536 /* XXXSMP breaks atomicity */ 537 NET_UNLOCK(); 538 rw_enter_write(&sc->sc_lock); 539 error = pflow_set(sc, &pflowr); 540 NET_LOCK(); 541 if (error != 0) { 542 rw_exit_write(&sc->sc_lock); 543 return (error); 544 } 545 546 if ((ifp->if_flags & IFF_UP) && sc->so != NULL) { 547 ifp->if_flags |= IFF_RUNNING; 548 sc->sc_gcounter=pflowstats.pflow_flows; 549 if (sc->sc_version == PFLOW_PROTO_10) 550 pflow_sendout_ipfix_tmpl(sc); 551 } else 552 ifp->if_flags &= ~IFF_RUNNING; 553 rw_exit_write(&sc->sc_lock); 554 555 break; 556 557 default: 558 return (ENOTTY); 559 } 560 return (0); 561 } 562 563 void 564 pflow_init_timeouts(struct pflow_softc *sc) 565 { 566 switch (sc->sc_version) { 567 case PFLOW_PROTO_5: 568 if (timeout_initialized(&sc->sc_tmo6)) 569 timeout_del(&sc->sc_tmo6); 570 if (timeout_initialized(&sc->sc_tmo_tmpl)) 571 timeout_del(&sc->sc_tmo_tmpl); 572 if (!timeout_initialized(&sc->sc_tmo)) 573 timeout_set_proc(&sc->sc_tmo, pflow_timeout, sc); 574 break; 575 case PFLOW_PROTO_10: 576 if (!timeout_initialized(&sc->sc_tmo_tmpl)) 577 timeout_set_proc(&sc->sc_tmo_tmpl, pflow_timeout_tmpl, 578 sc); 579 if (!timeout_initialized(&sc->sc_tmo)) 580 timeout_set_proc(&sc->sc_tmo, pflow_timeout, sc); 581 if (!timeout_initialized(&sc->sc_tmo6)) 582 timeout_set_proc(&sc->sc_tmo6, pflow_timeout6, sc); 583 584 timeout_add_sec(&sc->sc_tmo_tmpl, PFLOW_TMPL_TIMEOUT); 585 break; 586 default: /* NOTREACHED */ 587 break; 588 } 589 } 590 591 int 592 pflow_calc_mtu(struct pflow_softc *sc, int mtu, int hdrsz) 593 { 594 595 sc->sc_maxcount4 = (mtu - hdrsz - 596 sizeof(struct udpiphdr)) / sizeof(struct pflow_ipfix_flow4); 597 sc->sc_maxcount6 = (mtu - hdrsz - 598 sizeof(struct udpiphdr)) / sizeof(struct pflow_ipfix_flow6); 599 if (sc->sc_maxcount4 > PFLOW_MAXFLOWS) 600 sc->sc_maxcount4 = PFLOW_MAXFLOWS; 601 if (sc->sc_maxcount6 > PFLOW_MAXFLOWS) 602 sc->sc_maxcount6 = PFLOW_MAXFLOWS; 603 return (hdrsz + sizeof(struct udpiphdr) + 604 MIN(sc->sc_maxcount4 * sizeof(struct pflow_ipfix_flow4), 605 sc->sc_maxcount6 * sizeof(struct pflow_ipfix_flow6))); 606 } 607 608 void 609 pflow_setmtu(struct pflow_softc *sc, int mtu_req) 610 { 611 int mtu; 612 613 mtu = mtu_req; 614 615 switch (sc->sc_version) { 616 case PFLOW_PROTO_5: 617 sc->sc_maxcount = (mtu - sizeof(struct pflow_header) - 618 sizeof(struct udpiphdr)) / sizeof(struct pflow_flow); 619 if (sc->sc_maxcount > PFLOW_MAXFLOWS) 620 sc->sc_maxcount = PFLOW_MAXFLOWS; 621 sc->sc_if.if_mtu = sizeof(struct pflow_header) + 622 sizeof(struct udpiphdr) + 623 sc->sc_maxcount * sizeof(struct pflow_flow); 624 break; 625 case PFLOW_PROTO_10: 626 sc->sc_if.if_mtu = 627 pflow_calc_mtu(sc, mtu, sizeof(struct pflow_v10_header)); 628 break; 629 default: /* NOTREACHED */ 630 break; 631 } 632 } 633 634 struct mbuf * 635 pflow_get_mbuf(struct pflow_softc *sc, u_int16_t set_id) 636 { 637 struct pflow_set_header set_hdr; 638 struct pflow_header h; 639 struct mbuf *m; 640 641 MGETHDR(m, M_DONTWAIT, MT_DATA); 642 if (m == NULL) { 643 pflowstats.pflow_onomem++; 644 return (NULL); 645 } 646 647 MCLGET(m, M_DONTWAIT); 648 if ((m->m_flags & M_EXT) == 0) { 649 m_free(m); 650 pflowstats.pflow_onomem++; 651 return (NULL); 652 } 653 654 m->m_len = m->m_pkthdr.len = 0; 655 m->m_pkthdr.ph_ifidx = 0; 656 657 if (sc == NULL) /* get only a new empty mbuf */ 658 return (m); 659 660 switch (sc->sc_version) { 661 case PFLOW_PROTO_5: 662 /* populate pflow_header */ 663 h.reserved1 = 0; 664 h.reserved2 = 0; 665 h.count = 0; 666 h.version = htons(PFLOW_PROTO_5); 667 h.flow_sequence = htonl(sc->sc_gcounter); 668 h.engine_type = PFLOW_ENGINE_TYPE; 669 h.engine_id = PFLOW_ENGINE_ID; 670 m_copyback(m, 0, PFLOW_HDRLEN, &h, M_NOWAIT); 671 672 sc->sc_count = 0; 673 timeout_add_sec(&sc->sc_tmo, PFLOW_TIMEOUT); 674 break; 675 case PFLOW_PROTO_10: 676 /* populate pflow_set_header */ 677 set_hdr.set_length = 0; 678 set_hdr.set_id = htons(set_id); 679 m_copyback(m, 0, PFLOW_SET_HDRLEN, &set_hdr, M_NOWAIT); 680 break; 681 default: /* NOTREACHED */ 682 break; 683 } 684 685 return (m); 686 } 687 688 void 689 copy_flow_data(struct pflow_flow *flow1, struct pflow_flow *flow2, 690 struct pf_state *st, struct pf_state_key *sk, int src, int dst) 691 { 692 flow1->src_ip = flow2->dest_ip = sk->addr[src].v4.s_addr; 693 flow1->src_port = flow2->dest_port = sk->port[src]; 694 flow1->dest_ip = flow2->src_ip = sk->addr[dst].v4.s_addr; 695 flow1->dest_port = flow2->src_port = sk->port[dst]; 696 697 flow1->dest_as = flow2->src_as = 698 flow1->src_as = flow2->dest_as = 0; 699 flow1->if_index_in = htons(st->if_index_in); 700 flow1->if_index_out = htons(st->if_index_out); 701 flow2->if_index_in = htons(st->if_index_out); 702 flow2->if_index_out = htons(st->if_index_in); 703 flow1->dest_mask = flow2->src_mask = 704 flow1->src_mask = flow2->dest_mask = 0; 705 706 flow1->flow_packets = htonl(st->packets[0]); 707 flow2->flow_packets = htonl(st->packets[1]); 708 flow1->flow_octets = htonl(st->bytes[0]); 709 flow2->flow_octets = htonl(st->bytes[1]); 710 711 /* 712 * Pretend the flow was created or expired when the machine came up 713 * when creation is in the future of the last time a package was seen 714 * or was created / expired before this machine came up due to pfsync. 715 */ 716 flow1->flow_start = flow2->flow_start = st->creation < 0 || 717 st->creation > st->expire ? htonl(0) : htonl(st->creation * 1000); 718 flow1->flow_finish = flow2->flow_finish = st->expire < 0 ? htonl(0) : 719 htonl(st->expire * 1000); 720 flow1->tcp_flags = flow2->tcp_flags = 0; 721 flow1->protocol = flow2->protocol = sk->proto; 722 flow1->tos = flow2->tos = st->rule.ptr->tos; 723 } 724 725 void 726 copy_flow_ipfix_4_data(struct pflow_ipfix_flow4 *flow1, 727 struct pflow_ipfix_flow4 *flow2, struct pf_state *st, 728 struct pf_state_key *sk, struct pflow_softc *sc, int src, int dst) 729 { 730 flow1->src_ip = flow2->dest_ip = sk->addr[src].v4.s_addr; 731 flow1->src_port = flow2->dest_port = sk->port[src]; 732 flow1->dest_ip = flow2->src_ip = sk->addr[dst].v4.s_addr; 733 flow1->dest_port = flow2->src_port = sk->port[dst]; 734 735 flow1->if_index_in = htonl(st->if_index_in); 736 flow1->if_index_out = htonl(st->if_index_out); 737 flow2->if_index_in = htonl(st->if_index_out); 738 flow2->if_index_out = htonl(st->if_index_in); 739 740 flow1->flow_packets = htobe64(st->packets[0]); 741 flow2->flow_packets = htobe64(st->packets[1]); 742 flow1->flow_octets = htobe64(st->bytes[0]); 743 flow2->flow_octets = htobe64(st->bytes[1]); 744 745 /* 746 * Pretend the flow was created when the machine came up when creation 747 * is in the future of the last time a package was seen due to pfsync. 748 */ 749 if (st->creation > st->expire) 750 flow1->flow_start = flow2->flow_start = htobe64((gettime() - 751 getuptime())*1000); 752 else 753 flow1->flow_start = flow2->flow_start = htobe64((gettime() - 754 (getuptime() - st->creation))*1000); 755 flow1->flow_finish = flow2->flow_finish = htobe64((gettime() - 756 (getuptime() - st->expire))*1000); 757 758 flow1->protocol = flow2->protocol = sk->proto; 759 flow1->tos = flow2->tos = st->rule.ptr->tos; 760 } 761 762 void 763 copy_flow_ipfix_6_data(struct pflow_ipfix_flow6 *flow1, 764 struct pflow_ipfix_flow6 *flow2, struct pf_state *st, 765 struct pf_state_key *sk, struct pflow_softc *sc, int src, int dst) 766 { 767 bcopy(&sk->addr[src].v6, &flow1->src_ip, sizeof(flow1->src_ip)); 768 bcopy(&sk->addr[src].v6, &flow2->dest_ip, sizeof(flow2->dest_ip)); 769 flow1->src_port = flow2->dest_port = sk->port[src]; 770 bcopy(&sk->addr[dst].v6, &flow1->dest_ip, sizeof(flow1->dest_ip)); 771 bcopy(&sk->addr[dst].v6, &flow2->src_ip, sizeof(flow2->src_ip)); 772 flow1->dest_port = flow2->src_port = sk->port[dst]; 773 774 flow1->if_index_in = htonl(st->if_index_in); 775 flow1->if_index_out = htonl(st->if_index_out); 776 flow2->if_index_in = htonl(st->if_index_out); 777 flow2->if_index_out = htonl(st->if_index_in); 778 779 flow1->flow_packets = htobe64(st->packets[0]); 780 flow2->flow_packets = htobe64(st->packets[1]); 781 flow1->flow_octets = htobe64(st->bytes[0]); 782 flow2->flow_octets = htobe64(st->bytes[1]); 783 784 /* 785 * Pretend the flow was created when the machine came up when creation 786 * is in the future of the last time a package was seen due to pfsync. 787 */ 788 if (st->creation > st->expire) 789 flow1->flow_start = flow2->flow_start = htobe64((gettime() - 790 getuptime())*1000); 791 else 792 flow1->flow_start = flow2->flow_start = htobe64((gettime() - 793 (getuptime() - st->creation))*1000); 794 flow1->flow_finish = flow2->flow_finish = htobe64((gettime() - 795 (getuptime() - st->expire))*1000); 796 797 flow1->protocol = flow2->protocol = sk->proto; 798 flow1->tos = flow2->tos = st->rule.ptr->tos; 799 } 800 801 int 802 export_pflow(struct pf_state *st) 803 { 804 struct pflow_softc *sc = NULL; 805 struct pf_state_key *sk; 806 807 sk = st->key[st->direction == PF_IN ? PF_SK_WIRE : PF_SK_STACK]; 808 809 SLIST_FOREACH(sc, &pflowif_list, sc_next) { 810 switch (sc->sc_version) { 811 case PFLOW_PROTO_5: 812 if( sk->af == AF_INET ) 813 export_pflow_if(st, sk, sc); 814 break; 815 case PFLOW_PROTO_10: 816 if( sk->af == AF_INET || sk->af == AF_INET6 ) 817 export_pflow_if(st, sk, sc); 818 break; 819 default: /* NOTREACHED */ 820 break; 821 } 822 } 823 824 return (0); 825 } 826 827 int 828 export_pflow_if(struct pf_state *st, struct pf_state_key *sk, 829 struct pflow_softc *sc) 830 { 831 struct pf_state pfs_copy; 832 struct ifnet *ifp = &sc->sc_if; 833 u_int64_t bytes[2]; 834 int ret = 0; 835 836 if (!(ifp->if_flags & IFF_RUNNING)) 837 return (0); 838 839 if (sc->sc_version == PFLOW_PROTO_10) 840 return (pflow_pack_flow_ipfix(st, sk, sc)); 841 842 /* PFLOW_PROTO_5 */ 843 if ((st->bytes[0] < (u_int64_t)PFLOW_MAXBYTES) 844 && (st->bytes[1] < (u_int64_t)PFLOW_MAXBYTES)) 845 return (pflow_pack_flow(st, sk, sc)); 846 847 /* flow > PFLOW_MAXBYTES need special handling */ 848 bcopy(st, &pfs_copy, sizeof(pfs_copy)); 849 bytes[0] = pfs_copy.bytes[0]; 850 bytes[1] = pfs_copy.bytes[1]; 851 852 while (bytes[0] > PFLOW_MAXBYTES) { 853 pfs_copy.bytes[0] = PFLOW_MAXBYTES; 854 pfs_copy.bytes[1] = 0; 855 856 if ((ret = pflow_pack_flow(&pfs_copy, sk, sc)) != 0) 857 return (ret); 858 if ((bytes[0] - PFLOW_MAXBYTES) > 0) 859 bytes[0] -= PFLOW_MAXBYTES; 860 } 861 862 while (bytes[1] > (u_int64_t)PFLOW_MAXBYTES) { 863 pfs_copy.bytes[1] = PFLOW_MAXBYTES; 864 pfs_copy.bytes[0] = 0; 865 866 if ((ret = pflow_pack_flow(&pfs_copy, sk, sc)) != 0) 867 return (ret); 868 if ((bytes[1] - PFLOW_MAXBYTES) > 0) 869 bytes[1] -= PFLOW_MAXBYTES; 870 } 871 872 pfs_copy.bytes[0] = bytes[0]; 873 pfs_copy.bytes[1] = bytes[1]; 874 875 return (pflow_pack_flow(&pfs_copy, sk, sc)); 876 } 877 878 int 879 copy_flow_to_m(struct pflow_flow *flow, struct pflow_softc *sc) 880 { 881 int ret = 0; 882 883 if (sc->sc_mbuf == NULL) { 884 if ((sc->sc_mbuf = pflow_get_mbuf(sc, 0)) == NULL) 885 return (ENOBUFS); 886 } 887 m_copyback(sc->sc_mbuf, PFLOW_HDRLEN + 888 (sc->sc_count * sizeof(struct pflow_flow)), 889 sizeof(struct pflow_flow), flow, M_NOWAIT); 890 891 if (pflowstats.pflow_flows == sc->sc_gcounter) 892 pflowstats.pflow_flows++; 893 sc->sc_gcounter++; 894 sc->sc_count++; 895 896 if (sc->sc_count >= sc->sc_maxcount) 897 ret = pflow_sendout_v5(sc); 898 899 return(ret); 900 } 901 902 int 903 copy_flow_ipfix_4_to_m(struct pflow_ipfix_flow4 *flow, struct pflow_softc *sc) 904 { 905 int ret = 0; 906 907 if (sc->sc_mbuf == NULL) { 908 if ((sc->sc_mbuf = 909 pflow_get_mbuf(sc, PFLOW_IPFIX_TMPL_IPV4_ID)) == NULL) { 910 return (ENOBUFS); 911 } 912 sc->sc_count4 = 0; 913 timeout_add_sec(&sc->sc_tmo, PFLOW_TIMEOUT); 914 } 915 m_copyback(sc->sc_mbuf, PFLOW_SET_HDRLEN + 916 (sc->sc_count4 * sizeof(struct pflow_ipfix_flow4)), 917 sizeof(struct pflow_ipfix_flow4), flow, M_NOWAIT); 918 919 if (pflowstats.pflow_flows == sc->sc_gcounter) 920 pflowstats.pflow_flows++; 921 sc->sc_gcounter++; 922 sc->sc_count4++; 923 924 if (sc->sc_count4 >= sc->sc_maxcount4) 925 ret = pflow_sendout_ipfix(sc, AF_INET); 926 return(ret); 927 } 928 929 int 930 copy_flow_ipfix_6_to_m(struct pflow_ipfix_flow6 *flow, struct pflow_softc *sc) 931 { 932 int ret = 0; 933 934 if (sc->sc_mbuf6 == NULL) { 935 if ((sc->sc_mbuf6 = 936 pflow_get_mbuf(sc, PFLOW_IPFIX_TMPL_IPV6_ID)) == NULL) { 937 return (ENOBUFS); 938 } 939 sc->sc_count6 = 0; 940 timeout_add_sec(&sc->sc_tmo6, PFLOW_TIMEOUT); 941 } 942 m_copyback(sc->sc_mbuf6, PFLOW_SET_HDRLEN + 943 (sc->sc_count6 * sizeof(struct pflow_ipfix_flow6)), 944 sizeof(struct pflow_ipfix_flow6), flow, M_NOWAIT); 945 946 if (pflowstats.pflow_flows == sc->sc_gcounter) 947 pflowstats.pflow_flows++; 948 sc->sc_gcounter++; 949 sc->sc_count6++; 950 951 if (sc->sc_count6 >= sc->sc_maxcount6) 952 ret = pflow_sendout_ipfix(sc, AF_INET6); 953 954 return(ret); 955 } 956 957 int 958 pflow_pack_flow(struct pf_state *st, struct pf_state_key *sk, 959 struct pflow_softc *sc) 960 { 961 struct pflow_flow flow1; 962 struct pflow_flow flow2; 963 int ret = 0; 964 965 bzero(&flow1, sizeof(flow1)); 966 bzero(&flow2, sizeof(flow2)); 967 968 if (st->direction == PF_OUT) 969 copy_flow_data(&flow1, &flow2, st, sk, 1, 0); 970 else 971 copy_flow_data(&flow1, &flow2, st, sk, 0, 1); 972 973 if (st->bytes[0] != 0) /* first flow from state */ 974 ret = copy_flow_to_m(&flow1, sc); 975 976 if (st->bytes[1] != 0) /* second flow from state */ 977 ret = copy_flow_to_m(&flow2, sc); 978 979 return (ret); 980 } 981 982 int 983 pflow_pack_flow_ipfix(struct pf_state *st, struct pf_state_key *sk, 984 struct pflow_softc *sc) 985 { 986 struct pflow_ipfix_flow4 flow4_1, flow4_2; 987 struct pflow_ipfix_flow6 flow6_1, flow6_2; 988 int ret = 0; 989 if (sk->af == AF_INET) { 990 bzero(&flow4_1, sizeof(flow4_1)); 991 bzero(&flow4_2, sizeof(flow4_2)); 992 993 if (st->direction == PF_OUT) 994 copy_flow_ipfix_4_data(&flow4_1, &flow4_2, st, sk, sc, 995 1, 0); 996 else 997 copy_flow_ipfix_4_data(&flow4_1, &flow4_2, st, sk, sc, 998 0, 1); 999 1000 if (st->bytes[0] != 0) /* first flow from state */ 1001 ret = copy_flow_ipfix_4_to_m(&flow4_1, sc); 1002 1003 if (st->bytes[1] != 0) /* second flow from state */ 1004 ret = copy_flow_ipfix_4_to_m(&flow4_2, sc); 1005 } else if (sk->af == AF_INET6) { 1006 bzero(&flow6_1, sizeof(flow6_1)); 1007 bzero(&flow6_2, sizeof(flow6_2)); 1008 1009 if (st->direction == PF_OUT) 1010 copy_flow_ipfix_6_data(&flow6_1, &flow6_2, st, sk, sc, 1011 1, 0); 1012 else 1013 copy_flow_ipfix_6_data(&flow6_1, &flow6_2, st, sk, sc, 1014 0, 1); 1015 1016 if (st->bytes[0] != 0) /* first flow from state */ 1017 ret = copy_flow_ipfix_6_to_m(&flow6_1, sc); 1018 1019 if (st->bytes[1] != 0) /* second flow from state */ 1020 ret = copy_flow_ipfix_6_to_m(&flow6_2, sc); 1021 } 1022 return (ret); 1023 } 1024 1025 void 1026 pflow_timeout(void *v) 1027 { 1028 struct pflow_softc *sc = v; 1029 1030 switch (sc->sc_version) { 1031 case PFLOW_PROTO_5: 1032 pflow_sendout_v5(sc); 1033 break; 1034 case PFLOW_PROTO_10: 1035 pflow_sendout_ipfix(sc, AF_INET); 1036 break; 1037 default: /* NOTREACHED */ 1038 break; 1039 } 1040 } 1041 1042 void 1043 pflow_timeout6(void *v) 1044 { 1045 struct pflow_softc *sc = v; 1046 1047 pflow_sendout_ipfix(sc, AF_INET6); 1048 } 1049 1050 void 1051 pflow_timeout_tmpl(void *v) 1052 { 1053 struct pflow_softc *sc = v; 1054 1055 pflow_sendout_ipfix_tmpl(sc); 1056 } 1057 1058 void 1059 pflow_flush(struct pflow_softc *sc) 1060 { 1061 switch (sc->sc_version) { 1062 case PFLOW_PROTO_5: 1063 pflow_sendout_v5(sc); 1064 break; 1065 case PFLOW_PROTO_10: 1066 pflow_sendout_ipfix(sc, AF_INET); 1067 pflow_sendout_ipfix(sc, AF_INET6); 1068 break; 1069 default: /* NOTREACHED */ 1070 break; 1071 } 1072 } 1073 1074 int 1075 pflow_sendout_v5(struct pflow_softc *sc) 1076 { 1077 struct mbuf *m = sc->sc_mbuf; 1078 struct pflow_header *h; 1079 struct ifnet *ifp = &sc->sc_if; 1080 struct timespec tv; 1081 1082 timeout_del(&sc->sc_tmo); 1083 1084 if (m == NULL) 1085 return (0); 1086 1087 sc->sc_mbuf = NULL; 1088 if (!(ifp->if_flags & IFF_RUNNING)) { 1089 m_freem(m); 1090 return (0); 1091 } 1092 1093 pflowstats.pflow_packets++; 1094 h = mtod(m, struct pflow_header *); 1095 h->count = htons(sc->sc_count); 1096 1097 /* populate pflow_header */ 1098 h->uptime_ms = htonl(getuptime() * 1000); 1099 1100 getnanotime(&tv); 1101 h->time_sec = htonl(tv.tv_sec); /* XXX 2038 */ 1102 h->time_nanosec = htonl(tv.tv_nsec); 1103 if (mq_enqueue(&sc->sc_outputqueue, m) == 0) 1104 task_add(net_tq(ifp->if_index), &sc->sc_outputtask); 1105 return (0); 1106 } 1107 1108 int 1109 pflow_sendout_ipfix(struct pflow_softc *sc, sa_family_t af) 1110 { 1111 struct mbuf *m; 1112 struct pflow_v10_header *h10; 1113 struct pflow_set_header *set_hdr; 1114 struct ifnet *ifp = &sc->sc_if; 1115 u_int32_t count; 1116 int set_length; 1117 1118 switch (af) { 1119 case AF_INET: 1120 m = sc->sc_mbuf; 1121 timeout_del(&sc->sc_tmo); 1122 if (m == NULL) 1123 return (0); 1124 sc->sc_mbuf = NULL; 1125 count = sc->sc_count4; 1126 set_length = sizeof(struct pflow_set_header) 1127 + sc->sc_count4 * sizeof(struct pflow_ipfix_flow4); 1128 break; 1129 case AF_INET6: 1130 m = sc->sc_mbuf6; 1131 timeout_del(&sc->sc_tmo6); 1132 if (m == NULL) 1133 return (0); 1134 sc->sc_mbuf6 = NULL; 1135 count = sc->sc_count6; 1136 set_length = sizeof(struct pflow_set_header) 1137 + sc->sc_count6 * sizeof(struct pflow_ipfix_flow6); 1138 break; 1139 default: 1140 unhandled_af(af); 1141 } 1142 1143 if (!(ifp->if_flags & IFF_RUNNING)) { 1144 m_freem(m); 1145 return (0); 1146 } 1147 1148 pflowstats.pflow_packets++; 1149 set_hdr = mtod(m, struct pflow_set_header *); 1150 set_hdr->set_length = htons(set_length); 1151 1152 /* populate pflow_header */ 1153 M_PREPEND(m, sizeof(struct pflow_v10_header), M_DONTWAIT); 1154 if (m == NULL) { 1155 pflowstats.pflow_onomem++; 1156 return (ENOBUFS); 1157 } 1158 h10 = mtod(m, struct pflow_v10_header *); 1159 h10->version = htons(PFLOW_PROTO_10); 1160 h10->length = htons(PFLOW_IPFIX_HDRLEN + set_length); 1161 h10->time_sec = htonl(gettime()); /* XXX 2038 */ 1162 h10->flow_sequence = htonl(sc->sc_sequence); 1163 sc->sc_sequence += count; 1164 h10->observation_dom = htonl(PFLOW_ENGINE_TYPE); 1165 if (mq_enqueue(&sc->sc_outputqueue, m) == 0) 1166 task_add(net_tq(ifp->if_index), &sc->sc_outputtask); 1167 return (0); 1168 } 1169 1170 int 1171 pflow_sendout_ipfix_tmpl(struct pflow_softc *sc) 1172 { 1173 struct mbuf *m; 1174 struct pflow_v10_header *h10; 1175 struct ifnet *ifp = &sc->sc_if; 1176 1177 timeout_del(&sc->sc_tmo_tmpl); 1178 1179 if (!(ifp->if_flags & IFF_RUNNING)) { 1180 return (0); 1181 } 1182 m = pflow_get_mbuf(NULL, 0); 1183 if (m == NULL) 1184 return (0); 1185 if (m_copyback(m, 0, sizeof(struct pflow_ipfix_tmpl), 1186 &sc->sc_tmpl_ipfix, M_NOWAIT)) { 1187 m_freem(m); 1188 return (0); 1189 } 1190 pflowstats.pflow_packets++; 1191 1192 /* populate pflow_header */ 1193 M_PREPEND(m, sizeof(struct pflow_v10_header), M_DONTWAIT); 1194 if (m == NULL) { 1195 pflowstats.pflow_onomem++; 1196 return (ENOBUFS); 1197 } 1198 h10 = mtod(m, struct pflow_v10_header *); 1199 h10->version = htons(PFLOW_PROTO_10); 1200 h10->length = htons(PFLOW_IPFIX_HDRLEN + sizeof(struct 1201 pflow_ipfix_tmpl)); 1202 h10->time_sec = htonl(gettime()); /* XXX 2038 */ 1203 h10->flow_sequence = htonl(sc->sc_sequence); 1204 h10->observation_dom = htonl(PFLOW_ENGINE_TYPE); 1205 1206 timeout_add_sec(&sc->sc_tmo_tmpl, PFLOW_TMPL_TIMEOUT); 1207 if (mq_enqueue(&sc->sc_outputqueue, m) == 0) 1208 task_add(net_tq(ifp->if_index), &sc->sc_outputtask); 1209 return (0); 1210 } 1211 1212 int 1213 pflow_sendout_mbuf(struct pflow_softc *sc, struct mbuf *m) 1214 { 1215 counters_pkt(sc->sc_if.if_counters, 1216 ifc_opackets, ifc_obytes, m->m_pkthdr.len); 1217 1218 if (sc->so == NULL) { 1219 m_freem(m); 1220 return (EINVAL); 1221 } 1222 return (sosend(sc->so, sc->send_nam, NULL, m, NULL, 0)); 1223 } 1224 1225 int 1226 pflow_sysctl(int *name, u_int namelen, void *oldp, size_t *oldlenp, 1227 void *newp, size_t newlen) 1228 { 1229 if (namelen != 1) 1230 return (ENOTDIR); 1231 1232 switch (name[0]) { 1233 case NET_PFLOW_STATS: 1234 if (newp != NULL) 1235 return (EPERM); 1236 return (sysctl_struct(oldp, oldlenp, newp, newlen, 1237 &pflowstats, sizeof(pflowstats))); 1238 default: 1239 return (EOPNOTSUPP); 1240 } 1241 return (0); 1242 } 1243