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