1 # Copyright (c) 2016-2018 Intel Corporation
3 # Licensed under the Apache License, Version 2.0 (the "License");
4 # you may not use this file except in compliance with the License.
5 # You may obtain a copy of the License at
7 # http://www.apache.org/licenses/LICENSE-2.0
9 # Unless required by applicable law or agreed to in writing, software
10 # distributed under the License is distributed on an "AS IS" BASIS,
11 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 # See the License for the specific language governing permissions and
13 # limitations under the License.
20 from yardstick.common import exceptions
21 from yardstick.common import utils
22 from yardstick.network_services.traffic_profile import base as tp_base
25 log = logging.getLogger(__name__)
30 PROTO_ETHERNET = 'ethernet'
37 SINGLE_VALUE = "singleValue"
42 ETHER_TYPE_802_1ad = '0x88a8'
44 IP_VERSION_4_MASK = 24
45 IP_VERSION_6_MASK = 64
47 TRAFFIC_STATUS_STARTED = 'started'
48 TRAFFIC_STATUS_STOPPED = 'stopped'
50 SUPPORTED_PROTO = [PROTO_UDP]
55 vlan_id, vlan_id_step=None, vlan_id_direction='increment',
56 prio=None, prio_step=None, prio_direction='increment',
58 self.vlan_id = vlan_id
59 self.vlan_id_step = vlan_id_step
60 self.vlan_id_direction = vlan_id_direction
62 self.prio_step = prio_step
63 self.prio_direction = prio_direction
67 # NOTE(ralonsoh): this pragma will be removed in the last patch of this series
68 class IxNextgen(object): # pragma: no cover
70 PORT_STATS_NAME_MAP = {
71 "stat_name": 'Stat Name',
72 "Frames_Tx": 'Frames Tx.',
73 "Valid_Frames_Rx": 'Valid Frames Rx.',
74 "Frames_Tx_Rate": 'Frames Tx. Rate',
75 "Valid_Frames_Rx_Rate": 'Valid Frames Rx. Rate',
76 "Tx_Rate_Kbps": 'Tx. Rate (Kbps)',
77 "Rx_Rate_Kbps": 'Rx. Rate (Kbps)',
78 "Tx_Rate_Mbps": 'Tx. Rate (Mbps)',
79 "Rx_Rate_Mbps": 'Rx. Rate (Mbps)',
83 "Store-Forward_Avg_latency_ns": 'Store-Forward Avg Latency (ns)',
84 "Store-Forward_Min_latency_ns": 'Store-Forward Min Latency (ns)',
85 "Store-Forward_Max_latency_ns": 'Store-Forward Max Latency (ns)',
89 def get_config(tg_cfg):
92 external_interface = tg_cfg["vdu"][0]["external-interface"]
93 for intf in external_interface:
94 card_port0 = intf["virtual-interface"]["vpci"]
95 card0, port0 = card_port0.split(':')[:2]
100 'machine': tg_cfg["mgmt-interface"]["ip"],
101 'port': tg_cfg["mgmt-interface"]["tg-config"]["tcl_port"],
102 'chassis': tg_cfg["mgmt-interface"]["tg-config"]["ixchassis"],
105 'output_dir': tg_cfg["mgmt-interface"]["tg-config"]["dut_result_dir"],
106 'version': tg_cfg["mgmt-interface"]["tg-config"]["version"],
112 def __init__(self): # pragma: no cover
119 def ixnet(self): # pragma: no cover
122 raise exceptions.IxNetworkClientNotConnected()
124 def get_vports(self):
125 """Return the list of assigned ports (vport objects)"""
126 vports = self.ixnet.getList(self.ixnet.getRoot(), 'vport')
129 def _get_config_element_by_flow_group_name(self, flow_group_name):
130 """Get a config element using the flow group name
132 Each named flow group contains one config element (by configuration).
133 According to the documentation, "configElements" is a list and "each
134 item in this list is aligned to the sequential order of your endpoint
137 :param flow_group_name: (str) flow group name; this parameter is
138 always a number (converted to string) starting
140 :return: (str) config element reference ID or None.
142 traffic_item = self.ixnet.getList(self.ixnet.getRoot() + '/traffic',
144 flow_groups = self.ixnet.getList(traffic_item, 'endpointSet')
145 for flow_group in flow_groups:
146 if (str(self.ixnet.getAttribute(flow_group, '-name')) ==
148 return traffic_item + '/configElement:' + flow_group_name
150 def _get_stack_item(self, flow_group_name, protocol_name):
151 """Return the stack item given the flow group name and the proto name
153 :param flow_group_name: (str) flow group name
154 :param protocol_name: (str) protocol name, referred to PROTO_*
156 :return: list of stack item descriptors
158 celement = self._get_config_element_by_flow_group_name(flow_group_name)
160 raise exceptions.IxNetworkFlowNotPresent(
161 flow_group=flow_group_name)
162 stack_items = self.ixnet.getList(celement, 'stack')
163 return [s_i for s_i in stack_items if protocol_name in s_i]
165 def _get_field_in_stack_item(self, stack_item, field_name):
166 """Return the field in a stack item given the name
168 :param stack_item: (str) stack item descriptor
169 :param field_name: (str) field name
170 :return: (str) field descriptor
172 fields = self.ixnet.getList(stack_item, 'field')
173 for field in (field for field in fields if field_name in field):
175 raise exceptions.IxNetworkFieldNotPresentInStackItem(
176 field_name=field_name, stack_item=stack_item)
178 def _get_traffic_state(self):
179 """Get traffic state"""
180 return self.ixnet.getAttribute(self.ixnet.getRoot() + 'traffic',
183 def is_traffic_running(self):
184 """Returns true if traffic state == TRAFFIC_STATUS_STARTED"""
185 return self._get_traffic_state() == TRAFFIC_STATUS_STARTED
187 def is_traffic_stopped(self):
188 """Returns true if traffic state == TRAFFIC_STATUS_STOPPED"""
189 return self._get_traffic_state() == TRAFFIC_STATUS_STOPPED
192 def _parse_framesize(framesize):
193 """Parse "framesize" config param. to return a list of weighted pairs
195 :param framesize: dictionary of frame sizes and weights
196 :return: list of paired frame sizes and weights
198 weighted_range_pairs = []
199 for size, weight in ((s, w) for (s, w) in framesize.items()
201 size = int(size.upper().replace('B', ''))
202 weighted_range_pairs.append([size, size, int(weight)])
203 return weighted_range_pairs
205 def iter_over_get_lists(self, x1, x2, y2, offset=0):
206 for x in self.ixnet.getList(x1, x2):
207 y_list = self.ixnet.getList(x, y2)
208 for i, y in enumerate(y_list, offset):
211 def connect(self, tg_cfg):
212 self._cfg = self.get_config(tg_cfg)
213 self._ixnet = IxNetwork.IxNet()
215 machine = self._cfg['machine']
216 port = str(self._cfg['port'])
217 version = str(self._cfg['version'])
218 return self.ixnet.connect(machine, '-port', port,
221 def clear_config(self):
222 """Wipe out any possible configuration present in the client"""
223 self.ixnet.execute('newConfig')
225 def assign_ports(self):
226 """Create and assign vports for each physical port defined in config
228 This configuration is present in the IXIA profile file. E.g.:
233 vpci: "2:15" # Card:port
236 local_ip: "152.16.100.20"
237 netmask: "255.255.0.0"
238 local_mac: "00:98:10:64:14:00"
242 chassis_ip = self._cfg['chassis']
243 ports = [(chassis_ip, card, port) for card, port in
244 zip(self._cfg['cards'], self._cfg['ports'])]
246 log.info('Create and assign vports: %s', ports)
250 vports.append(self.ixnet.add(self.ixnet.getRoot(), 'vport'))
253 self.ixnet.execute('assignPorts', ports, [], vports, True)
257 if self.ixnet.getAttribute(vport, '-state') != 'up':
258 log.warning('Port %s is down', vport)
260 def _create_traffic_item(self, traffic_type='raw'):
261 """Create the traffic item to hold the flow groups
263 The traffic item tracking by "Traffic Item" is enabled to retrieve the
266 log.info('Create the traffic item "RFC2544"')
267 traffic_item = self.ixnet.add(self.ixnet.getRoot() + '/traffic',
269 self.ixnet.setMultiAttribute(traffic_item, '-name', 'RFC2544',
270 '-trafficType', traffic_type)
273 traffic_item_id = self.ixnet.remapIds(traffic_item)[0]
274 self.ixnet.setAttribute(traffic_item_id + '/tracking',
275 '-trackBy', 'trafficGroupId0')
278 def _create_flow_groups(self, uplink, downlink):
279 """Create the flow groups between the endpoints"""
280 traffic_item_id = self.ixnet.getList(self.ixnet.getRoot() + 'traffic',
282 log.info('Create the flow groups')
285 for up, down in zip(uplink, downlink):
286 log.info('FGs: %s <--> %s', up, down)
287 endpoint_set_1 = self.ixnet.add(traffic_item_id, 'endpointSet')
288 endpoint_set_2 = self.ixnet.add(traffic_item_id, 'endpointSet')
289 self.ixnet.setMultiAttribute(
290 endpoint_set_1, '-name', str(index + 1),
292 '-destinations', [down])
293 self.ixnet.setMultiAttribute(
294 endpoint_set_2, '-name', str(index + 2),
296 '-destinations', [up])
300 def _append_procotol_to_stack(self, protocol_name, previous_element):
301 """Append a new element in the packet definition stack"""
302 protocol = (self.ixnet.getRoot() +
303 '/traffic/protocolTemplate:"{}"'.format(protocol_name))
304 self.ixnet.execute('append', previous_element, protocol)
306 def _setup_config_elements(self, add_default_proto=True):
307 """Setup the config elements
309 The traffic item is configured to allow individual configurations per
310 config element. The default frame configuration is applied:
311 Ethernet II: added by default
314 Payload: added by default
315 Ethernet II (Trailer): added by default
318 traffic_item_id = self.ixnet.getList(self.ixnet.getRoot() + 'traffic',
320 log.info('Split the frame rate distribution per config element')
321 config_elements = self.ixnet.getList(traffic_item_id, 'configElement')
322 for config_element in config_elements:
323 self.ixnet.setAttribute(config_element + '/frameRateDistribution',
324 '-portDistribution', 'splitRateEvenly')
325 self.ixnet.setAttribute(config_element + '/frameRateDistribution',
326 '-streamDistribution', 'splitRateEvenly')
328 if add_default_proto:
329 self._append_procotol_to_stack(
330 PROTO_UDP, config_element + '/stack:"ethernet-1"')
331 self._append_procotol_to_stack(
332 PROTO_IPV4, config_element + '/stack:"ethernet-1"')
334 def create_traffic_model(self, uplink_ports, downlink_ports):
335 """Create a traffic item and the needed flow groups
337 Each flow group inside the traffic item (only one is present)
338 represents the traffic between two ports:
340 FlowGroup1: port1 -> port2
341 FlowGroup2: port1 <- port2
342 FlowGroup3: port3 -> port4
343 FlowGroup4: port3 <- port4
345 self._create_traffic_item('raw')
346 uplink_endpoints = [port + '/protocols' for port in uplink_ports]
347 downlink_endpoints = [port + '/protocols' for port in downlink_ports]
348 self._create_flow_groups(uplink_endpoints, downlink_endpoints)
349 self._setup_config_elements()
351 def create_ipv4_traffic_model(self, uplink_topologies, downlink_topologies):
352 """Create a traffic item and the needed flow groups
354 Each flow group inside the traffic item (only one is present)
355 represents the traffic between two topologies:
357 FlowGroup1: uplink1 -> downlink1
358 FlowGroup2: uplink1 <- downlink1
359 FlowGroup3: uplink2 -> downlink2
360 FlowGroup4: uplink2 <- downlink2
362 self._create_traffic_item('ipv4')
363 self._create_flow_groups(uplink_topologies, downlink_topologies)
364 self._setup_config_elements(False)
366 def _update_frame_mac(self, ethernet_descriptor, field, mac_address):
367 """Set the MAC address in a config element stack Ethernet field
369 :param ethernet_descriptor: (str) ethernet descriptor, e.g.:
370 /traffic/trafficItem:1/configElement:1/stack:"ethernet-1"
371 :param field: (str) field name, e.g.: destinationAddress
372 :param mac_address: (str) MAC address
374 field_descriptor = self._get_field_in_stack_item(ethernet_descriptor,
376 self.ixnet.setMultiAttribute(field_descriptor,
377 '-singleValue', mac_address,
378 '-fieldValue', mac_address,
379 '-valueType', 'singleValue')
382 def update_frame(self, traffic, duration):
383 """Update the L2 frame
385 This function updates the L2 frame options:
386 - Traffic type: "continuous", "fixedDuration".
387 - Duration: in case of traffic_type="fixedDuration", amount of seconds
389 - Rate: in frames per seconds or percentage.
390 - Type of rate: "framesPerSecond" or "percentLineRate" ("bitsPerSecond"
392 - Frame size: custom IMIX [1] definition; a list of packet size in
393 bytes and the weight. E.g.:
394 [[64, 64, 10], [128, 128, 15], [512, 512, 5]]
396 [1] https://en.wikipedia.org/wiki/Internet_Mix
398 :param traffic: list of traffic elements; each traffic element contains
399 the injection parameter for each flow group.
400 :param duration: (int) injection time in seconds.
402 for traffic_param in traffic.values():
403 fg_id = str(traffic_param['id'])
404 config_element = self._get_config_element_by_flow_group_name(fg_id)
405 if not config_element:
406 raise exceptions.IxNetworkFlowNotPresent(flow_group=fg_id)
408 type = traffic_param.get('traffic_type', 'fixedDuration')
410 'framesPerSecond' if traffic_param['rate_unit'] ==
411 tp_base.TrafficProfileConfig.RATE_FPS else 'percentLineRate')
412 weighted_range_pairs = self._parse_framesize(
413 traffic_param['outer_l2'].get('framesize', {}))
414 srcmac = str(traffic_param['outer_l2'].get('srcmac', '00:00:00:00:00:01'))
415 dstmac = str(traffic_param['outer_l2'].get('dstmac', '00:00:00:00:00:02'))
417 if traffic_param['outer_l2'].get('QinQ'):
418 s_vlan = traffic_param['outer_l2']['QinQ']['S-VLAN']
419 c_vlan = traffic_param['outer_l2']['QinQ']['C-VLAN']
421 field_descriptor = self._get_field_in_stack_item(
422 self._get_stack_item(fg_id, PROTO_ETHERNET)[0],
425 self.ixnet.setMultiAttribute(field_descriptor,
427 '-singleValue', ETHER_TYPE_802_1ad,
428 '-fieldValue', ETHER_TYPE_802_1ad,
429 '-valueType', SINGLE_VALUE)
431 self._append_procotol_to_stack(
432 PROTO_VLAN, config_element + '/stack:"ethernet-1"')
433 self._append_procotol_to_stack(
434 PROTO_VLAN, config_element + '/stack:"ethernet-1"')
436 self._update_vlan_tag(fg_id, s_vlan, S_VLAN)
437 self._update_vlan_tag(fg_id, c_vlan, C_VLAN)
439 self.ixnet.setMultiAttribute(
440 config_element + '/transmissionControl',
441 '-type', type, '-duration', duration)
443 self.ixnet.setMultiAttribute(
444 config_element + '/frameRate',
445 '-rate', traffic_param['rate'], '-type', rate_unit)
447 if len(weighted_range_pairs):
448 self.ixnet.setMultiAttribute(
449 config_element + '/frameSize',
450 '-type', 'weightedPairs',
451 '-weightedRangePairs', weighted_range_pairs)
456 self._update_frame_mac(
457 self._get_stack_item(fg_id, PROTO_ETHERNET)[0],
458 'destinationAddress', dstmac)
460 self._update_frame_mac(
461 self._get_stack_item(fg_id, PROTO_ETHERNET)[0],
462 'sourceAddress', srcmac)
464 def _update_vlan_tag(self, fg_id, params, vlan=0):
465 field_to_param_map = {
466 'vlanUserPriority': 'priority',
470 for field, param in field_to_param_map.items():
471 value = params.get(param)
473 field_descriptor = self._get_field_in_stack_item(
474 self._get_stack_item(fg_id, PROTO_VLAN)[vlan],
477 self.ixnet.setMultiAttribute(field_descriptor,
479 '-singleValue', value,
480 '-fieldValue', value,
481 '-valueType', SINGLE_VALUE)
485 def _update_ipv4_address(self, ip_descriptor, field, ip_address, seed,
487 """Set the IPv4 address in a config element stack IP field
489 :param ip_descriptor: (str) IP descriptor, e.g.:
490 /traffic/trafficItem:1/configElement:1/stack:"ipv4-2"
491 :param field: (str) field name, e.g.: scrIp, dstIp
492 :param ip_address: (str) IP address
493 :param seed: (int) seed length
494 :param mask: (int) IP address mask length
495 :param count: (int) number of random IPs to generate
497 field_descriptor = self._get_field_in_stack_item(ip_descriptor,
499 random_mask = str(ipaddress.IPv4Address(
500 2**(ipaddress.IPV4LENGTH - mask) - 1).compressed)
501 self.ixnet.setMultiAttribute(field_descriptor,
503 '-fixedBits', ip_address,
504 '-randomMask', random_mask,
505 '-valueType', 'random',
506 '-countValue', count)
509 def update_ip_packet(self, traffic):
510 """Update the IP packet
512 NOTE: Only IPv4 is currently supported.
513 :param traffic: list of traffic elements; each traffic element contains
514 the injection parameter for each flow group.
516 # NOTE(ralonsoh): L4 configuration is not set.
517 for traffic_param in traffic.values():
518 fg_id = str(traffic_param['id'])
519 if not self._get_config_element_by_flow_group_name(fg_id):
520 raise exceptions.IxNetworkFlowNotPresent(flow_group=fg_id)
522 if traffic_param['outer_l3']:
523 count = traffic_param['outer_l3']['count']
524 srcip = traffic_param['outer_l3']['srcip']
525 dstip = traffic_param['outer_l3']['dstip']
526 srcseed = traffic_param['outer_l3']['srcseed']
527 dstseed = traffic_param['outer_l3']['dstseed']
528 srcmask = traffic_param['outer_l3']['srcmask'] \
530 dstmask = traffic_param['outer_l3']['dstmask'] \
533 self._update_ipv4_address(
534 self._get_stack_item(fg_id, PROTO_IPV4)[0],
535 'srcIp', str(srcip), srcseed, srcmask, count)
537 self._update_ipv4_address(
538 self._get_stack_item(fg_id, PROTO_IPV4)[0],
539 'dstIp', str(dstip), dstseed, dstmask, count)
541 def update_l4(self, traffic):
542 """Update the L4 headers
544 NOTE: Only UDP is currently supported
545 :param traffic: list of traffic elements; each traffic element contains
546 the injection parameter for each flow group
548 for traffic_param in traffic.values():
549 fg_id = str(traffic_param['id'])
550 if not self._get_config_element_by_flow_group_name(fg_id):
551 raise exceptions.IxNetworkFlowNotPresent(flow_group=fg_id)
553 proto = traffic_param['outer_l3'].get('proto')
554 if not (proto and traffic_param['outer_l4']):
557 if proto not in SUPPORTED_PROTO:
558 raise exceptions.IXIAUnsupportedProtocol(protocol=proto)
560 count = traffic_param['outer_l4']['count']
561 seed = traffic_param['outer_l4']['seed']
563 srcport = traffic_param['outer_l4']['srcport']
564 srcmask = traffic_param['outer_l4']['srcportmask']
566 dstport = traffic_param['outer_l4']['dstport']
567 dstmask = traffic_param['outer_l4']['dstportmask']
569 if proto == PROTO_UDP:
571 self._update_udp_port(
572 self._get_stack_item(fg_id, proto)[0],
573 'srcPort', srcport, seed, srcmask, count)
575 self._update_udp_port(
576 self._get_stack_item(fg_id, proto)[0],
577 'dstPort', dstport, seed, dstmask, count)
579 def _update_udp_port(self, descriptor, field, value,
580 seed=1, mask=0, count=1):
581 """Set the UDP port in a config element stack UDP field
583 :param udp_descriptor: (str) UDP descriptor, e.g.:
584 /traffic/trafficItem:1/configElement:1/stack:"udp-3"
585 :param field: (str) field name, e.g.: scrPort, dstPort
586 :param value: (int) UDP port fixed bits
587 :param seed: (int) seed length
588 :param mask: (int) UDP port mask
589 :param count: (int) number of random ports to generate
591 field_descriptor = self._get_field_in_stack_item(descriptor, field)
596 self.ixnet.setMultiAttribute(field_descriptor,
601 '-valueType', 'random',
602 '-countValue', count)
606 def _build_stats_map(self, view_obj, name_map):
607 return {data_yardstick: self.ixnet.execute(
608 'getColumnValues', view_obj, data_ixia)
609 for data_yardstick, data_ixia in name_map.items()}
611 def get_statistics(self):
612 """Retrieve port and flow statistics
614 "Port Statistics" parameters are stored in self.PORT_STATS_NAME_MAP.
615 "Flow Statistics" parameters are stored in self.LATENCY_NAME_MAP.
617 :return: dictionary with the statistics; the keys of this dictionary
618 are PORT_STATS_NAME_MAP and LATENCY_NAME_MAP keys.
620 port_statistics = '::ixNet::OBJ-/statistics/view:"Port Statistics"'
621 flow_statistics = '::ixNet::OBJ-/statistics/view:"Flow Statistics"'
622 stats = self._build_stats_map(port_statistics,
623 self.PORT_STATS_NAME_MAP)
624 stats.update(self._build_stats_map(flow_statistics,
625 self.LATENCY_NAME_MAP))
628 def start_protocols(self):
629 self.ixnet.execute('startAllProtocols')
631 def stop_protocols(self):
632 self.ixnet.execute('stopAllProtocols')
634 def start_traffic(self):
635 """Start the traffic injection in the traffic item
637 By configuration, there is only one traffic item. This function returns
638 when the traffic state is TRAFFIC_STATUS_STARTED.
640 traffic_items = self.ixnet.getList('/traffic', 'trafficItem')
641 if self.is_traffic_running():
642 self.ixnet.execute('stop', '/traffic')
643 # pylint: disable=unnecessary-lambda
644 utils.wait_until_true(lambda: self.is_traffic_stopped())
646 self.ixnet.execute('generate', traffic_items)
647 self.ixnet.execute('apply', '/traffic')
648 self.ixnet.execute('start', '/traffic')
649 # pylint: disable=unnecessary-lambda
650 utils.wait_until_true(lambda: self.is_traffic_running())
652 def add_topology(self, name, vports):
653 log.debug("add_topology: name='%s' ports='%s'", name, vports)
654 obj = self.ixnet.add(self.ixnet.getRoot(), 'topology')
655 self.ixnet.setMultiAttribute(obj, '-name', name, '-vports', vports)
659 def add_device_group(self, topology, name, multiplier):
660 log.debug("add_device_group: tpl='%s', name='%s', multiplier='%s'",
661 topology, name, multiplier)
663 obj = self.ixnet.add(topology, 'deviceGroup')
664 self.ixnet.setMultiAttribute(obj, '-name', name, '-multiplier',
669 def add_ethernet(self, dev_group, name):
671 "add_ethernet: device_group='%s' name='%s'", dev_group, name)
672 obj = self.ixnet.add(dev_group, 'ethernet')
673 self.ixnet.setMultiAttribute(obj, '-name', name)
677 def _create_vlans(self, ethernet, count):
678 self.ixnet.setMultiAttribute(ethernet, '-useVlans', 'true')
679 self.ixnet.setMultiAttribute(ethernet, '-vlanCount', count)
682 def _configure_vlans(self, ethernet, vlans):
683 vlans_obj = self.ixnet.getList(ethernet, 'vlan')
684 for i, vlan_obj in enumerate(vlans_obj):
685 if vlans[i].vlan_id_step is not None:
686 vlan_id_obj = self.ixnet.getAttribute(vlan_obj, '-vlanId')
687 self.ixnet.setMultiAttribute(vlan_id_obj, '-clearOverlays',
688 'true', '-pattern', 'counter')
689 vlan_id_counter = self.ixnet.add(vlan_id_obj, 'counter')
690 self.ixnet.setMultiAttribute(vlan_id_counter, '-start',
691 vlans[i].vlan_id, '-step',
692 vlans[i].vlan_id_step,
694 vlans[i].vlan_id_direction)
696 vlan_id_obj = self.ixnet.getAttribute(vlan_obj, '-vlanId')
697 self.ixnet.setMultiAttribute(vlan_id_obj + '/singleValue',
698 '-value', vlans[i].vlan_id)
700 if vlans[i].prio_step is not None:
701 prio_obj = self.ixnet.getAttribute(vlan_obj, '-priority')
702 self.ixnet.setMultiAttribute(prio_obj, '-clearOverlays', 'true',
703 '-pattern', 'counter')
704 prio_counter = self.ixnet.add(prio_obj, 'counter')
705 self.ixnet.setMultiAttribute(prio_counter,
706 '-start', vlans[i].prio,
707 '-step', vlans[i].prio_step,
708 '-direction', vlans[i].prio_direction)
709 elif vlans[i].prio is not None:
710 prio_obj = self.ixnet.getAttribute(vlan_obj, '-priority')
711 self.ixnet.setMultiAttribute(prio_obj + '/singleValue',
712 '-value', vlans[i].prio)
714 if vlans[i].tp_id is not None:
715 tp_id_obj = self.ixnet.getAttribute(vlan_obj, '-tpid')
716 self.ixnet.setMultiAttribute(tp_id_obj + '/singleValue',
717 '-value', vlans[i].tp_id)
721 def add_vlans(self, ethernet, vlans):
722 log.debug("add_vlans: ethernet='%s'", ethernet)
724 if vlans is None or len(vlans) == 0:
726 "Invalid 'vlans' argument. Expected list of Vlan instances.")
728 self._create_vlans(ethernet, len(vlans))
729 self._configure_vlans(ethernet, vlans)
731 def add_ipv4(self, ethernet, name='',
732 addr=None, addr_step=None, addr_direction='increment',
733 prefix=None, prefix_step=None, prefix_direction='increment',
734 gateway=None, gw_step=None, gw_direction='increment'):
735 log.debug("add_ipv4: ethernet='%s' name='%s'", ethernet, name)
736 obj = self.ixnet.add(ethernet, 'ipv4')
738 self.ixnet.setAttribute(obj, '-name', name)
741 if addr_step is not None:
742 # handle counter pattern
743 _address = self.ixnet.getAttribute(obj, '-address')
744 self.ixnet.setMultiAttribute(_address, '-clearOverlays', 'true',
745 '-pattern', 'counter')
747 address_counter = self.ixnet.add(_address, 'counter')
748 self.ixnet.setMultiAttribute(address_counter,
751 '-direction', addr_direction)
752 elif addr is not None:
753 # handle single value
754 _address = self.ixnet.getAttribute(obj, '-address')
755 self.ixnet.setMultiAttribute(_address + '/singleValue', '-value',
758 if prefix_step is not None:
759 # handle counter pattern
760 _prefix = self.ixnet.getAttribute(obj, '-prefix')
761 self.ixnet.setMultiAttribute(_prefix, '-clearOverlays', 'true',
762 '-pattern', 'counter')
763 prefix_counter = self.ixnet.add(_prefix, 'counter')
764 self.ixnet.setMultiAttribute(prefix_counter,
766 '-step', prefix_step,
767 '-direction', prefix_direction)
768 elif prefix is not None:
769 # handle single value
770 _prefix = self.ixnet.getAttribute(obj, '-prefix')
771 self.ixnet.setMultiAttribute(_prefix + '/singleValue', '-value',
774 if gw_step is not None:
775 # handle counter pattern
776 _gateway = self.ixnet.getAttribute(obj, '-gatewayIp')
777 self.ixnet.setMultiAttribute(_gateway, '-clearOverlays', 'true',
778 '-pattern', 'counter')
780 gateway_counter = self.ixnet.add(_gateway, 'counter')
781 self.ixnet.setMultiAttribute(gateway_counter,
784 '-direction', gw_direction)
785 elif gateway is not None:
786 # handle single value
787 _gateway = self.ixnet.getAttribute(obj, '-gatewayIp')
788 self.ixnet.setMultiAttribute(_gateway + '/singleValue', '-value',
794 def add_pppox_client(self, xproto, auth, user, pwd):
796 "add_pppox_client: xproto='%s', auth='%s', user='%s', pwd='%s'",
797 xproto, auth, user, pwd)
798 obj = self.ixnet.add(xproto, 'pppoxclient')
802 auth_type = self.ixnet.getAttribute(obj, '-authType')
803 self.ixnet.setMultiAttribute(auth_type + '/singleValue', '-value',
805 pap_user = self.ixnet.getAttribute(obj, '-papUser')
806 self.ixnet.setMultiAttribute(pap_user + '/singleValue', '-value',
808 pap_pwd = self.ixnet.getAttribute(obj, '-papPassword')
809 self.ixnet.setMultiAttribute(pap_pwd + '/singleValue', '-value',
812 raise NotImplementedError()
817 def add_bgp(self, ipv4, dut_ip, local_as, bgp_type=None):
818 """Add BGP protocol"""
819 log.debug("add_bgp: ipv4='%s', dut_ip='%s', local_as='%s'", ipv4,
821 obj = self.ixnet.add(ipv4, 'bgpIpv4Peer')
825 dut_ip_addr = self.ixnet.getAttribute(obj, '-dutIp')
826 self.ixnet.setAttribute(dut_ip_addr + '/singleValue',
829 # Set local AS number
830 local_as_number = self.ixnet.getAttribute(obj, '-localAs2Bytes')
831 self.ixnet.setAttribute(local_as_number + '/singleValue',
835 # Set BGP type. If not specified, default value is using.
836 # Default type is "internal"
837 bgp_type_field = self.ixnet.getAttribute(obj, '-type')
838 self.ixnet.setAttribute(bgp_type_field + '/singleValue',