コード例 #1
0
def Trigger(tc):

    if tc.skip: return api.types.status.SUCCESS
    result = api.types.status.SUCCESS

    for intf1 in tc.all_intfs:

        if result == api.types.status.FAILURE:
            break
        #  Run tcpdump on intf1 in promiscuous mode
        req = api.Trigger_CreateExecuteCommandsRequest(serial=True)
        if api.GetNodeOs(
                tc.naples_node) == "windows" and intf1 in tc.host_intfs:
            intfGuid = ionic_utils.winIntfGuid(tc.naples_node, intf1)
            intfVal = str(ionic_utils.winTcpDumpIdx(tc.naples_node, intfGuid))
            cmd = "/mnt/c/Windows/System32/tcpdump.exe"
        else:
            intfVal = intf1
            cmd = "tcpdump"

        cmd += " -l -i " + intfVal + " -tne ether host " + tc.random_mac
        __PR_AddCommand(intf1, tc, req, cmd, True)

        # Run tcpdump in non-promiscuous mode on all other interfaces
        for intf2 in tc.all_intfs:
            if intf2 != intf1:
                if api.GetNodeOs(tc.naples_node
                                 ) == "windows" and intf2 in tc.host_intfs:
                    intfGuid = ionic_utils.winIntfGuid(tc.naples_node, intf2)
                    intfVal = str(
                        ionic_utils.winTcpDumpIdx(tc.naples_node, intfGuid))
                    cmd = "/mnt/c/Windows/System32/tcpdump.exe"
                else:
                    intfVal = intf2
                    cmd = "tcpdump"

                cmd += " -l -i " + intfVal + " -ptne ether host " + tc.random_mac
                __PR_AddCommand(intf2, tc, req, cmd, True)

        cmd = "sleep 1; ping -c 5 " + tc.target_IP + ";sleep 1"
        api.Trigger_AddHostCommand(req, tc.peer_node, cmd)
        cmds_terminated = False
        trig_resp = api.Trigger(req)

        # Verify packet filter flags of each interface in halctl
        show_lif_resp, ret = hal_show_utils.GetHALShowOutput(
            tc.naples_node, "lif")
        if not ret:
            api.Logger.error("Something went wrong with GetHALShowOutput")
            result = api.types.status.FAILURE
            break
        lif_obj_docs = yaml.load_all(show_lif_resp.commands[0].stdout,
                                     Loader=yaml.Loader)

        for lif_obj in lif_obj_docs:
            if lif_obj == None:
                break
            if api.GetNodeOs(
                    tc.naples_node) == "windows" and intf1 in tc.host_intfs:
                halIntfName = ionic_utils.winHalIntfName(tc.naples_node, intf1)
            else:
                halIntfName = intf1
            if lif_obj['spec']['name'].startswith(halIntfName):
                if lif_obj['spec']['packetfilter'][
                        'receivepromiscuous'] != True:
                    api.Logger.error(
                        "halctl PR flag not set for promiscuous mode interface [%s]"
                        % (intf1))
                    result = api.types.status.FAILURE
            else:
                if lif_obj['spec']['packetfilter'][
                        'receivepromiscuous'] == True:
                    api.Logger.error(
                        "halctl PR flag set for non-promiscuous mode interface [%s]"
                        % (lif_obj['spec']['name']))
                    result = api.types.status.FAILURE

        term_resp = api.Trigger_TerminateAllCommands(trig_resp)
        resp = api.Trigger_AggregateCommandsResponse(trig_resp, term_resp)
        cmds_terminated = True

        # Search tcpdump stdout for packets with dst MAC matching tc.random_mac
        pattern = "> " + tc.random_mac

        # Parse tcpdump stdout of promiscuous mode interface
        found = resp.commands[0].stdout.find(pattern)
        if tc.expect_pkt[intf1] and found == -1:
            api.Logger.error(
                "Interface [%s] did not receive Unknown Unicast packet in promiscuous mode"
                % (intf1))
            api.PrintCommandResults(resp.commands[0])
            result = api.types.status.FAILURE
        elif not tc.expect_pkt[intf1] and found > 0:
            api.Logger.error(
                "Interface [%s] received packet in promiscuous mode while not expecting"
                % (intf1))
            api.PrintCommandResults(resp.commands[0])
            result = api.types.status.FAILURE

        # Parse tcpdump stdout of rest of the interfaces
        cmds = resp.commands[1:]
        for cmd in cmds:
            found = cmd.stdout.find(pattern)
            if found > 0:
                api.Logger.error(
                    "Interface in non-promiscuous mode received unknown unicast packet"
                )
                api.PrintCommandResults(cmd)
                result = api.types.status.FAILURE
                break

    #    api.Logger.info(" ==================  DUMP FOR %s   ================================================================" %(intf1))
    #    for cmd in resp.commands:
    #        api.PrintCommandResults(cmd)
    #    api.Logger.info(" ==================  COMPLETED ITERATION FOR %s ====================================================" %(intf1))

    if not cmds_terminated:
        api.Trigger_TerminateAllCommands(trig_resp)
    return result
