@@ -485,6 +485,27 @@ static int dpdk_output_queues_config(pktio_entry_t *pktio_entry,
return 0;
}
+static void dpdk_init_capability(pktio_entry_t *pktio_entry)
+{
+ pkt_dpdk_t *pkt_dpdk = &pktio_entry->s.pkt_dpdk;
+ odp_pktio_capability_t *capa = &pkt_dpdk->capa;
+ struct rte_eth_dev_info dev_info;
+
+ memset(&dev_info, 0, sizeof(struct rte_eth_dev_info));
+ memset(capa, 0, sizeof(odp_pktio_capability_t));
+
+ rte_eth_dev_info_get(pkt_dpdk->port_id, &dev_info);
+ capa->max_input_queues = RTE_MIN(dev_info.max_rx_queues,
+ PKTIO_MAX_QUEUES);
+ capa->max_output_queues = RTE_MIN(dev_info.max_tx_queues,
+ PKTIO_MAX_QUEUES);
+ capa->set_op.op.promisc_mode = 1;
+
+ odp_pktio_config_init(&capa->config);
+ capa->config.pktin.bit.ts_all = 1;
+ capa->config.pktin.bit.ts_ptp = 1;
+}
+
static int dpdk_open(odp_pktio_t id ODP_UNUSED,
pktio_entry_t *pktio_entry,
const char *netdev,
@@ -535,13 +556,7 @@ static int dpdk_open(odp_pktio_t id ODP_UNUSED,
return -1;
}
- memset(&dev_info, 0, sizeof(struct rte_eth_dev_info));
- rte_eth_dev_info_get(pkt_dpdk->port_id, &dev_info);
- pkt_dpdk->capa.max_input_queues = RTE_MIN(dev_info.max_rx_queues,
- PKTIO_MAX_QUEUES);
- pkt_dpdk->capa.max_output_queues = RTE_MIN(dev_info.max_tx_queues,
- PKTIO_MAX_QUEUES);
- pkt_dpdk->capa.set_op.op.promisc_mode = 1;
+ dpdk_init_capability(pktio_entry);
mtu = dpdk_mtu_get(pktio_entry);
if (mtu == 0) {
@@ -652,7 +667,7 @@ static int dpdk_stop(pktio_entry_t *pktio_entry)
static inline int mbuf_to_pkt(pktio_entry_t *pktio_entry,
odp_packet_t pkt_table[],
struct rte_mbuf *mbuf_table[],
- uint16_t num)
+ uint16_t num, odp_time_t *ts)
{
odp_packet_t pkt;
odp_packet_hdr_t *pkt_hdr;
@@ -677,7 +692,7 @@ static inline int mbuf_to_pkt(pktio_entry_t *pktio_entry,
if (pktio_cls_enabled(pktio_entry)) {
if (_odp_packet_cls_enq(pktio_entry,
(const uint8_t *)buf, pkt_len,
- NULL, &pkt_table[nb_pkts]))
+ ts, &pkt_table[nb_pkts]))
nb_pkts++;
} else {
pkt = packet_alloc(pktio_entry->s.pkt_dpdk.pool,
@@ -704,6 +719,8 @@ static inline int mbuf_to_pkt(pktio_entry_t *pktio_entry,
if (mbuf->ol_flags & PKT_RX_RSS_HASH)
odp_packet_flow_hash_set(pkt, mbuf->hash.rss);
+ packet_set_ts(pkt_hdr, ts);
+
pkt_table[nb_pkts++] = pkt;
}
rte_pktmbuf_free(mbuf);
@@ -765,6 +782,8 @@ static int dpdk_recv_queue(pktio_entry_t *pktio_entry,
{
pkt_dpdk_t *pkt_dpdk = &pktio_entry->s.pkt_dpdk;
pkt_cache_t *rx_cache = &pkt_dpdk->rx_cache[index];
+ odp_time_t ts_val;
+ odp_time_t *ts = NULL;
int nb_rx;
struct rte_mbuf *rx_mbufs[num];
int i;
@@ -795,7 +814,6 @@ static int dpdk_recv_queue(pktio_entry_t *pktio_entry,
nb_rx = rte_eth_rx_burst(pktio_entry->s.pkt_dpdk.port_id, index,
new_mbufs, pkt_dpdk->min_rx_burst);
-
rx_cache->s.idx = 0;
for (i = 0; i < nb_rx; i++) {
if (i < num) {
@@ -813,8 +831,15 @@ static int dpdk_recv_queue(pktio_entry_t *pktio_entry,
rx_mbufs, num);
}
- if (nb_rx > 0)
- nb_rx = mbuf_to_pkt(pktio_entry, pkt_table, rx_mbufs, nb_rx);
+ if (nb_rx > 0) {
+ if (pktio_entry->s.config.pktin.bit.ts_all ||
+ pktio_entry->s.config.pktin.bit.ts_ptp) {
+ ts_val = odp_time_global();
+ ts = &ts_val;
+ }
+ nb_rx = mbuf_to_pkt(pktio_entry, pkt_table, rx_mbufs, nb_rx,
+ ts);
+ }
if (!pktio_entry->s.pkt_dpdk.lockless_rx)
odp_ticketlock_unlock(&pkt_dpdk->rx_lock[index]);
@@ -56,6 +56,8 @@ static int loopback_recv(pktio_entry_t *pktio_entry, odp_packet_t pkts[],
queue_entry_t *qentry;
odp_packet_hdr_t *pkt_hdr;
odp_packet_t pkt;
+ odp_time_t ts_val;
+ odp_time_t *ts = NULL;
if (odp_unlikely(len > QUEUE_MULTI_MAX))
len = QUEUE_MULTI_MAX;
@@ -63,6 +65,12 @@ static int loopback_recv(pktio_entry_t *pktio_entry, odp_packet_t pkts[],
qentry = queue_to_qentry(pktio_entry->s.pkt_loop.loopq);
nbr = queue_deq_multi(qentry, hdr_tbl, len);
+ if (pktio_entry->s.config.pktin.bit.ts_all ||
+ pktio_entry->s.config.pktin.bit.ts_ptp) {
+ ts_val = odp_time_global();
+ ts = &ts_val;
+ }
+
if (pktio_cls_enabled(pktio_entry)) {
for (i = 0, j = 0; i < nbr; i++) {
pkt = _odp_packet_from_buffer(odp_hdr_to_buf
@@ -71,6 +79,7 @@ static int loopback_recv(pktio_entry_t *pktio_entry, odp_packet_t pkts[],
packet_parse_reset(pkt_hdr);
packet_parse_l2(pkt_hdr);
if (0 > _odp_packet_classifier(pktio_entry, pkt)) {
+ packet_set_ts(pkt_hdr, ts);
pkts[j++] = pkt;
pktio_entry->s.stats.in_octets +=
odp_packet_len(pkts[i]);
@@ -84,6 +93,7 @@ static int loopback_recv(pktio_entry_t *pktio_entry, odp_packet_t pkts[],
pkt_hdr = odp_packet_hdr(pkts[i]);
packet_parse_reset(pkt_hdr);
packet_parse_l2(pkt_hdr);
+ packet_set_ts(pkt_hdr, ts);
pktio_entry->s.stats.in_octets +=
odp_packet_len(pkts[i]);
}
@@ -140,6 +150,21 @@ static int loopback_link_status(pktio_entry_t *pktio_entry ODP_UNUSED)
return 1;
}
+static int loopback_capability(pktio_entry_t *pktio_entry ODP_UNUSED,
+ odp_pktio_capability_t *capa)
+{
+ memset(capa, 0, sizeof(odp_pktio_capability_t));
+
+ capa->max_input_queues = 1;
+ capa->max_output_queues = 1;
+ capa->set_op.op.promisc_mode = 1;
+
+ odp_pktio_config_init(&capa->config);
+ capa->config.pktin.bit.ts_all = 1;
+ capa->config.pktin.bit.ts_ptp = 1;
+ return 0;
+}
+
static int loopback_promisc_mode_set(pktio_entry_t *pktio_entry,
odp_bool_t enable)
{
@@ -183,7 +208,7 @@ const pktio_if_ops_t loopback_pktio_ops = {
.promisc_mode_get = loopback_promisc_mode_get,
.mac_get = loopback_mac_addr_get,
.link_status = loopback_link_status,
- .capability = NULL,
+ .capability = loopback_capability,
.pktin_ts_res = NULL,
.pktin_ts_from_ns = NULL,
.config = NULL,
@@ -251,6 +251,47 @@ static inline int netmap_wait_for_link(pktio_entry_t *pktio_entry)
}
/**
+ * Initialize netmap capability values
+ *
+ * @param pktio_entry Packet IO entry
+ */
+static void netmap_init_capability(pktio_entry_t *pktio_entry)
+{
+ pkt_netmap_t *pkt_nm = &pktio_entry->s.pkt_nm;
+ odp_pktio_capability_t *capa = &pkt_nm->capa;
+
+ memset(&pkt_nm->capa, 0, sizeof(odp_pktio_capability_t));
+
+ capa->max_input_queues = PKTIO_MAX_QUEUES;
+ if (pkt_nm->num_rx_rings < PKTIO_MAX_QUEUES)
+ capa->max_input_queues = pkt_nm->num_rx_rings;
+ if (capa->max_input_queues > NM_MAX_DESC) {
+ /* Have to use a single descriptor to fetch packets from all
+ * netmap rings */
+ capa->max_input_queues = 1;
+ ODP_DBG("Unable to store all %" PRIu32 " rx rings (max %d)\n"
+ " max input queues: %u\n", pkt_nm->num_rx_rings,
+ NM_MAX_DESC, capa->max_input_queues);
+ }
+
+ capa->max_output_queues = PKTIO_MAX_QUEUES;
+ if (pkt_nm->num_tx_rings < PKTIO_MAX_QUEUES)
+ capa->max_output_queues = pkt_nm->num_tx_rings;
+ if (capa->max_output_queues > NM_MAX_DESC) {
+ capa->max_output_queues = NM_MAX_DESC;
+ ODP_DBG("Unable to store all %" PRIu32 " tx rings (max %d)\n"
+ " max output queues: %u\n", pkt_nm->num_tx_rings,
+ NM_MAX_DESC, capa->max_output_queues);
+ }
+
+ capa->set_op.op.promisc_mode = 1;
+
+ odp_pktio_config_init(&capa->config);
+ capa->config.pktin.bit.ts_all = 1;
+ capa->config.pktin.bit.ts_ptp = 1;
+}
+
+/**
* Open a netmap interface
*
* In addition to standard interfaces (with or without modified netmap drivers)
@@ -326,29 +367,9 @@ static int netmap_open(odp_pktio_t id ODP_UNUSED, pktio_entry_t *pktio_entry,
goto error;
}
pkt_nm->num_rx_rings = desc->nifp->ni_rx_rings;
- pkt_nm->capa.max_input_queues = PKTIO_MAX_QUEUES;
- if (pkt_nm->num_rx_rings < PKTIO_MAX_QUEUES)
- pkt_nm->capa.max_input_queues = pkt_nm->num_rx_rings;
- if (pkt_nm->capa.max_input_queues > NM_MAX_DESC) {
- /* Have to use a single descriptor to fetch packets from all
- * netmap rings */
- pkt_nm->capa.max_input_queues = 1;
- ODP_DBG("Unable to store all %" PRIu32 " rx rings (max %d)\n"
- " max input queues: %u\n", pkt_nm->num_rx_rings,
- NM_MAX_DESC, pkt_nm->capa.max_input_queues);
- }
pkt_nm->num_tx_rings = desc->nifp->ni_tx_rings;
- pkt_nm->capa.max_output_queues = PKTIO_MAX_QUEUES;
- if (pkt_nm->num_tx_rings < PKTIO_MAX_QUEUES)
- pkt_nm->capa.max_output_queues = pkt_nm->num_tx_rings;
- if (pkt_nm->capa.max_output_queues > NM_MAX_DESC) {
- pkt_nm->capa.max_output_queues = NM_MAX_DESC;
- ODP_DBG("Unable to store all %" PRIu32 " tx rings (max %d)\n"
- " max output queues: %u\n", pkt_nm->num_tx_rings,
- NM_MAX_DESC, pkt_nm->capa.max_output_queues);
- }
- pkt_nm->capa.set_op.op.promisc_mode = 1;
+ netmap_init_capability(pktio_entry);
ring = NETMAP_RXRING(desc->nifp, desc->cur_rx_ring);
buf_size = ring->nr_buf_size;
@@ -562,13 +583,14 @@ static int netmap_stop(pktio_entry_t *pktio_entry ODP_UNUSED)
* @param pkt_out Storage for new ODP packet handle
* @param buf Netmap buffer address
* @param len Netmap buffer length
+ * @param ts Pointer to pktin timestamp
*
* @retval 0 on success
* @retval <0 on failure
*/
static inline int netmap_pkt_to_odp(pktio_entry_t *pktio_entry,
odp_packet_t *pkt_out, const char *buf,
- uint16_t len)
+ uint16_t len, odp_time_t *ts)
{
odp_packet_t pkt;
int ret;
@@ -586,7 +608,7 @@ static inline int netmap_pkt_to_odp(pktio_entry_t *pktio_entry,
if (pktio_cls_enabled(pktio_entry)) {
ret = _odp_packet_cls_enq(pktio_entry, (const uint8_t *)buf,
- len, NULL, pkt_out);
+ len, ts, pkt_out);
if (ret)
return 0;
return -1;
@@ -610,6 +632,8 @@ static inline int netmap_pkt_to_odp(pktio_entry_t *pktio_entry,
pkt_hdr->input = pktio_entry->s.handle;
+ packet_set_ts(pkt_hdr, ts);
+
*pkt_out = pkt;
}
@@ -621,6 +645,8 @@ static inline int netmap_recv_desc(pktio_entry_t *pktio_entry,
odp_packet_t pkt_table[], int num)
{
struct netmap_ring *ring;
+ odp_time_t ts_val;
+ odp_time_t *ts = NULL;
char *buf;
uint32_t slot_id;
int i;
@@ -628,12 +654,20 @@ static inline int netmap_recv_desc(pktio_entry_t *pktio_entry,
int num_rx = 0;
int num_rings = desc->last_rx_ring - desc->first_rx_ring + 1;
+ if (pktio_entry->s.config.pktin.bit.ts_all ||
+ pktio_entry->s.config.pktin.bit.ts_ptp)
+ ts = &ts_val;
+
for (i = 0; i < num_rings && num_rx != num; i++) {
if (ring_id > desc->last_rx_ring)
ring_id = desc->first_rx_ring;
ring = NETMAP_RXRING(desc->nifp, ring_id);
+ /* Take timestamp beforehand per ring to improve performance */
+ if (ts != NULL)
+ ts_val = odp_time_global();
+
while (!nm_ring_empty(ring) && num_rx != num) {
slot_id = ring->cur;
buf = NETMAP_BUF(ring, ring->slot[slot_id].buf_idx);
@@ -641,7 +675,8 @@ static inline int netmap_recv_desc(pktio_entry_t *pktio_entry,
odp_prefetch(buf);
if (!netmap_pkt_to_odp(pktio_entry, &pkt_table[num_rx],
- buf, ring->slot[slot_id].len))
+ buf, ring->slot[slot_id].len,
+ ts))
num_rx++;
ring->cur = nm_ring_next(ring, slot_id);
@@ -211,6 +211,8 @@ static int pcapif_recv_pkt(pktio_entry_t *pktio_entry, odp_packet_t pkts[],
odp_packet_hdr_t *pkt_hdr;
uint32_t pkt_len;
pkt_pcap_t *pcap = &pktio_entry->s.pkt_pcap;
+ odp_time_t ts_val;
+ odp_time_t *ts = NULL;
if (pktio_entry->s.state != STATE_STARTED)
return 0;
@@ -218,6 +220,10 @@ static int pcapif_recv_pkt(pktio_entry_t *pktio_entry, odp_packet_t pkts[],
if (!pcap->rx)
return 0;
+ if (pktio_entry->s.config.pktin.bit.ts_all ||
+ pktio_entry->s.config.pktin.bit.ts_ptp)
+ ts = &ts_val;
+
pkt = ODP_PACKET_INVALID;
pkt_len = 0;
@@ -240,6 +246,9 @@ static int pcapif_recv_pkt(pktio_entry_t *pktio_entry, odp_packet_t pkts[],
if (ret != 1)
break;
+ if (ts != NULL)
+ ts_val = odp_time_global();
+
pkt_hdr = odp_packet_hdr(pkt);
if (!odp_packet_pull_tail(pkt, pkt_len - hdr->caplen)) {
@@ -256,6 +265,8 @@ static int pcapif_recv_pkt(pktio_entry_t *pktio_entry, odp_packet_t pkts[],
packet_parse_l2(pkt_hdr);
pktio_entry->s.stats.in_octets += pkt_hdr->frame_len;
+ packet_set_ts(pkt_hdr, ts);
+
pkts[i] = pkt;
pkt = ODP_PACKET_INVALID;
@@ -331,6 +342,21 @@ static int pcapif_mac_addr_get(pktio_entry_t *pktio_entry ODP_UNUSED,
return ODPH_ETHADDR_LEN;
}
+static int pcapif_capability(pktio_entry_t *pktio_entry ODP_UNUSED,
+ odp_pktio_capability_t *capa)
+{
+ memset(capa, 0, sizeof(odp_pktio_capability_t));
+
+ capa->max_input_queues = 1;
+ capa->max_output_queues = 1;
+ capa->set_op.op.promisc_mode = 1;
+
+ odp_pktio_config_init(&capa->config);
+ capa->config.pktin.bit.ts_all = 1;
+ capa->config.pktin.bit.ts_ptp = 1;
+ return 0;
+}
+
static int pcapif_promisc_mode_set(pktio_entry_t *pktio_entry,
odp_bool_t enable)
{
@@ -406,7 +432,7 @@ const pktio_if_ops_t pcap_pktio_ops = {
.promisc_mode_set = pcapif_promisc_mode_set,
.promisc_mode_get = pcapif_promisc_mode_get,
.mac_get = pcapif_mac_addr_get,
- .capability = NULL,
+ .capability = pcapif_capability,
.pktin_ts_res = NULL,
.pktin_ts_from_ns = NULL,
.config = NULL,
@@ -610,6 +610,8 @@ static int sock_mmsg_recv(pktio_entry_t *pktio_entry,
odp_packet_t pkt_table[], unsigned len)
{
pkt_sock_t *pkt_sock = &pktio_entry->s.pkt_sock;
+ odp_time_t ts_val;
+ odp_time_t *ts = NULL;
const int sockfd = pkt_sock->sockfd;
int msgvec_len;
struct mmsghdr msgvec[ODP_PACKET_SOCKET_MAX_BURST_RX];
@@ -622,6 +624,10 @@ static int sock_mmsg_recv(pktio_entry_t *pktio_entry,
if (odp_unlikely(len > ODP_PACKET_SOCKET_MAX_BURST_RX))
return -1;
+ if (pktio_entry->s.config.pktin.bit.ts_all ||
+ pktio_entry->s.config.pktin.bit.ts_ptp)
+ ts = &ts_val;
+
memset(msgvec, 0, sizeof(msgvec));
recv_cache = pkt_sock->cache_ptr;
@@ -639,6 +645,10 @@ static int sock_mmsg_recv(pktio_entry_t *pktio_entry,
recv_msgs = recvmmsg(sockfd, msgvec, msgvec_len,
MSG_DONTWAIT, NULL);
+
+ if (ts != NULL)
+ ts_val = odp_time_global();
+
for (i = 0; i < recv_msgs; i++) {
void *base = msgvec[i].msg_hdr.msg_iov->iov_base;
struct ethhdr *eth_hdr = base;
@@ -650,7 +660,7 @@ static int sock_mmsg_recv(pktio_entry_t *pktio_entry,
continue;
ret = _odp_packet_cls_enq(pktio_entry, base,
- pkt_len, NULL,
+ pkt_len, ts,
&pkt_table[nb_rx]);
if (ret)
nb_rx++;
@@ -677,6 +687,9 @@ static int sock_mmsg_recv(pktio_entry_t *pktio_entry,
recv_msgs = recvmmsg(sockfd, msgvec, msgvec_len,
MSG_DONTWAIT, NULL);
+ if (ts != NULL)
+ ts_val = odp_time_global();
+
for (i = 0; i < recv_msgs; i++) {
void *base = msgvec[i].msg_hdr.msg_iov->iov_base;
struct ethhdr *eth_hdr = base;
@@ -693,8 +706,9 @@ static int sock_mmsg_recv(pktio_entry_t *pktio_entry,
odp_packet_pull_tail(pkt_table[i],
odp_packet_len(pkt_table[i]) -
msgvec[i].msg_len);
-
packet_parse_l2(pkt_hdr);
+ packet_set_ts(pkt_hdr, ts);
+
pkt_table[nb_rx] = pkt_table[i];
nb_rx++;
}
@@ -813,6 +827,21 @@ static int sock_link_status(pktio_entry_t *pktio_entry)
pktio_entry->s.name);
}
+static int sock_capability(pktio_entry_t *pktio_entry ODP_UNUSED,
+ odp_pktio_capability_t *capa)
+{
+ memset(capa, 0, sizeof(odp_pktio_capability_t));
+
+ capa->max_input_queues = 1;
+ capa->max_output_queues = 1;
+ capa->set_op.op.promisc_mode = 1;
+
+ odp_pktio_config_init(&capa->config);
+ capa->config.pktin.bit.ts_all = 1;
+ capa->config.pktin.bit.ts_ptp = 1;
+ return 0;
+}
+
static int sock_stats(pktio_entry_t *pktio_entry,
odp_pktio_stats_t *stats)
{
@@ -856,7 +885,7 @@ const pktio_if_ops_t sock_mmsg_pktio_ops = {
.promisc_mode_get = sock_promisc_mode_get,
.mac_get = sock_mac_addr_get,
.link_status = sock_link_status,
- .capability = NULL,
+ .capability = sock_capability,
.pktin_ts_res = NULL,
.pktin_ts_from_ns = NULL,
.config = NULL,
@@ -116,6 +116,8 @@ static inline unsigned pkt_mmap_v2_rx(pktio_entry_t *pktio_entry,
unsigned char if_mac[])
{
union frame_map ppd;
+ odp_time_t ts_val;
+ odp_time_t *ts = NULL;
unsigned frame_num, next_frame_num;
uint8_t *pkt_buf;
int pkt_len;
@@ -125,6 +127,10 @@ static inline unsigned pkt_mmap_v2_rx(pktio_entry_t *pktio_entry,
struct ring *ring;
int ret;
+ if (pktio_entry->s.config.pktin.bit.ts_all ||
+ pktio_entry->s.config.pktin.bit.ts_ptp)
+ ts = &ts_val;
+
ring = &pkt_sock->rx_ring;
frame_num = ring->frame_num;
@@ -132,6 +138,9 @@ static inline unsigned pkt_mmap_v2_rx(pktio_entry_t *pktio_entry,
if (!mmap_rx_kernel_ready(ring->rd[frame_num].iov_base))
break;
+ if (ts != NULL)
+ ts_val = odp_time_global();
+
ppd.raw = ring->rd[frame_num].iov_base;
next_frame_num = (frame_num + 1) % ring->rd_num;
@@ -149,7 +158,7 @@ static inline unsigned pkt_mmap_v2_rx(pktio_entry_t *pktio_entry,
if (pktio_cls_enabled(pktio_entry)) {
ret = _odp_packet_cls_enq(pktio_entry, pkt_buf,
- pkt_len, NULL,
+ pkt_len, ts,
&pkt_table[nb_rx]);
if (ret)
nb_rx++;
@@ -173,6 +182,8 @@ static inline unsigned pkt_mmap_v2_rx(pktio_entry_t *pktio_entry,
}
packet_parse_l2(hdr);
+ packet_set_ts(hdr, ts);
+
nb_rx++;
}
@@ -582,6 +593,21 @@ static int sock_mmap_link_status(pktio_entry_t *pktio_entry)
pktio_entry->s.name);
}
+static int sock_mmap_capability(pktio_entry_t *pktio_entry ODP_UNUSED,
+ odp_pktio_capability_t *capa)
+{
+ memset(capa, 0, sizeof(odp_pktio_capability_t));
+
+ capa->max_input_queues = 1;
+ capa->max_output_queues = 1;
+ capa->set_op.op.promisc_mode = 1;
+
+ odp_pktio_config_init(&capa->config);
+ capa->config.pktin.bit.ts_all = 1;
+ capa->config.pktin.bit.ts_ptp = 1;
+ return 0;
+}
+
static int sock_mmap_stats(pktio_entry_t *pktio_entry,
odp_pktio_stats_t *stats)
{
@@ -625,7 +651,7 @@ const pktio_if_ops_t sock_mmap_pktio_ops = {
.promisc_mode_get = sock_mmap_promisc_mode_get,
.mac_get = sock_mmap_mac_addr_get,
.link_status = sock_mmap_link_status,
- .capability = NULL,
+ .capability = sock_mmap_capability,
.pktin_ts_res = NULL,
.pktin_ts_from_ns = NULL,
.config = NULL,
@@ -179,11 +179,11 @@ static int tap_pktio_close(pktio_entry_t *pktio_entry)
return ret;
}
-static odp_packet_t pack_odp_pkt(odp_pool_t pool,
- const void *data,
- unsigned int len)
+static odp_packet_t pack_odp_pkt(odp_pool_t pool, const void *data,
+ unsigned int len, odp_time_t *ts)
{
odp_packet_t pkt;
+ odp_packet_hdr_t *pkt_hdr;
pkt = packet_alloc(pool, len, 1);
@@ -196,7 +196,9 @@ static odp_packet_t pack_odp_pkt(odp_pool_t pool,
return ODP_PACKET_INVALID;
}
- packet_parse_l2(odp_packet_hdr(pkt));
+ pkt_hdr = odp_packet_hdr(pkt);
+ packet_parse_l2(pkt_hdr);
+ packet_set_ts(pkt_hdr, ts);
return pkt;
}
@@ -208,18 +210,27 @@ static int tap_pktio_recv(pktio_entry_t *pktio_entry, odp_packet_t pkts[],
unsigned i;
uint8_t buf[BUF_SIZE];
pkt_tap_t *tap = &pktio_entry->s.pkt_tap;
+ odp_time_t ts_val;
+ odp_time_t *ts = NULL;
+
+ if (pktio_entry->s.config.pktin.bit.ts_all ||
+ pktio_entry->s.config.pktin.bit.ts_ptp)
+ ts = &ts_val;
for (i = 0; i < len; i++) {
do {
retval = read(tap->fd, buf, BUF_SIZE);
} while (retval < 0 && errno == EINTR);
+ if (ts != NULL)
+ ts_val = odp_time_global();
+
if (retval < 0) {
__odp_errno = errno;
break;
}
- pkts[i] = pack_odp_pkt(tap->pool, buf, retval);
+ pkts[i] = pack_odp_pkt(tap->pool, buf, retval, ts);
if (pkts[i] == ODP_PACKET_INVALID)
break;
}
@@ -310,6 +321,21 @@ static int tap_mac_addr_get(pktio_entry_t *pktio_entry, void *mac_addr)
return ETH_ALEN;
}
+static int tap_capability(pktio_entry_t *pktio_entry ODP_UNUSED,
+ odp_pktio_capability_t *capa)
+{
+ memset(capa, 0, sizeof(odp_pktio_capability_t));
+
+ capa->max_input_queues = 1;
+ capa->max_output_queues = 1;
+ capa->set_op.op.promisc_mode = 1;
+
+ odp_pktio_config_init(&capa->config);
+ capa->config.pktin.bit.ts_all = 1;
+ capa->config.pktin.bit.ts_ptp = 1;
+ return 0;
+}
+
const pktio_if_ops_t tap_pktio_ops = {
.init_global = NULL,
.init_local = NULL,
@@ -324,6 +350,7 @@ const pktio_if_ops_t tap_pktio_ops = {
.promisc_mode_set = tap_promisc_mode_set,
.promisc_mode_get = tap_promisc_mode_get,
.mac_get = tap_mac_addr_get,
+ .capability = tap_capability,
.pktin_ts_res = NULL,
.pktin_ts_from_ns = NULL,
.config = NULL
Adds packet input timestamping support using odp global time. Also implements odp_pktio_capability() for pktio types still lacking it. Signed-off-by: Matias Elo <matias.elo@nokia.com> --- platform/linux-generic/pktio/dpdk.c | 49 +++++++++++++----- platform/linux-generic/pktio/loop.c | 27 +++++++++- platform/linux-generic/pktio/netmap.c | 83 +++++++++++++++++++++--------- platform/linux-generic/pktio/pcap.c | 28 +++++++++- platform/linux-generic/pktio/socket.c | 35 +++++++++++-- platform/linux-generic/pktio/socket_mmap.c | 30 ++++++++++- platform/linux-generic/pktio/tap.c | 37 +++++++++++-- 7 files changed, 241 insertions(+), 48 deletions(-)