Example #1
0
def process_tc_data(data):
    # If file is empty then we do nothing
    if len(data) == 0:
        return

    if not 'interface' in data:
        h.err_exit('Interface not found in tc config')

    interface = data.get('interface')

    delete_qdiscs(interface)

    # Moved from existing script
    use_scheduler = ''
    is_using_taprio = False
    if 'mqprio' in data: use_scheduler = 'mqprio'
    if 'taprio' in data:
        is_using_taprio = True
        use_scheduler = 'taprio'

    clock_id = 'CLOCK_TAI'
    if use_scheduler:
        #print("Setting up {} qdisc".format(use_scheduler))
        maps = set_mapping(data, use_scheduler)

        if use_scheduler == 'taprio':
            time_elapsed = data['taprio']['time_elapsed']
            base_time = '$(expr $(date +%s) + 5)000000000'
            #print('Base time set to {}s from now'.format(time_elapsed))
            set_taprio(interface, maps, data["taprio"], base_time, clock_id)

        elif use_scheduler == 'mqprio':
            set_mqprio(interface, maps, data["mqprio"])

    show_qdisc_cmd = get_show_qdisc_cmd(interface)

    if 'cbs' in data:
        #print('Setup CBS')
        set_cbs(interface, data["cbs"])

    if 'etf' in data:
        #print('Setup ETF')
        for each_config in data["etf"]:
            set_etf(interface, clock_id, each_config, show_qdisc_cmd,
                    is_using_taprio)

    if 'vlanrx' in data:
        #print('Setup VLAN RX steering')
        init_ingress(interface, show_qdisc_cmd)
        for each_config in data["vlanrx"]:
            set_vlanrx(interface, each_config, show_qdisc_cmd)

    if 'run_sh' in data:
        #print('Running raw shell commands, this shouldn\'t happen in prod')
        for cmd in data.get('run_sh'):
            h.sh_run(cmd)
Example #2
0
def set_mqprio(iface, maps, config):
    num_tc = 0
    queues = 0
    handle = 0
    for each in config.keys():
        if each == "num_tc":
            num_tc = config["num_tc"]
        if each == "queues":
            queues = config["queues"]
        if each == "handle":
            handle = config["handle"]

    if not num_tc:
        #print("num_tc not defined")
        exit(1)
    if not queues:
        #print("queues not defined")
        exit(1)
    if not handle:
        #print("handle not defined")
        exit(1)

    # Final mqprio command to run
    set_mqprio_cmd = "tc qdisc add dev {} ".format(iface)
    set_mqprio_cmd += "parent root handle {} ".format(handle)
    set_mqprio_cmd += "mqprio num_tc {} ".format(num_tc)
    set_mqprio_cmd += "map {} queues {} hw 0".format(maps, queues)
    output = h.sh_run(set_mqprio_cmd)
Example #3
0
def process_ptp(obj):
    h.ensure_keys_exist('ptp', obj, 'interface')
    iface = obj.get('interface')
    ignore_existing = obj.get('ignore_existing', False)
    socket_prio = str(obj.get('socket_prio', 2))

    ## TODO sock prio or net prio
    if not ignore_existing: return
    h.sh_run('pkill ptp4l')

    # ptp4l -mP2Hi eth0 -f scripts/gPTP.cfg --step_threshold=2 --socket_priority 1
    arglist = [
        'taskset', '-c', '1', 'ptp4l', '-mP2Hi', iface, '-f',
        'scripts/gPTP.cfg', '--step_threshold=2'
    ]
    arglist += ['--socket_priority', socket_prio]
    h.run_with_out(arglist, '/var/log/ptp4l.log')
    h.sh_run('sleep 30')
Example #4
0
def set_vlanrx(iface, config, show_qdisc_cmd):

    vlan_priority = str(config['vlan_priority'])
    rx_hw_q = str(config['rx_hw_q'])

    set_vlanrx_cmd = "tc filter add dev {} ".format(iface)
    set_vlanrx_cmd += "parent ffff: protocol 802.1Q flower vlan_prio {} ".format(
        vlan_priority)
    set_vlanrx_cmd += "hw_tc {} ".format(rx_hw_q)

    output = h.sh_run(set_vlanrx_cmd)
Example #5
0
def set_cbs(iface, scenario_config):
    handle = scenario_config["handle"]
    parent = scenario_config["parent"]
    queue = scenario_config["queue"] + 1
    sendslope = scenario_config["sendslope"]
    idleslope = scenario_config["idleslope"]
    hicredit = scenario_config["locredit"]
    locredit = scenario_config["locredit"]
    offload = scenario_config["offload"]

    # generate cbs command
    etf_default_cmd = 'tc qdisc replace dev {} '.format(iface)
    etf_default_cmd += 'handle {} parent {}:{} '.format(handle, parent, queue)
    etf_default_cmd += 'cbs idleslope {} sendslope {} '.format(
        idleslope, sendslope)
    etf_default_cmd += 'hicredit {} locredit {} '.format(hicredit, locredit)
    etf_default_cmd += 'offload {} '.format(offload)

    #print('Adding cbs qdisc on queue {}...'.format(queue))
    output = h.sh_run(etf_default_cmd)
    h.sh_run('sleep 5')
