diff --git a/source3/smbd/server.c b/source3/smbd/server.c
index aba980e9375..e2d6c8c0be1 100644
--- a/source3/smbd/server.c
+++ b/source3/smbd/server.c
@@ -1284,6 +1284,13 @@ static bool open_sockets_smbd(struct smbd_parent_context *parent,
 	messaging_register(msg_ctx, NULL, MSG_SMB_NOTIFY_STARTED,
 			   smb_parent_send_to_children);
 
+	if (lp_interfaces() && lp_bind_interfaces_only()) {
+		messaging_register(msg_ctx,
+				   NULL,
+				   MSG_SMB_IP_DROPPED,
+				   smb_parent_send_to_children);
+	}
+
 #ifdef DEVELOPER
 	messaging_register(msg_ctx, NULL, MSG_SMB_INJECT_FAULT,
 			   msg_inject_fault);
@@ -1640,6 +1647,7 @@ static void smbd_init_addrchange(TALLOC_CTX *mem_ctx,
 }
 
 static void smbd_close_socket_for_ip(struct smbd_parent_context *parent,
+				     struct messaging_context *msg_ctx,
 				     struct sockaddr_storage *addr)
 {
 	struct smbd_open_socket *s = NULL;
@@ -1655,12 +1663,25 @@ static void smbd_close_socket_for_ip(struct smbd_parent_context *parent,
 		if (sockaddr_equal((struct sockaddr *)&a,
 				   (struct sockaddr *)addr)) {
 			char addrstr[INET6_ADDRSTRLEN];
+			DATA_BLOB blob;
+			NTSTATUS status;
 
 			DLIST_REMOVE(parent->sockets, s);
 			TALLOC_FREE(s);
 			print_sockaddr(addrstr, sizeof(addrstr), addr);
 			DBG_NOTICE("smbd: Closed listening socket for %s\n",
 				   addrstr);
+
+			blob = data_blob_const(addrstr, strlen(addrstr)+1);
+			status = messaging_send(msg_ctx,
+						messaging_server_id(msg_ctx),
+						MSG_SMB_IP_DROPPED,
+						&blob);
+			if (!NT_STATUS_IS_OK(status)) {
+				DBG_NOTICE(
+					"messaging_send failed: %s - ignoring\n",
+					nt_errstr(status));
+			}
 			return;
 		}
 	}
@@ -1693,7 +1714,7 @@ static void smbd_addr_changed(struct tevent_req *req)
 			   "on if_index %u\n",
 			   addrstr, if_index);
 
-		smbd_close_socket_for_ip(state->parent, &addr);
+		smbd_close_socket_for_ip(state->parent, state->msg_ctx, &addr);
 
 		goto rearm;
 	}
diff --git a/source3/smbd/smb2_process.c b/source3/smbd/smb2_process.c
index 482c448e81b..4a6cda39a2f 100644
--- a/source3/smbd/smb2_process.c
+++ b/source3/smbd/smb2_process.c
@@ -1565,6 +1565,38 @@ static void msg_kill_client_ip(struct messaging_context *msg_ctx,
 	TALLOC_FREE(client_ip);
 }
 
+static void msg_kill_client_with_server_ip(struct messaging_context *msg_ctx,
+				      void *private_data,
+				      uint32_t msg_type,
+				      struct server_id server_id,
+				      DATA_BLOB *data)
+{
+	struct smbd_server_connection *sconn = talloc_get_type_abort(
+		private_data, struct smbd_server_connection);
+	const char *ip = (char *) data->data;
+	char *server_ip = NULL;
+	TALLOC_CTX *ctx = NULL;
+
+	DBG_NOTICE("Got kill request for source IP %s\n", ip);
+	ctx = talloc_stackframe();
+
+	server_ip = tsocket_address_inet_addr_string(sconn->local_address, ctx);
+	if (server_ip == NULL) {
+		goto out_free;
+	}
+
+	if (strequal(ip, server_ip)) {
+		DBG_NOTICE(
+			"Got ip dropped message for %s - exiting immediately\n",
+			ip);
+		TALLOC_FREE(ctx);
+		exit_server_cleanly("Forced disconnect for client");
+	}
+
+out_free:
+	TALLOC_FREE(ctx);
+}
+
 /*
  * Do the recurring check if we're idle
  */
@@ -2019,6 +2051,12 @@ void smbd_process(struct tevent_context *ev_ctx,
 	messaging_register(sconn->msg_ctx, NULL,
 			   MSG_DEBUG, debug_message);
 
+	messaging_deregister(sconn->msg_ctx, MSG_SMB_IP_DROPPED, NULL);
+	messaging_register(sconn->msg_ctx,
+			   sconn,
+			   MSG_SMB_IP_DROPPED,
+			   msg_kill_client_with_server_ip);
+
 #if defined(WITH_SMB1SERVER)
 	if ((lp_keepalive() != 0) &&
 	    !(event_add_idle(ev_ctx,