コード例 #2
0
def Trigger(tc):
    if tc.ignore == True:
        return api.types.status.SUCCESS

    if tc.error == True:
        return api.types.status.FAILURE

    tc.resp_tcpdump_erspan = None
    tc.resp_cleanup = None

    protoDir = api.GetTopologyDirectory() +\
               "/gen/telemetry/{}/{}".format('mirror', 'endpoint')
    api.Logger.info("Template Config files location: ", protoDir)

    policies = utils.GetTargetJsons('mirror', 'endpoint')
    for policy_json in policies:
        #
        # Get template-Mirror Config
        #
        api.Logger.info("Adding one config object for {}", format(policy_json))
        newObjects = agent_api.AddOneConfig(policy_json)
        if len(newObjects) == 0:
            api.Logger.error("Adding new objects to store failed")
            tc.error = True
            return api.types.status.FAILURE

        #
        # Modify template-Mirror Config to make sure that Naples-node
        # act as either source or destination
        #
        # Set up Collector in the remote node
        #
        if newObjects[0].kind == 'InterfaceMirrorSession':
            tc.ep_collector_objects = newObjects
            agent_api.RemoveConfigObjects(tc.ep_collector_objects)
        elif newObjects[0].kind == 'Endpoint':
            tc.endpoint_objects = newObjects
            agent_api.RemoveConfigObjects(tc.endpoint_objects)
            updateEndpointObjectTempl(tc, tc.endpoint_objects,
                                      tc.store_endpoint_objects[0])

    for i in range(0, len(policies)):
        #
        # Push Collector object
        #
        if i == 0:
            colObjects = tc.ep_collector_objects
            if tc.iterators.session == 'single':
                ret = eutils.generateEpCollectorConfig(tc, colObjects)
            else:
                ret = eutils.generateEpCollectorConfigForMultiMirrorSession(
                    tc, colObjects)
            if ret != api.types.status.SUCCESS:
                api.Logger.error("Unable to identify Collector Workload")
                tc.error = True
                return api.types.status.FAILURE

            api.Logger.info("Pushing collector objects")
            ret = agent_api.PushConfigObjects(colObjects,
                                              [tc.naples.node_name],
                                              [tc.naples_device_name])
            if ret != api.types.status.SUCCESS:
                api.Logger.error("Unable to push collector objects")
                tc.error = True
                return api.types.status.FAILURE
            continue

        api.Logger.info("Generating Endpoint objects")
        cfg_api.PrintConfigsObjects(colObjects)
        #
        # Update Endpoint objects
        #
        epObjects = tc.endpoint_objects
        ret = eutils.generateEndpointConfig(tc, epObjects, colObjects)
        if ret != api.types.status.SUCCESS:
            agent_api.DeleteConfigObjects(tc.ep_collector_objects,
                                          [tc.naples.node_name],
                                          [tc.naples_device_name])
            api.Logger.error("Unable to identify Endpoints")
            tc.error = True
            return api.types.status.FAILURE

        api.Logger.info("Pushing Endpoint objects")
        ret = agent_api.UpdateConfigObjects(epObjects, [tc.naples.node_name],
                                            [tc.naples_device_name])
        if ret != api.types.status.SUCCESS:
            agent_api.DeleteConfigObjects(tc.ep_collector_objects,
                                          [tc.naples.node_name],
                                          [tc.naples_device_name])
            api.Logger.error("Unable to update endpoint objects")
            tc.error = True
            return api.types.status.FAILURE

        #
        # Establish Forwarding set up between Naples-peer and Collectors
        #
        eutils.establishForwardingSetup(tc)

        req_tcpdump_erspan = api.Trigger_CreateExecuteCommandsRequest(\
                             serial = True)
        for c in range(0, len(tc.ep_collector)):
            #
            # Set up TCPDUMP's on the collector
            #
            idx = tc.ep_collector_idx[c]
            if tc.ep_collector[c].IsNaples():
                ### TODO - run & revisit for windows case and fix any issues.
                if api.GetNodeOs(tc.naples.node_name) == "windows":
                    intfGuid = ionic_utils.winIntfGuid(
                        tc.ep_collector[c].node_name,
                        tc.ep_collector[c].interface)
                    intfVal = str(
                        ionic_utils.winTcpDumpIdx(tc.ep_collector[c].node_name,
                                                  intfGuid))
                    cmd = "sudo /mnt/c/Windows/System32/tcpdump.exe -c 1000 -XX -vv -i {} ip proto 47 and dst {} -U -w ep-mirror-{}.pcap"\
                          .format(intfVal, tc.collector_ip_address[idx], c)
                else:
                    intfVal = tc.ep_collector[c].interface
                    cmd = "tcpdump -c 1000 -XX -vv -nni {} ip proto gre and dst {}\
                           --immediate-mode -U -w ep-mirror-{}.pcap"\
                          .format(intfVal,
                              tc.collector_ip_address[idx], c)
            else:
                cmd = "tcpdump -p -c 1000 -XX -vv -nni {} ip proto gre\
                       and dst {} --immediate-mode -U -w ep-mirror-{}.pcap"\
                      .format(tc.ep_collector[c].interface,
                              tc.collector_ip_address[idx], c)
            eutils.add_command(req_tcpdump_erspan, tc.ep_collector[c], cmd,
                               True)

        resp_tcpdump_erspan = api.Trigger(req_tcpdump_erspan)
        for cmd in resp_tcpdump_erspan.commands:
            api.PrintCommandResults(cmd)

        #
        # Classic mode requires a delay to make sure that TCPDUMP background
        # process is fully up
        #
        if tc.classic_mode == True:
            time.sleep(2)

        #
        # Trigger packets for ERSPAN to take effect
        #
        tc.dest_port = '120'
        if api.GetNodeOs(tc.naples.node_name) == 'linux' or api.GetNodeOs(
                tc.naples.node_name) == 'windows':
            eutils.triggerTrafficInClassicModeLinux(tc)
        else:
            eutils.triggerTrafficInHostPinModeOrFreeBSD(tc)

        #
        # Dump sessions/flows/P4-tables for debug purposes
        #
        eutils.showSessionAndP4TablesForDebug(tc, tc.ep_collector,
                                              tc.ep_collector_idx)

        #
        # Terminate TCPDUMP background process
        #
        term_resp_tcpdump_erspan = api.Trigger_TerminateAllCommands(\
                                   resp_tcpdump_erspan)
        tc.resp_tcpdump_erspan = api.Trigger_AggregateCommandsResponse(\
                              resp_tcpdump_erspan, term_resp_tcpdump_erspan)
        if api.GetNodeOs(tc.naples.node_name) == "windows":
            req = api.Trigger_CreateExecuteCommandsRequest(serial=True)
            cmd = api.WINDOWS_POWERSHELL_CMD + " Stop-Process -Name 'tcpdump' -Force"
            api.Trigger_AddCommand(req,
                                   tc.naples.node_name,
                                   tc.naples.workload_name,
                                   cmd,
                                   background=False)
            resp = api.Trigger(req)

        # Delete the objects
        eutils.deGenerateEndpointConfig(tc, tc.endpoint_objects,
                                        tc.ep_collector_objects)
        agent_api.UpdateConfigObjects(tc.endpoint_objects,
                                      [tc.naples.node_name],
                                      [tc.naples_device_name])

        agent_api.DeleteConfigObjects(tc.ep_collector_objects,
                                      [tc.naples.node_name],
                                      [tc.naples_device_name])

        #
        # Make sure that Mirror-config has been removed
        #
        tc.resp_cleanup = eutils.showP4TablesForValidation(tc)

    return api.types.status.SUCCESS