Example #6
0
def process_phc2sys(obj):
    h.ensure_keys_exist('phc2sys', obj, 'clock', 'interface')
    clock = obj.get('clock')
    iface = obj.get('interface')
    ignore_existing = obj.get('ignore_existing', False)

    if not ignore_existing: return
    h.sh_run('pkill phc2sys')
    h.sh_run('sleep 2')

    # pmc -ub 0 -t 1 "SET GRANDMASTER_SETTINGS_NP clockClass 248 \
    #       clockAccuracy 0xfe offsetScaledLogVariance 0xffff    \
    #       currentUtcOffset 37 leap61 0 leap59 0 currentUtcOffsetValid 1 \
    #       ptpTimescale 1 timeTraceable 1 frequencyTraceable 0 timeSource 0xa0
    arglist = [
        'pmc', '-u', '-b', '0', '-t', '1', '"',
        'SET GRANDMASTER_SETTINGS_NP clockClass 248'
        ' clockAccuracy 0xfe offsetScaledLogVariance 0xffff currentUtcOffset 37'
        ' leap61 0 leap59 0 currentUtcOffsetValid 1 ptpTimescale 1 timeTraceable'
        ' 1 frequencyTraceable 0 timeSource 0xa0', '"'
    ]
    h.run_with_out(arglist, '/var/log/pmc.log')

    h.sh_run('sleep 2')

    # phc2sys -c CLOCK_REALTIME --step_threshold=1 -s eth0 \
    #       --transportSpecific=1 -O 0 -w -ml 7
    arglist = [
        'taskset', '-c', '1', 'phc2sys', '-c', 'CLOCK_REALTIME',
        '--step_threshold=1', '-s', iface, '--transportSpecific=1', '-O', '0',
        '-w', '-ml', '7'
    ]
    h.run_with_out(arglist, '/var/log/phc2sys.log')
Example #7
0
def process_iperf3(obj):
    # kill all currently running iperf3
    h.sh_run('pkill iperf3')
    run_server = obj.get('run_server', False)
    client_target_add = str(obj.get('client_target_address'))
    cpu_aff = str(obj.get('cpu_affinity', 3))
    client_runtime = str(obj.get('client_runtime_in_sec', 5000))
    iperf3_log = "/var/log/iperf3_client.log"
    client_bw = str(obj.get('client_bandwidth_in_mbps', 1))

    # run the iperf3 server if server is enabled
    if run_server:
        iperf3_com = 'iperf3 -s -D --affinity {} &'.format(cpu_aff)
        h.sh_run(iperf3_com)

    # create the iperf3 client(udp) shell script if target server IP is given
    if client_target_add:
        client_iperf3_com = 'iperf3 -c {} --affinity {} -u -t {} --logfile {} -b {}M '.format(
            client_target_add, cpu_aff, client_runtime, iperf3_log, client_bw)
        f = open('iperf3-gen-cmd.sh', 'w')
        f.write(str(client_iperf3_com))
        f.close()
Example #8
0
def set_etf(iface, clkid, config, show_cmd, use_taprio):
    # unpack config variable
    delta = str(config['delta'])

    # naming convention for queue is <parent>:<queue>
    # since <queue> naming starts from 1, we add 1 to queue.
    queue = str(config['queue'] + 1)

    # deadline_mode and offload is turn off by default
    deadline_mode = False
    offload = False

    # find the parent for specific qdisc
    cmd = 'HANDLE_ID="$(tc qdisc show dev {} | tr -d \':\' | awk \'NR==1{{print $3}}\')"'.format(
        iface)
    h.sh_run(cmd)

    # check if config specify deadline_mode or offload
    for each in config.keys():
        if each == 'deadline_mode':
            deadline_mode = config['deadline_mode']
        if each == 'offload':
            offload = config['offload']

    # generate etf command
    etf_default_cmd = 'tc qdisc replace dev {} parent $HANDLE_ID:{} etf '.format(
        iface, queue)
    etf_default_cmd += ' clockid {}'.format(clkid)
    etf_default_cmd += ' delta {}'.format(delta)
    if offload == True:
        etf_default_cmd += ' offload'
    if deadline_mode == True:
        etf_default_cmd += ' deadline_mode'

    # #print('Adding etf qdisc on queue {}...'.format(queue))
    output = h.sh_run(etf_default_cmd)
