def on_datamodel_in_sync(self): if not self._data_model_in_sync: _log.info("%s: First time we've been in-sync with the datamodel," "sending snapshot to DispatchChains and FIPManager.", self) self._data_model_in_sync = True # Tell the dispatch chains about the local endpoints in advance so # that we don't flap the dispatch chain at start-of-day. Note: # the snapshot may contain information that is ahead of the # state that our individual LocalEndpoint actors are sending to the # DispatchChains actor. That is OK! The worst that can happen is # that a LocalEndpoint undoes part of our update and then goes on # to re-apply the update when it catches up to the snapshot. local_ifaces = frozenset(self.endpoint_id_by_iface_name.keys()) self.dispatch_chains.apply_snapshot(local_ifaces, async=True) self._update_dirty_policy() nat_maps = {} for ep_id, ep in self.endpoints_by_id.iteritems(): if ep_id in self.local_endpoint_ids: nat_map = ep.get(nat_key(self.ip_type), None) if nat_map: nat_maps[ep_id] = nat_map self.fip_manager.apply_snapshot(nat_maps, async=True)
def on_datamodel_in_sync(self): if not self._data_model_in_sync: _log.info( "%s: First time we've been in-sync with the datamodel," "sending snapshot to DispatchChains and FIPManager.", self) self._data_model_in_sync = True # Tell the dispatch chains about the local endpoints in advance so # that we don't flap the dispatch chain at start-of-day. Note: # the snapshot may contain information that is ahead of the # state that our individual LocalEndpoint actors are sending to the # DispatchChains actor. That is OK! The worst that can happen is # that a LocalEndpoint undoes part of our update and then goes on # to re-apply the update when it catches up to the snapshot. workload_ifaces = set() host_eps = set() for if_name, ep_id in self.endpoint_id_by_iface_name.iteritems(): if isinstance(ep_id, WloadEndpointId): workload_ifaces.add(if_name) else: host_eps.add(if_name) self.workload_disp_chains.apply_snapshot( frozenset(workload_ifaces), async=True) self.host_disp_chains.apply_snapshot(frozenset(host_eps), async=True) self._update_dirty_policy() nat_maps = {} for ep_id, ep in self.endpoints_by_id.iteritems(): if ep_id in self.local_endpoint_ids: nat_map = ep.get(nat_key(self.ip_type), None) if nat_map: nat_maps[ep_id] = nat_map self.fip_manager.apply_snapshot(nat_maps, async=True)
def _update_chains(self): updates, deps = self.iptables_generator.endpoint_updates( IP_TYPE_TO_VERSION[self.ip_type], self.combined_id.endpoint, self._suffix, self._mac, self.endpoint["profile_ids"]) try: self.iptables_updater.rewrite_chains(updates, deps, async=False) self.fip_manager.update_endpoint(self.combined_id, self.endpoint.get( nat_key(self.ip_type), None), async=True) except FailedSystemCall: _log.exception("Failed to program chains for %s. Removing.", self) try: self.iptables_updater.delete_chains( self.iptables_generator.endpoint_chain_names(self._suffix), async=False) self.fip_manager.update_endpoint(self.combined_id, None, async=True) except FailedSystemCall: _log.exception("Failed to remove chains after original " "failure") else: self._iptables_in_sync = True self._chains_programmed = True
def _configure_interface(self): """ Applies sysctls and routes to the interface. """ if not self._device_is_up: _log.debug("Device is known to be down, skipping attempt to " "configure it.") return try: if self.ip_type == IPV4: devices.configure_interface_ipv4(self._iface_name) reset_arp = self._mac_changed else: ipv6_gw = self.endpoint.get("ipv6_gateway", None) devices.configure_interface_ipv6(self._iface_name, ipv6_gw) reset_arp = False ips = set() for ip in self.endpoint.get(self.nets_key, []): ips.add(futils.net_to_ip(ip)) for nat_map in self.endpoint.get(nat_key(self.ip_type), []): ips.add(nat_map['ext_ip']) devices.set_routes(self.ip_type, ips, self._iface_name, self.endpoint.get("mac"), reset_arp=reset_arp) except (IOError, FailedSystemCall) as e: if not devices.interface_exists(self._iface_name): _log.info("Interface %s for %s does not exist yet", self._iface_name, self.combined_id) elif not devices.interface_up(self._iface_name): _log.info("Interface %s for %s is not up yet", self._iface_name, self.combined_id) else: # Either the interface flapped back up after the failure (in # which case we'll retry when the event reaches us) or there # was a genuine failure due to bad data or some other factor. # # Since the former is fairly common, we log at warning level # rather than error, which avoids false positives. _log.warning( "Failed to configure interface %s for %s: %r. " "Either the interface is flapping or it is " "misconfigured.", self._iface_name, self.combined_id, e) else: _log.info("Interface %s configured", self._iface_name) super(WorkloadEndpoint, self)._configure_interface()
def _configure_interface(self): """ Applies sysctls and routes to the interface. """ if not self._device_is_up: _log.debug("Device is known to be down, skipping attempt to " "configure it.") return try: if self.ip_type == IPV4: devices.configure_interface_ipv4(self._iface_name) reset_arp = self._mac_changed else: ipv6_gw = self.endpoint.get("ipv6_gateway", None) devices.configure_interface_ipv6(self._iface_name, ipv6_gw) reset_arp = False ips = set() for ip in self.endpoint.get(self.nets_key, []): ips.add(futils.net_to_ip(ip)) for nat_map in self.endpoint.get(nat_key(self.ip_type), []): ips.add(nat_map['ext_ip']) devices.set_routes(self.ip_type, ips, self._iface_name, self.endpoint["mac"], reset_arp=reset_arp) except (IOError, FailedSystemCall) as e: if not devices.interface_exists(self._iface_name): _log.info("Interface %s for %s does not exist yet", self._iface_name, self.combined_id) elif not devices.interface_up(self._iface_name): _log.info("Interface %s for %s is not up yet", self._iface_name, self.combined_id) else: # Either the interface flapped back up after the failure (in # which case we'll retry when the event reaches us) or there # was a genuine failure due to bad data or some other factor. # # Since the former is fairly common, we log at warning level # rather than error, which avoids false positives. _log.warning("Failed to configure interface %s for %s: %r. " "Either the interface is flapping or it is " "misconfigured.", self._iface_name, self.combined_id, e) else: _log.info("Interface %s configured", self._iface_name) self._device_in_sync = True
def nat_key(self): return nat_key(self.ip_type)