Esempio n. 1
0
def clear(remotes=default_remotes):
    check_access(remotes)

    for remote in remotes:
        exec(remote, 'ip -all netns delete || true')
        # removal of all l2tp tunnels - removes all sessions as well
        exec(
            remote,
            'ip l2tp show tunnel | grep Tunnel | tr "," " " | cut -d" " -f2 | xargs -r -n1 ip l2tp del tunnel tunnel_id'
        )
Esempio n. 2
0
def show(remotes=default_remotes):
    check_access(remotes)

    for remote_id, remote in enumerate(remotes):
        nodes = exec(remote, 'ip netns list', get_output=True)[0].count('ns-')
        veth = int(
            exec(remote,
                 'ip netns exec switch ip addr list | grep -c "@ve-" || true',
                 get_output=True)[0]) // 2
        l2tp = int(
            exec(remote,
                 'ip l2tp show session | grep -c "ve-" || true',
                 get_output=True)[0])
        label = remote.address or 'local'
        print(f'{label}: {nodes} nodes, {veth} veth links, {l2tp} l2tp links')
Esempio n. 3
0
def apply(state={},
          node_command=None,
          link_command=None,
          remotes=default_remotes):
    check_access(remotes)

    new_state = state
    (cur_state, cur_state_rmap) = get_current_state(remotes)

    # handle different new_state types
    if isinstance(new_state, str):
        if new_state == 'none':
            new_state = {}
        else:
            if not os.path.isfile(new_state):
                eprint(f'File not found: {new_state}')
                stop_all_terminals()
                exit(1)

            with open(new_state) as file:
                new_state = json.load(file)

    # map each node to a remote or local computer
    # distribute evenly with minimized interconnects
    rmap = _get_remote_mapping(cur_state, new_state, remotes, cur_state_rmap)
    data = _get_task(cur_state, new_state)

    beg_ms = millis()

    # add "switch" namespace
    if state_empty(cur_state):
        for remote in remotes:
            # add switch if it does not exist yet
            exec(remote, 'ip netns add "switch" || true')
            # disable IPv6 in switch namespace (no need, less overhead)
            exec(
                remote,
                'ip netns exec "switch" sysctl -q -w net.ipv6.conf.all.disable_ipv6=1'
            )

    for node in data.nodes_update:
        update_node(node, node_command, rmap)

    for link in data.links_update:
        update_link(link, link_command, rmap)

    for node in data.nodes_create:
        create_node(node, node_command, rmap)

    for link in data.links_create:
        create_link(link, link_command, rmap)

    for link in data.links_remove:
        remove_link(link, rmap)

    for node in data.nodes_remove:
        remove_node(node, rmap)

    # remove "switch" namespace
    if state_empty(new_state):
        for remote in remotes:
            exec(remote, 'ip netns del "switch" || true')

    # wait for tasks to complete
    wait_for_completion()
    end_ms = millis()

    if verbosity != 'quiet':
        print('Network setup in {}:'.format(format_duration(end_ms - beg_ms)))
        print(
            f'  nodes: {len(data.nodes_create)} created, {len(data.nodes_remove)} removed, {len(data.nodes_update)} updated'
        )
        print(
            f'  links: {len(data.links_create)} created, {len(data.links_remove)} removed, {len(data.links_update)} updated'
        )

    return new_state
Esempio n. 4
0
#!/usr/bin/env python3

import os
import sys
import glob

sys.path.append('../../')
from shared import Remote
import shared
import ping
import software
import network

remotes = [Remote()]  #[Remote('192.168.44.133'), Remote('192.168.44.137')]

shared.check_access(remotes)
software.clear(remotes)
network.clear(remotes)

prefix = os.environ.get('PREFIX', '')


# 100MBit LAN cable
def get_tc_command(link, ifname):
    return f'tc qdisc replace dev "{ifname}" root tbf rate 100mbit burst 8192 latency 1ms'


def run(protocol, csvfile):
    for path in sorted(glob.glob(f'../../data/grid4/*.json')):
        state = shared.load_json(path)
        (node_count, link_count) = shared.json_count(state)
