def do_create_ap(self, port_list, count, verbose_level, ap_cert, ap_privkey, ap_ca_priv):
        '''Create AP(s) on port'''
        if count < 1:
            raise TRexError('Count should be greated than zero')
        if not port_list:
            raise TRexError('Please specify TRex ports where to add AP(s)')

        bu_mac, bu_ip, _ = self.ap_manager._gen_ap_params()
        init_ports = [port for port in port_list if port not in self.ap_manager.service_ctx]
        ap_names = []
        success = False
        try:
            self.ap_manager.init(init_ports) # implicitly for console
            for port in port_list:
                for _ in range(count):
                    ap_params = self.ap_manager._gen_ap_params()
                    self.ap_manager.create_ap(port, *ap_params, verbose_level = verbose_level, rsa_ca_priv_file = ap_ca_priv, rsa_priv_file = ap_privkey, rsa_cert_file = ap_cert)
                    ap_names.append(ap_params[0])
            assert ap_names
            self.ap_manager.join_aps(ap_names)
            success = True
        finally:
            if not success:
                for name in ap_names: # rollback
                    self.ap_manager.remove_ap(name)
                self.ap_manager.set_base_values(mac = bu_mac, ip = bu_ip)
                close_ports = [port for port in init_ports if port in self.ap_manager.service_ctx]
                if close_ports:
                    self.ap_manager.close(close_ports)
Пример #2
0
    def do_add_client(self, ap_ids, count):
        '''Add client(s) to AP(s)'''
        if count < 1 or count > 200:
            raise TRexError('Count of clients should be within range 1-200')
        ap_ids = ap_ids or self.ap_manager.aps

        bu_mac, bu_ip = self.ap_manager._gen_client_params()
        client_ips = []
        success = False
        try:
            for ap_id in ap_ids:
                for _ in range(count):
                    client_params = self.ap_manager._gen_client_params()
                    self.ap_manager.create_client(
                        *client_params,
                        ap_id=self.ap_manager._get_ap_by_id(ap_id))
                    client_ips.append(client_params[1])
            self.ap_manager.join_clients(client_ips)
            success = True
        finally:
            if not success:
                for ip in client_ips:  # rollback
                    self.ap_manager.remove_client(ip)
                self.ap_manager.set_base_values(client_mac=bu_mac,
                                                client_ip=bu_ip)
Пример #3
0
    def do_start(self, client_ids, file_path, multiplier, tunables,
                 total_mult):
        '''Start traffic on behalf on client(s).'''
        if not client_ids:
            clients = self.ap_manager.clients
        else:
            clients = set(
                [self.ap_manager._get_client_by_id(id) for id in client_ids])
            if len(client_ids) != len(clients):
                raise TRexError('Client IDs should be unique')
        if not clients:
            raise TRexError('No clients to start traffic on behalf of them!')
        ports = list(set([client.ap.port_id for client in clients]))

        # stop ports if needed
        active_ports = list_intersect(self.trex_client.get_active_ports(),
                                      ports)
        if active_ports:
            self.trex_client.stop(active_ports)

        # remove all streams
        self.trex_client.remove_all_streams(ports)

        # pack the profile
        try:
            tunables = tunables or {}
            for client in clients:
                profile = STLProfile.load(file_path,
                                          direction=tunables.get(
                                              'direction',
                                              client.ap.port_id % 2),
                                          port_id=client.ap.port_id,
                                          **tunables)

                self.ap_manager.add_streams(client, profile.get_streams())

        except STLError as e:
            msg = bold("\nError loading profile '%s'" % file_path)
            self.ap_manager.log(msg + '\n')
            self.ap_manager.log(e.brief() + "\n")

        self.trex_client.start(ports=ports,
                               mult=multiplier,
                               force=True,
                               total=total_mult)

        return RC_OK()
Пример #4
0
    def plugin_unload(self):
        if self.console is None:
            raise TRexError(
                "Trex console must be provided in order to unload emu plugin")

        self.console.unload_client_plugin_functions(
            func_prefix=Emu_Plugin.EMU_PREFIX)
        self.c.disconnect()
Пример #5
0
    def plugin_load(self):
        if self.console is None:
            raise TRexError(
                'Trex console must be provided in order to load emu plugin')

        c = self.console.client
        c_mode = c.get_mode()
        if c_mode != "ASTF":
            raise TRexError(
                'TRex client mode must be ASTF, current client mode: %s' %
                c_mode)

        if not hasattr(self.console, 'emu_client'):
            raise TRexError(
                'Cannot find trex emu client in console, load emu plugin first'
            )

        self.emu_c = self.console.emu_client
        self.astf_c = c
