A regra de roteamento lê a marca do pacote, não o conntrack
O roteamento por política lê a marca do pacote; o conntrack guarda um valor diferente com vida mais longa. Copiar entre os dois é um passo que alguém tem de escrever.
Quatro verificações separam uma regra de marca que funciona de uma rota que funciona: qual marca a regra lê, se o pacote ainda a carrega no momento da consulta, se uma marca de conexão foi restaurada nos pacotes seguintes e se se a máscara e a prioridade da regra correspondente lhe permitem disparar. Um contador que aumenta prova apenas que alguma regra correspondeu a algo. Não diz nada sobre o que o pacote carregava quando o kernel escolheu o seu caminho.
As duas marcas vivem em lugares diferentes e expiram segundo calendários diferentes.
Duas marcas, duas vidas
Uma marca de pacote pertence a um único skb, viaja com ele pelos hooks e é consumida pelo seletor fwmark do roteamento por política. Uma marca de conexão pertence à entrada de conntrack, persiste ao longo dos pacotes desse fluxo e é invisível para a regra de roteamento até que algo a copie de volta. Guardar uma marca de pacote na conexão é um armazenamento; restaurá-la é uma ação separada. Nenhuma das duas acontece implicitamente.
Por isso um conjunto de regras pode parecer coerente enquanto a decisão de roteamento vê zero: o valor foi guardado e nada o restaurou.
Copiar entre as duas é um passo que você escreve
As duas instruções que importam seguem direções opostas: uma guarda a marca do pacote na conexão, a outra carrega a marca da conexão no pacote. Qual delas você precisa depende de quando a classificação ocorre em relação ao fluxo. Um projeto pode precisar apenas da marca de pacote, e acrescentar marcação por conntrack porque algum contorno usava as duas é a forma como uma política simples adquire um segundo modo de falha.
ct mark set meta mark meta mark set ct mark
Escreva a direção ao lado da regra, porque não é óbvia à primeira vista a partir da sintaxe. A primeira linha guarda, a segunda restaura, e nenhuma implica a outra.
Classifique antes da consulta que a consome
O tráfego gerado localmente e o tráfego encaminhado de uma LAN atravessam hooks diferentes e chegam às decisões de roteamento em momentos diferentes. Uma regra de saída que funciona para as conexões do próprio router não prova que o pacote de um cliente encaminhado foi marcado antes da sua consulta. Coloque a classificação onde a consulta que a consome ainda não ocorreu, e verifique se as regras seguintes na mesma cadeia sobrescrevem o valor. A ordem dentro de uma cadeia faz parte da configuração, não é um detalhe de implementação.
A persistência do estado de conexão também precisa de um plano explícito. Se apenas o primeiro pacote de um fluxo é classificado, os pacotes seguintes precisam da restauração da marca guardada, ou seguirão o caminho sem marca. É essa a diferença entre uma marca que descreve uma conexão e uma que descreve um pacote.
Faça à rota uma pergunta com marca
ip route get 10.77.0.10 mark 0x2
Inspecione as regras e a tabela e depois consulte a rota com a marca incluída, além da origem ou da interface de entrada quando afetarem a política. Uma consulta comum sem marca responde a outra pergunta e informará com prazer o caminho que você não queria. Verifique a máscara e a prioridade da regra, bem como o seu valor, e confirme que a tabela escolhida contém uma rota utilizável.
Um contador que aumenta é prova de que alguma regra correspondeu a algum pacote. Não é prova de que o pacote final carregava a marca pretendida no ponto de decisão correto.
Leia a marca, a direção, o momento e a máscara. Quatro verificações, e a rota deixa de ser um mistério.