Lines Matching +full:dp +full:- +full:bridge

1 /*-
2 * SPDX-License-Identifier: BSD-2-Clause
5 * Copyright (c) 2009-2021 Bjoern A. Zeeb <bz@FreeBSD.org>
33 * A pair of virtual back-to-back connected ethernet like interfaces
34 * (``two interfaces with a virtual cross-over cable'').
86 #define RXRSIZE 4096 /* Probably overkill by 4-8x. */
89 "Pair of virtual cross-over connected Ethernet-like interfaces");
103 "Pair of virtual cross-over connected Ethernet-like interfaces");
147 if (m->m_pkthdr.csum_flags & CSUM_SND_TAG) { in epair_clear_mbuf()
148 m_snd_tag_rele(m->m_pkthdr.snd_tag); in epair_clear_mbuf()
149 m->m_pkthdr.snd_tag = NULL; in epair_clear_mbuf()
150 m->m_pkthdr.csum_flags &= ~CSUM_SND_TAG; in epair_clear_mbuf()
154 m->m_flags &= ~M_VLANTAG; in epair_clear_mbuf()
155 m->m_pkthdr.ether_vtag = 0; in epair_clear_mbuf()
168 ifp = q->sc->ifp; in epair_tx_start_deferred()
171 CURVNET_SET(ifp->if_vnet); in epair_tx_start_deferred()
173 mtx_lock(&q->mtx); in epair_tx_start_deferred()
174 m = mbufq_flush(&q->q); in epair_tx_start_deferred()
175 q->state = EPAIR_QUEUE_RUNNING; in epair_tx_start_deferred()
176 mtx_unlock(&q->mtx); in epair_tx_start_deferred()
180 m->m_nextpkt = NULL; in epair_tx_start_deferred()
187 * end up starving ourselves in a multi-epair routing configuration. in epair_tx_start_deferred()
189 mtx_lock(&q->mtx); in epair_tx_start_deferred()
190 if (!mbufq_empty(&q->q)) { in epair_tx_start_deferred()
192 q->state = EPAIR_QUEUE_WAKING; in epair_tx_start_deferred()
195 q->state = EPAIR_QUEUE_IDLE; in epair_tx_start_deferred()
197 mtx_unlock(&q->mtx); in epair_tx_start_deferred()
200 taskqueue_enqueue(epair_tasks.tq[q->id], &q->tx_task); in epair_tx_start_deferred()
219 switch (ntohs(eh->ether_type)) { in epair_select_queue()
235 bucket %= sc->num_queues; in epair_select_queue()
239 return (&sc->queues[bucket]); in epair_select_queue()
248 M_SETFIB(m, src_ifp->if_fib); in epair_prepare_mbuf()
250 MPASS(m->m_nextpkt == NULL); in epair_prepare_mbuf()
251 MPASS((m->m_pkthdr.csum_flags & CSUM_SND_TAG) == 0); in epair_prepare_mbuf()
266 oifp = osc->ifp; in epair_menq()
267 ifp = osc->oifp; in epair_menq()
272 len = m->m_pkthdr.len; in epair_menq()
273 mcast = (m->m_flags & (M_BCAST | M_MCAST)) != 0; in epair_menq()
277 mtx_lock(&q->mtx); in epair_menq()
278 if (q->state == EPAIR_QUEUE_IDLE) { in epair_menq()
279 q->state = EPAIR_QUEUE_WAKING; in epair_menq()
280 taskqueue_enqueue(epair_tasks.tq[q->id], &q->tx_task); in epair_menq()
282 error = mbufq_enqueue(&q->q, m); in epair_menq()
283 mtx_unlock(&q->mtx); in epair_menq()
307 * and will put the packet into the receive-queue (rxq) of the in epair_start()
310 sc = ifp->if_softc; in epair_start()
311 oifp = sc->oifp; in epair_start()
312 sc = oifp->if_softc; in epair_start()
314 IFQ_DEQUEUE(&ifp->if_snd, m); in epair_start()
321 if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0 || in epair_start()
322 (ifp->if_flags & IFF_UP) == 0 || in epair_start()
323 (oifp->if_drv_flags & IFF_DRV_RUNNING) == 0 || in epair_start()
324 (oifp->if_flags & IFF_UP) == 0) { in epair_start()
352 if (m->m_pkthdr.len > (ifp->if_mtu + sizeof(struct ether_vlan_header))) { in epair_transmit()
361 * and will put the packet into the receive-queue (rxq) of the in epair_transmit()
364 if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0) { in epair_transmit()
369 if ((ifp->if_flags & IFF_UP) == 0) { in epair_transmit()
381 sc = ifp->if_softc; in epair_transmit()
382 oifp = sc->oifp; in epair_transmit()
383 if ((oifp->if_drv_flags & IFF_DRV_RUNNING) == 0 || in epair_transmit()
384 (oifp->if_flags & IFF_UP) == 0) { in epair_transmit()
391 len = m->m_pkthdr.len; in epair_transmit()
392 mcast = (m->m_flags & (M_BCAST | M_MCAST)) != 0; in epair_transmit()
396 IF_LOCK(&ifp->if_snd); in epair_transmit()
397 if (ALTQ_IS_ENABLED(&ifp->if_snd)) { in epair_transmit()
398 ALTQ_ENQUEUE(&ifp->if_snd, m, NULL, error); in epair_transmit()
401 IF_UNLOCK(&ifp->if_snd); in epair_transmit()
410 IF_UNLOCK(&ifp->if_snd); in epair_transmit()
413 epair_menq(m, oifp->if_softc); in epair_transmit()
434 imr->ifm_status = IFM_AVALID | IFM_ACTIVE; in epair_media_status()
435 imr->ifm_active = IFM_ETHER | IFM_10G_T | IFM_FDX; in epair_media_status()
439 * Update ifp->if_hwassist according to the current value of ifp->if_capenable.
446 if (ifp->if_capenable & IFCAP_TXCSUM) in epair_caps_changed()
448 if (ifp->if_capenable & IFCAP_TXCSUM_IPV6) in epair_caps_changed()
450 ifp->if_hwassist = hwassist; in epair_caps_changed()
470 sc = ifp->if_softc; in epair_ioctl()
471 error = ifmedia_ioctl(ifp, ifr, &sc->media, cmd); in epair_ioctl()
476 ifp->if_mtu = ifr->ifr_mtu; in epair_ioctl()
481 ifr->ifr_reqcap = ifp->if_capabilities; in epair_ioctl()
482 ifr->ifr_curcap = ifp->if_capenable; in epair_ioctl()
493 ifp->if_capenable = ifr->ifr_reqcap | IFCAP_RXCSUM | in epair_ioctl()
499 * A bridge disables IFCAP_TXCSUM(_IPV6) when adding one epair in epair_ioctl()
500 * interface if another interface in the bridge has it disabled. in epair_ioctl()
502 * other epair interface to avoid sending packets in the bridge in epair_ioctl()
505 sc = ifp->if_softc; in epair_ioctl()
506 if ((ifp->if_capenable ^ sc->oifp->if_capenable) & in epair_ioctl()
508 sc->oifp->if_capenable &= in epair_ioctl()
510 sc->oifp->if_capenable |= ifp->if_capenable & in epair_ioctl()
512 epair_caps_changed(sc->oifp); in epair_ioctl()
546 * - epair in epair_clone_match()
547 * - epair<n> in epair_clone_match()
550 if (strncmp(epairname, name, sizeof(epairname)-1) != 0) in epair_clone_match()
553 for (cp = name + sizeof(epairname) - 1; *cp != '\0'; cp++) { in epair_clone_match()
567 ether_gen_addr_byname(if_name(sc->ifp), &gen_eaddr); in epair_generate_mac_byname()
578 ifp = scb->ifp; in epair_clone_add()
581 memcpy(eaddr, scb->oifp->if_hw_addr, ETHER_ADDR_LEN); in epair_clone_add()
597 sc->ifp = ifp; in epair_alloc_sc()
598 sc->num_queues = epair_tasks.tasks; in epair_alloc_sc()
599 sc->queues = mallocarray(sc->num_queues, sizeof(struct epair_queue), in epair_alloc_sc()
601 for (int i = 0; i < sc->num_queues; i++) { in epair_alloc_sc()
602 struct epair_queue *q = &sc->queues[i]; in epair_alloc_sc()
603 q->id = i; in epair_alloc_sc()
604 q->state = EPAIR_QUEUE_IDLE; in epair_alloc_sc()
605 mtx_init(&q->mtx, "epairq", NULL, MTX_DEF | MTX_NEW); in epair_alloc_sc()
606 mbufq_init(&q->q, RXRSIZE); in epair_alloc_sc()
607 q->sc = sc; in epair_alloc_sc()
608 NET_TASK_INIT(&q->tx_task, 0, epair_tx_start_deferred, q); in epair_alloc_sc()
612 ifmedia_init(&sc->media, 0, epair_media_change, epair_media_status); in epair_alloc_sc()
613 ifmedia_add(&sc->media, IFM_ETHER | IFM_10G_T, 0, NULL); in epair_alloc_sc()
614 ifmedia_set(&sc->media, IFM_ETHER | IFM_10G_T); in epair_alloc_sc()
622 struct ifnet *ifp = sc->ifp; in epair_setup_ifp()
624 ifp->if_softc = sc; in epair_setup_ifp()
625 strlcpy(ifp->if_xname, name, IFNAMSIZ); in epair_setup_ifp()
626 ifp->if_dname = epairname; in epair_setup_ifp()
627 ifp->if_dunit = unit; in epair_setup_ifp()
628 ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST; in epair_setup_ifp()
629 ifp->if_capabilities = IFCAP_VLAN_MTU | IFCAP_TXCSUM | in epair_setup_ifp()
631 ifp->if_capenable = IFCAP_VLAN_MTU | IFCAP_TXCSUM | in epair_setup_ifp()
634 ifp->if_transmit = epair_transmit; in epair_setup_ifp()
635 ifp->if_qflush = epair_qflush; in epair_setup_ifp()
636 ifp->if_start = epair_start; in epair_setup_ifp()
637 ifp->if_ioctl = epair_ioctl; in epair_setup_ifp()
638 ifp->if_init = epair_init; in epair_setup_ifp()
642 ifp->if_baudrate = IF_Gbps(10); /* arbitrary maximum */ in epair_setup_ifp()
669 getcredhostid(curthread->td_ucred, (unsigned long *)&hostid); in epair_generate_mac()
673 struct ifnet *ifp = sc->ifp; in epair_generate_mac()
675 if (ifp->if_index > next_index) in epair_generate_mac()
676 next_index = ifp->if_index; in epair_generate_mac()
695 if_free(sc->ifp); in epair_free_sc()
696 ifmedia_removeall(&sc->media); in epair_free_sc()
697 for (int i = 0; i < sc->num_queues; i++) { in epair_free_sc()
698 struct epair_queue *q = &sc->queues[i]; in epair_free_sc()
699 mtx_destroy(&q->mtx); in epair_free_sc()
701 free(sc->queues, M_EPAIR); in epair_free_sc()
709 ifp->if_drv_flags |= IFF_DRV_RUNNING; in epair_set_state()
713 ifp->if_drv_flags &= ~IFF_DRV_RUNNING; in epair_set_state()
721 char *dp; in epair_handle_unit() local
737 for (dp = name; *dp != '\0'; dp++); in epair_handle_unit()
739 int slen = snprintf(dp, len - (dp - name), "%d", unit); in epair_handle_unit()
740 if (slen > len - (dp - name) - 1) { in epair_handle_unit()
745 dp += slen; in epair_handle_unit()
747 if (len - (dp - name) - 1 < 1) { in epair_handle_unit()
752 *dp = 'b'; in epair_handle_unit()
753 /* Must not change dp so we can replace 'a' by 'b' later. */ in epair_handle_unit()
754 *(dp+1) = '\0'; in epair_handle_unit()
762 *dp = 'a'; in epair_handle_unit()
781 char *dp; in epair_clone_create() local
794 * Cross-reference the interfaces so we will be able to free both. in epair_clone_create()
796 sca->oifp = scb->ifp; in epair_clone_create()
797 scb->oifp = sca->ifp; in epair_clone_create()
800 ifp = sca->ifp; in epair_clone_create()
810 dp = name + strlen(name) - 1; in epair_clone_create()
811 *dp = 'b'; in epair_clone_create()
815 ifp = scb->ifp; in epair_clone_create()
819 strlcpy(name, scb->ifp->if_xname, len); in epair_clone_create()
827 strlcpy(name, sca->ifp->if_xname, len); in epair_clone_create()
830 epair_set_state(sca->ifp, true); in epair_clone_create()
831 epair_set_state(scb->ifp, true); in epair_clone_create()
833 *ifpp = sca->ifp; in epair_clone_create()
841 for (int i = 0; i < sc->num_queues; i++) { in epair_drain_rings()
845 q = &sc->queues[i]; in epair_drain_rings()
846 mtx_lock(&q->mtx); in epair_drain_rings()
847 m = mbufq_flush(&q->q); in epair_drain_rings()
848 mtx_unlock(&q->mtx); in epair_drain_rings()
851 n = m->m_nextpkt; in epair_drain_rings()
869 if (ifp->if_softc == NULL) in epair_clone_destroy()
872 unit = ifp->if_dunit; in epair_clone_destroy()
873 sca = ifp->if_softc; in epair_clone_destroy()
874 oifp = sca->oifp; in epair_clone_destroy()
875 scb = oifp->if_softc; in epair_clone_destroy()
885 CURVNET_SET_QUIET(oifp->if_vnet); in epair_clone_destroy()
887 oifp->if_softc = NULL; in epair_clone_destroy()