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