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