1 /* $OpenBSD: if_pflow.c,v 1.100 2023/11/09 08:53:20 mvs Exp $ */ 2 3 /* 4 * Copyright (c) 2023 Rubicon Communications, LLC (Netgate) 5 * Copyright (c) 2011 Florian Obser <florian@narrans.de> 6 * Copyright (c) 2011 Sebastian Benoit <benoit-lists@fb12.de> 7 * Copyright (c) 2008 Henning Brauer <henning@openbsd.org> 8 * Copyright (c) 2008 Joerg Goltermann <jg@osn.de> 9 * 10 * Permission to use, copy, modify, and distribute this software for any 11 * purpose with or without fee is hereby granted, provided that the above 12 * copyright notice and this permission notice appear in all copies. 13 * 14 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 15 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 16 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 17 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 18 * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER IN 19 * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT 20 * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 21 */ 22 23 #include <sys/cdefs.h> 24 #include <sys/param.h> 25 #include <sys/bus.h> 26 #include <sys/callout.h> 27 #include <sys/endian.h> 28 #include <sys/interrupt.h> 29 #include <sys/kernel.h> 30 #include <sys/malloc.h> 31 #include <sys/module.h> 32 #include <sys/mbuf.h> 33 #include <sys/socket.h> 34 #include <sys/socketvar.h> 35 #include <sys/sockio.h> 36 #include <sys/sysctl.h> 37 #include <sys/systm.h> 38 #include <sys/priv.h> 39 40 #include <net/if.h> 41 #include <net/if_types.h> 42 #include <net/bpf.h> 43 #include <net/route.h> 44 #include <netinet/in.h> 45 #include <netinet/if_ether.h> 46 #include <netinet/tcp.h> 47 48 #include <netinet/ip.h> 49 #include <netinet/ip_icmp.h> 50 #include <netinet/ip_var.h> 51 #include <netinet/udp.h> 52 #include <netinet/udp_var.h> 53 #include <netinet/in_pcb.h> 54 55 #include <netlink/netlink.h> 56 #include <netlink/netlink_ctl.h> 57 #include <netlink/netlink_generic.h> 58 #include <netlink/netlink_message_writer.h> 59 60 #include <net/pfvar.h> 61 #include <net/pflow.h> 62 #include "net/if_var.h" 63 64 #define PFLOW_MINMTU \ 65 (sizeof(struct pflow_header) + sizeof(struct pflow_flow)) 66 67 #ifdef PFLOWDEBUG 68 #define DPRINTF(x) do { printf x ; } while (0) 69 #else 70 #define DPRINTF(x) 71 #endif 72 73 enum pflow_family_t { 74 PFLOW_INET, 75 PFLOW_INET6, 76 PFLOW_NAT4, 77 }; 78 79 static void pflow_output_process(void *); 80 static int pflow_create(int); 81 static int pflow_destroy(int, bool); 82 static int pflow_calc_mtu(struct pflow_softc *, int, int); 83 static void pflow_setmtu(struct pflow_softc *, int); 84 static int pflowvalidsockaddr(const struct sockaddr *, int); 85 86 static struct mbuf *pflow_get_mbuf(struct pflow_softc *, u_int16_t); 87 static void pflow_flush(struct pflow_softc *); 88 static int pflow_sendout_v5(struct pflow_softc *); 89 static int pflow_sendout_ipfix(struct pflow_softc *, enum pflow_family_t); 90 static int pflow_sendout_ipfix_tmpl(struct pflow_softc *); 91 static int pflow_sendout_mbuf(struct pflow_softc *, struct mbuf *); 92 static int sysctl_pflowstats(SYSCTL_HANDLER_ARGS); 93 static void pflow_timeout(void *); 94 static void pflow_timeout6(void *); 95 static void pflow_timeout_tmpl(void *); 96 static void pflow_timeout_nat4(void *); 97 static void copy_flow_data(struct pflow_flow *, struct pflow_flow *, 98 const struct pf_kstate *, struct pf_state_key *, int, int); 99 static void copy_flow_ipfix_4_data(struct pflow_ipfix_flow4 *, 100 struct pflow_ipfix_flow4 *, const struct pf_kstate *, struct pf_state_key *, 101 struct pflow_softc *, int, int); 102 static void copy_flow_ipfix_6_data(struct pflow_ipfix_flow6 *, 103 struct pflow_ipfix_flow6 *, const struct pf_kstate *, struct pf_state_key *, 104 struct pflow_softc *, int, int); 105 static int pflow_pack_flow(const struct pf_kstate *, struct pf_state_key *, 106 struct pflow_softc *); 107 static int pflow_pack_flow_ipfix(const struct pf_kstate *, struct pf_state_key *, 108 struct pflow_softc *); 109 static void export_pflow(const struct pf_kstate *); 110 static int export_pflow_if(const struct pf_kstate*, struct pf_state_key *, 111 struct pflow_softc *); 112 static int copy_flow_to_m(struct pflow_flow *flow, struct pflow_softc *sc); 113 static int copy_flow_ipfix_4_to_m(struct pflow_ipfix_flow4 *flow, 114 struct pflow_softc *sc); 115 static int copy_flow_ipfix_6_to_m(struct pflow_ipfix_flow6 *flow, 116 struct pflow_softc *sc); 117 static int copy_nat_ipfix_4_to_m(struct pflow_ipfix_nat4 *, 118 const struct pf_kstate *, struct pflow_softc *, 119 uint8_t, uint64_t); 120 121 static const char pflowname[] = "pflow"; 122 123 enum pflowstat_counters { 124 pflow_flows, 125 pflow_packets, 126 pflow_onomem, 127 pflow_oerrors, 128 pflow_ncounters, 129 }; 130 struct pflowstats_ctr { 131 counter_u64_t c[pflow_ncounters]; 132 }; 133 134 /** 135 * Locking concept 136 * 137 * The list of pflow devices (V_pflowif_list) is managed through epoch. 138 * It is safe to read the list without locking (while in NET_EPOCH). 139 * There may only be one simultaneous modifier, hence we need V_pflow_list_mtx 140 * on every add/delete. 141 * 142 * Each pflow interface protects its own data with the sc_lock mutex. 143 * 144 * We do not require any pf locks, and in fact expect to be called without 145 * hashrow locks held. 146 **/ 147 148 VNET_DEFINE(struct unrhdr *, pflow_unr); 149 #define V_pflow_unr VNET(pflow_unr) 150 VNET_DEFINE(CK_LIST_HEAD(, pflow_softc), pflowif_list); 151 #define V_pflowif_list VNET(pflowif_list) 152 VNET_DEFINE(struct mtx, pflowif_list_mtx); 153 #define V_pflowif_list_mtx VNET(pflowif_list_mtx) 154 VNET_DEFINE(struct pflowstats_ctr, pflowstat); 155 #define V_pflowstats VNET(pflowstat) 156 157 #define PFLOW_LOCK(_sc) mtx_lock(&(_sc)->sc_lock) 158 #define PFLOW_UNLOCK(_sc) mtx_unlock(&(_sc)->sc_lock) 159 #define PFLOW_ASSERT(_sc) mtx_assert(&(_sc)->sc_lock, MA_OWNED) 160 161 SYSCTL_NODE(_net, OID_AUTO, pflow, CTLFLAG_RW | CTLFLAG_MPSAFE, 0, 162 "PFLOW"); 163 SYSCTL_PROC(_net_pflow, OID_AUTO, stats, CTLTYPE_OPAQUE | CTLFLAG_RD | CTLFLAG_MPSAFE, 164 0, 0, sysctl_pflowstats, "S,pflowstats", 165 "PFLOW statistics (struct pflowstats, net/if_pflow.h)"); 166 167 static inline void 168 pflowstat_inc(enum pflowstat_counters c) 169 { 170 counter_u64_add(V_pflowstats.c[c], 1); 171 } 172 173 static void 174 vnet_pflowattach(void) 175 { 176 CK_LIST_INIT(&V_pflowif_list); 177 mtx_init(&V_pflowif_list_mtx, "pflow interface list mtx", NULL, MTX_DEF); 178 179 V_pflow_unr = new_unrhdr(0, INT_MAX, &V_pflowif_list_mtx); 180 181 for (int i = 0; i < pflow_ncounters; i++) 182 V_pflowstats.c[i] = counter_u64_alloc(M_WAITOK); 183 } 184 VNET_SYSINIT(vnet_pflowattach, SI_SUB_PROTO_FIREWALL, SI_ORDER_ANY, 185 vnet_pflowattach, NULL); 186 187 static void 188 vnet_pflowdetach(void) 189 { 190 struct pflow_softc *sc; 191 192 CK_LIST_FOREACH(sc, &V_pflowif_list, sc_next) { 193 pflow_destroy(sc->sc_id, false); 194 } 195 196 MPASS(CK_LIST_EMPTY(&V_pflowif_list)); 197 delete_unrhdr(V_pflow_unr); 198 mtx_destroy(&V_pflowif_list_mtx); 199 200 for (int i = 0; i < pflow_ncounters; i++) 201 counter_u64_free(V_pflowstats.c[i]); 202 } 203 VNET_SYSUNINIT(vnet_pflowdetach, SI_SUB_PROTO_FIREWALL, SI_ORDER_FOURTH, 204 vnet_pflowdetach, NULL); 205 206 static void 207 vnet_pflow_finalise(void) 208 { 209 /* 210 * Ensure we've freed all interfaces, and do not have pending 211 * epoch cleanup calls. 212 */ 213 NET_EPOCH_DRAIN_CALLBACKS(); 214 } 215 VNET_SYSUNINIT(vnet_pflow_finalise, SI_SUB_PROTO_FIREWALL, SI_ORDER_THIRD, 216 vnet_pflow_finalise, NULL); 217 218 static void 219 pflow_output_process(void *arg) 220 { 221 struct mbufq ml; 222 struct pflow_softc *sc = arg; 223 struct mbuf *m; 224 225 mbufq_init(&ml, 0); 226 227 PFLOW_LOCK(sc); 228 mbufq_concat(&ml, &sc->sc_outputqueue); 229 PFLOW_UNLOCK(sc); 230 231 CURVNET_SET(sc->sc_vnet); 232 while ((m = mbufq_dequeue(&ml)) != NULL) { 233 pflow_sendout_mbuf(sc, m); 234 } 235 CURVNET_RESTORE(); 236 } 237 238 static int 239 pflow_create(int unit) 240 { 241 struct pflow_softc *pflowif; 242 int error; 243 244 pflowif = malloc(sizeof(*pflowif), M_DEVBUF, M_WAITOK|M_ZERO); 245 mtx_init(&pflowif->sc_lock, "pflowlk", NULL, MTX_DEF); 246 pflowif->sc_version = PFLOW_PROTO_DEFAULT; 247 pflowif->sc_observation_dom = PFLOW_ENGINE_TYPE; 248 249 /* ipfix template init */ 250 bzero(&pflowif->sc_tmpl_ipfix,sizeof(pflowif->sc_tmpl_ipfix)); 251 pflowif->sc_tmpl_ipfix.set_header.set_id = 252 htons(PFLOW_IPFIX_TMPL_SET_ID); 253 pflowif->sc_tmpl_ipfix.set_header.set_length = 254 htons(sizeof(struct pflow_ipfix_tmpl)); 255 256 /* ipfix IPv4 template */ 257 pflowif->sc_tmpl_ipfix.ipv4_tmpl.h.tmpl_id = 258 htons(PFLOW_IPFIX_TMPL_IPV4_ID); 259 pflowif->sc_tmpl_ipfix.ipv4_tmpl.h.field_count 260 = htons(PFLOW_IPFIX_TMPL_IPV4_FIELD_COUNT); 261 pflowif->sc_tmpl_ipfix.ipv4_tmpl.src_ip.field_id = 262 htons(PFIX_IE_sourceIPv4Address); 263 pflowif->sc_tmpl_ipfix.ipv4_tmpl.src_ip.len = htons(4); 264 pflowif->sc_tmpl_ipfix.ipv4_tmpl.dest_ip.field_id = 265 htons(PFIX_IE_destinationIPv4Address); 266 pflowif->sc_tmpl_ipfix.ipv4_tmpl.dest_ip.len = htons(4); 267 pflowif->sc_tmpl_ipfix.ipv4_tmpl.if_index_in.field_id = 268 htons(PFIX_IE_ingressInterface); 269 pflowif->sc_tmpl_ipfix.ipv4_tmpl.if_index_in.len = htons(4); 270 pflowif->sc_tmpl_ipfix.ipv4_tmpl.if_index_out.field_id = 271 htons(PFIX_IE_egressInterface); 272 pflowif->sc_tmpl_ipfix.ipv4_tmpl.if_index_out.len = htons(4); 273 pflowif->sc_tmpl_ipfix.ipv4_tmpl.packets.field_id = 274 htons(PFIX_IE_packetDeltaCount); 275 pflowif->sc_tmpl_ipfix.ipv4_tmpl.packets.len = htons(8); 276 pflowif->sc_tmpl_ipfix.ipv4_tmpl.octets.field_id = 277 htons(PFIX_IE_octetDeltaCount); 278 pflowif->sc_tmpl_ipfix.ipv4_tmpl.octets.len = htons(8); 279 pflowif->sc_tmpl_ipfix.ipv4_tmpl.start.field_id = 280 htons(PFIX_IE_flowStartMilliseconds); 281 pflowif->sc_tmpl_ipfix.ipv4_tmpl.start.len = htons(8); 282 pflowif->sc_tmpl_ipfix.ipv4_tmpl.finish.field_id = 283 htons(PFIX_IE_flowEndMilliseconds); 284 pflowif->sc_tmpl_ipfix.ipv4_tmpl.finish.len = htons(8); 285 pflowif->sc_tmpl_ipfix.ipv4_tmpl.src_port.field_id = 286 htons(PFIX_IE_sourceTransportPort); 287 pflowif->sc_tmpl_ipfix.ipv4_tmpl.src_port.len = htons(2); 288 pflowif->sc_tmpl_ipfix.ipv4_tmpl.dest_port.field_id = 289 htons(PFIX_IE_destinationTransportPort); 290 pflowif->sc_tmpl_ipfix.ipv4_tmpl.dest_port.len = htons(2); 291 pflowif->sc_tmpl_ipfix.ipv4_tmpl.tos.field_id = 292 htons(PFIX_IE_ipClassOfService); 293 pflowif->sc_tmpl_ipfix.ipv4_tmpl.tos.len = htons(1); 294 pflowif->sc_tmpl_ipfix.ipv4_tmpl.protocol.field_id = 295 htons(PFIX_IE_protocolIdentifier); 296 pflowif->sc_tmpl_ipfix.ipv4_tmpl.protocol.len = htons(1); 297 298 /* ipfix IPv6 template */ 299 pflowif->sc_tmpl_ipfix.ipv6_tmpl.h.tmpl_id = 300 htons(PFLOW_IPFIX_TMPL_IPV6_ID); 301 pflowif->sc_tmpl_ipfix.ipv6_tmpl.h.field_count = 302 htons(PFLOW_IPFIX_TMPL_IPV6_FIELD_COUNT); 303 pflowif->sc_tmpl_ipfix.ipv6_tmpl.src_ip.field_id = 304 htons(PFIX_IE_sourceIPv6Address); 305 pflowif->sc_tmpl_ipfix.ipv6_tmpl.src_ip.len = htons(16); 306 pflowif->sc_tmpl_ipfix.ipv6_tmpl.dest_ip.field_id = 307 htons(PFIX_IE_destinationIPv6Address); 308 pflowif->sc_tmpl_ipfix.ipv6_tmpl.dest_ip.len = htons(16); 309 pflowif->sc_tmpl_ipfix.ipv6_tmpl.if_index_in.field_id = 310 htons(PFIX_IE_ingressInterface); 311 pflowif->sc_tmpl_ipfix.ipv6_tmpl.if_index_in.len = htons(4); 312 pflowif->sc_tmpl_ipfix.ipv6_tmpl.if_index_out.field_id = 313 htons(PFIX_IE_egressInterface); 314 pflowif->sc_tmpl_ipfix.ipv6_tmpl.if_index_out.len = htons(4); 315 pflowif->sc_tmpl_ipfix.ipv6_tmpl.packets.field_id = 316 htons(PFIX_IE_packetDeltaCount); 317 pflowif->sc_tmpl_ipfix.ipv6_tmpl.packets.len = htons(8); 318 pflowif->sc_tmpl_ipfix.ipv6_tmpl.octets.field_id = 319 htons(PFIX_IE_octetDeltaCount); 320 pflowif->sc_tmpl_ipfix.ipv6_tmpl.octets.len = htons(8); 321 pflowif->sc_tmpl_ipfix.ipv6_tmpl.start.field_id = 322 htons(PFIX_IE_flowStartMilliseconds); 323 pflowif->sc_tmpl_ipfix.ipv6_tmpl.start.len = htons(8); 324 pflowif->sc_tmpl_ipfix.ipv6_tmpl.finish.field_id = 325 htons(PFIX_IE_flowEndMilliseconds); 326 pflowif->sc_tmpl_ipfix.ipv6_tmpl.finish.len = htons(8); 327 pflowif->sc_tmpl_ipfix.ipv6_tmpl.src_port.field_id = 328 htons(PFIX_IE_sourceTransportPort); 329 pflowif->sc_tmpl_ipfix.ipv6_tmpl.src_port.len = htons(2); 330 pflowif->sc_tmpl_ipfix.ipv6_tmpl.dest_port.field_id = 331 htons(PFIX_IE_destinationTransportPort); 332 pflowif->sc_tmpl_ipfix.ipv6_tmpl.dest_port.len = htons(2); 333 pflowif->sc_tmpl_ipfix.ipv6_tmpl.tos.field_id = 334 htons(PFIX_IE_ipClassOfService); 335 pflowif->sc_tmpl_ipfix.ipv6_tmpl.tos.len = htons(1); 336 pflowif->sc_tmpl_ipfix.ipv6_tmpl.protocol.field_id = 337 htons(PFIX_IE_protocolIdentifier); 338 pflowif->sc_tmpl_ipfix.ipv6_tmpl.protocol.len = htons(1); 339 340 /* NAT44 create template */ 341 pflowif->sc_tmpl_ipfix.nat44_tmpl.h.tmpl_id = 342 htons(PFLOW_IPFIX_TMPL_NAT44_ID); 343 pflowif->sc_tmpl_ipfix.nat44_tmpl.h.field_count = 344 htons(PFLOW_IPFIX_TMPL_NAT44_FIELD_COUNT); 345 pflowif->sc_tmpl_ipfix.nat44_tmpl.timestamp.field_id = 346 htons(PFIX_IE_timeStamp); 347 pflowif->sc_tmpl_ipfix.nat44_tmpl.timestamp.len = 348 htons(8); 349 pflowif->sc_tmpl_ipfix.nat44_tmpl.nat_event.field_id = 350 htons(PFIX_IE_natEvent); 351 pflowif->sc_tmpl_ipfix.nat44_tmpl.nat_event.len = 352 htons(1); 353 pflowif->sc_tmpl_ipfix.nat44_tmpl.protocol.field_id = 354 htons(PFIX_IE_protocolIdentifier); 355 pflowif->sc_tmpl_ipfix.nat44_tmpl.protocol.len = htons(1); 356 pflowif->sc_tmpl_ipfix.nat44_tmpl.src_ip.field_id = 357 htons(PFIX_IE_sourceIPv4Address); 358 pflowif->sc_tmpl_ipfix.nat44_tmpl.src_ip.len = 359 htons(4); 360 pflowif->sc_tmpl_ipfix.nat44_tmpl.src_port.field_id = 361 htons(PFIX_IE_sourceTransportPort); 362 pflowif->sc_tmpl_ipfix.nat44_tmpl.src_port.len = htons(2); 363 pflowif->sc_tmpl_ipfix.nat44_tmpl.postnat_src_ip.field_id = 364 htons(PFIX_IE_postNATSourceIPv4Address); 365 pflowif->sc_tmpl_ipfix.nat44_tmpl.postnat_src_ip.len = 366 htons(4); 367 pflowif->sc_tmpl_ipfix.nat44_tmpl.postnat_src_port.field_id = 368 htons(PFIX_IE_postNAPTSourceTransportPort); 369 pflowif->sc_tmpl_ipfix.nat44_tmpl.postnat_src_port.len = 370 htons(2); 371 pflowif->sc_tmpl_ipfix.nat44_tmpl.dst_ip.field_id = 372 htons(PFIX_IE_destinationIPv4Address); 373 pflowif->sc_tmpl_ipfix.nat44_tmpl.dst_ip.len = 374 htons(4); 375 pflowif->sc_tmpl_ipfix.nat44_tmpl.dst_port.field_id = 376 htons(PFIX_IE_destinationTransportPort); 377 pflowif->sc_tmpl_ipfix.nat44_tmpl.dst_port.len = htons(2); 378 pflowif->sc_tmpl_ipfix.nat44_tmpl.postnat_dst_ip.field_id = 379 htons(PFIX_IE_postNATDestinationIPv4Address); 380 pflowif->sc_tmpl_ipfix.nat44_tmpl.postnat_dst_ip.len = 381 htons(4); 382 pflowif->sc_tmpl_ipfix.nat44_tmpl.postnat_dst_port.field_id = 383 htons(PFIX_IE_postNAPTDestinationTransportPort); 384 pflowif->sc_tmpl_ipfix.nat44_tmpl.postnat_dst_port.len = 385 htons(2); 386 387 pflowif->sc_id = unit; 388 pflowif->sc_vnet = curvnet; 389 390 mbufq_init(&pflowif->sc_outputqueue, 8192); 391 pflow_setmtu(pflowif, ETHERMTU); 392 393 callout_init_mtx(&pflowif->sc_tmo, &pflowif->sc_lock, 0); 394 callout_init_mtx(&pflowif->sc_tmo6, &pflowif->sc_lock, 0); 395 callout_init_mtx(&pflowif->sc_tmo_nat4, &pflowif->sc_lock, 0); 396 callout_init_mtx(&pflowif->sc_tmo_tmpl, &pflowif->sc_lock, 0); 397 398 error = swi_add(&pflowif->sc_swi_ie, pflowname, pflow_output_process, 399 pflowif, SWI_NET, INTR_MPSAFE, &pflowif->sc_swi_cookie); 400 if (error) { 401 free(pflowif, M_DEVBUF); 402 return (error); 403 } 404 405 /* Insert into list of pflows */ 406 mtx_lock(&V_pflowif_list_mtx); 407 CK_LIST_INSERT_HEAD(&V_pflowif_list, pflowif, sc_next); 408 mtx_unlock(&V_pflowif_list_mtx); 409 410 V_pflow_export_state_ptr = export_pflow; 411 412 return (0); 413 } 414 415 static void 416 pflow_free_cb(struct epoch_context *ctx) 417 { 418 struct pflow_softc *sc; 419 420 sc = __containerof(ctx, struct pflow_softc, sc_epoch_ctx); 421 422 free(sc, M_DEVBUF); 423 } 424 425 static int 426 pflow_destroy(int unit, bool drain) 427 { 428 struct pflow_softc *sc; 429 int error __diagused; 430 431 mtx_lock(&V_pflowif_list_mtx); 432 CK_LIST_FOREACH(sc, &V_pflowif_list, sc_next) { 433 if (sc->sc_id == unit) 434 break; 435 } 436 if (sc == NULL) { 437 mtx_unlock(&V_pflowif_list_mtx); 438 return (ENOENT); 439 } 440 CK_LIST_REMOVE(sc, sc_next); 441 if (CK_LIST_EMPTY(&V_pflowif_list)) 442 V_pflow_export_state_ptr = NULL; 443 mtx_unlock(&V_pflowif_list_mtx); 444 445 sc->sc_dying = 1; 446 447 if (drain) { 448 /* Let's be sure no one is using this interface any more. */ 449 NET_EPOCH_DRAIN_CALLBACKS(); 450 } 451 452 error = swi_remove(sc->sc_swi_cookie); 453 MPASS(error == 0); 454 error = intr_event_destroy(sc->sc_swi_ie); 455 MPASS(error == 0); 456 457 callout_drain(&sc->sc_tmo); 458 callout_drain(&sc->sc_tmo6); 459 callout_drain(&sc->sc_tmo_nat4); 460 callout_drain(&sc->sc_tmo_tmpl); 461 462 m_freem(sc->sc_mbuf); 463 m_freem(sc->sc_mbuf6); 464 m_freem(sc->sc_mbuf_nat4); 465 466 PFLOW_LOCK(sc); 467 mbufq_drain(&sc->sc_outputqueue); 468 if (sc->so != NULL) { 469 soclose(sc->so); 470 sc->so = NULL; 471 } 472 if (sc->sc_flowdst != NULL) 473 free(sc->sc_flowdst, M_DEVBUF); 474 if (sc->sc_flowsrc != NULL) 475 free(sc->sc_flowsrc, M_DEVBUF); 476 PFLOW_UNLOCK(sc); 477 478 mtx_destroy(&sc->sc_lock); 479 480 free_unr(V_pflow_unr, unit); 481 482 NET_EPOCH_CALL(pflow_free_cb, &sc->sc_epoch_ctx); 483 484 return (0); 485 } 486 487 static int 488 pflowvalidsockaddr(const struct sockaddr *sa, int ignore_port) 489 { 490 const struct sockaddr_in6 *sin6; 491 const struct sockaddr_in *sin; 492 493 if (sa == NULL) 494 return (0); 495 switch(sa->sa_family) { 496 case AF_INET: 497 sin = (const struct sockaddr_in *)sa; 498 return (sin->sin_addr.s_addr != INADDR_ANY && 499 (ignore_port || sin->sin_port != 0)); 500 case AF_INET6: 501 sin6 = (const struct sockaddr_in6 *)sa; 502 return (!IN6_IS_ADDR_UNSPECIFIED(&sin6->sin6_addr) && 503 (ignore_port || sin6->sin6_port != 0)); 504 default: 505 return (0); 506 } 507 } 508 509 int 510 pflow_calc_mtu(struct pflow_softc *sc, int mtu, int hdrsz) 511 { 512 size_t min; 513 514 sc->sc_maxcount4 = (mtu - hdrsz - 515 sizeof(struct udpiphdr)) / sizeof(struct pflow_ipfix_flow4); 516 sc->sc_maxcount6 = (mtu - hdrsz - 517 sizeof(struct udpiphdr)) / sizeof(struct pflow_ipfix_flow6); 518 sc->sc_maxcount_nat4 = (mtu - hdrsz - 519 sizeof(struct udpiphdr)) / sizeof(struct pflow_ipfix_nat4); 520 if (sc->sc_maxcount4 > PFLOW_MAXFLOWS) 521 sc->sc_maxcount4 = PFLOW_MAXFLOWS; 522 if (sc->sc_maxcount6 > PFLOW_MAXFLOWS) 523 sc->sc_maxcount6 = PFLOW_MAXFLOWS; 524 if (sc->sc_maxcount_nat4 > PFLOW_MAXFLOWS) 525 sc->sc_maxcount_nat4 = PFLOW_MAXFLOWS; 526 527 min = MIN(sc->sc_maxcount4 * sizeof(struct pflow_ipfix_flow4), 528 sc->sc_maxcount6 * sizeof(struct pflow_ipfix_flow6)); 529 min = MIN(min, sc->sc_maxcount_nat4 * sizeof(struct pflow_ipfix_nat4)); 530 531 return (hdrsz + sizeof(struct udpiphdr) + min); 532 } 533 534 static void 535 pflow_setmtu(struct pflow_softc *sc, int mtu_req) 536 { 537 int mtu; 538 539 mtu = mtu_req; 540 541 switch (sc->sc_version) { 542 case PFLOW_PROTO_5: 543 sc->sc_maxcount = (mtu - sizeof(struct pflow_header) - 544 sizeof(struct udpiphdr)) / sizeof(struct pflow_flow); 545 if (sc->sc_maxcount > PFLOW_MAXFLOWS) 546 sc->sc_maxcount = PFLOW_MAXFLOWS; 547 break; 548 case PFLOW_PROTO_10: 549 pflow_calc_mtu(sc, mtu, sizeof(struct pflow_v10_header)); 550 break; 551 default: /* NOTREACHED */ 552 break; 553 } 554 } 555 556 static struct mbuf * 557 pflow_get_mbuf(struct pflow_softc *sc, u_int16_t set_id) 558 { 559 struct pflow_set_header set_hdr; 560 struct pflow_header h; 561 struct mbuf *m; 562 563 MGETHDR(m, M_NOWAIT, MT_DATA); 564 if (m == NULL) { 565 pflowstat_inc(pflow_onomem); 566 return (NULL); 567 } 568 569 MCLGET(m, M_NOWAIT); 570 if ((m->m_flags & M_EXT) == 0) { 571 m_free(m); 572 pflowstat_inc(pflow_onomem); 573 return (NULL); 574 } 575 576 m->m_len = m->m_pkthdr.len = 0; 577 578 if (sc == NULL) /* get only a new empty mbuf */ 579 return (m); 580 581 switch (sc->sc_version) { 582 case PFLOW_PROTO_5: 583 /* populate pflow_header */ 584 h.reserved1 = 0; 585 h.reserved2 = 0; 586 h.count = 0; 587 h.version = htons(PFLOW_PROTO_5); 588 h.flow_sequence = htonl(sc->sc_gcounter); 589 h.engine_type = PFLOW_ENGINE_TYPE; 590 h.engine_id = PFLOW_ENGINE_ID; 591 m_copyback(m, 0, PFLOW_HDRLEN, (caddr_t)&h); 592 593 sc->sc_count = 0; 594 callout_reset(&sc->sc_tmo, PFLOW_TIMEOUT * hz, 595 pflow_timeout, sc); 596 break; 597 case PFLOW_PROTO_10: 598 /* populate pflow_set_header */ 599 set_hdr.set_length = 0; 600 set_hdr.set_id = htons(set_id); 601 m_copyback(m, 0, PFLOW_SET_HDRLEN, (caddr_t)&set_hdr); 602 break; 603 default: /* NOTREACHED */ 604 break; 605 } 606 607 return (m); 608 } 609 610 static void 611 copy_flow_data(struct pflow_flow *flow1, struct pflow_flow *flow2, 612 const struct pf_kstate *st, struct pf_state_key *sk, int src, int dst) 613 { 614 flow1->src_ip = flow2->dest_ip = sk->addr[src].v4.s_addr; 615 flow1->src_port = flow2->dest_port = sk->port[src]; 616 flow1->dest_ip = flow2->src_ip = sk->addr[dst].v4.s_addr; 617 flow1->dest_port = flow2->src_port = sk->port[dst]; 618 619 flow1->dest_as = flow2->src_as = 620 flow1->src_as = flow2->dest_as = 0; 621 flow1->if_index_in = htons(st->if_index_in); 622 flow1->if_index_out = htons(st->if_index_out); 623 flow2->if_index_in = htons(st->if_index_out); 624 flow2->if_index_out = htons(st->if_index_in); 625 flow1->dest_mask = flow2->src_mask = 626 flow1->src_mask = flow2->dest_mask = 0; 627 628 flow1->flow_packets = htonl(st->packets[0]); 629 flow2->flow_packets = htonl(st->packets[1]); 630 flow1->flow_octets = htonl(st->bytes[0]); 631 flow2->flow_octets = htonl(st->bytes[1]); 632 633 /* 634 * Pretend the flow was created or expired when the machine came up 635 * when creation is in the future of the last time a package was seen 636 * or was created / expired before this machine came up due to pfsync. 637 */ 638 flow1->flow_start = flow2->flow_start = st->creation < 0 || 639 st->creation > st->expire ? htonl(0) : htonl(st->creation); 640 flow1->flow_finish = flow2->flow_finish = st->expire < 0 ? htonl(0) : 641 htonl(st->expire); 642 flow1->tcp_flags = flow2->tcp_flags = 0; 643 flow1->protocol = flow2->protocol = sk->proto; 644 flow1->tos = flow2->tos = st->rule.ptr->tos; 645 } 646 647 static void 648 copy_flow_ipfix_4_data(struct pflow_ipfix_flow4 *flow1, 649 struct pflow_ipfix_flow4 *flow2, const struct pf_kstate *st, 650 struct pf_state_key *sk, struct pflow_softc *sc, int src, int dst) 651 { 652 flow1->src_ip = flow2->dest_ip = sk->addr[src].v4.s_addr; 653 flow1->src_port = flow2->dest_port = sk->port[src]; 654 flow1->dest_ip = flow2->src_ip = sk->addr[dst].v4.s_addr; 655 flow1->dest_port = flow2->src_port = sk->port[dst]; 656 657 flow1->if_index_in = htonl(st->if_index_in); 658 flow1->if_index_out = htonl(st->if_index_out); 659 flow2->if_index_in = htonl(st->if_index_out); 660 flow2->if_index_out = htonl(st->if_index_in); 661 662 flow1->flow_packets = htobe64(st->packets[0]); 663 flow2->flow_packets = htobe64(st->packets[1]); 664 flow1->flow_octets = htobe64(st->bytes[0]); 665 flow2->flow_octets = htobe64(st->bytes[1]); 666 667 /* 668 * Pretend the flow was created when the machine came up when creation 669 * is in the future of the last time a package was seen due to pfsync. 670 */ 671 if (st->creation > st->expire) 672 flow1->flow_start = flow2->flow_start = htobe64((time_second - 673 time_uptime)*1000); 674 else 675 flow1->flow_start = flow2->flow_start = htobe64((pf_get_time() - 676 (pf_get_uptime() - st->creation))); 677 flow1->flow_finish = flow2->flow_finish = htobe64((pf_get_time() - 678 (pf_get_uptime() - st->expire))); 679 680 flow1->protocol = flow2->protocol = sk->proto; 681 flow1->tos = flow2->tos = st->rule.ptr->tos; 682 } 683 684 static void 685 copy_flow_ipfix_6_data(struct pflow_ipfix_flow6 *flow1, 686 struct pflow_ipfix_flow6 *flow2, const struct pf_kstate *st, 687 struct pf_state_key *sk, struct pflow_softc *sc, int src, int dst) 688 { 689 bcopy(&sk->addr[src].v6, &flow1->src_ip, sizeof(flow1->src_ip)); 690 bcopy(&sk->addr[src].v6, &flow2->dest_ip, sizeof(flow2->dest_ip)); 691 flow1->src_port = flow2->dest_port = sk->port[src]; 692 bcopy(&sk->addr[dst].v6, &flow1->dest_ip, sizeof(flow1->dest_ip)); 693 bcopy(&sk->addr[dst].v6, &flow2->src_ip, sizeof(flow2->src_ip)); 694 flow1->dest_port = flow2->src_port = sk->port[dst]; 695 696 flow1->if_index_in = htonl(st->if_index_in); 697 flow1->if_index_out = htonl(st->if_index_out); 698 flow2->if_index_in = htonl(st->if_index_out); 699 flow2->if_index_out = htonl(st->if_index_in); 700 701 flow1->flow_packets = htobe64(st->packets[0]); 702 flow2->flow_packets = htobe64(st->packets[1]); 703 flow1->flow_octets = htobe64(st->bytes[0]); 704 flow2->flow_octets = htobe64(st->bytes[1]); 705 706 /* 707 * Pretend the flow was created when the machine came up when creation 708 * is in the future of the last time a package was seen due to pfsync. 709 */ 710 if (st->creation > st->expire) 711 flow1->flow_start = flow2->flow_start = htobe64((time_second - 712 time_uptime)*1000); 713 else 714 flow1->flow_start = flow2->flow_start = htobe64((pf_get_time() - 715 (pf_get_uptime() - st->creation))); 716 flow1->flow_finish = flow2->flow_finish = htobe64((pf_get_time() - 717 (pf_get_uptime() - st->expire))); 718 719 flow1->protocol = flow2->protocol = sk->proto; 720 flow1->tos = flow2->tos = st->rule.ptr->tos; 721 } 722 723 static void 724 copy_nat_ipfix_4_data(struct pflow_ipfix_nat4 *nat1, 725 struct pflow_ipfix_nat4 *nat2, const struct pf_kstate *st, 726 struct pf_state_key *sk, struct pflow_softc *sc, int src, int dst) 727 { 728 nat1->src_ip = nat2->dest_ip = st->key[PF_SK_STACK]->addr[src].v4.s_addr; 729 nat1->src_port = nat2->dest_port = st->key[PF_SK_STACK]->port[src]; 730 nat1->dest_ip = nat2->src_ip = st->key[PF_SK_STACK]->addr[dst].v4.s_addr; 731 nat1->dest_port = nat2->src_port = st->key[PF_SK_STACK]->port[dst]; 732 nat1->postnat_src_ip = nat2->postnat_dest_ip = st->key[PF_SK_WIRE]->addr[src].v4.s_addr; 733 nat1->postnat_src_port = nat2->postnat_dest_port = st->key[PF_SK_WIRE]->port[src]; 734 nat1->postnat_dest_ip = nat2->postnat_src_ip = st->key[PF_SK_WIRE]->addr[dst].v4.s_addr; 735 nat1->postnat_dest_port = nat2->postnat_src_port = st->key[PF_SK_WIRE]->port[dst]; 736 nat1->protocol = nat2->protocol = sk->proto; 737 738 /* 739 * Because we have to generate a create and delete event we'll fill out the 740 * timestamp and nat_event fields when we transmit. As opposed to doing this 741 * work a second time. 742 */ 743 } 744 745 static void 746 export_pflow(const struct pf_kstate *st) 747 { 748 struct pflow_softc *sc = NULL; 749 struct pf_state_key *sk; 750 751 NET_EPOCH_ASSERT(); 752 753 sk = st->key[st->direction == PF_IN ? PF_SK_WIRE : PF_SK_STACK]; 754 755 CK_LIST_FOREACH(sc, &V_pflowif_list, sc_next) { 756 PFLOW_LOCK(sc); 757 switch (sc->sc_version) { 758 case PFLOW_PROTO_5: 759 if (sk->af == AF_INET) 760 export_pflow_if(st, sk, sc); 761 break; 762 case PFLOW_PROTO_10: 763 if (sk->af == AF_INET || sk->af == AF_INET6) 764 export_pflow_if(st, sk, sc); 765 break; 766 default: /* NOTREACHED */ 767 break; 768 } 769 PFLOW_UNLOCK(sc); 770 } 771 } 772 773 static int 774 export_pflow_if(const struct pf_kstate *st, struct pf_state_key *sk, 775 struct pflow_softc *sc) 776 { 777 struct pf_kstate pfs_copy; 778 u_int64_t bytes[2]; 779 int ret = 0; 780 781 if (sc->sc_version == PFLOW_PROTO_10) 782 return (pflow_pack_flow_ipfix(st, sk, sc)); 783 784 /* PFLOW_PROTO_5 */ 785 if ((st->bytes[0] < (u_int64_t)PFLOW_MAXBYTES) 786 && (st->bytes[1] < (u_int64_t)PFLOW_MAXBYTES)) 787 return (pflow_pack_flow(st, sk, sc)); 788 789 /* flow > PFLOW_MAXBYTES need special handling */ 790 bcopy(st, &pfs_copy, sizeof(pfs_copy)); 791 bytes[0] = pfs_copy.bytes[0]; 792 bytes[1] = pfs_copy.bytes[1]; 793 794 while (bytes[0] > PFLOW_MAXBYTES) { 795 pfs_copy.bytes[0] = PFLOW_MAXBYTES; 796 pfs_copy.bytes[1] = 0; 797 798 if ((ret = pflow_pack_flow(&pfs_copy, sk, sc)) != 0) 799 return (ret); 800 if ((bytes[0] - PFLOW_MAXBYTES) > 0) 801 bytes[0] -= PFLOW_MAXBYTES; 802 } 803 804 while (bytes[1] > (u_int64_t)PFLOW_MAXBYTES) { 805 pfs_copy.bytes[1] = PFLOW_MAXBYTES; 806 pfs_copy.bytes[0] = 0; 807 808 if ((ret = pflow_pack_flow(&pfs_copy, sk, sc)) != 0) 809 return (ret); 810 if ((bytes[1] - PFLOW_MAXBYTES) > 0) 811 bytes[1] -= PFLOW_MAXBYTES; 812 } 813 814 pfs_copy.bytes[0] = bytes[0]; 815 pfs_copy.bytes[1] = bytes[1]; 816 817 return (pflow_pack_flow(&pfs_copy, sk, sc)); 818 } 819 820 static int 821 copy_flow_to_m(struct pflow_flow *flow, struct pflow_softc *sc) 822 { 823 int ret = 0; 824 825 PFLOW_ASSERT(sc); 826 827 if (sc->sc_mbuf == NULL) { 828 if ((sc->sc_mbuf = pflow_get_mbuf(sc, 0)) == NULL) 829 return (ENOBUFS); 830 } 831 m_copyback(sc->sc_mbuf, PFLOW_HDRLEN + 832 (sc->sc_count * sizeof(struct pflow_flow)), 833 sizeof(struct pflow_flow), (caddr_t)flow); 834 835 pflowstat_inc(pflow_flows); 836 sc->sc_gcounter++; 837 sc->sc_count++; 838 839 if (sc->sc_count >= sc->sc_maxcount) 840 ret = pflow_sendout_v5(sc); 841 842 return(ret); 843 } 844 845 static int 846 copy_flow_ipfix_4_to_m(struct pflow_ipfix_flow4 *flow, struct pflow_softc *sc) 847 { 848 int ret = 0; 849 850 PFLOW_ASSERT(sc); 851 852 if (sc->sc_mbuf == NULL) { 853 if ((sc->sc_mbuf = 854 pflow_get_mbuf(sc, PFLOW_IPFIX_TMPL_IPV4_ID)) == NULL) { 855 return (ENOBUFS); 856 } 857 sc->sc_count4 = 0; 858 callout_reset(&sc->sc_tmo, PFLOW_TIMEOUT * hz, 859 pflow_timeout, sc); 860 } 861 m_copyback(sc->sc_mbuf, PFLOW_SET_HDRLEN + 862 (sc->sc_count4 * sizeof(struct pflow_ipfix_flow4)), 863 sizeof(struct pflow_ipfix_flow4), (caddr_t)flow); 864 865 pflowstat_inc(pflow_flows); 866 sc->sc_gcounter++; 867 sc->sc_count4++; 868 869 if (sc->sc_count4 >= sc->sc_maxcount4) 870 ret = pflow_sendout_ipfix(sc, PFLOW_INET); 871 return(ret); 872 } 873 874 static int 875 copy_flow_ipfix_6_to_m(struct pflow_ipfix_flow6 *flow, struct pflow_softc *sc) 876 { 877 int ret = 0; 878 879 PFLOW_ASSERT(sc); 880 881 if (sc->sc_mbuf6 == NULL) { 882 if ((sc->sc_mbuf6 = 883 pflow_get_mbuf(sc, PFLOW_IPFIX_TMPL_IPV6_ID)) == NULL) { 884 return (ENOBUFS); 885 } 886 sc->sc_count6 = 0; 887 callout_reset(&sc->sc_tmo6, PFLOW_TIMEOUT * hz, 888 pflow_timeout6, sc); 889 } 890 m_copyback(sc->sc_mbuf6, PFLOW_SET_HDRLEN + 891 (sc->sc_count6 * sizeof(struct pflow_ipfix_flow6)), 892 sizeof(struct pflow_ipfix_flow6), (caddr_t)flow); 893 894 pflowstat_inc(pflow_flows); 895 sc->sc_gcounter++; 896 sc->sc_count6++; 897 898 if (sc->sc_count6 >= sc->sc_maxcount6) 899 ret = pflow_sendout_ipfix(sc, PFLOW_INET6); 900 901 return(ret); 902 } 903 904 int 905 copy_nat_ipfix_4_to_m(struct pflow_ipfix_nat4 *nat, const struct pf_kstate *st, 906 struct pflow_softc *sc, uint8_t event, uint64_t timestamp) 907 { 908 int ret = 0; 909 910 PFLOW_ASSERT(sc); 911 912 if (sc->sc_mbuf_nat4 == NULL) { 913 if ((sc->sc_mbuf_nat4 = 914 pflow_get_mbuf(sc, PFLOW_IPFIX_TMPL_NAT44_ID)) == NULL) { 915 return (ENOBUFS); 916 } 917 sc->sc_count_nat4 = 0; 918 callout_reset(&sc->sc_tmo, PFLOW_TIMEOUT * hz, 919 pflow_timeout_nat4, sc); 920 } 921 922 nat->nat_event = event; 923 nat->timestamp = htobe64(pf_get_time() - (pf_get_uptime() - timestamp)); 924 m_copyback(sc->sc_mbuf_nat4, PFLOW_SET_HDRLEN + 925 (sc->sc_count_nat4 * sizeof(struct pflow_ipfix_nat4)), 926 sizeof(struct pflow_ipfix_nat4), (caddr_t)nat); 927 sc->sc_count_nat4++; 928 929 pflowstat_inc(pflow_flows); 930 sc->sc_gcounter++; 931 932 if (sc->sc_count_nat4 >= sc->sc_maxcount_nat4) 933 ret = pflow_sendout_ipfix(sc, PFLOW_NAT4); 934 935 return (ret); 936 } 937 938 static int 939 pflow_pack_flow(const struct pf_kstate *st, struct pf_state_key *sk, 940 struct pflow_softc *sc) 941 { 942 struct pflow_flow flow1; 943 struct pflow_flow flow2; 944 int ret = 0; 945 946 bzero(&flow1, sizeof(flow1)); 947 bzero(&flow2, sizeof(flow2)); 948 949 if (st->direction == PF_OUT) 950 copy_flow_data(&flow1, &flow2, st, sk, 1, 0); 951 else 952 copy_flow_data(&flow1, &flow2, st, sk, 0, 1); 953 954 if (st->bytes[0] != 0) /* first flow from state */ 955 ret = copy_flow_to_m(&flow1, sc); 956 957 if (st->bytes[1] != 0) /* second flow from state */ 958 ret = copy_flow_to_m(&flow2, sc); 959 960 return (ret); 961 } 962 963 static bool 964 pflow_is_natd(const struct pf_kstate *st) 965 { 966 /* If ports or addresses are different we've been NAT-ed. */ 967 return (memcmp(st->key[PF_SK_WIRE], st->key[PF_SK_STACK], 968 sizeof(struct pf_addr) * 2 + sizeof(uint16_t) * 2) != 0); 969 } 970 971 static int 972 pflow_pack_flow_ipfix(const struct pf_kstate *st, struct pf_state_key *sk, 973 struct pflow_softc *sc) 974 { 975 struct pflow_ipfix_flow4 flow4_1, flow4_2; 976 struct pflow_ipfix_nat4 nat4_1, nat4_2; 977 struct pflow_ipfix_flow6 flow6_1, flow6_2; 978 int ret = 0; 979 bool nat = false; 980 981 if (sk->af == AF_INET) { 982 bzero(&flow4_1, sizeof(flow4_1)); 983 bzero(&flow4_2, sizeof(flow4_2)); 984 985 nat = pflow_is_natd(st); 986 987 if (st->direction == PF_OUT) 988 copy_flow_ipfix_4_data(&flow4_1, &flow4_2, st, sk, sc, 989 1, 0); 990 else 991 copy_flow_ipfix_4_data(&flow4_1, &flow4_2, st, sk, sc, 992 0, 1); 993 994 if (nat) 995 copy_nat_ipfix_4_data(&nat4_1, &nat4_2, st, sk, sc, 1, 0); 996 997 if (st->bytes[0] != 0) /* first flow from state */ { 998 ret = copy_flow_ipfix_4_to_m(&flow4_1, sc); 999 1000 if (ret == 0 && nat) { 1001 ret = copy_nat_ipfix_4_to_m(&nat4_1, st, sc, 1002 PFIX_NAT_EVENT_SESSION_CREATE, st->creation); 1003 ret |= copy_nat_ipfix_4_to_m(&nat4_1, st, sc, 1004 PFIX_NAT_EVENT_SESSION_DELETE, st->expire); 1005 } 1006 } 1007 1008 if (st->bytes[1] != 0) /* second flow from state */ { 1009 ret = copy_flow_ipfix_4_to_m(&flow4_2, sc); 1010 1011 if (ret == 0 && nat) { 1012 ret = copy_nat_ipfix_4_to_m(&nat4_2, st, sc, 1013 PFIX_NAT_EVENT_SESSION_CREATE, st->creation); 1014 ret |= copy_nat_ipfix_4_to_m(&nat4_2, st, sc, 1015 PFIX_NAT_EVENT_SESSION_DELETE, st->expire); 1016 } 1017 } 1018 } else if (sk->af == AF_INET6) { 1019 bzero(&flow6_1, sizeof(flow6_1)); 1020 bzero(&flow6_2, sizeof(flow6_2)); 1021 1022 if (st->direction == PF_OUT) 1023 copy_flow_ipfix_6_data(&flow6_1, &flow6_2, st, sk, sc, 1024 1, 0); 1025 else 1026 copy_flow_ipfix_6_data(&flow6_1, &flow6_2, st, sk, sc, 1027 0, 1); 1028 1029 if (st->bytes[0] != 0) /* first flow from state */ 1030 ret = copy_flow_ipfix_6_to_m(&flow6_1, sc); 1031 1032 if (st->bytes[1] != 0) /* second flow from state */ 1033 ret = copy_flow_ipfix_6_to_m(&flow6_2, sc); 1034 } 1035 return (ret); 1036 } 1037 1038 static void 1039 pflow_timeout(void *v) 1040 { 1041 struct pflow_softc *sc = v; 1042 1043 PFLOW_ASSERT(sc); 1044 CURVNET_SET(sc->sc_vnet); 1045 1046 switch (sc->sc_version) { 1047 case PFLOW_PROTO_5: 1048 pflow_sendout_v5(sc); 1049 break; 1050 case PFLOW_PROTO_10: 1051 pflow_sendout_ipfix(sc, PFLOW_INET); 1052 break; 1053 default: /* NOTREACHED */ 1054 panic("Unsupported version %d", sc->sc_version); 1055 break; 1056 } 1057 1058 CURVNET_RESTORE(); 1059 } 1060 1061 static void 1062 pflow_timeout6(void *v) 1063 { 1064 struct pflow_softc *sc = v; 1065 1066 PFLOW_ASSERT(sc); 1067 1068 if (sc->sc_version != PFLOW_PROTO_10) 1069 return; 1070 1071 CURVNET_SET(sc->sc_vnet); 1072 pflow_sendout_ipfix(sc, PFLOW_INET6); 1073 CURVNET_RESTORE(); 1074 } 1075 1076 static void 1077 pflow_timeout_tmpl(void *v) 1078 { 1079 struct pflow_softc *sc = v; 1080 1081 PFLOW_ASSERT(sc); 1082 1083 if (sc->sc_version != PFLOW_PROTO_10) 1084 return; 1085 1086 CURVNET_SET(sc->sc_vnet); 1087 pflow_sendout_ipfix_tmpl(sc); 1088 CURVNET_RESTORE(); 1089 } 1090 1091 static void 1092 pflow_timeout_nat4(void *v) 1093 { 1094 struct pflow_softc *sc = v; 1095 1096 PFLOW_ASSERT(sc); 1097 1098 if (sc->sc_version != PFLOW_PROTO_10) 1099 return; 1100 1101 CURVNET_SET(sc->sc_vnet); 1102 pflow_sendout_ipfix(sc, PFLOW_NAT4); 1103 CURVNET_RESTORE(); 1104 } 1105 1106 static void 1107 pflow_flush(struct pflow_softc *sc) 1108 { 1109 PFLOW_ASSERT(sc); 1110 1111 switch (sc->sc_version) { 1112 case PFLOW_PROTO_5: 1113 pflow_sendout_v5(sc); 1114 break; 1115 case PFLOW_PROTO_10: 1116 pflow_sendout_ipfix(sc, PFLOW_INET); 1117 pflow_sendout_ipfix(sc, PFLOW_INET6); 1118 pflow_sendout_ipfix(sc, PFLOW_NAT4); 1119 break; 1120 default: /* NOTREACHED */ 1121 break; 1122 } 1123 } 1124 1125 static int 1126 pflow_sendout_v5(struct pflow_softc *sc) 1127 { 1128 struct mbuf *m = sc->sc_mbuf; 1129 struct pflow_header *h; 1130 struct timespec tv; 1131 1132 PFLOW_ASSERT(sc); 1133 1134 if (m == NULL) 1135 return (0); 1136 1137 sc->sc_mbuf = NULL; 1138 1139 pflowstat_inc(pflow_packets); 1140 h = mtod(m, struct pflow_header *); 1141 h->count = htons(sc->sc_count); 1142 1143 /* populate pflow_header */ 1144 h->uptime_ms = htonl(time_uptime * 1000); 1145 1146 getnanotime(&tv); 1147 h->time_sec = htonl(tv.tv_sec); /* XXX 2038 */ 1148 h->time_nanosec = htonl(tv.tv_nsec); 1149 if (mbufq_enqueue(&sc->sc_outputqueue, m) == 0) 1150 swi_sched(sc->sc_swi_cookie, 0); 1151 1152 return (0); 1153 } 1154 1155 static int 1156 pflow_sendout_ipfix(struct pflow_softc *sc, enum pflow_family_t af) 1157 { 1158 struct mbuf *m; 1159 struct pflow_v10_header *h10; 1160 struct pflow_set_header *set_hdr; 1161 u_int32_t count; 1162 int set_length; 1163 1164 PFLOW_ASSERT(sc); 1165 1166 switch (af) { 1167 case PFLOW_INET: 1168 m = sc->sc_mbuf; 1169 callout_stop(&sc->sc_tmo); 1170 if (m == NULL) 1171 return (0); 1172 sc->sc_mbuf = NULL; 1173 count = sc->sc_count4; 1174 set_length = sizeof(struct pflow_set_header) 1175 + sc->sc_count4 * sizeof(struct pflow_ipfix_flow4); 1176 break; 1177 case PFLOW_INET6: 1178 m = sc->sc_mbuf6; 1179 callout_stop(&sc->sc_tmo6); 1180 if (m == NULL) 1181 return (0); 1182 sc->sc_mbuf6 = NULL; 1183 count = sc->sc_count6; 1184 set_length = sizeof(struct pflow_set_header) 1185 + sc->sc_count6 * sizeof(struct pflow_ipfix_flow6); 1186 break; 1187 case PFLOW_NAT4: 1188 m = sc->sc_mbuf_nat4; 1189 callout_stop(&sc->sc_tmo_nat4); 1190 if (m == NULL) 1191 return (0); 1192 sc->sc_mbuf_nat4 = NULL; 1193 count = sc->sc_count_nat4; 1194 set_length = sizeof(struct pflow_set_header) 1195 + sc->sc_count_nat4 * sizeof(struct pflow_ipfix_nat4); 1196 break; 1197 default: 1198 panic("Unsupported AF %d", af); 1199 } 1200 1201 pflowstat_inc(pflow_packets); 1202 1203 set_hdr = mtod(m, struct pflow_set_header *); 1204 set_hdr->set_length = htons(set_length); 1205 1206 /* populate pflow_header */ 1207 M_PREPEND(m, sizeof(struct pflow_v10_header), M_NOWAIT); 1208 if (m == NULL) { 1209 pflowstat_inc(pflow_onomem); 1210 return (ENOBUFS); 1211 } 1212 h10 = mtod(m, struct pflow_v10_header *); 1213 h10->version = htons(PFLOW_PROTO_10); 1214 h10->length = htons(PFLOW_IPFIX_HDRLEN + set_length); 1215 h10->time_sec = htonl(time_second); /* XXX 2038 */ 1216 h10->flow_sequence = htonl(sc->sc_sequence); 1217 sc->sc_sequence += count; 1218 h10->observation_dom = htonl(sc->sc_observation_dom); 1219 if (mbufq_enqueue(&sc->sc_outputqueue, m) == 0) 1220 swi_sched(sc->sc_swi_cookie, 0); 1221 1222 return (0); 1223 } 1224 1225 static int 1226 pflow_sendout_ipfix_tmpl(struct pflow_softc *sc) 1227 { 1228 struct mbuf *m; 1229 struct pflow_v10_header *h10; 1230 1231 PFLOW_ASSERT(sc); 1232 1233 m = pflow_get_mbuf(sc, 0); 1234 if (m == NULL) 1235 return (0); 1236 m_copyback(m, 0, sizeof(struct pflow_ipfix_tmpl), 1237 (caddr_t)&sc->sc_tmpl_ipfix); 1238 1239 pflowstat_inc(pflow_packets); 1240 1241 /* populate pflow_header */ 1242 M_PREPEND(m, sizeof(struct pflow_v10_header), M_NOWAIT); 1243 if (m == NULL) { 1244 pflowstat_inc(pflow_onomem); 1245 return (ENOBUFS); 1246 } 1247 h10 = mtod(m, struct pflow_v10_header *); 1248 h10->version = htons(PFLOW_PROTO_10); 1249 h10->length = htons(PFLOW_IPFIX_HDRLEN + sizeof(struct 1250 pflow_ipfix_tmpl)); 1251 h10->time_sec = htonl(time_second); /* XXX 2038 */ 1252 h10->flow_sequence = htonl(sc->sc_sequence); 1253 h10->observation_dom = htonl(sc->sc_observation_dom); 1254 1255 callout_reset(&sc->sc_tmo_tmpl, PFLOW_TMPL_TIMEOUT * hz, 1256 pflow_timeout_tmpl, sc); 1257 if (mbufq_enqueue(&sc->sc_outputqueue, m) == 0) 1258 swi_sched(sc->sc_swi_cookie, 0); 1259 1260 return (0); 1261 } 1262 1263 static int 1264 pflow_sendout_mbuf(struct pflow_softc *sc, struct mbuf *m) 1265 { 1266 if (sc->so == NULL) { 1267 m_freem(m); 1268 return (EINVAL); 1269 } 1270 return (sosend(sc->so, sc->sc_flowdst, NULL, m, NULL, 0, curthread)); 1271 } 1272 1273 static int 1274 sysctl_pflowstats(SYSCTL_HANDLER_ARGS) 1275 { 1276 struct pflowstats pflowstats; 1277 1278 pflowstats.pflow_flows = 1279 counter_u64_fetch(V_pflowstats.c[pflow_flows]); 1280 pflowstats.pflow_packets = 1281 counter_u64_fetch(V_pflowstats.c[pflow_packets]); 1282 pflowstats.pflow_onomem = 1283 counter_u64_fetch(V_pflowstats.c[pflow_onomem]); 1284 pflowstats.pflow_oerrors = 1285 counter_u64_fetch(V_pflowstats.c[pflow_oerrors]); 1286 1287 return (sysctl_handle_opaque(oidp, &pflowstats, sizeof(pflowstats), req)); 1288 } 1289 1290 static int 1291 pflow_nl_list(struct nlmsghdr *hdr, struct nl_pstate *npt) 1292 { 1293 struct epoch_tracker et; 1294 struct pflow_softc *sc = NULL; 1295 struct nl_writer *nw = npt->nw; 1296 int error = 0; 1297 1298 hdr->nlmsg_flags |= NLM_F_MULTI; 1299 1300 NET_EPOCH_ENTER(et); 1301 CK_LIST_FOREACH(sc, &V_pflowif_list, sc_next) { 1302 if (!nlmsg_reply(nw, hdr, sizeof(struct genlmsghdr))) { 1303 error = ENOMEM; 1304 goto out; 1305 } 1306 1307 struct genlmsghdr *ghdr_new = nlmsg_reserve_object(nw, struct genlmsghdr); 1308 ghdr_new->cmd = PFLOWNL_CMD_LIST; 1309 ghdr_new->version = 0; 1310 ghdr_new->reserved = 0; 1311 1312 nlattr_add_u32(nw, PFLOWNL_L_ID, sc->sc_id); 1313 1314 if (! nlmsg_end(nw)) { 1315 error = ENOMEM; 1316 goto out; 1317 } 1318 } 1319 1320 out: 1321 NET_EPOCH_EXIT(et); 1322 1323 if (error != 0) 1324 nlmsg_abort(nw); 1325 1326 return (error); 1327 } 1328 1329 static int 1330 pflow_nl_create(struct nlmsghdr *hdr, struct nl_pstate *npt) 1331 { 1332 struct nl_writer *nw = npt->nw; 1333 int error = 0; 1334 int unit; 1335 1336 if (! nlmsg_reply(nw, hdr, sizeof(struct genlmsghdr))) { 1337 return (ENOMEM); 1338 } 1339 1340 struct genlmsghdr *ghdr_new = nlmsg_reserve_object(nw, struct genlmsghdr); 1341 ghdr_new->cmd = PFLOWNL_CMD_CREATE; 1342 ghdr_new->version = 0; 1343 ghdr_new->reserved = 0; 1344 1345 unit = alloc_unr(V_pflow_unr); 1346 1347 error = pflow_create(unit); 1348 if (error != 0) { 1349 free_unr(V_pflow_unr, unit); 1350 nlmsg_abort(nw); 1351 return (error); 1352 } 1353 1354 nlattr_add_s32(nw, PFLOWNL_CREATE_ID, unit); 1355 1356 if (! nlmsg_end(nw)) { 1357 pflow_destroy(unit, true); 1358 return (ENOMEM); 1359 } 1360 1361 return (0); 1362 } 1363 1364 struct pflow_parsed_del { 1365 int id; 1366 }; 1367 #define _IN(_field) offsetof(struct genlmsghdr, _field) 1368 #define _OUT(_field) offsetof(struct pflow_parsed_del, _field) 1369 static const struct nlattr_parser nla_p_del[] = { 1370 { .type = PFLOWNL_DEL_ID, .off = _OUT(id), .cb = nlattr_get_uint32 }, 1371 }; 1372 static const struct nlfield_parser nlf_p_del[] = {}; 1373 #undef _IN 1374 #undef _OUT 1375 NL_DECLARE_PARSER(del_parser, struct genlmsghdr, nlf_p_del, nla_p_del); 1376 1377 static int 1378 pflow_nl_del(struct nlmsghdr *hdr, struct nl_pstate *npt) 1379 { 1380 struct pflow_parsed_del d = {}; 1381 int error; 1382 1383 error = nl_parse_nlmsg(hdr, &del_parser, npt, &d); 1384 if (error != 0) 1385 return (error); 1386 1387 error = pflow_destroy(d.id, true); 1388 1389 return (error); 1390 } 1391 1392 struct pflow_parsed_get { 1393 int id; 1394 }; 1395 #define _IN(_field) offsetof(struct genlmsghdr, _field) 1396 #define _OUT(_field) offsetof(struct pflow_parsed_get, _field) 1397 static const struct nlattr_parser nla_p_get[] = { 1398 { .type = PFLOWNL_GET_ID, .off = _OUT(id), .cb = nlattr_get_uint32 }, 1399 }; 1400 static const struct nlfield_parser nlf_p_get[] = {}; 1401 #undef _IN 1402 #undef _OUT 1403 NL_DECLARE_PARSER(get_parser, struct genlmsghdr, nlf_p_get, nla_p_get); 1404 1405 static bool 1406 nlattr_add_sockaddr(struct nl_writer *nw, int attr, const struct sockaddr *s) 1407 { 1408 int off = nlattr_add_nested(nw, attr); 1409 if (off == 0) 1410 return (false); 1411 1412 nlattr_add_u8(nw, PFLOWNL_ADDR_FAMILY, s->sa_family); 1413 1414 switch (s->sa_family) { 1415 case AF_INET: { 1416 const struct sockaddr_in *in = (const struct sockaddr_in *)s; 1417 nlattr_add_u16(nw, PFLOWNL_ADDR_PORT, in->sin_port); 1418 nlattr_add_in_addr(nw, PFLOWNL_ADDR_IP, &in->sin_addr); 1419 break; 1420 } 1421 case AF_INET6: { 1422 const struct sockaddr_in6 *in6 = (const struct sockaddr_in6 *)s; 1423 nlattr_add_u16(nw, PFLOWNL_ADDR_PORT, in6->sin6_port); 1424 nlattr_add_in6_addr(nw, PFLOWNL_ADDR_IP6, &in6->sin6_addr); 1425 break; 1426 } 1427 default: 1428 panic("Unknown address family %d", s->sa_family); 1429 } 1430 1431 nlattr_set_len(nw, off); 1432 return (true); 1433 } 1434 1435 static int 1436 pflow_nl_get(struct nlmsghdr *hdr, struct nl_pstate *npt) 1437 { 1438 struct epoch_tracker et; 1439 struct pflow_parsed_get g = {}; 1440 struct pflow_softc *sc = NULL; 1441 struct nl_writer *nw = npt->nw; 1442 struct genlmsghdr *ghdr_new; 1443 int error; 1444 1445 error = nl_parse_nlmsg(hdr, &get_parser, npt, &g); 1446 if (error != 0) 1447 return (error); 1448 1449 NET_EPOCH_ENTER(et); 1450 CK_LIST_FOREACH(sc, &V_pflowif_list, sc_next) { 1451 if (sc->sc_id == g.id) 1452 break; 1453 } 1454 if (sc == NULL) { 1455 error = ENOENT; 1456 goto out; 1457 } 1458 1459 if (! nlmsg_reply(nw, hdr, sizeof(struct genlmsghdr))) { 1460 nlmsg_abort(nw); 1461 error = ENOMEM; 1462 goto out; 1463 } 1464 1465 ghdr_new = nlmsg_reserve_object(nw, struct genlmsghdr); 1466 if (ghdr_new == NULL) { 1467 nlmsg_abort(nw); 1468 error = ENOMEM; 1469 goto out; 1470 } 1471 1472 ghdr_new->cmd = PFLOWNL_CMD_GET; 1473 ghdr_new->version = 0; 1474 ghdr_new->reserved = 0; 1475 1476 nlattr_add_u32(nw, PFLOWNL_GET_ID, sc->sc_id); 1477 nlattr_add_u16(nw, PFLOWNL_GET_VERSION, sc->sc_version); 1478 if (sc->sc_flowsrc) 1479 nlattr_add_sockaddr(nw, PFLOWNL_GET_SRC, sc->sc_flowsrc); 1480 if (sc->sc_flowdst) 1481 nlattr_add_sockaddr(nw, PFLOWNL_GET_DST, sc->sc_flowdst); 1482 nlattr_add_u32(nw, PFLOWNL_GET_OBSERVATION_DOMAIN, 1483 sc->sc_observation_dom); 1484 1485 if (! nlmsg_end(nw)) { 1486 nlmsg_abort(nw); 1487 error = ENOMEM; 1488 } 1489 1490 out: 1491 NET_EPOCH_EXIT(et); 1492 1493 return (error); 1494 } 1495 1496 struct pflow_sockaddr { 1497 union { 1498 struct sockaddr_in in; 1499 struct sockaddr_in6 in6; 1500 struct sockaddr_storage storage; 1501 }; 1502 }; 1503 static bool 1504 pflow_postparse_sockaddr(void *parsed_args, struct nl_pstate *npt __unused) 1505 { 1506 struct pflow_sockaddr *s = (struct pflow_sockaddr *)parsed_args; 1507 1508 if (s->storage.ss_family == AF_INET) 1509 s->storage.ss_len = sizeof(struct sockaddr_in); 1510 else if (s->storage.ss_family == AF_INET6) 1511 s->storage.ss_len = sizeof(struct sockaddr_in6); 1512 else 1513 return (false); 1514 1515 return (true); 1516 } 1517 1518 #define _OUT(_field) offsetof(struct pflow_sockaddr, _field) 1519 static struct nlattr_parser nla_p_sockaddr[] = { 1520 { .type = PFLOWNL_ADDR_FAMILY, .off = _OUT(in.sin_family), .cb = nlattr_get_uint8 }, 1521 { .type = PFLOWNL_ADDR_PORT, .off = _OUT(in.sin_port), .cb = nlattr_get_uint16 }, 1522 { .type = PFLOWNL_ADDR_IP, .off = _OUT(in.sin_addr), .cb = nlattr_get_in_addr }, 1523 { .type = PFLOWNL_ADDR_IP6, .off = _OUT(in6.sin6_addr), .cb = nlattr_get_in6_addr }, 1524 }; 1525 NL_DECLARE_ATTR_PARSER_EXT(addr_parser, nla_p_sockaddr, pflow_postparse_sockaddr); 1526 #undef _OUT 1527 1528 struct pflow_parsed_set { 1529 int id; 1530 uint16_t version; 1531 struct sockaddr_storage src; 1532 struct sockaddr_storage dst; 1533 uint32_t observation_dom; 1534 }; 1535 #define _IN(_field) offsetof(struct genlmsghdr, _field) 1536 #define _OUT(_field) offsetof(struct pflow_parsed_set, _field) 1537 static const struct nlattr_parser nla_p_set[] = { 1538 { .type = PFLOWNL_SET_ID, .off = _OUT(id), .cb = nlattr_get_uint32 }, 1539 { .type = PFLOWNL_SET_VERSION, .off = _OUT(version), .cb = nlattr_get_uint16 }, 1540 { .type = PFLOWNL_SET_SRC, .off = _OUT(src), .arg = &addr_parser, .cb = nlattr_get_nested }, 1541 { .type = PFLOWNL_SET_DST, .off = _OUT(dst), .arg = &addr_parser, .cb = nlattr_get_nested }, 1542 { .type = PFLOWNL_SET_OBSERVATION_DOMAIN, .off = _OUT(observation_dom), .cb = nlattr_get_uint32 }, 1543 }; 1544 static const struct nlfield_parser nlf_p_set[] = {}; 1545 #undef _IN 1546 #undef _OUT 1547 NL_DECLARE_PARSER(set_parser, struct genlmsghdr, nlf_p_set, nla_p_set); 1548 1549 static int 1550 pflow_set(struct pflow_softc *sc, const struct pflow_parsed_set *pflowr, struct ucred *cred) 1551 { 1552 struct thread *td; 1553 struct socket *so; 1554 int error = 0; 1555 1556 td = curthread; 1557 1558 PFLOW_ASSERT(sc); 1559 1560 if (pflowr->version != 0) { 1561 switch(pflowr->version) { 1562 case PFLOW_PROTO_5: 1563 case PFLOW_PROTO_10: 1564 break; 1565 default: 1566 return(EINVAL); 1567 } 1568 } 1569 1570 pflow_flush(sc); 1571 1572 if (pflowr->dst.ss_len != 0) { 1573 if (sc->sc_flowdst != NULL && 1574 sc->sc_flowdst->sa_family != pflowr->dst.ss_family) { 1575 free(sc->sc_flowdst, M_DEVBUF); 1576 sc->sc_flowdst = NULL; 1577 if (sc->so != NULL) { 1578 soclose(sc->so); 1579 sc->so = NULL; 1580 } 1581 } 1582 1583 switch (pflowr->dst.ss_family) { 1584 case AF_INET: 1585 if (sc->sc_flowdst == NULL) { 1586 if ((sc->sc_flowdst = malloc( 1587 sizeof(struct sockaddr_in), 1588 M_DEVBUF, M_NOWAIT)) == NULL) 1589 return (ENOMEM); 1590 } 1591 memcpy(sc->sc_flowdst, &pflowr->dst, 1592 sizeof(struct sockaddr_in)); 1593 sc->sc_flowdst->sa_len = sizeof(struct 1594 sockaddr_in); 1595 break; 1596 case AF_INET6: 1597 if (sc->sc_flowdst == NULL) { 1598 if ((sc->sc_flowdst = malloc( 1599 sizeof(struct sockaddr_in6), 1600 M_DEVBUF, M_NOWAIT)) == NULL) 1601 return (ENOMEM); 1602 } 1603 memcpy(sc->sc_flowdst, &pflowr->dst, 1604 sizeof(struct sockaddr_in6)); 1605 sc->sc_flowdst->sa_len = sizeof(struct 1606 sockaddr_in6); 1607 break; 1608 default: 1609 break; 1610 } 1611 } 1612 1613 if (pflowr->src.ss_len != 0) { 1614 if (sc->sc_flowsrc != NULL) 1615 free(sc->sc_flowsrc, M_DEVBUF); 1616 sc->sc_flowsrc = NULL; 1617 if (sc->so != NULL) { 1618 soclose(sc->so); 1619 sc->so = NULL; 1620 } 1621 switch(pflowr->src.ss_family) { 1622 case AF_INET: 1623 if ((sc->sc_flowsrc = malloc( 1624 sizeof(struct sockaddr_in), 1625 M_DEVBUF, M_NOWAIT)) == NULL) 1626 return (ENOMEM); 1627 memcpy(sc->sc_flowsrc, &pflowr->src, 1628 sizeof(struct sockaddr_in)); 1629 sc->sc_flowsrc->sa_len = sizeof(struct 1630 sockaddr_in); 1631 break; 1632 case AF_INET6: 1633 if ((sc->sc_flowsrc = malloc( 1634 sizeof(struct sockaddr_in6), 1635 M_DEVBUF, M_NOWAIT)) == NULL) 1636 return (ENOMEM); 1637 memcpy(sc->sc_flowsrc, &pflowr->src, 1638 sizeof(struct sockaddr_in6)); 1639 sc->sc_flowsrc->sa_len = sizeof(struct 1640 sockaddr_in6); 1641 break; 1642 default: 1643 break; 1644 } 1645 } 1646 1647 if (sc->so == NULL) { 1648 if (pflowvalidsockaddr(sc->sc_flowdst, 0)) { 1649 error = socreate(sc->sc_flowdst->sa_family, 1650 &so, SOCK_DGRAM, IPPROTO_UDP, cred, td); 1651 if (error) 1652 return (error); 1653 if (pflowvalidsockaddr(sc->sc_flowsrc, 1)) { 1654 error = sobind(so, sc->sc_flowsrc, td); 1655 if (error) { 1656 soclose(so); 1657 return (error); 1658 } 1659 } 1660 sc->so = so; 1661 } 1662 } else if (!pflowvalidsockaddr(sc->sc_flowdst, 0)) { 1663 soclose(sc->so); 1664 sc->so = NULL; 1665 } 1666 1667 if (pflowr->observation_dom != 0) 1668 sc->sc_observation_dom = pflowr->observation_dom; 1669 1670 /* error check is above */ 1671 if (pflowr->version != 0) 1672 sc->sc_version = pflowr->version; 1673 1674 pflow_setmtu(sc, ETHERMTU); 1675 1676 switch (sc->sc_version) { 1677 case PFLOW_PROTO_5: 1678 callout_stop(&sc->sc_tmo6); 1679 callout_stop(&sc->sc_tmo_tmpl); 1680 break; 1681 case PFLOW_PROTO_10: 1682 callout_reset(&sc->sc_tmo_tmpl, PFLOW_TMPL_TIMEOUT * hz, 1683 pflow_timeout_tmpl, sc); 1684 break; 1685 default: /* NOTREACHED */ 1686 break; 1687 } 1688 1689 return (0); 1690 } 1691 1692 static int 1693 pflow_nl_set(struct nlmsghdr *hdr, struct nl_pstate *npt) 1694 { 1695 struct epoch_tracker et; 1696 struct pflow_parsed_set s = {}; 1697 struct pflow_softc *sc = NULL; 1698 int error; 1699 1700 error = nl_parse_nlmsg(hdr, &set_parser, npt, &s); 1701 if (error != 0) 1702 return (error); 1703 1704 NET_EPOCH_ENTER(et); 1705 CK_LIST_FOREACH(sc, &V_pflowif_list, sc_next) { 1706 if (sc->sc_id == s.id) 1707 break; 1708 } 1709 if (sc == NULL) { 1710 error = ENOENT; 1711 goto out; 1712 } 1713 1714 PFLOW_LOCK(sc); 1715 error = pflow_set(sc, &s, nlp_get_cred(npt->nlp)); 1716 PFLOW_UNLOCK(sc); 1717 1718 out: 1719 NET_EPOCH_EXIT(et); 1720 return (error); 1721 } 1722 1723 static const struct genl_cmd pflow_cmds[] = { 1724 { 1725 .cmd_num = PFLOWNL_CMD_LIST, 1726 .cmd_name = "LIST", 1727 .cmd_cb = pflow_nl_list, 1728 .cmd_flags = GENL_CMD_CAP_DO | GENL_CMD_CAP_DUMP | GENL_CMD_CAP_HASPOL, 1729 .cmd_priv = PRIV_NETINET_PF, 1730 }, 1731 { 1732 .cmd_num = PFLOWNL_CMD_CREATE, 1733 .cmd_name = "CREATE", 1734 .cmd_cb = pflow_nl_create, 1735 .cmd_flags = GENL_CMD_CAP_DO | GENL_CMD_CAP_DUMP | GENL_CMD_CAP_HASPOL, 1736 .cmd_priv = PRIV_NETINET_PF, 1737 }, 1738 { 1739 .cmd_num = PFLOWNL_CMD_DEL, 1740 .cmd_name = "DEL", 1741 .cmd_cb = pflow_nl_del, 1742 .cmd_flags = GENL_CMD_CAP_DO | GENL_CMD_CAP_DUMP | GENL_CMD_CAP_HASPOL, 1743 .cmd_priv = PRIV_NETINET_PF, 1744 }, 1745 { 1746 .cmd_num = PFLOWNL_CMD_GET, 1747 .cmd_name = "GET", 1748 .cmd_cb = pflow_nl_get, 1749 .cmd_flags = GENL_CMD_CAP_DUMP | GENL_CMD_CAP_HASPOL, 1750 .cmd_priv = PRIV_NETINET_PF, 1751 }, 1752 { 1753 .cmd_num = PFLOWNL_CMD_SET, 1754 .cmd_name = "SET", 1755 .cmd_cb = pflow_nl_set, 1756 .cmd_flags = GENL_CMD_CAP_DO | GENL_CMD_CAP_DUMP | GENL_CMD_CAP_HASPOL, 1757 .cmd_priv = PRIV_NETINET_PF, 1758 }, 1759 }; 1760 1761 static const struct nlhdr_parser *all_parsers[] = { 1762 &del_parser, 1763 &get_parser, 1764 &set_parser, 1765 }; 1766 1767 static int 1768 pflow_init(void) 1769 { 1770 bool ret; 1771 int family_id __diagused; 1772 1773 NL_VERIFY_PARSERS(all_parsers); 1774 1775 family_id = genl_register_family(PFLOWNL_FAMILY_NAME, 0, 2, PFLOWNL_CMD_MAX); 1776 MPASS(family_id != 0); 1777 ret = genl_register_cmds(PFLOWNL_FAMILY_NAME, pflow_cmds, NL_ARRAY_LEN(pflow_cmds)); 1778 1779 return (ret ? 0 : ENODEV); 1780 } 1781 1782 static void 1783 pflow_uninit(void) 1784 { 1785 genl_unregister_family(PFLOWNL_FAMILY_NAME); 1786 } 1787 1788 static int 1789 pflow_modevent(module_t mod, int type, void *data) 1790 { 1791 int error = 0; 1792 1793 switch (type) { 1794 case MOD_LOAD: 1795 error = pflow_init(); 1796 break; 1797 case MOD_UNLOAD: 1798 pflow_uninit(); 1799 break; 1800 default: 1801 error = EINVAL; 1802 break; 1803 } 1804 1805 return (error); 1806 } 1807 1808 static moduledata_t pflow_mod = { 1809 pflowname, 1810 pflow_modevent, 1811 0 1812 }; 1813 1814 DECLARE_MODULE(pflow, pflow_mod, SI_SUB_PROTO_FIREWALL, SI_ORDER_ANY); 1815 MODULE_VERSION(pflow, 1); 1816 MODULE_DEPEND(pflow, pf, PF_MODVER, PF_MODVER, PF_MODVER); 1817