Greetings,
The following fragment is from the ip_vs_out() routine in
ip_vs_core.c. It seems to me that packets for which there is no cp but
where ip_vs_lookup_real_service succeeds should also be dropped. In other
words, the decision to "eat" the packet should be independent of the
decision to send the ICMP DEST_UNREACH.
if (!cp) {
if (sysctl_ip_vs_nat_icmp_send &&
ip_vs_lookup_real_service(iph->protocol,
iph->saddr, h.portp[0])) {
/*
* Notify the real server: there is no existing
* entry if it is not RST packet or not TCP packet.
*/
if (!h.th->rst || iph->protocol != IPPROTO_TCP) {
icmp_send(skb, ICMP_DEST_UNREACH,
ICMP_PORT_UNREACH, 0);
kfree_skb(skb);
return NF_STOLEN;
}
}
IP_VS_DBG(12, "packet for %s %d.%d.%d.%d:%d "
"continue traversal as normal.\n",
ip_vs_proto_name(iph->protocol),
NIPQUAD(iph->daddr),
ntohs(h.portp[1]));
if (skb_is_nonlinear(skb))
ip_send_check(iph);
return NF_ACCEPT;
}
Thus, I think it should look something like:
if (!cp) {
if (ip_vs_lookup_real_service(iph->protocol,
iph->saddr, h.portp[0])) {
if (sysctl_ip_vs_nat_icmp_send) {
/*
* Notify the real server: there is no existing
* entry if it is not RST packet or not TCP packet.
*/
if (!h.th->rst || iph->protocol != IPPROTO_TCP) {
icmp_send(skb, ICMP_DEST_UNREACH,
ICMP_PORT_UNREACH, 0);
}
}
kfree_skb(skb);
return NF_STOLEN;
}
IP_VS_DBG(12, "packet for %s %d.%d.%d.%d:%d "
"continue traversal as normal.\n",
ip_vs_proto_name(iph->protocol),
NIPQUAD(iph->daddr),
ntohs(h.portp[1]));
if (skb_is_nonlinear(skb))
ip_send_check(iph);
return NF_ACCEPT;
}
If there is some flaw in my thinking I would appreciate it if
someone could explain this to me so I can understand :-)
Thanks,
Rodger Erickson
|