return True
+def get_routing_table(root_helper=None, namespace=None):
+ """Return a list of dictionaries, each representing a route.
+
+ The dictionary format is: {'destination': cidr,
+ 'nexthop': ip,
+ 'device': device_name}
+ """
+
+ ip_wrapper = IPWrapper(root_helper, namespace=namespace)
+ table = ip_wrapper.netns.execute(['ip', 'route'], check_exit_code=True)
+
+ routes = []
+ # Example for route_lines:
+ # default via 192.168.3.120 dev wlp3s0 proto static metric 1024
+ # 10.0.0.0/8 dev tun0 proto static scope link metric 1024
+ # The first column is the destination, followed by key/value pairs.
+ # The generator splits the routing table by newline, then strips and splits
+ # each individual line.
+ route_lines = (line.split() for line in table.split('\n') if line.strip())
+ for route in route_lines:
+ network = route[0]
+ # Create a dict of key/value pairs (For example - 'dev': 'tun0')
+ # excluding the first column.
+ data = dict(route[i:i + 2] for i in range(1, len(route), 2))
+ routes.append({'destination': network,
+ 'nexthop': data.get('via'),
+ 'device': data.get('dev')})
+ return routes
+
+
def ensure_device_is_ready(device_name, root_helper=None, namespace=None):
dev = IPDevice(device_name, root_helper, namespace)
dev.set_log_fail_as_error(False)
import collections
+import netaddr
from oslo.config import cfg
from oslo.utils import importutils
*attr, root_helper=self.root_helper))
device.link.delete()
+
+ def test_get_routing_table(self):
+ attr = self.generate_device_details()
+ device = self.manage_device(attr)
+ device_ip = attr.ip_cidr.split('/')[0]
+ destination = '8.8.8.0/24'
+ device.route.add_route(destination, device_ip)
+
+ expected_routes = [{'nexthop': device_ip,
+ 'device': attr.name,
+ 'destination': destination},
+ {'nexthop': None,
+ 'device': attr.name,
+ 'destination': str(
+ netaddr.IPNetwork(attr.ip_cidr).cidr)}]
+
+ routes = ip_lib.get_routing_table(self.root_helper, attr.namespace)
+ self.assertEqual(expected_routes, routes)
def generate_router_info(self, enable_ha):
return test_l3_agent.prepare_router_data(enable_snat=True,
enable_floating_ip=True,
- enable_ha=enable_ha)
+ enable_ha=enable_ha,
+ extra_routes=True)
def manage_router(self, agent, router):
self.addCleanup(self._delete_router, agent, router['id'])
}
virtual_routes {
0.0.0.0/0 via %(default_gateway_ip)s dev %(external_device_name)s
+ 8.8.8.0/24 via 19.4.4.4
}
}""" % {
'ha_confs_path': ha_confs_path,
self.assertTrue(self.device_exists_with_ip_mac(
device, self.agent.get_internal_device_name, router.ns_name))
+ def _assert_extra_routes(self, router):
+ routes = ip_lib.get_routing_table(self.root_helper, router.ns_name)
+ routes = [{'nexthop': route['nexthop'],
+ 'destination': route['destination']} for route in routes]
+
+ for extra_route in router.router['routes']:
+ self.assertIn(extra_route, routes)
+
class L3AgentTestCase(L3AgentTestFramework):
def test_observer_notifications_legacy_router(self):
self.assertIn(new_fip, new_config)
self.assertNotIn(old_gw, new_config)
self.assertIn(new_gw, new_config)
- self.assertNotIn(old_external_device_ip, new_config)
- self.assertIn(new_external_device_ip, new_config)
+ external_port = self.agent._get_ex_gw_port(router)
+ external_device_name = self.agent.get_external_device_name(
+ external_port['id'])
+ self.assertNotIn('%s/24 dev %s' %
+ (old_external_device_ip, external_device_name),
+ new_config)
+ self.assertIn('%s/24 dev %s' %
+ (new_external_device_ip, external_device_name),
+ new_config)
def _router_lifecycle(self, enable_ha):
router_info = self.generate_router_info(enable_ha)
self._assert_snat_chains(router)
self._assert_floating_ip_chains(router)
self._assert_metadata_chains(router)
+ self._assert_extra_routes(router)
if enable_ha:
self._assert_ha_device(router)
self._assert_snat_chains(router)
self._assert_floating_ip_chains(router)
self._assert_metadata_chains(router)
+ self._assert_extra_routes(router)
self._delete_router(self.agent, router.router_id)
self._assert_router_does_not_exist(router)
def prepare_router_data(ip_version=4, enable_snat=None, num_internal_ports=1,
- enable_floating_ip=False, enable_ha=False):
+ enable_floating_ip=False, enable_ha=False,
+ extra_routes=False):
if ip_version == 4:
ip_addr = '19.4.4.4'
cidr = '19.4.4.0/24'
'subnet': {'cidr': cidr,
'gateway_ip': gateway_ip}}
+ routes = []
+ if extra_routes:
+ routes = [{'destination': '8.8.8.0/24', 'nexthop': ip_addr}]
+
router = {
'id': router_id,
'distributed': False,
l3_constants.INTERFACE_KEY: [],
- 'routes': [],
+ 'routes': routes,
'gw_port': ex_gw_port}
if enable_floating_ip: