1 /* $OpenBSD: if_veb.c,v 1.35 2024/02/13 12:22:09 bluhm Exp $ */ 2 3 /* 4 * Copyright (c) 2021 David Gwynne <dlg@openbsd.org> 5 * 6 * Permission to use, copy, modify, and distribute this software for any 7 * purpose with or without fee is hereby granted, provided that the above 8 * copyright notice and this permission notice appear in all copies. 9 * 10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 11 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 12 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 13 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 14 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 15 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 16 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 17 */ 18 19 #include "bpfilter.h" 20 #include "pf.h" 21 #include "vlan.h" 22 23 #include <sys/param.h> 24 #include <sys/kernel.h> 25 #include <sys/malloc.h> 26 #include <sys/mbuf.h> 27 #include <sys/queue.h> 28 #include <sys/socket.h> 29 #include <sys/sockio.h> 30 #include <sys/systm.h> 31 #include <sys/syslog.h> 32 #include <sys/rwlock.h> 33 #include <sys/percpu.h> 34 #include <sys/smr.h> 35 #include <sys/task.h> 36 #include <sys/pool.h> 37 38 #include <net/if.h> 39 #include <net/if_dl.h> 40 #include <net/if_types.h> 41 42 #include <netinet/in.h> 43 #include <netinet/ip.h> 44 #include <netinet/if_ether.h> 45 46 #ifdef INET6 47 #include <netinet6/in6_var.h> 48 #include <netinet/ip6.h> 49 #endif 50 51 #if 0 && defined(IPSEC) 52 /* 53 * IPsec handling is disabled in veb until getting and using tdbs is mpsafe. 54 */ 55 #include <netinet/ip_ipsp.h> 56 #include <net/if_enc.h> 57 #endif 58 59 #include <net/if_bridge.h> 60 #include <net/if_etherbridge.h> 61 62 #if NBPFILTER > 0 63 #include <net/bpf.h> 64 #endif 65 66 #if NPF > 0 67 #include <net/pfvar.h> 68 #endif 69 70 #if NVLAN > 0 71 #include <net/if_vlan_var.h> 72 #endif 73 74 /* SIOCBRDGIFFLGS, SIOCBRDGIFFLGS */ 75 #define VEB_IFBIF_FLAGS (IFBIF_LEARNING|IFBIF_DISCOVER|IFBIF_BLOCKNONIP) 76 77 struct veb_rule { 78 TAILQ_ENTRY(veb_rule) vr_entry; 79 SMR_TAILQ_ENTRY(veb_rule) vr_lentry[2]; 80 81 uint16_t vr_flags; 82 #define VEB_R_F_IN (1U << 0) 83 #define VEB_R_F_OUT (1U << 1) 84 #define VEB_R_F_SRC (1U << 2) 85 #define VEB_R_F_DST (1U << 3) 86 87 #define VEB_R_F_ARP (1U << 4) 88 #define VEB_R_F_RARP (1U << 5) 89 #define VEB_R_F_SHA (1U << 6) 90 #define VEB_R_F_SPA (1U << 7) 91 #define VEB_R_F_THA (1U << 8) 92 #define VEB_R_F_TPA (1U << 9) 93 uint16_t vr_arp_op; 94 95 uint64_t vr_src; 96 uint64_t vr_dst; 97 struct ether_addr vr_arp_sha; 98 struct ether_addr vr_arp_tha; 99 struct in_addr vr_arp_spa; 100 struct in_addr vr_arp_tpa; 101 102 unsigned int vr_action; 103 #define VEB_R_MATCH 0 104 #define VEB_R_PASS 1 105 #define VEB_R_BLOCK 2 106 107 int vr_pftag; 108 }; 109 110 TAILQ_HEAD(veb_rules, veb_rule); 111 SMR_TAILQ_HEAD(veb_rule_list, veb_rule); 112 113 struct veb_softc; 114 115 struct veb_port { 116 struct ifnet *p_ifp0; 117 struct refcnt p_refs; 118 119 int (*p_enqueue)(struct ifnet *, struct mbuf *); 120 121 int (*p_ioctl)(struct ifnet *, u_long, caddr_t); 122 int (*p_output)(struct ifnet *, struct mbuf *, struct sockaddr *, 123 struct rtentry *); 124 125 struct task p_ltask; 126 struct task p_dtask; 127 128 struct veb_softc *p_veb; 129 130 struct ether_brport p_brport; 131 132 unsigned int p_link_state; 133 unsigned int p_bif_flags; 134 uint32_t p_protected; 135 136 struct veb_rules p_vrl; 137 unsigned int p_nvrl; 138 struct veb_rule_list p_vr_list[2]; 139 #define VEB_RULE_LIST_OUT 0 140 #define VEB_RULE_LIST_IN 1 141 }; 142 143 struct veb_ports { 144 struct refcnt m_refs; 145 unsigned int m_count; 146 147 /* followed by an array of veb_port pointers */ 148 }; 149 150 struct veb_softc { 151 struct ifnet sc_if; 152 unsigned int sc_dead; 153 154 struct etherbridge sc_eb; 155 156 struct rwlock sc_rule_lock; 157 struct veb_ports *sc_ports; 158 struct veb_ports *sc_spans; 159 }; 160 161 #define DPRINTF(_sc, fmt...) do { \ 162 if (ISSET((_sc)->sc_if.if_flags, IFF_DEBUG)) \ 163 printf(fmt); \ 164 } while (0) 165 166 static int veb_clone_create(struct if_clone *, int); 167 static int veb_clone_destroy(struct ifnet *); 168 169 static int veb_ioctl(struct ifnet *, u_long, caddr_t); 170 static void veb_input(struct ifnet *, struct mbuf *); 171 static int veb_enqueue(struct ifnet *, struct mbuf *); 172 static int veb_output(struct ifnet *, struct mbuf *, struct sockaddr *, 173 struct rtentry *); 174 static void veb_start(struct ifqueue *); 175 176 static int veb_up(struct veb_softc *); 177 static int veb_down(struct veb_softc *); 178 static int veb_iff(struct veb_softc *); 179 180 static void veb_p_linkch(void *); 181 static void veb_p_detach(void *); 182 static int veb_p_ioctl(struct ifnet *, u_long, caddr_t); 183 static int veb_p_output(struct ifnet *, struct mbuf *, 184 struct sockaddr *, struct rtentry *); 185 186 static inline size_t 187 veb_ports_size(unsigned int n) 188 { 189 /* use of _ALIGN is inspired by CMSGs */ 190 return _ALIGN(sizeof(struct veb_ports)) + 191 n * sizeof(struct veb_port *); 192 } 193 194 static inline struct veb_port ** 195 veb_ports_array(struct veb_ports *m) 196 { 197 return (struct veb_port **)((caddr_t)m + _ALIGN(sizeof(*m))); 198 } 199 200 static inline void veb_ports_free(struct veb_ports *); 201 202 static void veb_p_unlink(struct veb_softc *, struct veb_port *); 203 static void veb_p_fini(struct veb_port *); 204 static void veb_p_dtor(struct veb_softc *, struct veb_port *); 205 static int veb_add_port(struct veb_softc *, 206 const struct ifbreq *, unsigned int); 207 static int veb_del_port(struct veb_softc *, 208 const struct ifbreq *, unsigned int); 209 static int veb_port_list(struct veb_softc *, struct ifbifconf *); 210 static int veb_port_set_flags(struct veb_softc *, struct ifbreq *); 211 static int veb_port_get_flags(struct veb_softc *, struct ifbreq *); 212 static int veb_port_set_protected(struct veb_softc *, 213 const struct ifbreq *); 214 static int veb_add_addr(struct veb_softc *, const struct ifbareq *); 215 static int veb_del_addr(struct veb_softc *, const struct ifbareq *); 216 217 static int veb_rule_add(struct veb_softc *, const struct ifbrlreq *); 218 static int veb_rule_list_flush(struct veb_softc *, 219 const struct ifbrlreq *); 220 static void veb_rule_list_free(struct veb_rule *); 221 static int veb_rule_list_get(struct veb_softc *, struct ifbrlconf *); 222 223 static int veb_eb_port_cmp(void *, void *, void *); 224 static void *veb_eb_port_take(void *, void *); 225 static void veb_eb_port_rele(void *, void *); 226 static size_t veb_eb_port_ifname(void *, char *, size_t, void *); 227 static void veb_eb_port_sa(void *, struct sockaddr_storage *, void *); 228 229 static void veb_eb_brport_take(void *); 230 static void veb_eb_brport_rele(void *); 231 232 static const struct etherbridge_ops veb_etherbridge_ops = { 233 veb_eb_port_cmp, 234 veb_eb_port_take, 235 veb_eb_port_rele, 236 veb_eb_port_ifname, 237 veb_eb_port_sa, 238 }; 239 240 static struct if_clone veb_cloner = 241 IF_CLONE_INITIALIZER("veb", veb_clone_create, veb_clone_destroy); 242 243 static struct pool veb_rule_pool; 244 245 static int vport_clone_create(struct if_clone *, int); 246 static int vport_clone_destroy(struct ifnet *); 247 248 struct vport_softc { 249 struct arpcom sc_ac; 250 unsigned int sc_dead; 251 }; 252 253 static int vport_if_enqueue(struct ifnet *, struct mbuf *); 254 255 static int vport_ioctl(struct ifnet *, u_long, caddr_t); 256 static int vport_enqueue(struct ifnet *, struct mbuf *); 257 static void vport_start(struct ifqueue *); 258 259 static int vport_up(struct vport_softc *); 260 static int vport_down(struct vport_softc *); 261 static int vport_iff(struct vport_softc *); 262 263 static struct if_clone vport_cloner = 264 IF_CLONE_INITIALIZER("vport", vport_clone_create, vport_clone_destroy); 265 266 void 267 vebattach(int count) 268 { 269 if_clone_attach(&veb_cloner); 270 if_clone_attach(&vport_cloner); 271 } 272 273 static int 274 veb_clone_create(struct if_clone *ifc, int unit) 275 { 276 struct veb_softc *sc; 277 struct ifnet *ifp; 278 int error; 279 280 if (veb_rule_pool.pr_size == 0) { 281 pool_init(&veb_rule_pool, sizeof(struct veb_rule), 282 0, IPL_SOFTNET, 0, "vebrpl", NULL); 283 } 284 285 sc = malloc(sizeof(*sc), M_DEVBUF, M_WAITOK|M_ZERO|M_CANFAIL); 286 if (sc == NULL) 287 return (ENOMEM); 288 289 rw_init(&sc->sc_rule_lock, "vebrlk"); 290 sc->sc_ports = NULL; 291 sc->sc_spans = NULL; 292 293 ifp = &sc->sc_if; 294 295 snprintf(ifp->if_xname, IFNAMSIZ, "%s%d", ifc->ifc_name, unit); 296 297 error = etherbridge_init(&sc->sc_eb, ifp->if_xname, 298 &veb_etherbridge_ops, sc); 299 if (error != 0) { 300 free(sc, M_DEVBUF, sizeof(*sc)); 301 return (error); 302 } 303 304 ifp->if_softc = sc; 305 ifp->if_type = IFT_BRIDGE; 306 ifp->if_hdrlen = ETHER_HDR_LEN; 307 ifp->if_hardmtu = ETHER_MAX_HARDMTU_LEN; 308 ifp->if_ioctl = veb_ioctl; 309 ifp->if_input = veb_input; 310 ifp->if_output = veb_output; 311 ifp->if_enqueue = veb_enqueue; 312 ifp->if_qstart = veb_start; 313 ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST; 314 ifp->if_xflags = IFXF_CLONED | IFXF_MPSAFE; 315 316 if_counters_alloc(ifp); 317 if_attach(ifp); 318 319 if_alloc_sadl(ifp); 320 321 #if NBPFILTER > 0 322 bpfattach(&ifp->if_bpf, ifp, DLT_EN10MB, ETHER_HDR_LEN); 323 #endif 324 325 return (0); 326 } 327 328 static int 329 veb_clone_destroy(struct ifnet *ifp) 330 { 331 struct veb_softc *sc = ifp->if_softc; 332 struct veb_ports *mp, *ms; 333 struct veb_port **ps; 334 struct veb_port *p; 335 unsigned int i; 336 337 NET_LOCK(); 338 sc->sc_dead = 1; 339 340 if (ISSET(ifp->if_flags, IFF_RUNNING)) 341 veb_down(sc); 342 NET_UNLOCK(); 343 344 if_detach(ifp); 345 346 NET_LOCK(); 347 348 /* 349 * this is an upside down version of veb_p_dtor() and 350 * veb_ports_destroy() to avoid a lot of malloc/free and 351 * smr_barrier calls if we remove ports one by one. 352 */ 353 354 mp = SMR_PTR_GET_LOCKED(&sc->sc_ports); 355 SMR_PTR_SET_LOCKED(&sc->sc_ports, NULL); 356 if (mp != NULL) { 357 ps = veb_ports_array(mp); 358 for (i = 0; i < mp->m_count; i++) 359 veb_p_unlink(sc, ps[i]); 360 } 361 362 ms = SMR_PTR_GET_LOCKED(&sc->sc_spans); 363 SMR_PTR_SET_LOCKED(&sc->sc_spans, NULL); 364 if (ms != NULL) { 365 ps = veb_ports_array(ms); 366 for (i = 0; i < ms->m_count; i++) 367 veb_p_unlink(sc, ps[i]); 368 } 369 370 if (mp != NULL || ms != NULL) { 371 smr_barrier(); /* everything everywhere all at once */ 372 373 if (mp != NULL) { 374 refcnt_finalize(&mp->m_refs, "vebdtor"); 375 376 ps = veb_ports_array(mp); 377 for (i = 0; i < mp->m_count; i++) { 378 p = ps[i]; 379 /* the ports map holds a port ref */ 380 refcnt_rele(&p->p_refs); 381 /* now we can finalize the port */ 382 veb_p_fini(p); 383 } 384 385 veb_ports_free(mp); 386 } 387 if (ms != NULL) { 388 refcnt_finalize(&ms->m_refs, "vebdtor"); 389 390 ps = veb_ports_array(ms); 391 for (i = 0; i < ms->m_count; i++) { 392 p = ps[i]; 393 /* the ports map holds a port ref */ 394 refcnt_rele(&p->p_refs); 395 /* now we can finalize the port */ 396 veb_p_fini(p); 397 } 398 399 veb_ports_free(ms); 400 } 401 } 402 NET_UNLOCK(); 403 404 etherbridge_destroy(&sc->sc_eb); 405 406 free(sc, M_DEVBUF, sizeof(*sc)); 407 408 return (0); 409 } 410 411 static struct mbuf * 412 veb_span_input(struct ifnet *ifp0, struct mbuf *m, uint64_t dst, void *brport) 413 { 414 m_freem(m); 415 return (NULL); 416 } 417 418 static void 419 veb_span(struct veb_softc *sc, struct mbuf *m0) 420 { 421 struct veb_ports *sm; 422 struct veb_port **ps; 423 struct veb_port *p; 424 struct ifnet *ifp0; 425 struct mbuf *m; 426 unsigned int i; 427 428 smr_read_enter(); 429 sm = SMR_PTR_GET(&sc->sc_spans); 430 if (sm != NULL) 431 refcnt_take(&sm->m_refs); 432 smr_read_leave(); 433 if (sm == NULL) 434 return; 435 436 ps = veb_ports_array(sm); 437 for (i = 0; i < sm->m_count; i++) { 438 p = ps[i]; 439 440 ifp0 = p->p_ifp0; 441 if (!ISSET(ifp0->if_flags, IFF_RUNNING)) 442 continue; 443 444 m = m_dup_pkt(m0, max_linkhdr + ETHER_ALIGN, M_NOWAIT); 445 if (m == NULL) { 446 /* XXX count error */ 447 continue; 448 } 449 450 if_enqueue(ifp0, m); /* XXX count error */ 451 } 452 refcnt_rele_wake(&sm->m_refs); 453 } 454 455 static int 456 veb_ip_filter(const struct mbuf *m) 457 { 458 const struct ether_header *eh; 459 460 eh = mtod(m, struct ether_header *); 461 switch (ntohs(eh->ether_type)) { 462 case ETHERTYPE_IP: 463 case ETHERTYPE_ARP: 464 case ETHERTYPE_REVARP: 465 case ETHERTYPE_IPV6: 466 return (0); 467 default: 468 break; 469 } 470 471 return (1); 472 } 473 474 static int 475 veb_vlan_filter(const struct mbuf *m) 476 { 477 const struct ether_header *eh; 478 479 eh = mtod(m, struct ether_header *); 480 switch (ntohs(eh->ether_type)) { 481 case ETHERTYPE_VLAN: 482 case ETHERTYPE_QINQ: 483 return (1); 484 default: 485 break; 486 } 487 488 return (0); 489 } 490 491 static int 492 veb_rule_arp_match(const struct veb_rule *vr, struct mbuf *m) 493 { 494 struct ether_header *eh; 495 struct ether_arp ea; 496 497 eh = mtod(m, struct ether_header *); 498 499 if (eh->ether_type != htons(ETHERTYPE_ARP)) 500 return (0); 501 if (m->m_pkthdr.len < sizeof(*eh) + sizeof(ea)) 502 return (0); 503 504 m_copydata(m, sizeof(*eh), sizeof(ea), (caddr_t)&ea); 505 506 if (ea.arp_hrd != htons(ARPHRD_ETHER) || 507 ea.arp_pro != htons(ETHERTYPE_IP) || 508 ea.arp_hln != ETHER_ADDR_LEN || 509 ea.arp_pln != sizeof(struct in_addr)) 510 return (0); 511 512 if (ISSET(vr->vr_flags, VEB_R_F_ARP)) { 513 if (ea.arp_op != htons(ARPOP_REQUEST) && 514 ea.arp_op != htons(ARPOP_REPLY)) 515 return (0); 516 } 517 if (ISSET(vr->vr_flags, VEB_R_F_RARP)) { 518 if (ea.arp_op != htons(ARPOP_REVREQUEST) && 519 ea.arp_op != htons(ARPOP_REVREPLY)) 520 return (0); 521 } 522 523 if (vr->vr_arp_op != htons(0) && vr->vr_arp_op != ea.arp_op) 524 return (0); 525 526 if (ISSET(vr->vr_flags, VEB_R_F_SHA) && 527 !ETHER_IS_EQ(&vr->vr_arp_sha, ea.arp_sha)) 528 return (0); 529 if (ISSET(vr->vr_flags, VEB_R_F_THA) && 530 !ETHER_IS_EQ(&vr->vr_arp_tha, ea.arp_tha)) 531 return (0); 532 if (ISSET(vr->vr_flags, VEB_R_F_SPA) && 533 memcmp(&vr->vr_arp_spa, ea.arp_spa, sizeof(vr->vr_arp_spa)) != 0) 534 return (0); 535 if (ISSET(vr->vr_flags, VEB_R_F_TPA) && 536 memcmp(&vr->vr_arp_tpa, ea.arp_tpa, sizeof(vr->vr_arp_tpa)) != 0) 537 return (0); 538 539 return (1); 540 } 541 542 static int 543 veb_rule_list_test(struct veb_rule *vr, int dir, struct mbuf *m, 544 uint64_t src, uint64_t dst) 545 { 546 SMR_ASSERT_CRITICAL(); 547 548 do { 549 if (ISSET(vr->vr_flags, VEB_R_F_ARP|VEB_R_F_RARP) && 550 !veb_rule_arp_match(vr, m)) 551 continue; 552 553 if (ISSET(vr->vr_flags, VEB_R_F_SRC) && 554 vr->vr_src != src) 555 continue; 556 if (ISSET(vr->vr_flags, VEB_R_F_DST) && 557 vr->vr_dst != dst) 558 continue; 559 560 if (vr->vr_action == VEB_R_BLOCK) 561 return (VEB_R_BLOCK); 562 #if NPF > 0 563 pf_tag_packet(m, vr->vr_pftag, -1); 564 #endif 565 if (vr->vr_action == VEB_R_PASS) 566 return (VEB_R_PASS); 567 } while ((vr = SMR_TAILQ_NEXT(vr, vr_lentry[dir])) != NULL); 568 569 return (VEB_R_PASS); 570 } 571 572 static inline int 573 veb_rule_filter(struct veb_port *p, int dir, struct mbuf *m, 574 uint64_t src, uint64_t dst) 575 { 576 struct veb_rule *vr; 577 int filter = VEB_R_PASS; 578 579 smr_read_enter(); 580 vr = SMR_TAILQ_FIRST(&p->p_vr_list[dir]); 581 if (vr != NULL) 582 filter = veb_rule_list_test(vr, dir, m, src, dst); 583 smr_read_leave(); 584 585 return (filter == VEB_R_BLOCK); 586 } 587 588 #if NPF > 0 589 struct veb_pf_ip_family { 590 sa_family_t af; 591 struct mbuf *(*ip_check)(struct ifnet *, struct mbuf *); 592 void (*ip_input)(struct ifnet *, struct mbuf *); 593 }; 594 595 static const struct veb_pf_ip_family veb_pf_ipv4 = { 596 .af = AF_INET, 597 .ip_check = ipv4_check, 598 .ip_input = ipv4_input, 599 }; 600 601 #ifdef INET6 602 static const struct veb_pf_ip_family veb_pf_ipv6 = { 603 .af = AF_INET6, 604 .ip_check = ipv6_check, 605 .ip_input = ipv6_input, 606 }; 607 #endif 608 609 static struct mbuf * 610 veb_pf(struct ifnet *ifp0, int dir, struct mbuf *m) 611 { 612 struct ether_header *eh, copy; 613 const struct veb_pf_ip_family *fam; 614 int hlen; 615 616 /* 617 * pf runs on vport interfaces when they enter or leave the 618 * l3 stack, so don't confuse things (even more) by running 619 * pf again here. note that because of this exception the 620 * pf direction on vport interfaces is reversed compared to 621 * other veb ports. 622 */ 623 if (ifp0->if_enqueue == vport_enqueue) 624 return (m); 625 626 eh = mtod(m, struct ether_header *); 627 switch (ntohs(eh->ether_type)) { 628 case ETHERTYPE_IP: 629 fam = &veb_pf_ipv4; 630 break; 631 #ifdef INET6 632 case ETHERTYPE_IPV6: 633 fam = &veb_pf_ipv6; 634 break; 635 #endif 636 default: 637 return (m); 638 } 639 640 copy = *eh; 641 m_adj(m, sizeof(*eh)); 642 643 m = (*fam->ip_check)(ifp0, m); 644 if (m == NULL) 645 return (NULL); 646 647 if (pf_test(fam->af, dir, ifp0, &m) != PF_PASS) { 648 m_freem(m); 649 return (NULL); 650 } 651 if (m == NULL) 652 return (NULL); 653 654 if (dir == PF_IN && ISSET(m->m_pkthdr.pf.flags, PF_TAG_DIVERTED)) { 655 pf_mbuf_unlink_state_key(m); 656 pf_mbuf_unlink_inpcb(m); 657 (*fam->ip_input)(ifp0, m); 658 return (NULL); 659 } 660 661 hlen = roundup(sizeof(*eh), sizeof(long)); 662 m = m_prepend(m, hlen, M_DONTWAIT); 663 if (m == NULL) 664 return (NULL); 665 666 /* checksum? */ 667 668 m_adj(m, hlen - sizeof(*eh)); 669 eh = mtod(m, struct ether_header *); 670 *eh = copy; 671 672 return (m); 673 } 674 #endif /* NPF > 0 */ 675 676 #if 0 && defined(IPSEC) 677 static struct mbuf * 678 veb_ipsec_proto_in(struct ifnet *ifp0, struct mbuf *m, int iphlen, 679 /* const */ union sockaddr_union *dst, int poff) 680 { 681 struct tdb *tdb; 682 uint16_t cpi; 683 uint32_t spi; 684 uint8_t proto; 685 686 /* ipsec_common_input checks for 8 bytes of input, so we do too */ 687 if (m->m_pkthdr.len < iphlen + 2 * sizeof(u_int32_t)) 688 return (m); /* decline */ 689 690 proto = *(mtod(m, uint8_t *) + poff); 691 /* i'm not a huge fan of how these headers get picked at */ 692 switch (proto) { 693 case IPPROTO_ESP: 694 m_copydata(m, iphlen, sizeof(spi), &spi); 695 break; 696 case IPPROTO_AH: 697 m_copydata(m, iphlen + sizeof(uint32_t), sizeof(spi), &spi); 698 break; 699 case IPPROTO_IPCOMP: 700 m_copydata(m, iphlen + sizeof(uint16_t), sizeof(cpi), &cpi); 701 spi = htonl(ntohs(cpi)); 702 break; 703 default: 704 return (m); /* decline */ 705 } 706 707 tdb = gettdb(m->m_pkthdr.ph_rtableid, spi, dst, proto); 708 if (tdb != NULL && !ISSET(tdb->tdb_flags, TDBF_INVALID) && 709 tdb->tdb_xform != NULL) { 710 if (tdb->tdb_first_use == 0) { 711 tdb->tdb_first_use = gettime(); 712 if (ISSET(tdb->tdb_flags, TDBF_FIRSTUSE)) { 713 timeout_add_sec(&tdb->tdb_first_tmo, 714 tdb->tdb_exp_first_use); 715 } 716 if (ISSET(tdb->tdb_flags, TDBF_SOFT_FIRSTUSE)) { 717 timeout_add_sec(&tdb->tdb_sfirst_tmo, 718 tdb->tdb_soft_first_use); 719 } 720 } 721 722 (*(tdb->tdb_xform->xf_input))(m, tdb, iphlen, poff); 723 return (NULL); 724 } 725 726 return (m); 727 } 728 729 static struct mbuf * 730 veb_ipsec_ipv4_in(struct ifnet *ifp0, struct mbuf *m) 731 { 732 union sockaddr_union su = { 733 .sin.sin_len = sizeof(su.sin), 734 .sin.sin_family = AF_INET, 735 }; 736 struct ip *ip; 737 int iphlen; 738 739 if (m->m_len < sizeof(*ip)) { 740 m = m_pullup(m, sizeof(*ip)); 741 if (m == NULL) 742 return (NULL); 743 } 744 745 ip = mtod(m, struct ip *); 746 iphlen = ip->ip_hl << 2; 747 if (iphlen < sizeof(*ip)) { 748 /* this is a weird packet, decline */ 749 return (m); 750 } 751 752 su.sin.sin_addr = ip->ip_dst; 753 754 return (veb_ipsec_proto_in(ifp0, m, iphlen, &su, 755 offsetof(struct ip, ip_p))); 756 } 757 758 #ifdef INET6 759 static struct mbuf * 760 veb_ipsec_ipv6_in(struct ifnet *ifp0, struct mbuf *m) 761 { 762 union sockaddr_union su = { 763 .sin6.sin6_len = sizeof(su.sin6), 764 .sin6.sin6_family = AF_INET6, 765 }; 766 struct ip6_hdr *ip6; 767 768 if (m->m_len < sizeof(*ip6)) { 769 m = m_pullup(m, sizeof(*ip6)); 770 if (m == NULL) 771 return (NULL); 772 } 773 774 ip6 = mtod(m, struct ip6_hdr *); 775 776 su.sin6.sin6_addr = ip6->ip6_dst; 777 778 /* XXX scope? */ 779 780 return (veb_ipsec_proto_in(ifp0, m, sizeof(*ip6), &su, 781 offsetof(struct ip6_hdr, ip6_nxt))); 782 } 783 #endif /* INET6 */ 784 785 static struct mbuf * 786 veb_ipsec_in(struct ifnet *ifp0, struct mbuf *m) 787 { 788 struct mbuf *(*ipsec_ip_in)(struct ifnet *, struct mbuf *); 789 struct ether_header *eh, copy; 790 791 if (ifp0->if_enqueue == vport_enqueue) 792 return (m); 793 794 eh = mtod(m, struct ether_header *); 795 switch (ntohs(eh->ether_type)) { 796 case ETHERTYPE_IP: 797 ipsec_ip_in = veb_ipsec_ipv4_in; 798 break; 799 #ifdef INET6 800 case ETHERTYPE_IPV6: 801 ipsec_ip_in = veb_ipsec_ipv6_in; 802 break; 803 #endif /* INET6 */ 804 default: 805 return (m); 806 } 807 808 copy = *eh; 809 m_adj(m, sizeof(*eh)); 810 811 m = (*ipsec_ip_in)(ifp0, m); 812 if (m == NULL) 813 return (NULL); 814 815 m = m_prepend(m, sizeof(*eh), M_DONTWAIT); 816 if (m == NULL) 817 return (NULL); 818 819 eh = mtod(m, struct ether_header *); 820 *eh = copy; 821 822 return (m); 823 } 824 825 static struct mbuf * 826 veb_ipsec_proto_out(struct mbuf *m, sa_family_t af, int iphlen) 827 { 828 struct tdb *tdb; 829 int error; 830 #if NPF > 0 831 struct ifnet *encifp; 832 #endif 833 834 tdb = ipsp_spd_lookup(m, af, iphlen, &error, IPSP_DIRECTION_OUT, 835 NULL, NULL, NULL); 836 if (tdb == NULL) 837 return (m); 838 839 #if NPF > 0 840 encifp = enc_getif(tdb->tdb_rdomain, tdb->tdb_tap); 841 if (encifp != NULL) { 842 if (pf_test(af, PF_OUT, encifp, &m) != PF_PASS) { 843 m_freem(m); 844 return (NULL); 845 } 846 if (m == NULL) 847 return (NULL); 848 } 849 #endif /* NPF > 0 */ 850 851 /* XXX mtu checks */ 852 853 (void)ipsp_process_packet(m, tdb, af, 0); 854 return (NULL); 855 } 856 857 static struct mbuf * 858 veb_ipsec_ipv4_out(struct mbuf *m) 859 { 860 struct ip *ip; 861 int iphlen; 862 863 if (m->m_len < sizeof(*ip)) { 864 m = m_pullup(m, sizeof(*ip)); 865 if (m == NULL) 866 return (NULL); 867 } 868 869 ip = mtod(m, struct ip *); 870 iphlen = ip->ip_hl << 2; 871 if (iphlen < sizeof(*ip)) { 872 /* this is a weird packet, decline */ 873 return (m); 874 } 875 876 return (veb_ipsec_proto_out(m, AF_INET, iphlen)); 877 } 878 879 #ifdef INET6 880 static struct mbuf * 881 veb_ipsec_ipv6_out(struct mbuf *m) 882 { 883 return (veb_ipsec_proto_out(m, AF_INET6, sizeof(struct ip6_hdr))); 884 } 885 #endif /* INET6 */ 886 887 static struct mbuf * 888 veb_ipsec_out(struct ifnet *ifp0, struct mbuf *m) 889 { 890 struct mbuf *(*ipsec_ip_out)(struct mbuf *); 891 struct ether_header *eh, copy; 892 893 if (ifp0->if_enqueue == vport_enqueue) 894 return (m); 895 896 eh = mtod(m, struct ether_header *); 897 switch (ntohs(eh->ether_type)) { 898 case ETHERTYPE_IP: 899 ipsec_ip_out = veb_ipsec_ipv4_out; 900 break; 901 #ifdef INET6 902 case ETHERTYPE_IPV6: 903 ipsec_ip_out = veb_ipsec_ipv6_out; 904 break; 905 #endif /* INET6 */ 906 default: 907 return (m); 908 } 909 910 copy = *eh; 911 m_adj(m, sizeof(*eh)); 912 913 m = (*ipsec_ip_out)(m); 914 if (m == NULL) 915 return (NULL); 916 917 m = m_prepend(m, sizeof(*eh), M_DONTWAIT); 918 if (m == NULL) 919 return (NULL); 920 921 eh = mtod(m, struct ether_header *); 922 *eh = copy; 923 924 return (m); 925 } 926 #endif /* IPSEC */ 927 928 static void 929 veb_broadcast(struct veb_softc *sc, struct veb_port *rp, struct mbuf *m0, 930 uint64_t src, uint64_t dst) 931 { 932 struct ifnet *ifp = &sc->sc_if; 933 struct veb_ports *pm; 934 struct veb_port **ps; 935 struct veb_port *tp; 936 struct ifnet *ifp0; 937 struct mbuf *m; 938 unsigned int i; 939 940 #if NPF > 0 941 /* 942 * we couldn't find a specific port to send this packet to, 943 * but pf should still have a chance to apply policy to it. 944 * let pf look at it, but use the veb interface as a proxy. 945 */ 946 if (ISSET(ifp->if_flags, IFF_LINK1) && 947 (m0 = veb_pf(ifp, PF_OUT, m0)) == NULL) 948 return; 949 #endif 950 951 #if 0 && defined(IPSEC) 952 /* same goes for ipsec */ 953 if (ISSET(ifp->if_flags, IFF_LINK2) && 954 (m0 = veb_ipsec_out(ifp, m0)) == NULL) 955 return; 956 #endif 957 958 counters_pkt(ifp->if_counters, ifc_opackets, ifc_obytes, 959 m0->m_pkthdr.len); 960 961 smr_read_enter(); 962 pm = SMR_PTR_GET(&sc->sc_ports); 963 if (__predict_true(pm != NULL)) 964 refcnt_take(&pm->m_refs); 965 smr_read_leave(); 966 if (__predict_false(pm == NULL)) 967 goto done; 968 969 ps = veb_ports_array(pm); 970 for (i = 0; i < pm->m_count; i++) { 971 tp = ps[i]; 972 973 if (rp == tp || (rp->p_protected & tp->p_protected)) { 974 /* 975 * don't let Ethernet packets hairpin or 976 * move between ports in the same protected 977 * domain(s). 978 */ 979 continue; 980 } 981 982 ifp0 = tp->p_ifp0; 983 if (!ISSET(ifp0->if_flags, IFF_RUNNING)) { 984 /* don't waste time */ 985 continue; 986 } 987 988 if (!ISSET(tp->p_bif_flags, IFBIF_DISCOVER) && 989 !ISSET(m0->m_flags, M_BCAST | M_MCAST)) { 990 /* don't flood unknown unicast */ 991 continue; 992 } 993 994 if (veb_rule_filter(tp, VEB_RULE_LIST_OUT, m0, src, dst)) 995 continue; 996 997 m = m_dup_pkt(m0, max_linkhdr + ETHER_ALIGN, M_NOWAIT); 998 if (m == NULL) { 999 /* XXX count error? */ 1000 continue; 1001 } 1002 1003 (*tp->p_enqueue)(ifp0, m); /* XXX count error */ 1004 } 1005 refcnt_rele_wake(&pm->m_refs); 1006 1007 done: 1008 m_freem(m0); 1009 } 1010 1011 static struct mbuf * 1012 veb_transmit(struct veb_softc *sc, struct veb_port *rp, struct veb_port *tp, 1013 struct mbuf *m, uint64_t src, uint64_t dst) 1014 { 1015 struct ifnet *ifp = &sc->sc_if; 1016 struct ifnet *ifp0; 1017 1018 if (tp == NULL) 1019 return (m); 1020 1021 if (rp == tp || (rp->p_protected & tp->p_protected)) { 1022 /* 1023 * don't let Ethernet packets hairpin or move between 1024 * ports in the same protected domain(s). 1025 */ 1026 goto drop; 1027 } 1028 1029 if (veb_rule_filter(tp, VEB_RULE_LIST_OUT, m, src, dst)) 1030 goto drop; 1031 1032 ifp0 = tp->p_ifp0; 1033 1034 #if 0 && defined(IPSEC) 1035 if (ISSET(ifp->if_flags, IFF_LINK2) && 1036 (m = veb_ipsec_out(ifp0, m0)) == NULL) 1037 return; 1038 #endif 1039 1040 #if NPF > 0 1041 if (ISSET(ifp->if_flags, IFF_LINK1) && 1042 (m = veb_pf(ifp0, PF_OUT, m)) == NULL) 1043 return (NULL); 1044 #endif 1045 1046 counters_pkt(ifp->if_counters, ifc_opackets, ifc_obytes, 1047 m->m_pkthdr.len); 1048 1049 (*tp->p_enqueue)(ifp0, m); /* XXX count error */ 1050 1051 return (NULL); 1052 drop: 1053 m_freem(m); 1054 return (NULL); 1055 } 1056 1057 static struct mbuf * 1058 veb_vport_input(struct ifnet *ifp0, struct mbuf *m, uint64_t dst, void *brport) 1059 { 1060 return (m); 1061 } 1062 1063 static struct mbuf * 1064 veb_port_input(struct ifnet *ifp0, struct mbuf *m, uint64_t dst, void *brport) 1065 { 1066 struct veb_port *p = brport; 1067 struct veb_softc *sc = p->p_veb; 1068 struct ifnet *ifp = &sc->sc_if; 1069 struct ether_header *eh; 1070 uint64_t src; 1071 #if NBPFILTER > 0 1072 caddr_t if_bpf; 1073 #endif 1074 1075 if (!ISSET(ifp->if_flags, IFF_RUNNING)) 1076 return (m); 1077 1078 eh = mtod(m, struct ether_header *); 1079 src = ether_addr_to_e64((struct ether_addr *)eh->ether_shost); 1080 1081 /* Is this a MAC Bridge component Reserved address? */ 1082 if (ETH64_IS_8021_RSVD(dst)) { 1083 if (!ISSET(ifp->if_flags, IFF_LINK0)) { 1084 /* 1085 * letting vlans through implies this is 1086 * an s-vlan component. 1087 */ 1088 goto drop; 1089 } 1090 1091 /* look at the last nibble of the 802.1 reserved address */ 1092 switch (dst & 0xf) { 1093 case 0x0: /* Nearest Customer Bridge Group Address */ 1094 case 0xb: /* EDE-SS PEP (IEEE Std 802.1AEcg) */ 1095 case 0xc: /* reserved */ 1096 case 0xd: /* Provider Bridge MVRP Address */ 1097 case 0xf: /* reserved */ 1098 break; 1099 default: 1100 goto drop; 1101 } 1102 } 1103 1104 #if NVLAN > 0 1105 /* 1106 * If the underlying interface removed the VLAN header itself, 1107 * add it back. 1108 */ 1109 if (ISSET(m->m_flags, M_VLANTAG)) { 1110 m = vlan_inject(m, ETHERTYPE_VLAN, m->m_pkthdr.ether_vtag); 1111 if (m == NULL) { 1112 counters_inc(ifp->if_counters, ifc_ierrors); 1113 goto drop; 1114 } 1115 } 1116 #endif 1117 1118 counters_pkt(ifp->if_counters, ifc_ipackets, ifc_ibytes, 1119 m->m_pkthdr.len); 1120 1121 /* force packets into the one routing domain for pf */ 1122 m->m_pkthdr.ph_rtableid = ifp->if_rdomain; 1123 1124 #if NBPFILTER > 0 1125 if_bpf = READ_ONCE(ifp->if_bpf); 1126 if (if_bpf != NULL) { 1127 if (bpf_mtap_ether(if_bpf, m, 0) != 0) 1128 goto drop; 1129 } 1130 #endif 1131 1132 veb_span(sc, m); 1133 1134 if (ISSET(p->p_bif_flags, IFBIF_BLOCKNONIP) && 1135 veb_ip_filter(m)) 1136 goto drop; 1137 1138 if (!ISSET(ifp->if_flags, IFF_LINK0) && 1139 veb_vlan_filter(m)) 1140 goto drop; 1141 1142 if (veb_rule_filter(p, VEB_RULE_LIST_IN, m, src, dst)) 1143 goto drop; 1144 1145 #if NPF > 0 1146 if (ISSET(ifp->if_flags, IFF_LINK1) && 1147 (m = veb_pf(ifp0, PF_IN, m)) == NULL) 1148 return (NULL); 1149 #endif 1150 1151 #if 0 && defined(IPSEC) 1152 if (ISSET(ifp->if_flags, IFF_LINK2) && 1153 (m = veb_ipsec_in(ifp0, m)) == NULL) 1154 return (NULL); 1155 #endif 1156 1157 eh = mtod(m, struct ether_header *); 1158 1159 if (ISSET(p->p_bif_flags, IFBIF_LEARNING)) 1160 etherbridge_map(&sc->sc_eb, p, src); 1161 1162 CLR(m->m_flags, M_BCAST|M_MCAST); 1163 1164 if (!ETH64_IS_MULTICAST(dst)) { 1165 struct veb_port *tp = NULL; 1166 1167 smr_read_enter(); 1168 tp = etherbridge_resolve(&sc->sc_eb, dst); 1169 if (tp != NULL) 1170 veb_eb_port_take(NULL, tp); 1171 smr_read_leave(); 1172 if (tp != NULL) { 1173 m = veb_transmit(sc, p, tp, m, src, dst); 1174 veb_eb_port_rele(NULL, tp); 1175 } 1176 1177 if (m == NULL) 1178 return (NULL); 1179 1180 /* unknown unicast address */ 1181 } else { 1182 SET(m->m_flags, ETH64_IS_BROADCAST(dst) ? M_BCAST : M_MCAST); 1183 } 1184 1185 veb_broadcast(sc, p, m, src, dst); 1186 return (NULL); 1187 1188 drop: 1189 m_freem(m); 1190 return (NULL); 1191 } 1192 1193 static void 1194 veb_input(struct ifnet *ifp, struct mbuf *m) 1195 { 1196 m_freem(m); 1197 } 1198 1199 static int 1200 veb_output(struct ifnet *ifp, struct mbuf *m, struct sockaddr *dst, 1201 struct rtentry *rt) 1202 { 1203 m_freem(m); 1204 return (ENODEV); 1205 } 1206 1207 static int 1208 veb_enqueue(struct ifnet *ifp, struct mbuf *m) 1209 { 1210 m_freem(m); 1211 return (ENODEV); 1212 } 1213 1214 static void 1215 veb_start(struct ifqueue *ifq) 1216 { 1217 ifq_purge(ifq); 1218 } 1219 1220 static int 1221 veb_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data) 1222 { 1223 struct veb_softc *sc = ifp->if_softc; 1224 struct ifbrparam *bparam = (struct ifbrparam *)data; 1225 int error = 0; 1226 1227 if (sc->sc_dead) 1228 return (ENXIO); 1229 1230 switch (cmd) { 1231 case SIOCSIFFLAGS: 1232 if (ISSET(ifp->if_flags, IFF_UP)) { 1233 if (!ISSET(ifp->if_flags, IFF_RUNNING)) 1234 error = veb_up(sc); 1235 } else { 1236 if (ISSET(ifp->if_flags, IFF_RUNNING)) 1237 error = veb_down(sc); 1238 } 1239 break; 1240 1241 case SIOCBRDGADD: 1242 error = suser(curproc); 1243 if (error != 0) 1244 break; 1245 1246 error = veb_add_port(sc, (struct ifbreq *)data, 0); 1247 break; 1248 case SIOCBRDGADDS: 1249 error = suser(curproc); 1250 if (error != 0) 1251 break; 1252 1253 error = veb_add_port(sc, (struct ifbreq *)data, 1); 1254 break; 1255 case SIOCBRDGDEL: 1256 error = suser(curproc); 1257 if (error != 0) 1258 break; 1259 1260 error = veb_del_port(sc, (struct ifbreq *)data, 0); 1261 break; 1262 case SIOCBRDGDELS: 1263 error = suser(curproc); 1264 if (error != 0) 1265 break; 1266 1267 error = veb_del_port(sc, (struct ifbreq *)data, 1); 1268 break; 1269 1270 case SIOCBRDGSCACHE: 1271 error = suser(curproc); 1272 if (error != 0) 1273 break; 1274 1275 error = etherbridge_set_max(&sc->sc_eb, bparam); 1276 break; 1277 case SIOCBRDGGCACHE: 1278 error = etherbridge_get_max(&sc->sc_eb, bparam); 1279 break; 1280 1281 case SIOCBRDGSTO: 1282 error = suser(curproc); 1283 if (error != 0) 1284 break; 1285 1286 error = etherbridge_set_tmo(&sc->sc_eb, bparam); 1287 break; 1288 case SIOCBRDGGTO: 1289 error = etherbridge_get_tmo(&sc->sc_eb, bparam); 1290 break; 1291 1292 case SIOCBRDGRTS: 1293 error = etherbridge_rtfind(&sc->sc_eb, (struct ifbaconf *)data); 1294 break; 1295 case SIOCBRDGIFS: 1296 error = veb_port_list(sc, (struct ifbifconf *)data); 1297 break; 1298 case SIOCBRDGFLUSH: 1299 etherbridge_flush(&sc->sc_eb, 1300 ((struct ifbreq *)data)->ifbr_ifsflags); 1301 break; 1302 case SIOCBRDGSADDR: 1303 error = veb_add_addr(sc, (struct ifbareq *)data); 1304 break; 1305 case SIOCBRDGDADDR: 1306 error = veb_del_addr(sc, (struct ifbareq *)data); 1307 break; 1308 1309 case SIOCBRDGSIFPROT: 1310 error = veb_port_set_protected(sc, (struct ifbreq *)data); 1311 break; 1312 1313 case SIOCBRDGSIFFLGS: 1314 error = veb_port_set_flags(sc, (struct ifbreq *)data); 1315 break; 1316 case SIOCBRDGGIFFLGS: 1317 error = veb_port_get_flags(sc, (struct ifbreq *)data); 1318 break; 1319 1320 case SIOCBRDGARL: 1321 error = veb_rule_add(sc, (struct ifbrlreq *)data); 1322 break; 1323 case SIOCBRDGFRL: 1324 error = veb_rule_list_flush(sc, (struct ifbrlreq *)data); 1325 break; 1326 case SIOCBRDGGRL: 1327 error = veb_rule_list_get(sc, (struct ifbrlconf *)data); 1328 break; 1329 1330 default: 1331 error = ENOTTY; 1332 break; 1333 } 1334 1335 if (error == ENETRESET) 1336 error = veb_iff(sc); 1337 1338 return (error); 1339 } 1340 1341 static struct veb_ports * 1342 veb_ports_insert(struct veb_ports *om, struct veb_port *p) 1343 { 1344 struct veb_ports *nm; 1345 struct veb_port **nps, **ops; 1346 unsigned int ocount = om != NULL ? om->m_count : 0; 1347 unsigned int ncount = ocount + 1; 1348 unsigned int i; 1349 1350 nm = malloc(veb_ports_size(ncount), M_DEVBUF, M_WAITOK|M_ZERO); 1351 1352 refcnt_init(&nm->m_refs); 1353 nm->m_count = ncount; 1354 1355 nps = veb_ports_array(nm); 1356 1357 if (om != NULL) { 1358 ops = veb_ports_array(om); 1359 for (i = 0; i < ocount; i++) { 1360 struct veb_port *op = ops[i]; 1361 refcnt_take(&op->p_refs); 1362 nps[i] = op; 1363 } 1364 } else 1365 i = 0; 1366 1367 refcnt_take(&p->p_refs); 1368 nps[i] = p; 1369 1370 return (nm); 1371 } 1372 1373 static struct veb_ports * 1374 veb_ports_remove(struct veb_ports *om, struct veb_port *p) 1375 { 1376 struct veb_ports *nm; 1377 struct veb_port **nps, **ops; 1378 unsigned int ocount = om->m_count; 1379 unsigned int ncount = ocount - 1; 1380 unsigned int i, j; 1381 1382 if (ncount == 0) 1383 return (NULL); 1384 1385 nm = malloc(veb_ports_size(ncount), M_DEVBUF, M_WAITOK|M_ZERO); 1386 1387 refcnt_init(&nm->m_refs); 1388 nm->m_count = ncount; 1389 1390 nps = veb_ports_array(nm); 1391 j = 0; 1392 1393 ops = veb_ports_array(om); 1394 for (i = 0; i < ocount; i++) { 1395 struct veb_port *op = ops[i]; 1396 if (op == p) 1397 continue; 1398 1399 refcnt_take(&op->p_refs); 1400 nps[j++] = op; 1401 } 1402 KASSERT(j == ncount); 1403 1404 return (nm); 1405 } 1406 1407 static inline void 1408 veb_ports_free(struct veb_ports *m) 1409 { 1410 free(m, M_DEVBUF, veb_ports_size(m->m_count)); 1411 } 1412 1413 static void 1414 veb_ports_destroy(struct veb_ports *m) 1415 { 1416 struct veb_port **ps = veb_ports_array(m); 1417 unsigned int i; 1418 1419 for (i = 0; i < m->m_count; i++) { 1420 struct veb_port *p = ps[i]; 1421 refcnt_rele_wake(&p->p_refs); 1422 } 1423 1424 veb_ports_free(m); 1425 } 1426 1427 static int 1428 veb_add_port(struct veb_softc *sc, const struct ifbreq *req, unsigned int span) 1429 { 1430 struct ifnet *ifp = &sc->sc_if; 1431 struct ifnet *ifp0; 1432 struct veb_ports **ports_ptr; 1433 struct veb_ports *om, *nm; 1434 struct veb_port *p; 1435 int isvport; 1436 int error; 1437 1438 NET_ASSERT_LOCKED(); 1439 1440 ifp0 = if_unit(req->ifbr_ifsname); 1441 if (ifp0 == NULL) 1442 return (EINVAL); 1443 1444 if (ifp0->if_type != IFT_ETHER) { 1445 error = EPROTONOSUPPORT; 1446 goto put; 1447 } 1448 1449 if (ifp0 == ifp) { 1450 error = EPROTONOSUPPORT; 1451 goto put; 1452 } 1453 1454 isvport = (ifp0->if_enqueue == vport_enqueue); 1455 1456 error = ether_brport_isset(ifp0); 1457 if (error != 0) 1458 goto put; 1459 1460 /* let's try */ 1461 1462 p = malloc(sizeof(*p), M_DEVBUF, M_WAITOK|M_ZERO|M_CANFAIL); 1463 if (p == NULL) { 1464 error = ENOMEM; 1465 goto put; 1466 } 1467 1468 ifsetlro(ifp0, 0); 1469 1470 p->p_ifp0 = ifp0; 1471 p->p_veb = sc; 1472 1473 refcnt_init(&p->p_refs); 1474 TAILQ_INIT(&p->p_vrl); 1475 SMR_TAILQ_INIT(&p->p_vr_list[0]); 1476 SMR_TAILQ_INIT(&p->p_vr_list[1]); 1477 1478 p->p_enqueue = isvport ? vport_if_enqueue : if_enqueue; 1479 p->p_ioctl = ifp0->if_ioctl; 1480 p->p_output = ifp0->if_output; 1481 1482 if (span) { 1483 ports_ptr = &sc->sc_spans; 1484 1485 if (isvport) { 1486 error = EPROTONOSUPPORT; 1487 goto free; 1488 } 1489 1490 p->p_brport.eb_input = veb_span_input; 1491 p->p_bif_flags = IFBIF_SPAN; 1492 } else { 1493 ports_ptr = &sc->sc_ports; 1494 1495 error = ifpromisc(ifp0, 1); 1496 if (error != 0) 1497 goto free; 1498 1499 p->p_bif_flags = IFBIF_LEARNING | IFBIF_DISCOVER; 1500 p->p_brport.eb_input = isvport ? 1501 veb_vport_input : veb_port_input; 1502 } 1503 1504 p->p_brport.eb_port_take = veb_eb_brport_take; 1505 p->p_brport.eb_port_rele = veb_eb_brport_rele; 1506 1507 om = SMR_PTR_GET_LOCKED(ports_ptr); 1508 nm = veb_ports_insert(om, p); 1509 1510 /* this might have changed if we slept for malloc or ifpromisc */ 1511 error = ether_brport_isset(ifp0); 1512 if (error != 0) 1513 goto unpromisc; 1514 1515 task_set(&p->p_ltask, veb_p_linkch, p); 1516 if_linkstatehook_add(ifp0, &p->p_ltask); 1517 1518 task_set(&p->p_dtask, veb_p_detach, p); 1519 if_detachhook_add(ifp0, &p->p_dtask); 1520 1521 p->p_brport.eb_port = p; 1522 1523 /* commit */ 1524 SMR_PTR_SET_LOCKED(ports_ptr, nm); 1525 1526 ether_brport_set(ifp0, &p->p_brport); 1527 if (!isvport) { /* vport is special */ 1528 ifp0->if_ioctl = veb_p_ioctl; 1529 ifp0->if_output = veb_p_output; 1530 } 1531 1532 veb_p_linkch(p); 1533 1534 /* clean up the old veb_ports map */ 1535 smr_barrier(); 1536 if (om != NULL) { 1537 refcnt_finalize(&om->m_refs, "vebports"); 1538 veb_ports_destroy(om); 1539 } 1540 1541 return (0); 1542 1543 unpromisc: 1544 if (!span) 1545 ifpromisc(ifp0, 0); 1546 free: 1547 free(p, M_DEVBUF, sizeof(*p)); 1548 put: 1549 if_put(ifp0); 1550 return (error); 1551 } 1552 1553 static struct veb_port * 1554 veb_trunkport(struct veb_softc *sc, const char *name, unsigned int span) 1555 { 1556 struct veb_ports *m; 1557 struct veb_port **ps; 1558 struct veb_port *p; 1559 unsigned int i; 1560 1561 m = SMR_PTR_GET_LOCKED(span ? &sc->sc_spans : &sc->sc_ports); 1562 if (m == NULL) 1563 return (NULL); 1564 1565 ps = veb_ports_array(m); 1566 for (i = 0; i < m->m_count; i++) { 1567 p = ps[i]; 1568 1569 if (strncmp(p->p_ifp0->if_xname, name, IFNAMSIZ) == 0) 1570 return (p); 1571 } 1572 1573 return (NULL); 1574 } 1575 1576 static int 1577 veb_del_port(struct veb_softc *sc, const struct ifbreq *req, unsigned int span) 1578 { 1579 struct veb_port *p; 1580 1581 NET_ASSERT_LOCKED(); 1582 p = veb_trunkport(sc, req->ifbr_ifsname, span); 1583 if (p == NULL) 1584 return (EINVAL); 1585 1586 veb_p_dtor(sc, p); 1587 1588 return (0); 1589 } 1590 1591 static struct veb_port * 1592 veb_port_get(struct veb_softc *sc, const char *name) 1593 { 1594 struct veb_ports *m; 1595 struct veb_port **ps; 1596 struct veb_port *p; 1597 unsigned int i; 1598 1599 NET_ASSERT_LOCKED(); 1600 1601 m = SMR_PTR_GET_LOCKED(&sc->sc_ports); 1602 if (m == NULL) 1603 return (NULL); 1604 1605 ps = veb_ports_array(m); 1606 for (i = 0; i < m->m_count; i++) { 1607 p = ps[i]; 1608 1609 if (strncmp(p->p_ifp0->if_xname, name, IFNAMSIZ) == 0) { 1610 refcnt_take(&p->p_refs); 1611 return (p); 1612 } 1613 } 1614 1615 return (NULL); 1616 } 1617 1618 static void 1619 veb_port_put(struct veb_softc *sc, struct veb_port *p) 1620 { 1621 refcnt_rele_wake(&p->p_refs); 1622 } 1623 1624 static int 1625 veb_port_set_protected(struct veb_softc *sc, const struct ifbreq *ifbr) 1626 { 1627 struct veb_port *p; 1628 1629 p = veb_port_get(sc, ifbr->ifbr_ifsname); 1630 if (p == NULL) 1631 return (ESRCH); 1632 1633 p->p_protected = ifbr->ifbr_protected; 1634 veb_port_put(sc, p); 1635 1636 return (0); 1637 } 1638 1639 static int 1640 veb_rule_add(struct veb_softc *sc, const struct ifbrlreq *ifbr) 1641 { 1642 const struct ifbrarpf *brla = &ifbr->ifbr_arpf; 1643 struct veb_rule vr, *vrp; 1644 struct veb_port *p; 1645 int error; 1646 1647 memset(&vr, 0, sizeof(vr)); 1648 1649 switch (ifbr->ifbr_action) { 1650 case BRL_ACTION_BLOCK: 1651 vr.vr_action = VEB_R_BLOCK; 1652 break; 1653 case BRL_ACTION_PASS: 1654 vr.vr_action = VEB_R_PASS; 1655 break; 1656 /* XXX VEB_R_MATCH */ 1657 default: 1658 return (EINVAL); 1659 } 1660 1661 if (!ISSET(ifbr->ifbr_flags, BRL_FLAG_IN|BRL_FLAG_OUT)) 1662 return (EINVAL); 1663 if (ISSET(ifbr->ifbr_flags, BRL_FLAG_IN)) 1664 SET(vr.vr_flags, VEB_R_F_IN); 1665 if (ISSET(ifbr->ifbr_flags, BRL_FLAG_OUT)) 1666 SET(vr.vr_flags, VEB_R_F_OUT); 1667 1668 if (ISSET(ifbr->ifbr_flags, BRL_FLAG_SRCVALID)) { 1669 SET(vr.vr_flags, VEB_R_F_SRC); 1670 vr.vr_src = ether_addr_to_e64(&ifbr->ifbr_src); 1671 } 1672 if (ISSET(ifbr->ifbr_flags, BRL_FLAG_DSTVALID)) { 1673 SET(vr.vr_flags, VEB_R_F_DST); 1674 vr.vr_dst = ether_addr_to_e64(&ifbr->ifbr_dst); 1675 } 1676 1677 /* ARP rule */ 1678 if (ISSET(brla->brla_flags, BRLA_ARP|BRLA_RARP)) { 1679 if (ISSET(brla->brla_flags, BRLA_ARP)) 1680 SET(vr.vr_flags, VEB_R_F_ARP); 1681 if (ISSET(brla->brla_flags, BRLA_RARP)) 1682 SET(vr.vr_flags, VEB_R_F_RARP); 1683 1684 if (ISSET(brla->brla_flags, BRLA_SHA)) { 1685 SET(vr.vr_flags, VEB_R_F_SHA); 1686 vr.vr_arp_sha = brla->brla_sha; 1687 } 1688 if (ISSET(brla->brla_flags, BRLA_THA)) { 1689 SET(vr.vr_flags, VEB_R_F_THA); 1690 vr.vr_arp_tha = brla->brla_tha; 1691 } 1692 if (ISSET(brla->brla_flags, BRLA_SPA)) { 1693 SET(vr.vr_flags, VEB_R_F_SPA); 1694 vr.vr_arp_spa = brla->brla_spa; 1695 } 1696 if (ISSET(brla->brla_flags, BRLA_TPA)) { 1697 SET(vr.vr_flags, VEB_R_F_TPA); 1698 vr.vr_arp_tpa = brla->brla_tpa; 1699 } 1700 vr.vr_arp_op = htons(brla->brla_op); 1701 } 1702 1703 if (ifbr->ifbr_tagname[0] != '\0') { 1704 #if NPF > 0 1705 vr.vr_pftag = pf_tagname2tag((char *)ifbr->ifbr_tagname, 1); 1706 if (vr.vr_pftag == 0) 1707 return (ENOMEM); 1708 #else 1709 return (EINVAL); 1710 #endif 1711 } 1712 1713 p = veb_port_get(sc, ifbr->ifbr_ifsname); 1714 if (p == NULL) { 1715 error = ESRCH; 1716 goto error; 1717 } 1718 1719 vrp = pool_get(&veb_rule_pool, PR_WAITOK|PR_LIMITFAIL|PR_ZERO); 1720 if (vrp == NULL) { 1721 error = ENOMEM; 1722 goto port_put; 1723 } 1724 1725 *vrp = vr; 1726 1727 /* there's one big lock on a veb for all ports */ 1728 error = rw_enter(&sc->sc_rule_lock, RW_WRITE|RW_INTR); 1729 if (error != 0) 1730 goto rule_put; 1731 1732 TAILQ_INSERT_TAIL(&p->p_vrl, vrp, vr_entry); 1733 p->p_nvrl++; 1734 if (ISSET(vr.vr_flags, VEB_R_F_OUT)) { 1735 SMR_TAILQ_INSERT_TAIL_LOCKED(&p->p_vr_list[0], 1736 vrp, vr_lentry[0]); 1737 } 1738 if (ISSET(vr.vr_flags, VEB_R_F_IN)) { 1739 SMR_TAILQ_INSERT_TAIL_LOCKED(&p->p_vr_list[1], 1740 vrp, vr_lentry[1]); 1741 } 1742 1743 rw_exit(&sc->sc_rule_lock); 1744 veb_port_put(sc, p); 1745 1746 return (0); 1747 1748 rule_put: 1749 pool_put(&veb_rule_pool, vrp); 1750 port_put: 1751 veb_port_put(sc, p); 1752 error: 1753 #if NPF > 0 1754 pf_tag_unref(vr.vr_pftag); 1755 #endif 1756 return (error); 1757 } 1758 1759 static void 1760 veb_rule_list_free(struct veb_rule *nvr) 1761 { 1762 struct veb_rule *vr; 1763 1764 while ((vr = nvr) != NULL) { 1765 nvr = TAILQ_NEXT(vr, vr_entry); 1766 pool_put(&veb_rule_pool, vr); 1767 } 1768 } 1769 1770 static int 1771 veb_rule_list_flush(struct veb_softc *sc, const struct ifbrlreq *ifbr) 1772 { 1773 struct veb_port *p; 1774 struct veb_rule *vr; 1775 int error; 1776 1777 p = veb_port_get(sc, ifbr->ifbr_ifsname); 1778 if (p == NULL) 1779 return (ESRCH); 1780 1781 error = rw_enter(&sc->sc_rule_lock, RW_WRITE|RW_INTR); 1782 if (error != 0) { 1783 veb_port_put(sc, p); 1784 return (error); 1785 } 1786 1787 /* take all the rules away */ 1788 vr = TAILQ_FIRST(&p->p_vrl); 1789 1790 /* reset the lists and counts of rules */ 1791 TAILQ_INIT(&p->p_vrl); 1792 p->p_nvrl = 0; 1793 SMR_TAILQ_INIT(&p->p_vr_list[0]); 1794 SMR_TAILQ_INIT(&p->p_vr_list[1]); 1795 1796 rw_exit(&sc->sc_rule_lock); 1797 veb_port_put(sc, p); 1798 1799 smr_barrier(); 1800 veb_rule_list_free(vr); 1801 1802 return (0); 1803 } 1804 1805 static void 1806 veb_rule2ifbr(struct ifbrlreq *ifbr, const struct veb_rule *vr) 1807 { 1808 switch (vr->vr_action) { 1809 case VEB_R_PASS: 1810 ifbr->ifbr_action = BRL_ACTION_PASS; 1811 break; 1812 case VEB_R_BLOCK: 1813 ifbr->ifbr_action = BRL_ACTION_BLOCK; 1814 break; 1815 } 1816 1817 if (ISSET(vr->vr_flags, VEB_R_F_IN)) 1818 SET(ifbr->ifbr_flags, BRL_FLAG_IN); 1819 if (ISSET(vr->vr_flags, VEB_R_F_OUT)) 1820 SET(ifbr->ifbr_flags, BRL_FLAG_OUT); 1821 1822 if (ISSET(vr->vr_flags, VEB_R_F_SRC)) { 1823 SET(ifbr->ifbr_flags, BRL_FLAG_SRCVALID); 1824 ether_e64_to_addr(&ifbr->ifbr_src, vr->vr_src); 1825 } 1826 if (ISSET(vr->vr_flags, VEB_R_F_DST)) { 1827 SET(ifbr->ifbr_flags, BRL_FLAG_DSTVALID); 1828 ether_e64_to_addr(&ifbr->ifbr_dst, vr->vr_dst); 1829 } 1830 1831 /* ARP rule */ 1832 if (ISSET(vr->vr_flags, VEB_R_F_ARP|VEB_R_F_RARP)) { 1833 struct ifbrarpf *brla = &ifbr->ifbr_arpf; 1834 1835 if (ISSET(vr->vr_flags, VEB_R_F_ARP)) 1836 SET(brla->brla_flags, BRLA_ARP); 1837 if (ISSET(vr->vr_flags, VEB_R_F_RARP)) 1838 SET(brla->brla_flags, BRLA_RARP); 1839 1840 if (ISSET(vr->vr_flags, VEB_R_F_SHA)) { 1841 SET(brla->brla_flags, BRLA_SHA); 1842 brla->brla_sha = vr->vr_arp_sha; 1843 } 1844 if (ISSET(vr->vr_flags, VEB_R_F_THA)) { 1845 SET(brla->brla_flags, BRLA_THA); 1846 brla->brla_tha = vr->vr_arp_tha; 1847 } 1848 1849 if (ISSET(vr->vr_flags, VEB_R_F_SPA)) { 1850 SET(brla->brla_flags, BRLA_SPA); 1851 brla->brla_spa = vr->vr_arp_spa; 1852 } 1853 if (ISSET(vr->vr_flags, VEB_R_F_TPA)) { 1854 SET(brla->brla_flags, BRLA_TPA); 1855 brla->brla_tpa = vr->vr_arp_tpa; 1856 } 1857 1858 brla->brla_op = ntohs(vr->vr_arp_op); 1859 } 1860 1861 #if NPF > 0 1862 if (vr->vr_pftag != 0) 1863 pf_tag2tagname(vr->vr_pftag, ifbr->ifbr_tagname); 1864 #endif 1865 } 1866 1867 static int 1868 veb_rule_list_get(struct veb_softc *sc, struct ifbrlconf *ifbrl) 1869 { 1870 struct veb_port *p; 1871 struct veb_rule *vr; 1872 struct ifbrlreq *ifbr, *ifbrs; 1873 int error = 0; 1874 size_t len; 1875 1876 p = veb_port_get(sc, ifbrl->ifbrl_ifsname); 1877 if (p == NULL) 1878 return (ESRCH); 1879 1880 len = p->p_nvrl; /* estimate */ 1881 if (ifbrl->ifbrl_len == 0 || len == 0) { 1882 ifbrl->ifbrl_len = len * sizeof(*ifbrs); 1883 goto port_put; 1884 } 1885 1886 error = rw_enter(&sc->sc_rule_lock, RW_READ|RW_INTR); 1887 if (error != 0) 1888 goto port_put; 1889 1890 ifbrs = mallocarray(p->p_nvrl, sizeof(*ifbrs), M_TEMP, 1891 M_WAITOK|M_CANFAIL|M_ZERO); 1892 if (ifbrs == NULL) { 1893 rw_exit(&sc->sc_rule_lock); 1894 goto port_put; 1895 } 1896 len = p->p_nvrl * sizeof(*ifbrs); 1897 1898 ifbr = ifbrs; 1899 TAILQ_FOREACH(vr, &p->p_vrl, vr_entry) { 1900 strlcpy(ifbr->ifbr_name, sc->sc_if.if_xname, IFNAMSIZ); 1901 strlcpy(ifbr->ifbr_ifsname, p->p_ifp0->if_xname, IFNAMSIZ); 1902 veb_rule2ifbr(ifbr, vr); 1903 1904 ifbr++; 1905 } 1906 1907 rw_exit(&sc->sc_rule_lock); 1908 1909 error = copyout(ifbrs, ifbrl->ifbrl_buf, min(len, ifbrl->ifbrl_len)); 1910 if (error == 0) 1911 ifbrl->ifbrl_len = len; 1912 free(ifbrs, M_TEMP, len); 1913 1914 port_put: 1915 veb_port_put(sc, p); 1916 return (error); 1917 } 1918 1919 static int 1920 veb_port_list(struct veb_softc *sc, struct ifbifconf *bifc) 1921 { 1922 struct ifnet *ifp = &sc->sc_if; 1923 struct veb_ports *m; 1924 struct veb_port **ps; 1925 struct veb_port *p; 1926 struct ifnet *ifp0; 1927 struct ifbreq breq; 1928 int n = 0, error = 0; 1929 unsigned int i; 1930 1931 NET_ASSERT_LOCKED(); 1932 1933 if (bifc->ifbic_len == 0) { 1934 m = SMR_PTR_GET_LOCKED(&sc->sc_ports); 1935 if (m != NULL) 1936 n += m->m_count; 1937 m = SMR_PTR_GET_LOCKED(&sc->sc_spans); 1938 if (m != NULL) 1939 n += m->m_count; 1940 goto done; 1941 } 1942 1943 m = SMR_PTR_GET_LOCKED(&sc->sc_ports); 1944 if (m != NULL) { 1945 ps = veb_ports_array(m); 1946 for (i = 0; i < m->m_count; i++) { 1947 if (bifc->ifbic_len < sizeof(breq)) 1948 break; 1949 1950 p = ps[i]; 1951 1952 memset(&breq, 0, sizeof(breq)); 1953 1954 ifp0 = p->p_ifp0; 1955 1956 strlcpy(breq.ifbr_name, ifp->if_xname, IFNAMSIZ); 1957 strlcpy(breq.ifbr_ifsname, ifp0->if_xname, IFNAMSIZ); 1958 1959 breq.ifbr_ifsflags = p->p_bif_flags; 1960 breq.ifbr_portno = ifp0->if_index; 1961 breq.ifbr_protected = p->p_protected; 1962 if ((error = copyout(&breq, bifc->ifbic_req + n, 1963 sizeof(breq))) != 0) 1964 goto done; 1965 1966 bifc->ifbic_len -= sizeof(breq); 1967 n++; 1968 } 1969 } 1970 1971 m = SMR_PTR_GET_LOCKED(&sc->sc_spans); 1972 if (m != NULL) { 1973 ps = veb_ports_array(m); 1974 for (i = 0; i < m->m_count; i++) { 1975 if (bifc->ifbic_len < sizeof(breq)) 1976 break; 1977 1978 p = ps[i]; 1979 1980 memset(&breq, 0, sizeof(breq)); 1981 1982 strlcpy(breq.ifbr_name, ifp->if_xname, IFNAMSIZ); 1983 strlcpy(breq.ifbr_ifsname, p->p_ifp0->if_xname, 1984 IFNAMSIZ); 1985 1986 breq.ifbr_ifsflags = p->p_bif_flags; 1987 if ((error = copyout(&breq, bifc->ifbic_req + n, 1988 sizeof(breq))) != 0) 1989 goto done; 1990 1991 bifc->ifbic_len -= sizeof(breq); 1992 n++; 1993 } 1994 } 1995 1996 done: 1997 bifc->ifbic_len = n * sizeof(breq); 1998 return (error); 1999 } 2000 2001 static int 2002 veb_port_set_flags(struct veb_softc *sc, struct ifbreq *ifbr) 2003 { 2004 struct veb_port *p; 2005 2006 if (ISSET(ifbr->ifbr_ifsflags, ~VEB_IFBIF_FLAGS)) 2007 return (EINVAL); 2008 2009 p = veb_port_get(sc, ifbr->ifbr_ifsname); 2010 if (p == NULL) 2011 return (ESRCH); 2012 2013 p->p_bif_flags = ifbr->ifbr_ifsflags; 2014 2015 veb_port_put(sc, p); 2016 return (0); 2017 } 2018 2019 static int 2020 veb_port_get_flags(struct veb_softc *sc, struct ifbreq *ifbr) 2021 { 2022 struct veb_port *p; 2023 2024 p = veb_port_get(sc, ifbr->ifbr_ifsname); 2025 if (p == NULL) 2026 return (ESRCH); 2027 2028 ifbr->ifbr_ifsflags = p->p_bif_flags; 2029 ifbr->ifbr_portno = p->p_ifp0->if_index; 2030 ifbr->ifbr_protected = p->p_protected; 2031 2032 veb_port_put(sc, p); 2033 return (0); 2034 } 2035 2036 static int 2037 veb_add_addr(struct veb_softc *sc, const struct ifbareq *ifba) 2038 { 2039 struct veb_port *p; 2040 int error = 0; 2041 unsigned int type; 2042 2043 if (ISSET(ifba->ifba_flags, ~IFBAF_TYPEMASK)) 2044 return (EINVAL); 2045 switch (ifba->ifba_flags & IFBAF_TYPEMASK) { 2046 case IFBAF_DYNAMIC: 2047 type = EBE_DYNAMIC; 2048 break; 2049 case IFBAF_STATIC: 2050 type = EBE_STATIC; 2051 break; 2052 default: 2053 return (EINVAL); 2054 } 2055 2056 if (ifba->ifba_dstsa.ss_family != AF_UNSPEC) 2057 return (EAFNOSUPPORT); 2058 2059 p = veb_port_get(sc, ifba->ifba_ifsname); 2060 if (p == NULL) 2061 return (ESRCH); 2062 2063 error = etherbridge_add_addr(&sc->sc_eb, p, &ifba->ifba_dst, type); 2064 2065 veb_port_put(sc, p); 2066 2067 return (error); 2068 } 2069 2070 static int 2071 veb_del_addr(struct veb_softc *sc, const struct ifbareq *ifba) 2072 { 2073 return (etherbridge_del_addr(&sc->sc_eb, &ifba->ifba_dst)); 2074 } 2075 2076 static int 2077 veb_p_ioctl(struct ifnet *ifp0, u_long cmd, caddr_t data) 2078 { 2079 const struct ether_brport *eb = ether_brport_get_locked(ifp0); 2080 struct veb_port *p; 2081 int error = 0; 2082 2083 KASSERTMSG(eb != NULL, 2084 "%s: %s called without an ether_brport set", 2085 ifp0->if_xname, __func__); 2086 KASSERTMSG((eb->eb_input == veb_port_input) || 2087 (eb->eb_input == veb_span_input), 2088 "%s called %s, but eb_input (%p) seems wrong", 2089 ifp0->if_xname, __func__, eb->eb_input); 2090 2091 p = eb->eb_port; 2092 2093 switch (cmd) { 2094 case SIOCSIFADDR: 2095 error = EBUSY; 2096 break; 2097 2098 default: 2099 error = (*p->p_ioctl)(ifp0, cmd, data); 2100 break; 2101 } 2102 2103 return (error); 2104 } 2105 2106 static int 2107 veb_p_output(struct ifnet *ifp0, struct mbuf *m, struct sockaddr *dst, 2108 struct rtentry *rt) 2109 { 2110 int (*p_output)(struct ifnet *, struct mbuf *, struct sockaddr *, 2111 struct rtentry *) = NULL; 2112 const struct ether_brport *eb; 2113 2114 /* restrict transmission to bpf only */ 2115 if ((m_tag_find(m, PACKET_TAG_DLT, NULL) == NULL)) { 2116 m_freem(m); 2117 return (EBUSY); 2118 } 2119 2120 smr_read_enter(); 2121 eb = ether_brport_get(ifp0); 2122 if (eb != NULL && eb->eb_input == veb_port_input) { 2123 struct veb_port *p = eb->eb_port; 2124 p_output = p->p_output; /* code doesn't go away */ 2125 } 2126 smr_read_leave(); 2127 2128 if (p_output == NULL) { 2129 m_freem(m); 2130 return (ENXIO); 2131 } 2132 2133 return ((*p_output)(ifp0, m, dst, rt)); 2134 } 2135 2136 /* 2137 * there must be an smr_barrier after ether_brport_clr() and before 2138 * veb_port is freed in veb_p_fini() 2139 */ 2140 2141 static void 2142 veb_p_unlink(struct veb_softc *sc, struct veb_port *p) 2143 { 2144 struct ifnet *ifp = &sc->sc_if; 2145 struct ifnet *ifp0 = p->p_ifp0; 2146 2147 ifp0->if_ioctl = p->p_ioctl; 2148 ifp0->if_output = p->p_output; 2149 2150 ether_brport_clr(ifp0); /* needs an smr_barrier */ 2151 2152 if_detachhook_del(ifp0, &p->p_dtask); 2153 if_linkstatehook_del(ifp0, &p->p_ltask); 2154 2155 if (!ISSET(p->p_bif_flags, IFBIF_SPAN)) { 2156 if (ifpromisc(ifp0, 0) != 0) { 2157 log(LOG_WARNING, "%s %s: unable to disable promisc\n", 2158 ifp->if_xname, ifp0->if_xname); 2159 } 2160 2161 etherbridge_detach_port(&sc->sc_eb, p); 2162 } 2163 } 2164 2165 static void 2166 veb_p_fini(struct veb_port *p) 2167 { 2168 struct ifnet *ifp0 = p->p_ifp0; 2169 2170 refcnt_finalize(&p->p_refs, "vebpdtor"); 2171 veb_rule_list_free(TAILQ_FIRST(&p->p_vrl)); 2172 2173 if_put(ifp0); 2174 free(p, M_DEVBUF, sizeof(*p)); /* hope you didn't forget smr_barrier */ 2175 } 2176 2177 static void 2178 veb_p_dtor(struct veb_softc *sc, struct veb_port *p) 2179 { 2180 struct veb_ports **ports_ptr; 2181 struct veb_ports *om, *nm; 2182 2183 ports_ptr = ISSET(p->p_bif_flags, IFBIF_SPAN) ? 2184 &sc->sc_spans : &sc->sc_ports; 2185 2186 om = SMR_PTR_GET_LOCKED(ports_ptr); 2187 nm = veb_ports_remove(om, p); 2188 SMR_PTR_SET_LOCKED(ports_ptr, nm); 2189 2190 veb_p_unlink(sc, p); 2191 2192 smr_barrier(); 2193 refcnt_finalize(&om->m_refs, "vebports"); 2194 veb_ports_destroy(om); 2195 2196 veb_p_fini(p); 2197 } 2198 2199 static void 2200 veb_p_detach(void *arg) 2201 { 2202 struct veb_port *p = arg; 2203 struct veb_softc *sc = p->p_veb; 2204 2205 NET_ASSERT_LOCKED(); 2206 2207 veb_p_dtor(sc, p); 2208 } 2209 2210 static int 2211 veb_p_active(struct veb_port *p) 2212 { 2213 struct ifnet *ifp0 = p->p_ifp0; 2214 2215 return (ISSET(ifp0->if_flags, IFF_RUNNING) && 2216 LINK_STATE_IS_UP(ifp0->if_link_state)); 2217 } 2218 2219 static void 2220 veb_p_linkch(void *arg) 2221 { 2222 struct veb_port *p = arg; 2223 u_char link_state = LINK_STATE_FULL_DUPLEX; 2224 2225 NET_ASSERT_LOCKED(); 2226 2227 if (!veb_p_active(p)) 2228 link_state = LINK_STATE_DOWN; 2229 2230 p->p_link_state = link_state; 2231 } 2232 2233 static int 2234 veb_up(struct veb_softc *sc) 2235 { 2236 struct ifnet *ifp = &sc->sc_if; 2237 int error; 2238 2239 error = etherbridge_up(&sc->sc_eb); 2240 if (error != 0) 2241 return (error); 2242 2243 NET_ASSERT_LOCKED(); 2244 SET(ifp->if_flags, IFF_RUNNING); 2245 2246 return (0); 2247 } 2248 2249 static int 2250 veb_iff(struct veb_softc *sc) 2251 { 2252 return (0); 2253 } 2254 2255 static int 2256 veb_down(struct veb_softc *sc) 2257 { 2258 struct ifnet *ifp = &sc->sc_if; 2259 int error; 2260 2261 error = etherbridge_down(&sc->sc_eb); 2262 if (error != 0) 2263 return (0); 2264 2265 NET_ASSERT_LOCKED(); 2266 CLR(ifp->if_flags, IFF_RUNNING); 2267 2268 return (0); 2269 } 2270 2271 static int 2272 veb_eb_port_cmp(void *arg, void *a, void *b) 2273 { 2274 struct veb_port *pa = a, *pb = b; 2275 return (pa == pb); 2276 } 2277 2278 static void * 2279 veb_eb_port_take(void *arg, void *port) 2280 { 2281 struct veb_port *p = port; 2282 2283 refcnt_take(&p->p_refs); 2284 2285 return (p); 2286 } 2287 2288 static void 2289 veb_eb_port_rele(void *arg, void *port) 2290 { 2291 struct veb_port *p = port; 2292 2293 refcnt_rele_wake(&p->p_refs); 2294 } 2295 2296 static void 2297 veb_eb_brport_take(void *port) 2298 { 2299 veb_eb_port_take(NULL, port); 2300 } 2301 2302 static void 2303 veb_eb_brport_rele(void *port) 2304 { 2305 veb_eb_port_rele(NULL, port); 2306 } 2307 2308 static size_t 2309 veb_eb_port_ifname(void *arg, char *dst, size_t len, void *port) 2310 { 2311 struct veb_port *p = port; 2312 2313 return (strlcpy(dst, p->p_ifp0->if_xname, len)); 2314 } 2315 2316 static void 2317 veb_eb_port_sa(void *arg, struct sockaddr_storage *ss, void *port) 2318 { 2319 ss->ss_family = AF_UNSPEC; 2320 } 2321 2322 /* 2323 * virtual ethernet bridge port 2324 */ 2325 2326 static int 2327 vport_clone_create(struct if_clone *ifc, int unit) 2328 { 2329 struct vport_softc *sc; 2330 struct ifnet *ifp; 2331 2332 sc = malloc(sizeof(*sc), M_DEVBUF, M_WAITOK|M_ZERO|M_CANFAIL); 2333 if (sc == NULL) 2334 return (ENOMEM); 2335 2336 ifp = &sc->sc_ac.ac_if; 2337 2338 snprintf(ifp->if_xname, IFNAMSIZ, "%s%d", ifc->ifc_name, unit); 2339 2340 ifp->if_softc = sc; 2341 ifp->if_type = IFT_ETHER; 2342 ifp->if_hardmtu = ETHER_MAX_HARDMTU_LEN; 2343 ifp->if_ioctl = vport_ioctl; 2344 ifp->if_enqueue = vport_enqueue; 2345 ifp->if_qstart = vport_start; 2346 ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST; 2347 ifp->if_xflags = IFXF_CLONED | IFXF_MPSAFE; 2348 ether_fakeaddr(ifp); 2349 2350 if_counters_alloc(ifp); 2351 if_attach(ifp); 2352 ether_ifattach(ifp); 2353 2354 return (0); 2355 } 2356 2357 static int 2358 vport_clone_destroy(struct ifnet *ifp) 2359 { 2360 struct vport_softc *sc = ifp->if_softc; 2361 2362 NET_LOCK(); 2363 sc->sc_dead = 1; 2364 2365 if (ISSET(ifp->if_flags, IFF_RUNNING)) 2366 vport_down(sc); 2367 NET_UNLOCK(); 2368 2369 ether_ifdetach(ifp); 2370 if_detach(ifp); 2371 2372 free(sc, M_DEVBUF, sizeof(*sc)); 2373 2374 return (0); 2375 } 2376 2377 static int 2378 vport_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data) 2379 { 2380 struct vport_softc *sc = ifp->if_softc; 2381 int error = 0; 2382 2383 if (sc->sc_dead) 2384 return (ENXIO); 2385 2386 switch (cmd) { 2387 case SIOCSIFFLAGS: 2388 if (ISSET(ifp->if_flags, IFF_UP)) { 2389 if (!ISSET(ifp->if_flags, IFF_RUNNING)) 2390 error = vport_up(sc); 2391 } else { 2392 if (ISSET(ifp->if_flags, IFF_RUNNING)) 2393 error = vport_down(sc); 2394 } 2395 break; 2396 2397 case SIOCADDMULTI: 2398 case SIOCDELMULTI: 2399 break; 2400 2401 default: 2402 error = ether_ioctl(ifp, &sc->sc_ac, cmd, data); 2403 break; 2404 } 2405 2406 if (error == ENETRESET) 2407 error = vport_iff(sc); 2408 2409 return (error); 2410 } 2411 2412 static int 2413 vport_up(struct vport_softc *sc) 2414 { 2415 struct ifnet *ifp = &sc->sc_ac.ac_if; 2416 2417 NET_ASSERT_LOCKED(); 2418 SET(ifp->if_flags, IFF_RUNNING); 2419 2420 return (0); 2421 } 2422 2423 static int 2424 vport_iff(struct vport_softc *sc) 2425 { 2426 return (0); 2427 } 2428 2429 static int 2430 vport_down(struct vport_softc *sc) 2431 { 2432 struct ifnet *ifp = &sc->sc_ac.ac_if; 2433 2434 NET_ASSERT_LOCKED(); 2435 CLR(ifp->if_flags, IFF_RUNNING); 2436 2437 return (0); 2438 } 2439 2440 static int 2441 vport_if_enqueue(struct ifnet *ifp, struct mbuf *m) 2442 { 2443 /* 2444 * switching an l2 packet toward a vport means pushing it 2445 * into the network stack. this function exists to make 2446 * if_vinput compat with veb calling if_enqueue. 2447 */ 2448 2449 if_vinput(ifp, m); 2450 2451 return (0); 2452 } 2453 2454 static int 2455 vport_enqueue(struct ifnet *ifp, struct mbuf *m) 2456 { 2457 struct arpcom *ac; 2458 const struct ether_brport *eb; 2459 int error = ENETDOWN; 2460 #if NBPFILTER > 0 2461 caddr_t if_bpf; 2462 #endif 2463 2464 /* 2465 * a packet sent from the l3 stack out a vport goes into 2466 * veb for switching out another port. 2467 */ 2468 2469 #if NPF > 0 2470 /* 2471 * there's no relationship between pf states in the l3 stack 2472 * and the l2 bridge. 2473 */ 2474 pf_pkt_addr_changed(m); 2475 #endif 2476 2477 ac = (struct arpcom *)ifp; 2478 2479 smr_read_enter(); 2480 eb = SMR_PTR_GET(&ac->ac_brport); 2481 if (eb != NULL) 2482 eb->eb_port_take(eb->eb_port); 2483 smr_read_leave(); 2484 if (eb != NULL) { 2485 struct mbuf *(*input)(struct ifnet *, struct mbuf *, 2486 uint64_t, void *) = eb->eb_input; 2487 struct ether_header *eh; 2488 uint64_t dst; 2489 2490 counters_pkt(ifp->if_counters, ifc_opackets, ifc_obytes, 2491 m->m_pkthdr.len); 2492 2493 #if NBPFILTER > 0 2494 if_bpf = READ_ONCE(ifp->if_bpf); 2495 if (if_bpf != NULL) 2496 bpf_mtap_ether(if_bpf, m, BPF_DIRECTION_OUT); 2497 #endif 2498 2499 eh = mtod(m, struct ether_header *); 2500 dst = ether_addr_to_e64((struct ether_addr *)eh->ether_dhost); 2501 2502 if (input == veb_vport_input) 2503 input = veb_port_input; 2504 m = (*input)(ifp, m, dst, eb->eb_port); 2505 2506 error = 0; 2507 2508 eb->eb_port_rele(eb->eb_port); 2509 } 2510 2511 m_freem(m); 2512 2513 return (error); 2514 } 2515 2516 static void 2517 vport_start(struct ifqueue *ifq) 2518 { 2519 ifq_purge(ifq); 2520 } 2521