| 1784 | } |
| 1785 | |
| 1786 | static int |
| 1787 | tunwrite_l3(struct tuntap_softc *tp, struct mbuf *m) |
| 1788 | { |
| 1789 | struct epoch_tracker et; |
| 1790 | struct ifnet *ifp; |
| 1791 | int family, isr; |
| 1792 | |
| 1793 | ifp = TUN2IFP(tp); |
| 1794 | /* Could be unlocked read? */ |
| 1795 | TUN_LOCK(tp); |
| 1796 | if (tp->tun_flags & TUN_IFHEAD) { |
| 1797 | TUN_UNLOCK(tp); |
| 1798 | if (m->m_len < sizeof(family) && |
| 1799 | (m = m_pullup(m, sizeof(family))) == NULL) |
| 1800 | return (ENOBUFS); |
| 1801 | family = ntohl(*mtod(m, u_int32_t *)); |
| 1802 | m_adj(m, sizeof(family)); |
| 1803 | } else { |
| 1804 | TUN_UNLOCK(tp); |
| 1805 | family = AF_INET; |
| 1806 | } |
| 1807 | |
| 1808 | BPF_MTAP2(ifp, &family, sizeof(family), m); |
| 1809 | |
| 1810 | switch (family) { |
| 1811 | #ifdef INET |
| 1812 | case AF_INET: |
| 1813 | isr = NETISR_IP; |
| 1814 | break; |
| 1815 | #endif |
| 1816 | #ifdef INET6 |
| 1817 | case AF_INET6: |
| 1818 | isr = NETISR_IPV6; |
| 1819 | break; |
| 1820 | #endif |
| 1821 | default: |
| 1822 | m_freem(m); |
| 1823 | return (EAFNOSUPPORT); |
| 1824 | } |
| 1825 | random_harvest_queue(m, sizeof(*m), RANDOM_NET_TUN); |
| 1826 | if_inc_counter(ifp, IFCOUNTER_IBYTES, m->m_pkthdr.len); |
| 1827 | if_inc_counter(ifp, IFCOUNTER_IPACKETS, 1); |
| 1828 | CURVNET_SET(ifp->if_vnet); |
| 1829 | M_SETFIB(m, ifp->if_fib); |
| 1830 | NET_EPOCH_ENTER(et); |
| 1831 | netisr_dispatch(isr, m); |
| 1832 | NET_EPOCH_EXIT(et); |
| 1833 | CURVNET_RESTORE(); |
| 1834 | return (0); |
| 1835 | } |
| 1836 | |
| 1837 | /* |
| 1838 | * the cdevsw write interface - an atomic write is a packet - or else! |
no test coverage detected