Esempio n. 5
0
def check_access(remotes):
    shared.check_access(remotes)
Esempio n. 6
0
def main():
    parser = argparse.ArgumentParser()
    parser.add_argument('--verbosity',
                        choices=['verbose', 'normal', 'quiet'],
                        default='normal',
                        help='Set verbosity.')
    parser.add_argument(
        '--remotes',
        help='Distribute nodes and links on remotes described in the JSON file.'
    )
    parser.add_argument('--ip-protocol',
                        choices=['4', '6'],
                        help='Use IPv4/IPv6 only.')
    parser.set_defaults(to_state=None)

    subparsers = parser.add_subparsers(dest='action',
                                       required=True,
                                       help='Action')

    parser_start = subparsers.add_parser(
        'start', help='Start protocol daemons in every namespace.')
    parser_start.add_argument('protocol',
                              choices=protocol_choices,
                              help='Routing protocol to start.')
    parser_start.add_argument('to_state',
                              nargs='?',
                              default=None,
                              help='To state')

    parser_stop = subparsers.add_parser(
        'stop', help='Stop protocol daemons in every namespace.')
    parser_stop.add_argument('protocol',
                             choices=protocol_choices,
                             help='Routing protocol to stop.')
    parser_stop.add_argument('to_state',
                             nargs='?',
                             default=None,
                             help='To state')

    parser_change = subparsers.add_parser(
        'apply', help='Stop/Start protocol daemons in every namespace.')
    parser_change.add_argument('protocol',
                               choices=protocol_choices,
                               help='Routing protocol to change.')
    parser_change.add_argument('to_state',
                               nargs='?',
                               default=None,
                               help='To state')

    parser_run = subparsers.add_parser(
        'run', help='Execute any command in every namespace.')
    parser_run.add_argument(
        'command',
        nargs=argparse.REMAINDER,
        help='Shell command that is run. {name} is replaced by the nodes name.'
    )
    parser_run.add_argument('--quiet',
                            action='store_true',
                            help='Do not output stdout and stderr.')
    parser_run.add_argument('to_state',
                            nargs='?',
                            default=None,
                            help='To state')

    parser_clear = subparsers.add_parser('clear',
                                         help='Stop all routing protocols.')

    args = parser.parse_args()

    global ip_protocol
    ip_protocol = args.ip_protocol

    if args.remotes:
        with open(args.remotes) as file:
            args.remotes = json.load(file)
    else:
        args.remotes = default_remotes

    check_access(args.remotes)

    global verbosity
    verbosity = args.verbosity

    # get nodes that have been added or will be removed
    (old_ids, new_ids, rmap) = _get_update(args.to_state, args.remotes)

    if args.action == 'start':
        if args.to_state:
            start_routing_protocol(args.protocol, rmap, new_ids)
        else:
            all = list(rmap.keys())
            start_routing_protocol(args.protocol, rmap, all)
    elif args.action == 'stop':
        if args.to_state:
            stop_routing_protocol(args.protocol, rmap, old_ids)
        else:
            all = list(rmap.keys())
            stop_routing_protocol(args.protocol, rmap, all)
    elif args.action == 'apply':
        stop_routing_protocol(args.protocol, rmap, old_ids)
        start_routing_protocol(args.protocol, rmap, new_ids)
    elif args.action == 'clear':
        clear(args.remotes)
    elif args.action == 'run':
        run(' '.join(args.command), rmap, args.quiet)
    else:
        eprint('Unknown action: {}'.format(args.action))
        exit(1)

    stop_all_terminals()