Example #9
0
def process_custom_a(obj):
    h.ensure_keys_exist(obj, 'interface2', 'interface')
    iface = obj.get('interface')
    iface2 = obj.get('interface2')
    ignore_existing = obj.get('ignore_existing', False)
    socket_prio = str(obj.get('socket_prio', 1))

    if not ignore_existing: return
    h.sh_run('pkill phc2sys')
    h.sh_run('pkill ptp4l')

    # ptp4l -mP2Hi eth0 -f scripts/gPTP.cfg --step_threshold=2 --socket_priority 1
    arglist = [
        'taskset', '-c', '1', 'ptp4l', '-mP2Hi', iface, '-f',
        'scripts/gPTP.cfg', '--step_threshold=2'
    ]
    arglist += ['--socket_priority', '1']
    h.run_with_out(arglist, '/var/log/ptp4l.log')

    arglist = [
        'taskset', '-c', '1', 'ptp4l', '-mP2Hi', iface2, '-f',
        'scripts/gPTP.cfg', '--step_threshold=2'
    ]
    arglist += ['--socket_priority', '1']
    h.run_with_out(arglist, '/var/log/ptp4l2.log')

    #print("Give 30 secs for ptp to sync")
    if not h.IS_DRY:
        h.sh_run('sleep 30')

    # pmc -ub 0 -t 1 "SET GRANDMASTER_SETTINGS_NP clockClass 248 \
    #       clockAccuracy 0xfe offsetScaledLogVariance 0xffff    \
    #       currentUtcOffset 37 leap61 0 leap59 0 currentUtcOffsetValid 1 \
    #       ptpTimescale 1 timeTraceable 1 frequencyTraceable 0 timeSource 0xa0
    arglist = [
        'pmc', '-u', '-b', '0', '-t', '1', '"',
        'SET GRANDMASTER_SETTINGS_NP clockClass 248'
        ' clockAccuracy 0xfe offsetScaledLogVariance 0xffff currentUtcOffset 37'
        ' leap61 0 leap59 0 currentUtcOffsetValid 1 ptpTimescale 1 timeTraceable'
        ' 1 frequencyTraceable 0 timeSource 0xa0', '"'
    ]
    h.run_with_out(arglist, '/var/log/pmc.log')

    # phc2sys -c CLOCK_REALTIME --step_threshold=1 -s eth0 \
    #       --transportSpecific=1 -O 0 -w -ml 7
    arglist = [
        'taskset', '-c', '1', 'phc2sys', '-c', 'CLOCK_REALTIME',
        '--step_threshold=1', '-s', iface, '--transportSpecific=1', '-O', '0',
        '-w', '-ml', '7'
    ]
    h.run_with_out(arglist, '/var/log/phc2sys.log')
Example #10
0
def set_taprio(iface, maps, config, basetime, clkid):
    schedules = ""
    for each in config["schedule"]:
        schedules += "sched-entry S {} {} ".format(each['gate_mask'],
                                                   str(each['duration']))

    num_tc = 0
    queues = 0
    handle = 0
    for each in config.keys():
        if each == "num_tc":
            num_tc = config["num_tc"]
        if each == "queues":
            queues = config["queues"]
        if each == "handle":
            handle = config["handle"]

    if not num_tc:
        #print( "num_tc not defined" )
        exit(1)
    if not queues:
        #print(  "queues not defined" )
        exit(1)
    if not handle:
        #print ( "handle not defined" )
        exit(1)

    # Final taprio command to run
    set_taprio_cmd = "tc -d qdisc replace dev {} ".format(iface)
    set_taprio_cmd += "parent root handle {} ".format(handle)
    set_taprio_cmd += "taprio num_tc {} map {} ".format(num_tc, maps)
    set_taprio_cmd += "queues {} base-time {} ".format(queues, basetime)
    set_taprio_cmd += "{} flags 0x2".format(schedules)

    # Parse hardware offload option
    # It's specified in json as "offload": true|false
    if 'offload' in config and config.get('offload'):
        set_taprio_cmd += ' offload 1'

    output = h.sh_run(set_taprio_cmd)
Example #11
0
def init_ingress(iface, show_qdisc_cmd):
    clear_rx_cmd = "tc qdisc del dev {} parent ffff:".format(iface)
    add_ingress_cmd = "tc qdisc add dev {} ingress".format(iface)

    output = h.sh_run(clear_rx_cmd)
    output = h.sh_run(add_ingress_cmd)
Example #12
0
def delete_qdiscs(iface):
    #print('Deleting existing qdiscs')
    cmd = 'tc qdisc del dev {} parent root'.format(iface)
    proc = h.sh_run(cmd)
    h.sh_run('sleep 5')