Added patches according to OSCI-846
[openstack-build/neutron-build.git] / debian / patches / fix-l3-agent.patch
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
7  import netaddr
8  from oslo.config import cfg
9 +from quantum.agent.linux.interface import OVSInterfaceDriver
10  
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)
20  
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())
32  
33 @@ -370,7 +373,9 @@ class L3NATAgent(manager.Manager):
34                      ri.floating_ips.append(new_fip)
35  
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))
40 +        return rv
41  
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))
46  
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]
52  
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]
58  
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
63 +        else:
64 +            return ifname
65  
66 +    def external_gateway_added(self, ri, ex_gw_port, internal_cidrs):
67 +        ### SV: patched !!!
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
87 +            )
88 +
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}."
92 +                .format(
93 +                    ip=ex_gw_port['ip_cidr'],
94 +                    iface=interface_name,
95 +                    eiface=effective_interface_name
96 +                )
97 +            )
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))
101 +        else:
102 +            self.driver.init_l3(interface_name, [ex_gw_port['ip_cidr']], namespace=ri.ns_name())
103 +
104 +        self._send_gratuitous_arp_packet(ri, effective_interface_name, ip_address)
105  
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)
113 -            else:
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)
123 +                else:
124 +                    utils.execute(cmd, check_exit_code=False, root_helper=self.root_helper)
125  
126 -        for (c, r) in self.external_gateway_nat_rules(ex_gw_ip,
127 -                                                      internal_cidrs,
128 -                                                      interface_name):
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()
132  
133      def external_gateway_removed(self, ri, ex_gw_port, internal_cidrs):
134 -
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']
138 +
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)
143 +
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)
150  
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,
153 -                                                    interface_name):
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()
157  
158 @@ -463,6 +495,7 @@ class L3NATAgent(manager.Manager):
159  
160      def external_gateway_nat_rules(self, ex_gw_ip, internal_cidrs,
161                                     interface_name):
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):
176          return rules
177  
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}."
188 +                .format(
189 +                    ip=ip_cidr,
190 +                    iface=interface_name,
191 +                    eiface=effective_interface_name
192 +                )
193 +            )
194 +        device = ip_lib.IPDevice(effective_interface_name, self.root_helper, namespace=ri.ns_name())
195  
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)
201  
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()
205  
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)
212  
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)
217  
218          for chain, rule in self.floating_forward_rules(floating_ip, fixed_ip):
219 @@ -642,7 +686,16 @@ class L3NATAgent(manager.Manager):
220                      self.fullsync = True
221  
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
231 +                )
232 +            )
233 +
234  
235      def _update_routing_table(self, ri, operation, route):
236          cmd = ['ip', 'route', operation, 'to', route['destination'],