Minha recente observação, no OpenWRT Kamikaze 7.09 = 2.4.34 e no udhcpc do busybox 1.4.2:
Eu tenho uma política "ACCEPT" na cadeia OUTPUT, e na direção do INPUT, originalmente eu confiei nessa regra clássica de pega-tudo:
iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
para permitir as respostas do DHCP em (para meu udhcpc) na interface da WAN.
Ou seja, é aqui que o servidor DHCP a montante do meu ISP atribui um endereço IP para mim.
Observe a diferença entre uma troca inicial de DHCP (descobrir, oferecer, solicitar, ack) e uma renovação de concessão de DHCP (request, ack).
Após a inicialização, o udhcpc é iniciado pela troca inicial completa.
Essa troca teria sucesso. E outra renovação ou duas teria sucesso também - apenas um pedido e reconhecimento. O servidor DHCP do meu ISP normalmente pede um tempo de renovação de cerca de uma hora a 1,5 horas, assim meu cliente DHCP pede uma renovação a cada 30 a 45 minutos (esse comportamento é baseado no RFC).
Mas, sobre a terceira ou quarta renovação, ela começa a ficar interessante. O TCPdump mostraria cerca de três ou mais tentativas de renovação, seguidas de uma troca inicial completa - que duraria apenas alguns minutos ou mesmo segundos. Como se o udhcpc não gostasse do que ele voltou :-( e ficaria satisfeito com a troca completa. Depois disso, outra renovação em meia hora teria sucesso ... e a história se repetiria novamente.
Eu descobri que talvez seja o rastreamento de conexão no kernel que tem algo errado. Como se a entrada conntrack expirasse após duas horas ou mais, e as renovações posteriores do DHCP falharem, porque o ACK do servidor não chega ao udhcpc escutando no soquete. Note que o tcpdump (libpcap) escuta na interface bruta e pode ver todos os pacotes chegando, antes que eles estejam sujeitos ao iptables. Uma vez que o udhcpc desiste de renovações e, em desespero, tenta recomeçar do zero usando uma troca completa (começando com DISCOVER), o kernel estabelece uma nova entrada conntrack e pode entender pacotes relacionados por mais algum tempo ...
De fato, uma vez adicionei algo como:
iptables -A INPUT -i $OUT_IF -p udp --sport 67 --dport 68 -j ACCEPT
as renovações parecem funcionar para sempre.
Você pode encontrar os seguintes argumentos do cmdline tcpdump úteis:
tcpdump -vv -s 1500 -i eth0.1 port 67 or port 68
Nota: o -vv
pede a saída detalhada do dissector. eth0.1
é minha porta WAN (também uma interface "NAT externa").
Um atributo interessante nos pacotes ACK é o tempo de concessão LT: campo = sugerido / máximo concedido em segundos.
As solicitações DHCP são enviadas da porta 68 para a porta 67. As respostas vêm da porta 67 para a porta 68.