| 2703 | } |
| 2704 | |
| 2705 | static struct mbuf * |
| 2706 | assemble_segments(iflib_rxq_t rxq, if_rxd_info_t ri, if_rxsd_t sd, int *pf_rv) |
| 2707 | { |
| 2708 | struct mbuf *m, *mh, *mt; |
| 2709 | caddr_t cl; |
| 2710 | int *pf_rv_ptr, flags, i, padlen; |
| 2711 | bool consumed; |
| 2712 | |
| 2713 | i = 0; |
| 2714 | mh = NULL; |
| 2715 | consumed = false; |
| 2716 | *pf_rv = PFIL_PASS; |
| 2717 | pf_rv_ptr = pf_rv; |
| 2718 | do { |
| 2719 | m = rxd_frag_to_sd(rxq, &ri->iri_frags[i], !consumed, sd, |
| 2720 | pf_rv_ptr, ri); |
| 2721 | |
| 2722 | MPASS(*sd->ifsd_cl != NULL); |
| 2723 | |
| 2724 | /* |
| 2725 | * Exclude zero-length frags & frags from |
| 2726 | * packets the filter has consumed or dropped |
| 2727 | */ |
| 2728 | if (ri->iri_frags[i].irf_len == 0 || consumed || |
| 2729 | *pf_rv == PFIL_CONSUMED || *pf_rv == PFIL_DROPPED) { |
| 2730 | if (mh == NULL) { |
| 2731 | /* everything saved here */ |
| 2732 | consumed = true; |
| 2733 | pf_rv_ptr = NULL; |
| 2734 | continue; |
| 2735 | } |
| 2736 | /* XXX we can save the cluster here, but not the mbuf */ |
| 2737 | m_init(m, M_NOWAIT, MT_DATA, 0); |
| 2738 | m_free(m); |
| 2739 | continue; |
| 2740 | } |
| 2741 | if (mh == NULL) { |
| 2742 | flags = M_PKTHDR|M_EXT; |
| 2743 | mh = mt = m; |
| 2744 | padlen = ri->iri_pad; |
| 2745 | } else { |
| 2746 | flags = M_EXT; |
| 2747 | mt->m_next = m; |
| 2748 | mt = m; |
| 2749 | /* assuming padding is only on the first fragment */ |
| 2750 | padlen = 0; |
| 2751 | } |
| 2752 | cl = *sd->ifsd_cl; |
| 2753 | *sd->ifsd_cl = NULL; |
| 2754 | |
| 2755 | /* Can these two be made one ? */ |
| 2756 | m_init(m, M_NOWAIT, MT_DATA, flags); |
| 2757 | m_cljset(m, cl, sd->ifsd_fl->ifl_cltype); |
| 2758 | /* |
| 2759 | * These must follow m_init and m_cljset |
| 2760 | */ |
| 2761 | m->m_data += padlen; |
| 2762 | ri->iri_len -= padlen; |
no test coverage detected