Пример #6
0
 def do_reconnect(self, device_ids):
     '''Reconnect disconnected AP(s) or Client(s).'''
     device_ids = device_ids or ([a.name for a in self.ap_manager.aps] +
                                 [c.ip for c in self.ap_manager.clients])
     ports = set()
     aps = set()
     clients = set()
     err_ids = set()
     for device_id in device_ids:
         try:
             ap = self.ap_manager._get_ap_by_id(device_id)
             aps.add(ap)
             clients |= set(ap.clients)
             ports.add(ap.port_id)
         except:
             try:
                 client = self.ap_manager._get_client_by_id(device_id)
                 clients.add(client)
                 aps.add(client.ap)
                 ports.add(client.ap.port_id)
             except:
                 err_ids.add(device_id)
     if err_ids:
         raise TRexError('Invalid IDs: %s' %
                         ', '.join(sorted(err_ids, key=natural_sorted_key)))
     if not self.ap_manager.bg_client.is_connected():
         self.ap_manager.bg_client.connect()
     for port_id in ports:
         if port_id in self.ap_manager.service_ctx:
             if not self.ap_manager.service_ctx[port_id]['bg'].is_running():
                 self.ap_manager.service_ctx[port_id]['bg'].run()
     non_init_ports = [
         p for p in ports if p not in self.ap_manager.service_ctx
     ]
     not_joined_aps = [
         a for a in aps if not (a.is_connected and a.is_dtls_established)
     ]
     not_assoc_clients = [
         c for c in clients if not (c.is_associated and c.seen_arp_reply)
     ]
     if not (non_init_ports or not_joined_aps or not_assoc_clients):
         self.ap_manager.log(
             bold('Nothing to reconnect, everything works fine.'))
         return
     while non_init_ports:
         self.ap_manager.init(non_init_ports[:10])
         non_init_ports = non_init_ports[10:]
     while not_joined_aps:
         self.ap_manager.join_aps(not_joined_aps[:10])
         not_joined_aps = not_joined_aps[10:]
     while not_assoc_clients:
         self.ap_manager.join_clients(not_assoc_clients[:20])
         not_assoc_clients = not_assoc_clients[20:]
Пример #7
0
    def plugin_load(self):

        if self.console is None:
            raise TRexError(
                "Trex console must be provided in order to load emu plugin")

        client = self.console.client
        verbose = client.logger.get_verbose()

        # taking parameters from original
        self.c = EMUClient(server=self.console.emu_server,
                           verbose_level=verbose,
                           logger=client.logger)
        self.c.connect()

        self.console.load_client_plugin_functions(
            self.c, func_prefix=Emu_Plugin.EMU_PREFIX)
