/* This function is expected to be called in a loop until the entire mbuf chain has been consumed. For example:  */
struct os_mbuf* mem_split_frag(struct os_mbuf **om, uint16_t max_frag_sz, mem_frag_alloc_fn *alloc_cb, void *cb_arg)
/* This function is expected to be called in a loop until the entire mbuf chain has been consumed. For example:  */
struct os_mbuf* mem_split_frag(struct os_mbuf **om, uint16_t max_frag_sz, mem_frag_alloc_fn *alloc_cb, void *cb_arg)
{
    struct os_mbuf *frag;
    int rc;
    if (OS_MBUF_PKTLEN(*om) <= max_frag_sz) {
        frag = *om;
        *om = NULL;
        return frag;
    }
    frag = alloc_cb(max_frag_sz, cb_arg);
    if (frag == NULL) {
        goto err;
    }
    rc = os_mbuf_appendfrom(frag, *om, 0, max_frag_sz);
    if (rc != 0) {
        goto err;
    }
    os_mbuf_adj(*om, max_frag_sz);
    *om = os_mbuf_trim_front(*om);
    return frag;
err:
    os_mbuf_free_chain(frag);
    return NULL;
}