Fix VRRP gateway IP conflict on redundant VPC routers with external network providers (Netris/NSX) (#130)
Co-authored-by: Pearl Dsilva <pearl1954@gmail.com>
diff --git a/systemvm/debian/opt/cloud/bin/cs/CsAddress.py b/systemvm/debian/opt/cloud/bin/cs/CsAddress.py
index 37ca897..bdc2c91 100755
--- a/systemvm/debian/opt/cloud/bin/cs/CsAddress.py
+++ b/systemvm/debian/opt/cloud/bin/cs/CsAddress.py
@@ -23,12 +23,29 @@
from . import CsHelper
from .CsDatabag import CsDataBag
from .CsApp import CsApache, CsDnsmasq, CsPasswdSvc
+from .CsGuestNetwork import CsGuestNetwork
from .CsRoute import CsRoute
from .CsRule import CsRule
from .CsStaticRoutes import CsStaticRoutes
VRRP_TYPES = ['guest']
+
+def _guest_needs_vrrp(device, config):
+ """
+ A guest interface only needs to be managed by keepalived (i.e. have the
+ network gateway floated onto it as a VRRP virtual address) when the
+ CloudStack virtual router is actually the gateway for that network.
+ When an external provider (e.g. Netris) owns the gateway/source NAT for
+ the tier, the router must not also claim the gateway IP.
+ If no guestnetwork data is found for the device, default to the
+ historical behaviour (needs vrrp) to avoid regressing existing setups.
+ """
+ gn = CsGuestNetwork(device, config)
+ if gn.is_guestnetwork():
+ return gn.is_vr_guest_gateway()
+ return True
+
class CsAddress(CsDataBag):
def compare(self):
@@ -99,7 +116,7 @@
Returns if the ip needs to be managed by keepalived or not
"""
if "nw_type" in o and o['nw_type'] in VRRP_TYPES:
- return True
+ return _guest_needs_vrrp(o.get('device'), self.config)
return False
def get_control_if(self):
@@ -229,7 +246,7 @@
Returns if the ip needs to be managed by keepalived or not
"""
if "nw_type" in self.address and self.address['nw_type'] in VRRP_TYPES:
- return True
+ return _guest_needs_vrrp(self.get_device(), self.config)
return False
def is_control(self):
@@ -909,7 +926,7 @@
Returns if the ip needs to be managed by keepalived or not
"""
if "nw_type" in self.address and self.address['nw_type'] in VRRP_TYPES:
- return True
+ return _guest_needs_vrrp(self.dev, self.config)
return False
def is_public(self):