aboutsummaryrefslogtreecommitdiffstats
path: root/tools/pkt_gen
diff options
context:
space:
mode:
authorSridhar Rao <sridhar.rao@spirent.com>2021-10-01 02:44:43 +0000
committerGerrit Code Review <gerrit@opnfv.org>2021-10-01 02:44:43 +0000
commit467a22c1c2cbfc3c4a8448b7170d84dc26d658ec (patch)
tree590f6e7fb7fbbd2c6c0dd7e3fd7864234da3f17c /tools/pkt_gen
parent17e20bfa70d1a9ce5e6ee6687245e3e22f3633a8 (diff)
parent48f947e94e36e877aa6889e10cda0bbdcd573ef4 (diff)
Merge "Integrating DPPD-Prox with Vineperf"
Diffstat (limited to 'tools/pkt_gen')
-rw-r--r--tools/pkt_gen/prox/__init__.py18
-rw-r--r--tools/pkt_gen/prox/files/format.yaml105
-rw-r--r--tools/pkt_gen/prox/files/helper.lua77
-rw-r--r--tools/pkt_gen/prox/files/machine.map14
-rw-r--r--tools/pkt_gen/prox/files/vineperf-baremetal.cfg68
-rw-r--r--tools/pkt_gen/prox/prox.py203
-rw-r--r--tools/pkt_gen/prox/render.py75
-rw-r--r--tools/pkt_gen/prox/templates/params-vineperf.lua.j279
-rw-r--r--tools/pkt_gen/prox/templates/rapid-vineperf-baremetal.env.j224
-rw-r--r--tools/pkt_gen/prox/templates/tst009.test.j234
10 files changed, 697 insertions, 0 deletions
diff --git a/tools/pkt_gen/prox/__init__.py b/tools/pkt_gen/prox/__init__.py
new file mode 100644
index 00000000..e0e55121
--- /dev/null
+++ b/tools/pkt_gen/prox/__init__.py
@@ -0,0 +1,18 @@
+# Copyright 2021 Spirent Communications.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+"""Implementation of prox-based tests
+"""
+
+from .prox import *
diff --git a/tools/pkt_gen/prox/files/format.yaml b/tools/pkt_gen/prox/files/format.yaml
new file mode 100644
index 00000000..6b501040
--- /dev/null
+++ b/tools/pkt_gen/prox/files/format.yaml
@@ -0,0 +1,105 @@
+;Format: PushGateway
+;Format: Xtesting
+;URL:
+ part1: http://testresults.opnfv.org/test/api/v1/results
+;URL:
+ part1: http://192.168.36.61:9091/metrics/job/
+ part2: test
+ part3: /instance/
+ part4: environment_file
+;FlowsizeTest:
+ Flows: Flows
+ Size: Size
+ RequestedSpeed: RequestedSpeed
+ CoreGenerated: pps_req_tx
+ SentByNIC: pps_tx
+ FwdBySUT: pps_sut_tx
+ RevByCore: pps_rx
+ AvgLatency: lat_avg
+ PCTLatency: lat_perc
+ MinLatency: lat_min
+ MaxLatency: lat_max
+ Sent: abs_tx
+ Received: abs_rx
+ Lost: abs_dropped
+ Misordered: mis_ordered
+ Extent: extent
+ Duplicated: duplicate
+FlowSizeTest:
+ Environment: environment_file
+ Test: test
+ Flows: Flows
+ Size: Size
+ Speed (Mpps):
+ RequestedSpeed: RequestedSpeed
+ CoreGenerated: pps_req_tx
+ SentByNIC: pps_tx
+ FwdBySUT: pps_sut_tx
+ RevByCore: pps_rx
+ Latency (usec):
+ AvgLatency: lat_avg
+ PCTLatency: lat_perc
+ MinLatency: lat_min
+ MaxLatency: lat_max
+ Distribution:
+ bucket_size: bucket_size
+ buckets: buckets
+ Absolute Packet Count:
+ Sent: abs_tx
+ Received: abs_rx
+ Lost: abs_dropped
+ Re-ordering:
+ Misordered: mis_ordered
+ Extent: extent
+ Duplicated: duplicate
+IrqTest:
+ Environment: environment_file
+ Test: test
+ Buckets: buckets
+ Machine_data: machine_data
+ImpairTest:
+ Environment: environment_file
+ Test: test
+ Flows: Flows
+ Size: Size
+ Speed (Mpps):
+ RequestedSpeed: RequestedSpeed
+ CoreGenerated: pps_req_tx
+ SentByNIC: pps_tx
+ FwdBySUT: pps_sut_tx
+ RevByCore: pps_rx
+ Latency (usec):
+ AvgLatency: lat_avg
+ PCTLatency: lat_perc
+ MinLatency: lat_min
+ MaxLatency: lat_max
+ Distribution:
+ bucket_size: bucket_size
+ buckets: buckets
+ Absolute Packet Count:
+ Sent: abs_tx
+ Received: abs_rx
+ Lost: abs_dropped
+ Re-ordering:
+ Misordered: mis_ordered
+ Extent: extent
+ Duplicated: duplicate
+CoreStatsTest:
+ Environment: environment_file
+ Test: test
+ PROXID: PROXID
+ StepSize: StepSize
+ Received: Received
+ Sent: Sent
+ NonDPReceived: NonDPReceived
+ NonDPSent: NonDPSent
+ Dropped: Dropped
+PortStatsTest:
+ Environment: environment_file
+ Test: test
+ PROXID: PROXID
+ StepSize: StepSize
+ Received: Received
+ Sent: Sent
+ NoMbufs: NoMbufs
+ iErrMiss: iErrMiss
diff --git a/tools/pkt_gen/prox/files/helper.lua b/tools/pkt_gen/prox/files/helper.lua
new file mode 100644
index 00000000..1b4c657b
--- /dev/null
+++ b/tools/pkt_gen/prox/files/helper.lua
@@ -0,0 +1,77 @@
+--
+-- Copyright (c) 2020 Intel Corporation
+--
+-- Licensed under the Apache License, Version 2.0 (the "License");
+-- you may not use this file except in compliance with the License.
+-- You may obtain a copy of the License at
+--
+-- http://www.apache.org/licenses/LICENSE-2.0
+--
+-- Unless required by applicable law or agreed to in writing, software
+-- distributed under the License is distributed on an "AS IS" BASIS,
+-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+-- See the License for the specific language governing permissions and
+-- limitations under the License.
+--
+
+function convertIPToHex(ip)
+ local address_chunks = {}
+ if type(ip) ~= "string" then
+ print ("IP ADDRESS ERROR: ", ip)
+ return "IP ADDRESS ERROR"
+ end
+
+ local chunks = {ip:match("^(%d+)%.(%d+)%.(%d+)%.(%d+)(\/%d+)$")}
+ if #chunks == 5 then
+ for i,v in ipairs(chunks) do
+ if i < 5 then
+ if tonumber(v) > 255 then
+ print ("IPV4 ADDRESS ERROR: ", ip)
+ return "IPV4 ADDRESS ERROR"
+ end
+ address_chunks[#address_chunks + 1] = string.format ("%02x", v)
+ end
+ end
+ result = table.concat(address_chunks, " ")
+ print ("Hex IPV4: ", result)
+ return result
+ end
+
+ local chunks = {ip:match("^(%d+)%.(%d+)%.(%d+)%.(%d+)$")}
+ if #chunks == 4 then
+ for i,v in ipairs(chunks) do
+ if tonumber(v) > 255 then
+ print ("IPV4 ADDRESS ERROR: ", ip)
+ return "IPV4 ADDRESS ERROR"
+ end
+ address_chunks[#address_chunks + 1] = string.format ("%02x", v)
+ end
+ result = table.concat(address_chunks, " ")
+ print ("Hex IPV4: ", result)
+ return result
+ end
+
+ delimiter = ":"
+ for match in (ip..delimiter):gmatch("(.-)"..delimiter) do
+ if match ~= "" then
+ number = tonumber(match, 16)
+ if number <= 65535 then
+ table.insert(address_chunks, string.format("%02x %02x",number/256,number % 256))
+ end
+ else
+ table.insert(address_chunks, "")
+ end
+ end
+ for i, chunk in ipairs(address_chunks) do
+ if chunk =="" then
+ table.remove(address_chunks, i)
+ for j = 1,(8-#address_chunks) do
+ table.insert(address_chunks, i, "00 00")
+ end
+ break
+ end
+ end
+ result = table.concat(address_chunks, " ")
+ print ("Hex IPV6: ", result)
+ return result
+end
diff --git a/tools/pkt_gen/prox/files/machine.map b/tools/pkt_gen/prox/files/machine.map
new file mode 100644
index 00000000..2992884e
--- /dev/null
+++ b/tools/pkt_gen/prox/files/machine.map
@@ -0,0 +1,14 @@
+[DEFAULT]
+machine_index=0
+
+[TestM1]
+machine_index=1
+
+[TestM2]
+machine_index=2
+
+[TestM3]
+machine_index=3
+
+[TestM4]
+machine_index=4 \ No newline at end of file
diff --git a/tools/pkt_gen/prox/files/vineperf-baremetal.cfg b/tools/pkt_gen/prox/files/vineperf-baremetal.cfg
new file mode 100644
index 00000000..03299538
--- /dev/null
+++ b/tools/pkt_gen/prox/files/vineperf-baremetal.cfg
@@ -0,0 +1,68 @@
+[lua]
+dofile("params-vineperf.lua")
+
+[eal options]
+-n=4 ; force number of memory channels
+no-output=no ; disable DPDK debug output
+eal=--proc-type auto ${eal}
+
+[port 0]
+name=p0
+rx desc=2048
+tx desc=2048
+vlan=yes
+vdev=gen_tap
+local ipv4= ${local_ip1}
+lsc=no
+
+[port 1]
+name=p1
+rx desc=2048
+tx desc=2048
+vlan=yes
+vdev=rec_tap
+local ipv4=${local_ip2}
+lsc=no
+
+[variables]
+$mbs=8
+
+[defaults]
+mempool size=8K
+
+[global]
+name=${name}
+heartbeat timeout=${heartbeat}
+
+[core $mcore]
+mode=master
+
+[core $gencores]
+name=p0
+task=0
+mode=gen
+tx port=p0
+bps=1250000000
+pkt inline=00 00 00 00 00 00 00 00 00 00 00 00 08 00 45 00 00 2e 00 01 00 00 40 11 f7 7d ${local_hex_ip1} ${local_hex_ip2} 0b b8 0b b9 00 1a 55 7b
+pkt size=60
+min bulk size=$mbs
+max bulk size=16
+drop=yes
+lat pos=42
+accuracy pos=46
+packet id pos=50
+signature=0x98765432
+signature pos=56
+
+[core $latcores]
+name=lat
+task=0
+mode=lat
+rx port=p1
+lat pos=42
+accuracy pos=46
+packet id pos=50
+signature=0x98765432
+signature pos=56
+accuracy limit nsec=1000000
+latency bucket size=${bucket_size_exp}
diff --git a/tools/pkt_gen/prox/prox.py b/tools/pkt_gen/prox/prox.py
new file mode 100644
index 00000000..2b4ff9ce
--- /dev/null
+++ b/tools/pkt_gen/prox/prox.py
@@ -0,0 +1,203 @@
+# Copyright 2021 Spirent Communications.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+"""
+Code to integrate Prox Traffic generator with vineperf test framework.
+
+"""
+
+#import csv
+import logging
+import os
+#import subprocess
+
+from conf import settings
+from core.results.results_constants import ResultsConstants
+#from runrapid import RapidTestManager
+from tools import tasks
+from tools.pkt_gen.prox import render
+
+class Prox():
+ """
+ Prox Traffic Generator
+ """
+ _logger = logging.getLogger(__name__)
+
+ def connect(self):
+ """
+ Do nothing.
+ """
+ return self
+
+ def disconnect(self):
+ """
+ Do nothing.
+ """
+ return self
+
+ def send_burst_traffic(self, traffic=None, duration=20):
+ """
+ Do nothing.
+ """
+ raise NotImplementedError('Not implemented by PROX')
+
+ def send_rfc2889_forwarding(self, traffic=None, tests=1, _duration=20):
+ """
+ Send traffic per RFC2889 Forwarding test specifications.
+ """
+ raise NotImplementedError('Not implemented by PROX')
+
+ def send_rfc2889_caching(self, traffic=None, tests=1, _duration=20):
+ """
+ Send as per RFC2889 Addr-Caching test specifications.
+ """
+ raise NotImplementedError('Not implemented by PROX')
+
+ def send_rfc2889_learning(self, traffic=None, tests=1, _duration=20):
+ """
+ Send traffic per RFC2889 Addr-Learning test specifications.
+ """
+ raise NotImplementedError('Not implemented by PROX')
+
+ def send_cont_traffic(self, traffic=None, duration=30):
+ """
+ Send Custom - Continuous Test traffic
+ Reuse RFC2544 throughput test specifications along with
+ 'custom' configuration
+ """
+ raise NotImplementedError('Not implemented by PROX')
+
+ def get_rfc2544_results(self, output):
+ """
+ Reads the output and return the results
+ """
+ result = {}
+ values = None
+ for line in output.splitlines():
+ if line.startswith('|') and 'different number' in line:
+ pktsize = line.split(',')[1]
+ try:
+ int(pktsize)
+ except ValueError:
+ self._logger.info("Pkt Size is not an Int\n")
+ return result
+ if line.startswith('|') and '%' in line:
+ values = line.split('|')
+ if values and len(values) > 12:
+ tx_pps = float(values[4].strip().split(' ')[0]) * 1000000
+ rx_pps = float(values[7].strip().split(' ')[0]) * 1000000
+ rx_mbps = float(values[6].strip().split(' ')[0]) * 1000
+ max_lat = float(values[10].strip().split(' ')[0]) * 1000
+ avg_lat = float(values[8].strip().split(' ')[0]) * 1000
+ loss_percentage = ((float(values[11].strip()) -
+ float(values[12].strip()))/float(values[11].strip())) * 100
+ result[ResultsConstants.TX_RATE_FPS] = tx_pps
+ result[ResultsConstants.THROUGHPUT_RX_FPS] = rx_pps
+ result[ResultsConstants.TX_RATE_MBPS] = 0
+ result[ResultsConstants.THROUGHPUT_RX_MBPS] = rx_mbps
+ result[ResultsConstants.TX_RATE_PERCENT] = 0
+ result[ResultsConstants.THROUGHPUT_RX_PERCENT] = 0
+ result[ResultsConstants.MIN_LATENCY_NS] = 0
+ result[ResultsConstants.MAX_LATENCY_NS] = max_lat
+ result[ResultsConstants.AVG_LATENCY_NS] = avg_lat
+ result[ResultsConstants.FRAME_LOSS_PERCENT] = loss_percentage
+ return result
+
+ def send_rfc2544_throughput(self, traffic=None, tests=1, duration=20,
+ lossrate=0.0):
+ """
+ Send traffic per RFC2544 throughput test specifications.
+ """
+ print("Run with Duration: {}, Tests: {} & Lossrate: {}".format(
+ duration, tests, lossrate))
+ pkt_size = None
+ if traffic and 'l2' in traffic:
+ if 'framesize' in traffic['l2']:
+ framesize = traffic['l2']['framesize']
+ pkt_size = '['+str(framesize)+']'
+ if not settings.getValue('K8S'):
+ # First render all the configurations and place it
+ filesdir = settings.getValue('TRAFFICGEN_PROX_FILES_DIR')
+ confdir = settings.getValue('TRAFFICGEN_PROX_CONF_DIR')
+ render.render_content_jinja(pkt_size)
+ # copy some static files to config folder.
+ for stfile in settings.getValue('TRAFFICGEN_PROX_STATIC_CONF_FILES'):
+ srcfile = os.path.join(filesdir, stfile)
+ if os.path.exists(srcfile):
+ cmd = ['cp', srcfile, confdir ]
+ tasks.run_task(cmd, self._logger, 'Copying Static Conf. Files')
+ # in appropriate folder: pick /tmp or /opt or $HOME
+ envfile = os.path.join(confdir, settings.getValue('TRAFFICGEN_PROX_ENV_FILE'))
+ tstfile = os.path.join(confdir, settings.getValue('TRAFFICGEN_PROX_TEST_FILE'))
+ mmapfile = os.path.join(confdir, 'machine.map')
+ cmd = ['python', '-m', 'runrapid',
+ '--env', envfile,
+ '--test', tstfile,
+ '--map', mmapfile,
+ '--runtime', settings.getValue('TRAFFICGEN_PROX_RUNTIME')]
+ output, error = tasks.run_task(cmd, self._logger, 'Running RUN-RAPID command')
+ if output:
+ return self.get_rfc2544_results(output)
+ else:
+ self._logger.info(error)
+ return None
+ else:
+ self._logger.info("Only Baremetal Support is included.")
+ print("Only Baremetal Support is included")
+ return None
+
+
+ def send_rfc2544_back2back(self, traffic=None, tests=1, duration=20,
+ lossrate=0.0):
+ """
+ Send traffic per RFC2544 BacktoBack test specifications.
+ """
+ raise NotImplementedError('Not implemented by PROX')
+
+ def start_cont_traffic(self, traffic=None, duration=30):
+ """Non-blocking version of 'send_cont_traffic'.
+
+ See ITrafficGenerator for description
+ """
+ raise NotImplementedError('Not implemented by PROX')
+
+ def stop_cont_traffic(self):
+ """Stop continuous transmission and return results.
+ """
+ raise NotImplementedError('Not implemented by PROX')
+
+ def start_rfc2544_back2back(self, traffic=None, tests=1, duration=20,
+ lossrate=0.0):
+ """Send traffic per RFC2544 back2back test specifications.
+
+ See ITrafficGenerator for description
+ """
+ raise NotImplementedError('Not implemented by PROX')
+
+ def wait_rfc2544_back2back(self):
+ """Wait and set results of RFC2544 test.
+ """
+ raise NotImplementedError('Not implemented by PROX')
+
+ def start_rfc2544_throughput(self, traffic=None, tests=1, duration=20,
+ lossrate=0.0):
+ """Non-blocking version of 'send_rfc2544_throughput'.
+ See ITrafficGenerator for description
+ """
+ raise NotImplementedError('Not implemented by PROX')
+
+ def wait_rfc2544_throughput(self):
+ """Wait and set results of RFC2544 test.
+ """
+ raise NotImplementedError('Not implemented by PROX')
diff --git a/tools/pkt_gen/prox/render.py b/tools/pkt_gen/prox/render.py
new file mode 100644
index 00000000..05b49502
--- /dev/null
+++ b/tools/pkt_gen/prox/render.py
@@ -0,0 +1,75 @@
+# Copyright 2021 Spirent Communications.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+"""
+Render Jinja templates to corresponding files
+"""
+
+import os
+
+#from conf import merge_spec
+from conf import settings
+from jinja2 import Environment, FileSystemLoader
+
+def listdir_nohidden(path):
+ """
+ Exclude hidden directories
+ """
+ for fname in os.listdir(path):
+ if not fname.startswith('.'):
+ yield fname
+
+def render_content_jinja_baremetal(pkt_size):
+ """
+ Render Templates
+ """
+ templates_dir_path = settings.getValue('TRAFFICGEN_PROX_TEMPLATES_DIR')
+ values_from_vineperf = {
+ 'm1_admin_ip' : settings.getValue('TRAFFICGEN_PROX_EAST_MGMT_IP'),
+ 'm2_admin_ip' : settings.getValue('TRAFFICGEN_PROX_WEST_MGMT_IP'),
+ 'local_ip1' : settings.getValue('TRAFFICGEN_PROX_EAST_IP'),
+ 'local_ip2' : settings.getValue('TRAFFICGEN_PROX_WEST_IP'),
+ 'local_eip1' : settings.getValue('TRAFFICGEN_PROX_EAST_ENV_IP'),
+ 'local_eip2' : settings.getValue('TRAFFICGEN_PROX_WEST_ENV_IP'),
+ 'mac1' : settings.getValue('TRAFFICGEN_PROX_EAST_MAC'),
+ 'mac2' : settings.getValue('TRAFFICGEN_PROX_WEST_MAC'),
+ 'emac1' : settings.getValue('TRAFFICGEN_PROX_EAST_ENV_MAC'),
+ 'emac2' : settings.getValue('TRAFFICGEN_PROX_WEST_ENV_MAC'),
+ 'pci1': settings.getValue('TRAFFICGEN_PROX_EAST_PCI_ID'),
+ 'pci2': settings.getValue('TRAFFICGEN_PROX_WEST_PCI_ID'),
+ 'mcore' : settings.getValue('TRAFFICGEN_PROX_MASTER_CORES'),
+ 'gencores' : settings.getValue('TRAFFICGEN_PROX_GENERATOR_CORES'),
+ 'latcores' : settings.getValue('TRAFFICGEN_PROX_LATENCY_CORES'),
+ 'config_file' : os.path.join(settings.getValue('TRAFFICGEN_PROX_CONF_DIR'),
+ settings.getValue('TRAFFICGEN_PROX_GENERATOR_CONFIG_FILENAME')),
+ 'user' : settings.getValue('TRAFFICGEN_PROX_GENERATOR_USER'),
+ 'key' : os.path.join(settings.getValue('TRAFFICGEN_PROX_CONF_DIR'),
+ settings.getValue('TRAFFICGEN_PROX_GENERATOR_KEYFILE')),
+ 'latency_buckets': settings.getValue('TRAFFICGEN_PROX_LATENCY_BUCKETS'),
+ }
+ if pkt_size:
+ values_from_vineperf['pktsizes'] = pkt_size
+ else:
+ values_from_vineperf['pktsizes'] = settings.getValue('TRAFFICGEN_PROX_PKTSIZES')
+
+ file_loader = FileSystemLoader(templates_dir_path)
+ env = Environment(loader = file_loader)
+ destination_dir = settings.getValue("TRAFFICGEN_PROX_CONF_DIR")
+
+ for filename in listdir_nohidden(templates_dir_path):
+ file = env.get_template(filename)
+ rendered_content = file.render(data = values_from_vineperf)
+ filename = os.path.splitext(filename)[0]
+ with open(os.path.join(destination_dir, filename), "w+") as fileh:
+ fileh.write(rendered_content)
diff --git a/tools/pkt_gen/prox/templates/params-vineperf.lua.j2 b/tools/pkt_gen/prox/templates/params-vineperf.lua.j2
new file mode 100644
index 00000000..b389a51a
--- /dev/null
+++ b/tools/pkt_gen/prox/templates/params-vineperf.lua.j2
@@ -0,0 +1,79 @@
+function convertIPToHex(ip)
+ local address_chunks = {}
+ if type(ip) ~= "string" then
+ print ("IP ADDRESS ERROR: ", ip)
+ return "IP ADDRESS ERROR"
+ end
+
+ local chunks = {ip:match("^(%d+)%.(%d+)%.(%d+)%.(%d+)(\/%d+)$")}
+ if #chunks == 5 then
+ for i,v in ipairs(chunks) do
+ if i < 5 then
+ if tonumber(v) > 255 then
+ print ("IPV4 ADDRESS ERROR: ", ip)
+ return "IPV4 ADDRESS ERROR"
+ end
+ address_chunks[#address_chunks + 1] = string.format ("%02x", v)
+ end
+ end
+ result = table.concat(address_chunks, " ")
+ print ("Hex IPV4: ", result)
+ return result
+ end
+
+ local chunks = {ip:match("^(%d+)%.(%d+)%.(%d+)%.(%d+)$")}
+ if #chunks == 4 then
+ for i,v in ipairs(chunks) do
+ if tonumber(v) > 255 then
+ print ("IPV4 ADDRESS ERROR: ", ip)
+ return "IPV4 ADDRESS ERROR"
+ end
+ address_chunks[#address_chunks + 1] = string.format ("%02x", v)
+ end
+ result = table.concat(address_chunks, " ")
+ print ("Hex IPV4: ", result)
+ return result
+ end
+
+ delimiter = ":"
+ for match in (ip..delimiter):gmatch("(.-)"..delimiter) do
+ if match ~= "" then
+ number = tonumber(match, 16)
+ if number <= 65535 then
+ table.insert(address_chunks, string.format("%02x %02x",number/256,number % 256))
+ end
+ else
+ table.insert(address_chunks, "")
+ end
+ end
+ for i, chunk in ipairs(address_chunks) do
+ if chunk =="" then
+ table.remove(address_chunks, i)
+ for j = 1,(8-#address_chunks) do
+ table.insert(address_chunks, i, "00 00")
+ end
+ break
+ end
+ end
+ result = table.concat(address_chunks, " ")
+ print ("Hex IPV6: ", result)
+ return result
+end
+
+eal="--socket-mem=256,0 --file-prefix Generator -w {{data.pci1}} -w {{data.pci2}}"
+name="Generator"
+local_ip1={{data.local_ip1|tojson}}
+local_hex_ip1=convertIPToHex(local_ip1)
+local_ip2={{data.local_ip2|tojson}}
+local_hex_ip2=convertIPToHex(local_ip2)
+mcore={{data.mcore|tojson}}
+dest_ip1={{data.local_ip2|tojson}}
+dest_hex_ip1=convertIPToHex(dest_ip1)
+dest_hex_mac2={{data.mac1|tojson}}
+dest_ip2={{data.local_ip1|tojson}}
+dest_hex_ip2=convertIPToHex(dest_ip2)
+dest_hex_mac1={{data.mac2|tojson}}
+gencores={{data.gencores|tojson}}
+latcores={{data.latcores|tojson}}
+bucket_size_exp={{data.latency_buckets|tojson}}
+heartbeat="60"
diff --git a/tools/pkt_gen/prox/templates/rapid-vineperf-baremetal.env.j2 b/tools/pkt_gen/prox/templates/rapid-vineperf-baremetal.env.j2
new file mode 100644
index 00000000..8823fe2a
--- /dev/null
+++ b/tools/pkt_gen/prox/templates/rapid-vineperf-baremetal.env.j2
@@ -0,0 +1,24 @@
+[rapid]
+loglevel = DEBUG
+version = 19.6.30
+total_number_of_machines = 2
+
+[M1]
+name = rapid-east
+admin_ip = {{data.m1_admin_ip}}
+dp_ip1 = {{data.local_eip1}}
+dp_mac1 = {{data.emac1}}
+
+[M2]
+name = rapid-west
+admin_ip = {{data.m2_admin_ip}}
+dp_ip1 = {{data.local_eip2}}
+dp_mac1 = {{data.emac2}}
+
+[ssh]
+key = {{data.key}}
+user = {{data.user}}
+
+[Varia]
+vim = Openstack
+stack = rapid
diff --git a/tools/pkt_gen/prox/templates/tst009.test.j2 b/tools/pkt_gen/prox/templates/tst009.test.j2
new file mode 100644
index 00000000..86e7cc8d
--- /dev/null
+++ b/tools/pkt_gen/prox/templates/tst009.test.j2
@@ -0,0 +1,34 @@
+[TestParameters]
+name = Rapid_ETSINFV_TST009
+number_of_tests = 1
+total_number_of_test_machines = 2
+lat_percentile = 99
+
+[TestM1]
+name = Generator
+prox_launch_exit = false
+config_file = {{data.config_file}}
+dest_vm = 2
+mcore = [{{data.mcore}}]
+gencores = [{{data.gencores}}]
+latcores = [{{data.latcores}}]
+
+[TestM2]
+name = Dummy
+prox_launch_exit = false
+prox_socket = false
+
+[test1]
+test=TST009test
+warmupflowsize=128
+warmupimix=[64]
+warmupspeed=1
+warmuptime=2
+#imixs=[[64],[128],[256],[512],[1024],[1280],[1512]]
+imixs=[{{data.pktsizes}}]
+flows=[1]
+drop_rate_threshold = 0
+MAXr = 3
+MAXz = 5000
+MAXFramesPerSecondAllIngress = 12000000
+StepSize = 10000