440
440
ri.iptables_manager.apply()
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])
449
for fip in floating_ips:
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'])
457
# store to see if floatingip was remapped
458
id_to_fip_map[fip['id']] = fip
460
floating_ip_ids_to_remove = (existing_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'])
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.
446
Cleans up floating ips that should not longer be configured.
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())
452
# Clear out all iptables rules for floating ips
453
ri.iptables_manager.ipv4['nat'].clear_rules_by_tag('floating_ip')
455
existing_cidrs = set([addr['cidr'] for addr in device.addr.list()])
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
463
new_cidrs.add(ip_cidr)
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)
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,
476
ri.iptables_manager.apply()
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)
483
484
def _get_ex_gw_port(self, ri):
484
485
return ri.router.get('gw_port')
599
600
(internal_cidr, ex_gw_ip))]
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())
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)
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()
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'])
622
device = ip_lib.IPDevice(interface_name, self.root_helper,
623
namespace=ri.ns_name())
624
device.addr.delete(net.version, ip_cidr)
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()
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)),