]> review.fuel-infra Code Review - openstack-build/neutron-build.git/commitdiff
L3: make use of namespaces by agent configurable
authorGary Kotton <gkotton@redhat.com>
Mon, 27 Aug 2012 11:30:22 +0000 (07:30 -0400)
committerGary Kotton <gkotton@redhat.com>
Mon, 3 Sep 2012 21:16:40 +0000 (17:16 -0400)
Fixes bug 1042104

The fix follows the patch that was done on the DHCP agent to enable
the user to configure the usage of namespaces. In the event that
namspaces are disabled the agent is limited to running only one
router. The agent needs to define the router_id that is supported.
The process in this case is:
1. create router
2. start agent with router id

Change-Id: I2a71dc009c5aea285ff9f903b3faa99b0c9f820f

etc/l3_agent.ini
quantum/agent/l3_agent.py
quantum/tests/unit/test_l3_agent.py

index 121c4b47c9c40f187aa2740a1a7d6301f94725d9..46cafa3952cdf25f0d083aba6b304857c6a1606c 100644 (file)
@@ -21,3 +21,11 @@ admin_password = %SERVICE_PASSWORD%
 # root filter facility.
 # Change to "sudo" to skip the filtering and just run the comand directly
 root_helper = sudo
+
+# Allow overlapping IP (Must have kernel build with CONFIG_NET_NS=y and
+# iproute2 package that supports namespaces).
+# use_namespaces = True
+
+# If use_namespaces is set as False then the agent can only configure one router.
+# This is done by setting the specific router_id.
+# router_id =
index a93bf699cf6140aca0dd25cd1a6d5701d74a5579..fb634d051ad2f1b7a5a1ce7b205728c954cd11db 100644 (file)
@@ -43,12 +43,13 @@ EXTERNAL_DEV_PREFIX = 'qgw-'
 
 class RouterInfo(object):
 
-    def __init__(self, router_id, root_helper):
+    def __init__(self, router_id, root_helper, use_namespaces):
         self.router_id = router_id
         self.ex_gw_port = None
         self.internal_ports = []
         self.floating_ips = []
         self.root_helper = root_helper
+        self.use_namespaces = use_namespaces
 
         self.iptables_manager = iptables_manager.IptablesManager(
             root_helper=root_helper,
@@ -56,7 +57,8 @@ class RouterInfo(object):
             namespace=self.ns_name())
 
     def ns_name(self):
-        return NS_PREFIX + self.router_id
+        if self.use_namespaces:
+            return NS_PREFIX + self.router_id
 
 
 class L3NATAgent(object):
@@ -84,7 +86,12 @@ class L3NATAgent(object):
         #FIXME(danwent): not currently used
         cfg.BoolOpt('send_arp_for_ha',
                     default=True,
-                    help="Send gratuitious ARP when router IP is configured")
+                    help="Send gratuitious ARP when router IP is configured"),
+        cfg.BoolOpt('use_namespaces', default=True,
+                    help="Allow overlapping IP."),
+        cfg.StrOpt('router_id', default='',
+                   help="If namespaces is disabled, the l3 agent can only"
+                        " confgure a router that has the matching router ID.")
     ]
 
     def __init__(self, conf):
@@ -141,7 +148,8 @@ class L3NATAgent(object):
             elif d.name.startswith(EXTERNAL_DEV_PREFIX):
                 self.driver.unplug(d.name,
                                    bridge=self.conf.external_network_bridge)
-        ns_ip.netns.delete(namespace)
+        if self.conf.use_namespaces:
+            ns_ip.netns.delete(namespace)
 
     def _create_router_namespace(self, ri):
             ip_wrapper_root = ip_lib.IPWrapper(self.conf.root_helper)
@@ -172,11 +180,18 @@ class L3NATAgent(object):
         for r in self.qclient.list_routers()['routers']:
             #FIXME(danwent): handle admin state
 