Пример #8
0
    def do_proxy(self, proxy_wired_port, proxy_wireless_port, proxy_dest_mac,
                 proxy_filter_wlc_packets, proxy_disable, proxy_clear):
        '''Proxify traffic between wireless side (Stateful TRex) and wired side (WLC).'''
        if proxy_clear:
            self.ap_manager.disable_proxy_mode(ignore_errors=True)
        elif any([proxy_wired_port, proxy_wireless_port]):
            if proxy_wired_port is None:
                raise TRexError('Must specify wired port')
            if proxy_wireless_port is None:
                raise TRexError('Must specify wireless port')
            if proxy_disable:
                self.ap_manager.disable_proxy_mode(
                    ports=[proxy_wired_port, proxy_wireless_port])
            else:
                if proxy_wireless_port not in self.trex_client.ports:
                    raise TRexError('Invalid wireless port ID: %s' %
                                    proxy_wireless_port)
                port = self.trex_client.ports[proxy_wireless_port]
                if not port.is_service_mode_on():
                    port.set_service_mode(True)
                self.ap_manager.enable_proxy_mode(proxy_wired_port,
                                                  proxy_wireless_port,
                                                  proxy_dest_mac,
                                                  proxy_filter_wlc_packets)
        else:
            counters_dict = {
                'BPF reject': 'm_bpf_rejected',
                'IP convert ERR': 'm_ip_convert_err',
                'Map not found': 'm_map_not_found',
                'Not IP pkt': 'm_not_ip',
                'Pkt too large': 'm_too_large_pkt',
                'Pkt too small': 'm_too_small_pkt',
                'Pkts from WLC': 'm_pkt_from_wlc',
                'TX ERR': 'm_tx_err',
                'TX OK': 'm_tx_ok',
            }

            proxy_table = text_tables.Texttable(max_width=200)
            categories = ['Port', 'Counters', 'Clients']
            proxy_table.header([bold(c) for c in categories])
            proxy_table.set_cols_align(['l'] * len(categories))
            proxy_table.set_deco(15)
            for port_id in sorted(self.trex_client.get_acquired_ports()):
                data = self.ap_manager.get_proxy_stats(
                    ports=[port_id], decode_map=False)[port_id]
                if not data or not data['is_active']:
                    continue
                row = [
                    'ID: %s\n(%s)\nPair: %s' %
                    (port_id, 'WLAN' if data['is_wireless_side'] else 'LAN',
                     data['pair_port_id'])
                ]

                counters_table = text_tables.Texttable()
                counters_table.set_deco(0)
                counters_table.set_cols_dtype(['t', 'i'])
                counters_table.set_cols_align(['l'] * 2)
                for k in sorted(counters_dict.keys()):
                    val = data['counters'][counters_dict[k]]
                    if val:
                        counters_table.add_row(['%s:' % k, val])
                row.append(counters_table.draw())

                clients = ''
                clients_arr = sorted(data['capwap_map'].keys(),
                                     key=natural_sorted_key)
                if len(clients_arr) > 1:
                    first_ip_num = ipv4_str_to_num(
                        is_valid_ipv4_ret(clients_arr[0]))
                    last_ip_num = ipv4_str_to_num(
                        is_valid_ipv4_ret(clients_arr[-1]))
                    if first_ip_num == last_ip_num - len(
                            clients_arr) + 1:  # continuous range of IPs
                        clients = 'From %s to %s' % (clients_arr[0],
                                                     clients_arr[-1])
                    else:
                        while True:
                            clients_row = [
                                '%15s' % ip for ip in clients_arr[0:5]
                            ]
                            if not clients_row:
                                break
                            clients += ', '.join(clients_row) + '\n'
                            clients_arr = clients_arr[5:]
                else:
                    clients = clients_arr[0]
                row.append(clients)

                proxy_table.add_row(row)
            self.ap_manager.log(proxy_table.draw())
Пример #9
0
    def do_sync_topo(self):
        '''
        Sync astf topology with current Emu server data.
        Requires resolved dgw mac address and ipv4 and ipv6 dgw resolved macs must not be different.
        '''
        emu_c, astf_c = self.emu_c, self.astf_c

        emu_topo = ASTFTopology()
        emu_ns_and_c = emu_c.get_all_ns_and_clients()
        empty_ip_val = ''

        for ns in emu_ns_and_c:
            # take only clients ns
            if ns['vport'] % 2:
                continue

            port = str(ns['vport'])
            vlans = filter(lambda x: x != 0, ns.get('tci', []))
            if len(vlans) > 1:
                raise TRexError(
                    'Cannot convert topo when namespace has more than 1 vlan')
            elif len(vlans) == 1:
                vlan = vlans[0]
            else:
                vlan = 0

            for c_i, c in enumerate(ns.get('clients', []), start=1):
                port_id = '%s.%s' % (port, c_i)
                src_mac = c['mac']  # mac is mandatory for client
                src_ipv4 = c.get('ipv4', empty_ip_val)
                src_ipv6 = c.get('ipv6', empty_ip_val)

                if src_ipv4 == '0.0.0.0' or src_ipv4 == empty_ip_val:
                    raise TRexError(
                        'Cannot sync: node with mac: "%s" has no ipv4 address'
                        % src_mac)

                if c.get('dgw') and c['dgw'].get('resolve'):
                    ipv4_dst = c['dgw'].get('rmac')
                else:
                    ipv4_dst = None

                if c.get('ipv6_dgw') and c['ipv6_dgw'].get('resolve'):
                    ipv6_dst = c['ipv6_dgw'].get('rmac')
                else:
                    ipv6_dst = None

                if ipv4_dst is None and ipv6_dst is None:
                    raise TRexError(
                        'Cannot sync: node with mac: "%s" has no resolved default gateway mac address'
                        % src_mac)

                if ipv4_dst is not None and ipv6_dst is not None and ipv4_dst != ipv6_dst:
                    raise TRexError(
                        'Cannot sync: node with mac: "%s" has different resolved default gateway mac address for ipv4 and ipv6'
                        % src_mac)

                emu_topo.add_vif(port_id=port_id,
                                 src_mac=src_mac,
                                 src_ipv4=src_ipv4,
                                 src_ipv6=src_ipv6,
                                 vlan=vlan)
                emu_topo.add_gw(
                    port_id=port_id,
                    src_start=src_ipv4,
                    src_end=src_ipv4,
                    dst=ipv4_dst if ipv4_dst is not None else ipv6_dst)

        astf_c.topo_clear()
        astf_c.topo_load(emu_topo)
        astf_c.topo_resolve()

        astf_c.logger.info(format_text("emu topo synced\n", 'green', 'bold'))
