~ubuntu-branches/ubuntu/saucy/neutron/saucy-security

« back to all changes in this revision

Viewing changes to neutron/agent/l3_agent.py

  • Committer: Package Import Robot
  • Author(s): Jamie Strandboge
  • Date: 2014-05-05 12:19:54 UTC
  • mfrom: (14.1.4 saucy-proposed)
  • Revision ID: package-import@ubuntu.com-20140505121954-gora8vy6l804ht3n
Tags: 1:2013.2.3-0ubuntu1.1
SECURITY UPDATE: no change rebuild for security to fix CVE-2014-0056
(1faec83a)

Show diffs side-by-side

added added

removed removed

Lines of Context:
50
50
INTERNAL_DEV_PREFIX = 'qr-'
51
51
EXTERNAL_DEV_PREFIX = 'qg-'
52
52
RPC_LOOP_INTERVAL = 1
 
53
FLOATING_IP_CIDR_SUFFIX = '/32'
53
54
 
54
55
 
55
56
class L3PluginApi(proxy.RpcProxy):
95
96
        self._snat_enabled = None
96
97
        self._snat_action = None
97
98
        self.internal_ports = []
98
 
        self.floating_ips = []
99
99
        self.root_helper = root_helper
100
100
        self.use_namespaces = use_namespaces
101
101
        # Invoke the setter for establishing initial SNAT action
409
409
                               internal_cidrs, interface_name)
410
410
 
411
411
        # Process DNAT rules for floating IPs
412
 
        if ex_gw_port or ri.ex_gw_port:
 
412
        if ex_gw_port:
413
413
            self.process_router_floating_ips(ri, ex_gw_port)
414
414
 
415
415
        ri.ex_gw_port = ex_gw_port
440
440
        ri.iptables_manager.apply()
441
441
 
442
442
    def process_router_floating_ips(self, ri, ex_gw_port):
443
 
        floating_ips = ri.router.get(l3_constants.FLOATINGIP_KEY, [])
444
 
        existing_floating_ip_ids = set([fip['id'] for fip in ri.floating_ips])
445
 
        cur_floating_ip_ids = set([fip['id'] for fip in floating_ips])
446
 
 
447
 
        id_to_fip_map = {}
448
 
 
449
 
        for fip in floating_ips:
450
 
            if fip['port_id']:
451
 
                if fip['id'] not in existing_floating_ip_ids:
452
 
                    ri.floating_ips.append(fip)
453
 
                    self.floating_ip_added(ri, ex_gw_port,
454
 
                                           fip['floating_ip_address'],
455
 
                                           fip['fixed_ip_address'])
456
 
 
457
 
                # store to see if floatingip was remapped
458
 
                id_to_fip_map[fip['id']] = fip
459
 
 
460
 
        floating_ip_ids_to_remove = (existing_floating_ip_ids -
461
 
                                     cur_floating_ip_ids)
462
 
        for fip in ri.floating_ips:
463
 
            if fip['id'] in floating_ip_ids_to_remove:
464
 
                ri.floating_ips.remove(fip)
465
 
                self.floating_ip_removed(ri, ri.ex_gw_port,
466
 
                                         fip['floating_ip_address'],
467
 
                                         fip['fixed_ip_address'])
468
 
            else:
469
 
                # handle remapping of a floating IP
470
 
                new_fip = id_to_fip_map[fip['id']]
471
 
                new_fixed_ip = new_fip['fixed_ip_address']
472
 
                existing_fixed_ip = fip['fixed_ip_address']
473
 
                if (new_fixed_ip and existing_fixed_ip and
474
 
                        new_fixed_ip != existing_fixed_ip):
475
 
                    floating_ip = fip['floating_ip_address']
476
 
                    self.floating_ip_removed(ri, ri.ex_gw_port,
477
 
                                             floating_ip, existing_fixed_ip)
478
 
                    self.floating_ip_added(ri, ri.ex_gw_port,
479
 
                                           floating_ip, new_fixed_ip)
480
 
                    ri.floating_ips.remove(fip)
481
 
                    ri.floating_ips.append(new_fip)
 
443
        """Configure the router's floating IPs
 
444
        Configures floating ips in iptables and on the router's gateway device.
 
445
 
 
446
        Cleans up floating ips that should not longer be configured.
 
447
        """
 
