Eu tenho um aplicativo que está executando um soquete IP bruto, o destino deste soquete é governado pelas rotas instaladas através do comando 'ip route add'. Essas rotas podem mudar durante a vida útil de um soquete (por exemplo, porque as alterações do próximo salto)
Simplificado, digamos que eu tenha 2 interfaces, eth0
e eth1
. Eu também tenho uma rota padrão via eth0
.
O nó de extremidade do soquete não processado é, por exemplo, 10.10.10.10
, o eth1 tem o endereço 100.0.0.1
, eu faço o seguinte durante a vida útil do soquete bruto:
ip -f inet route delete 10.10.10.10
ip -f inet route add 100.0.0.2 dev eth1
ip -f inet route add 10.10.10.10/32 via 100.0.0.2 dev eth1
Agora, o que eu vejo é que após essa operação o tráfego vai corretamente via eth1
por alguns segundos, então dá errado (via eth0) por um tempo curto (menos de meio segundo) e então está correto novamente (como tanto quanto eu posso ver permanentemente).
Então, minha principal pergunta é:
-Alguém pode dar uma explicação do que pode dar errado aqui? Eu tentei adicionar ip route flush cache
após a seqüência mencionada antes, mas isso não fez nada. Atualmente estou intrigado porque o tráfego às vezes cai. Eu acho que é um problema de tempo nos comandos de roteamento ou algum outro gatilho desabilitando a rota por uma fração de segundo, mas estou ficando sem opções.
Eu tentei usar a opção SO_BINDTODEVICE
no meu soquete bruto, mas, infelizmente, isso não ajudou muito, a principal diferença é que quando o tráfego dá errado, ele não é enviado , porque passaria pela interface errada. No entanto, o que eu esperava era que isso colocasse o erro em algo como E_CANNOTROUTE (isso não existe) para que eu pudesse pegar isso e tentar enviar o pacote novamente. Atualmente ele não faz isso, mas existe uma maneira de eu pegar esse fracasso? Eu tenho (quase) controle total sobre o sistema e o aplicativo que executa o soquete.
Uma solução que eu sei que funcionaria seria não usar soquetes brutos L3, mas AF_PACKET
sockets (e também fazer ARP / ND eu mesmo), mas prefiro não entrar nisso ainda.
Atualizar
Eu melhorei o comportamento em meu sistema, alterando esse comportamento de mudança de rota. Quando tenho que atualizar o próximo salto, agora procuro a rota já instalada e tomo uma ação com base nisso:
- Se não estiver lá, basta instalar a nova rota e pular a exclusão.
- Se a rota exata já estiver presente (mesmo nh, mesmo dev), agora não faço nada.
- Se outro nh estiver presente para esta rota, faço agora uma exclusão mais específica para apenas este nh seguido por um add.
Embora isso tenha estabilizado a maioria dos meus problemas, às vezes ainda vejo a mesma coisa (embora com muito menos frequência) quando um delete + add real acontece (último caso no novo mecanismo). Além disso, isso na verdade ainda não explica o que está errado (apenas contorna isso), então deixarei essa questão em aberto por enquanto, estou realmente curioso sobre o que está errado aqui.
FYI: Eu tenho o problema no centos, tanto quanto eu posso ver indo de centos4 para centos6, 32-bit.