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