Ejemplo n.º 1
0
def capture_packets(params, tag='src', src_tag=None):
    if tag == 'src':
        port_info = src_info
    elif tag == 'dst':
        port_info = dst_info
    else:
        error('tag has to be one of [src, dst]!')
        return

    # XXX TODO
    # If src_tag and dst_tag are the same, then we need to monitor on just
    # br-int. Else, we will need to monitor on qr- ports (router ports)

    port_info['pids'] = []
    for port in port_info['ports'].keys():
        intf = port_info['ports'][port]
        filename = '%s.tcpdump.%s.txt' % (tag, intf)
        if os.path.isfile(filename):
            os.remove(filename)
        cmd = 'sudo tcpdump -v icmp -i %s -c %d -l > %s 2>&1' % (
            intf, params['count'], filename)
        pid = subprocess.Popen(cmd, shell=True).pid
        port_info['pids'].append(pid)
        status_update('%s: tcpdump launched with pid %d for interface %s' %
                      (tag, pid, intf))
Ejemplo n.º 2
0
def process_captures(tag='src'):
    if tag == 'src':
        port_info = src_info
    elif tag == 'dst':
        port_info = dst_info
    else:
        error('tag has to be one of [src, dst]!')
        return

    port_info['counts'] = {}
    port_info['pass'] = []
    port_info['fail'] = []
    for key in port_info['ports'].keys():
        intf = port_info['ports'][key]

        # Assume tcpdump did not capture anything
        port_info['counts'][key] = 0
        port_info['fail'].append(intf)
        filename = '%s.tcpdump.%s.txt' % (tag, intf)

        if not os.path.isfile(filename):
            continue

        with open(filename) as f:
            lines = f.readlines()
        for line in lines:
            m = re.search('(\d+)\s+packets captured', line)
            if m:
                port_info['counts'][key] = int(m.group(1))
                port_info['pass'].append(intf)
                break
Ejemplo n.º 3
0
def ovs_ofctl_show_br_parser(bridge, parse_this):
    bridge_dict = info['bridges']
    if not bridge_dict.has_key(bridge):
        common.error('Skipping bridge [' + bridge + ']! Supported bridges: ' +
                     str(bridge_dict.keys()))
        return
    bridge_entry = bridge_dict.get(bridge)
    pprint.pprint(bridge_entry)

    for line in parse_this:
        m = re.search('(\d+)\((\S+)\):\s+addr:(\S+)', line)
        if m:
            port_id = m.group(1)
            port = m.group(2)
            port_mac = m.group(3)
            if not bridge_entry['ports'].has_key(port):
                bridge_entry['ports'][port] = {}
            port_entry = bridge_entry['ports'][port]
            port_entry['id'] = port_id
            port_entry['mac'] = port_mac
            continue

        m = re.search('(\w+)\((\S+)\):\s+addr:(\S+)', line)
        if m:
            port_id = m.group(1)
            port = m.group(2)
            port_mac = m.group(3)
            if not bridge_entry['ports'].has_key(port):
                bridge_entry['ports'][port] = {}
            port_entry = bridge_entry['ports'][port]
            port_entry['id'] = port_id
            port_entry['mac'] = port_mac
Ejemplo n.º 4
0
def record_linuxbridge(bridges, bridge, interface_list):
    """Add given bridge and its interfaces to the bridges dictionary.

    The bridge is coming from brctl command.

    :param bridge: the name of the bridge.
    :param interface_list: the interfaces of the bridge.
    """
    if bridges.has_key(bridge):
        common.error('Bridge ' + bridge + ' repeated! Overwriting!')
    bridges[bridge] = {'interfaces': interface_list}
Ejemplo n.º 5
0
def add_new_command(cmds, cmd_key, cmd):
    """Add given command to the commands dictionary.

    :param cmds: the commands dictionary.
    :param cmd_key: the key of the dictionary where to add the command.
    :param cmd: the dictionary of the command.
    """
    if cmds.has_key(cmd_key):
        common.error(cmd_key + ' already exists in command dictionary')
    else:
        cmds[cmd_key] = cmd
