You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cloudstack.apache.org by ro...@apache.org on 2019/05/31 07:05:49 UTC
[cloudstack] branch 4.11 updated: systemvm: fix VR issues with
Multiple Public Subnets (#3361)
This is an automated email from the ASF dual-hosted git repository.
rohit pushed a commit to branch 4.11
in repository https://gitbox.apache.org/repos/asf/cloudstack.git
The following commit(s) were added to refs/heads/4.11 by this push:
new 2f268fb systemvm: fix VR issues with Multiple Public Subnets (#3361)
2f268fb is described below
commit 2f268fbb52203cae96d0cff57c189600abab1390
Author: Richard Lawley <ri...@richardlawley.com>
AuthorDate: Fri May 31 08:05:42 2019 +0100
systemvm: fix VR issues with Multiple Public Subnets (#3361)
This PR resolves 2 issues related to Virtual Routers with multiple public interfaces, and works around a third.
- Fixes #3353 - Adds missing throw routes for eth0/eth1 to eth3+ when there are >1 public IPs
- Fixes #3168 - Incorrect marks set on some static NAT rules (some code references were changed from hex(int(interfacenum)) to hex(100 + int(interfacenum)) - this change just adds the remaining ones
- Fixes #3352 - Work around that sends Gratuitous ARP messages when a HA VR becomes master to work around the problem of the MAC address being different between HA VRs. If that issue is fixed properly (i.e. a database entry for the subsequent interfaces so they can be static) then this is unnecessary, though should not cause any problems.
---
systemvm/debian/opt/cloud/bin/configure.py | 4 ++--
systemvm/debian/opt/cloud/bin/cs/CsAddress.py | 11 +++++-----
systemvm/debian/opt/cloud/bin/cs/CsRedundant.py | 27 +++++++++++++++++++++++++
3 files changed, 34 insertions(+), 8 deletions(-)
diff --git a/systemvm/debian/opt/cloud/bin/configure.py b/systemvm/debian/opt/cloud/bin/configure.py
index 253eb7c..4df9911 100755
--- a/systemvm/debian/opt/cloud/bin/configure.py
+++ b/systemvm/debian/opt/cloud/bin/configure.py
@@ -858,7 +858,7 @@ class CsForwardingRules(CsDataBag):
rule['protocol'],
rule['protocol'],
public_fwports,
- hex(int(public_fwinterface[3:]))
+ hex(100 + int(public_fwinterface[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" % \
(
@@ -927,7 +927,7 @@ class CsForwardingRules(CsDataBag):
rule["internal_ip"]])
self.fw.append(["mangle", "",
"-I PREROUTING -s %s/32 -m state --state NEW -j MARK --set-xmark %s/0xffffffff" %
- (rule["internal_ip"], hex(int(device[len("eth"):])))])
+ (rule["internal_ip"], hex(100 + int(device[len("eth"):])))])
self.fw.append(["nat", "front",
"-A PREROUTING -d %s/32 -j DNAT --to-destination %s" % (rule["public_ip"], rule["internal_ip"])])
self.fw.append(["nat", "front",
diff --git a/systemvm/debian/opt/cloud/bin/cs/CsAddress.py b/systemvm/debian/opt/cloud/bin/cs/CsAddress.py
index ab0cee6..8e67825 100755
--- a/systemvm/debian/opt/cloud/bin/cs/CsAddress.py
+++ b/systemvm/debian/opt/cloud/bin/cs/CsAddress.py
@@ -258,7 +258,7 @@ class CsIP:
def __init__(self, dev, config):
self.dev = dev
- self.dnum = hex(int(dev[3:]))
+ self.dnum = hex(100 + int(dev[3:]))
self.iplist = {}
self.address = {}
self.list()
@@ -518,12 +518,11 @@ class CsIP:
if method == "add":
if not self.config.is_vpc():
- # treat the first IP on a interface as special case to set up the routing rules
- if self.get_type() in ["public"] and (len(self.iplist) == 1):
- CsHelper.execute("sudo ip route add throw " + self.config.address().dbag['eth0'][0]['network'] + " table " + tableName + " proto static")
- CsHelper.execute("sudo ip route add throw " + self.config.address().dbag['eth1'][0]['network'] + " table " + tableName + " proto static")
+ if self.get_type() in ["public"]:
+ route.set_route("table %s throw %s proto static" % (tableName, self.config.address().dbag['eth0'][0]['network']))
+ route.set_route("table %s throw %s proto static" % (tableName, self.config.address().dbag['eth1'][0]['network']))
- # add 'defaul via gateway' rule in the device specific routing table
+ # add 'default via gateway' rule in the device specific routing table
if "gateway" in self.address and self.address["gateway"] and self.address["gateway"] != "None":
route.add_route(self.dev, self.address["gateway"])
if "network" in self.address and self.address["network"]:
diff --git a/systemvm/debian/opt/cloud/bin/cs/CsRedundant.py b/systemvm/debian/opt/cloud/bin/cs/CsRedundant.py
index 3ade4a2..25a4a1a 100755
--- a/systemvm/debian/opt/cloud/bin/cs/CsRedundant.py
+++ b/systemvm/debian/opt/cloud/bin/cs/CsRedundant.py
@@ -351,6 +351,33 @@ class CsRedundant(object):
interfaces = [interface for interface in self.address.get_interfaces() if interface.is_public()]
CsHelper.reconfigure_interfaces(self.cl, interfaces)
+
+ public_devices = list(set([interface.get_device() for interface in interfaces]))
+ if len(public_devices) > 1:
+ # Handle specific failures when multiple public interfaces
+
+ public_devices.sort()
+
+ # Ensure the default route is added, or outgoing traffic from VMs with static NAT on
+ # the subsequent interfaces will go from he wrong IP
+ route = CsRoute()
+ dev = ''
+ for interface in interfaces:
+ if dev == interface.get_device():
+ continue
+ dev = interface.get_device()
+ gateway = interface.get_gateway()
+ if gateway:
+ route.add_route(dev, gateway)
+
+ # The first public interface has a static MAC address between VRs. Subsequent ones don't,
+ # so an ARP announcement is needed on failover
+ for device in public_devices[1:]:
+ logging.info("Sending garp messages for IPs on %s" % device)
+ for interface in interfaces:
+ if interface.get_device() == device:
+ CsHelper.execute("arping -I %s -U %s -c 1" % (device, interface.get_ip()))
+
logging.info("Router switched to master mode")
def _collect_ignore_ips(self):