NSXv: Use BGP protocol to learn default gateways
We'd want to use ECMP when BGP is configured, the current code implements that by adding default static routes to BGP peers. This patch remove this behaviour, instead, admin is responsible to configure the GW edge with the default-originate feature enabled and adding the appropriate redistribution rule. Change-Id: Ib3e38f07583afa583beeac86ebdb1cd2ceb1ab6f
This commit is contained in:
parent
8548f110ac
commit
952d37e614
@ -673,6 +673,14 @@ nsxv_opts = [
|
|||||||
cfg.BoolOpt('exclusive_dhcp_edge',
|
cfg.BoolOpt('exclusive_dhcp_edge',
|
||||||
default=False,
|
default=False,
|
||||||
help=_("(Optional) Have exclusive DHCP edge per network.")),
|
help=_("(Optional) Have exclusive DHCP edge per network.")),
|
||||||
|
cfg.IntOpt('bgp_neighbour_hold_down_timer',
|
||||||
|
default=4,
|
||||||
|
help=_("(Optional) Set the interval (Seconds) for BGP "
|
||||||
|
"neighbour hold down time.")),
|
||||||
|
cfg.IntOpt('bgp_neighbour_keep_alive_timer',
|
||||||
|
default=1,
|
||||||
|
help=_("(Optional) Set the interval (Seconds) for BGP "
|
||||||
|
"neighbour keep alive time.")),
|
||||||
]
|
]
|
||||||
|
|
||||||
# define the configuration of each NSX-V availability zone.
|
# define the configuration of each NSX-V availability zone.
|
||||||
|
@ -57,6 +57,7 @@ class EdgeDynamicRoutingDriver(object):
|
|||||||
for prx in global_config['ipPrefixes']['ipPrefixes']]
|
for prx in global_config['ipPrefixes']['ipPrefixes']]
|
||||||
global_config['ipPrefixes'] = curr_prefixes
|
global_config['ipPrefixes'] = curr_prefixes
|
||||||
|
|
||||||
|
# Don't change any static routes.
|
||||||
static_routing = config.get('staticRouting', {})
|
static_routing = config.get('staticRouting', {})
|
||||||
static_routes = static_routing.get('staticRoutes', {})
|
static_routes = static_routing.get('staticRoutes', {})
|
||||||
current_routes = [{'route': route}
|
current_routes = [{'route': route}
|
||||||
@ -128,29 +129,8 @@ class EdgeDynamicRoutingDriver(object):
|
|||||||
|
|
||||||
self.vcns.update_bgp_dynamic_routing(edge_id, bgp_config)
|
self.vcns.update_bgp_dynamic_routing(edge_id, bgp_config)
|
||||||
|
|
||||||
def _get_edge_static_routes(self, edge_id):
|
|
||||||
h, routes = self.vcns.get_routes(edge_id)
|
|
||||||
static_routes = routes if routes else {}
|
|
||||||
static_routes.setdefault('staticRoutes', {'staticRoutes': []})
|
|
||||||
return static_routes
|
|
||||||
|
|
||||||
def _remove_default_static_routes(self, edge_id, droutes=None):
|
|
||||||
routes = self._get_edge_static_routes(edge_id)
|
|
||||||
# if droutes is empty or None, then remove all default static routes
|
|
||||||
droutes = droutes or routes['staticRoutes']['staticRoutes']
|
|
||||||
droutes = [r['nextHop'] for r in droutes]
|
|
||||||
routes['staticRoutes']['staticRoutes'] = [
|
|
||||||
r for r in routes['staticRoutes']['staticRoutes']
|
|
||||||
if r['network'] != '0.0.0.0/0' or r['nextHop'] not in droutes]
|
|
||||||
self.vcns.update_routes(edge_id, routes)
|
|
||||||
|
|
||||||
def _add_default_static_routes(self, edge_id, default_routes):
|
|
||||||
routes = self._get_edge_static_routes(edge_id)
|
|
||||||
routes['staticRoutes']['staticRoutes'].extend(default_routes)
|
|
||||||
self.vcns.update_routes(edge_id, routes)
|
|
||||||
|
|
||||||
def add_bgp_speaker_config(self, edge_id, prot_router_id, local_as,
|
def add_bgp_speaker_config(self, edge_id, prot_router_id, local_as,
|
||||||
enabled, default_routes, bgp_neighbours,
|
enabled, bgp_neighbours,
|
||||||
prefixes, redistribution_rules):
|
prefixes, redistribution_rules):
|
||||||
with locking.LockManager.get_lock(str(edge_id)):
|
with locking.LockManager.get_lock(str(edge_id)):
|
||||||
self._update_routing_config(edge_id,
|
self._update_routing_config(edge_id,
|
||||||
@ -161,30 +141,22 @@ class EdgeDynamicRoutingDriver(object):
|
|||||||
neighbours_to_add=bgp_neighbours,
|
neighbours_to_add=bgp_neighbours,
|
||||||
prefixes_to_add=prefixes,
|
prefixes_to_add=prefixes,
|
||||||
rules_to_add=redistribution_rules)
|
rules_to_add=redistribution_rules)
|
||||||
self._add_default_static_routes(edge_id, default_routes)
|
|
||||||
|
|
||||||
def delete_bgp_speaker_config(self, edge_id):
|
def delete_bgp_speaker_config(self, edge_id):
|
||||||
with locking.LockManager.get_lock(str(edge_id)):
|
with locking.LockManager.get_lock(str(edge_id)):
|
||||||
self.vcns.delete_bgp_routing_config(edge_id)
|
self.vcns.delete_bgp_routing_config(edge_id)
|
||||||
self._remove_default_static_routes(edge_id)
|
|
||||||
self._reset_routing_global_config(edge_id)
|
self._reset_routing_global_config(edge_id)
|
||||||
|
|
||||||
def add_bgp_neighbours(self, edge_id, bgp_neighbours,
|
def add_bgp_neighbours(self, edge_id, bgp_neighbours):
|
||||||
default_routes=None):
|
|
||||||
# Query the bgp config first and update the bgpNeighbour
|
# Query the bgp config first and update the bgpNeighbour
|
||||||
with locking.LockManager.get_lock(str(edge_id)):
|
with locking.LockManager.get_lock(str(edge_id)):
|
||||||
self._update_bgp_routing_config(edge_id,
|
self._update_bgp_routing_config(edge_id,
|
||||||
neighbours_to_add=bgp_neighbours)
|
neighbours_to_add=bgp_neighbours)
|
||||||
if default_routes:
|
|
||||||
self._add_default_static_routes(edge_id, default_routes)
|
|
||||||
|
|
||||||
def remove_bgp_neighbours(self, edge_id, bgp_neighbours,
|
def remove_bgp_neighbours(self, edge_id, bgp_neighbours):
|
||||||
default_routes=None):
|
|
||||||
with locking.LockManager.get_lock(str(edge_id)):
|
with locking.LockManager.get_lock(str(edge_id)):
|
||||||
self._update_bgp_routing_config(
|
self._update_bgp_routing_config(
|
||||||
edge_id, neighbours_to_remove=bgp_neighbours)
|
edge_id, neighbours_to_remove=bgp_neighbours)
|
||||||
if default_routes:
|
|
||||||
self._remove_default_static_routes(edge_id, default_routes)
|
|
||||||
|
|
||||||
def update_bgp_neighbours(self, edge_id, neighbours_to_add=None,
|
def update_bgp_neighbours(self, edge_id, neighbours_to_add=None,
|
||||||
neighbours_to_remove=None):
|
neighbours_to_remove=None):
|
||||||
|
@ -56,7 +56,9 @@ def bgp_neighbour(bgp_peer):
|
|||||||
'ipAddress': bgp_peer['peer_ip'],
|
'ipAddress': bgp_peer['peer_ip'],
|
||||||
'remoteAS': bgp_peer['remote_as'],
|
'remoteAS': bgp_peer['remote_as'],
|
||||||
'bgpFilters': bgp_filter,
|
'bgpFilters': bgp_filter,
|
||||||
'password': bgp_peer['password']
|
'password': bgp_peer['password'],
|
||||||
|
'holdDownTimer': cfg.CONF.nsxv.bgp_neighbour_hold_down_timer,
|
||||||
|
'keepAliveTimer': cfg.CONF.nsxv.bgp_neighbour_keep_alive_timer
|
||||||
}
|
}
|
||||||
return {'bgpNeighbour': nbr}
|
return {'bgpNeighbour': nbr}
|
||||||
|
|
||||||
@ -67,16 +69,13 @@ def gw_bgp_neighbour(ip_address, remote_as, password):
|
|||||||
'ipAddress': ip_address,
|
'ipAddress': ip_address,
|
||||||
'remoteAS': remote_as,
|
'remoteAS': remote_as,
|
||||||
'bgpFilters': bgp_filter,
|
'bgpFilters': bgp_filter,
|
||||||
'password': password
|
'password': password,
|
||||||
|
'holdDownTimer': cfg.CONF.nsxv.bgp_neighbour_hold_down_timer,
|
||||||
|
'keepAliveTimer': cfg.CONF.nsxv.bgp_neighbour_keep_alive_timer
|
||||||
}
|
}
|
||||||
return {'bgpNeighbour': nbr}
|
return {'bgpNeighbour': nbr}
|
||||||
|
|
||||||
|
|
||||||
def default_route(nexthop):
|
|
||||||
return {'network': '0.0.0.0/0',
|
|
||||||
'nextHop': nexthop}
|
|
||||||
|
|
||||||
|
|
||||||
class NSXvBgpDriver(object):
|
class NSXvBgpDriver(object):
|
||||||
"""Class driver to address the neutron_dynamic_routing API"""
|
"""Class driver to address the neutron_dynamic_routing API"""
|
||||||
|
|
||||||
@ -274,19 +273,17 @@ class NSXvBgpDriver(object):
|
|||||||
# list of tenant edge routers to be removed as bgp-neighbours to this
|
# list of tenant edge routers to be removed as bgp-neighbours to this
|
||||||
# peer if it's associated with specific ESG.
|
# peer if it's associated with specific ESG.
|
||||||
neighbours = []
|
neighbours = []
|
||||||
droute = default_route(nbr['bgpNeighbour']['ipAddress'])
|
|
||||||
for binding in bgp_bindings:
|
for binding in bgp_bindings:
|
||||||
try:
|
try:
|
||||||
self._nsxv.add_bgp_neighbours(binding['edge_id'], [nbr],
|
self._nsxv.add_bgp_neighbours(binding['edge_id'], [nbr])
|
||||||
default_routes=[droute])
|
|
||||||
except vcns_exc.VcnsApiException:
|
except vcns_exc.VcnsApiException:
|
||||||
LOG.error("Failed to add BGP neighbour on '%s'",
|
LOG.error("Failed to add BGP neighbour on '%s'",
|
||||||
binding['edge_id'])
|
binding['edge_id'])
|
||||||
else:
|
else:
|
||||||
nbr = gw_bgp_neighbour(binding['bgp_identifier'],
|
gw_nbr = gw_bgp_neighbour(binding['bgp_identifier'],
|
||||||
speaker['local_as'],
|
speaker['local_as'],
|
||||||
self._edge_password)
|
self._edge_password)
|
||||||
neighbours.append(nbr)
|
neighbours.append(gw_nbr)
|
||||||
LOG.debug("Succesfully added BGP neighbor '%s' on '%s'",
|
LOG.debug("Succesfully added BGP neighbor '%s' on '%s'",
|
||||||
bgp_peer_obj['peer_ip'], binding['edge_id'])
|
bgp_peer_obj['peer_ip'], binding['edge_id'])
|
||||||
|
|
||||||
@ -309,19 +306,17 @@ class NSXvBgpDriver(object):
|
|||||||
# list of tenant edge routers to be removed as bgp-neighbours to this
|
# list of tenant edge routers to be removed as bgp-neighbours to this
|
||||||
# peer if it's associated with specific ESG.
|
# peer if it's associated with specific ESG.
|
||||||
neighbours = []
|
neighbours = []
|
||||||
droute = default_route(nbr['bgpNeighbour']['ipAddress'])
|
|
||||||
for binding in bgp_bindings:
|
for binding in bgp_bindings:
|
||||||
try:
|
try:
|
||||||
self._nsxv.remove_bgp_neighbours(binding['edge_id'], [nbr],
|
self._nsxv.remove_bgp_neighbours(binding['edge_id'], [nbr])
|
||||||
default_routes=[droute])
|
|
||||||
except vcns_exc.VcnsApiException:
|
except vcns_exc.VcnsApiException:
|
||||||
LOG.error("Failed to remove BGP neighbour on '%s'",
|
LOG.error("Failed to remove BGP neighbour on '%s'",
|
||||||
binding['edge_id'])
|
binding['edge_id'])
|
||||||
else:
|
else:
|
||||||
nbr = gw_bgp_neighbour(binding['bgp_identifier'],
|
gw_nbr = gw_bgp_neighbour(binding['bgp_identifier'],
|
||||||
speaker['local_as'],
|
speaker['local_as'],
|
||||||
self._edge_password)
|
self._edge_password)
|
||||||
neighbours.append(nbr)
|
neighbours.append(gw_nbr)
|
||||||
LOG.debug("Succesfully removed BGP neighbor '%s' on '%s'",
|
LOG.debug("Succesfully removed BGP neighbor '%s' on '%s'",
|
||||||
bgp_peer_obj['peer_ip'], binding['edge_id'])
|
bgp_peer_obj['peer_ip'], binding['edge_id'])
|
||||||
|
|
||||||
@ -390,11 +385,9 @@ class NSXvBgpDriver(object):
|
|||||||
subnets, advertise_static_routes)
|
subnets, advertise_static_routes)
|
||||||
|
|
||||||
bgp_neighbours = [bgp_neighbour(bgp_peer) for bgp_peer in bgp_peers]
|
bgp_neighbours = [bgp_neighbour(bgp_peer) for bgp_peer in bgp_peers]
|
||||||
default_routes = [default_route(peer['peer_ip']) for peer in bgp_peers]
|
|
||||||
try:
|
try:
|
||||||
self._nsxv.add_bgp_speaker_config(edge_id, bgp_identifier,
|
self._nsxv.add_bgp_speaker_config(edge_id, bgp_identifier,
|
||||||
local_as, enabled_state,
|
local_as, enabled_state,
|
||||||
default_routes,
|
|
||||||
bgp_neighbours, prefixes,
|
bgp_neighbours, prefixes,
|
||||||
redis_rules)
|
redis_rules)
|
||||||
except vcns_exc.VcnsApiException:
|
except vcns_exc.VcnsApiException:
|
||||||
|
Loading…
Reference in New Issue
Block a user