trex_stateless_messaging.h revision 5257dbb8
1/*
2 Itay Marom
3 Hanoch Haim
4 Cisco Systems, Inc.
5*/
6
7/*
8Copyright (c) 2015-2016 Cisco Systems, Inc.
9
10Licensed under the Apache License, Version 2.0 (the "License");
11you may not use this file except in compliance with the License.
12You may obtain a copy of the License at
13
14    http://www.apache.org/licenses/LICENSE-2.0
15
16Unless required by applicable law or agreed to in writing, software
17distributed under the License is distributed on an "AS IS" BASIS,
18WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
19See the License for the specific language governing permissions and
20limitations under the License.
21*/
22#ifndef __TREX_STATELESS_MESSAGING_H__
23#define __TREX_STATELESS_MESSAGING_H__
24
25#include "msg_manager.h"
26#include "trex_dp_port_events.h"
27#include "trex_exception.h"
28#include "trex_stateless_rx_defs.h"
29#include "os_time.h"
30#include "utl_ip.h"
31#include "trex_stateless_capture.h"
32
33class TrexStatelessDpCore;
34class CRxCoreStateless;
35class TrexStreamsCompiledObj;
36class CFlowGenListPerThread;
37class TrexPktBuffer;
38
39/**
40 * Generic message reply object
41 *
42 * @author imarom (11/27/2016)
43 */
44template<typename T> class MsgReply {
45
46public:
47
48    MsgReply() {
49        reset();
50    }
51
52    void reset() {
53        m_pending = true;
54    }
55
56    bool is_pending() const {
57        return m_pending;
58    }
59
60    void set_reply(const T &reply) {
61        m_reply = reply;
62
63        /* before marking as done make sure all stores are committed */
64        asm volatile("mfence" ::: "memory");
65        m_pending = false;
66    }
67
68    T wait_for_reply(int timeout_ms = 500, int backoff_ms = 1) {
69        int guard = timeout_ms;
70
71        while (is_pending()) {
72            guard -= backoff_ms;
73            if (guard < 0) {
74                throw TrexException("timeout: failed to get reply from core");
75            }
76
77            delay(backoff_ms);
78        }
79
80        return m_reply;
81
82    }
83
84protected:
85    volatile bool  m_pending;
86    T              m_reply;
87};
88
89
90/**
91 * defines the base class for CP to DP messages
92 *
93 * @author imarom (27-Oct-15)
94 */
95class TrexStatelessCpToDpMsgBase {
96public:
97
98    TrexStatelessCpToDpMsgBase() {
99        m_quit_scheduler=false;
100    }
101
102    virtual ~TrexStatelessCpToDpMsgBase() {
103    }
104
105
106    virtual bool handle(TrexStatelessDpCore *dp_core) = 0;
107
108    /**
109     * clone the current message
110     *
111     */
112    virtual TrexStatelessCpToDpMsgBase * clone() = 0;
113
114    /* do we want to quit scheduler, can be set by handle function  */
115    void set_quit(bool enable){
116        m_quit_scheduler=enable;
117    }
118
119    bool is_quit(){
120        return ( m_quit_scheduler);
121    }
122
123    /* this node is called from scheduler in case the node is free */
124    virtual void on_node_remove(){
125    }
126
127    /* no copy constructor */
128    TrexStatelessCpToDpMsgBase(TrexStatelessCpToDpMsgBase &) = delete;
129
130protected:
131    int     m_event_id;
132    bool    m_quit_scheduler;
133};
134
135/**
136 * a message to start traffic
137 *
138 * @author imarom (27-Oct-15)
139 */
140class TrexStatelessDpStart : public TrexStatelessCpToDpMsgBase {
141public:
142
143    TrexStatelessDpStart(uint8_t m_port_id, int m_event_id, TrexStreamsCompiledObj *obj, double duration);
144
145    ~TrexStatelessDpStart();
146
147    virtual TrexStatelessCpToDpMsgBase * clone();
148
149    virtual bool handle(TrexStatelessDpCore *dp_core);
150
151private:
152
153    uint8_t                 m_port_id;
154    int                     m_event_id;
155    TrexStreamsCompiledObj *m_obj;
156    double                  m_duration;
157
158};
159
160class TrexStatelessDpPause : public TrexStatelessCpToDpMsgBase {
161public:
162
163    TrexStatelessDpPause(uint8_t port_id) : m_port_id(port_id) {
164    }
165
166
167    virtual TrexStatelessCpToDpMsgBase * clone();
168
169
170    virtual bool handle(TrexStatelessDpCore *dp_core);
171
172
173private:
174    uint8_t m_port_id;
175};
176
177
178class TrexStatelessDpResume : public TrexStatelessCpToDpMsgBase {
179public:
180
181    TrexStatelessDpResume(uint8_t port_id) : m_port_id(port_id) {
182    }
183
184
185    virtual TrexStatelessCpToDpMsgBase * clone();
186
187
188    virtual bool handle(TrexStatelessDpCore *dp_core);
189
190
191private:
192    uint8_t m_port_id;
193};
194
195
196/**
197 * a message to stop traffic
198 *
199 * @author imarom (27-Oct-15)
200 */
201class TrexStatelessDpStop : public TrexStatelessCpToDpMsgBase {
202public:
203
204    TrexStatelessDpStop(uint8_t port_id) : m_port_id(port_id) {
205        m_stop_only_for_event_id=false;
206        m_event_id = 0;
207        m_core = NULL;
208    }
209
210    virtual TrexStatelessCpToDpMsgBase * clone();
211
212
213    virtual bool handle(TrexStatelessDpCore *dp_core);
214
215    void set_core_ptr(CFlowGenListPerThread   *  core){
216            m_core = core;
217    }
218
219    CFlowGenListPerThread   * get_core_ptr(){
220        return ( m_core);
221    }
222
223
224    void set_event_id(int event_id){
225        m_event_id                =  event_id;
226    }
227
228    void set_wait_for_event_id(bool wait){
229        m_stop_only_for_event_id  =  wait;
230    }
231
232    virtual void on_node_remove();
233
234
235    bool get_is_stop_by_event_id(){
236        return (m_stop_only_for_event_id);
237    }
238
239    int get_event_id(){
240        return (m_event_id);
241    }
242
243private:
244    uint8_t m_port_id;
245    bool    m_stop_only_for_event_id;
246    int     m_event_id;
247    CFlowGenListPerThread   *  m_core ;
248
249};
250
251/**
252 * a message to Quit the datapath traffic. support only stateless for now
253 *
254 * @author hhaim
255 */
256class TrexStatelessDpQuit : public TrexStatelessCpToDpMsgBase {
257public:
258
259    TrexStatelessDpQuit()  {
260    }
261
262
263    virtual TrexStatelessCpToDpMsgBase * clone();
264
265    virtual bool handle(TrexStatelessDpCore *dp_core);
266
267};
268
269/**
270 * a message to check if both port are idel and exit
271 *
272 * @author hhaim
273 */
274class TrexStatelessDpCanQuit : public TrexStatelessCpToDpMsgBase {
275public:
276
277    TrexStatelessDpCanQuit()  {
278    }
279
280    virtual bool handle(TrexStatelessDpCore *dp_core);
281
282    virtual TrexStatelessCpToDpMsgBase * clone();
283};
284
285
286/**
287 * update message
288 */
289class TrexStatelessDpUpdate : public TrexStatelessCpToDpMsgBase {
290public:
291
292    TrexStatelessDpUpdate(uint8_t port_id, double factor)  {
293        m_port_id = port_id;
294        m_factor = factor;
295    }
296
297    virtual bool handle(TrexStatelessDpCore *dp_core);
298
299    virtual TrexStatelessCpToDpMsgBase * clone();
300
301private:
302    uint8_t  m_port_id;
303    double   m_factor;
304};
305
306
307/**
308 * psuh a PCAP message
309 */
310class TrexStatelessDpPushPCAP : public TrexStatelessCpToDpMsgBase {
311public:
312
313    TrexStatelessDpPushPCAP(uint8_t port_id,
314                            int event_id,
315                            const std::string &pcap_filename,
316                            double ipg_usec,
317                            double min_ipg_sec,
318                            double speedup,
319                            uint32_t count,
320                            double duration,
321                            bool is_dual) : m_pcap_filename(pcap_filename)  {
322
323        m_port_id  = port_id;
324        m_event_id = event_id;
325        m_ipg_usec = ipg_usec;
326        m_min_ipg_sec  = min_ipg_sec;
327        m_speedup  = speedup;
328        m_count    = count;
329        m_duration = duration;
330        m_is_dual  = is_dual;
331    }
332
333    virtual bool handle(TrexStatelessDpCore *dp_core);
334
335    virtual TrexStatelessCpToDpMsgBase * clone();
336
337private:
338    std::string  m_pcap_filename;
339    int          m_event_id;
340    double       m_ipg_usec;
341    double       m_min_ipg_sec;
342    double       m_speedup;
343    double       m_duration;
344    uint32_t     m_count;
345    uint8_t      m_port_id;
346    bool         m_is_dual;
347};
348
349
350/**
351 * barrier message for DP core
352 *
353 */
354class TrexStatelessDpBarrier : public TrexStatelessCpToDpMsgBase {
355public:
356
357    TrexStatelessDpBarrier(uint8_t port_id, int event_id) {
358        m_port_id  = port_id;
359        m_event_id = event_id;
360    }
361
362    virtual bool handle(TrexStatelessDpCore *dp_core);
363
364    virtual TrexStatelessCpToDpMsgBase * clone();
365
366private:
367    uint8_t m_port_id;
368    int     m_event_id;
369};
370
371
372/************************* messages from DP to CP **********************/
373
374/**
375 * defines the base class for DP to CP messages
376 *
377 * @author imarom (27-Oct-15)
378 */
379class TrexStatelessDpToCpMsgBase {
380public:
381
382    TrexStatelessDpToCpMsgBase() {
383    }
384
385    virtual ~TrexStatelessDpToCpMsgBase() {
386    }
387
388    /**
389     * virtual function to handle a message
390     *
391     */
392    virtual bool handle() = 0;
393
394    /* no copy constructor */
395    TrexStatelessDpToCpMsgBase(TrexStatelessDpToCpMsgBase &) = delete;
396
397};
398
399
400/**
401 * a message indicating an event has happened on a port at the
402 * DP
403 *
404 */
405class TrexDpPortEventMsg : public TrexStatelessDpToCpMsgBase {
406public:
407
408    TrexDpPortEventMsg(int thread_id, uint8_t port_id, int event_id, bool status = true) {
409        m_thread_id     = thread_id;
410        m_port_id       = port_id;
411        m_event_id      = event_id;
412        m_status        = status;
413    }
414
415    virtual bool handle();
416
417    int get_thread_id() {
418        return m_thread_id;
419    }
420
421    uint8_t get_port_id() {
422        return m_port_id;
423    }
424
425    int get_event_id() {
426        return m_event_id;
427    }
428
429    bool get_status() {
430        return m_status;
431    }
432
433private:
434    int                         m_thread_id;
435    uint8_t                     m_port_id;
436    int                         m_event_id;
437    bool                        m_status;
438
439};
440
441/************************* messages from CP to RX **********************/
442
443/**
444 * defines the base class for CP to RX messages
445 *
446 */
447class TrexStatelessCpToRxMsgBase {
448public:
449
450    TrexStatelessCpToRxMsgBase() {
451    }
452
453    virtual ~TrexStatelessCpToRxMsgBase() {
454    }
455
456    /**
457     * virtual function to handle a message
458     *
459     */
460    virtual bool handle (CRxCoreStateless *rx_core) = 0;
461
462    /* no copy constructor */
463    TrexStatelessCpToRxMsgBase(TrexStatelessCpToRxMsgBase &) = delete;
464
465};
466
467
468class TrexStatelessRxEnableLatency : public TrexStatelessCpToRxMsgBase {
469public:
470    TrexStatelessRxEnableLatency(MsgReply<bool> &reply) : m_reply(reply) {
471    }
472
473    bool handle (CRxCoreStateless *rx_core);
474
475private:
476    MsgReply<bool>    &m_reply;
477};
478
479class TrexStatelessRxDisableLatency : public TrexStatelessCpToRxMsgBase {
480    bool handle (CRxCoreStateless *rx_core);
481};
482
483class TrexStatelessRxQuit : public TrexStatelessCpToRxMsgBase {
484    bool handle (CRxCoreStateless *rx_core);
485};
486
487
488
489class TrexStatelessRxStartCapture : public TrexStatelessCpToRxMsgBase {
490public:
491    TrexStatelessRxStartCapture(const CaptureFilter& filter,
492                                uint64_t limit,
493                                MsgReply<capture_id_t> &reply) : m_reply(reply) {
494
495        m_limit  = limit;
496        m_filter = filter;
497    }
498
499    virtual bool handle(CRxCoreStateless *rx_core);
500
501private:
502    uint8_t                    m_port_id;
503    uint64_t                   m_limit;
504    CaptureFilter              m_filter;
505    MsgReply<capture_id_t>    &m_reply;
506};
507
508
509class TrexStatelessRxStopCapture : public TrexStatelessCpToRxMsgBase {
510public:
511    TrexStatelessRxStopCapture(capture_id_t capture_id, MsgReply<capture_id_t> &reply) : m_reply(reply) {
512        m_capture_id = capture_id;
513    }
514
515    virtual bool handle(CRxCoreStateless *rx_core);
516
517private:
518    capture_id_t              m_capture_id;
519    MsgReply<capture_id_t>   &m_reply;
520};
521
522
523class TrexStatelessRxStartQueue : public TrexStatelessCpToRxMsgBase {
524public:
525    TrexStatelessRxStartQueue(uint8_t port_id,
526                              uint64_t size,
527                              MsgReply<bool> &reply) : m_reply(reply) {
528
529        m_port_id = port_id;
530        m_size    = size;
531    }
532
533    virtual bool handle(CRxCoreStateless *rx_core);
534
535private:
536    uint8_t           m_port_id;
537    uint64_t          m_size;
538    MsgReply<bool>   &m_reply;
539};
540
541
542class TrexStatelessRxStopQueue : public TrexStatelessCpToRxMsgBase {
543public:
544    TrexStatelessRxStopQueue(uint8_t port_id) {
545        m_port_id = port_id;
546    }
547
548    virtual bool handle(CRxCoreStateless *rx_core);
549
550private:
551    uint8_t m_port_id;
552};
553
554
555
556class TrexStatelessRxQueueGetPkts : public TrexStatelessCpToRxMsgBase {
557public:
558
559    TrexStatelessRxQueueGetPkts(uint8_t port_id, MsgReply<const TrexPktBuffer *> &reply) : m_reply(reply) {
560        m_port_id = port_id;
561    }
562
563    /**
564     * virtual function to handle a message
565     *
566     */
567    virtual bool handle(CRxCoreStateless *rx_core);
568
569private:
570    uint8_t                              m_port_id;
571    MsgReply<const TrexPktBuffer *>     &m_reply;
572
573};
574
575/**
576 * updates the RX core that we are in L2 mode
577 */
578class TrexStatelessRxSetL2Mode : public TrexStatelessCpToRxMsgBase {
579public:
580    TrexStatelessRxSetL2Mode(uint8_t port_id) {
581        m_port_id = port_id;
582    }
583
584    virtual bool handle(CRxCoreStateless *rx_core);
585
586private:
587    uint8_t           m_port_id;
588};
589
590/**
591 * updates the RX core that we are in a L3 mode
592 */
593class TrexStatelessRxSetL3Mode : public TrexStatelessCpToRxMsgBase {
594public:
595    TrexStatelessRxSetL3Mode(uint8_t port_id,
596                             const CManyIPInfo &src_addr,
597                             bool is_grat_arp_needed) {
598
599        m_port_id              = port_id;
600        m_src_addr             = src_addr;
601        m_is_grat_arp_needed   = is_grat_arp_needed;
602    }
603
604    virtual bool handle(CRxCoreStateless *rx_core);
605
606private:
607    uint8_t           m_port_id;
608    CManyIPInfo       m_src_addr;
609    bool              m_is_grat_arp_needed;
610};
611
612/**
613 * a request from RX core to dump to Json the RX features
614 */
615class TrexStatelessRxFeaturesToJson : public TrexStatelessCpToRxMsgBase {
616public:
617
618    TrexStatelessRxFeaturesToJson(uint8_t port_id, MsgReply<Json::Value> &reply) : m_reply(reply) {
619        m_port_id = port_id;
620    }
621
622    /**
623     * virtual function to handle a message
624     *
625     */
626    virtual bool handle(CRxCoreStateless *rx_core);
627
628private:
629    uint8_t                  m_port_id;
630    MsgReply<Json::Value>   &m_reply;
631};
632
633#endif /* __TREX_STATELESS_MESSAGING_H__ */
634