Exemple #1
0
    def off(self, target, component):
        # Kill tcpdump, if it was started
        pidfile = os.path.join(target.state_dir, "tcpdump.pid")
        commonl.process_terminate(pidfile,
                                  tag="tcpdump",
                                  path="/usr/sbin/tcpdump")
        # remove the top level device
        mode = self._get_mode(target)
        if mode == 'physical':
            # bring down the lower device
            ifname = commonl.if_find_by_mac(target.tags['mac_addr'])
            subprocess.check_call(
                # flush the IP addresses, bring it down
                "/usr/sbin/ip add flush dev %s; "
                "/usr/sbin/ip link set dev %s down promisc off" %
                (ifname, ifname),
                shell=True)
        elif mode == 'vlan':
            commonl.if_remove_maybe("b%(id)s" % target.kws)
            # nothing; we killed the upper and on the lwoer, a
            # physical device we do nothing, as others might be using it
            pass
        elif mode == 'virtual':
            commonl.if_remove_maybe("b%(id)s" % target.kws)
            # remove the lower we created
            commonl.if_remove_maybe("_b%(id)s" % target.kws)
        else:
            raise AssertionError("Unknown mode %s" % mode)

        target.fsdb.set('power_state', 'off')
Exemple #2
0
 def _if_rename(target):
     if 'mac_addr' in target.tags:
         # We do have a physical device, so we are going to first,
         # rename it to match the IC's name (so it allows targets
         # to find it to run IP commands to attach to it)
         ifname = commonl.if_find_by_mac(target.tags['mac_addr'])
         if ifname == None:
             raise ValueError("Cannot find network interface with MAC '%s'"
                              % target.tags['mac_addr'])
         if ifname != target.id:
             subprocess.check_call("ip link set %s down" % ifname,
                                   shell = True)
             subprocess.check_call("ip link set %s name b%s"
                                   % (ifname, target.id), shell = True)
Exemple #3
0
    def on(self, target, _component):
        # Bring up the lower network interface; lower is called
        # whatever (if it is a physical device) or _bNAME; bring it
        # up, make it promiscuous
        mode = self._get_mode(target)
        if mode == 'vlan':
            # our lower is a physical device, our upper is a device
            # which till tag for eth vlan %(vlan)
            ifname = commonl.if_find_by_mac(target.tags['mac_addr'],
                                            physical=True)
            commonl.if_remove_maybe("b%(id)s" % target.kws)
            kws = dict(target.kws)
            kws['ifname'] = ifname
            subprocess.check_call(
                "/usr/sbin/ip link add"
                " link %(ifname)s name b%(id)s"
                " type vlan id %(vlan)s"
                #" protocol VLAN_PROTO"
                #" reorder_hdr on|off"
                #" gvrp on|off mvrp on|off loose_binding on|off"
                % kws,
                shell=True)
            subprocess.check_call(  # bring lower up
                "/usr/sbin/ip link set dev %s up promisc on" % ifname,
                shell=True)
        elif mode == 'physical':
            ifname = commonl.if_find_by_mac(target.tags['mac_addr'])
            subprocess.check_call(  # bring lower up
                "/usr/sbin/ip link set dev %s up promisc on" % ifname,
                shell=True)
            self._if_rename(target)
        elif mode == 'virtual':
            # We do not have a physical device, a bridge, to serve as
            # lower
            commonl.if_remove_maybe("_b%(id)s" % target.kws)
            subprocess.check_call("/usr/sbin/ip link add"
                                  "  name _b%(id)s"
                                  "  type bridge" % target.kws,
                                  shell=True)
            subprocess.check_call("/usr/sbin/ip link add"
                                  "  link _b%(id)s name b%(id)s"
                                  "  type macvlan mode bridge; " % target.kws,
                                  shell=True)
            subprocess.check_call(  # bring lower up
                "/usr/sbin/ip link set"
                "  dev _b%(id)s"
                "  up promisc on" % target.kws,
                shell=True)
        else:
            raise AssertionError("Unknown mode %s" % mode)

        # Configure the IP addresses for the top interface
        subprocess.check_call(  # clean up existing address
            "/usr/sbin/ip add flush dev b%(id)s " % target.kws,
            shell=True)
        subprocess.check_call(  # add IPv6
            # if this fails, check Network Manager hasn't disabled ipv6
            # sysctl -a | grep disable_ipv6 must show all to 0
            "/usr/sbin/ip addr add"
            "  %(ipv6_addr)s/%(ipv6_prefix_len)s dev b%(id)s " % target.kws,
            shell=True)
        subprocess.check_call(  # add IPv4
            "/usr/sbin/ip addr add"
            "  %(ipv4_addr)s/%(ipv4_prefix_len)d"
            "  dev b%(id)s" % target.kws,
            shell=True)

        # Bring up the top interface, which sets up ther outing
        subprocess.check_call(
            "/usr/sbin/ip link set dev b%(id)s up promisc on" % target.kws,
            shell=True)

        target.fsdb.set('power_state', 'on')

        # Start tcpdump on the network?
        #
        # The value of the tcpdump property, if not None, is the
        # filename we'll capture to.
        tcpdump = target.fsdb.get('tcpdump')
        if tcpdump:
            assert not os.path.sep in tcpdump \
                and tcpdump != "" \
                and tcpdump != os.path.pardir \
                and tcpdump != os.path.curdir, \
                "Bad filename for TCP dump capture '%s' specified as " \
                " value to property *tcpdump*: must not include" % tcpdump
            # per ttbd:make_ticket(), colon splits the real username
            # from the ticket
            owner = target.owner_get().split(":")[0]
            assert owner, "BUG? target not owned on power on?"
            capfile = os.path.join(target.files_path, owner, tcpdump)
            # Because it is in the user's area,
            # we assume the user knows what he is doing to overwrite it,
            # so we'll remove any first
            commonl.rm_f(capfile)
            pidfile = os.path.join(target.state_dir, "tcpdump.pid")
            logfile = os.path.join(target.state_dir, "tcpdump.log")
            cmdline = [
                "/usr/sbin/tcpdump", "-U", "-i",
                "_b%(id)s" % target.kws, "-w", capfile
            ]
            try:
                logf = open(logfile, "a")
                target.log.info("Starting tcpdump with: %s", " ".join(cmdline))
                p = subprocess.Popen(cmdline,
                                     shell=False,
                                     cwd=target.state_dir,
                                     close_fds=True,
                                     stdout=logf,
                                     stderr=subprocess.STDOUT)
            except OSError as e:
                raise RuntimeError("tcpdump failed to start: %s" % e)
            ttbl.daemon_pid_add(p.pid)  # FIXME: race condition if it died?
            with open(pidfile, "w") as pidfilef:
                pidfilef.write("%d" % p.pid)

            pid = commonl.process_started(  # Verify it started
                pidfile,
                "/usr/sbin/tcpdump",
                verification_f=os.path.exists,
                verification_f_args=(capfile, ),
                timeout=20,
                tag="tcpdump",
                log=target.log)
            if pid == None:
                raise RuntimeError("tcpdump failed to start after 5s")