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