LVS
lvs-users
Google
 
Web LinuxVirtualServer.org

Re: poor man's LocalNode

To: "LinuxVirtualServer.org users mailing list." <lvs-users@xxxxxxxxxxxxxxxxxxxxxx>
Subject: Re: poor man's LocalNode
From: Daniel Borca <dborca@xxxxxxxxx>
Date: Fri, 27 Jan 2006 02:13:06 -0800 (PST)
Ok, here's the patch (inline)

diff -Naur ipvs.orig/ip_vs_conn.c ipvs/ip_vs_conn.c
--- ipvs.orig/ip_vs_conn.c      2005-01-19 00:00:00.000000000 +0200
+++ ipvs/ip_vs_conn.c   2006-01-27 11:11:20.000000000 +0200
@@ -661,7 +661,45 @@
  */
 static int ip_vs_null_xmit(struct sk_buff *skb, struct ip_vs_conn *cp)
 {
+    struct iphdr *iph;
+    union ip_vs_tphdr h;
+    int ihl;
+
+    iph = skb->nh.iph;
+    ihl = iph->ihl << 2;
+    h.raw = (unsigned char *)iph + ihl;
+
+    if (skb->pkt_type != PACKET_HOST || iph->protocol != IPPROTO_TCP) {
+       /* not for us or not tcp */
+       return NF_ACCEPT;
+    }
+
+    if (h.th->dest == cp->dport) {
+       /* no alteration needed */
        return NF_ACCEPT;
+    }
+
+    /*
+    printk(KERN_DEBUG "ip_vs_null_xmit: "
+       "[%c%c%c%c] %u.%u.%u.%u:%d -> %u.%u.%u.%u:%d -> %u.%u.%u.%u:%d\n",
+       h.th->syn? 'S' : '.', h.th->fin? 'F' : '.', h.th->ack? 'A' : '.', 
h.th->rst? 'R' : '.',
+       NIPQUAD(iph->saddr), ntohs(h.th->source),
+       NIPQUAD(iph->daddr), ntohs(h.th->dest),
+       NIPQUAD(cp->daddr), ntohs(cp->dport));
+    */
+
+    IP_VS_DBG(10, "ip_vs_null_xmit: "
+       "%u.%u.%u.%u:%d -> %u.%u.%u.%u:%d -> %u.%u.%u.%u:%d\n",
+       NIPQUAD(iph->saddr), ntohs(h.th->source),
+       NIPQUAD(iph->daddr), ntohs(h.th->dest),
+       NIPQUAD(cp->daddr), ntohs(cp->dport));
+
+    /* Mangle the packet */
+    ip_vs_fast_check_update(&h,
+           1, 1, h.th->dest, cp->dport, iph->protocol);
+    h.th->dest = cp->dport;
+
+    return NF_ACCEPT;
 }
 
 
diff -Naur ipvs.orig/ip_vs_core.c ipvs/ip_vs_core.c
--- ipvs.orig/ip_vs_core.c      2005-04-04 00:00:00.000000000 +0300
+++ ipvs/ip_vs_core.c   2006-01-27 11:11:20.000000000 +0200
@@ -1174,6 +1174,73 @@
 }
 
 
