m_port_id=0;
}
- virtual int tx(rte_mbuf_t * m){
+ virtual int tx(rte_mbuf_t *m) {
assert(m_queue==0);
//printf(" tx on port %d \n",m_port_id);
// utl_DumpBuffer(stdout,rte_pktmbuf_mtod(m, uint8_t*),rte_pktmbuf_pkt_len(m),0);
return (0);
}
+ virtual int tx_latency(rte_mbuf_t *m) {
+ return tx(m);
+ }
+
virtual rte_mbuf_t * rx(){
//printf(" rx on port %d \n",m_port_id);
rte_mbuf_t * m=0;
void
CNodeGenerator::handle_maintenance(CFlowGenListPerThread *thread) {
- thread->tickle(); /* tickle the watchdog */
- thread->check_msgs(); /* check messages */
+ /* tickle and check messages */
+ thread->tickle();
+ thread->check_msgs();
+
m_v_if->flush_tx_queue(); /* flush pkt each timeout */
/* save last sync time as realtime */
#endif
/* update timestamp */
- struct rte_mbuf * m;
- m=msg->m_pkt;
- uint8_t *p=rte_pktmbuf_mtod(m, uint8_t*);
- latency_header * h=(latency_header *)(p+msg->m_latency_offset);
- h->time_stamp = os_get_hr_tick_64();
+ if (msg->m_update_ts) {
+ struct rte_mbuf *m = msg->m_pkt;
+ uint8_t *p = rte_pktmbuf_mtod(m, uint8_t*);
+ latency_header * h = (latency_header *)(p+msg->m_latency_offset);
+ h->time_stamp = os_get_hr_tick_64();
+ }
+
m_node_gen.m_v_if->send_one_pkt((pkt_dir_t)msg->m_dir,msg->m_pkt);
}
}
}
-void CFlowGenListPerThread::check_msgs(void) {
-
- /* inlined for performance */
- m_stateless_dp_info.periodic_check_for_cp_messages();
-
+bool CFlowGenListPerThread::check_msgs_from_rx() {
if ( likely ( m_ring_from_rx->isEmpty() ) ) {
- return;
+ return false;
}
#ifdef NAT_TRACE_
CGlobalInfo::free_node(node);
}
+
+ return true;
+}
+
+bool CFlowGenListPerThread::check_msgs() {
+
+ bool had_msg = false;
+
+ /* inlined for performance */
+ if (m_stateless_dp_info.periodic_check_for_cp_messages()) {
+ had_msg = true;
+ }
+
+ if (check_msgs_from_rx()) {
+ had_msg = true;
+ }
+
+ return had_msg;
}
virtual void send_one_pkt(pkt_dir_t dir, rte_mbuf_t *m) {}
/* flush all pending packets into the stream */
virtual int flush_tx_queue(void)=0;
- virtual void handle_rx_queue(void) {};
/* update the source and destination mac-addr of a given mbuf by global database */
virtual int update_mac_addr_from_global_cfg(pkt_dir_t dir, uint8_t * p)=0;
/* translate port_id to the correct dir on the core */
m_monitor.tickle();
}
+
/* return the dual port ID this thread is attached to in 4 ports configuration
there are 2 dual-ports
return ( m_cpu_cp_u.GetVal());
}
+
+ bool check_msgs();
+
private:
- void check_msgs(void);
-
+
+ bool check_msgs_from_rx();
+
void handle_nat_msg(CGenNodeNatInfo * msg);
void handle_latency_pkt_msg(CGenNodeLatencyPktInfo * msg);
uint64_t m_tot_bytes;
};
+static_assert(sizeof(CGenNodeNatInfo) == sizeof(CGenNode), "sizeof(CGenNodeNatInfo) != sizeof(CGenNode)" );
+static_assert(sizeof(CGenNodeLatencyPktInfo) == sizeof(CGenNode), "sizeof(CGenNodeLatencyPktInfo) != sizeof(CGenNode)" );
+
#endif
m_tx_queue_id=tx_queue;
m_rx_queue_id=rx_queue;
}
-
- virtual int tx(rte_mbuf_t * m){
- rte_mbuf_t * tx_pkts[2];
- tx_pkts[0]=m;
+
+ virtual int tx(rte_mbuf_t *m) {
+ rte_mbuf_t *tx_pkts[2];
+
+ tx_pkts[0] = m;
if ( likely( CGlobalInfo::m_options.preview.get_vlan_mode_enable() ) ){
/* vlan mode is the default */
/* set the vlan */
return (0);
}
+
+
+ /* nothing special with HW implementation */
+ virtual int tx_latency(rte_mbuf_t *m) {
+ return tx(m);
+ }
+
virtual rte_mbuf_t * rx(){
rte_mbuf_t * rx_pkts[1];
uint16_t cnt=m_port->rx_burst(m_rx_queue_id,rx_pkts,1);
}
}
+
virtual uint16_t rx_burst(struct rte_mbuf **rx_pkts,
uint16_t nb_pkts){
uint16_t cnt=m_port->rx_burst(m_rx_queue_id,rx_pkts,nb_pkts);
class CLatencyVmPort : public CPortLatencyHWBase {
public:
- void Create(uint8_t port_index,CNodeRing * ring,
- CLatencyManager * mgr, CPhyEthIF * p) {
- m_dir = (port_index%2);
+ void Create(uint8_t port_index,
+ CNodeRing *ring,
+ CLatencyManager *mgr,
+ CPhyEthIF *p) {
+
+ m_dir = (port_index % 2);
m_ring_to_dp = ring;
m_mgr = mgr;
- m_port = p;
+ m_port = p;
}
- virtual int tx(rte_mbuf_t * m){
- if ( likely( CGlobalInfo::m_options.preview.get_vlan_mode_enable() ) ){
- /* vlan mode is the default */
- /* set the vlan */
- m->ol_flags = PKT_TX_VLAN_PKT;
- m->vlan_tci =CGlobalInfo::m_options.m_vlan_port[0];
- m->l2_len =14;
- }
-
- /* allocate node */
- CGenNodeLatencyPktInfo * node=(CGenNodeLatencyPktInfo * )CGlobalInfo::create_node();
- if ( node ) {
- node->m_msg_type = CGenNodeMsgBase::LATENCY_PKT;
- node->m_dir = m_dir;
- node->m_pkt = m;
- node->m_latency_offset = m_mgr->get_latency_header_offset();
-
- if ( m_ring_to_dp->Enqueue((CGenNode*)node) ==0 ){
- return (0);
- }
- }
- return (-1);
+
+ virtual int tx(rte_mbuf_t *m) {
+ return tx_common(m, false);
+ }
+
+ virtual int tx_latency(rte_mbuf_t *m) {
+ return tx_common(m, true);
}
virtual rte_mbuf_t * rx() {
}
private:
+ virtual int tx_common(rte_mbuf_t *m, bool fix_timestamp) {
+
+ if ( likely( CGlobalInfo::m_options.preview.get_vlan_mode_enable() ) ){
+ /* vlan mode is the default */
+ /* set the vlan */
+ m->ol_flags = PKT_TX_VLAN_PKT;
+ m->vlan_tci =CGlobalInfo::m_options.m_vlan_port[0];
+ m->l2_len =14;
+ }
+
+ /* allocate node */
+ CGenNodeLatencyPktInfo *node=(CGenNodeLatencyPktInfo * )CGlobalInfo::create_node();
+ if (!node) {
+ return (-1);
+ }
+
+ node->m_msg_type = CGenNodeMsgBase::LATENCY_PKT;
+ node->m_dir = m_dir;
+ node->m_pkt = m;
+
+ if (fix_timestamp) {
+ node->m_latency_offset = m_mgr->get_latency_header_offset();
+ node->m_update_ts = 1;
+ } else {
+ node->m_update_ts = 0;
+ }
+
+ if ( m_ring_to_dp->Enqueue((CGenNode*)node) != 0 ){
+ return (-1);
+ }
+
+ return (0);
+ }
+
CPhyEthIF * m_port;
uint8_t m_dir;
CNodeRing * m_ring_to_dp; /* ring dp -> latency thread */
struct CGenNodeLatencyPktInfo : public CGenNodeMsgBase {
uint8_t m_dir;
uint16_t m_latency_offset;
- #if __x86_64__
- uint32_t m_pad3;
-#endif
- struct rte_mbuf * m_pkt;
+
+ uint8_t m_update_ts;
+ uint8_t m_pad3[3];
+
+ struct rte_mbuf *m_pkt;
uint32_t m_pad4[MAX_PKT_MSG_INFO];
};
uint8_t *p = rte_pktmbuf_mtod(m, uint8_t*);
c_l_pkt_mode->send_debug_print(p + 34);
#endif
- if ( lp->m_io->tx(m) == 0 ){
+ if ( lp->m_io->tx_latency(m) == 0 ){
lp->m_port.m_tx_pkt_ok++;
}else{
lp->m_port.m_tx_pkt_err++;
class CPortLatencyHWBase {
- public:
- virtual int tx(rte_mbuf_t * m)=0;
- virtual rte_mbuf_t * rx()=0;
- virtual uint16_t rx_burst(struct rte_mbuf **rx_pkts,
- uint16_t nb_pkts){
- return(0);
- }
+public:
+
+ /**
+ * sends a packet
+ *
+ */
+ virtual int tx(rte_mbuf_t *m) = 0;
+
+ /**
+ * sends a latency packet
+ * if needed, timestamp will be updated
+ *
+ */
+ virtual int tx_latency(rte_mbuf_t *m) = 0;
+
+ virtual rte_mbuf_t * rx() = 0;
+ virtual uint16_t rx_burst(struct rte_mbuf **rx_pkts, uint16_t nb_pkts) = 0;
};
while (m_state == STATE_IDLE) {
m_core->tickle();
- m_core->m_node_gen.m_v_if->handle_rx_queue();
- bool had_msg = periodic_check_for_cp_messages();
+
+ bool had_msg = m_core->check_msgs();
if (had_msg) {
counter = 0;
continue;