static bool net_tx_pkt_do_sw_fragmentation(struct NetTxPkt *pkt,

    NetClientState *nc)

{

    struct iovec fragment[NET_MAX_FRAG_SG_LIST];

    size_t fragment_len = 0;

    bool more_frags = false;



    /* some pointers for shorter code */

    void *l2_iov_base, *l3_iov_base;

    size_t l2_iov_len, l3_iov_len;

    int src_idx =  NET_TX_PKT_PL_START_FRAG, dst_idx;

    size_t src_offset = 0;

    size_t fragment_offset = 0;



    l2_iov_base = pkt->vec[NET_TX_PKT_L2HDR_FRAG].iov_base;

    l2_iov_len = pkt->vec[NET_TX_PKT_L2HDR_FRAG].iov_len;

    l3_iov_base = pkt->vec[NET_TX_PKT_L3HDR_FRAG].iov_base;

    l3_iov_len = pkt->vec[NET_TX_PKT_L3HDR_FRAG].iov_len;



    /* Copy headers */

    fragment[NET_TX_PKT_FRAGMENT_L2_HDR_POS].iov_base = l2_iov_base;

    fragment[NET_TX_PKT_FRAGMENT_L2_HDR_POS].iov_len = l2_iov_len;

    fragment[NET_TX_PKT_FRAGMENT_L3_HDR_POS].iov_base = l3_iov_base;

    fragment[NET_TX_PKT_FRAGMENT_L3_HDR_POS].iov_len = l3_iov_len;





    /* Put as much data as possible and send */

    do {

        fragment_len = net_tx_pkt_fetch_fragment(pkt, &src_idx, &src_offset,

            fragment, &dst_idx);



        more_frags = (fragment_offset + fragment_len < pkt->payload_len);



        eth_setup_ip4_fragmentation(l2_iov_base, l2_iov_len, l3_iov_base,

            l3_iov_len, fragment_len, fragment_offset, more_frags);



        eth_fix_ip4_checksum(l3_iov_base, l3_iov_len);



        net_tx_pkt_sendv(pkt, nc, fragment, dst_idx);



        fragment_offset += fragment_len;



    } while (more_frags);



    return true;

}
