def on(self, target, component): if not commonl.prctl_cap_get_effective() & 1 << 12: # If we don't have network setting privilege, # don't even go there # CAP_NET_ADMIN is 12 (from /usr/include/linux/prctl.h. # # Fail here (upon use) instead of during server startup, # because maybe we don't really care about it and we have # a default configuration with the thargets that would # need this. raise RuntimeError("daemon lacks CAP_NET_ADMIN: unable to" " add networking capabilities ") if_name, ic_name = self._component_validate(target, component) if not commonl.if_present(f"b{ic_name}"): target.log.info(f"{ic_name}: assuming network off since netif " f"b{ic_name} is not present") return commonl.if_remove_maybe(if_name) # ensure no leftovers subprocess.check_call(["ip", "tuntap", "add", if_name, "mode", "tap"], stderr=subprocess.STDOUT) subprocess.check_call( ["ip", "link", "set", if_name, "master", "b" + ic_name], stderr=subprocess.STDOUT) # promisc on: needed so we can wireshark in subprocess.check_call( ["ip", "link", "set", if_name, "promisc", "on", "up"], stderr=subprocess.STDOUT) # We don't assign IP addresses here -- we leave it for the # client; if we do, for example QEMU won't work as it is just # used to associate the interface target.fsdb.set(component, if_name)
def __init__(self, **kwargs): ttbl.power.impl_c.__init__(self, **kwargs) if not commonl.prctl_cap_get_effective() & 1 << 12: # If we don't have network setting privilege, # don't even go there # CAP_NET_ADMIN is 12 (from /usr/include/linux/prctl.h raise RuntimeError("daemon lacks CAP_NET_ADMIN: unable to" " add networking capabilities ")
def _power_on_pre_nw(self): # We need the __init__ part doing it earlier because remember, # these might be running different processes, and the basic # self.qemu_cmdline array has to be initialized so we can # find the actual binary being used. kws = dict(self.kws) # Get fresh values for these keys for key in list(self.fsdb.keys()): if key.startswith("qemu-"): kws[key] = self.fsdb.get(key) # Setup network stuff, create virtual tap interfaces for ic_name, ic_kws in list(self.tags.get('interconnects', {}).items()): if 'ipv4_addr' in ic_kws or 'ipv6_addr' in ic_kws: _kws = dict(kws) _kws.update(ic_kws) _kws['ic_name'] = ic_name # QEMU device ident only allows a-zA-Z0-9-, starting # with letter _kws['ident'] = "id" + self._r_ident.sub("", _kws['mac_addr']) # CAP_NET_ADMIN is 12 (from /usr/include/linux/prctl.h if not commonl.prctl_cap_get_effective() & 1 << 12: # If we don't have network setting privilege, # don't even go there self.log.warning("daemon lacks CAP_NET_ADMIN: unable to " "add networking capabilities ") continue if not commonl.if_present("_b%s" % ic_name): self.log.warning("network %s powered off? networking " "disabled" % ic_name) # If the network is not powered up, skip it # FIXME: replace with it calling vlan_pci.something() # that brings up the basic interface (_bICNAME) so # that once we power the network, it works continue commonl.if_remove_maybe("t%s%s" % (ic_name, self.id)) subprocess.check_call( "ip link add " " link _b%(ic_name)s " " name t%(ic_name)s%(id)s" " address %(mac_addr)s" " up" " type macvtap mode bridge; " "ip link set t%(ic_name)s%(id)s" " promisc on " " up" % _kws, shell = True) # Add to the command line # note model=virtio WORKS with QEMU's BIOS OVMW_CODE.fd self.qemu_cmdline_append += \ " -net nic,id=%(ident)s,model=virtio,macaddr=%(mac_addr)s" \ " -net tap,fd=0,name=%(ident)s" % _kws # Add a nat/host interface? if ic_name == 'nat_host': raise RuntimeError("NAT configuration is currently broken") # we hardcode the MAC address of the NAT ethernet # interface, which we'll also add in the configuration # for systemd-network in /etc/systemd/network for it # to do DHCP. There is only one of those interfaces # per virtual host, so it will never conflict with # anything and we don't use the form of addressing in # any MAC we generate. mac_addr = "02:01:01:01:01:01" self.qemu_cmdline_append += \ " -net nic,name=nat_host,model=virtio,macaddr=%s" \ " -net user,id=nat_host,net=192.168.200.0/24,dhcpstart=192.168.200.10 " \ % mac_addr # If no network interfaces we added, remove the default # networking QEMU does if "-net" not in self.qemu_cmdline \ and "-net" not in self.qemu_cmdline_append: self.qemu_cmdline_append += "-net none "
def _power_on_pre_nw(self): # We need the __init__ part doing it earlier because remember, # these might be running different processes, and the basic # self.qemu_cmdline array has to be initialized so we can # find the actual binary being used. kws = dict(self.kws) # Get fresh values for these keys for key in self.fsdb.keys(): if key.startswith("qemu-"): kws[key] = self.fsdb.get(key) # Setup network stuff, create virtual tap interfaces for ic_name, ic_kws in self.tags.get('interconnects', {}).iteritems(): if 'ipv4_addr' in ic_kws or 'ipv6_addr' in ic_kws: _kws = dict(kws) _kws.update(ic_kws) _kws['ic_name'] = ic_name # QEMU device ident only allows a-zA-Z0-9-, starting # with letter _kws['ident'] = "id" + self._r_ident.sub("", _kws['mac_addr']) # CAP_NET_ADMIN is 12 (from /usr/include/linux/prctl.h if not commonl.prctl_cap_get_effective() & 1 << 12: # If we don't have network setting privilege, # don't even go there self.log.warning("daemon lacks CAP_NET_ADMIN: unable to " "add networking capabilities ") continue if not commonl.if_present("_b%s" % ic_name): self.log.warning("network %s powered off? networking " "disabled" % ic_name) # If the network is not powered up, skip it # FIXME: replace with it calling vlan_pci.something() # that brings up the basic interface (_bICNAME) so # that once we power the network, it works continue commonl.if_remove_maybe("t%s%s" % (ic_name, self.id)) subprocess.check_call( "ip link add " " link _b%(ic_name)s " " name t%(ic_name)s%(id)s" " address %(mac_addr)s" " up" " type macvtap mode bridge; " "ip link set t%(ic_name)s%(id)s" " promisc on " " up" % _kws, shell = True) # Add to the command line # note model=virtio WORKS with QEMU's BIOS OVMW_CODE.fd self.qemu_cmdline_append += \ " -net nic,id=%(ident)s,model=virtio,macaddr=%(mac_addr)s" \ " -net tap,fd=0,name=%(ident)s" % _kws # Add a nat/host interface? if ic_name == 'nat_host': raise RuntimeError("NAT configuration is currently broken") # we hardcode the MAC address of the NAT ethernet # interface, which we'll also add in the configuration # for systemd-network in /etc/systemd/network for it # to do DHCP. There is only one of those interfaces # per virtual host, so it will never conflict with # anything and we don't use the form of addressing in # any MAC we generate. mac_addr = "02:01:01:01:01:01" self.qemu_cmdline_append += \ " -net nic,name=nat_host,model=virtio,macaddr=%s" \ " -net user,id=nat_host,net=192.168.200.0/24,dhcpstart=192.168.200.10 " \ % mac_addr # If no network interfaces we added, remove the default # networking QEMU does if "-net" not in self.qemu_cmdline \ and "-net" not in self.qemu_cmdline_append: self.qemu_cmdline_append += "-net none "