Ejemplo n.º 6
0
def get_bridge_entry(bridge):
    """Returns given bridge dictionary.

    :param bridge: the name of the bridge.
    """
    bridges = info['bridges']
    if not bridges.has_key(bridge):
        common.error('Bridge ' + bridge +
                     ' does not exist! Supported bridges: ' +
                     str(bridges.keys()))
        return None
    else:
        return bridges.get(bridge)
Ejemplo n.º 7
0
def ovs_vsctl_show_parser(parse_this):
    bridge = None
    bridge_dict = info['bridges']
    for line in parse_this:
        m = re.search('Bridge\s+(br-\S+)', line)
        if m:
            bridge = str(m.group(1))
            if not bridge_dict.has_key(bridge):
                common.error('Skipping bridge [' + bridge +
                             ']! Supported bridges: ' +
                             str(bridge_dict.keys()))
                bridge = None
                continue
            bridge_entry = bridge_dict.get(bridge)
        if bridge:
            m = re.search('fail_mode: (\S+)', line)
            if m:
                bridge_entry['fail_mode'] = m.group(1)
                continue
            m = re.search('Port (\S+)', line)
            if m:
                # the port names seem to have double quotes around them!
                port = m.group(1).replace('"', '')
                if not bridge_entry['ports'].has_key(port):
                    bridge_entry['ports'][port] = {}
                port_entry = bridge_entry['ports'][port]
                continue
            m = re.search('tag: (\d+)', line)
            if m:
                port_entry['tag'] = m.group(1)
                continue
            m = re.search('Interface (\S+)', line)
            if m:
                # the interface names seem to have double quotes around them!
                interface = m.group(1).replace('"', '')
                if not port_entry.has_key('interfaces'):
                    port_entry['interfaces'] = {}
                port_entry['interfaces'][interface] = {}
                interface_entry = port_entry['interfaces'][interface]
                continue
            m = re.search('type: (\S+)', line)
            if m:
                interface_entry['type'] = m.group(1)
                continue
            m = re.search('options: {(\S+)}', line)
            if m:
                options = m.group(1)
                interface_entry['options'] = options
                continue
Ejemplo n.º 8
0
def path(params):
    global src_info
    global dst_info
    global net_info

    src_info = None
    dst_info = None
    net_info = None

    settings['debug'] = True
    BASE_DIR = os.path.dirname(os.path.dirname(__file__))
    CUR_DIR = os.getcwd()
    if not re.search('/openstack_dashboard/don/', CUR_DIR):
        os.chdir(BASE_DIR + '/ovs')
    NEW_DIR = os.getcwd()
    debug(BASE_DIR + ':' + CUR_DIR + ':' + NEW_DIR)

    src_ip = params['src_ip']
    dst_ip = params['dst_ip']
    json_file = params['json_file']
    router = params['router']

    debug('Json_file: ' + json_file)

    info = load_json(json_file)
    qrouter = router_to_namespace(info, router)
    params['qrouter'] = qrouter

    src_info = get_port_info(info, src_ip)
    dst_info = get_port_info(info, dst_ip)

    if src_info is None:
        return "Source ip not found on the network"
    if dst_info is None:
        return "Destination ip not found on the network"
    if qrouter is None:
        return "No such router information found on the network"

    # src and dst are in the same network
    if src_info['tag'] == dst_info['tag']:
        path_same_network(params)
    else:
        status_update('The source and destination are in different networks')
        next_hop_list = get_next_hop(src_info, dst_info, qrouter, params)
        if len(next_hop_list) == 0:
            error('Could not find next hop list from %s to %s' %
                  (src_ip, dst_ip))
        path_same_network(params, next_hop_list)
