mbuf_get_seg_ofs() doesn't handle the case when requested offset
equals to packet length. Though it is a valid situation for
algorithms with no ICV data (IPsec with null encryption as an example).

Fixes: 12a0423236a9 ("ipsec: support multi-segment packets")

Signed-off-by: Konstantin Ananyev <konstantin.anan...@intel.com>
---
 lib/librte_ipsec/misc.h | 18 ++++++++++++------
 1 file changed, 12 insertions(+), 6 deletions(-)

diff --git a/lib/librte_ipsec/misc.h b/lib/librte_ipsec/misc.h
index b0cafef4e..fe4641bfc 100644
--- a/lib/librte_ipsec/misc.h
+++ b/lib/librte_ipsec/misc.h
@@ -46,16 +46,22 @@ move_bad_mbufs(struct rte_mbuf *mb[], const uint32_t 
bad_idx[], uint32_t nb_mb,
 static inline struct rte_mbuf *
 mbuf_get_seg_ofs(struct rte_mbuf *mb, uint32_t *ofs)
 {
-       uint32_t k, n;
+       uint32_t k, n, plen;
        struct rte_mbuf *ms;
 
-       ms = mb;
+       plen = mb->pkt_len;
        n = *ofs;
 
-       for (k = rte_pktmbuf_data_len(ms); n >= k;
-                       k = rte_pktmbuf_data_len(ms)) {
-               ms = ms->next;
-               n -= k;
+       if (n == plen) {
+               ms = rte_pktmbuf_lastseg(mb);
+               n = n + rte_pktmbuf_data_len(ms) - plen;
+       } else {
+               ms = mb;
+               for (k = rte_pktmbuf_data_len(ms); n >= k;
+                               k = rte_pktmbuf_data_len(ms)) {
+                       ms = ms->next;
+                       n -= k;
+               }
        }
 
        *ofs = n;
-- 
2.17.1

Reply via email to