def resolved_work_item(self, endpoint): ''' This is the actual routine which sends the Resolved message to all relevant DOVE Switches @param endpoint: The Endpoint Object Looked up @type endpoint: Endpoint ''' pipv4_list = endpoint.tunnel_endpoint.ip_listv4.ip_list[:] pipv6_list = endpoint.tunnel_endpoint.ip_listv6.ip_list[:] for dps_client in self.dps_clients.keys(): try: client = self.dps_clients[dps_client] dvgs = client.values() except Exception: pass for dvg in dvgs: DpsCollection.global_lock.acquire() if not dvg.valid: DpsCollection.global_lock.release() continue try: dvg.send_endpoint_location_reply_to(dps_client.location.ip_value_packed, dps_client.location.port, endpoint.dvg.unique_id, endpoint.version, pipv4_list, pipv6_list, endpoint.vMac, self.vIP.ip_value_packed #vIP ) except Exception, ex: message = 'Address Resolution: Send location reply to Exception [%s]'%ex dcslib.dps_data_write_log(DpsLogLevels.WARNING, message) DpsCollection.global_lock.release()
def resolved_work_item(self, endpoint): ''' This is the actual routine which sends the Resolved message to all relevant DOVE Switches @param endpoint: The Endpoint Object Looked up @type endpoint: Endpoint ''' pipv4_list = endpoint.tunnel_endpoint.ip_listv4.ip_list[:] pipv6_list = endpoint.tunnel_endpoint.ip_listv6.ip_list[:] for dps_client in self.dps_clients.keys(): try: client = self.dps_clients[dps_client] dvgs = client.values() except Exception: pass for dvg in dvgs: DpsCollection.global_lock.acquire() if not dvg.valid: DpsCollection.global_lock.release() continue try: dvg.send_endpoint_location_reply_to( dps_client.location.ip_value_packed, dps_client.location.port, endpoint.dvg.unique_id, endpoint.version, pipv4_list, pipv6_list, endpoint.vMac, self.vIP.ip_value_packed #vIP ) except Exception, ex: message = 'Address Resolution: Send location reply to Exception [%s]' % ex dcslib.dps_data_write_log(DpsLogLevels.WARNING, message) DpsCollection.global_lock.release()
def send_vm_migration_update_to(self, dps_client, endpoint, vnid, query_id): if not self.active: return if query_id == 0: query_id_use = DpsCollection.generate_query_id() else: query_id_use = query_id # to send to dcslib.send_all_vm_migration_update () vipv4_list = [] vipv6_list = [] pipv4_list = endpoint.tunnel_endpoint.ip_listv4.ip_list[:] pipv6_list = endpoint.tunnel_endpoint.ip_listv6.ip_list[:] for vIP_obj in endpoint.vIP_set.values(): if vIP_obj.fValid: if vIP_obj.inet_type == socket.AF_INET: vipv4_list.append(vIP_obj.ip_value) elif vIP_obj.inet_type == socket.AF_INET6: vipv6_list.append(vIP_obj.ip_value) ret_val = dcslib.send_all_vm_migration_update(dps_client.location.ip_value_packed, #DPS Client Location IP dps_client.location.port, #DPS Client Port vnid, #VNID ID query_id_use, endpoint.dvg.unique_id, endpoint.version, pipv4_list, pipv6_list, endpoint.vMac, vipv4_list, vipv6_list) if ret_val != 0: message = 'send_all_vm_migration_update FAILED with value %d'%(ret_val) dcslib.dps_data_write_log(DpsLogLevels.NOTICE, message) return
def unregister(domain, dvg, client_type, pip_tuple_list): ''' This routine should be called when a set of tunnel endpoint IP Addresses are unregistered by the DPS Client Protocol Handler. @param domain: The Domain object @type domain: Domain @param dvg: The DVG/VNID object @type dvg: DVG @param client_type: The Type of Client: should be in DpsClientType.types @type client_type: Integer @param pip_tuple_list: A list of tuples of Physical IP Addresses, each tuple is of the form (inet_type, ip_value). The inet_type = socket type i.e. AF_INET or AF_INET6 The ip_value = IPv4 in integer or IPv6 in string @type pip_tuple_list: List of tuples ''' #TODO: See if we need a DPS Client validation check if ((client_type == DpsClientType.dove_switch) or (client_type == DpsClientType.vlan_gateway) or (client_type == DpsClientType.external_gateway)): for pip_tuple in pip_tuple_list: inet_type = pip_tuple[0] pip_value = pip_tuple[1] #Find the Tunnel from Domain Collection if inet_type == socket.AF_INET: ip_hash = domain.Tunnel_Endpoints_Hash_IPv4 else: ip_hash = domain.Tunnel_Endpoints_Hash_IPv6 try: tunnel = ip_hash[pip_value] try: TunnelEndpoint.ip_delete(tunnel, dvg, client_type, inet_type, pip_value) #tunnel.show_details() except: message = 'Tunnel.Unregister: Problem deleting IP %s' % pip_value dcslib.dps_data_write_log(DpsLogLevels.WARNING, message) except Exception: pass if client_type == DpsClientType.external_gateway: for pip_tuple in pip_tuple_list: inet_type = pip_tuple[0] pip_value = pip_tuple[1] try: if inet_type == socket.AF_INET: IPList = dvg.ExternalGatewayIPListv4 else: IPList = dvg.ExternalGatewayIPListv6 IPList.remove(inet_type, pip_value) except Exception: pass #TODO: Send update to all other Tunnels in Domain about this IP List unregister return
def vnid_delete(self, dvg): ''' This routine must be called whenever a VNID is deleted in the domain @param dvg: The VNID that asked for this endpoint @type dvg: DVG ''' for resolution_obj in self.endpoint_resolution.values(): self.total -= resolution_obj.vnid_delete(dvg) if self.total < 0: message = 'AddressResolution.vnid_delete: Problem with accounting' dcslib.dps_data_write_log(DpsLogLevels.WARNING, message) return
def unregister(domain, dvg, client_type, pip_tuple_list): ''' This routine should be called when a set of tunnel endpoint IP Addresses are unregistered by the DPS Client Protocol Handler. @param domain: The Domain object @type domain: Domain @param dvg: The DVG/VNID object @type dvg: DVG @param client_type: The Type of Client: should be in DpsClientType.types @type client_type: Integer @param pip_tuple_list: A list of tuples of Physical IP Addresses, each tuple is of the form (inet_type, ip_value). The inet_type = socket type i.e. AF_INET or AF_INET6 The ip_value = IPv4 in integer or IPv6 in string @type pip_tuple_list: List of tuples ''' #TODO: See if we need a DPS Client validation check if ((client_type == DpsClientType.dove_switch) or (client_type == DpsClientType.vlan_gateway) or (client_type == DpsClientType.external_gateway)): for pip_tuple in pip_tuple_list: inet_type = pip_tuple[0] pip_value = pip_tuple[1] #Find the Tunnel from Domain Collection if inet_type == socket.AF_INET: ip_hash = domain.Tunnel_Endpoints_Hash_IPv4 else: ip_hash = domain.Tunnel_Endpoints_Hash_IPv6 try: tunnel = ip_hash[pip_value] try: TunnelEndpoint.ip_delete(tunnel, dvg, client_type, inet_type, pip_value) #tunnel.show_details() except: message = 'Tunnel.Unregister: Problem deleting IP %s'%pip_value dcslib.dps_data_write_log(DpsLogLevels.WARNING, message) except Exception: pass if client_type == DpsClientType.external_gateway: for pip_tuple in pip_tuple_list: inet_type = pip_tuple[0] pip_value = pip_tuple[1] try: if inet_type == socket.AF_INET: IPList = dvg.ExternalGatewayIPListv4 else: IPList = dvg.ExternalGatewayIPListv6 IPList.remove(inet_type, pip_value) except Exception: pass #TODO: Send update to all other Tunnels in Domain about this IP List unregister return
def dps_client_delete(self, dps_client): ''' This routine must be called whenever a dps_client is deleted from the domain @param dps_client: The DPS Client @type dps_client: DPSClient ''' for resolution_obj in self.endpoint_resolution.values(): self.total -= resolution_obj.dps_client_delete(dps_client) if self.total < 0: message = 'AddressResolution.dps_client_delete: Problem with accounting' dcslib.dps_data_write_log(DpsLogLevels.WARNING, message) return
def show(self): ''' ''' message = '------- MULTICAST DETAILS for Domain %s -------'%(self.domain_id) dcslib.dps_data_write_log(DpsLogLevels.NOTICE, message) self.Global_Scope.show() self.All.show() for mac_group in self.MAC_Group.values(): mac_group.show() ############################################################# #Show Policies. ############################################################# domain = self.domain count = len(domain.Policy_Hash_DVG[0]) if count > 0: message = '----------- MULTICAST Policies -------------------' dcslib.dps_data_write_log(DpsLogLevels.NOTICE, message) for policy in domain.Policy_Hash_DVG[1].values(): if policy.src_dvg == policy.dst_dvg and policy.action_connectivity == policy.action_forward: continue message = '%s'%policy.show() dcslib.dps_data_write_log(DpsLogLevels.NOTICE, message) #print '-----------------------------------------------------------\r' else: message = 'Policy Count %s'%count dcslib.dps_data_write_log(DpsLogLevels.NOTICE, message) return
def show_vnid(self, vnid): ''' Shows only Multicast Receivers and Senders in a particular VNID @param vnid: The VNID @type vnid: Integer ''' message = '------- MULTICAST DETAILS for VNID %s -------'%(vnid) dcslib.dps_data_write_log(DpsLogLevels.NOTICE, message) self.All.show_vnid(vnid) for mac_group in self.MAC_Group.values(): mac_group.show_vnid(vnid) ############################################################# #Show Policies. ############################################################# domain = self.domain count = len(domain.Policy_Hash_DVG[0]) if count > 0: message = '----------- MULTICAST Policies -------------------' dcslib.dps_data_write_log(DpsLogLevels.NOTICE, message) for policy in domain.Policy_Hash_DVG[1].values(): if policy.src_dvg.unique_id != vnid and policy.dst_dvg.unique_id != vnid: continue if policy.src_dvg == policy.dst_dvg and policy.action_connectivity == policy.action_forward: continue message = '%s'%policy.show() dcslib.dps_data_write_log(DpsLogLevels.NOTICE, message) #print '-----------------------------------------------------------\r' else: message = 'Policy Count %s'%count dcslib.dps_data_write_log(DpsLogLevels.NOTICE, message) return
def delete(self): ''' Delete self ''' if not self.valid: return self.valid = False for key in self.endpoint_resolution.keys(): try: obj = self.endpoint_resolution[key] self.total -= obj.delete() del self.endpoint_resolution[key] except Exception: pass if self.total != 0: message = 'AddressResolution.delete: Accounting Problem' dcslib.dps_data_write_log(DpsLogLevels.WARNING, message) return
def delete(self, ip_value, mask_value): ''' Deletes a IP Subnet from List @param ip_value: IP Address of Subnet @type ip_value: Integer @param mask_value: Mask of Subnet @type mask_value: Integer @return: The status of the operation @rtype: dove_status (defined in include/status.h) Integer ''' key = '%s:%s'%(ip_value, mask_value) try: del self.PyList[key] except Exception: pass self.count -= 1 if self.count < 0: message = 'IPSubnetList.delete: Count %s < 0 - Counting Error'%self.count dcslib.dps_data_write_log(DpsLogLevels.WARNING, message) return DOVEStatus.DOVE_STATUS_OK
def delete(self, ip_value, mask_value): ''' Deletes a IP Subnet from List @param ip_value: IP Address of Subnet @type ip_value: Integer @param mask_value: Mask of Subnet @type mask_value: Integer @return: The status of the operation @rtype: dove_status (defined in include/status.h) Integer ''' key = '%s:%s' % (ip_value, mask_value) try: del self.PyList[key] except Exception: pass self.count -= 1 if self.count < 0: message = 'IPSubnetList.delete: Count %s < 0 - Counting Error' % self.count dcslib.dps_data_write_log(DpsLogLevels.WARNING, message) return DOVEStatus.DOVE_STATUS_OK
def process_endpoint_update(self, endpoint, vIP_val): ''' This routine checks which DPS Client have been waiting for this endpoint update and sends resolution to those DPS Clients @param endpoint: The Endpoint being updated @type endpoint: Endpoint @param vIP_val: The vIP Value @type vIP_val: Integer or String ''' while True: try: resolution_obj = self.endpoint_resolution[vIP_val] del self.endpoint_resolution[vIP_val] except Exception: break try: self.total -= resolution_obj.resolved(endpoint) except Exception, ex: message = 'AddressResolution.process_endpoint_update Problem Resolving Exception %s' % ex dcslib.dps_data_write_log(DpsLogLevels.WARNING, message) break
def process_endpoint_update(self, endpoint, vIP_val): ''' This routine checks which DPS Client have been waiting for this endpoint update and sends resolution to those DPS Clients @param endpoint: The Endpoint being updated @type endpoint: Endpoint @param vIP_val: The vIP Value @type vIP_val: Integer or String ''' while True: try: resolution_obj = self.endpoint_resolution[vIP_val] del self.endpoint_resolution[vIP_val] except Exception: break try: self.total -= resolution_obj.resolved(endpoint) except Exception, ex: message = 'AddressResolution.process_endpoint_update Problem Resolving Exception %s'%ex dcslib.dps_data_write_log(DpsLogLevels.WARNING, message) break
def send_vm_migration_update_to(self, dps_client, endpoint, vnid, query_id): if not self.active: return if query_id == 0: query_id_use = DpsCollection.generate_query_id() else: query_id_use = query_id # to send to dcslib.send_all_vm_migration_update () vipv4_list = [] vipv6_list = [] pipv4_list = endpoint.tunnel_endpoint.ip_listv4.ip_list[:] pipv6_list = endpoint.tunnel_endpoint.ip_listv6.ip_list[:] for vIP_obj in endpoint.vIP_set.values(): if vIP_obj.fValid: if vIP_obj.inet_type == socket.AF_INET: vipv4_list.append(vIP_obj.ip_value) elif vIP_obj.inet_type == socket.AF_INET6: vipv6_list.append(vIP_obj.ip_value) ret_val = dcslib.send_all_vm_migration_update( dps_client.location.ip_value_packed, #DPS Client Location IP dps_client.location.port, #DPS Client Port vnid, #VNID ID query_id_use, endpoint.dvg.unique_id, endpoint.version, pipv4_list, pipv6_list, endpoint.vMac, vipv4_list, vipv6_list) if ret_val != 0: message = 'send_all_vm_migration_update FAILED with value %d' % ( ret_val) dcslib.dps_data_write_log(DpsLogLevels.NOTICE, message) return
def register(domain, dvg, client_type, transaction_type, dps_client, pip_tuple_list): ''' This routine should be called when a set of tunnel endpoint IP Addresses are registered by the DPS Client Protocol Handler. @param domain: The Domain object @type domain: Domain @param dvg: The DVG/VNID object @type dvg: DVG @param client_type: The Type of Client: should be in DpsClientType.types @type client_type: Integer @param transaction_type: The Type of Transaction: should be in Domain.transaction_types @type transaction_type: Integer @param dps_client: The DPS Client associated with this Tunnel @type dps_client: DPSClient @type dps_client_port: Integer @param pip_tuple_list: A list of tuples of Physical IP Addresses, each tuple is of the form (inet_type, ip_value). The inet_type = socket type i.e. AF_INET or AF_INET6 The ip_value = IPv4 in integer or IPv6 in string @type pip_tuple_list: List of tuples ''' #Find if a tunnel exists with existing pIP if len(pip_tuple_list) == 0: return tunnel_set = {} if ((client_type == DpsClientType.dove_switch) or (client_type == DpsClientType.vlan_gateway) or (client_type == DpsClientType.external_gateway)): for pip_tuple in pip_tuple_list: inet_type = pip_tuple[0] pip_value = pip_tuple[1] #ip_location = IPAddressLocation(inet_type, pip_value, 0) #print 'Tunnel Registration: VNID %s, IP %s\r'%(dvg.unique_id, ip_location.show_ip()) if inet_type == socket.AF_INET: ip_hash = domain.Tunnel_Endpoints_Hash_IPv4 else: ip_hash = domain.Tunnel_Endpoints_Hash_IPv6 try: tunnel = ip_hash[pip_value] if tunnel.dps_client != dps_client: message = 'Tunnel %s migrated from DPS Client %s to %s\r'%(tunnel.primary_ip().show_ip(), tunnel.dps_client.location.show_ip(), dps_client.location.show_ip()) dcslib.dps_data_write_log(DpsLogLevels.NOTICE, message) #Delete the Tunnel IP since it no longer belongs with this #Tunnel object tunnel.ip_clear(inet_type, pip_value) continue tunnel_set[tunnel] = True except Exception: continue if len(tunnel_set) > 1: #More than 1 tunnels found corresponding to the IP Addresses #Merge them into a single tunnel tunnels = tunnel_set.keys() tunnel_primary = tunnels[0] tunnels_secondary = tunnels[1:] for tunnel_secondary in tunnels_secondary: print 'TunnelEndpoint.merge tunnel_primary %s, tunnel_secondary %s\r'%(tunnel_primary, tunnel_primary) TunnelEndpoint.merge_tunnels(tunnel_primary, tunnel_secondary) tunnel = tunnel_primary elif len(tunnel_set) == 1: tunnel = tunnel_set.keys()[0] else: tunnel = None if tunnel is not None: tunnel.DVG_Hash[client_type][dvg.unique_id] = dvg for pip_tuple in pip_tuple_list: inet_type = pip_tuple[0] pip_value = pip_tuple[1] tunnel.ip_add(dvg, False, client_type, inet_type, pip_value, transaction_type) DPSClientHost.Host_Add(domain, dps_client.location.inet_type, dps_client.location.ip_value, dps_client.location.port, client_type) else: #Allocate a new tunnel tunnel = TunnelEndpoint(True, domain, dvg, client_type, transaction_type, dps_client, pip_tuple_list) #if tunnel is not None: # tunnel.show_details() if client_type == DpsClientType.external_gateway: for pip_tuple in pip_tuple_list: inet_type = pip_tuple[0] pip_value = pip_tuple[1] try: if inet_type == socket.AF_INET: IPList = dvg.ExternalGatewayIPListv4 else: IPList = dvg.ExternalGatewayIPListv6 IPList.add(inet_type, pip_value) except Exception: pass return
class AddressResolution: ''' Represents Address Resolution object for a Domain. ''' def __init__(self, domain_id): ''' Constructor: @param domain_id: Domain ID @type domain_id: Integer ''' self.domain_id = domain_id #Set of Endpoint Resolutions waiting to be resolved. #Keyed by IP value self.endpoint_resolution = {} #Total amount of waiting clients self.total = 0 #Max amount of waiters allowed self.total_max = 32 #Max amount of non-found vIP addresses self.vIP_not_found_max = 8 #Mark as valid self.valid = True def process_lookup_not_found(self, dps_client, dvg, vIP_type, vIP_val): ''' This routine process a Virtual IP Address that couldn't be found in the list of Endpoint @param dps_client: The DPS Client @type dps_client: DPSClient @param dvg: The sending VNID @type dvg: Integer @param vIP_val: Virtual IP Address @type vIP_val: Integer and String @return: True if Address Resolution needs to be sent out False otherwise @rtype: Boolean ''' fSendAddressResolution = True try: try: resolution_obj = self.endpoint_resolution[vIP_val] fSendAddressResolution = False except Exception: resolution_obj = AddressResolutionvIP(vIP_type, vIP_val) self.endpoint_resolution[vIP_val] = resolution_obj added = resolution_obj.add(dps_client, dvg) if added: self.total += 1 except Exception: fSendAddressResolution = False return fSendAddressResolution def dps_client_delete(self, dps_client): ''' This routine must be called whenever a dps_client is deleted from the domain @param dps_client: The DPS Client @type dps_client: DPSClient ''' for resolution_obj in self.endpoint_resolution.values(): self.total -= resolution_obj.dps_client_delete(dps_client) if self.total < 0: message = 'AddressResolution.dps_client_delete: Problem with accounting' dcslib.dps_data_write_log(DpsLogLevels.WARNING, message) return def vnid_delete(self, dvg): ''' This routine must be called whenever a VNID is deleted in the domain @param dvg: The VNID that asked for this endpoint @type dvg: DVG ''' for resolution_obj in self.endpoint_resolution.values(): self.total -= resolution_obj.vnid_delete(dvg) if self.total < 0: message = 'AddressResolution.vnid_delete: Problem with accounting' dcslib.dps_data_write_log(DpsLogLevels.WARNING, message) return def process_endpoint_update(self, endpoint, vIP_val): ''' This routine checks which DPS Client have been waiting for this endpoint update and sends resolution to those DPS Clients @param endpoint: The Endpoint being updated @type endpoint: Endpoint @param vIP_val: The vIP Value @type vIP_val: Integer or String ''' while True: try: resolution_obj = self.endpoint_resolution[vIP_val] del self.endpoint_resolution[vIP_val] except Exception: break try: self.total -= resolution_obj.resolved(endpoint) except Exception, ex: message = 'AddressResolution.process_endpoint_update Problem Resolving Exception %s' % ex dcslib.dps_data_write_log(DpsLogLevels.WARNING, message) break if self.total < 0: message = 'AddressResolution.process_endpoint_update: Problem with accounting' dcslib.dps_data_write_log(DpsLogLevels.WARNING, message) return
def show(self): ''' ''' message = '----------------------------------------------' dcslib.dps_data_write_log(DpsLogLevels.NOTICE, message) if self.global_scope: message = 'GLOBAL SCOPE, VNID %s'%self.dvg.unique_id else: message = 'MULTICAST MAC %s, VNID %s'%(mac_show(self.mac), self.dvg.unique_id) dcslib.dps_data_write_log(DpsLogLevels.NOTICE, message) if len(self.receiver_all) > 0: message = 'MULTICAST Receivers (NO IP Address)' dcslib.dps_data_write_log(DpsLogLevels.NOTICE, message) count = 1 for tunnel in self.receiver_all.keys(): message = ' [%d] Tunnel %s'%(count, tunnel.primary_ip().show()) dcslib.dps_data_write_log(DpsLogLevels.NOTICE, message) count += 1 if len(self.receiver_iphash) > 0: for iphash_key in self.receiver_iphash.keys(): try: if type(iphash_key) == type(1): ip_address = IPAddressLocation(socket.AF_INET, iphash_key, 0) else: ip_address = IPAddressLocation(socket.AF_INET6, iphash_key, 0) except Exception: continue message = 'MULTICAST Receivers IP Address %s'%ip_address.show() dcslib.dps_data_write_log(DpsLogLevels.NOTICE, message) iphash = self.receiver_iphash[iphash_key] count = 1; for tunnel in iphash.keys(): message = ' [%d] Tunnel %s'%(count, tunnel.primary_ip().show()) dcslib.dps_data_write_log(DpsLogLevels.NOTICE, message) count += 1 if len(self.sender_all) > 0: message = 'MULTICAST Senders (NO IP Address)' dcslib.dps_data_write_log(DpsLogLevels.NOTICE, message) count = 1 for tunnel in self.sender_all.keys(): message = ' [%d] Tunnel %s'%(count, tunnel.primary_ip().show()) dcslib.dps_data_write_log(DpsLogLevels.NOTICE, message) count += 1 if len(self.sender_iphash) > 0: for iphash_key in self.sender_iphash.keys(): try: if type(iphash_key) == type(1): ip_address = IPAddressLocation(socket.AF_INET, iphash_key, 0) else: ip_address = IPAddressLocation(socket.AF_INET6, iphash_key, 0) except Exception: continue message = 'MULTICAST Senders IP Address %s'%ip_address.show() dcslib.dps_data_write_log(DpsLogLevels.NOTICE, message) iphash = self.sender_iphash[iphash_key] count = 1 for tunnel in iphash.keys(): message = ' [%d] Tunnel %s'%(count, tunnel.primary_ip().show()) dcslib.dps_data_write_log(DpsLogLevels.NOTICE, message) count += 1 message = '----------------------------------------------' dcslib.dps_data_write_log(DpsLogLevels.NOTICE, message) return
def register(domain, dvg, client_type, transaction_type, dps_client, pip_tuple_list): ''' This routine should be called when a set of tunnel endpoint IP Addresses are registered by the DPS Client Protocol Handler. @param domain: The Domain object @type domain: Domain @param dvg: The DVG/VNID object @type dvg: DVG @param client_type: The Type of Client: should be in DpsClientType.types @type client_type: Integer @param transaction_type: The Type of Transaction: should be in Domain.transaction_types @type transaction_type: Integer @param dps_client: The DPS Client associated with this Tunnel @type dps_client: DPSClient @type dps_client_port: Integer @param pip_tuple_list: A list of tuples of Physical IP Addresses, each tuple is of the form (inet_type, ip_value). The inet_type = socket type i.e. AF_INET or AF_INET6 The ip_value = IPv4 in integer or IPv6 in string @type pip_tuple_list: List of tuples ''' #Find if a tunnel exists with existing pIP if len(pip_tuple_list) == 0: return tunnel_set = {} if ((client_type == DpsClientType.dove_switch) or (client_type == DpsClientType.vlan_gateway) or (client_type == DpsClientType.external_gateway)): for pip_tuple in pip_tuple_list: inet_type = pip_tuple[0] pip_value = pip_tuple[1] #ip_location = IPAddressLocation(inet_type, pip_value, 0) #print 'Tunnel Registration: VNID %s, IP %s\r'%(dvg.unique_id, ip_location.show_ip()) if inet_type == socket.AF_INET: ip_hash = domain.Tunnel_Endpoints_Hash_IPv4 else: ip_hash = domain.Tunnel_Endpoints_Hash_IPv6 try: tunnel = ip_hash[pip_value] if tunnel.dps_client != dps_client: message = 'Tunnel %s migrated from DPS Client %s to %s\r' % ( tunnel.primary_ip().show_ip(), tunnel.dps_client.location.show_ip(), dps_client.location.show_ip()) dcslib.dps_data_write_log(DpsLogLevels.NOTICE, message) #Delete the Tunnel IP since it no longer belongs with this #Tunnel object tunnel.ip_clear(inet_type, pip_value) continue tunnel_set[tunnel] = True except Exception: continue if len(tunnel_set) > 1: #More than 1 tunnels found corresponding to the IP Addresses #Merge them into a single tunnel tunnels = tunnel_set.keys() tunnel_primary = tunnels[0] tunnels_secondary = tunnels[1:] for tunnel_secondary in tunnels_secondary: print 'TunnelEndpoint.merge tunnel_primary %s, tunnel_secondary %s\r' % ( tunnel_primary, tunnel_primary) TunnelEndpoint.merge_tunnels(tunnel_primary, tunnel_secondary) tunnel = tunnel_primary elif len(tunnel_set) == 1: tunnel = tunnel_set.keys()[0] else: tunnel = None if tunnel is not None: tunnel.DVG_Hash[client_type][dvg.unique_id] = dvg for pip_tuple in pip_tuple_list: inet_type = pip_tuple[0] pip_value = pip_tuple[1] tunnel.ip_add(dvg, False, client_type, inet_type, pip_value, transaction_type) DPSClientHost.Host_Add(domain, dps_client.location.inet_type, dps_client.location.ip_value, dps_client.location.port, client_type) else: #Allocate a new tunnel tunnel = TunnelEndpoint(True, domain, dvg, client_type, transaction_type, dps_client, pip_tuple_list) #if tunnel is not None: # tunnel.show_details() if client_type == DpsClientType.external_gateway: for pip_tuple in pip_tuple_list: inet_type = pip_tuple[0] pip_value = pip_tuple[1] try: if inet_type == socket.AF_INET: IPList = dvg.ExternalGatewayIPListv4 else: IPList = dvg.ExternalGatewayIPListv6 IPList.add(inet_type, pip_value) except Exception: pass return