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