aboutsummaryrefslogtreecommitdiffstats
path: root/lib/libtle_l4p/misc.h
diff options
context:
space:
mode:
Diffstat (limited to 'lib/libtle_l4p/misc.h')
-rw-r--r--lib/libtle_l4p/misc.h166
1 files changed, 149 insertions, 17 deletions
diff --git a/lib/libtle_l4p/misc.h b/lib/libtle_l4p/misc.h
index 8be5dfe..d39e5a1 100644
--- a/lib/libtle_l4p/misc.h
+++ b/lib/libtle_l4p/misc.h
@@ -16,12 +16,34 @@
#ifndef _MISC_H_
#define _MISC_H_
+#include <tle_stats.h>
#include <tle_dpdk_wrapper.h>
#ifdef __cplusplus
extern "C" {
#endif
+union typflg {
+ uint16_t raw;
+ struct {
+ uint8_t type; /* TLE_V4/TLE_V6 */
+ uint8_t flags; /* TCP header flags */
+ };
+};
+
+union pkt_info {
+ rte_xmm_t raw;
+ struct {
+ union typflg tf;
+ uint16_t csf; /* checksum flags */
+ union l4_ports port;
+ union {
+ union ipv4_addrs addr4;
+ const union ipv6_addrs *addr6;
+ };
+ };
+};
+
static inline int
xmm_cmp(const rte_xmm_t *da, const rte_xmm_t *sa)
{
@@ -286,43 +308,41 @@ _ipv4x_cksum(const void *iph, size_t len)
return (cksum == 0xffff) ? cksum : ~cksum;
}
-/*
- * helper function to check csum.
- */
static inline int
-check_pkt_csum(const struct rte_mbuf *m, uint64_t ol_flags, uint32_t type,
- uint32_t proto)
+check_pkt_csum(const struct rte_mbuf *m, uint32_t type, uint32_t proto)
{
const struct ipv4_hdr *l3h4;
const struct ipv6_hdr *l3h6;
const struct udp_hdr *l4h;
- uint64_t fl3, fl4;
- uint16_t csum;
int32_t ret;
-
- fl4 = ol_flags & PKT_RX_L4_CKSUM_MASK;
- fl3 = (type == TLE_V4) ?
- (ol_flags & PKT_RX_IP_CKSUM_MASK) : PKT_RX_IP_CKSUM_GOOD;
+ uint16_t csum;
+ uint64_t ol_flags = m->ol_flags;
/* case 0: both ip and l4 cksum is verified or data is valid */
- if ((fl3 | fl4) == (PKT_RX_IP_CKSUM_GOOD | PKT_RX_L4_CKSUM_GOOD))
+ if ((ol_flags & PKT_RX_IP_CKSUM_GOOD) &&
+ (ol_flags & PKT_RX_L4_CKSUM_GOOD))
return 0;
/* case 1: either ip or l4 cksum bad */
- if (fl3 == PKT_RX_IP_CKSUM_BAD || fl4 == PKT_RX_L4_CKSUM_BAD)
+ if ((ol_flags & PKT_RX_IP_CKSUM_MASK) == PKT_RX_IP_CKSUM_BAD)
+ return 1;
+
+ if ((ol_flags & PKT_RX_L4_CKSUM_MASK) == PKT_RX_L4_CKSUM_BAD)
return 1;
/* case 2: either ip or l4 or both cksum is unknown */
+ ret = 0;
l3h4 = rte_pktmbuf_mtod_offset(m, const struct ipv4_hdr *, m->l2_len);
l3h6 = rte_pktmbuf_mtod_offset(m, const struct ipv6_hdr *, m->l2_len);
- ret = 0;
- if (fl3 == PKT_RX_IP_CKSUM_UNKNOWN && l3h4->hdr_checksum != 0) {
+ if ((ol_flags & PKT_RX_IP_CKSUM_MASK) == PKT_RX_IP_CKSUM_UNKNOWN &&
+ l3h4->hdr_checksum != 0) {
csum = _ipv4x_cksum(l3h4, m->l3_len);
ret = (csum != UINT16_MAX);
}
- if (ret == 0 && fl4 == PKT_RX_L4_CKSUM_UNKNOWN) {
+ if (ret == 0 && (ol_flags & PKT_RX_L4_CKSUM_MASK) ==
+ PKT_RX_L4_CKSUM_UNKNOWN) {
/*
* for IPv4 it is allowed to have zero UDP cksum,
@@ -376,8 +396,20 @@ rwl_acquire(rte_atomic32_t *p)
static inline void
rwl_down(rte_atomic32_t *p)
{
- while (rte_atomic32_cmpset((volatile uint32_t *)p, 0, INT32_MIN) == 0)
+ while (rte_atomic32_cmpset((volatile uint32_t *)p, 0, INT32_MIN) == 0)
+ rte_pause();
+}
+
+static inline int
+rwl_try_down(rte_atomic32_t *p)
+{
+ while (rte_atomic32_cmpset((volatile uint32_t *)p, 0, INT32_MIN) == 0) {
+ /* Already down */
+ if (rte_atomic32_read(p) == INT32_MIN)
+ return -1;
rte_pause();
+ }
+ return 0;
}
static inline void
@@ -510,6 +542,106 @@ _iovec_to_mbsegs(struct iovec *iv, uint32_t seglen, struct rte_mbuf *mb[],
return i;
}
+/**
+ * Remove len bytes at the beginning of an mbuf.
+ *
+ * It's an enhancement version of rte_pktmbuf_abj which not support
+ * adjusting length greater than the length of the first segment.
+ *
+ * Returns a pointer to the new mbuf. If the
+ * length is greater than the total length of the mbuf, then the
+ * function will fail and return NULL, without modifying the mbuf.
+ *
+ * @param m
+ * The packet mbuf.
+ * @param len
+ * The amount of data to remove (in bytes).
+ * @return
+ * A pointer to the new start of the data.
+ */
+static inline struct rte_mbuf *
+_rte_pktmbuf_adj(struct rte_mbuf *m, uint32_t len)
+{
+ struct rte_mbuf *next;
+ uint32_t remain, plen;
+ uint16_t segs;
+
+ if (unlikely(len > m->pkt_len))
+ return NULL;
+
+ plen = m->pkt_len;
+ remain = len;
+ segs = m->nb_segs;
+ /* don't free last segment */
+ while (remain >= m->data_len && m->next) {
+ next = m->next;
+ remain -= m->data_len;
+ segs--;
+ rte_pktmbuf_free_seg(m);
+ m = next;
+ }
+
+ if (remain) {
+ m->data_len = (uint16_t)(m->data_len - remain);
+ m->data_off = (uint16_t)(m->data_off + remain);
+ }
+
+ m->pkt_len = plen - len;
+ m->nb_segs = segs;
+ return m;
+}
+
+/**
+ * Remove len bytes of data at the end of the mbuf.
+ *
+ * It's an enhancement version of rte_pktmbuf_trim, which not support
+ * removing length greater than the length of the last segment.
+ *
+ * @param m
+ * The packet mbuf.
+ * @param len
+ * The amount of data to remove (in bytes).
+ * @return
+ * - 0: On success.
+ * - -1: On error.
+ */
+static inline int
+_rte_pktmbuf_trim(struct rte_mbuf *m, uint32_t len)
+{
+ struct rte_mbuf *last, *next, *tmp;
+ uint32_t remain;
+ uint16_t segs;
+
+ if (unlikely(len > m->pkt_len))
+ return -1;
+
+ tmp = m;
+ /* find the last segment will remain after trim */
+ remain = m->pkt_len - len;
+ while (remain > tmp->data_len) {
+ remain -= tmp->data_len;
+ tmp = tmp->next;
+ }
+
+ /* trim the remained last segment */
+ tmp->data_len = remain;
+
+ /* remove trimmed segments */
+ segs = m->nb_segs;
+ last = tmp;
+ for (tmp = tmp->next; tmp != NULL; tmp = next) {
+ next = tmp->next;
+ rte_pktmbuf_free_seg(tmp);
+ segs--;
+ }
+
+ last->next = NULL;
+ m->pkt_len -= len;
+ m->nb_segs = segs;
+
+ return 0;
+}
+
#ifdef __cplusplus
}
#endif