import six
from six.moves.configparser import ConfigParser
-
-from yardstick.common.utils import ip_to_hex
+from yardstick.common import utils
LOG = logging.getLogger(__name__)
link {0} up
"""
-ACTION_TEMPLATE = """\
-p action add {0} accept
-p action add {0} fwd {0}
-p action add {0} count
-"""
-
-FW_ACTION_TEMPLATE = """\
-p action add {0} accept
-p action add {0} fwd {0}
-p action add {0} count
-p action add {0} conntrack
-"""
-
# This sets up a basic passthrough with no rules
SCRIPT_TPL = """
{link_config}
{arp_config6}
-{actions}
+{arp_route_tbl}
+
+{arp_route_tbl6}
-{rules}
+{flows}
"""
return parser.get(section, key)
return default
- @staticmethod
- def make_ip_addr(ip, mask):
- """
- :param ip: ip adddress
- :type ip: str
- :param mask: /24 prefix of 255.255.255.0 netmask
- :type mask: str
- :return: interface
- :rtype: IPv4Interface
- """
-
- try:
- return ipaddress.ip_interface(six.text_type('/'.join([ip, mask])))
- except (TypeError, ValueError):
- # None so we can skip later
- return None
-
@classmethod
def validate_ip_and_prefixlen(cls, ip_addr, prefixlen):
- ip_addr = cls.make_ip_addr(ip_addr, prefixlen)
+ ip_addr = utils.make_ip_addr(ip_addr, prefixlen)
return ip_addr.ip.exploded, ip_addr.network.prefixlen
def __init__(self, topology_file, config_tpl, tmp_file, vnfd_helper,
self.tmp_file = os.path.join("/tmp", tmp_file)
self.pktq_out_os = []
self.socket = socket
- self.start_core = ""
+ self.start_core = 1
self.pipeline_counter = ""
self.txrx_pipeline = ""
self._port_pairs = None
self.ports_len = 0
self.prv_que_handler = None
self.vnfd = None
- self.rules = None
+ self.flows = None
self.pktq_out = []
@staticmethod
def update_timer(self):
timer_tpl = self.get_config_tpl_data('TIMER')
- timer_tpl['core'] = self.gen_core(self.start_core)
+ timer_tpl['core'] = self.gen_core(0)
self.update_write_parser(timer_tpl)
- self.start_core += 1
def get_config_tpl_data(self, type_value):
for section in self.read_parser.sections():
def init_write_parser_template(self, type_value='ARPICMP'):
for section in self.read_parser.sections():
if type_value == self.parser_get(self.read_parser, section, 'type', object()):
- self.start_core = self.read_parser.getint(section, 'core')
self.pipeline_counter = self.read_parser.getint(section, 'core')
self.txrx_pipeline = self.read_parser.getint(section, 'core')
return
"".join(("{},".format(port_list.index(x)) for x in uplink_ports)))
def generate_arp_route_tbl(self):
- arp_route_tbl_tmpl = "({port0_dst_ip_hex},{port0_netmask_hex},{port_num}," \
- "{next_hop_ip_hex})"
+ arp_route_tbl_tmpl = "routeadd net {port_num} {port_dst_ip} 0x{port_netmask_hex}"
def build_arp_config(port):
dpdk_port_num = self.vnfd_helper.port_num(port)
interface = self.vnfd_helper.find_interface(name=port)["virtual-interface"]
# We must use the dst because we are on the VNF and we need to
# reach the TG.
- dst_port0_ip = ipaddress.ip_interface(six.text_type(
+ dst_port_ip = ipaddress.ip_interface(six.text_type(
"%s/%s" % (interface["dst_ip"], interface["netmask"])))
arp_vars = {
- "port0_dst_ip_hex": ip_to_hex(dst_port0_ip.network.network_address.exploded),
- "port0_netmask_hex": ip_to_hex(dst_port0_ip.network.netmask.exploded),
+ "port_netmask_hex": utils.ip_to_hex(dst_port_ip.network.netmask.exploded),
# this is the port num that contains port0 subnet and next_hop_ip_hex
# this is LINKID which should be based on DPDK port number
"port_num": dpdk_port_num,
# next hop is dst in this case
# must be within subnet
- "next_hop_ip_hex": ip_to_hex(dst_port0_ip.ip.exploded),
+ "port_dst_ip": str(dst_port_ip.ip),
}
return arp_route_tbl_tmpl.format(**arp_vars)
- return ' '.join(build_arp_config(port) for port in self.all_ports)
+ return '\n'.join(build_arp_config(port) for port in self.all_ports)
def generate_arpicmp_data(self):
swq_in_str = self.make_range_str('SWQ{}', self.swq, offset=self.lb_count)
self.port_pair_list)
arpicmp_data = {
- 'core': self.gen_core(self.start_core),
+ 'core': self.gen_core(0),
'pktq_in': swq_in_str,
'pktq_out': swq_out_str,
# we need to disable ports_mac_list?
# 'ports_mac_list': ' '.join(mac_iter),
'pktq_in_prv': ' '.join(pktq_in_iter),
'prv_to_pub_map': self.set_priv_to_pub_mapping(),
- 'arp_route_tbl': self.generate_arp_route_tbl(),
- # nd_route_tbl must be set or we get segault on random OpenStack IPv6 traffic
- # 'nd_route_tbl': "(0064:ff9b:0:0:0:0:9810:6414,120,0,0064:ff9b:0:0:0:0:9810:6414)"
- # safe default? route discard prefix to localhost
- 'nd_route_tbl': "(0100::,64,0,::1)"
}
self.pktq_out_os = swq_out_str.split(' ')
# HWLB is a run to complition. So override the pktq_in/pktq_out
return arpicmp_data
- def generate_final_txrx_data(self):
+ def generate_final_txrx_data(self, core=0):
swq_start = self.swq - self.ports_len * self.worker_threads
txq_start = 0
'pktq_in': swq_str,
'pktq_out': txq_str,
'pipeline_txrx_type': 'TXTX',
- 'core': self.gen_core(self.start_core),
+ 'core': self.gen_core(core),
}
pktq_in = rxtx_data['pktq_in']
pktq_in = '{0} {1}'.format(pktq_in, self.pktq_out_os[self.lb_index - 1])
'core': self.gen_core(self.start_core),
}
self.pipeline_counter += 1
- return txrx_data
+ return self.start_core, txrx_data
def generate_lb_data(self):
pktq_in = self.make_range_str('SWQ{}', self.swq, offset=self.ports_len)
self.arpicmp_tpl.update(arpicmp_data)
self.update_write_parser(self.arpicmp_tpl)
- self.start_core += 1
if self.vnf_type == 'CGNAPT':
self.pipeline_counter += 1
self.update_timer()
+ if self.lb_config == 'HW':
+ self.start_core = 1
+
for lb in self.lb_to_port_pair_mapping:
self.lb_index = lb
self.mul = 0
self.ports_len = port_pair_count * 2
self.set_priv_que_handler()
if self.lb_config == 'SW':
- txrx_data = self.generate_initial_txrx_data()
+ core, txrx_data = self.generate_initial_txrx_data()
self.txrx_tpl.update(txrx_data)
self.update_write_parser(self.txrx_tpl)
self.start_core += 1
self.update_write_parser(self.loadb_tpl)
self.start_core += 1
- for i in range(self.worker_threads):
+ for _ in range(self.worker_threads):
vnf_data = self.generate_vnf_data()
if not self.vnf_tpl:
self.vnf_tpl = {}
self.generate_next_core_id()
if self.lb_config == 'SW':
- txrx_data = self.generate_final_txrx_data()
+ txrx_data = self.generate_final_txrx_data(core)
self.txrx_tpl.update(txrx_data)
self.update_write_parser(self.txrx_tpl)
- self.start_core += 1
self.vnf_tpl = self.get_config_tpl_data(self.vnf_type)
def generate_config(self):
return '\n'.join(('p {3} arpadd {0} {1} {2}'.format(*values) for values in arp_config6))
- def generate_action_config(self):
- port_list = (self.vnfd_helper.port_num(p) for p in self.all_ports)
- if self.vnf_type == "VFW":
- template = FW_ACTION_TEMPLATE
- else:
- template = ACTION_TEMPLATE
-
- return ''.join((template.format(port) for port in port_list))
-
- def get_ip_from_port(self, port):
- # we can't use gateway because in OpenStack gateways interfer with floating ip routing
- # return self.make_ip_addr(self.get_ports_gateway(port), self.get_netmask_gateway(port))
- vintf = self.vnfd_helper.find_interface(name=port)["virtual-interface"]
- ip = vintf["local_ip"]
- netmask = vintf["netmask"]
- return self.make_ip_addr(ip, netmask)
-
- def get_network_and_prefixlen_from_ip_of_port(self, port):
- ip_addr = self.get_ip_from_port(port)
- # handle cases with no gateway
- if ip_addr:
- return ip_addr.network.network_address.exploded, ip_addr.network.prefixlen
- else:
- return None, None
-
- def generate_rule_config(self):
- cmd = 'acl' if self.vnf_type == "ACL" else "vfw"
- rules_config = self.rules if self.rules else ''
- new_rules = []
- new_ipv6_rules = []
- pattern = 'p {0} add {1} {2} {3} {4} {5} 0 65535 0 65535 0 0 {6}'
- for src_intf, dst_intf in self.port_pair_list:
- src_port = self.vnfd_helper.port_num(src_intf)
- dst_port = self.vnfd_helper.port_num(dst_intf)
-
- src_net, src_prefix_len = self.get_network_and_prefixlen_from_ip_of_port(src_intf)
- dst_net, dst_prefix_len = self.get_network_and_prefixlen_from_ip_of_port(dst_intf)
- # ignore entires with empty values
- if all((src_net, src_prefix_len, dst_net, dst_prefix_len)):
- new_rules.append((cmd, self.txrx_pipeline, src_net, src_prefix_len,
- dst_net, dst_prefix_len, dst_port))
- new_rules.append((cmd, self.txrx_pipeline, dst_net, dst_prefix_len,
- src_net, src_prefix_len, src_port))
-
- # src_net = self.get_ports_gateway6(port_pair[0])
- # src_prefix_len = self.get_netmask_gateway6(port_pair[0])
- # dst_net = self.get_ports_gateway6(port_pair[1])
- # dst_prefix_len = self.get_netmask_gateway6(port_pair[0])
- # # ignore entires with empty values
- # if all((src_net, src_prefix_len, dst_net, dst_prefix_len)):
- # new_ipv6_rules.append((cmd, self.txrx_pipeline, src_net, src_prefix_len,
- # dst_net, dst_prefix_len, dst_port))
- # new_ipv6_rules.append((cmd, self.txrx_pipeline, dst_net, dst_prefix_len,
- # src_net, src_prefix_len, src_port))
-
- acl_apply = "\np %s applyruleset" % cmd
- new_rules_config = '\n'.join(pattern.format(*values) for values
- in chain(new_rules, new_ipv6_rules))
- return ''.join([rules_config, new_rules_config, acl_apply])
+ def get_flows_config(self):
+ return self.flows if self.flows else ''
def generate_script_data(self):
self._port_pairs = PortPairs(self.vnfd_helper.interfaces)
# disable IPv6 for now
# 'arp_config6': self.generate_arp_config6(),
'arp_config6': "",
- 'actions': '',
- 'rules': '',
+ 'arp_route_tbl': self.generate_arp_route_tbl(),
+ 'arp_route_tbl6': "",
+ 'flows': self.get_flows_config()
}
-
- if self.vnf_type in ('ACL', 'VFW'):
- script_data.update({
- 'actions': self.generate_action_config(),
- 'rules': self.generate_rule_config(),
- })
-
return script_data
- def generate_script(self, vnfd, rules=None):
+ def generate_script(self, vnfd, flows=None):
self.vnfd = vnfd
- self.rules = rules
+ self.flows = flows
script_data = self.generate_script_data()
script = SCRIPT_TPL.format(**script_data)
if self.lb_config == self.HW_LB: