Ok, eu tive que brincar com soquetes crus agora.
No entanto, raw sockets ( man 7 raw
, socket(AF_INET, SOCK_RAW, ...)
) realmente funcionam na camada 3. Você disse que você escreve quadros ethernet raw, e faz ARP, então possivelmente você quer dizer soquetes de pacotes ( man 7 packet
, socket(AF_PACKET, SOCK_RAW, ...)
).
Para soquetes de pacotes e soquetes brutos, os pacotes não são roteados adequadamente, mas colocados diretamente na parte de saída de uma interface específica. Essa interface pode ser determinada ligando-se a ela por nome ou procurando o endereço de destino. Então "o encaminhamento acontece automaticamente pelo kernel" não é verdade: Nenhum encaminhamento acontece. Em particular, se o destino for um endereço local, o pacote não será reencaminhado através da interface de loopback.
Isso torna este método totalmente inadequado para simular um dispositivo com um "ponto final de interface extra" no host.
Quanto aos macvlans, o modo de ponte é descrito como
The macvlan is a trivial bridge that doesn't need to do learning as it knows every mac address it can receive, so it doesn't need to implement learning or stp. Which makes it simple stupid and and fast.
Acredito que isso significa que os macvlans fazem uma ponte examinando o endereço MAC da interface original e cada endereço MAC adicional adicionado por um macvlan. O que significa que, como você está emulando o endereço MAC por meio de soquetes brutos, o código do macvlan não sabe que há um endereço MAC "adicional" e, portanto, não pode encontrar nenhum destino para ele.
Acrescente a isso que sockets raw e packet precisam de root (o que não deveria ser necessário para uma aplicação emulando algum outro dispositivo), então, na minha opinião, sockets raw e packet são totalmente inadequados para este tipo de aplicação. Eles são voltados para a implementação de novos protocolos IP ou outras coisas de rede de baixo nível no espaço do usuário, e nada mais.
Então, meu conselho ainda seria: não use soquetes raw / packet. Use uma interface de toque, como o QEMU ou outros emuladores. Isso permitirá que seu aplicativo seja executado como não-raiz e você poderá configurar qualquer configuração de rede no host desejado (rotear na camada 3 ou vinculá-la à camada 2).