trex_stateless_port.h revision 418fd3d0
1/*
2 Itay Marom
3 Cisco Systems, Inc.
4*/
5
6/*
7Copyright (c) 2015-2016 Cisco Systems, Inc.
8
9Licensed under the Apache License, Version 2.0 (the "License");
10you may not use this file except in compliance with the License.
11You may obtain a copy of the License at
12
13    http://www.apache.org/licenses/LICENSE-2.0
14
15Unless required by applicable law or agreed to in writing, software
16distributed under the License is distributed on an "AS IS" BASIS,
17WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18See the License for the specific language governing permissions and
19limitations under the License.
20*/
21#ifndef __TREX_STATELESS_PORT_H__
22#define __TREX_STATELESS_PORT_H__
23
24#include "common/basic_utils.h"
25#include "internal_api/trex_platform_api.h"
26#include "trex_dp_port_events.h"
27#include "trex_stateless_rx_defs.h"
28#include "trex_stream.h"
29#include "trex_exception.h"
30#include "trex_stateless_capture.h"
31
32class TrexStatelessCpToDpMsgBase;
33class TrexStatelessCpToRxMsgBase;
34class TrexStreamsGraphObj;
35class TrexPortMultiplier;
36class TrexPktBuffer;
37
38
39/**
40 * TRex port owner can perform
41 * write commands
42 * while port is owned - others can
43 * do read only commands
44 *
45 */
46class TrexPortOwner {
47public:
48
49    TrexPortOwner();
50
51    /**
52     * is port free to acquire
53     */
54    bool is_free() {
55        return m_is_free;
56    }
57
58    void release() {
59        m_is_free = true;
60        m_owner_name = "";
61        m_handler = "";
62        m_session_id = 0;
63    }
64
65    bool is_owned_by(const std::string &user) {
66        return ( !m_is_free && (m_owner_name == user) );
67    }
68
69    void own(const std::string &owner_name, uint32_t session_id) {
70
71        /* save user data */
72        m_owner_name = owner_name;
73        m_session_id = session_id;
74
75        /* internal data */
76        m_handler = utl_generate_random_str(m_seed, 8);
77        m_is_free = false;
78    }
79
80    bool verify(const std::string &handler) {
81        return ( (!m_is_free) && (m_handler == handler) );
82    }
83
84    const std::string &get_name() {
85        return (!m_is_free ? m_owner_name : g_unowned_name);
86    }
87
88    const std::string &get_handler() {
89        return (!m_is_free ? m_handler : g_unowned_handler);
90    }
91
92    const uint32_t get_session_id() {
93        return m_session_id;
94    }
95
96private:
97
98    /* is this port owned by someone ? */
99    bool         m_is_free;
100
101    /* user provided info */
102    std::string  m_owner_name;
103
104    /* which session of the user holds this port*/
105    uint32_t     m_session_id;
106
107    /* handler genereated internally */
108    std::string  m_handler;
109
110    /* seed for generating random values */
111    unsigned int m_seed;
112
113    /* just references defaults... */
114    static const std::string g_unowned_name;
115    static const std::string g_unowned_handler;
116};
117
118class AsyncStopEvent;
119
120/**
121 * describes a stateless port
122 *
123 * @author imarom (31-Aug-15)
124 */
125class TrexStatelessPort {
126    friend TrexDpPortEvents;
127    friend TrexDpPortEvent;
128    friend AsyncStopEvent;
129
130public:
131
132    /**
133     * port state
134     */
135    enum port_state_e {
136        PORT_STATE_DOWN     = 0x1,
137        PORT_STATE_IDLE     = 0x2,
138        PORT_STATE_STREAMS  = 0x4,
139        PORT_STATE_TX       = 0x8,
140        PORT_STATE_PAUSE    = 0x10,
141        PORT_STATE_PCAP_TX  = 0x20,
142    };
143
144    /**
145     * describess different error codes for port operations
146     */
147    enum rc_e {
148        RC_OK,
149        RC_ERR_BAD_STATE_FOR_OP,
150        RC_ERR_NO_STREAMS,
151        RC_ERR_FAILED_TO_COMPILE_STREAMS
152    };
153
154    /**
155     * port capture mode
156     */
157    enum capture_mode_e {
158        PORT_CAPTURE_NONE = 0,
159        PORT_CAPTURE_RX,
160        PORT_CAPTURE_ALL
161    };
162
163    TrexStatelessPort(uint8_t port_id, const TrexPlatformApi *api);
164
165    ~TrexStatelessPort();
166
167    /**
168     * acquire port
169     * throws TrexException in case of an error
170     */
171    void acquire(const std::string &user, uint32_t session_id, bool force = false);
172
173    /**
174     * release the port from the current user
175     * throws TrexException in case of an error
176     */
177    void release(void);
178
179    /**
180     * validate the state of the port before start
181     * it will return a stream graph
182     * containing information about the streams
183     * configured on this port
184     *
185     * on error it throws TrexException
186     */
187    const TrexStreamsGraphObj *validate(void);
188
189    /**
190     * start traffic
191     * throws TrexException in case of an error
192     */
193    void start_traffic(const TrexPortMultiplier &mul, double duration, bool force = false, uint64_t core_mask = UINT64_MAX);
194
195    /**
196     * stop traffic
197     * throws TrexException in case of an error
198     */
199    void stop_traffic(void);
200
201    /**
202     * remove all RX filters
203     * valid only when port is stopped
204     *
205     * @author imarom (28-Mar-16)
206     */
207    void remove_rx_filters(void);
208
209    /**
210     * pause traffic
211     * throws TrexException in case of an error
212     */
213    void pause_traffic(void);
214
215    /**
216     * resume traffic
217     * throws TrexException in case of an error
218     */
219    void resume_traffic(void);
220
221    /**
222     * update current traffic on port
223     *
224     */
225    void update_traffic(const TrexPortMultiplier &mul, bool force);
226
227    /**
228     * push a PCAP file onto the port
229     *
230     */
231    void push_remote(const std::string &pcap_filename,
232                     double            ipg_usec,
233                     double            min_ipg_sec,
234                     double            speedup,
235                     uint32_t          count,
236                     double            duration,
237                     bool              is_dual);
238
239
240    /**
241     * sets service mode
242     *
243     * @author imarom (1/22/2017)
244     *
245     * @param enabled
246     */
247    void set_service_mode(bool enabled);
248
249    bool is_service_mode_on() const {
250        return m_is_service_mode_on;
251    }
252
253    /**
254     * get the port state
255     *
256     */
257    port_state_e get_state() const {
258        return m_port_state;
259    }
260
261    /**
262     * return true if the port is active
263     * (paused is considered active)
264     */
265    bool is_active() const;
266
267    /**
268     * port state as string
269     *
270     */
271    std::string get_state_as_string() const;
272
273    /**
274     * the the max stream id currently assigned
275     *
276     */
277    int get_max_stream_id() const;
278
279    /**
280     * fill up properties of the port
281     *
282     * @author imarom (16-Sep-15)
283     *
284     * @param driver
285     */
286    void get_properties(std::string &driver);
287
288    /**
289     * encode stats as JSON
290     */
291    void encode_stats(Json::Value &port);
292
293    uint8_t get_port_id() {
294        return m_port_id;
295    }
296
297    /**
298     * delegators
299     *
300     */
301
302    void add_stream(TrexStream *stream);
303    void remove_stream(TrexStream *stream);
304    void remove_and_delete_all_streams();
305
306    TrexStream * get_stream_by_id(uint32_t stream_id) {
307        return m_stream_table.get_stream_by_id(stream_id);
308    }
309
310    int get_stream_count() {
311        return m_stream_table.size();
312    }
313
314    void get_id_list(std::vector<uint32_t> &id_list) {
315        m_stream_table.get_id_list(id_list);
316    }
317
318    void get_object_list(std::vector<TrexStream *> &object_list) {
319        m_stream_table.get_object_list(object_list);
320    }
321
322    TrexDpPortEvents & get_dp_events() {
323        return m_dp_events;
324    }
325
326
327    /**
328     * returns the number of DP cores linked to this port
329     *
330     */
331    uint8_t get_dp_core_count() {
332        return m_cores_id_list.size();
333    }
334
335    /**
336     * returns the traffic multiplier currently being used by the DP
337     *
338     */
339    double get_multiplier() {
340        return (m_factor);
341    }
342
343    /**
344     * get port speed in bits per second
345     *
346     */
347    uint64_t get_port_speed_bps() const;
348
349    /**
350     * return RX caps
351     *
352     */
353    int get_rx_caps() const {
354        return m_rx_caps;
355    }
356
357    uint16_t get_rx_count_num() const {
358        return m_rx_count_num;
359    }
360
361    /**
362     * return true if port adds CRC to a packet (not occurs for
363     * VNICs)
364     *
365     * @author imarom (24-Feb-16)
366     *
367     * @return bool
368     */
369    bool has_crc_added() const {
370        return m_api_info.has_crc;
371    }
372
373    TrexPortOwner & get_owner() {
374        return m_owner;
375    }
376
377
378    /**
379     * get the port effective rate (on a started / paused port)
380     *
381     * @author imarom (07-Jan-16)
382     *
383     */
384    void get_port_effective_rate(double &pps,
385                                 double &bps_L1,
386                                 double &bps_L2,
387                                 double &percentage);
388
389    void get_pci_info(std::string &pci_addr, int &numa_node);
390
391    /**
392     * start RX queueing of packets
393     *
394     * @author imarom (11/7/2016)
395     *
396     * @param limit
397     */
398    void start_rx_queue(uint64_t limit);
399
400    /**
401     * stop RX queueing
402     *
403     * @author imarom (11/7/2016)
404     */
405    void stop_rx_queue();
406
407    /**
408     * fetch the RX queue packets from the queue
409     *
410     */
411    const TrexPktBuffer *get_rx_queue_pkts();
412
413    /**
414     * configures port for L2 mode
415     *
416     */
417    void set_l2_mode(const uint8_t *dest_mac);
418
419    /**
420     * configures port in L3 mode
421     *
422     */
423    void set_l3_mode(uint32_t src_ipv4, uint32_t dest_ipv4);
424    void set_l3_mode(uint32_t src_ipv4, uint32_t dest_ipv4, const uint8_t *resolved_mac);
425
426    /**
427     * generate a JSON describing the status
428     * of the RX features
429     *
430     */
431    Json::Value rx_features_to_json();
432
433    /**
434     * return the port attribute object
435     *
436     */
437    TRexPortAttr *getPortAttrObj() {
438        return m_platform_api->getPortAttrObj(m_port_id);
439    }
440
441private:
442    void set_service_mode_on();
443    void set_service_mode_off();
444
445    bool is_core_active(int core_id);
446
447    const std::vector<uint8_t> get_core_id_list () {
448        return m_cores_id_list;
449    }
450
451    bool verify_state(int state, const char *cmd_name, bool should_throw = true) const;
452
453    void change_state(port_state_e new_state);
454
455    std::string generate_handler();
456
457    /**
458     * send message to all cores using duplicate
459     *
460     */
461    void send_message_to_all_dp(TrexStatelessCpToDpMsgBase *msg, bool send_to_active_only = false);
462
463    /**
464     * send message to specific DP core
465     *
466     */
467    void send_message_to_dp(uint8_t core_id, TrexStatelessCpToDpMsgBase *msg);
468
469    /**
470     * send message to specific RX core
471     *
472     */
473    void send_message_to_rx(TrexStatelessCpToRxMsgBase *msg);
474
475    /**
476     * when a port stops, perform various actions
477     *
478     */
479    void common_port_stop_actions(bool async);
480
481    /**
482     * calculate effective M per core
483     *
484     */
485    double calculate_effective_factor(const TrexPortMultiplier &mul, bool force = false);
486    double calculate_effective_factor_internal(const TrexPortMultiplier &mul);
487
488
489    /**
490     * generates a graph of streams graph
491     *
492     */
493    void generate_streams_graph();
494
495    /**
496     * dispose of it
497     *
498     * @author imarom (26-Nov-15)
499     */
500    void delete_streams_graph();
501
502
503    TrexStreamTable    m_stream_table;
504    uint8_t            m_port_id;
505    port_state_e       m_port_state;
506
507    TrexPlatformApi::intf_info_st m_api_info;
508    const TrexPlatformApi *m_platform_api;
509
510    uint16_t           m_rx_count_num;
511    uint16_t           m_rx_caps;
512
513    /* holds the DP cores associated with this port */
514    std::vector<uint8_t>   m_cores_id_list;
515
516    bool               m_last_all_streams_continues;
517    double             m_last_duration;
518    double             m_factor;
519
520    TrexDpPortEvents   m_dp_events;
521
522    /* holds a graph of streams rate*/
523    const TrexStreamsGraphObj  *m_graph_obj;
524
525    /* owner information */
526    TrexPortOwner       m_owner;
527
528    int m_pending_async_stop_event;
529
530    bool  m_is_service_mode_on;
531
532    static const uint32_t MAX_STREAMS = 20000;
533
534};
535
536
537/**
538 * port multiplier object
539 *
540 */
541class TrexPortMultiplier {
542public:
543
544
545    /**
546     * defines the type of multipler passed to start
547     */
548    enum mul_type_e {
549        MUL_FACTOR,
550        MUL_BPS,
551        MUL_BPSL1,
552        MUL_PPS,
553        MUL_PERCENTAGE
554    };
555
556    /**
557     * multiplier can be absolute value
558     * increment value or subtract value
559     */
560    enum mul_op_e {
561        OP_ABS,
562        OP_ADD,
563        OP_SUB
564    };
565
566
567    TrexPortMultiplier(mul_type_e type, mul_op_e op, double value) {
568        m_type   = type;
569        m_op     = op;
570        m_value  = value;
571    }
572
573    TrexPortMultiplier(const std::string &type_str, const std::string &op_str, double value);
574
575
576public:
577    static const std::initializer_list<std::string> g_types;
578    static const std::initializer_list<std::string> g_ops;
579
580    mul_type_e             m_type;
581    mul_op_e               m_op;
582    double                 m_value;
583};
584
585#endif /* __TREX_STATELESS_PORT_H__ */
586