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
|