448
        interface_name = self.get_external_device_name(ex_gw_port['id'])
 
449
        device = ip_lib.IPDevice(interface_name, self.root_helper,
 
450
                                 namespace=ri.ns_name())
 
451
 
 
452
        # Clear out all iptables rules for floating ips
 
453
        ri.iptables_manager.ipv4['nat'].clear_rules_by_tag('floating_ip')
 
454
 
 
455
        existing_cidrs = set([addr['cidr'] for addr in device.addr.list()])
 
456
        new_cidrs = set()
 
457
 
 
458
        # Loop once to ensure that floating ips are configured.
 
459
        for fip in ri.router.get(l3_constants.FLOATINGIP_KEY, []):
 
460
            fip_ip = fip['floating_ip_address']
 
461
            ip_cidr = str(fip_ip) + FLOATING_IP_CIDR_SUFFIX
 
462
 
 
463
            new_cidrs.add(ip_cidr)
 
464
 
 
465
            if ip_cidr not in existing_cidrs:
 
466
                net = netaddr.IPNetwork(ip_cidr)
 
467
                device.addr.add(net.version, ip_cidr, str(net.broadcast))
 
468
                self._send_gratuitous_arp_packet(ri, interface_name, fip_ip)
 
469
 
 
470
            # Rebuild iptables rules for the floating ip.
 
471
            fixed = fip['fixed_ip_address']
 
472
            for chain, rule in self.floating_forward_rules(fip_ip, fixed):
 
473
                ri.iptables_manager.ipv4['nat'].add_rule(chain, rule,
 
474
                                                         tag='floating_ip')
 
475
 
 
476
        ri.iptables_manager.apply()
 
477
 
 
478
        # Clean up addresses that no longer belong on the gateway interface.
 
479
        for ip_cidr in existing_cidrs - new_cidrs:
 
480
            if ip_cidr.endswith(FLOATING_IP_CIDR_SUFFIX):
 
481
                net = netaddr.IPNetwork(ip_cidr)
 
482
                device.addr.delete(net.version, ip_cidr)
482
483
 
483
484
    def _get_ex_gw_port(self, ri):
484
485
        return ri.router.get('gw_port')
599
600
                 (internal_cidr, ex_gw_ip))]
600
601
        return rules
601
602
 
602
 
    def floating_ip_added(self, ri, ex_gw_port, floating_ip, fixed_ip):
603
 
        ip_cidr = str(floating_ip) + '/32'
604
 
        interface_name = self.get_external_device_name(ex_gw_port['id'])
605
 
        device = ip_lib.IPDevice(interface_name, self.root_helper,
606
 
                                 namespace=ri.ns_name())
607
 
 
608
 
        if ip_cidr not in [addr['cidr'] for addr in device.addr.list()]:
609
 
            net = netaddr.IPNetwork(ip_cidr)
610
 
            device.addr.add(net.version, ip_cidr, str(net.broadcast))
611
 
            self._send_gratuitous_arp_packet(ri, interface_name, floating_ip)
612
 
 
613
 
        for chain, rule in self.floating_forward_rules(floating_ip, fixed_ip):
614
 
            ri.iptables_manager.ipv4['nat'].add_rule(chain, rule)
615
 
        ri.iptables_manager.apply()
616
 
 
617
 
    def floating_ip_removed(self, ri, ex_gw_port, floating_ip, fixed_ip):
618
 
        ip_cidr = str(floating_ip) + '/32'
619
 
        net = netaddr.IPNetwork(ip_cidr)
620
 
        interface_name = self.get_external_device_name(ex_gw_port['id'])
621
 
 
622
 
        device = ip_lib.IPDevice(interface_name, self.root_helper,
623
 
                                 namespace=ri.ns_name())
624
 
        device.addr.delete(net.version, ip_cidr)
625
 
 
626
 
        for chain, rule in self.floating_forward_rules(floating_ip, fixed_ip):
627
 
            ri.iptables_manager.ipv4['nat'].remove_rule(chain, rule)
628
 
        ri.iptables_manager.apply()
629
 
 
630
603
    def floating_forward_rules(self, floating_ip, fixed_ip):
631
604
        return [('PREROUTING', '-d %s -j DNAT --to %s' %
632
605
                 (floating_ip, fixed_ip)),