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