How to create a filter and add query params to all links

Assuming you mean $post->ID, you can use the post_link and post_type_link filters to append your query string. We’re using the add_query_arg() function to do this:

/**
 * Modify the posts navigation WHERE clause
 * to include our acceptable post types
 * 
 * @param String $post_link - Post URL
 * @param WP_Post $post - Current Post
 * 
 * @return String
 */
function wpse375877_link_referrer( $post_link, $post ) {
    
    // Return Early
    if( is_admin() ) {
        return $post_link;
    }
    
    return add_query_arg( array(
        'id'        => $post->ID,
        'referrer'  => $post_link,
    ) );
    
}
add_filter( 'post_link',        'wpse375877_link_referrer', 20, 2 );
add_filter( 'post_type_link',   'wpse375877_link_referrer', 20, 2 );

The above ensures that any WordPress functions will be given a modified post URL. Now, if we wanted to redirect any URLs missing this query string, you can use template_redirect action hook:

/**
 * Redirect any items without query string
 * 
 * @return void
 */
function wpse375877_redirect_to_referrer() {
    
    if( ! isset( $_GET, $_GET['id'], $_GET['referrer'] ) ) {
        
        wp_safe_redirect(
            add_query_arg( array(
                'id'        => get_the_ID(),
                'referrer'  => get_permalink(),
            ), get_permalink() )
        );
        exit();
        
    }
    
}
add_action( 'template_redirect', 'wpse375877_redirect_to_referrer' );

I’m not 100% sure if I should be using urlencode() on these URLs or not.