I've just been messing with 0.9.12(kernel 2.2.15), and the new FWmark
virtual service mode.
It works great, but I'd like to know of a way to have the destination port
remain unchanged.
What I mean is this.
Virtualhost needs to serve several ports. The load balancer marks all
packets to it with
fwmark 1. There are then two real servers that do the actual serving.
ipchains -A input -d virtualhost -m 1
ipvsadm -A -f 1 -s rr
ipvsadm -a -f 1 -r real1 -m
ipvsadm -a -f 1 -r real2 -m
Unfortunately, this causes packets to be delievered to the real servers with
destination
ports of 0. It would seem more logical to leave the destination port
unchanged, if it is
not specified.
in ipvsadm.c I see where it says:
parse = parse_service(optarg,
mc.u.vs_user.protocol,
&mc.u.vs_user.daddr,
&mc.u.vs_user.dport);
if (!(parse&SERVICE_ADDR))
fail(2, "illegal real server "
"address[:port] specified");
/* copy vport to dport if none specified */
if (parse == 1)
mc.u.vs_user.dport = mc.u.vs_user.vport;
So we have told the kernel ip masq code that the destination port should be
0. With fwmark mc.u.vs_user.vport would, of course, be 0, as we don't know
it until we actually receive the code. After looking through ip_masq.c, I
think we just need to set the IP_MASQ_F_NO_DPORT flag.
this code is in ip_masq.c, function ip_fw_demasquerade():
if ( ms->flags & IP_MASQ_F_NO_DPORT ) { /* && ms->protocol == IPPROTO_TCP )
{ */
write_lock(&__ip_masq_lock);
ip_masq_unhash(ms);
ms->flags &= ~IP_MASQ_F_NO_DPORT;
ms->dport = h.portp[0];
ip_masq_hash(ms); /* hash on new dport */
write_unlock(&__ip_masq_lock);
IP_MASQ_DEBUG(1, "ip_fw_demasquerade(): filled
dport=%d\n",
ntohs(ms->dport));
}
Unfortunately, I'm not familiar with the patch procedure(I'm learning..)...
but I think this
could be changed in ipvsadm.c
|