fp->frags[IP_FIRST_FRAG_IDX] = zero_frag;
}
-/* chain two mbufs */
-static inline void
-ip_frag_chain(struct rte_mbuf *mn, struct rte_mbuf *mp)
-{
- struct rte_mbuf *ms;
-
- /* adjust start of the last fragment data. */
- rte_pktmbuf_adj(mp, (uint16_t)(mp->l2_len + mp->l3_len));
-
- /* chain two fragments. */
- ms = rte_pktmbuf_lastseg(mn);
- ms->next = mp;
-
- /* accumulate number of segments and total length. */
- mn->nb_segs = (uint8_t)(mn->nb_segs + mp->nb_segs);
- mn->pkt_len += mp->pkt_len;
-
- /* reset pkt_len and nb_segs for chained fragment. */
- mp->pkt_len = mp->data_len;
- mp->nb_segs = 1;
-}
-
-
#endif /* _IP_FRAG_COMMON_H_ */
/* previous fragment found. */
if(fp->frags[i].ofs + fp->frags[i].len == ofs) {
- ip_frag_chain(fp->frags[i].mb, m);
+ /* adjust start of the last fragment data. */
+ rte_pktmbuf_adj(m, (uint16_t)(m->l2_len + m->l3_len));
+ rte_pktmbuf_chain(fp->frags[i].mb, m);
/* update our last fragment and offset. */
m = fp->frags[i].mb;
}
/* chain with the first fragment. */
- ip_frag_chain(fp->frags[IP_FIRST_FRAG_IDX].mb, m);
+ rte_pktmbuf_adj(m, (uint16_t)(m->l2_len + m->l3_len));
+ rte_pktmbuf_chain(fp->frags[IP_FIRST_FRAG_IDX].mb, m);
m = fp->frags[IP_FIRST_FRAG_IDX].mb;
/* update mbuf fields for reassembled packet. */
/* previous fragment found. */
if (fp->frags[i].ofs + fp->frags[i].len == ofs) {
- ip_frag_chain(fp->frags[i].mb, m);
+ /* adjust start of the last fragment data. */
+ rte_pktmbuf_adj(m, (uint16_t)(m->l2_len + m->l3_len));
+ rte_pktmbuf_chain(fp->frags[i].mb, m);
/* update our last fragment and offset. */
m = fp->frags[i].mb;
}
/* chain with the first fragment. */
- ip_frag_chain(fp->frags[IP_FIRST_FRAG_IDX].mb, m);
+ rte_pktmbuf_adj(m, (uint16_t)(m->l2_len + m->l3_len));
+ rte_pktmbuf_chain(fp->frags[IP_FIRST_FRAG_IDX].mb, m);
m = fp->frags[IP_FIRST_FRAG_IDX].mb;
/* update mbuf fields for reassembled packet. */
return !!(m->nb_segs == 1);
}
+/**
+ * Chain an mbuf to another, thereby creating a segmented packet.
+ *
+ * Note: The implementation will do a linear walk over the segments to find
+ * the tail entry. For cases when there are many segments, it's better to
+ * chain the entries manually.
+ *
+ * @param head
+ * The head of the mbuf chain (the first packet)
+ * @param tail
+ * The mbuf to put last in the chain
+ *
+ * @return
+ * - 0, on success.
+ * - -EOVERFLOW, if the chain is full (256 entries)
+ */
+static inline int rte_pktmbuf_chain(struct rte_mbuf *head, struct rte_mbuf *tail)
+{
+ struct rte_mbuf *cur_tail;
+
+ /* Check for number-of-segments-overflow */
+ if (head->nb_segs + tail->nb_segs >= 1 << (sizeof(head->nb_segs) * 8))
+ return -EOVERFLOW;
+
+ /* Chain 'tail' onto the old tail */
+ cur_tail = rte_pktmbuf_lastseg(head);
+ cur_tail->next = tail;
+
+ /* accumulate number of segments and total length. */
+ head->nb_segs = (uint8_t)(head->nb_segs + tail->nb_segs);
+ head->pkt_len += tail->pkt_len;
+
+ /* pkt_len is only set in the head */
+ tail->pkt_len = tail->data_len;
+
+ return 0;
+}
+
/**
* Dump an mbuf structure to the console.
*