From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mails.dpdk.org (mails.dpdk.org [217.70.189.124]) by inbox.dpdk.org (Postfix) with ESMTP id B6C0DA052A; Mon, 25 Jan 2021 09:51:58 +0100 (CET) Received: from [217.70.189.124] (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id B1DD2140E19; Mon, 25 Jan 2021 09:51:58 +0100 (CET) Received: from mga18.intel.com (mga18.intel.com [134.134.136.126]) by mails.dpdk.org (Postfix) with ESMTP id B4CE3140DFD for ; Mon, 25 Jan 2021 09:51:56 +0100 (CET) IronPort-SDR: 40vJ2ymQBRYZ24qVvZVqksd8XyhW4zpoinOcQPWCmlliDtuuwXGBWvYnlDArkLG+lP2nwdnUac Qf2t3fu4jRqw== X-IronPort-AV: E=McAfee;i="6000,8403,9874"; a="167366434" X-IronPort-AV: E=Sophos;i="5.79,373,1602572400"; d="scan'208";a="167366434" Received: from fmsmga001.fm.intel.com ([10.253.24.23]) by orsmga106.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 25 Jan 2021 00:51:48 -0800 IronPort-SDR: V/BY+G9ZCTe0zc5as5X2UBS+hlEcALN9RaIrYa2DgfzFb2yWtnmg56903a5kf2IAYg0mCr8JdV GcItePqSAbfA== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.79,373,1602572400"; d="scan'208";a="471978515" Received: from dpdk-moyufen06.sh.intel.com ([10.67.116.208]) by fmsmga001.fm.intel.com with ESMTP; 25 Jan 2021 00:51:47 -0800 From: yufengmx To: dts@dpdk.org, lijuan.tu@intel.com Cc: yufengmx Date: Mon, 25 Jan 2021 16:44:04 +0800 Message-Id: <20210125084414.8503-18-yufengx.mo@intel.com> X-Mailer: git-send-email 2.21.0 In-Reply-To: <20210125084414.8503-1-yufengx.mo@intel.com> References: <20210125084414.8503-1-yufengx.mo@intel.com> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit Subject: [dts] [PATCH V1 17/27] framework/pktgen: enable ixNetwork X-BeenThere: dts@dpdk.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: test suite reviews and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dts-bounces@dpdk.org Sender: "dts" enable ixNetwork rfc2544 testing scenario. Signed-off-by: yufengmx --- framework/pktgen_ixia_network.py | 224 +++++++++++++++++++++++++++++++ 1 file changed, 224 insertions(+) create mode 100644 framework/pktgen_ixia_network.py diff --git a/framework/pktgen_ixia_network.py b/framework/pktgen_ixia_network.py new file mode 100644 index 00000000..3cca2578 --- /dev/null +++ b/framework/pktgen_ixia_network.py @@ -0,0 +1,224 @@ +# BSD LICENSE +# +# Copyright(c) 2010-2021 Intel Corporation. All rights reserved. +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in +# the documentation and/or other materials provided with the +# distribution. +# * Neither the name of Intel Corporation nor the names of its +# contributors may be used to endorse or promote products derived +# from this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +import os +import time +import traceback +from pprint import pformat + +from pktgen_base import PacketGenerator, PKTGEN_IXIA_NETWORK + + +class IxNetworkPacketGenerator(PacketGenerator): + """ + ixNetwork packet generator + """ + def __init__(self, tester): + self.pktgen_type = PKTGEN_IXIA_NETWORK + self._conn = None + # ixNetwork configuration information of dts + conf_inst = self._get_generator_conf_instance() + self.conf = conf_inst.load_pktgen_config() + # ixNetwork port configuration + self._traffic_ports = [] + self._ports = [] + self._rx_ports = [] + + super(IxNetworkPacketGenerator, self).__init__(tester) + + def get_ports(self): + ''' used for ixNetwork packet generator ''' + return self._conn.get_ports() + + def _prepare_generator(self): + ''' connect with ixNetwork api server ''' + try: + self._connect(self.conf) + except Exception as e: + msg = "failed to connect to ixNetwork api server" + raise Exception(msg) + + def _connect(self, conf): + # initialize ixNetwork class + from ixia_network import IxNetwork + self._conn = IxNetwork(self.pktgen_type, conf, self.logger) + for p in self._conn.get_ports(): + self._ports.append(p) + + self.logger.debug(self._ports) + + def _disconnect(self): + ''' + disconnect with ixNetwork api server + ''' + try: + self._remove_all_streams() + self._conn.disconnect() + except Exception as e: + msg = 'Error disconnecting: %s' % e + self.logger.error(msg) + self._conn = None + + def quit_generator(self): + ''' close ixNetwork session ''' + if self._conn is not None: + self._disconnect() + + def _get_port_pci(self, port_id): + ''' + get ixNetwork port pci address + ''' + for pktgen_port_id, info in enumerate(self._ports): + if pktgen_port_id == port_id: + _pci = info.get('pci') + return _pci + else: + return None + + def _get_gen_port(self, pci): + ''' + get port management id of the packet generator + ''' + for pktgen_port_id, info in enumerate(self._ports): + _pci = info.get('pci') + if _pci == pci: + return pktgen_port_id + else: + return -1 + + def _is_gen_port(self, pci): + ''' + check if a pci address is managed by the packet generator + ''' + for name, _port_obj in self._conn.ports.items(): + _pci = _port_obj.info['pci_addr'] + self.logger.debug((_pci, pci)) + if _pci == pci: + return True + else: + return False + + def _get_ports(self): + """ + Return self ports information + """ + ports = [] + for idx in range(len(self._ports)): + ports.append('IXIA:%d' % idx) + return ports + + def send_ping6(self, pci, mac, ipv6): + ''' Send ping6 packet from IXIA ports. ''' + return self._conn.send_ping6(pci, mac, ipv6) + + def _clear_streams(self): + ''' clear streams in `PacketGenerator` ''' + # if streams has been attached, remove them from ixNetwork api server. + self._remove_all_streams() + + def _remove_all_streams(self): + ''' + remove all stream deployed on the packet generator + ''' + if not self.get_streams(): + return + + def _check_options(self, opts={}): + return True + + def _retrieve_port_statistic(self, stream_id, mode): + ''' ixNetwork traffic statistics ''' + stats = self._conn.get_stats(self._traffic_ports, mode) + stream = self._get_stream(stream_id) + self.logger.debug(pformat(stream)) + self.logger.debug(pformat(stats)) + if mode == 'rfc2544': + return stats + else: + msg = "not support mode <{0}>".format(mode) + raise Exception(msg) + + ########################################################################## + # + # class ``PacketGenerator`` abstract methods should be implemented here + # + ########################################################################## + def _prepare_transmission(self, stream_ids=[], latency=False): + ''' add one/multiple streams in one/multiple ports ''' + port_config = {} + + for stream_id in stream_ids: + stream = self._get_stream(stream_id) + tx_port = stream.get('tx_port') + rx_port = stream.get('rx_port') + pcap_file = stream.get('pcap_file') + # save port id list + if tx_port not in self._traffic_ports: + self._traffic_ports.append(tx_port) + if rx_port not in self._traffic_ports: + self._traffic_ports.append(rx_port) + if rx_port not in self._rx_ports: + self._rx_ports.append(rx_port) + # set all streams in one port to do batch configuration + options = stream['options'] + if tx_port not in list(port_config.keys()): + port_config[tx_port] = [] + config = {} + config.update(options) + # get stream rate percent + stream_config = options.get('stream_config') + rate_percent = stream_config.get('rate') + # set port list input parameter of ixNetwork class + ixia_option = [tx_port, rx_port, pcap_file, options] + port_config[tx_port].append(ixia_option) + + self.rate_percent = rate_percent + if not port_config: + msg = 'no stream options for ixNetwork packet generator' + raise Exception(msg) + + port_lists = [] + for port_id, option in port_config.items(): + port_lists += option + self._conn.prepare_ixia_network_stream(port_lists) + + def _start_transmission(self, stream_ids, options={}): + # run ixNetwork api server + try: + # Start traffic on port(s) + self.logger.info("begin traffic ......") + self._conn.start(options) + except Exception as e: + self.logger.error(traceback.format_exc()) + self.logger.error(e) + + def _stop_transmission(self, stream_id): + if self._traffic_ports: + self.logger.info("traffic completed. ") -- 2.21.0