def release_ip_address(self, sid, ip): """ Release an IP address. A released IP is moved to a released list. Released IPs are recycled periodically to the free list. SID IP mappings are removed at the recycling time. Args: sid (string): universal subscriber id ip (ipaddress.ip_address): IP address to release Raises: MappingNotFoundError: if the given sid-ip mapping is not found IPNotInUseError: if the given IP is not found in the used list """ with self._lock: if not (sid in self._sid_ips_map and ip in self._sid_ips_map[sid]): logging.error( "Releasing unknown <SID, IP> pair: <%s, %s>", sid, ip) raise MappingNotFoundError( "(%s, %s) pair is not found", sid, str(ip)) if not self._test_ip_state(ip, IPState.ALLOCATED): logging.error("IP not found in used list, check if IP is " "already released: <%s, %s>", sid, ip) raise IPNotInUseError("IP not found in used list: %s", str(ip)) self._mark_ip_state(ip, IPState.RELEASED) IP_RELEASED_TOTAL.inc() self._try_set_recycle_timer() # start the timer to recycle
def release_ip_address( self, sid: str, ip: ip_address, ): """ Release an IP address. A released IP is moved to a released list. Released IPs are recycled periodically to the free list. SID IP mappings are removed at the recycling time. Args: sid (string): universal subscriber id ip (ipaddress.ip_address): IP address to release version (int): version of IP address to release Raises: MappingNotFoundError: if the given sid-ip mapping is not found IPNotInUseError: if the given IP is not found in the used list """ with self._lock: if not (sid in self._store.sid_ips_map and ip == self._store.sid_ips_map[sid].ip): logging.warning( "Releasing unknown <SID, IP> pair: <%s, %s> " "sid_ips_map[%s]: %s", sid, ip, sid, self._store.sid_ips_map.get(sid), ) raise MappingNotFoundError( "(%s, %s) pair is not found" % (sid, ip), ) if not self.is_ip_in_state(ip, IPState.ALLOCATED): logging.warning( "IP not found in used list, check if IP is " "already released: <%s, %s>", sid, ip, ) raise IPNotInUseError("IP not found in used list: %s" % ip) IP_RELEASED_TOTAL.inc() if ip.version == 4: self._store.ip_state_map.mark_ip_state(ip, IPState.RELEASED) self._try_set_recycle_timer() # start the timer to recycle elif ip.version == 6: # For IPv6, no recycling logic ip_desc = self._store.ipv6_state_map.mark_ip_state( ip, IPState.FREE, ) self.ipv6_allocator.release_ip(ip_desc) del self._store.sid_ips_map[ip_desc.sid]