On Tue, Jun 21, 2005 at 10:39:24AM +0900, Horms wrote:
> On Tue, Jun 21, 2005 at 09:26:20AM +1000, Dave Whitla wrote:
> > Thanks Horms,
> >
> > This should be suitable to test as is. I'll see about making it remote
> > NAT friendly and repost if I can.
>
> Thanks, I have been having some ideas on how to do that myself,
> which revolve around a inet_addr_type(udest->addr) == RTN_LOCAL
> test in the nat_xmit function.
>
> I should also point out that the patch below will probably also
> break LVS-DR and LVS-TUN for local real servers. Its really just
> a quick way to test if Local LVS-NAT is a sensible thing or not.
Here is my second attempt, this should automatically switch
local real-servers to Local unless the requested forwarding
method is Masq and the real port differs from the virtual port.
That is, if you want to do portmaping on a local service it will
use Masq, otherwise it will use Local.
It seems to work, but there are probably a few gotchas in there
and I haven't tested a whole lot.
--
Horms
diff --git a/net/ipv4/ipvs/ip_vs_core.c b/net/ipv4/ipvs/ip_vs_core.c
--- a/net/ipv4/ipvs/ip_vs_core.c
+++ b/net/ipv4/ipvs/ip_vs_core.c
@@ -1084,6 +1084,15 @@ static struct nf_hook_ops ip_vs_out_ops
.priority = 100,
};
+/* change source only for local VS/NAT */
+static struct nf_hook_ops ip_vs_local_out_ops = {
+ .hook = ip_vs_out,
+ .owner = THIS_MODULE,
+ .pf = PF_INET,
+ .hooknum = NF_IP_LOCAL_OUT,
+ .priority = 100,
+};
+
/* After packet filtering (but before ip_vs_out_icmp), catch icmp
destined for 0.0.0.0/0, which is for incoming IPVS connections */
static struct nf_hook_ops ip_vs_forward_icmp_ops = {
@@ -1142,10 +1151,15 @@ static int __init ip_vs_init(void)
IP_VS_ERR("can't register out hook.\n");
goto cleanup_inops;
}
+ ret = nf_register_hook(&ip_vs_local_out_ops);
+ if (ret < 0) {
+ IP_VS_ERR("can't register local out hook.\n");
+ goto cleanup_outops;
+ }
ret = nf_register_hook(&ip_vs_post_routing_ops);
if (ret < 0) {
IP_VS_ERR("can't register post_routing hook.\n");
- goto cleanup_outops;
+ goto cleanup_localoutops;
}
ret = nf_register_hook(&ip_vs_forward_icmp_ops);
if (ret < 0) {
@@ -1158,6 +1172,8 @@ static int __init ip_vs_init(void)
cleanup_postroutingops:
nf_unregister_hook(&ip_vs_post_routing_ops);
+ cleanup_localoutops:
+ nf_unregister_hook(&ip_vs_local_out_ops);
cleanup_outops:
nf_unregister_hook(&ip_vs_out_ops);
cleanup_inops:
@@ -1179,6 +1195,7 @@ static void __exit ip_vs_cleanup(void)
nf_unregister_hook(&ip_vs_post_routing_ops);
nf_unregister_hook(&ip_vs_out_ops);
nf_unregister_hook(&ip_vs_in_ops);
+ nf_unregister_hook(&ip_vs_local_out_ops);
ip_vs_conn_cleanup();
ip_vs_app_cleanup();
ip_vs_protocol_cleanup();
diff --git a/net/ipv4/ipvs/ip_vs_ctl.c b/net/ipv4/ipvs/ip_vs_ctl.c
--- a/net/ipv4/ipvs/ip_vs_ctl.c
+++ b/net/ipv4/ipvs/ip_vs_ctl.c
@@ -672,8 +672,17 @@ __ip_vs_update_dest(struct ip_vs_service
/* check if local node and update the flags */
if (inet_addr_type(udest->addr) == RTN_LOCAL) {
- conn_flags = (conn_flags & ~IP_VS_CONN_F_FWD_MASK)
- | IP_VS_CONN_F_LOCALNODE;
+ if ((conn_flags & IP_VS_CONN_F_FWD_MASK) == IP_VS_CONN_F_MASQ) {
+ if (dest->port == dest->vport) {
+ conn_flags = (conn_flags &
+ ~IP_VS_CONN_F_FWD_MASK) |
+ IP_VS_CONN_F_LOCALNODE;
+ }
+ }
+ else {
+ conn_flags = (conn_flags & ~IP_VS_CONN_F_FWD_MASK)
+ | IP_VS_CONN_F_LOCALNODE;
+ }
}
/* set the IP_VS_CONN_F_NOOUTPUT flag if not masquerading/NAT */
|