Ejemplo n.º 9
0
def qrouter_usable(qrouter, src_ip, dst_ip, username, passwd):
    status_update('Testing whether %s is reachable via qrouter %s (dst %s)' %
                  (src_ip, qrouter, dst_ip))
    outfile = 'path.testping.txt'
    ping_process = launch_ping(src_ip, dst_ip, username, passwd, 2, 2, qrouter,
                               outfile)
    status_update("Ping process %s" % (ping_process))
    time.sleep(5)

    ping_pass = process_ping(outfile, src_ip, check_ssh_connectivity_only=True)

    if ping_pass:
        status_update('IP %s is reachable via qrouter: %s' % (src_ip, qrouter))
        return True
    else:
        error('IP %s is reachable via qrouter: %s' % (src_ip, qrouter))

    return False
Ejemplo n.º 10
0
def get_port_info(info, port_ip):
    port_info = None
    for tap, ip in info['tap_to_ip'].iteritems():
        if ip == port_ip:
            port_info = {}
            port_info['ip'] = ip
            port_info['ports'] = {}
            port_info['ports']['tap'] = 'tap' + tap
            port_info['ports']['brctl'] = 'qbr' + tap
            port_info['ports']['qvb'] = 'qvb' + tap
            port_info['ports']['qvo'] = 'qvo' + tap

            # also get the tag (used later to figure out where to run tcpdump)
            br_int = info['bridges'].get('br-int', None)
            if not br_int:
                error('No OVS integration bridge (br-int)! Cannot proceed')
                return None

            tag = br_int['ports'][port_info['ports']['qvo']]['tag']
            port_info['tag'] = tag

            break
    return port_info
Ejemplo n.º 11
0
def path_same_network(params, nms_hops=None):
    src_ip = params['src_ip']
    dst_ip = params['dst_ip']
    json_file = params['json_file']
    username = params['username']
    passwd = params['passwd']
    count = params['count']
    timeout = params['timeout']
    qrouter = params['qrouter']
    router = params['router']

    if qrouter_usable(qrouter, src_ip, dst_ip, username, passwd):
        outfile = 'path.ping.txt'
        ping_process = launch_ping(src_ip, dst_ip, username, passwd, count,
                                   timeout, qrouter, outfile)
        debug('Ping started with pid: %d' % ping_process.pid)

        capture_packets(params, 'src')
        capture_packets(params, 'dst', src_tag=src_info['tag'])
        if src_info['tag'] != dst_info['tag']:
            capture_network_packets(params, nms_hops)

        status_update(
            'Waiting %s sec for tcpdump and ping processes to complete' %
            (params['count'] + 2))
        time.sleep(params['count'] + 4)

        status_update('if processes have not stopped, lets kill them')
        cleanup_processes([ping_process.pid] + src_info['pids'] +
                          dst_info['pids'])
        if net_info:
            cleanup_processes(net_info['pids'])

        process_captures('src')
        process_captures('dst')
        if src_info['tag'] != dst_info['tag']:
            process_network_captures()
        ping_pass = process_ping(outfile)

        debug(pprint.pformat(src_info))
        debug(pprint.pformat(dst_info))
        debug(pprint.pformat(net_info))
        info = {
            'src': src_ip,
            'dst': dst_ip,
            'src_info': src_info,
            'dst_info': dst_info,
            'net_info': net_info,
            'ping_pass': ping_pass,
            'error': '',
        }

        status_update('Dumping results into %s in JSON format' %
                      params['path_file'])
        dump_json(info, params['path_file'])

        if params['plot']:
            cmd = 'python plot.py --info_file %s --highlight_file %s --combined_file static/ping' % (
                json_file, params['path_file'])
            status_update('Running ' + cmd)
            output = execute_cmd(cmd, shell=True).split('\n')
            debug(pprint.pformat(output))
        status_update('Done')
    else:
        err_msg = 'Cannot reach %s via router %s' % (src_ip, router)
        info = {
            'src': src_ip,
            'dst': dst_ip,
            'src_info': src_info,
            'dst_info': dst_info,
            'ping_pass': False,
            'error': err_msg
        }
        error(err_msg)
        status_update('Dumping results into %s in JSON format' %
                      params['path_file'])
        dump_json(info, params['path_file'])
        status_update('Done')