Skip to content

Commit

Permalink
always push down metadata rules for router, not just if gateway exists
Browse files Browse the repository at this point in the history
bug 1051842

the l3-agent only pushes down some of the DNAT rules for metadata mapping
if there is a gateway set on a router. However, the nova-api server could
itself be running in the local router namespace (or on the same box as
the quantum-l3-agent in the case were namespaces are disabled. In fact,
with namespaces disabled, this is the likely setup for a simple
environment). Thus, we should simply always push down the metadata nat
rules for a router, router than waiting until a gateway is added.

This patch also refactors the actions taken by the l3-agent when a router
is added or removed into a separate function for improved readability,
as add/removing the nat rules made these code segments even longer.

Change-Id: I3c6eb35b51df3babf747dbcff7f943b850e69838
  • Loading branch information
Dan Wendlandt committed Sep 17, 2012
1 parent 2d20ad3 commit f6e9158
Showing 1 changed file with 34 additions and 17 deletions.
51 changes: 34 additions & 17 deletions quantum/agent/l3_agent.py
Original file line number Diff line number Diff line change
Expand Up @@ -219,21 +219,38 @@ def do_single_loop(self):
else:
continue
if r['id'] not in self.router_info:
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']])
self._router_added(r['id'])

ri = self.router_info[r['id']]
self.process_router(ri)

# identify and remove routers that no longer exist
for router_id in prev_router_ids - cur_router_ids:
ri = self.router_info[router_id]
del self.router_info[router_id]
self._destroy_router_namespace(ri.ns_name())
self._router_removed(router_id)
prev_router_ids = cur_router_ids

def _router_added(self, router_id):
ri = RouterInfo(router_id, self.conf.root_helper,
self.conf.use_namespaces)
self.router_info[router_id] = ri
if self.conf.use_namespaces:
self._create_router_namespace(ri)
for c, r in self.metadata_filter_rules():
ri.iptables_manager.ipv4['filter'].add_rule(c, r)
for c, r in self.metadata_nat_rules():
ri.iptables_manager.ipv4['nat'].add_rule(c, r)
ri.iptables_manager.apply()

def _router_removed(self, router_id):
ri = self.router_info[router_id]
for c, r in self.metadata_filter_rules():
ri.iptables_manager.ipv4['filter'].remove_rule(c, r)
for c, r in self.metadata_nat_rules():
ri.iptables_manager.ipv4['nat'].remove_rule(c, r)
ri.iptables_manager.apply()
del self.router_info[router_id]
self._destroy_router_namespace(ri.ns_name())

def _set_subnet_info(self, port):
ips = port['fixed_ips']
if not ips:
Expand Down Expand Up @@ -372,8 +389,6 @@ def external_gateway_added(self, ri, ex_gw_port, internal_cidrs):
utils.execute(cmd, check_exit_code=False,
root_helper=self.conf.root_helper)

for (c, r) in self.external_gateway_filter_rules():
ri.iptables_manager.ipv4['filter'].add_rule(c, r)
for (c, r) in self.external_gateway_nat_rules(ex_gw_ip,
internal_cidrs,
interface_name):
Expand All @@ -392,14 +407,12 @@ def external_gateway_removed(self, ri, ex_gw_port, internal_cidrs):
prefix=EXTERNAL_DEV_PREFIX)

ex_gw_ip = ex_gw_port['fixed_ips'][0]['ip_address']
for c, r in self.external_gateway_filter_rules():
ri.iptables_manager.ipv4['filter'].remove_rule(c, r)
for c, r in self.external_gateway_nat_rules(ex_gw_ip, internal_cidrs,
interface_name):
ri.iptables_manager.ipv4['nat'].remove_rule(c, r)
ri.iptables_manager.apply()

def external_gateway_filter_rules(self):
def metadata_filter_rules(self):
rules = []
if self.conf.metadata_ip:
rules.append(('INPUT', '-s 0.0.0.0/0 -d %s '
Expand All @@ -408,16 +421,20 @@ def external_gateway_filter_rules(self):
(self.conf.metadata_ip, self.conf.metadata_port)))
return rules

def external_gateway_nat_rules(self, ex_gw_ip, internal_cidrs,
interface_name):
rules = [('POSTROUTING', '! -i %(interface_name)s '
'! -o %(interface_name)s -m conntrack ! '
'--ctstate DNAT -j ACCEPT' % locals())]
def metadata_nat_rules(self):
rules = []
if self.conf.metadata_ip:
rules.append(('PREROUTING', '-s 0.0.0.0/0 -d 169.254.169.254/32 '
'-p tcp -m tcp --dport 80 -j DNAT '
'--to-destination %s:%s' %
(self.conf.metadata_ip, self.conf.metadata_port)))
return rules

def external_gateway_nat_rules(self, ex_gw_ip, internal_cidrs,
interface_name):
rules = [('POSTROUTING', '! -i %(interface_name)s '
'! -o %(interface_name)s -m conntrack ! '
'--ctstate DNAT -j ACCEPT' % locals())]
for cidr in internal_cidrs:
rules.extend(self.internal_network_nat_rules(ex_gw_ip, cidr))
return rules
Expand Down

0 comments on commit f6e9158

Please sign in to comment.