* Recive data from a hook. Pass the packet to the correct input routine. */
| 681 | * Recive data from a hook. Pass the packet to the correct input routine. |
| 682 | */ |
| 683 | static int |
| 684 | ng_iface_rcvdata(hook_p hook, item_p item) |
| 685 | { |
| 686 | const priv_p priv = NG_NODE_PRIVATE(NG_HOOK_NODE(hook)); |
| 687 | const iffam_p iffam = get_iffam_from_hook(priv, hook); |
| 688 | struct ifnet *const ifp = priv->ifp; |
| 689 | struct epoch_tracker et; |
| 690 | struct mbuf *m; |
| 691 | int isr; |
| 692 | |
| 693 | NGI_GET_M(item, m); |
| 694 | NG_FREE_ITEM(item); |
| 695 | /* Sanity checks */ |
| 696 | KASSERT(iffam != NULL, ("%s: iffam", __func__)); |
| 697 | M_ASSERTPKTHDR(m); |
| 698 | if ((ifp->if_flags & IFF_UP) == 0) { |
| 699 | NG_FREE_M(m); |
| 700 | return (ENETDOWN); |
| 701 | } |
| 702 | |
| 703 | /* Update interface stats */ |
| 704 | if_inc_counter(ifp, IFCOUNTER_IPACKETS, 1); |
| 705 | if_inc_counter(ifp, IFCOUNTER_IBYTES, m->m_pkthdr.len); |
| 706 | |
| 707 | /* Note receiving interface */ |
| 708 | m->m_pkthdr.rcvif = ifp; |
| 709 | |
| 710 | /* Berkeley packet filter */ |
| 711 | ng_iface_bpftap(ifp, m, iffam->family); |
| 712 | |
| 713 | /* Send packet */ |
| 714 | switch (iffam->family) { |
| 715 | #ifdef INET |
| 716 | case AF_INET: |
| 717 | isr = NETISR_IP; |
| 718 | break; |
| 719 | #endif |
| 720 | #ifdef INET6 |
| 721 | case AF_INET6: |
| 722 | isr = NETISR_IPV6; |
| 723 | break; |
| 724 | #endif |
| 725 | default: |
| 726 | m_freem(m); |
| 727 | return (EAFNOSUPPORT); |
| 728 | } |
| 729 | random_harvest_queue(m, sizeof(*m), RANDOM_NET_NG); |
| 730 | M_SETFIB(m, ifp->if_fib); |
| 731 | CURVNET_SET(ifp->if_vnet); |
| 732 | NET_EPOCH_ENTER(et); |
| 733 | netisr_dispatch(isr, m); |
| 734 | NET_EPOCH_EXIT(et); |
| 735 | CURVNET_RESTORE(); |
| 736 | return (0); |
| 737 | } |
| 738 | |
| 739 | /* |
| 740 | * Shutdown and remove the node and its associated interface. |
nothing calls this directly
no test coverage detected