-            cur_router_ids.add(r['id'])
+            # If namespaces are disabled, only process the router associated
+            # with the configured agent id.
+            if (self.conf.use_namespaces or
+                r['id'] == self.conf.router_id):
+                cur_router_ids.add(r['id'])
+            else:
+                continue
             if r['id'] not in self.router_info:
-                self.router_info[r['id']] = RouterInfo(r['id'],
-                                                       self.conf.root_helper)
-                self._create_router_namespace(self.router_info[r['id']])
+                self.router_info[r['id']] = RouterInfo(
+                    r['id'], self.conf.root_helper, self.conf.use_namespaces)
+                if self.conf.use_namespaces:
+                    self._create_router_namespace(self.router_info[r['id']])
 
             ri = self.router_info[r['id']]
             self.process_router(ri)
@@ -320,7 +335,8 @@ class L3NATAgent(object):
             cmd = ['route', 'add', 'default', 'gw', gw_ip]
             ip_wrapper = ip_lib.IPWrapper(self.conf.root_helper,
                                           namespace=ri.ns_name())
-            ip_wrapper.netns.execute(cmd)
+            if self.conf.use_namespaces:
+                ip_wrapper.netns.execute(cmd)
 
         for (c, r) in self.external_gateway_filter_rules():
             ri.iptables_manager.ipv4['filter'].add_rule(c, r)
index 8b3fd4c9a125693ed64cfa0ea8cd23dd2fab0ace..587f611fe9e2d59d4629aa44aa17215ea64539a5 100644 (file)
@@ -73,7 +73,8 @@ class TestBasicRouterOperations(unittest.TestCase):
 
     def testRouterInfoCreate(self):
         id = _uuid()
-        ri = l3_agent.RouterInfo(id, self.conf.root_helper)
+        ri = l3_agent.RouterInfo(id, self.conf.root_helper,
+                                 self.conf.use_namespaces)
 
         self.assertTrue(ri.ns_name().endswith(id))
 
@@ -87,7 +88,8 @@ class TestBasicRouterOperations(unittest.TestCase):
         port_id = _uuid()
         router_id = _uuid()
         network_id = _uuid()
-        ri = l3_agent.RouterInfo(router_id, self.conf.root_helper)
+        ri = l3_agent.RouterInfo(router_id, self.conf.root_helper,
+                                 self.conf.use_namespaces)
         agent = l3_agent.L3NATAgent(self.conf)
         interface_name = agent.get_internal_device_name(port_id)
         cidr = '99.0.1.9/24'
@@ -115,7 +117,8 @@ class TestBasicRouterOperations(unittest.TestCase):
 
     def _test_external_gateway_action(self, action):
         router_id = _uuid()
-        ri = l3_agent.RouterInfo(router_id, self.conf.root_helper)
+        ri = l3_agent.RouterInfo(router_id, self.conf.root_helper,
+                                 self.conf.use_namespaces)
         agent = l3_agent.L3NATAgent(self.conf)
         internal_cidrs = ['100.0.1.0/24', '200.74.0.0/16']
         ex_gw_port = {'fixed_ips': [{'ip_address': '20.0.0.30',
@@ -148,7 +151,8 @@ class TestBasicRouterOperations(unittest.TestCase):
 
     def _test_floating_ip_action(self, action):
         router_id = _uuid()
-        ri = l3_agent.RouterInfo(router_id, self.conf.root_helper)
+        ri = l3_agent.RouterInfo(router_id, self.conf.root_helper,
+                                 self.conf.use_namespaces)
         agent = l3_agent.L3NATAgent(self.conf)
         floating_ip = '20.0.0.100'
         fixed_ip = '10.0.0.23'
@@ -179,7 +183,8 @@ class TestBasicRouterOperations(unittest.TestCase):
 
         agent = l3_agent.L3NATAgent(self.conf)
         router_id = _uuid()
-        ri = l3_agent.RouterInfo(router_id, self.conf.root_helper)
+        ri = l3_agent.RouterInfo(router_id, self.conf.root_helper,
+                                 self.conf.use_namespaces)
 
         # return data so that state is built up
         ex_gw_port = {'id': _uuid(),