+/*
+ *     It is hooked at the NF_IP_LOCAL_OUT chain,
+ *      in order to handle multiple LocalNodes.
+ */
+static unsigned int
+ip_vs_local_out (unsigned int hooknum,
+                struct sk_buff **skb_p,
+                const struct net_device *in,
+                const struct net_device *out,
+                int (*okfn)(struct sk_buff *))
+{
+    struct ip_vs_conn *cp;
+    struct sk_buff *skb = *skb_p;
+
+    struct iphdr *iph;
+    union ip_vs_tphdr h;
+    int ihl;
+
+    iph = skb->nh.iph;
+    ihl = iph->ihl << 2;
+    h.raw = (unsigned char *)iph + ihl;
+
+    if (skb->pkt_type != PACKET_HOST || iph->protocol != IPPROTO_TCP) {
+       /* not from us or not tcp */
+       return NF_ACCEPT;
+    }
+
+    cp = ip_vs_conn_out_get(iph->protocol, iph->saddr, h.th->source,
+                               iph->daddr, h.th->dest);
+
+    if (!cp) {
+       /* no connection found */
+       return NF_ACCEPT;
+    }
+
+    if (h.th->source == cp->vport) {
+       /* no alteration needed */
+       ip_vs_conn_put(cp);
+       return NF_ACCEPT;
+    }
+
+    /*
+    printk(KERN_DEBUG "ip_vs_local_out: "
+       "[%c%c%c%c] %u.%u.%u.%u:%d -> %u.%u.%u.%u:%d -> %u.%u.%u.%u:%d\n",
+       h.th->syn? 'S' : '.', h.th->fin? 'F' : '.', h.th->ack? 'A' : '.', 
h.th->rst? 'R' : '.',
+       NIPQUAD(iph->saddr), ntohs(h.th->source),
+       NIPQUAD(cp->vaddr), ntohs(cp->vport),
+       NIPQUAD(iph->daddr), ntohs(h.th->dest));
+    */
+
+    IP_VS_DBG(10, "ip_vs_local_out: "
+       "%u.%u.%u.%u:%d -> %u.%u.%u.%u:%d -> %u.%u.%u.%u:%d\n",
+       NIPQUAD(iph->saddr), ntohs(h.th->source),
+       NIPQUAD(cp->vaddr), ntohs(cp->vport),
+       NIPQUAD(iph->daddr), ntohs(h.th->dest));
+
+    /* Mangle the packet */
+    ip_vs_fast_check_update(&h,
+           1, 1, h.th->source, cp->vport, iph->protocol);
+    h.th->source = cp->vport;
+
+    ip_vs_conn_put(cp);
+
+    return NF_ACCEPT;
+}
+
+
 /* After packet filtering, forward packet through VS/DR, VS/TUN,
    or VS/NAT(change destination), so that filtering rules can be
    applied to IPVS. */
@@ -1201,6 +1268,12 @@
        ip_vs_post_routing, PF_INET, NF_IP_POST_ROUTING, NF_IP_PRI_NAT_SRC-1
 };
 
+/* First thing after packet generation, handle multiple LocalNodes */
+static struct nf_hook_ops ip_vs_local_out_ops = {
+       { NULL, NULL },
+       ip_vs_local_out, PF_INET, NF_IP_LOCAL_OUT, NF_IP_PRI_FIRST
+};
+
 
 /*
  *     Initialize IP Virtual Server
@@ -1247,10 +1320,17 @@
                IP_VS_ERR("can't register forward_icmp hook.\n");
                goto cleanup_postroutingops;
        }
+       ret = nf_register_hook(&ip_vs_local_out_ops);
+       if (ret < 0) {
+               IP_VS_ERR("can't register local_out hook.\n");
+               goto cleanup_forwardicmpops;
+       }
 
        IP_VS_INFO("ipvs loaded.\n");
        return ret;
 
+  cleanup_forwardicmpops:
+       nf_unregister_hook(&ip_vs_forward_icmp_ops);
   cleanup_postroutingops:
        nf_unregister_hook(&ip_vs_post_routing_ops);
   cleanup_outops:
@@ -1269,6 +1349,7 @@
 
 static void __exit ip_vs_cleanup(void)
 {
+       nf_unregister_hook(&ip_vs_local_out_ops);
        nf_unregister_hook(&ip_vs_forward_icmp_ops);
        nf_unregister_hook(&ip_vs_post_routing_ops);
        nf_unregister_hook(&ip_vs_out_ops);


Regards,
Daniel Borca

http://www.geocities.com/dborca/

__________________________________________________
Do You Yahoo!?
Tired of spam?  Yahoo! Mail has the best spam protection around 
http://mail.yahoo.com 

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