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 1bd0949bab8..d49c47a8a72 100755 --- a/systemvm/patches/debian/config/opt/cloud/bin/cs/CsAddress.py +++ b/systemvm/patches/debian/config/opt/cloud/bin/cs/CsAddress.py @@ -96,14 +96,19 @@ class CsAddress(CsDataBag): return None def process(self): + route = CsRoute() + found_defaultroute = False + for dev in self.dbag: if dev == "id": continue ip = CsIP(dev, self.config) for address in self.dbag[dev]: - if not address["nw_type"] == "control": - CsRoute(dev).add(address) + + gateway = str(address["gateway"]) + network = str(address["network"]) + ip.setAddress(address) if ip.configured(): @@ -118,6 +123,16 @@ class CsAddress(CsDataBag): if CsDevice(dev, self.config).waitfordevice(): ip.configure() + if address["nw_type"] != "control": + route.add_route(dev, network) + + # once we start processing public ip's we need to verify there + # is a default route and add if needed + if address["nw_type"] == "public" and not found_defaultroute: + if not route.defaultroute_exists(): + if route.add_defaultroute(gateway): + found_defaultroute = True + class CsInterface: @@ -275,8 +290,8 @@ class CsIP: def post_configure(self): """ The steps that must be done after a device is configured """ if not self.get_type() in ["control"]: - route = CsRoute(self.dev) - route.routeTable() + route = CsRoute() + route.add_table(self.dev) CsRule(self.dev).addMark() self.check_is_up() self.set_mark() @@ -467,9 +482,13 @@ class CsIP: self.fw.append(["", "", "-A NETWORK_STATS -i eth2 ! -o eth0 -p tcp"]) def post_config_change(self, method): - route = CsRoute(self.dev) - route.routeTable() - route.add(self.address, method) + route = CsRoute() + if method == "add": + route.add_table(self.dev) + route.add_route(self.dev, str(self.address["network"])) + elif method == "delete": + logging.warn("delete route not implemented") + self.fw_router() self.fw_vpcrouter() # On deletion nw_type will no longer be known 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 234d9b9ffee..fd2d98987cc 100755 --- a/systemvm/patches/debian/config/opt/cloud/bin/cs/CsRoute.py +++ b/systemvm/patches/debian/config/opt/cloud/bin/cs/CsRoute.py @@ -23,27 +23,33 @@ class CsRoute: """ Manage routes """ - def __init__(self, dev): - self.dev = dev - self.tableNo = dev[3:] - self.table = "Table_%s" % (dev) + def __init__(self): + self.table_prefix = "Table_" - def routeTable(self): - str = "%s %s" % (self.tableNo, self.table) + def get_tablename(self, name): + return self.table_prefix + name + + def add_table(self, devicename): + tablenumber = devicename[3:] + tablename = self.get_tablename(devicename) + str = "%s %s" % (tablenumber, tablename) filename = "/etc/iproute2/rt_tables" logging.info( "Adding route table: " + str + " to " + filename + " if not present ") CsHelper.addifmissing(filename, str) - def flush(self): - CsHelper.execute("ip route flush table %s" % (self.table)) + def flush_table(self, tablename): + CsHelper.execute("ip route flush table %s" % (tablename)) CsHelper.execute("ip route flush cache") - def add(self, address, method="add"): - # ip route show dev eth1 table Table_eth1 10.0.2.0/24 - if(method == "add"): - cmd = "dev %s table %s %s" % (self.dev, self.table, address['network']) - self.set_route(cmd, method) + def add_route(self, dev, address): + """ Wrapper method that adds table name and device to route statement """ + # ip route add dev eth1 table Table_eth1 10.0.2.0/24 + table = self.get_tablename(dev) + logging.info("Adding route: dev " + dev + " table: " + + table + " network: " + address + " if not present") + cmd = "dev %s table %s %s" % (dev, table, address) + self.set_route(cmd) def set_route(self, cmd, method="add"): """ Add a route if it is not already defined """ @@ -59,3 +65,30 @@ class CsRoute: else: return CsHelper.execute(cmd) + + def add_defaultroute(self, gateway): + """ Add a default route + :param str gateway + :return: bool + """ + if gateway is not None: + cmd = "default via " + gateway + logging.info("Adding default route") + self.set_route(cmd) + return True + else: + return False + + def defaultroute_exists(self): + """ Return True if a default route is present + :return: bool + """ + logging.info("Checking if default ipv4 route is present") + route_found = CsHelper.execute("ip -4 route list 0/0") + + if len(route_found) > 0: + logging.info("Default route found: " + route_found[0]) + return True + else: + logging.warn("No default route found!") + return False diff --git a/systemvm/test/python/TestCsRoute.py b/systemvm/test/python/TestCsRoute.py index dc464d5fefd..6035258aa73 100644 --- a/systemvm/test/python/TestCsRoute.py +++ b/systemvm/test/python/TestCsRoute.py @@ -26,8 +26,21 @@ class TestCsRoute(unittest.TestCase): merge.DataBag.DPATH = "." def test_init(self): - csroute = CsRoute(["one", "two", "three", "four"]) - self.assertTrue(csroute is not None) + csroute = CsRoute() + self.assertIsInstance(csroute, CsRoute) + + def test_defaultroute_exists(self): + csroute = CsRoute() + self.assertFalse(csroute.defaultroute_exists()) + + def test_add_defaultroute(self): + csroute = CsRoute() + self.assertTrue(csroute.add_defaultroute("192.168.1.1")) + + def test_get_tablename(self): + csroute = CsRoute() + name = "eth1" + self.assertEqual("Table_eth1", csroute.get_tablename(name)) if __name__ == '__main__': unittest.main()