Пример #10
0
 def do_proxy(self, proxy_wired_port, proxy_wireless_port, proxy_disable,
              proxy_clear):
     '''Proxify traffic between wireless side (Stateful TRex) and wired side (WLC).'''
     if proxy_clear:
         self.ap_manager.disable_proxy_mode(ignore_errors=True)
     elif any([proxy_wired_port, proxy_wireless_port]):
         if proxy_wired_port is None:
             raise TRexError('Must specify wired port')
         if proxy_wireless_port is None:
             raise TRexError('Must specify wireless port')
         if proxy_disable:
             self.ap_manager.disable_proxy_mode(
                 ports=[proxy_wired_port, proxy_wireless_port])
         else:
             assert proxy_wireless_port in self.trex_client.ports, 'Invalid wireless port ID: %s' % proxy_wireless_port
             port = self.trex_client.ports[proxy_wireless_port]
             if not port.is_service_mode_on():
                 port.set_service_mode(True)
             self.ap_manager.enable_proxy_mode(
                 wired_port=proxy_wired_port,
                 wireless_port=proxy_wireless_port)
     else:
         counters_dict = {
             'BPF reject': 'm_bpf_rejected',
             'IP convert err': 'm_ip_convert_err',
             'Alloc error': 'm_map_alloc_err',
             'Map not found': 'm_map_not_found',
             'Not IP pkt': 'm_not_ip',
             'Pkt too large': 'm_too_large_pkt',
             'Pkt too small': 'm_too_small_pkt',
             'TX err': 'm_tx_err',
             'TX OK': 'm_tx_ok',
         }
         proxy_table = text_tables.Texttable(max_width=200)
         categories = ['Port', 'Counters', 'Wrapping map per client']
         proxy_table.header([bold(c) for c in categories])
         proxy_table.set_cols_align(['l'] * len(categories))
         proxy_table.set_deco(15)
         for port_id in sorted(self.trex_client.get_acquired_ports()):
             data = self.ap_manager.get_proxy_stats(
                 ports=[port_id], decode_map=True)[port_id]
             if not data or not data['is_active']:
                 continue
             row = [
                 'ID: %s\n(%s)\nPair: %s' %
                 (port_id, 'WLAN' if data['is_wireless_side'] else 'LAN',
                  data['pair_port_id'])
             ]
             counters_table = text_tables.Texttable()
             counters_table.set_deco(0)
             counters_table.set_cols_dtype(['t', 'i'])
             counters_table.set_cols_align(['l'] * 2)
             for k in sorted(counters_dict.keys()):
                 val = data['counters'][counters_dict[k]]
                 if not val:
                     continue
                 counters_table.add_row(['%s:' % k, val])
             row.append(counters_table.draw())
             mappings = []
             for client_ip in sorted(list(data['capwap_map'].keys()),
                                     key=natural_sorted_key):
                 pkt_cmd = data['capwap_map'][client_ip]
                 if len(pkt_cmd) > 100:
                     pkt_cmd = pkt_cmd[:97] + '...'
                 mappings.append('%s: %s' % (client_ip, pkt_cmd))
             row.append('\n'.join(mappings))
             proxy_table.add_row(row)
         self.ap_manager.log(proxy_table.draw())
Пример #11
0
 def _call_method(self, method_name, method_params):
     rc = self.rpc.transmit(method_name=method_name, params=method_params)
     if not rc:
         raise TRexError(rc.err())
     return rc.data()
Пример #12
0
 def err(name, val, reason):
     raise TRexError('Validation error, argument "{name}" with value "{val}"\nReason: {reason}'.format(name=name,
                                                                                                         val=val,
                                                                                                         reason=reason))