1 diff --git a/neunton/agent/l3_agent.py b/neunton/agent/l3_agent.py
2 index 79156cd..0037b80 100644
3 --- a/neunton/agent/l3_agent.py
4 +++ b/neunton/agent/l3_agent.py
5 @@ -23,6 +23,7 @@ import eventlet
6 from eventlet import semaphore
8 from oslo.config import cfg
9 +from quantum.agent.linux.interface import OVSInterfaceDriver
11 from neunton.agent.common import config
12 from neunton.agent.linux import external_process
13 @@ -233,7 +234,8 @@ class L3NATAgent(manager.Manager):
14 for c, r in self.metadata_nat_rules():
15 ri.iptables_manager.ipv4['nat'].add_rule(c, r)
16 ri.iptables_manager.apply()
17 - self._spawn_metadata_proxy(ri)
18 + if self.conf.use_namespaces:
19 + self._spawn_metadata_proxy(ri)
21 def _router_removed(self, router_id):
22 ri = self.router_info[router_id]
23 @@ -246,7 +248,8 @@ class L3NATAgent(manager.Manager):
24 for c, r in self.metadata_nat_rules():
25 ri.iptables_manager.ipv4['nat'].remove_rule(c, r)
26 ri.iptables_manager.apply()
27 - self._destroy_metadata_proxy(ri)
28 + if self.conf.use_namespaces:
29 + self._destroy_metadata_proxy(ri)
30 del self.router_info[router_id]
31 self._destroy_router_namespace(ri.ns_name())
33 @@ -370,7 +373,9 @@ class L3NATAgent(manager.Manager):
34 ri.floating_ips.append(new_fip)
36 def _get_ex_gw_port(self, ri):
37 - return ri.router.get('gw_port')
38 + rv = ri.router.get('gw_port')
39 + LOG.debug("***SV::_get_ex_gw_port: {0}".format(rv))
42 def _send_gratuitous_arp_packet(self, ri, interface_name, ip_address):
43 if self.conf.send_arp_for_ha > 0:
44 @@ -390,49 +395,78 @@ class L3NATAgent(manager.Manager):
45 LOG.error(_("Failed sending gratuitous ARP: %s"), str(e))
47 def get_internal_device_name(self, port_id):
48 - return (INTERNAL_DEV_PREFIX + port_id)[:self.driver.DEV_NAME_LEN]
49 + devname = INTERNAL_DEV_PREFIX + port_id
50 + LOG.debug("***SV::get_internal_device_name: {0}".format(devname))
51 + return devname[:self.driver.DEV_NAME_LEN]
53 def get_external_device_name(self, port_id):
54 - return (EXTERNAL_DEV_PREFIX + port_id)[:self.driver.DEV_NAME_LEN]
55 + devname = EXTERNAL_DEV_PREFIX + port_id
56 + LOG.debug("***SV::get_external_device_name: {0}".format(devname))
57 + return devname[:self.driver.DEV_NAME_LEN]
59 - def external_gateway_added(self, ri, ex_gw_port, internal_cidrs):
60 + def get_effective_interface_name(self, ifname):
61 + if not self.conf.use_namespaces:
62 + return self.conf.external_network_bridge
66 + def external_gateway_added(self, ri, ex_gw_port, internal_cidrs):
68 interface_name = self.get_external_device_name(ex_gw_port['id'])
69 + effective_interface_name = self.get_effective_interface_name(interface_name)
70 ex_gw_ip = ex_gw_port['fixed_ips'][0]['ip_address']
71 - if not ip_lib.device_exists(interface_name,
72 - root_helper=self.root_helper,
73 - namespace=ri.ns_name()):
74 + ip_address = ex_gw_port['ip_cidr'].split('/')[0]
75 + if not ip_lib.device_exists(interface_name, root_helper=self.root_helper, namespace=ri.ns_name()):
76 self.driver.plug(ex_gw_port['network_id'],
77 ex_gw_port['id'], interface_name,
78 ex_gw_port['mac_address'],
79 bridge=self.conf.external_network_bridge,
80 namespace=ri.ns_name(),
81 - prefix=EXTERNAL_DEV_PREFIX)
82 - self.driver.init_l3(interface_name, [ex_gw_port['ip_cidr']],
83 - namespace=ri.ns_name())
84 - ip_address = ex_gw_port['ip_cidr'].split('/')[0]
85 - self._send_gratuitous_arp_packet(ri, interface_name, ip_address)
86 + prefix=EXTERNAL_DEV_PREFIX
89 + if not self.conf.use_namespaces:
90 + LOG.info("Warning! You are not using network namespaces! "
91 + "IP {ip} will be assigned to interface {iface}, instead {eiface}."
93 + ip=ex_gw_port['ip_cidr'],
94 + iface=interface_name,
95 + eiface=effective_interface_name
98 + net = netaddr.IPNetwork(ex_gw_port['ip_cidr'])
99 + device = ip_lib.IPDevice(effective_interface_name, self.root_helper, namespace=ri.ns_name())
100 + device.addr.add(net.version, ex_gw_port['ip_cidr'], str(net.broadcast))
102 + self.driver.init_l3(interface_name, [ex_gw_port['ip_cidr']], namespace=ri.ns_name())
104 + self._send_gratuitous_arp_packet(ri, effective_interface_name, ip_address)
106 gw_ip = ex_gw_port['subnet']['gateway_ip']
107 - if ex_gw_port['subnet']['gateway_ip']:
108 - cmd = ['route', 'add', 'default', 'gw', gw_ip]
109 - if self.conf.use_namespaces:
110 - ip_wrapper = ip_lib.IPWrapper(self.root_helper,
111 - namespace=ri.ns_name())
112 - ip_wrapper.netns.execute(cmd, check_exit_code=False)
114 - utils.execute(cmd, check_exit_code=False,
115 - root_helper=self.root_helper)
116 + if interface_name == effective_interface_name:
117 + # work in net.namespaces, or 1st assignation on this interface
118 + if ex_gw_port['subnet']['gateway_ip']:
119 + cmd = ['route', 'add', 'default', 'gw', gw_ip]
120 + if self.conf.use_namespaces:
121 + ip_wrapper = ip_lib.IPWrapper(self.root_helper, namespace=ri.ns_name())
122 + ip_wrapper.netns.execute(cmd, check_exit_code=False)
124 + utils.execute(cmd, check_exit_code=False, root_helper=self.root_helper)
126 - for (c, r) in self.external_gateway_nat_rules(ex_gw_ip,
129 + for (c, r) in self.external_gateway_nat_rules(ex_gw_ip, internal_cidrs, effective_interface_name):
130 ri.iptables_manager.ipv4['nat'].add_rule(c, r)
131 ri.iptables_manager.apply()
133 def external_gateway_removed(self, ri, ex_gw_port, internal_cidrs):
135 interface_name = self.get_external_device_name(ex_gw_port['id'])
136 + effective_interface_name = self.get_effective_interface_name(interface_name)
137 + ex_gw_ip = ex_gw_port['fixed_ips'][0]['ip_address']
139 + if not self.conf.use_namespaces:
140 + net = netaddr.IPNetwork(ex_gw_ip)
141 + device = ip_lib.IPDevice(effective_interface_name, self.root_helper, namespace=ri.ns_name())
142 + device.addr.delete(net.version, ex_gw_ip)
144 if ip_lib.device_exists(interface_name,
145 root_helper=self.root_helper,
146 namespace=ri.ns_name()):
147 @@ -441,9 +475,7 @@ class L3NATAgent(manager.Manager):
148 namespace=ri.ns_name(),
149 prefix=EXTERNAL_DEV_PREFIX)
151 - ex_gw_ip = ex_gw_port['fixed_ips'][0]['ip_address']
152 - for c, r in self.external_gateway_nat_rules(ex_gw_ip, internal_cidrs,
154 + for c, r in self.external_gateway_nat_rules(ex_gw_ip, internal_cidrs, effective_interface_name):
155 ri.iptables_manager.ipv4['nat'].remove_rule(c, r)
156 ri.iptables_manager.apply()
158 @@ -463,6 +495,7 @@ class L3NATAgent(manager.Manager):
160 def external_gateway_nat_rules(self, ex_gw_ip, internal_cidrs,
162 + ### SV: need-patch !!!
163 rules = [('POSTROUTING', '! -i %(interface_name)s '
164 '! -o %(interface_name)s -m conntrack ! '
165 '--ctstate DNAT -j ACCEPT' % locals())]
166 @@ -475,7 +508,7 @@ class L3NATAgent(manager.Manager):
167 interface_name = self.get_internal_device_name(port_id)
168 if not ip_lib.device_exists(interface_name,
169 root_helper=self.root_helper,
170 - namespace=ri.ns_name()):
171 + namespace=ri.ns_name()): # check existing MAC address of qr_*
172 self.driver.plug(network_id, port_id, interface_name, mac_address,
173 namespace=ri.ns_name(),
174 prefix=INTERNAL_DEV_PREFIX)
175 @@ -513,27 +546,38 @@ class L3NATAgent(manager.Manager):
178 def floating_ip_added(self, ri, ex_gw_port, floating_ip, fixed_ip):
179 + ### SV: patched !!!
180 ip_cidr = str(floating_ip) + '/32'
181 interface_name = self.get_external_device_name(ex_gw_port['id'])
182 - device = ip_lib.IPDevice(interface_name, self.root_helper,
183 - namespace=ri.ns_name())
184 + effective_interface_name = self.get_effective_interface_name(interface_name)
185 + if not self.conf.use_namespaces:
186 + LOG.info("Warning! You are not using network namespaces! "
187 + "Floating IP {ip} will be assigned to interface {iface}, instead {eiface}."
190 + iface=interface_name,
191 + eiface=effective_interface_name
194 + device = ip_lib.IPDevice(effective_interface_name, self.root_helper, namespace=ri.ns_name())
196 if ip_cidr not in [addr['cidr'] for addr in device.addr.list()]:
197 net = netaddr.IPNetwork(ip_cidr)
198 device.addr.add(net.version, ip_cidr, str(net.broadcast))
199 - self._send_gratuitous_arp_packet(ri, interface_name, floating_ip)
200 + self._send_gratuitous_arp_packet(ri, effective_interface_name, floating_ip)
202 for chain, rule in self.floating_forward_rules(floating_ip, fixed_ip):
203 ri.iptables_manager.ipv4['nat'].add_rule(chain, rule)
204 ri.iptables_manager.apply()
206 def floating_ip_removed(self, ri, ex_gw_port, floating_ip, fixed_ip):
207 + ### SV: patched !!!
208 ip_cidr = str(floating_ip) + '/32'
209 net = netaddr.IPNetwork(ip_cidr)
210 interface_name = self.get_external_device_name(ex_gw_port['id'])
211 + effective_interface_name = self.get_effective_interface_name(interface_name)
213 - device = ip_lib.IPDevice(interface_name, self.root_helper,
214 - namespace=ri.ns_name())
215 + device = ip_lib.IPDevice(effective_interface_name, self.root_helper, namespace=ri.ns_name())
216 device.addr.delete(net.version, ip_cidr)
218 for chain, rule in self.floating_forward_rules(floating_ip, fixed_ip):
219 @@ -642,7 +686,16 @@ class L3NATAgent(manager.Manager):
222 def after_start(self):
223 - LOG.info(_("L3 agent started"))
224 + LOG.info(_("L3 agent started (Mirantis-patched)"))
225 + LOG.debug("*Ext.bridge name is '{0}'".format(self.conf.external_network_bridge))
226 + if not self.conf.use_namespaces:
227 + LOG.info("Warning!!!")
228 + LOG.info("You are not using network namespaces! "
229 + "Floating IPs will be assigned to interface {iface}".format(
230 + iface=self.conf.external_network_bridge
235 def _update_routing_table(self, ri, operation, route):
236 cmd = ['ip', 'route', operation, 'to', route['destination'],