コード例 #3
0
def Trigger(tc):

    if tc.skip: return api.types.status.SUCCESS
    result = api.types.status.SUCCESS

    if tc.args.mode == "non-promiscuous":
        # Run tcdpump in non-promiscuous mode
        tcpdump_flags_extra = " -p "
    else:
        tcpdump_flags_extra = ""

    # For further debug, listen for packets on peer node as well
    if tc.args.mode == "promiscuous":
        req_node2 = api.Trigger_CreateExecuteCommandsRequest(serial=True)

        for workload in tc.peer_workloads:
            if api.GetNodeOs(tc.naples_node) == "windows":
                intfGuid = ionic_utils.winIntfGuid(tc.naples_node,
                                                   workload.interface)
                intf = str(ionic_utils.winTcpDumpIdx(tc.naples_node, intfGuid))
                cmd = "/mnt/c/Windows/System32/tcpdump.exe"
            else:
                intf = workload.interface
                cmd = "tcpdump"

            cmd += " -l -i " + intf + " -tne arp host " + tc.target_IP + " or icmp"
            api.Trigger_AddHostCommand(req_node2, tc.peer_node, cmd, True)
        trig_resp_node2 = api.Trigger(req_node2)

    for intf1 in tc.host_intfs:

        if result == api.types.status.FAILURE:
            break

        # Create a static ARP entry for the target IP with MAC addr belonging to current host interface
        mac_addr = host_utils.GetMACAddress(tc.naples_node, intf1)
        api.Logger.info("%s MAC ADDR: %s" % (intf1, mac_addr))
        if host_utils.AddStaticARP(
                tc.peer_node, tc.peer_workloads[0].interface, tc.target_IP,
                mac_addr) != api.types.status.SUCCESS:
            api.Logger.error("Failed to add Static ARP entry on %s %s %s" %
                             (tc.peer_node, tc.target_IP, mac_addr))
            result = api.types.status.FAILURE
            break

        req = api.Trigger_CreateExecuteCommandsRequest(serial=True)

        # Warm N3K FDB table with current interface MAC address (to avoid future flooding of packets with DST MAC matching this interface)
        if api.GetNodeOs(tc.naples_node) == "windows":
            cmd = "/mnt/c/Windows/System32/arp-ping.exe -n 1 -s " + utils.GetIPAddress(
                tc.naples_node, intf1) + " " + tc.target_IP
        else:
            cmd = "arping -c 1 -I " + intf1 + " " + tc.target_IP
        api.Trigger_AddHostCommand(req, tc.naples_node, cmd)

        # Run tcpdump on all interfaces
        for intf2 in tc.all_intfs:
            if api.GetNodeOs(
                    tc.naples_node) == "windows" and intf2 in tc.host_intfs:
                intfGuid = ionic_utils.winIntfGuid(tc.naples_node, intf2)
                intfVal = str(
                    ionic_utils.winTcpDumpIdx(tc.naples_node, intfGuid))
                cmd = "/mnt/c/Windows/System32/tcpdump.exe"
            else:
                intfVal = intf2
                cmd = "tcpdump"

            cmd += " -l -i " + intfVal + tcpdump_flags_extra + " -tne ether host " + mac_addr
            __PR_AddCommand(intf2, tc, req, cmd, True)

        cmd = "sleep 1; ping -c 5 " + tc.target_IP + ";sleep 1"

        api.Trigger_AddHostCommand(req, tc.peer_node, cmd)
        trig_resp = api.Trigger(req)
        term_resp = api.Trigger_TerminateAllCommands(trig_resp)
        resp = api.Trigger_AggregateCommandsResponse(trig_resp, term_resp)

        # Skipping halctl flag checks here as other testcases prior to this already validates halcltl o/p.
        # Search tcpdump stdout for packets with dst MAC matching mac_addr
        # No other interface other than current 'intf1' should receive the packet
        pattern = "> " + mac_addr
        cmds = resp.commands[1:-1]
        for intf, cmd in zip(tc.all_intfs, cmds):
            found = cmd.stdout.find(pattern)
            if intf == intf1:
                if found == -1:
                    api.Logger.error(
                        "Interface [%s] did not receive expected known unicast packet"
                        % (intf))
                    result = api.types.status.FAILURE
            elif found > 0:
                api.Logger.error(
                    "Interface [%s] received known unicast packet while not expecting"
                    % (intf))
                result = api.types.status.FAILURE

        # Cleanup for current host interface 'intf1'
        if host_utils.DeleteARP(tc.peer_node, tc.peer_workloads[0].interface,
                                tc.target_IP) != api.types.status.SUCCESS:
            api.Logger.error("Failed to delete Static ARP entry on %s %s" %
                             (tc.peer_node, tc.target_IP))
            result = api.types.status.FAILURE

    if tc.args.mode == "promiscuous":
        term_resp_node2 = api.Trigger_TerminateAllCommands(trig_resp_node2)
        resp_node2 = api.Trigger_AggregateCommandsResponse(
            trig_resp_node2, term_resp_node2)

    # Incase of testcase failure, dump the entire command output for further debug
    if result == api.types.status.FAILURE:
        api.Logger.error(
            " ============================= COMMAND DUMP ================================================"
        )
        for cmd in resp.commands:
            api.PrintCommandResults(cmd)

        # Dump tcpdump o/p from peer node
        if tc.args.mode == "promiscuous":
            api.Logger.error(
                " ============================= COMMAND DUMP from NODE 2 ================================================"
            )
            for cmd in resp_node2.commands:
                api.PrintCommandResults(cmd)
            api.Logger.error(
                " =============================  END NODE 2 DUMP ========================================================"
            )

    return result
