aboutsummaryrefslogtreecommitdiff
path: root/platform/linux-generic/pktio/socket.c
diff options
context:
space:
mode:
Diffstat (limited to 'platform/linux-generic/pktio/socket.c')
-rw-r--r--platform/linux-generic/pktio/socket.c67
1 files changed, 42 insertions, 25 deletions
diff --git a/platform/linux-generic/pktio/socket.c b/platform/linux-generic/pktio/socket.c
index 81c178b9d..9d1bbe545 100644
--- a/platform/linux-generic/pktio/socket.c
+++ b/platform/linux-generic/pktio/socket.c
@@ -15,12 +15,14 @@
#include <odp/api/ticketlock.h>
#include <odp_socket_common.h>
+#include <odp_parse_internal.h>
#include <odp_packet_internal.h>
#include <odp_packet_io_internal.h>
#include <odp_packet_io_stats.h>
#include <odp_debug_internal.h>
#include <odp_errno_define.h>
#include <odp_classification_internal.h>
+#include <odp_macros_internal.h>
#include <sys/socket.h>
#include <stdio.h>
@@ -233,6 +235,9 @@ static int sock_mmsg_recv(pktio_entry_t *pktio_entry, int index ODP_UNUSED,
int i;
uint16_t frame_offset = pktio_entry->s.pktin_frame_offset;
uint32_t alloc_len = pkt_sock->mtu + frame_offset;
+ const odp_proto_chksums_t chksums = pktio_entry->s.in_chksums;
+ const odp_proto_layer_t layer = pktio_entry->s.parse_layer;
+ const odp_pktin_config_opt_t opt = pktio_entry->s.config.pktin;
memset(msgvec, 0, sizeof(msgvec));
@@ -249,8 +254,7 @@ static int sock_mmsg_recv(pktio_entry_t *pktio_entry, int index ODP_UNUSED,
recv_msgs = recvmmsg(sockfd, msgvec, nb_pkts, MSG_DONTWAIT, NULL);
odp_ticketlock_unlock(&pkt_sock->rx_lock);
- if (pktio_entry->s.config.pktin.bit.ts_all ||
- pktio_entry->s.config.pktin.bit.ts_ptp) {
+ if (opt.bit.ts_all || opt.bit.ts_ptp) {
ts_val = odp_time_global();
ts = &ts_val;
}
@@ -262,25 +266,48 @@ static int sock_mmsg_recv(pktio_entry_t *pktio_entry, int index ODP_UNUSED,
odp_packet_hdr_t *pkt_hdr = packet_hdr(pkt);
uint16_t pkt_len = msgvec[i].msg_len;
int ret;
+ uint64_t l4_part_sum = 0;
if (odp_unlikely(msgvec[i].msg_hdr.msg_flags & MSG_TRUNC)) {
odp_packet_free(pkt);
ODP_DBG("dropped truncated packet\n");
continue;
}
- if (pktio_cls_enabled(pktio_entry)) {
- uint16_t seg_len = pkt_len;
- if (msgvec[i].msg_hdr.msg_iov->iov_len < pkt_len)
- seg_len = msgvec[i].msg_hdr.msg_iov->iov_len;
+ ret = odp_packet_trunc_tail(&pkt, odp_packet_len(pkt) - pkt_len,
+ NULL, NULL);
+ if (ret < 0) {
+ ODP_ERR("trunc_tail failed");
+ odp_packet_free(pkt);
+ continue;
+ }
+
+ if (layer) {
+ uint8_t buf[PARSE_BYTES];
+ uint16_t seg_len = msgvec[i].msg_hdr.msg_iov->iov_len;
- if (_odp_cls_classify_packet(pktio_entry, base, pkt_len,
- seg_len, &pool, pkt_hdr,
- true)) {
- ODP_ERR("_odp_cls_classify_packet failed");
+ /* Make sure there is enough data for the packet
+ * parser in the case of a segmented packet. */
+ if (odp_unlikely(seg_len < PARSE_BYTES && pkt_len > seg_len)) {
+ seg_len = MIN(pkt_len, PARSE_BYTES);
+ odp_packet_copy_to_mem(pkt, 0, seg_len, buf);
+ base = buf;
+ }
+
+ if (_odp_packet_parse_common(&pkt_hdr->p, base, pkt_len,
+ seg_len, layer, chksums,
+ &l4_part_sum, opt) < 0) {
odp_packet_free(pkt);
continue;
}
+
+ if (pktio_cls_enabled(pktio_entry)) {
+ if (_odp_cls_classify_packet(pktio_entry, base, &pool,
+ pkt_hdr)) {
+ odp_packet_free(pkt);
+ continue;
+ }
+ }
}
/* Don't receive packets sent by ourselves */
@@ -290,20 +317,10 @@ static int sock_mmsg_recv(pktio_entry_t *pktio_entry, int index ODP_UNUSED,
continue;
}
- ret = odp_packet_trunc_tail(&pkt, odp_packet_len(pkt) - pkt_len,
- NULL, NULL);
- if (ret < 0) {
- ODP_ERR("trunk_tail failed");
- odp_packet_free(pkt);
- continue;
- }
-
pkt_hdr->input = pktio_entry->s.handle;
- if (!pktio_cls_enabled(pktio_entry))
- _odp_packet_parse_layer(pkt_hdr,
- pktio_entry->s.config.parser.layer,
- pktio_entry->s.in_chksums);
+ if (layer >= ODP_PROTO_LAYER_L4)
+ _odp_packet_l4_chksum(pkt_hdr, chksums, l4_part_sum);
packet_set_ts(pkt_hdr, ts);
@@ -359,11 +376,11 @@ static int sock_recv_tmo(pktio_entry_t *pktio_entry, int index,
}
static int sock_recv_mq_tmo(pktio_entry_t *pktio_entry[], int index[],
- int num_q, odp_packet_t pkt_table[], int num,
- unsigned *from, uint64_t usecs)
+ uint32_t num_q, odp_packet_t pkt_table[], int num,
+ uint32_t *from, uint64_t usecs)
{
struct timeval timeout;
- int i;
+ uint32_t i;
int ret;
int maxfd = -1, maxfd2;
fd_set readfds;