Graças à lista de discussão netdev, tenho uma resposta. Há um recurso que eu nunca ouvi falar, chamado de "filtragem de caminho inverso". Quando ativado, esse recurso de roteamento do kernel descartará silenciosamente pacotes de entrada se eles chegarem em uma interface diferente da interface que seria usada pelos pacotes de saída para o endereço de origem. Ele é um recurso de segurança e é um bom padrão na maioria das circunstâncias, especialmente quando você não tem o iptables configurado com cuidado.
O CentOS (e presumivelmente o RHEL) ativa a filtragem de caminho reverso por padrão em /etc/sysctl.conf (net.ipv4.conf.default.rp_filter = 1). Eu adicionei os seguintes comandos ao meu script de configuração:
echo 0 > /proc/sys/net/ipv4/conf/tunnel1/rp_filter
echo 0 > /proc/sys/net/ipv4/conf/tunnel2/rp_filter
Isso desativa a filtragem de caminho inverso para as duas pseudointerfaces e tudo funciona agora.
Note que adicionar ao sysctl.conf para minhas interfaces específicas não teria funcionado para mim, já que essas interfaces são criadas "on the fly", e o sysctl.conf é lido apenas no momento da inicialização. Eu poderia, é claro, ter alterado o padrão em sysctl.conf, mas não queria desativar o recurso para minhas outras interfaces.