1 # Copyright (c) 2016-2017 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_config_element_by_flow_group_name(self, flow_group_name):
125 """Get a config element using the flow group name
127 Each named flow group contains one config element (by configuration).
128 According to the documentation, "configElements" is a list and "each
129 item in this list is aligned to the sequential order of your endpoint
132 :param flow_group_name: (str) flow group name; this parameter is
133 always a number (converted to string) starting
135 :return: (str) config element reference ID or None.
137 traffic_item = self.ixnet.getList(self.ixnet.getRoot() + '/traffic',
139 flow_groups = self.ixnet.getList(traffic_item, 'endpointSet')
140 for flow_group in flow_groups:
141 if (str(self.ixnet.getAttribute(flow_group, '-name')) ==
143 return traffic_item + '/configElement:' + flow_group_name
145 def _get_stack_item(self, flow_group_name, protocol_name):
146 """Return the stack item given the flow group name and the proto name
148 :param flow_group_name: (str) flow group name
149 :param protocol_name: (str) protocol name, referred to PROTO_*
151 :return: list of stack item descriptors
153 celement = self._get_config_element_by_flow_group_name(flow_group_name)
155 raise exceptions.IxNetworkFlowNotPresent(
156 flow_group=flow_group_name)
157 stack_items = self.ixnet.getList(celement, 'stack')
158 return [s_i for s_i in stack_items if protocol_name in s_i]
160 def _get_field_in_stack_item(self, stack_item, field_name):
161 """Return the field in a stack item given the name
163 :param stack_item: (str) stack item descriptor
164 :param field_name: (str) field name
165 :return: (str) field descriptor
167 fields = self.ixnet.getList(stack_item, 'field')
168 for field in (field for field in fields if field_name in field):
170 raise exceptions.IxNetworkFieldNotPresentInStackItem(
171 field_name=field_name, stack_item=stack_item)
173 def _get_traffic_state(self):
174 """Get traffic state"""
175 return self.ixnet.getAttribute(self.ixnet.getRoot() + 'traffic',
178 def is_traffic_running(self):
179 """Returns true if traffic state == TRAFFIC_STATUS_STARTED"""
180 return self._get_traffic_state() == TRAFFIC_STATUS_STARTED
182 def is_traffic_stopped(self):
183 """Returns true if traffic state == TRAFFIC_STATUS_STOPPED"""
184 return self._get_traffic_state() == TRAFFIC_STATUS_STOPPED
187 def _parse_framesize(framesize):
188 """Parse "framesize" config param. to return a list of weighted pairs
190 :param framesize: dictionary of frame sizes and weights
191 :return: list of paired frame sizes and weights
193 weighted_range_pairs = []
194 for size, weight in ((s, w) for (s, w) in framesize.items()
196 size = int(size.upper().replace('B', ''))
197 weighted_range_pairs.append([size, size, int(weight)])
198 return weighted_range_pairs
200 def iter_over_get_lists(self, x1, x2, y2, offset=0):
201 for x in self.ixnet.getList(x1, x2):
202 y_list = self.ixnet.getList(x, y2)
203 for i, y in enumerate(y_list, offset):
206 def connect(self, tg_cfg):
207 self._cfg = self.get_config(tg_cfg)
208 self._ixnet = IxNetwork.IxNet()
210 machine = self._cfg['machine']
211 port = str(self._cfg['port'])
212 version = str(self._cfg['version'])
213 return self.ixnet.connect(machine, '-port', port,
216 def clear_config(self):
217 """Wipe out any possible configuration present in the client"""
218 self.ixnet.execute('newConfig')
220 def assign_ports(self):
221 """Create and assign vports for each physical port defined in config
223 This configuration is present in the IXIA profile file. E.g.:
228 vpci: "2:15" # Card:port
231 local_ip: "152.16.100.20"
232 netmask: "255.255.0.0"
233 local_mac: "00:98:10:64:14:00"
237 chassis_ip = self._cfg['chassis']
238 ports = [(chassis_ip, card, port) for card, port in
239 zip(self._cfg['cards'], self._cfg['ports'])]
241 log.info('Create and assign vports: %s', ports)
245 vports.append(self.ixnet.add(self.ixnet.getRoot(), 'vport'))
248 self.ixnet.execute('assignPorts', ports, [], vports, True)
252 if self.ixnet.getAttribute(vport, '-state') != 'up':
253 log.warning('Port %s is down', vport)
255 def _create_traffic_item(self):
256 """Create the traffic item to hold the flow groups
258 The traffic item tracking by "Traffic Item" is enabled to retrieve the
261 log.info('Create the traffic item "RFC2544"')
262 traffic_item = self.ixnet.add(self.ixnet.getRoot() + '/traffic',
264 self.ixnet.setMultiAttribute(traffic_item, '-name', 'RFC2544',
265 '-trafficType', 'raw')
268 traffic_item_id = self.ixnet.remapIds(traffic_item)[0]
269 self.ixnet.setAttribute(traffic_item_id + '/tracking',
270 '-trackBy', 'trafficGroupId0')
273 def _create_flow_groups(self):
274 """Create the flow groups between the assigned ports"""
275 traffic_item_id = self.ixnet.getList(self.ixnet.getRoot() + 'traffic',
277 log.info('Create the flow groups')
278 vports = self.ixnet.getList(self.ixnet.getRoot(), 'vport')
279 uplink_ports = vports[::2]
280 downlink_ports = vports[1::2]
282 for up, down in zip(uplink_ports, downlink_ports):
283 log.info('FGs: %s <--> %s', up, down)
284 endpoint_set_1 = self.ixnet.add(traffic_item_id, 'endpointSet')
285 endpoint_set_2 = self.ixnet.add(traffic_item_id, 'endpointSet')
286 self.ixnet.setMultiAttribute(
287 endpoint_set_1, '-name', str(index + 1),
288 '-sources', [up + '/protocols'],
289 '-destinations', [down + '/protocols'])
290 self.ixnet.setMultiAttribute(
291 endpoint_set_2, '-name', str(index + 2),
292 '-sources', [down + '/protocols'],
293 '-destinations', [up + '/protocols'])
297 def _append_procotol_to_stack(self, protocol_name, previous_element):
298 """Append a new element in the packet definition stack"""
299 protocol = (self.ixnet.getRoot() +
300 '/traffic/protocolTemplate:"{}"'.format(protocol_name))
301 self.ixnet.execute('append', previous_element, protocol)
303 def _setup_config_elements(self):
304 """Setup the config elements
306 The traffic item is configured to allow individual configurations per
307 config element. The default frame configuration is applied:
308 Ethernet II: added by default
311 Payload: added by default
312 Ethernet II (Trailer): added by default
315 traffic_item_id = self.ixnet.getList(self.ixnet.getRoot() + 'traffic',
317 log.info('Split the frame rate distribution per config element')
318 config_elements = self.ixnet.getList(traffic_item_id, 'configElement')
319 for config_element in config_elements:
320 self.ixnet.setAttribute(config_element + '/frameRateDistribution',
321 '-portDistribution', 'splitRateEvenly')
322 self.ixnet.setAttribute(config_element + '/frameRateDistribution',
323 '-streamDistribution', 'splitRateEvenly')
325 self._append_procotol_to_stack(
326 PROTO_UDP, config_element + '/stack:"ethernet-1"')
327 self._append_procotol_to_stack(
328 PROTO_IPV4, config_element + '/stack:"ethernet-1"')
330 def create_traffic_model(self):
331 """Create a traffic item and the needed flow groups
333 Each flow group inside the traffic item (only one is present)
334 represents the traffic between two ports:
336 FlowGroup1: port1 -> port2
337 FlowGroup2: port1 <- port2
338 FlowGroup3: port3 -> port4
339 FlowGroup4: port3 <- port4
341 self._create_traffic_item()
342 self._create_flow_groups()
343 self._setup_config_elements()
345 def _update_frame_mac(self, ethernet_descriptor, field, mac_address):
346 """Set the MAC address in a config element stack Ethernet field
348 :param ethernet_descriptor: (str) ethernet descriptor, e.g.:
349 /traffic/trafficItem:1/configElement:1/stack:"ethernet-1"
350 :param field: (str) field name, e.g.: destinationAddress
351 :param mac_address: (str) MAC address
353 field_descriptor = self._get_field_in_stack_item(ethernet_descriptor,
355 self.ixnet.setMultiAttribute(field_descriptor,
356 '-singleValue', mac_address,
357 '-fieldValue', mac_address,
358 '-valueType', 'singleValue')
361 def update_frame(self, traffic, duration):
362 """Update the L2 frame
364 This function updates the L2 frame options:
365 - Traffic type: "continuous", "fixedDuration".
366 - Duration: in case of traffic_type="fixedDuration", amount of seconds
368 - Rate: in frames per seconds or percentage.
369 - Type of rate: "framesPerSecond" or "percentLineRate" ("bitsPerSecond"
371 - Frame size: custom IMIX [1] definition; a list of packet size in
372 bytes and the weight. E.g.:
373 [[64, 64, 10], [128, 128, 15], [512, 512, 5]]
375 [1] https://en.wikipedia.org/wiki/Internet_Mix
377 :param traffic: list of traffic elements; each traffic element contains
378 the injection parameter for each flow group.
379 :param duration: (int) injection time in seconds.
381 for traffic_param in traffic.values():
382 fg_id = str(traffic_param['id'])
383 config_element = self._get_config_element_by_flow_group_name(fg_id)
384 if not config_element:
385 raise exceptions.IxNetworkFlowNotPresent(flow_group=fg_id)
387 type = traffic_param.get('traffic_type', 'fixedDuration')
388 rate = traffic_param['rate']
390 'framesPerSecond' if traffic_param['rate_unit'] ==
391 tp_base.TrafficProfileConfig.RATE_FPS else 'percentLineRate')
392 weighted_range_pairs = self._parse_framesize(
393 traffic_param['outer_l2']['framesize'])
394 srcmac = str(traffic_param['outer_l2'].get('srcmac', '00:00:00:00:00:01'))
395 dstmac = str(traffic_param['outer_l2'].get('dstmac', '00:00:00:00:00:02'))
397 if traffic_param['outer_l2']['QinQ']:
398 s_vlan = traffic_param['outer_l2']['QinQ']['S-VLAN']
399 c_vlan = traffic_param['outer_l2']['QinQ']['C-VLAN']
401 field_descriptor = self._get_field_in_stack_item(
402 self._get_stack_item(fg_id, PROTO_ETHERNET)[0],
405 self.ixnet.setMultiAttribute(field_descriptor,
407 '-singleValue', ETHER_TYPE_802_1ad,
408 '-fieldValue', ETHER_TYPE_802_1ad,
409 '-valueType', SINGLE_VALUE)
411 self._append_procotol_to_stack(
412 PROTO_VLAN, config_element + '/stack:"ethernet-1"')
413 self._append_procotol_to_stack(
414 PROTO_VLAN, config_element + '/stack:"ethernet-1"')
416 self._update_vlan_tag(fg_id, s_vlan, S_VLAN)
417 self._update_vlan_tag(fg_id, c_vlan, C_VLAN)
419 self.ixnet.setMultiAttribute(
420 config_element + '/transmissionControl',
421 '-type', type, '-duration', duration)
422 self.ixnet.setMultiAttribute(
423 config_element + '/frameRate',
424 '-rate', rate, '-type', rate_unit)
425 self.ixnet.setMultiAttribute(
426 config_element + '/frameSize',
427 '-type', 'weightedPairs',
428 '-weightedRangePairs', weighted_range_pairs)
431 self._update_frame_mac(
432 self._get_stack_item(fg_id, PROTO_ETHERNET)[0],
433 'destinationAddress', dstmac)
434 self._update_frame_mac(
435 self._get_stack_item(fg_id, PROTO_ETHERNET)[0],
436 'sourceAddress', srcmac)
438 def _update_vlan_tag(self, fg_id, params, vlan=0):
439 field_to_param_map = {
440 'vlanUserPriority': 'priority',
444 for field, param in field_to_param_map.items():
445 value = params.get(param)
447 field_descriptor = self._get_field_in_stack_item(
448 self._get_stack_item(fg_id, PROTO_VLAN)[vlan],
451 self.ixnet.setMultiAttribute(field_descriptor,
453 '-singleValue', value,
454 '-fieldValue', value,
455 '-valueType', SINGLE_VALUE)
459 def _update_ipv4_address(self, ip_descriptor, field, ip_address, seed,
461 """Set the IPv4 address in a config element stack IP field
463 :param ip_descriptor: (str) IP descriptor, e.g.:
464 /traffic/trafficItem:1/configElement:1/stack:"ipv4-2"
465 :param field: (str) field name, e.g.: scrIp, dstIp
466 :param ip_address: (str) IP address
467 :param seed: (int) seed length
468 :param mask: (int) IP address mask length
469 :param count: (int) number of random IPs to generate
471 field_descriptor = self._get_field_in_stack_item(ip_descriptor,
473 random_mask = str(ipaddress.IPv4Address(
474 2**(ipaddress.IPV4LENGTH - mask) - 1).compressed)
475 self.ixnet.setMultiAttribute(field_descriptor,
477 '-fixedBits', ip_address,
478 '-randomMask', random_mask,
479 '-valueType', 'random',
480 '-countValue', count)
483 def update_ip_packet(self, traffic):
484 """Update the IP packet
486 NOTE: Only IPv4 is currently supported.
487 :param traffic: list of traffic elements; each traffic element contains
488 the injection parameter for each flow group.
490 # NOTE(ralonsoh): L4 configuration is not set.
491 for traffic_param in traffic.values():
492 fg_id = str(traffic_param['id'])
493 if not self._get_config_element_by_flow_group_name(fg_id):
494 raise exceptions.IxNetworkFlowNotPresent(flow_group=fg_id)
496 count = traffic_param['outer_l3']['count']
497 srcip = str(traffic_param['outer_l3']['srcip'])
498 dstip = str(traffic_param['outer_l3']['dstip'])
499 srcseed = traffic_param['outer_l3']['srcseed']
500 dstseed = traffic_param['outer_l3']['dstseed']
501 srcmask = traffic_param['outer_l3']['srcmask'] or IP_VERSION_4_MASK
502 dstmask = traffic_param['outer_l3']['dstmask'] or IP_VERSION_4_MASK
504 self._update_ipv4_address(
505 self._get_stack_item(fg_id, PROTO_IPV4)[0],
506 'srcIp', srcip, srcseed, srcmask, count)
507 self._update_ipv4_address(
508 self._get_stack_item(fg_id, PROTO_IPV4)[0],
509 'dstIp', dstip, dstseed, dstmask, count)
511 def update_l4(self, traffic):
512 """Update the L4 headers
514 NOTE: Only UDP is currently supported
515 :param traffic: list of traffic elements; each traffic element contains
516 the injection parameter for each flow group
518 for traffic_param in traffic.values():
519 fg_id = str(traffic_param['id'])
520 if not self._get_config_element_by_flow_group_name(fg_id):
521 raise exceptions.IxNetworkFlowNotPresent(flow_group=fg_id)
523 proto = traffic_param['outer_l3']['proto']
524 if proto not in SUPPORTED_PROTO:
525 raise exceptions.IXIAUnsupportedProtocol(protocol=proto)
527 count = traffic_param['outer_l4']['count']
528 seed = traffic_param['outer_l4']['seed']
530 srcport = traffic_param['outer_l4']['srcport']
531 srcmask = traffic_param['outer_l4']['srcportmask']
533 dstport = traffic_param['outer_l4']['dstport']
534 dstmask = traffic_param['outer_l4']['dstportmask']
536 if proto in SUPPORTED_PROTO:
537 self._update_udp_port(self._get_stack_item(fg_id, proto)[0],
538 'srcPort', srcport, seed, srcmask, count)
540 self._update_udp_port(self._get_stack_item(fg_id, proto)[0],
541 'dstPort', dstport, seed, dstmask, count)
543 def _update_udp_port(self, descriptor, field, value,
544 seed=1, mask=0, count=1):
545 """Set the UDP port in a config element stack UDP field
547 :param udp_descriptor: (str) UDP descriptor, e.g.:
548 /traffic/trafficItem:1/configElement:1/stack:"udp-3"
549 :param field: (str) field name, e.g.: scrPort, dstPort
550 :param value: (int) UDP port fixed bits
551 :param seed: (int) seed length
552 :param mask: (int) UDP port mask
553 :param count: (int) number of random ports to generate
555 field_descriptor = self._get_field_in_stack_item(descriptor, field)
560 self.ixnet.setMultiAttribute(field_descriptor,
565 '-valueType', 'random',
566 '-countValue', count)
570 def _build_stats_map(self, view_obj, name_map):
571 return {data_yardstick: self.ixnet.execute(
572 'getColumnValues', view_obj, data_ixia)
573 for data_yardstick, data_ixia in name_map.items()}
575 def get_statistics(self):
576 """Retrieve port and flow statistics
578 "Port Statistics" parameters are stored in self.PORT_STATS_NAME_MAP.
579 "Flow Statistics" parameters are stored in self.LATENCY_NAME_MAP.
581 :return: dictionary with the statistics; the keys of this dictionary
582 are PORT_STATS_NAME_MAP and LATENCY_NAME_MAP keys.
584 port_statistics = '::ixNet::OBJ-/statistics/view:"Port Statistics"'
585 flow_statistics = '::ixNet::OBJ-/statistics/view:"Flow Statistics"'
586 stats = self._build_stats_map(port_statistics,
587 self.PORT_STATS_NAME_MAP)
588 stats.update(self._build_stats_map(flow_statistics,
589 self.LATENCY_NAME_MAP))
592 def start_traffic(self):
593 """Start the traffic injection in the traffic item
595 By configuration, there is only one traffic item. This function returns
596 when the traffic state is TRAFFIC_STATUS_STARTED.
598 traffic_items = self.ixnet.getList('/traffic', 'trafficItem')
599 if self.is_traffic_running():
600 self.ixnet.execute('stop', '/traffic')
601 # pylint: disable=unnecessary-lambda
602 utils.wait_until_true(lambda: self.is_traffic_stopped())
604 self.ixnet.execute('generate', traffic_items)
605 self.ixnet.execute('apply', '/traffic')
606 self.ixnet.execute('start', '/traffic')
607 # pylint: disable=unnecessary-lambda
608 utils.wait_until_true(lambda: self.is_traffic_running())
610 def add_topology(self, name, vports):
611 log.debug("add_topology: name='%s' ports='%s'", name, vports)
612 obj = self.ixnet.add(self.ixnet.getRoot(), 'topology')
613 self.ixnet.setMultiAttribute(obj, '-name', name, '-vports', vports)
617 def add_device_group(self, topology, name, multiplier):
618 log.debug("add_device_group: tpl='%s', name='%s', multiplier='%s'",
619 topology, name, multiplier)
621 obj = self.ixnet.add(topology, 'deviceGroup')
622 self.ixnet.setMultiAttribute(obj, '-name', name, '-multiplier',
627 def add_ethernet(self, dev_group, name):
629 "add_ethernet: device_group='%s' name='%s'", dev_group, name)
630 obj = self.ixnet.add(dev_group, 'ethernet')
631 self.ixnet.setMultiAttribute(obj, '-name', name)
635 def _create_vlans(self, ethernet, count):
636 self.ixnet.setMultiAttribute(ethernet, '-useVlans', 'true')
637 self.ixnet.setMultiAttribute(ethernet, '-vlanCount', count)
640 def _configure_vlans(self, ethernet, vlans):
641 vlans_obj = self.ixnet.getList(ethernet, 'vlan')
642 for i, vlan_obj in enumerate(vlans_obj):
643 if vlans[i].vlan_id_step is not None:
644 vlan_id_obj = self.ixnet.getAttribute(vlan_obj, '-vlanId')
645 self.ixnet.setMultiAttribute(vlan_id_obj, '-clearOverlays',
646 'true', '-pattern', 'counter')
647 vlan_id_counter = self.ixnet.add(vlan_id_obj, 'counter')
648 self.ixnet.setMultiAttribute(vlan_id_counter, '-start',
649 vlans[i].vlan_id, '-step',
650 vlans[i].vlan_id_step,
652 vlans[i].vlan_id_direction)
654 vlan_id_obj = self.ixnet.getAttribute(vlan_obj, '-vlanId')
655 self.ixnet.setMultiAttribute(vlan_id_obj + '/singleValue',
656 '-value', vlans[i].vlan_id)
658 if vlans[i].prio_step is not None:
659 prio_obj = self.ixnet.getAttribute(vlan_obj, '-priority')
660 self.ixnet.setMultiAttribute(prio_obj, '-clearOverlays', 'true',
661 '-pattern', 'counter')
662 prio_counter = self.ixnet.add(prio_obj, 'counter')
663 self.ixnet.setMultiAttribute(prio_counter,
664 '-start', vlans[i].prio,
665 '-step', vlans[i].prio_step,
666 '-direction', vlans[i].prio_direction)
667 elif vlans[i].prio is not None:
668 prio_obj = self.ixnet.getAttribute(vlan_obj, '-priority')
669 self.ixnet.setMultiAttribute(prio_obj + '/singleValue',
670 '-value', vlans[i].prio)
672 if vlans[i].tp_id is not None:
673 tp_id_obj = self.ixnet.getAttribute(vlan_obj, '-tpid')
674 self.ixnet.setMultiAttribute(tp_id_obj + '/singleValue',
675 '-value', vlans[i].tp_id)
679 def add_vlans(self, ethernet, vlans):
680 log.debug("add_vlans: ethernet='%s'", ethernet)
682 if vlans is None or len(vlans) == 0:
684 "Invalid 'vlans' argument. Expected list of Vlan instances.")
686 self._create_vlans(ethernet, len(vlans))
687 self._configure_vlans(ethernet, vlans)
689 def add_ipv4(self, ethernet, name='',
690 addr=None, addr_step=None, addr_direction='increment',
691 prefix=None, prefix_step=None, prefix_direction='increment',
692 gateway=None, gw_step=None, gw_direction='increment'):
693 log.debug("add_ipv4: ethernet='%s' name='%s'", ethernet, name)
694 obj = self.ixnet.add(ethernet, 'ipv4')
696 self.ixnet.setAttribute(obj, '-name', name)
699 if addr_step is not None:
700 # handle counter pattern
701 _address = self.ixnet.getAttribute(obj, '-address')
702 self.ixnet.setMultiAttribute(_address, '-clearOverlays', 'true',
703 '-pattern', 'counter')
705 address_counter = self.ixnet.add(_address, 'counter')
706 self.ixnet.setMultiAttribute(address_counter,
709 '-direction', addr_direction)
710 elif addr is not None:
711 # handle single value
712 _address = self.ixnet.getAttribute(obj, '-address')
713 self.ixnet.setMultiAttribute(_address + '/singleValue', '-value',
716 if prefix_step is not None:
717 # handle counter pattern
718 _prefix = self.ixnet.getAttribute(obj, '-prefix')
719 self.ixnet.setMultiAttribute(_prefix, '-clearOverlays', 'true',
720 '-pattern', 'counter')
721 prefix_counter = self.ixnet.add(_prefix, 'counter')
722 self.ixnet.setMultiAttribute(prefix_counter,
724 '-step', prefix_step,
725 '-direction', prefix_direction)
726 elif prefix is not None:
727 # handle single value
728 _prefix = self.ixnet.getAttribute(obj, '-prefix')
729 self.ixnet.setMultiAttribute(_prefix + '/singleValue', '-value',
732 if gw_step is not None:
733 # handle counter pattern
734 _gateway = self.ixnet.getAttribute(obj, '-gatewayIp')
735 self.ixnet.setMultiAttribute(_gateway, '-clearOverlays', 'true',
736 '-pattern', 'counter')
738 gateway_counter = self.ixnet.add(_gateway, 'counter')
739 self.ixnet.setMultiAttribute(gateway_counter,
742 '-direction', gw_direction)
743 elif gateway is not None:
744 # handle single value
745 _gateway = self.ixnet.getAttribute(obj, '-gatewayIp')
746 self.ixnet.setMultiAttribute(_gateway + '/singleValue', '-value',
752 def add_pppox_client(self, xproto, auth, user, pwd):
754 "add_pppox_client: xproto='%s', auth='%s', user='%s', pwd='%s'",
755 xproto, auth, user, pwd)
756 obj = self.ixnet.add(xproto, 'pppoxclient')
760 auth_type = self.ixnet.getAttribute(obj, '-authType')
761 self.ixnet.setMultiAttribute(auth_type + '/singleValue', '-value',
763 pap_user = self.ixnet.getAttribute(obj, '-papUser')
764 self.ixnet.setMultiAttribute(pap_user + '/singleValue', '-value',
766 pap_pwd = self.ixnet.getAttribute(obj, '-papPassword')
767 self.ixnet.setMultiAttribute(pap_pwd + '/singleValue', '-value',
770 raise NotImplementedError()