LVS
lvs-users
Google
 
Web LinuxVirtualServer.org

Re: Local Nodes (NOT Local Node)

To: Dave Whitla <dave.whitla@xxxxxxxxx>, <lvs-users@xxxxxxxxxxxxxxxxxxxxxx>
Subject: Re: Local Nodes (NOT Local Node)
From: Horms <horms@xxxxxxxxxxxx>
Date: Tue, 21 Jun 2005 12:42:37 +0900
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 */

<Prev in Thread] Current Thread [Next in Thread>