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