def update_interface(self, other_interface, ignore_mgmt=True):
        """
        Update an existing interface by comparing values between two
        interfaces. If a VLAN interface is defined in the other interface
        and it doesn't exist on the existing interface, it will be created.
        
        :param other_interface Interface: an instance of an
            interface where values in this interface will be used to as the
            template to determine changes. This only has to provide attributes
            that need to change (or not).
        :param bool ignore_mgmt: ignore resetting management fields. These are
            generally better set after creation using `engine.interface_options`
        :raises UpdateElementFailed: Failed to update the element
        :return: (Interface, modified, created)
        :rtype: tuple
        
        .. note:: Interfaces with multiple IP addresses are ignored
        """
        base_updated = self._update_interface(other_interface)
        
        mgmt = ('auth_request', 'backup_heartbeat', 'backup_mgt',
            'primary_mgt', 'primary_heartbeat', 'outgoing')
        
        updated = False
        invalid_routes = []
            
        def process_interfaces(current, interface):
            updated = False
            invalid_routes = []
            
            # Ignore interfaces with multiple addresses
            if current.has_multiple_addresses:
                return updated, invalid_routes
            
            local_interfaces = current.interfaces # Existing interface
            for interface in interface.interfaces: # New values
                local_interface = None
                if not getattr(interface, 'nodeid', None): # CVI
                    cvi = [itf for itf in local_interfaces if not getattr(itf, 'nodeid', None)]
                    local_interface = cvi[0] if cvi else None
                else:
                    local_interface = local_interfaces.get(nodeid=interface.nodeid)
                
                if local_interface: # CVI or NDI sub interfaces
                    for name, value in interface.data.items():
                        if getattr(local_interface, name) != value:
                            if ignore_mgmt and name in mgmt:
                                pass
                            else:
                                local_interface[name] = value
                                updated = True
                            if 'network_value' in name: # Only reset routes if network changed
                                invalid_routes.append(interface.nicid)
                else:
                    current.data.setdefault('interfaces', []).append(
                        {interface.typeof: interface.data})
                    updated = True
            return updated, invalid_routes

        # Handle VLANs
        is_vlan = other_interface.has_vlan
        if is_vlan:
            vlan_interfaces = self.vlan_interface
            for pvlan in other_interface.vlan_interface:
                current = vlan_interfaces.get(pvlan.vlan_id)
                if current:
                    # PhysicalVlanInterface, set any parent interface values
                    if current._update_interface(pvlan):
                        updated = True
                else:
                    # Create new interface
                    self.data.setdefault('vlanInterfaces', []).append(pvlan.data)
                    updated = True
                    continue # Skip sub interface check
                
                _updated, routes = process_interfaces(current, pvlan)
                if _updated: updated = True
                invalid_routes.extend(routes)

        else:
            _updated, routes = process_interfaces(self, other_interface)
            if _updated: updated = True
            invalid_routes.extend(routes)
            
        interface = self
        if updated or base_updated:
            interface = self.update()
            if invalid_routes: # Interface updated, check the routes
                del_invalid_routes(self._engine, invalid_routes)
            
        return interface, base_updated or updated
Update an existing interface by comparing values between two
        interfaces. If a VLAN interface is defined in the other interface
        and it doesn't exist on the existing interface, it will be created.
        
        :param other_interface Interface: an instance of an
            interface where values in this interface will be used to as the
            template to determine changes. This only has to provide attributes
            that need to change (or not).
        :param bool ignore_mgmt: ignore resetting management fields. These are
            generally better set after creation using `engine.interface_options`
        :raises UpdateElementFailed: Failed to update the element
        :return: (Interface, modified, created)
        :rtype: tuple
        
        .. note:: Interfaces with multiple IP addresses are ignored