コード例 #4
0
def Trigger(tc):

    if tc.skip: return api.types.status.SUCCESS
    result = api.types.status.SUCCESS

    req = api.Trigger_CreateExecuteCommandsRequest(serial=True)

    if tc.args.mode == "non-promiscuous":
        # Run tcdpump in non-promiscuous mode
        tcpdump_flags_extra = " -p "
    else:
        tcpdump_flags_extra = ""

    # Run tcpdump on all interfaces
    for intf in tc.all_intfs:
        if api.GetNodeOs(
                tc.naples_node) == "windows" and intf in tc.host_intfs:
            intfGuid = ionic_utils.winIntfGuid(tc.naples_node, intf)
            intfVal = str(ionic_utils.winTcpDumpIdx(tc.naples_node, intfGuid))
            cmd = "/mnt/c/Windows/System32/tcpdump.exe"
        else:
            intfVal = intf
            cmd = "tcpdump"

        cmd += " -l -i " + intfVal + tcpdump_flags_extra + " -tne ether host " + tc.random_mac
        __PR_AddCommand(intf, tc, req, cmd, True)

    cmd = "sleep 1; ping -c 5 " + tc.target_IP + ";sleep 1"
    api.Trigger_AddHostCommand(req, tc.peer_node, cmd)
    trig_resp = api.Trigger(req)

    # Verify packet filter flags of each interface in halctl
    show_lif_resp, ret = hal_show_utils.GetHALShowOutput(tc.naples_node, "lif")
    if not ret:
        api.Logger.error("Something went wrong with GetHALShowOutput")
        result = api.types.status.FAILURE

    lif_obj_docs = yaml.load_all(show_lif_resp.commands[0].stdout)

    for lif_obj in lif_obj_docs:

        if lif_obj == None:
            break

        # See if the lif belongs to any of the interface in tc.all_intfs (inteface lif)
        intf_lif = False
        for intf in tc.all_intfs:
            if api.GetNodeOs(
                    tc.naples_node) == "windows" and intf in tc.host_intfs:
                halIntfName = ionic_utils.winHalIntfName(tc.naples_node, intf)
            else:
                halIntfName = intf
            if lif_obj['spec']['name'].startswith(halIntfName):
                intf_lif = True
                break

        lif_pr_flag = lif_obj['spec']['packetfilter']['receivepromiscuous']

        # A lif must have its PR flag when it is an interface lif and tc.args.mode is 'promiscuous'
        if tc.args.mode == "promiscuous":
            if intf_lif and lif_pr_flag != True:
                api.Logger.error(
                    "halctl PR flag not set for promiscuous mode interface [%s]"
                    % (lif_obj['spec']['name']))
                result = api.types.status.FAILURE
        else:
            if lif_pr_flag == True:
                api.Logger.error(
                    "halctl PR flag set for non-promiscuous mode LIF [%s]" %
                    (lif_obj['spec']['name']))
                result = api.types.status.FAILURE

    term_resp = api.Trigger_TerminateAllCommands(trig_resp)
    resp = api.Trigger_AggregateCommandsResponse(trig_resp, term_resp)

    # Search tcpdump stdout for packets with dst MAC matching tc.random_mac
    pattern = "> " + tc.random_mac

    cmds = resp.commands[:-1]
    for intf, cmd in zip(tc.all_intfs, cmds):
        found = cmd.stdout.find(pattern)
        if found > 0 and not tc.expect_pkt[intf]:
            api.Logger.error(
                "Interface [%s] received Unknown unicast packet while not expecting"
                % (intf))
            result = api.types.status.FAILURE
        elif found == -1 and tc.expect_pkt[intf]:
            api.Logger.error(
                "Interface [%s] did not receive expected Unknown unicast packet"
                % (intf))
            result = api.types.status.FAILURE

    # Incase of testcase failure, dump the entire command output for further debug
    if result == api.types.status.FAILURE:
        api.Logger.error(
            " ============================= COMMAND DUMP ================================================"
        )
        for cmd in resp.commands:
            api.PrintCommandResults(cmd)
        api.Logger.error(
            " =============================  END  ========================================================"
        )

    return result