@@ -141,11 +141,30 @@ void DpdkRingReader::init(const char* params)
141141 } else {
142142 is_reader_ready = true ;
143143 }
144+ getDynfieldInfo ();
144145}
145146
146147struct timeval DpdkRingReader::getTimestamp (rte_mbuf* mbuf)
147148{
148149 struct timeval tv;
150+ if (m_nfbMetadataEnabled) {
151+ uint64_t nfb_dynflag_mask = (1ULL << m_nfbMetadataDynfieldInfo.dynflag_bit_index );
152+
153+ if (mbuf->ol_flags & nfb_dynflag_mask) {
154+ const uint16_t ct_hdr_offset = *RTE_MBUF_DYNFIELD (
155+ mbuf, m_nfbMetadataDynfieldInfo.dynfield_byte_index , uint16_t *
156+ );
157+
158+ struct NfbMetadata *ct_hdr = (struct NfbMetadata *)
159+ ((uint8_t *)mbuf->buf_addr + ct_hdr_offset);
160+
161+ tv.tv_sec = ct_hdr->timestamp .timestamp_s ;
162+ tv.tv_usec = ct_hdr->timestamp .timestamp_ns / 1000 ;
163+ return tv;
164+ }
165+ }
166+
167+ // fallback to software timestamp
149168 auto now = std::chrono::system_clock::now ();
150169 auto now_t = std::chrono::system_clock::to_time_t (now);
151170
@@ -210,4 +229,31 @@ void DpdkRingReader::configure_telemetry_dirs(
210229 register_file (queues_dir, " input-stats" , statsOps);
211230}
212231
232+ void DpdkRingReader::getDynfieldInfo ()
233+ {
234+ struct rte_mbuf_dynfield dynfield_params;
235+ struct rte_mbuf_dynflag dynflag_param;
236+ int ret;
237+ bool dynflag_found = false ;
238+ bool dynfield_found = false ;
239+
240+ rte_errno = 0 ;
241+ ret = rte_mbuf_dynflag_lookup (" rte_net_nfb_dynflag_header_vld" , &dynflag_param);
242+ if (ret >= 0 ) {
243+ m_nfbMetadataDynfieldInfo.dynflag_bit_index = ret;
244+ dynflag_found = true ;
245+ }
246+
247+ rte_errno = 0 ;
248+ ret = rte_mbuf_dynfield_lookup (" rte_net_nfb_dynfield_header_offset" , &dynfield_params);
249+ if (ret >= 0 ) {
250+ m_nfbMetadataDynfieldInfo.dynfield_byte_index = ret;
251+ dynfield_found = true ;
252+ }
253+
254+ if (dynflag_found && dynfield_found) {
255+ m_nfbMetadataEnabled = true ;
256+ }
257+ }
258+
213259} // namespace ipxp
0 commit comments