diff --git a/apps/app_chanspy.c b/apps/app_chanspy.c
index 5806b997d7..9f530c50da 100644
--- a/apps/app_chanspy.c
+++ b/apps/app_chanspy.c
@@ -508,7 +508,7 @@ static int start_spying(struct ast_autochan *autochan, const char *spychan_name,
 	if (!res) {
 		ast_channel_lock(autochan->chan);
 		if (ast_channel_is_bridged(autochan->chan)) {
-			ast_softhangup_nolock(autochan->chan, AST_SOFTHANGUP_UNBRIDGE);
+			ast_channel_set_unbridged_nolock(autochan->chan, 1);
 		}
 		ast_channel_unlock(autochan->chan);
 	}
diff --git a/apps/app_mixmonitor.c b/apps/app_mixmonitor.c
index 52128942ab..cf7b935185 100644
--- a/apps/app_mixmonitor.c
+++ b/apps/app_mixmonitor.c
@@ -461,7 +461,7 @@ static int startmon(struct ast_channel *chan, struct ast_audiohook *audiohook)
 	if (!res) {
 		ast_channel_lock(chan);
 		if (ast_channel_is_bridged(chan)) {
-			ast_softhangup_nolock(chan, AST_SOFTHANGUP_UNBRIDGE);
+			ast_channel_set_unbridged_nolock(chan, 1);
 		}
 		ast_channel_unlock(chan);
 	}
diff --git a/apps/app_stack.c b/apps/app_stack.c
index b05afb0e5c..c9d37cd344 100644
--- a/apps/app_stack.c
+++ b/apps/app_stack.c
@@ -976,10 +976,9 @@ static int gosub_run(struct ast_channel *chan, const char *sub_args, int ignore_
 
 	/* Save non-hangup softhangup flags. */
 	saved_hangup_flags = ast_channel_softhangup_internal_flag(chan)
-		& (AST_SOFTHANGUP_ASYNCGOTO | AST_SOFTHANGUP_UNBRIDGE);
+		& AST_SOFTHANGUP_ASYNCGOTO;
 	if (saved_hangup_flags) {
-		ast_channel_clear_softhangup(chan,
-			AST_SOFTHANGUP_ASYNCGOTO | AST_SOFTHANGUP_UNBRIDGE);
+		ast_channel_clear_softhangup(chan, AST_SOFTHANGUP_ASYNCGOTO);
 	}
 
 	/* Save autoloop flag */
@@ -1028,10 +1027,6 @@ static int gosub_run(struct ast_channel *chan, const char *sub_args, int ignore_
 		 */
 		do {
 			/* Check for hangup. */
-			if (ast_channel_softhangup_internal_flag(chan) & AST_SOFTHANGUP_UNBRIDGE) {
-				saved_hangup_flags |= AST_SOFTHANGUP_UNBRIDGE;
-				ast_channel_clear_softhangup(chan, AST_SOFTHANGUP_UNBRIDGE);
-			}
 			if (ast_check_hangup(chan)) {
 				if (ast_channel_softhangup_internal_flag(chan) & AST_SOFTHANGUP_ASYNCGOTO) {
 					ast_log(LOG_ERROR, "%s An async goto just messed up our execution location.\n",
diff --git a/include/asterisk/channel.h b/include/asterisk/channel.h
index 08f4effe60..cee07f2cb7 100644
--- a/include/asterisk/channel.h
+++ b/include/asterisk/channel.h
@@ -1048,11 +1048,6 @@ enum {
 	 * needed.
 	 */
 	AST_SOFTHANGUP_EXPLICIT =  (1 << 5),
-	/*!
-	 * Used to request that the bridge core re-evaluate the current
-	 * bridging technology in use by the bridge this channel is in.
-	 */
-	AST_SOFTHANGUP_UNBRIDGE =  (1 << 6),
 	/*!
 	 * Used to indicate that the channel is currently executing hangup
 	 * logic in the dialplan. The channel has been hungup when this is
@@ -1574,6 +1569,40 @@ int ast_check_hangup(struct ast_channel *chan);
 
 int ast_check_hangup_locked(struct ast_channel *chan);
 
+/*! \brief This function will check if the bridge needs to be re-evaluated due to
+ *         external changes.
+ *
+ *  \param chan Channel on which to check the unbridge_eval flag
+ *
+ *  \return Returns 0 if the flag is down or 1 if the flag is up.
+ */
+int ast_channel_unbridged(struct ast_channel *chan);
+
+/*! \brief ast_channel_unbridged variant. Use this if the channel
+ *         is already locked prior to calling.
+ *
+ *  \param chan Channel on which to check the unbridge flag
+ *
+ *  \return Returns 0 if the flag is down or 1 if the flag is up.
+ */
+int ast_channel_unbridged_nolock(struct ast_channel *chan);
+
+/*! \brief Sets the unbridged flag and queues a NULL frame on the channel to trigger
+ *         a check by bridge_channel_wait
+ *
+ *  \param chan Which channel is having its unbridged value set
+ *  \param value What the unbridge value is being set to
+ */
+void ast_channel_set_unbridged(struct ast_channel *chan, int value);
+
+/*! \brief Variant of ast_channel_set_unbridged. Use this if the channel
+ *         is already locked prior to calling.
+ *
+ *  \param chan Which channel is having its unbridged value set
+ *  \param value What the unbridge value is being set to
+ */
+void ast_channel_set_unbridged_nolock(struct ast_channel *chan, int value);
+
 /*!
  * \brief Lock the given channel, then request softhangup on the channel with the given causecode
  * \param chan channel on which to hang up
diff --git a/main/bridge_after.c b/main/bridge_after.c
index fbe4e605a5..a21cbf58ea 100644
--- a/main/bridge_after.c
+++ b/main/bridge_after.c
@@ -452,9 +452,9 @@ int ast_bridge_setup_after_goto(struct ast_channel *chan)
 	int goto_failed = -1;
 
 	/* We are going to be leaving the bridging system now;
-	 * clear any pending UNBRIDGE flags
+	 * clear any pending unbridge flags
 	 */
-	ast_channel_clear_softhangup(chan, AST_SOFTHANGUP_UNBRIDGE);
+	ast_channel_set_unbridged(chan, 0);
 
 	/* Determine if we are going to setup a dialplan location and where. */
 	if (ast_channel_softhangup_internal_flag(chan) & AST_SOFTHANGUP_ASYNCGOTO) {
diff --git a/main/bridge_channel.c b/main/bridge_channel.c
index 5c2e56241d..f6b4665455 100644
--- a/main/bridge_channel.c
+++ b/main/bridge_channel.c
@@ -2281,8 +2281,8 @@ static void bridge_channel_wait(struct ast_bridge_channel *bridge_channel)
 		ms = bridge_channel_next_interval(bridge_channel);
 		chan = ast_waitfor_nandfds(&bridge_channel->chan, 1,
 			&bridge_channel->alert_pipe[0], 1, NULL, &outfd, &ms);
-		if (ast_channel_softhangup_internal_flag(bridge_channel->chan) & AST_SOFTHANGUP_UNBRIDGE) {
-			ast_channel_clear_softhangup(bridge_channel->chan, AST_SOFTHANGUP_UNBRIDGE);
+		if (ast_channel_unbridged(bridge_channel->chan)) {
+			ast_channel_set_unbridged(bridge_channel->chan, 0);
 			ast_bridge_channel_lock_bridge(bridge_channel);
 			bridge_channel->bridge->reconfigured = 1;
 			bridge_reconfigured(bridge_channel->bridge, 0);
diff --git a/main/channel.c b/main/channel.c
index 50b9e87261..5681ec1a52 100644
--- a/main/channel.c
+++ b/main/channel.c
@@ -10217,11 +10217,11 @@ int ast_channel_is_bridged(const struct ast_channel *chan)
 int ast_channel_is_leaving_bridge(struct ast_channel *chan)
 {
 	int hangup_flags = ast_channel_softhangup_internal_flag(chan);
-	int hangup_test = hangup_flags & (AST_SOFTHANGUP_ASYNCGOTO | AST_SOFTHANGUP_UNBRIDGE);
+	int hangup_test = hangup_flags & AST_SOFTHANGUP_ASYNCGOTO;
 
-	/* This function should only return true if either ASYNCGOTO
-	 * or UNBRIDGE is set, or both flags are set. It should return
-	 * false if any other flag is set.
+	/* This function should only return true if only the ASYNCGOTO
+	 * is set. It should false if any other flag is set or if the
+	 * ASYNCGOTO flag is not set.
 	 */
 	return (hangup_test && (hangup_test == hangup_flags));
 }
@@ -10518,7 +10518,7 @@ void ast_channel_end_dtmf(struct ast_channel *chan, char digit, struct timeval s
 	ast_channel_lock(chan);
 	dead = ast_test_flag(ast_channel_flags(chan), AST_FLAG_ZOMBIE)
 		|| (ast_channel_softhangup_internal_flag(chan)
-			& ~(AST_SOFTHANGUP_ASYNCGOTO | AST_SOFTHANGUP_UNBRIDGE));
+			& ~AST_SOFTHANGUP_ASYNCGOTO);
 	ast_channel_unlock(chan);
 	if (dead) {
 		/* Channel is a zombie or a real hangup. */
diff --git a/main/channel_internal_api.c b/main/channel_internal_api.c
index 8a9e18eb00..e32a52791a 100644
--- a/main/channel_internal_api.c
+++ b/main/channel_internal_api.c
@@ -173,6 +173,8 @@ struct ast_channel {
 							 *   See \arg \ref AstFileDesc */
 	int softhangup;				/*!< Whether or not we have been hung up...  Do not set this value
 							 *   directly, use ast_softhangup() */
+	int unbridged;              /*!< If non-zero, the bridge core needs to re-evaluate the current
+	                                 bridging technology which is in use by this channel's bridge. */
 	int fdno;					/*!< Which fd had an event detected on */
 	int streamid;					/*!< For streaming playback, the schedule ID */
 	int vstreamid;					/*!< For streaming video playback, the schedule ID */
@@ -377,7 +379,6 @@ int ast_channel_data_add_structure(struct ast_data *tree,
 	ast_data_add_bool(data_softhangup, "timeout", ast_channel_softhangup_internal_flag(chan) & AST_SOFTHANGUP_TIMEOUT);
 	ast_data_add_bool(data_softhangup, "appunload", ast_channel_softhangup_internal_flag(chan) & AST_SOFTHANGUP_APPUNLOAD);
 	ast_data_add_bool(data_softhangup, "explicit", ast_channel_softhangup_internal_flag(chan) & AST_SOFTHANGUP_EXPLICIT);
-	ast_data_add_bool(data_softhangup, "unbridge", ast_channel_softhangup_internal_flag(chan) & AST_SOFTHANGUP_UNBRIDGE);
 
 	/* channel flags */
 	data_flags = ast_data_add_node(tree, "flags");
@@ -1141,6 +1142,33 @@ void ast_channel_softhangup_internal_flag_clear(struct ast_channel *chan, int va
 	chan ->softhangup &= ~value;
 }
 
+int ast_channel_unbridged_nolock(struct ast_channel *chan)
+{
+	return chan->unbridged;
+}
+
+int ast_channel_unbridged(struct ast_channel *chan)
+{
+	int res;
+	ast_channel_lock(chan);
+	res = ast_channel_unbridged_nolock(chan);
+	ast_channel_unlock(chan);
+	return res;
+}
+
+void ast_channel_set_unbridged_nolock(struct ast_channel *chan, int value)
+{
+	chan->unbridged = value;
+	ast_queue_frame(chan, &ast_null_frame);
+}
+
+void ast_channel_set_unbridged(struct ast_channel *chan, int value)
+{
+	ast_channel_lock(chan);
+	ast_channel_set_unbridged_nolock(chan, value);
+	ast_channel_unlock(chan);
+}
+
 void ast_channel_callid_cleanup(struct ast_channel *chan)
 {
 	if (chan->callid) {
diff --git a/main/framehook.c b/main/framehook.c
index 0d42b49906..ec4e1695f9 100644
--- a/main/framehook.c
+++ b/main/framehook.c
@@ -170,7 +170,7 @@ int ast_framehook_attach(struct ast_channel *chan, struct ast_framehook_interfac
 	}
 
 	if (ast_channel_is_bridged(chan)) {
-		ast_softhangup_nolock(chan, AST_SOFTHANGUP_UNBRIDGE);
+		ast_channel_set_unbridged_nolock(chan, 1);
 	}
 
 	return framehook->id;
@@ -199,7 +199,7 @@ int ast_framehook_detach(struct ast_channel *chan, int id)
 	AST_LIST_TRAVERSE_SAFE_END;
 
 	if (ast_channel_is_bridged(chan)) {
-		ast_softhangup_nolock(chan, AST_SOFTHANGUP_UNBRIDGE);
+		ast_channel_set_unbridged_nolock(chan, 1);
 	}
 
 	return res;
diff --git a/main/pbx.c b/main/pbx.c
index 785175fc4b..d814c5ac61 100644
--- a/main/pbx.c
+++ b/main/pbx.c
@@ -6363,11 +6363,6 @@ static enum ast_pbx_result __ast_pbx_run(struct ast_channel *c,
 			S_COR(ast_channel_caller(c)->id.number.valid, ast_channel_caller(c)->id.number.str, NULL),
 			&found, 1))) {
 
-			/* Defensively clear the UNBRIDGE flag in case it leaked
-			 * out of the bridging framework. UNBRIDE never implies
-			 * that a channel is hung up.
-			 */
-			ast_channel_clear_softhangup(c, AST_SOFTHANGUP_UNBRIDGE);
 			if (!ast_check_hangup(c)) {
 				ast_channel_priority_set(c, ast_channel_priority(c) + 1);
 				continue;