Connect vif's to already running VMs on NetVM/ProxyVM startup (#190)
Also cleanup stale vifs using "xm network-detach ... -f" Fix iptables rules to support not only first vif of VM
This commit is contained in:
parent
655f13e2ec
commit
98f4028142
@ -5,7 +5,8 @@ netmask=`/usr/bin/xenstore-read qubes_netmask`
|
||||
gateway=`/usr/bin/xenstore-read qubes_gateway`
|
||||
secondary_dns=`/usr/bin/xenstore-read qubes_secondary_dns`
|
||||
if [ x$ip != x ]; then
|
||||
/sbin/ifconfig $INTERFACE $ip netmask 255.255.255.255 up
|
||||
/sbin/ifconfig $INTERFACE $ip netmask 255.255.255.255
|
||||
/sbin/ifconfig $INTERFACE up
|
||||
/sbin/route add default dev $INTERFACE
|
||||
echo "nameserver $gateway" > /etc/resolv.conf
|
||||
echo "nameserver $secondary_dns" >> /etc/resolv.conf
|
||||
|
@ -543,6 +543,28 @@ class QubesVm(object):
|
||||
f_private.truncate (size)
|
||||
f_private.close ()
|
||||
|
||||
def cleanup_vifs(self):
|
||||
"""
|
||||
Xend does not remove vif when backend domain is down, so we must do it
|
||||
manually
|
||||
"""
|
||||
|
||||
if not self.is_running():
|
||||
return
|
||||
|
||||
p = subprocess.Popen (["/usr/sbin/xm", "network-list", self.name],
|
||||
stdout=subprocess.PIPE)
|
||||
result = p.communicate()
|
||||
for line in result[0].split('\n'):
|
||||
m = re.match(r"^(\d+)\s*(\d+)", line)
|
||||
if m:
|
||||
retcode = subprocess.call(["/usr/sbin/xm", "list", m.group(2)],
|
||||
stderr=subprocess.PIPE)
|
||||
if retcode != 0:
|
||||
# Don't check retcode - it always will fail when backend domain is down
|
||||
subprocess.call(["/usr/sbin/xm",
|
||||
"network-detach", self.name, m.group(1), "-f"], stderr=subprocess.PIPE)
|
||||
|
||||
def create_xenstore_entries(self, xid):
|
||||
if dry_run:
|
||||
return
|
||||
@ -1371,6 +1393,29 @@ class QubesNetVm(QubesVm):
|
||||
|
||||
return subprocess.check_call(command)
|
||||
|
||||
def start(self, debug_console = False, verbose = False, preparing_dvm=False):
|
||||
if dry_run:
|
||||
return
|
||||
|
||||
xid=super(QubesNetVm, self).start(debug_console=debug_console, verbose=verbose)
|
||||
|
||||
# Connect vif's of already running VMs
|
||||
for vm in self.connected_vms.values():
|
||||
if not vm.is_running():
|
||||
continue
|
||||
|
||||
if verbose:
|
||||
print "--> Attaching network to '{0}'...".format(vm.name)
|
||||
|
||||
# Cleanup stale VIFs
|
||||
vm.cleanup_vifs()
|
||||
|
||||
xm_cmdline = ["/usr/sbin/xm", "network-attach", vm.name, "script=vif-route-qubes", "ip="+vm.ip, "backend="+self.name ]
|
||||
retcode = subprocess.call (xm_cmdline)
|
||||
if retcode != 0:
|
||||
print ("WARNING: Cannot attach to network to '{0}'!".format(vm.name))
|
||||
return xid
|
||||
|
||||
def add_external_ip_permission(self, xid):
|
||||
if int(xid) < 0:
|
||||
return
|
||||
@ -1471,7 +1516,7 @@ class QubesProxyVm(QubesNetVm):
|
||||
continue
|
||||
|
||||
iptables += "# '{0}' VM:\n".format(vm.name)
|
||||
iptables += "-A FORWARD ! -s {0}/32 -i vif{1}.0 -j DROP\n".format(vm.ip, xid)
|
||||
iptables += "-A FORWARD ! -s {0}/32 -i vif{1}.+ -j DROP\n".format(vm.ip, xid)
|
||||
|
||||
accept_action = "ACCEPT"
|
||||
reject_action = "REJECT --reject-with icmp-host-prohibited"
|
||||
@ -1484,7 +1529,7 @@ class QubesProxyVm(QubesNetVm):
|
||||
rules_action = accept_action
|
||||
|
||||
for rule in conf["rules"]:
|
||||
iptables += "-A FORWARD -i vif{0}.0 -d {1}".format(xid, rule["address"])
|
||||
iptables += "-A FORWARD -i vif{0}.+ -d {1}".format(xid, rule["address"])
|
||||
if rule["netmask"] != 32:
|
||||
iptables += "/{0}".format(rule["netmask"])
|
||||
|
||||
@ -1497,12 +1542,12 @@ class QubesProxyVm(QubesNetVm):
|
||||
|
||||
if conf["allowDns"]:
|
||||
# PREROUTING does DNAT to NetVM DNSes, so we need self.netvm_vm. properties
|
||||
iptables += "-A FORWARD -i vif{0}.0 -p udp -d {1} --dport 53 -j ACCEPT\n".format(xid,self.netvm_vm.gateway)
|
||||
iptables += "-A FORWARD -i vif{0}.0 -p udp -d {1} --dport 53 -j ACCEPT\n".format(xid,self.netvm_vm.secondary_dns)
|
||||
iptables += "-A FORWARD -i vif{0}.+ -p udp -d {1} --dport 53 -j ACCEPT\n".format(xid,self.netvm_vm.gateway)
|
||||
iptables += "-A FORWARD -i vif{0}.+ -p udp -d {1} --dport 53 -j ACCEPT\n".format(xid,self.netvm_vm.secondary_dns)
|
||||
if conf["allowIcmp"]:
|
||||
iptables += "-A FORWARD -i vif{0}.0 -p icmp -j ACCEPT\n".format(xid)
|
||||
iptables += "-A FORWARD -i vif{0}.+ -p icmp -j ACCEPT\n".format(xid)
|
||||
|
||||
iptables += "-A FORWARD -i vif{0}.0 -j {1}\n".format(xid, default_action)
|
||||
iptables += "-A FORWARD -i vif{0}.+ -j {1}\n".format(xid, default_action)
|
||||
|
||||
iptables += "#End of VM rules\n"
|
||||
iptables += "-A FORWARD -j DROP\n"
|
||||
|
@ -166,6 +166,9 @@ def main():
|
||||
parser.add_option ("--localcmd", action="store", dest="localcmd", default=None,
|
||||
help="With --pass_io, pass stdin/stdout/stderr to the given program")
|
||||
|
||||
parser.add_option ("--force", action="store_true", dest="force", default=False,
|
||||
help="Force operation, even if may damage other VMs (eg shutdown of NetVM)")
|
||||
|
||||
(options, args) = parser.parse_args ()
|
||||
|
||||
|
||||
@ -218,8 +221,12 @@ def main():
|
||||
|
||||
# If stopping NetVM - stop connected VMs too
|
||||
if options.shutdown and vm.is_netvm():
|
||||
vms_list += [vm for vm in qvm_collection.get_vms_connected_to(vm.qid) if vm.is_running()]
|
||||
vms_list.reverse()
|
||||
connected_vms = [vm for vm in qvm_collection.get_vms_connected_to(vm.qid) if vm.is_running()]
|
||||
if connected_vms and not options.force:
|
||||
print "ERROR: There are other VMs connected to this VM, "
|
||||
print " shutdown them first or use --force option"
|
||||
print "VMs list: " + str([vm.name for vm in connected_vms])
|
||||
exit(1)
|
||||
|
||||
if takes_cmd_argument:
|
||||
cmd = "{user}:{cmd}".format(user=options.user, cmd=cmdstr)
|
||||
|
Loading…
Reference in New Issue
Block a user