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