Esempio n. 7
0
def main():
    parser = argparse.ArgumentParser()
    parser.add_argument('--verbosity',
                        choices=['verbose', 'normal', 'quiet'],
                        default='normal',
                        help='Set verbosity.')
    parser.add_argument(
        '--remotes',
        help='Distribute nodes and links on remotes described in the JSON file.'
    )
    parser.set_defaults(to_state=None)

    subparsers = parser.add_subparsers(dest='action',
                                       required=True,
                                       help='Action')

    parser_start = subparsers.add_parser(
        'start', help='Run start script in every namespace.')
    parser_start.add_argument('protocol',
                              help='Routing protocol script prefix.')
    parser_start.add_argument('to_state',
                              nargs='?',
                              default=None,
                              help='To state')

    parser_stop = subparsers.add_parser(
        'stop', help='Run stop script in every namespace.')
    parser_stop.add_argument('protocol',
                             help='Routing protocol script prefix.')
    parser_stop.add_argument('to_state',
                             nargs='?',
                             default=None,
                             help='To state')

    parser_change = subparsers.add_parser(
        'apply', help='Run stop/start scripts in every namespace.')
    parser_change.add_argument('protocol',
                               help='Routing protocol script prefix.')
    parser_change.add_argument('to_state',
                               nargs='?',
                               default=None,
                               help='To state')

    parser_run = subparsers.add_parser(
        'run', help='Execute any command in every namespace.')
    parser_run.add_argument(
        'command',
        nargs=argparse.REMAINDER,
        help=
        'Shell command that is run. Remote address and namespace id is added to call arguments.'
    )
    parser_run.add_argument('to_state',
                            nargs='?',
                            default=None,
                            help='To state')

    parser_copy = subparsers.add_parser('copy', help='Copy to all remotes.')
    parser_copy.add_argument('source', nargs='+')
    parser_copy.add_argument('destination')

    parser_clear = subparsers.add_parser(
        'clear', help='Run all stop scripts in every namespaces.')

    args = parser.parse_args()

    if args.remotes:
        if not os.path.isfile(args.remotes):
            eprint(f'File not found: {args.remotes}')
            stop_all_terminals()
            exit(1)

        with open(args.remotes) as file:
            args.remotes = [Remote.from_json(obj) for obj in json.load(file)]
    else:
        args.remotes = default_remotes

    check_access(args.remotes)

    global verbosity
    verbosity = args.verbosity

    # get nodes that have been added or will be removed
    (old_ids, new_ids, rmap) = _get_update(args.to_state, args.remotes)

    if args.action == 'start':
        ids = new_ids if args.to_state else list(rmap.keys())

        beg_ms = millis()
        _start_protocol(args.protocol, rmap, ids)
        end_ms = millis()

        if verbosity != 'quiet':
            print('started {} in {} namespaces in {}'.format(
                args.protocol, len(ids), format_duration(end_ms - beg_ms)))
    elif args.action == 'stop':
        ids = old_ids if args.to_state else list(rmap.keys())

        beg_ms = millis()
        _stop_protocol(args.protocol, rmap, ids)
        end_ms = millis()

        if verbosity != 'quiet':
            print('stopped {} in {} namespaces in {}'.format(
                args.protocol, len(ids), format_duration(end_ms - beg_ms)))
    elif args.action == 'apply':
        beg_ms = millis()
        _stop_protocol(args.protocol, rmap, old_ids)
        _start_protocol(args.protocol, rmap, new_ids)
        end_ms = millis()

        if verbosity != 'quiet':
            print('applied {} in {} namespaces in {}'.format(
                args.protocol, len(rmap.keys()),
                format_duration(end_ms - beg_ms)))
    elif args.action == 'clear':
        beg_ms = millis()
        clear(args.remotes)
        end_ms = millis()

        if verbosity != 'quiet':
            print('cleared on {} remotes in {}'.format(
                len(args.remotes), format_duration(end_ms - beg_ms)))
    elif args.action == 'copy':
        beg_ms = millis()
        copy(args.remotes, args.source, args.destination)
        end_ms = millis()

        if verbosity != 'quiet':
            print('copied on {} remotes in {}'.format(
                len(args.remotes), format_duration(end_ms - beg_ms)))
    elif args.action == 'run':
        ids = new_ids if args.to_state else list(rmap.keys())

        for id in ids:
            remote = rmap[id]
            label = remote.address or 'local'
            cmd = f'ip netns exec ns-{id} {" ".join(args.command)} {label} {id}'
            _exec_verbose(remote, cmd)
    else:
        eprint('Unknown action: {}'.format(args.action))
        stop_all_terminals()
        exit(1)

    stop_all_terminals()