diff --git a/systemvm/patches/debian/config/opt/cloud/bin/configure.py b/systemvm/patches/debian/config/opt/cloud/bin/configure.py index 399c9c420cc..246c9959bb7 100755 --- a/systemvm/patches/debian/config/opt/cloud/bin/configure.py +++ b/systemvm/patches/debian/config/opt/cloud/bin/configure.py @@ -496,15 +496,22 @@ class CsForwardingRules(CsDataBag): elif rule["type"] == "staticnat": self.processStaticNatRule(rule) - def getDeviceByIp(self, ip): - ips = CsDataBag("ips") - dbag = ips.get_bag() - for device in dbag: - if device == "id": - continue - for addy in dbag[device]: - if addy["public_ip"] == ip: - return device + def getDeviceByIp(self, ipa): + for ip in self.config.address().get_ips(): + if ip.ip_in_subnet(ipa): + return ip.get_device() + return None + + def getNetworkByIp(self, ipa): + for ip in self.config.address().get_ips(): + if ip.ip_in_subnet(ipa): + return ip.get_network() + return None + + def getGatewayByIp(self, ipa): + for ip in self.config.address().get_ips(): + if ip.ip_in_subnet(ipa): + return ip.get_gateway() return None def portsToString(self, ports, delimiter): @@ -515,7 +522,70 @@ class CsForwardingRules(CsDataBag): return "%s%s%s" % (ports_parts[0], delimiter, ports_parts[1]) def processForwardRule(self, rule): - # FIXME this seems to be different for regular VRs? + if self.config.is_vpc(): + self.forward_vpc(rule) + else: + self.forward_vr(rule) + + def forward_vr(self, rule): + fw1 = "-A PREROUTING -d %s/32 -i %s -p %s -m %s --dport %s -j DNAT --to-destination %s:%s" % \ + ( rule['public_ip'], + self.getDeviceByIp(rule['public_ip']), + rule['protocol'], + rule['protocol'], + self.portsToString(rule['public_ports'], ':'), + rule['internal_ip'], + self.portsToString(rule['internal_ports'], '-') + ) + fw2 = "-A PREROUTING -d %s/32 -i %s -p %s -m %s --dport %s -j DNAT --to-destination %s:%s" % \ + ( rule['public_ip'], + self.getDeviceByIp(rule['internal_ip']), + rule['protocol'], + rule['protocol'], + self.portsToString(rule['public_ports'], ':'), + rule['internal_ip'], + self.portsToString(rule['internal_ports'], '-') + ) + fw3 = "-A OUTPUT -d %s/32 -p %s -m %s --dport %s -j DNAT --to-destination %s:%s" % \ + ( rule['public_ip'], + rule['protocol'], + rule['protocol'], + self.portsToString(rule['public_ports'], ':'), + rule['internal_ip'], + self.portsToString(rule['internal_ports'], '-') + ) + fw4 = "-j SNAT --to-source %s -A POSTROUTING -s %s -d %s/32 -o %s -p %s -m %s --dport %s" % \ + ( self.getGatewayByIp(rule['internal_ip']), + self.getNetworkByIp(rule['internal_ip']), + rule['internal_ip'], + self.getDeviceByIp(rule['internal_ip']), + rule['protocol'], + rule['protocol'], + self.portsToString(rule['internal_ports'], ':') + ) + fw5 = "-A PREROUTING -d %s/32 -i %s -p %s -m %s --dport %s -j MARK --set-xmark %s/0xffffffff" % \ + ( rule['public_ip'], + self.getDeviceByIp(rule['public_ip']), + rule['protocol'], + rule['protocol'], + self.portsToString(rule['public_ports'], ':'), + hex(int(self.getDeviceByIp(rule['public_ip'])[3:])) + ) + fw6 = "-A PREROUTING -d %s/32 -i %s -p %s -m %s --dport %s -m state --state NEW -j CONNMARK --save-mark --nfmask 0xffffffff --ctmask 0xffffffff" % \ + ( rule['public_ip'], + self.getDeviceByIp(rule['public_ip']), + rule['protocol'], + rule['protocol'], + self.portsToString(rule['public_ports'], ':'), + ) + self.fw.append(["nat", "", fw1]) + self.fw.append(["nat", "", fw2]) + self.fw.append(["nat", "", fw3]) + self.fw.append(["nat", "", fw4]) + self.fw.append(["nat", "", fw5]) + self.fw.append(["nat", "", fw6]) + + def forward_vpc(self, rule): fwrule = "-A PREROUTING -d %s/32" % rule["public_ip"] if not rule["protocol"] == "any": fwrule += " -m %s -p %s" % (rule["protocol"], rule["protocol"]) diff --git a/systemvm/patches/debian/config/opt/cloud/bin/cs/CsAddress.py b/systemvm/patches/debian/config/opt/cloud/bin/cs/CsAddress.py index f675a6554cd..7dc357bc1e8 100755 --- a/systemvm/patches/debian/config/opt/cloud/bin/cs/CsAddress.py +++ b/systemvm/patches/debian/config/opt/cloud/bin/cs/CsAddress.py @@ -19,6 +19,7 @@ from CsDatabag import CsDataBag, CsCmdLine from CsApp import CsApache, CsDnsmasq, CsPasswdSvc import CsHelper import logging +from netaddr import IPAddress, IPNetwork import CsHelper import subprocess @@ -118,6 +119,9 @@ class CsInterface: def get_ip(self): return self.get_attr("public_ip") + def get_network(self): + return self.get_attr("network") + def get_netmask(self): return self.get_attr("netmask") @@ -125,7 +129,15 @@ class CsInterface: if self.config.is_vpc(): return self.get_attr("gateway") else: - return self.config.cmdline().get_guest_gw() + if self.config.cmdline().is_redundant(): + return self.config.cmdline().get_guest_gw() + else: + return self.get_ip() + + def ip_in_subnet(self, ip): + ipo = IPAddress(ip) + net = IPNetwork("%s/%s" % (self.get_ip(), self.get_size())) + return ipo in list(net) def get_gateway_cidr(self): return "%s/%s" % (self.get_gateway(), self.get_size()) @@ -185,7 +197,7 @@ class CsDevice: self.table = '' self.tableNo = '' if dev != '': - self.tableNo = dev[3] + self.tableNo = dev[3:] self.table = "Table_%s" % dev self.fw = config.get_fw() self.cl = config.cmdline() @@ -228,7 +240,7 @@ class CsIP: def __init__(self, dev, config): self.dev = dev - self.dnum = dev[3] + self.dnum = hex(int(dev[3:])) self.iplist = {} self.address = {} self.list() @@ -275,8 +287,8 @@ class CsIP: CsHelper.execute(cmd2) def set_mark(self): - cmd = "-A PREROUTING -i %s -m state --state NEW -j CONNMARK --set-xmark 0x%s/0xffffffff" % \ - (self.getDevice(), self.getDevice()[3]) + cmd = "-A PREROUTING -i %s -m state --state NEW -j CONNMARK --set-xmark %s/0xffffffff" % \ + (self.getDevice(), self.dnum) self.fw.append(["mangle", "", cmd]) def get_type(self): @@ -327,7 +339,7 @@ class CsIP: "-A POSTROUTING -o eth2 -j SNAT --to-source %s" % self.address['public_ip']]) self.fw.append(["mangle", "", "-A PREROUTING -i %s -m state --state NEW " % self.dev + - "-j CONNMARK --set-xmark 0x%s/0xffffffff" % self.dnum]) + "-j CONNMARK --set-xmark %s/0xffffffff" % self.dnum]) self.fw.append(["mangle", "", "-A FIREWALL_%s -j DROP" % self.address['public_ip']]) self.fw.append(["filter", "", "-A INPUT -d 224.0.0.18/32 -j ACCEPT"]) @@ -350,7 +362,7 @@ class CsIP: self.fw.append(["filter", "", "-A FORWARD -i eth0 -o eth2 -j FW_OUTBOUND"]) self.fw.append(["mangle", "", "-A PREROUTING -i %s -m state --state NEW " % self.dev + - "-j CONNMARK --set-xmark 0x%s/0xffffffff" % self.dnum]) + "-j CONNMARK --set-xmark %s/0xffffffff" % self.dnum]) if self.get_type() in ["control"]: self.fw.append(["filter", "", "-A FW_OUTBOUND -m state --state RELATED,ESTABLISHED -j ACCEPT"]) diff --git a/systemvm/patches/debian/config/opt/cloud/bin/cs/CsDatabag.py b/systemvm/patches/debian/config/opt/cloud/bin/cs/CsDatabag.py index 035e864bc34..e8f15fed9ba 100755 --- a/systemvm/patches/debian/config/opt/cloud/bin/cs/CsDatabag.py +++ b/systemvm/patches/debian/config/opt/cloud/bin/cs/CsDatabag.py @@ -62,6 +62,14 @@ class CsCmdLine(CsDataBag): return self.idata()['router_pr'] return 99 + def set_guest_gw(self, val): + self.idata()['guestgw'] = val + + def get_guest_gw(self): + if "guestgw" in self.idata(): + return self.idata()['guestgw'] + return False + def set_priority(self, val): self.idata()['router_pr'] = val @@ -73,21 +81,6 @@ class CsCmdLine(CsDataBag): def set_redundant(self, val="true"): self.idata()['redundant_router'] = val - def set_guest_gw(self, val): - self.idata()['guestgw'] = val - - def get_guest_gw(self): - if "guestgw" in self.idata(): - return self.idata()['guestgw'] - else: - return "1.2.3.4" - - def get_guest_gw_cidr(self): - if "guestgw" in self.idata(): - return "%s/%s" % (self.idata()['guestgw'], self.idata()['guestcidrsize']) - else: - return "1.2.3.4/8" - def get_name(self): if "name" in self.idata(): return self.idata()['name'] diff --git a/systemvm/patches/debian/config/opt/cloud/bin/cs/CsDhcp.py b/systemvm/patches/debian/config/opt/cloud/bin/cs/CsDhcp.py index 821444f7459..234ed4cb1dd 100755 --- a/systemvm/patches/debian/config/opt/cloud/bin/cs/CsDhcp.py +++ b/systemvm/patches/debian/config/opt/cloud/bin/cs/CsDhcp.py @@ -98,7 +98,7 @@ class CsDhcp(CsDataBag): to = {"device": bits[0], "mac": bits[1], "ip": bits[2], - "host": bits[3], + "host": bits[3:], "del": False } changed.append(to) diff --git a/systemvm/patches/debian/config/opt/cloud/bin/cs/CsRoute.py b/systemvm/patches/debian/config/opt/cloud/bin/cs/CsRoute.py index f44ce5897e9..6fb6e1c6749 100755 --- a/systemvm/patches/debian/config/opt/cloud/bin/cs/CsRoute.py +++ b/systemvm/patches/debian/config/opt/cloud/bin/cs/CsRoute.py @@ -24,7 +24,7 @@ class CsRoute: def __init__(self, dev): self.dev = dev - self.tableNo = dev[3] + self.tableNo = dev[3:] self.table = "Table_%s" % (dev) def routeTable(self): diff --git a/systemvm/patches/debian/config/opt/cloud/bin/cs/CsRule.py b/systemvm/patches/debian/config/opt/cloud/bin/cs/CsRule.py index e2ca806f029..ed164b3bdc6 100755 --- a/systemvm/patches/debian/config/opt/cloud/bin/cs/CsRule.py +++ b/systemvm/patches/debian/config/opt/cloud/bin/cs/CsRule.py @@ -27,7 +27,7 @@ class CsRule: def __init__(self, dev): self.dev = dev - self.tableNo = dev[3] + self.tableNo = int(dev[3:]) self.table = "Table_%s" % (dev) def addMark(self): @@ -37,7 +37,7 @@ class CsRule: logging.info("Added fwmark rule for %s" % (self.table)) def findMark(self): - srch = "from all fwmark 0x%s lookup %s" % (self.tableNo, self.table) + srch = "from all fwmark %s lookup %s" % (hex(self.tableNo), self.table) for i in CsHelper.execute("ip rule show"): if srch in i.strip(): return True