def _external_gateway_added(self, ex_gw_port, interface_name, ns_name, preserve_ips): LOG.debug("External gateway added: port(%s), interface(%s), ns(%s)", ex_gw_port, interface_name, ns_name) self._plug_external_gateway(ex_gw_port, interface_name, ns_name) # Build up the interface and gateway IP addresses that # will be added to the interface. ip_cidrs = common_utils.fixed_ip_cidrs(ex_gw_port["fixed_ips"]) gateway_ips = self._get_external_gw_ips(ex_gw_port) enable_ra_on_gw = False if self.use_ipv6 and not self.is_v6_gateway_set(gateway_ips): # There is no IPv6 gw_ip, use RouterAdvt for default route. enable_ra_on_gw = True self.driver.init_router_port( interface_name, ip_cidrs, namespace=ns_name, gateway_ips=gateway_ips, extra_subnets=ex_gw_port.get("extra_subnets", []), preserve_ips=preserve_ips, enable_ra_on_gw=enable_ra_on_gw, clean_connections=True, ) for fixed_ip in ex_gw_port["fixed_ips"]: ip_lib.send_ip_addr_adv_notif(ns_name, interface_name, fixed_ip["ip_address"], self.agent_conf)
def add_centralized_floatingip(self, fip, fip_cidr): """Function to handle the centralized Floatingip addition.""" if not self.get_ex_gw_port(): return if not self._is_this_snat_host(): return interface_name = self.get_snat_external_device_interface_name( self.get_ex_gw_port()) try: ip_lib.add_ip_address(fip_cidr, interface_name, namespace=self.snat_namespace.name) except ip_lib.IpAddressAlreadyExists: pass except RuntimeError: LOG.warning( "Unable to configure IP address for centralized " "floating IP: %s", fip['id']) return lib_constants.FLOATINGIP_STATUS_ERROR self.process_floating_ip_nat_rules_for_centralized_floatingip() # Send a GARP message on the external interface for the # centralized floatingip configured. ip_lib.send_ip_addr_adv_notif(self.snat_namespace.name, interface_name, fip['floating_ip_address']) return lib_constants.FLOATINGIP_STATUS_ACTIVE
def _external_gateway_added(self, ex_gw_port, interface_name, ns_name, preserve_ips): self._plug_external_gateway(ex_gw_port, interface_name, ns_name) # Build up the interface and gateway IP addresses that # will be added to the interface. ip_cidrs = common_utils.fixed_ip_cidrs(ex_gw_port['fixed_ips']) gateway_ips = self._get_external_gw_ips(ex_gw_port) enable_ra_on_gw = False if self.use_ipv6 and not self.is_v6_gateway_set(gateway_ips): # There is no IPv6 gw_ip, use RouterAdvt for default route. enable_ra_on_gw = True self.driver.init_l3(interface_name, ip_cidrs, namespace=ns_name, gateway_ips=gateway_ips, extra_subnets=ex_gw_port.get('extra_subnets', []), preserve_ips=preserve_ips, enable_ra_on_gw=enable_ra_on_gw) for fixed_ip in ex_gw_port['fixed_ips']: ip_lib.send_ip_addr_adv_notif(ns_name, interface_name, fixed_ip['ip_address'], self.agent_conf)
def _internal_network_added(self, ns_name, network_id, port_id, fixed_ips, mac_address, interface_name, prefix, mtu=None): LOG.debug("adding internal network: prefix(%s), port(%s)", prefix, port_id) self.driver.plug(network_id, port_id, interface_name, mac_address, namespace=ns_name, prefix=prefix, mtu=mtu) ip_cidrs = common_utils.fixed_ip_cidrs(fixed_ips) self.driver.init_router_port(interface_name, ip_cidrs, namespace=ns_name) for fixed_ip in fixed_ips: ip_lib.send_ip_addr_adv_notif(ns_name, interface_name, fixed_ip['ip_address'], self.agent_conf)
def _gateway_added(self, ex_gw_port, interface_name): """Add Floating IP gateway port.""" LOG.debug("add gateway interface(%s)", interface_name) ns_name = self.get_name() self.driver.plug( ex_gw_port["network_id"], ex_gw_port["id"], interface_name, ex_gw_port["mac_address"], bridge=self.agent_conf.external_network_bridge, namespace=ns_name, prefix=FIP_EXT_DEV_PREFIX, ) ip_cidrs = common_utils.fixed_ip_cidrs(ex_gw_port["fixed_ips"]) self.driver.init_l3(interface_name, ip_cidrs, namespace=ns_name, clean_connections=True) for fixed_ip in ex_gw_port["fixed_ips"]: ip_lib.send_ip_addr_adv_notif(ns_name, interface_name, fixed_ip["ip_address"], self.agent_conf) for subnet in ex_gw_port["subnets"]: gw_ip = subnet.get("gateway_ip") if gw_ip: is_gateway_not_in_subnet = not ipam_utils.check_subnet_ip(subnet.get("cidr"), gw_ip) ipd = ip_lib.IPDevice(interface_name, namespace=ns_name) if is_gateway_not_in_subnet: ipd.route.add_route(gw_ip, scope="link") ipd.route.add_gateway(gw_ip) cmd = ["sysctl", "-w", "net.ipv4.conf.%s.proxy_arp=1" % interface_name] # TODO(Carl) mlavelle's work has self.ip_wrapper ip_wrapper = ip_lib.IPWrapper(namespace=ns_name) ip_wrapper.netns.execute(cmd, check_exit_code=False)
def floating_ip_added_dist(self, fip, fip_cidr): """Add floating IP to FIP namespace.""" floating_ip = fip['floating_ip_address'] fixed_ip = fip['fixed_ip_address'] rule_pr = self.fip_ns.allocate_rule_priority() self.floating_ips_dict[floating_ip] = rule_pr fip_2_rtr_name = self.fip_ns.get_int_device_name(self.router_id) ip_rule = ip_lib.IPRule(namespace=self.ns_name) ip_rule.rule.add(ip=fixed_ip, table=dvr_fip_ns.FIP_RT_TBL, priority=rule_pr) #Add routing rule in fip namespace fip_ns_name = self.fip_ns.get_name() rtr_2_fip, _ = self.rtr_fip_subnet.get_pair() device = ip_lib.IPDevice(fip_2_rtr_name, namespace=fip_ns_name) device.route.add_route(fip_cidr, str(rtr_2_fip.ip)) interface_name = ( self.fip_ns.get_ext_device_name( self.fip_ns.agent_gateway_port['id'])) ip_lib.send_ip_addr_adv_notif(fip_ns_name, interface_name, floating_ip, self.agent_conf) # update internal structures self.dist_fip_count = self.dist_fip_count + 1
def _gateway_added(self, ex_gw_port, interface_name): """Add Floating IP gateway port.""" LOG.debug("add gateway interface(%s)", interface_name) ns_name = self.get_name() self.driver.plug(ex_gw_port['network_id'], ex_gw_port['id'], interface_name, ex_gw_port['mac_address'], bridge=self.agent_conf.external_network_bridge, namespace=ns_name, prefix=FIP_EXT_DEV_PREFIX) ip_cidrs = common_utils.fixed_ip_cidrs(ex_gw_port['fixed_ips']) self.driver.init_l3(interface_name, ip_cidrs, namespace=ns_name, clean_connections=True) for fixed_ip in ex_gw_port['fixed_ips']: ip_lib.send_ip_addr_adv_notif(ns_name, interface_name, fixed_ip['ip_address'], self.agent_conf) for subnet in ex_gw_port['subnets']: gw_ip = subnet.get('gateway_ip') if gw_ip: ipd = ip_lib.IPDevice(interface_name, namespace=ns_name) ipd.route.add_gateway(gw_ip) cmd = ['sysctl', '-w', 'net.ipv4.conf.%s.proxy_arp=1' % interface_name] # TODO(Carl) mlavelle's work has self.ip_wrapper ip_wrapper = ip_lib.IPWrapper(namespace=ns_name) ip_wrapper.netns.execute(cmd, check_exit_code=False)
def floating_ip_added_dist(self, fip, fip_cidr): """Add floating IP to FIP namespace.""" floating_ip = fip['floating_ip_address'] fixed_ip = fip['fixed_ip_address'] rule_pr = self.fip_ns.allocate_rule_priority(floating_ip) self.floating_ips_dict[floating_ip] = rule_pr fip_2_rtr_name = self.fip_ns.get_int_device_name(self.router_id) ip_rule = ip_lib.IPRule(namespace=self.ns_name) ip_rule.rule.add(ip=fixed_ip, table=dvr_fip_ns.FIP_RT_TBL, priority=rule_pr) #Add routing rule in fip namespace fip_ns_name = self.fip_ns.get_name() if self.rtr_fip_subnet is None: self.rtr_fip_subnet = self.fip_ns.local_subnets.allocate( self.router_id) rtr_2_fip, _ = self.rtr_fip_subnet.get_pair() device = ip_lib.IPDevice(fip_2_rtr_name, namespace=fip_ns_name) device.route.add_route(fip_cidr, str(rtr_2_fip.ip)) interface_name = (self.fip_ns.get_ext_device_name( self.fip_ns.agent_gateway_port['id'])) ip_lib.send_ip_addr_adv_notif(fip_ns_name, interface_name, floating_ip, self.agent_conf) # update internal structures self.dist_fip_count = self.dist_fip_count + 1
def _external_gateway_added(self, ex_gw_port, interface_name, ns_name, preserve_ips): LOG.debug("External gateway added: port(%s), interface(%s), ns(%s)", ex_gw_port, interface_name, ns_name) self._plug_external_gateway(ex_gw_port, interface_name, ns_name) # Build up the interface and gateway IP addresses that # will be added to the interface. ip_cidrs = common_utils.fixed_ip_cidrs(ex_gw_port['fixed_ips']) gateway_ips, enable_ra_on_gw = self._get_external_gw_ips(ex_gw_port) self.driver.init_router_port( interface_name, ip_cidrs, namespace=ns_name, gateway_ips=gateway_ips, extra_subnets=ex_gw_port.get('extra_subnets', []), preserve_ips=preserve_ips, enable_ra_on_gw=enable_ra_on_gw, clean_connections=True) for fixed_ip in ex_gw_port['fixed_ips']: ip_lib.send_ip_addr_adv_notif(ns_name, interface_name, fixed_ip['ip_address'], self.agent_conf)
def floating_ip_added_dist(self, fip, fip_cidr): """Add floating IP to respective namespace based on agent mode.""" if fip.get(n_const.DVR_SNAT_BOUND): floating_ip_status = self.add_centralized_floatingip(fip, fip_cidr) if floating_ip_status == lib_constants.FLOATINGIP_STATUS_ACTIVE: self.centralized_floatingips_set.add(fip_cidr) return floating_ip_status floating_ip = fip['floating_ip_address'] fixed_ip = fip['fixed_ip_address'] self._add_floating_ip_rule(floating_ip, fixed_ip) fip_2_rtr_name = self.fip_ns.get_int_device_name(self.router_id) #Add routing rule in fip namespace fip_ns_name = self.fip_ns.get_name() if self.rtr_fip_subnet is None: self.rtr_fip_subnet = self.fip_ns.local_subnets.allocate( self.router_id) rtr_2_fip, __ = self.rtr_fip_subnet.get_pair() device = ip_lib.IPDevice(fip_2_rtr_name, namespace=fip_ns_name) device.route.add_route(fip_cidr, str(rtr_2_fip.ip)) interface_name = ( self.fip_ns.get_ext_device_name( self.fip_ns.agent_gateway_port['id'])) ip_lib.send_ip_addr_adv_notif(fip_ns_name, interface_name, floating_ip) return lib_constants.FLOATINGIP_STATUS_ACTIVE
def _update_gateway_route(self, agent_gateway_port, interface_name, tbl_index): ns_name = self.get_name() ipd = ip_lib.IPDevice(interface_name, namespace=ns_name) # If the 'fg-' device doesn't exist in the namespace then trying # to send advertisements or configure the default route will just # throw exceptions. Unsubscribe this external network so that # the next call will trigger the interface to be plugged. if not ipd.exists(): LOG.warning('DVR: FIP gateway port with interface ' 'name: %(device)s does not exist in the given ' 'namespace: %(ns)s', {'device': interface_name, 'ns': ns_name}) msg = _('DVR: Gateway update route in FIP namespace failed, retry ' 'should be attempted on next call') raise l3_exc.FloatingIpSetupException(msg) for fixed_ip in agent_gateway_port['fixed_ips']: ip_lib.send_ip_addr_adv_notif(ns_name, interface_name, fixed_ip['ip_address']) for subnet in agent_gateway_port['subnets']: gw_ip = subnet.get('gateway_ip') if gw_ip: is_gateway_not_in_subnet = not ipam_utils.check_subnet_ip( subnet.get('cidr'), gw_ip) if is_gateway_not_in_subnet: ipd.route.add_route(gw_ip, scope='link') self._add_default_gateway_for_fip(gw_ip, ipd, tbl_index) else: current_gateway = ipd.route.get_gateway() if current_gateway and current_gateway.get('gateway'): ipd.route.delete_gateway(current_gateway.get('gateway'))
def _external_gateway_added(self, ex_gw_port, interface_name, ns_name, preserve_ips): LOG.debug("External gateway added: port(%s), interface(%s), ns(%s)", ex_gw_port, interface_name, ns_name) self._plug_external_gateway(ex_gw_port, interface_name, ns_name) # Build up the interface and gateway IP addresses that # will be added to the interface. ip_cidrs = common_utils.fixed_ip_cidrs(ex_gw_port['fixed_ips']) gateway_ips = self._get_external_gw_ips(ex_gw_port) enable_ra_on_gw = False if self.use_ipv6 and not self.is_v6_gateway_set(gateway_ips): # There is no IPv6 gw_ip, use RouterAdvt for default route. enable_ra_on_gw = True self.driver.init_router_port( interface_name, ip_cidrs, namespace=ns_name, gateway_ips=gateway_ips, extra_subnets=ex_gw_port.get('extra_subnets', []), preserve_ips=preserve_ips, enable_ra_on_gw=enable_ra_on_gw, clean_connections=True) for fixed_ip in ex_gw_port['fixed_ips']: ip_lib.send_ip_addr_adv_notif(ns_name, interface_name, fixed_ip['ip_address'], self.agent_conf)
def update_gateway_port(self, agent_gateway_port): gateway_ip_not_changed = self.agent_gateway_port and ( not self._check_for_gateway_ip_change(agent_gateway_port)) self.agent_gateway_port = agent_gateway_port if gateway_ip_not_changed: return ns_name = self.get_name() interface_name = self.get_ext_device_name(agent_gateway_port['id']) for fixed_ip in agent_gateway_port['fixed_ips']: ip_lib.send_ip_addr_adv_notif(ns_name, interface_name, fixed_ip['ip_address'], self.agent_conf) ipd = ip_lib.IPDevice(interface_name, namespace=ns_name) for subnet in agent_gateway_port['subnets']: gw_ip = subnet.get('gateway_ip') if gw_ip: is_gateway_not_in_subnet = not ipam_utils.check_subnet_ip( subnet.get('cidr'), gw_ip) if is_gateway_not_in_subnet: ipd.route.add_route(gw_ip, scope='link') ipd.route.add_gateway(gw_ip) else: current_gateway = ipd.route.get_gateway() if current_gateway and current_gateway.get('gateway'): ipd.route.delete_gateway(current_gateway.get('gateway'))
def floating_ip_added_dist(self, fip, fip_cidr): """Add floating IP to respective namespace based on agent mode.""" if fip.get(n_const.DVR_SNAT_BOUND): floating_ip_status = self.add_centralized_floatingip(fip, fip_cidr) if floating_ip_status == lib_constants.FLOATINGIP_STATUS_ACTIVE: self.centralized_floatingips_set.add(fip_cidr) return floating_ip_status if not self._check_if_floatingip_bound_to_host(fip): # TODO(Swami): Need to figure out what status # should be returned when the floating IP is # not destined for this agent and if the floating # IP is configured in a different compute host. # This should not happen once we fix the server # side code, but still a check to make sure if # the floating IP is intended for this host should # be done. return floating_ip = fip['floating_ip_address'] fixed_ip = fip['fixed_ip_address'] self._add_floating_ip_rule(floating_ip, fixed_ip) fip_2_rtr_name = self.fip_ns.get_int_device_name(self.router_id) #Add routing rule in fip namespace fip_ns_name = self.fip_ns.get_name() if self.rtr_fip_subnet is None: self.rtr_fip_subnet = self.fip_ns.local_subnets.allocate( self.router_id) rtr_2_fip, __ = self.rtr_fip_subnet.get_pair() device = ip_lib.IPDevice(fip_2_rtr_name, namespace=fip_ns_name) device.route.add_route(fip_cidr, str(rtr_2_fip.ip)) interface_name = (self.fip_ns.get_ext_device_name( self.fip_ns.agent_gateway_port['id'])) ip_lib.send_ip_addr_adv_notif(fip_ns_name, interface_name, floating_ip) return lib_constants.FLOATINGIP_STATUS_ACTIVE
def _update_gateway_route(self, agent_gateway_port, interface_name, tbl_index): ns_name = self.get_name() ipd = ip_lib.IPDevice(interface_name, namespace=ns_name) # If the 'fg-' device doesn't exist in the namespace then trying # to send advertisements or configure the default route will just # throw exceptions. Unsubscribe this external network so that # the next call will trigger the interface to be plugged. if not ipd.exists(): LOG.warning(_LW('DVR: FIP gateway port with interface ' 'name: %(device)s does not exist in the given ' 'namespace: %(ns)s'), {'device': interface_name, 'ns': ns_name}) msg = _('DVR: Gateway update route in FIP namespace failed, retry ' 'should be attempted on next call') raise n_exc.FloatingIpSetupException(msg) for fixed_ip in agent_gateway_port['fixed_ips']: ip_lib.send_ip_addr_adv_notif(ns_name, interface_name, fixed_ip['ip_address'], self.agent_conf.send_arp_for_ha) for subnet in agent_gateway_port['subnets']: gw_ip = subnet.get('gateway_ip') if gw_ip: is_gateway_not_in_subnet = not ipam_utils.check_subnet_ip( subnet.get('cidr'), gw_ip) if is_gateway_not_in_subnet: ipd.route.add_route(gw_ip, scope='link') self._add_default_gateway_for_fip(gw_ip, ipd, tbl_index) else: current_gateway = ipd.route.get_gateway() if current_gateway and current_gateway.get('gateway'): ipd.route.delete_gateway(current_gateway.get('gateway'))
def _internal_network_added(self, ns_name, network_id, port_id, fixed_ips, mac_address, interface_name, prefix): LOG.debug("adding internal network: prefix(%s), port(%s)", prefix, port_id) self.driver.plug(network_id, port_id, interface_name, mac_address, namespace=ns_name, prefix=prefix) ip_cidrs = common_utils.fixed_ip_cidrs(fixed_ips) self.driver.init_router_port(interface_name, ip_cidrs, namespace=ns_name) for fixed_ip in fixed_ips: ip_lib.send_ip_addr_adv_notif(ns_name, interface_name, fixed_ip["ip_address"], self.agent_conf)
def test_no_ipv6_addr_notif(self, spawn_n): ipv6_addr = 'fd00::1' config = mock.Mock() config.send_arp_for_ha = 3 ip_lib.send_ip_addr_adv_notif(mock.sentinel.ns_name, mock.sentinel.iface_name, ipv6_addr, config) self.assertFalse(spawn_n.called)
def send_garp(self, event): """Send gratuitous ARP for given event.""" ip_lib.send_ip_addr_adv_notif( self.namespace, event.interface, str(netaddr.IPNetwork(event.cidr).ip), log_exception=False )
def add_floating_ip(self, fip, interface_name, device): if not self._add_fip_addr_to_device(fip, device): return lib_constants.FLOATINGIP_STATUS_ERROR # As GARP is processed in a distinct thread the call below # won't raise an exception to be handled. ip_lib.send_ip_addr_adv_notif(self.ns_name, interface_name, fip['floating_ip_address']) return lib_constants.FLOATINGIP_STATUS_ACTIVE
def add_floating_ip(self, fip, interface_name, device): if not self._add_fip_addr_to_device(fip, device): return lib_constants.FLOATINGIP_STATUS_ERROR # As GARP is processed in a distinct thread the call below # won't raise an exception to be handled. ip_lib.send_ip_addr_adv_notif( self.ns_name, interface_name, fip["floating_ip_address"], self.agent_conf.send_arp_for_ha ) return lib_constants.FLOATINGIP_STATUS_ACTIVE
def send_garp(self, event): """Send gratuitous ARP for given event.""" ip_address = str(netaddr.IPNetwork(event['cidr']).ip) ip_lib.send_ip_addr_adv_notif(self.namespace, event['name'], ip_address, log_exception=False) LOG.debug('Sent GARP to %(ip_address)s from %(device_name)s', { 'ip_address': ip_address, 'device_name': event['name'] })
def _internal_network_added(self, ns_name, network_id, port_id, fixed_ips, mac_address, interface_name, prefix): self.driver.plug(network_id, port_id, interface_name, mac_address, namespace=ns_name, prefix=prefix) ip_cidrs = common_utils.fixed_ip_cidrs(fixed_ips) self.driver.init_l3(interface_name, ip_cidrs, namespace=ns_name) for fixed_ip in fixed_ips: ip_lib.send_ip_addr_adv_notif(ns_name, interface_name, fixed_ip['ip_address'], self.agent_conf)
def test_send_ipv4_addr_adv_notif(self, spawn_n, mIPWrapper): spawn_n.side_effect = lambda f: f() ARPING_COUNT = 3 address = "20.0.0.1" config = mock.Mock() config.send_arp_for_ha = ARPING_COUNT ip_lib.send_ip_addr_adv_notif(mock.sentinel.ns_name, mock.sentinel.iface_name, address, config) self.assertTrue(spawn_n.called) mIPWrapper.assert_called_once_with(namespace=mock.sentinel.ns_name) ip_wrapper = mIPWrapper(namespace=mock.sentinel.ns_name) # Just test that arping is called with the right arguments arping_cmd = ["arping", "-A", "-I", mock.sentinel.iface_name, "-c", ARPING_COUNT, "-w", mock.ANY, address] ip_wrapper.netns.execute.assert_any_call(arping_cmd, check_exit_code=True)
def _external_gateway_added(self, ex_gw_port, interface_name, ns_name, preserve_ips): LOG.debug("External gateway added: port(%s), interface(%s), ns(%s)", ex_gw_port, interface_name, ns_name) self._plug_external_gateway(ex_gw_port, interface_name, ns_name) # Build up the interface and gateway IP addresses that # will be added to the interface. ip_cidrs = common_utils.fixed_ip_cidrs(ex_gw_port['fixed_ips']) gateway_ips = self._get_external_gw_ips(ex_gw_port) enable_ra_on_gw = False if self.use_ipv6 and not self.is_v6_gateway_set(gateway_ips): # There is no IPv6 gw_ip, use RouterAdvt for default route. enable_ra_on_gw = True self._add_route_to_gw(ex_gw_port, device_name=interface_name, namespace=ns_name, preserve_ips=preserve_ips) self.driver.init_router_port(interface_name, ip_cidrs, namespace=ns_name, extra_subnets=ex_gw_port.get( 'extra_subnets', []), preserve_ips=preserve_ips, clean_connections=True) device = ip_lib.IPDevice(interface_name, namespace=ns_name) current_gateways = set() for ip_version in (l3_constants.IP_VERSION_4, l3_constants.IP_VERSION_6): gateway = device.route.get_gateway(ip_version=ip_version) if gateway and gateway.get('gateway'): current_gateways.add(gateway.get('gateway')) for ip in current_gateways - set(gateway_ips): device.route.delete_gateway(ip) for ip in gateway_ips: device.route.add_gateway(ip) if enable_ra_on_gw: self.driver.configure_ipv6_ra(ns_name, interface_name) for fixed_ip in ex_gw_port['fixed_ips']: ip_lib.send_ip_addr_adv_notif(ns_name, interface_name, fixed_ip['ip_address'], self.agent_conf)
def _internal_network_added(self, ns_name, network_id, port_id, fixed_ips, mac_address, interface_name): LOG.debug("adding internal network: port(%s)", port_id) #import ipdb;ipdb.set_trace() self.driver.plug_new(network_id, port_id, interface_name, fixed_ips, mac_address, namespace=ns_name) ip_cidrs = common_utils.fixed_ip_cidrs(fixed_ips) self.driver.init_router_port( interface_name, ip_cidrs, namespace=ns_name) if interface_name not in consts.FTNT_PORTS: for fixed_ip in fixed_ips: # samsu: arp maynot needed in this case ip_lib.send_ip_addr_adv_notif(ns_name, interface_name, fixed_ip['ip_address'], self.agent_conf)
def floating_ip_added_dist(self, fip, fip_cidr): """Add floating IP to FIP namespace.""" floating_ip = fip['floating_ip_address'] fixed_ip = fip['fixed_ip_address'] self._add_floating_ip_rule(floating_ip, fixed_ip) fip_2_rtr_name = self.fip_ns.get_int_device_name(self.router_id) #Add routing rule in fip namespace fip_ns_name = self.fip_ns.get_name() if self.rtr_fip_subnet is None: self.rtr_fip_subnet = self.fip_ns.local_subnets.allocate( self.router_id) rtr_2_fip, __ = self.rtr_fip_subnet.get_pair() device = ip_lib.IPDevice(fip_2_rtr_name, namespace=fip_ns_name) device.route.add_route(fip_cidr, str(rtr_2_fip.ip)) interface_name = (self.fip_ns.get_ext_device_name( self.fip_ns.agent_gateway_port['id'])) ip_lib.send_ip_addr_adv_notif(fip_ns_name, interface_name, floating_ip)
def _external_gateway_added(self, ex_gw_port, interface_name, ns_name, preserve_ips): LOG.debug("External gateway added: port(%s), interface(%s), ns(%s)", ex_gw_port, interface_name, ns_name) self._plug_external_gateway(ex_gw_port, interface_name, ns_name) # Build up the interface and gateway IP addresses that # will be added to the interface. ip_cidrs = common_utils.fixed_ip_cidrs(ex_gw_port['fixed_ips']) gateway_ips = self._get_external_gw_ips(ex_gw_port) enable_ra_on_gw = False if self.use_ipv6 and not self.is_v6_gateway_set(gateway_ips): # There is no IPv6 gw_ip, use RouterAdvt for default route. enable_ra_on_gw = True self._add_route_to_gw(ex_gw_port, device_name=interface_name, namespace=ns_name, preserve_ips=preserve_ips) self.driver.init_router_port( interface_name, ip_cidrs, namespace=ns_name, extra_subnets=ex_gw_port.get('extra_subnets', []), preserve_ips=preserve_ips, clean_connections=True) device = ip_lib.IPDevice(interface_name, namespace=ns_name) current_gateways = set() for ip_version in (l3_constants.IP_VERSION_4, l3_constants.IP_VERSION_6): gateway = device.route.get_gateway(ip_version=ip_version) if gateway and gateway.get('gateway'): current_gateways.add(gateway.get('gateway')) for ip in current_gateways - set(gateway_ips): device.route.delete_gateway(ip) for ip in gateway_ips: device.route.add_gateway(ip) if enable_ra_on_gw: self.driver.configure_ipv6_ra(ns_name, interface_name) for fixed_ip in ex_gw_port['fixed_ips']: ip_lib.send_ip_addr_adv_notif(ns_name, interface_name, fixed_ip['ip_address'], self.agent_conf)
def _update_gateway_port(self, agent_gateway_port, interface_name): if (self.agent_gateway_port and not self._check_for_gateway_ip_change(agent_gateway_port)): return ns_name = self.get_name() ipd = ip_lib.IPDevice(interface_name, namespace=ns_name) # If the 'fg-' device doesn't exist in the namespace then trying # to send advertisements or configure the default route will just # throw exceptions. Unsubscribe this external network so that # the next call will trigger the interface to be plugged. if not ipd.exists(): self.unsubscribe(agent_gateway_port['network_id']) LOG.warning(_LW('DVR: FIP gateway port with interface ' 'name: %(device)s does not exist in the given ' 'namespace: %(ns)s'), {'device': interface_name, 'ns': ns_name}) msg = _('DVR: Gateway setup in FIP namespace failed, retry ' 'should be attempted on next call') raise n_exc.FloatingIpSetupException(msg) for fixed_ip in agent_gateway_port['fixed_ips']: ip_lib.send_ip_addr_adv_notif(ns_name, interface_name, fixed_ip['ip_address'], self.agent_conf.send_arp_for_ha) for subnet in agent_gateway_port['subnets']: gw_ip = subnet.get('gateway_ip') if gw_ip: is_gateway_not_in_subnet = not ipam_utils.check_subnet_ip( subnet.get('cidr'), gw_ip) if is_gateway_not_in_subnet: ipd.route.add_route(gw_ip, scope='link') ipd.route.add_gateway(gw_ip) else: current_gateway = ipd.route.get_gateway() if current_gateway and current_gateway.get('gateway'): ipd.route.delete_gateway(current_gateway.get('gateway')) # Cache the agent gateway port after successfully configuring # the gateway, so that checking on self.agent_gateway_port # will be a valid check self.agent_gateway_port = agent_gateway_port
def floating_ip_added_dist(self, fip, fip_cidr): """Add floating IP to FIP namespace.""" floating_ip = fip['floating_ip_address'] fixed_ip = fip['fixed_ip_address'] self._add_floating_ip_rule(floating_ip, fixed_ip) fip_2_rtr_name = self.fip_ns.get_int_device_name(self.router_id) #Add routing rule in fip namespace fip_ns_name = self.fip_ns.get_name() if self.rtr_fip_subnet is None: self.rtr_fip_subnet = self.fip_ns.local_subnets.allocate( self.router_id) rtr_2_fip, __ = self.rtr_fip_subnet.get_pair() device = ip_lib.IPDevice(fip_2_rtr_name, namespace=fip_ns_name) device.route.add_route(fip_cidr, str(rtr_2_fip.ip)) interface_name = ( self.fip_ns.get_ext_device_name( self.fip_ns.agent_gateway_port['id'])) ip_lib.send_ip_addr_adv_notif(fip_ns_name, interface_name, floating_ip)
def floating_ip_added_dist(self, fip, fip_cidr): """Add floating IP to respective namespace based on agent mode.""" if fip.get(lib_constants.DVR_SNAT_BOUND): floating_ip_status = self.add_centralized_floatingip(fip, fip_cidr) return floating_ip_status if not self._check_if_floatingip_bound_to_host(fip): # TODO(Swami): Need to figure out what status # should be returned when the floating IP is # not destined for this agent and if the floating # IP is configured in a different compute host. # This should not happen once we fix the server # side code, but still a check to make sure if # the floating IP is intended for this host should # be done. return # dvr_no_external host should not process any floating IP route rules. if (self.agent_conf.agent_mode == lib_constants.L3_AGENT_MODE_DVR_NO_EXTERNAL): return floating_ip = fip['floating_ip_address'] fixed_ip = fip['fixed_ip_address'] self._add_floating_ip_rule(floating_ip, fixed_ip) fip_2_rtr_name = self.fip_ns.get_int_device_name(self.router_id) # Add routing rule in fip namespace fip_ns_name = self.fip_ns.get_name() if self.rtr_fip_subnet is None: self.rtr_fip_subnet = self.fip_ns.local_subnets.allocate( self.router_id) rtr_2_fip, __ = self.rtr_fip_subnet.get_pair() device = ip_lib.IPDevice(fip_2_rtr_name, namespace=fip_ns_name) device.route.add_route(fip_cidr, str(rtr_2_fip.ip)) interface_name = ( self.fip_ns.get_ext_device_name( self.fip_ns.agent_gateway_port['id'])) ip_lib.send_ip_addr_adv_notif(fip_ns_name, interface_name, floating_ip) return lib_constants.FLOATINGIP_STATUS_ACTIVE
def _external_gateway_added(self, ex_gw_port, interface_name, ns_name, preserve_ips): self._plug_external_gateway(ex_gw_port, interface_name, ns_name) # Build up the interface and gateway IP addresses that # will be added to the interface. ip_cidrs = common_utils.fixed_ip_cidrs(ex_gw_port['fixed_ips']) gateway_ips, enable_ra_on_gw = self._get_external_gw_ips(ex_gw_port) self.driver.init_router_port(interface_name, ip_cidrs, namespace=ns_name, gateway_ips=gateway_ips, extra_subnets=ex_gw_port.get( 'extra_subnets', []), preserve_ips=preserve_ips, enable_ra_on_gw=enable_ra_on_gw, clean_connections=True) for fixed_ip in ex_gw_port['fixed_ips']: ip_lib.send_ip_addr_adv_notif(ns_name, interface_name, fixed_ip['ip_address'], self.agent_conf)
def test_send_ipv4_addr_adv_notif(self, spawn_n, mIPWrapper): spawn_n.side_effect = lambda f: f() ARPING_COUNT = 3 address = '20.0.0.1' config = mock.Mock() config.send_arp_for_ha = ARPING_COUNT ip_lib.send_ip_addr_adv_notif(mock.sentinel.ns_name, mock.sentinel.iface_name, address, config) self.assertTrue(spawn_n.called) mIPWrapper.assert_called_once_with(namespace=mock.sentinel.ns_name) ip_wrapper = mIPWrapper(namespace=mock.sentinel.ns_name) # Just test that arping is called with the right arguments arping_cmd = [ 'arping', '-A', '-I', mock.sentinel.iface_name, '-c', ARPING_COUNT, '-w', mock.ANY, address ] ip_wrapper.netns.execute.assert_any_call(arping_cmd, check_exit_code=True)
def floating_ip_added_dist(self, fip, fip_cidr): """Add floating IP to respective namespace based on agent mode.""" if fip.get(lib_constants.DVR_SNAT_BOUND): # TODO(dougwig) - remove this disable when fixing bug #1816874 # pylint: disable=assignment-from-no-return floating_ip_status = self.add_centralized_floatingip(fip, fip_cidr) return floating_ip_status if not self._check_if_floatingip_bound_to_host(fip): # TODO(Swami): Need to figure out what status # should be returned when the floating IP is # not destined for this agent and if the floating # IP is configured in a different compute host. # This should not happen once we fix the server # side code, but still a check to make sure if # the floating IP is intended for this host should # be done. return # dvr_no_external host should not process any floating IP route rules. if (self.agent_conf.agent_mode == lib_constants.L3_AGENT_MODE_DVR_NO_EXTERNAL): return floating_ip = fip['floating_ip_address'] fixed_ip = fip['fixed_ip_address'] self._add_floating_ip_rule(floating_ip, fixed_ip) fip_2_rtr_name = self.fip_ns.get_int_device_name(self.router_id) # Add routing rule in fip namespace fip_ns_name = self.fip_ns.get_name() if self.rtr_fip_subnet is None: self.rtr_fip_subnet = self.fip_ns.local_subnets.allocate( self.router_id) rtr_2_fip, __ = self.rtr_fip_subnet.get_pair() device = ip_lib.IPDevice(fip_2_rtr_name, namespace=fip_ns_name) device.route.add_route(fip_cidr, str(rtr_2_fip.ip)) interface_name = (self.fip_ns.get_ext_device_name( self.fip_ns.agent_gateway_port['id'])) ip_lib.send_ip_addr_adv_notif(fip_ns_name, interface_name, floating_ip) return lib_constants.FLOATINGIP_STATUS_ACTIVE
def add_centralized_floatingip(self, fip, fip_cidr): """Function to handle the centralized Floatingip addition.""" if not self.get_ex_gw_port(): return if not self._is_this_snat_host(): return interface_name = self.get_snat_external_device_interface_name( self.get_ex_gw_port()) device = ip_lib.IPDevice( interface_name, namespace=self.snat_namespace.name) try: device.addr.add(fip_cidr) except RuntimeError: LOG.warning("Unable to configure IP address for centralized " "floating IP: %s", fip['id']) return lib_constants.FLOATINGIP_STATUS_ERROR self.process_floating_ip_nat_rules_for_centralized_floatingip() # Send a GARP message on the external interface for the # centralized floatingip configured. ip_lib.send_ip_addr_adv_notif(self.snat_namespace.name, interface_name, fip['floating_ip_address']) return lib_constants.FLOATINGIP_STATUS_ACTIVE
def _process_create(self, port_forwardings, ri, interface_name, namespace, iptables_manager): if not port_forwardings: return device = ip_lib.IPDevice(interface_name, namespace=namespace) is_distributed = ri.router.get('distributed') ha_port = ri.router.get(lib_consts.HA_INTERFACE_KEY, None) fip_statuses = {} for port_forwarding in port_forwardings: # check if the port forwarding is managed in this agent from # OVO and router rpc. if port_forwarding.id in self.mapping.managed_port_forwardings: LOG.debug("Skip port forwarding %s for create, as it had been " "managed by agent", port_forwarding.id) continue existing_cidrs = ri.get_router_cidrs(device) fip_ip = str(port_forwarding.floating_ip_address) fip_cidr = str(netaddr.IPNetwork(fip_ip)) status = '' if fip_cidr not in existing_cidrs: try: if not is_distributed: fip_statuses[port_forwarding.floatingip_id] = ( ri.add_floating_ip( {'floating_ip_address': fip_ip}, interface_name, device)) else: if not ha_port: device.addr.add(fip_cidr) ip_lib.send_ip_addr_adv_notif(namespace, interface_name, fip_ip) else: ri._add_vip(fip_cidr, interface_name) status = lib_consts.FLOATINGIP_STATUS_ACTIVE except Exception: # Any error will causes the fip status to be set 'ERROR' status = lib_consts.FLOATINGIP_STATUS_ERROR LOG.warning("Unable to configure floating IP %(fip_id)s " "for port forwarding %(pf_id)s", {'fip_id': port_forwarding.floatingip_id, 'pf_id': port_forwarding.id}) else: if not ha_port: ip_lib.send_ip_addr_adv_notif(namespace, interface_name, fip_ip) if status: fip_statuses[port_forwarding.floatingip_id] = status if ha_port and ha_port['status'] == lib_consts.PORT_STATUS_ACTIVE: ri.enable_keepalived() for port_forwarding in port_forwardings: rule_tag = PORT_FORWARDING_PREFIX + port_forwarding.id self._rule_apply(iptables_manager, port_forwarding, rule_tag) iptables_manager.apply() self._sending_port_forwarding_fip_status(ri, fip_statuses) self._store_local(port_forwardings, events.CREATED)
def _process_create(self, port_forwardings, ri, interface_name, namespace, iptables_manager): if not port_forwardings: return device = ip_lib.IPDevice(interface_name, namespace=namespace) is_distributed = ri.router.get('distributed') ha_port = ri.router.get(constants.HA_INTERFACE_KEY, None) fip_statuses = {} for port_forwarding in port_forwardings: # check if the port forwarding is managed in this agent from # OVO and router rpc. if port_forwarding.id in self.mapping.managed_port_forwardings: LOG.debug( "Skip port forwarding %s for create, as it had been " "managed by agent", port_forwarding.id) continue existing_cidrs = ri.get_router_cidrs(device) fip_ip = str(port_forwarding.floating_ip_address) fip_cidr = str(netaddr.IPNetwork(fip_ip)) status = '' if fip_cidr not in existing_cidrs: try: if not is_distributed: fip_statuses[port_forwarding.floatingip_id] = ( ri.add_floating_ip({'floating_ip_address': fip_ip}, interface_name, device)) else: if not ha_port: device.addr.add(fip_cidr) ip_lib.send_ip_addr_adv_notif( namespace, interface_name, fip_ip) else: ri._add_vip(fip_cidr, interface_name) status = constants.FLOATINGIP_STATUS_ACTIVE except Exception: # Any error will causes the fip status to be set 'ERROR' status = constants.FLOATINGIP_STATUS_ERROR LOG.warning( "Unable to configure floating IP %(fip_id)s " "for port forwarding %(pf_id)s", { 'fip_id': port_forwarding.floatingip_id, 'pf_id': port_forwarding.id }) else: if not ha_port: ip_lib.send_ip_addr_adv_notif(namespace, interface_name, fip_ip) if status: fip_statuses[port_forwarding.floatingip_id] = status if ha_port and ha_port['status'] == constants.PORT_STATUS_ACTIVE: ri.enable_keepalived() for port_forwarding in port_forwardings: rule_tag = PORT_FORWARDING_PREFIX + port_forwarding.id self._rule_apply(iptables_manager, port_forwarding, rule_tag) iptables_manager.apply() self._sending_port_forwarding_fip_status(ri, fip_statuses) self._store_local(port_forwardings, events.CREATED)