LVS
lvs-users
Google
 
Web LinuxVirtualServer.org

[PATCH 1/2 inlining] Using LVS as a way to provide load-balanced interne

To: "LinuxVirtualServer.org users mailing list." <lvs-users@xxxxxxxxxxxxxxxxxxxxxx>
Subject: [PATCH 1/2 inlining] Using LVS as a way to provide load-balanced internet
From: Ludo Stellingwerff <ludo@xxxxxxxxxxxxx>
Date: Fri, 29 Jul 2005 14:26:23 +0200
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

diff -wur kernel-source-2.6.11/include/net/ip_vs.h
kernel-source-2.6.11new/include/net/ip_vs.h
- --- kernel-source-2.6.11/include/net/ip_vs.h    2005-03-02
08:37:31.000000000 +0100
+++ kernel-source-2.6.11new/include/net/ip_vs.h    2005-07-08
07:19:40.000000000 +0200
@@ -76,6 +76,7 @@
 #define IP_VS_CONN_F_TUNNEL    0x0002        /* tunneling */
 #define IP_VS_CONN_F_DROUTE    0x0003        /* direct routing */
 #define IP_VS_CONN_F_BYPASS    0x0004        /* cache bypass */
+#define IP_VS_CONN_F_NROUTE    0x0005        /* reinject into normal
routing */
 #define IP_VS_CONN_F_SYNC    0x0020        /* entry created by sync */
 #define IP_VS_CONN_F_HASHED    0x0040        /* hashed entry */
 #define IP_VS_CONN_F_NOOUTPUT    0x0080        /* no output packets */
@@ -933,6 +934,8 @@
 (struct sk_buff *skb, struct ip_vs_conn *cp, struct ip_vs_protocol *pp);
 extern int ip_vs_dr_xmit
 (struct sk_buff *skb, struct ip_vs_conn *cp, struct ip_vs_protocol *pp);
+extern int ip_vs_reinject_xmit
+(struct sk_buff *skb, struct ip_vs_conn *cp, struct ip_vs_protocol *pp);
 extern int ip_vs_icmp_xmit
 (struct sk_buff *skb, struct ip_vs_conn *cp, struct ip_vs_protocol
*pp, int offset);
 extern void ip_vs_dst_reset(struct ip_vs_dest *dest);
diff -wur kernel-source-2.6.11/net/ipv4/ipvs/ip_vs_conn.c
kernel-source-2.6.11new/net/ipv4/ipvs/ip_vs_conn.c
- --- kernel-source-2.6.11/net/ipv4/ipvs/ip_vs_conn.c    2005-03-02
08:38:26.000000000 +0100
+++ kernel-source-2.6.11new/net/ipv4/ipvs/ip_vs_conn.c    2005-07-08
07:19:41.000000000 +0200
@@ -328,6 +328,10 @@
     case IP_VS_CONN_F_BYPASS:
         cp->packet_xmit = ip_vs_bypass_xmit;
         break;
+
+    case IP_VS_CONN_F_NROUTE:
+        cp->packet_xmit = ip_vs_reinject_xmit;
+        break;
     }
 }
 
diff -wur kernel-source-2.6.11/net/ipv4/ipvs/ip_vs_core.c
kernel-source-2.6.11new/net/ipv4/ipvs/ip_vs_core.c
- --- kernel-source-2.6.11/net/ipv4/ipvs/ip_vs_core.c    2005-03-02
08:37:30.000000000 +0100
+++ kernel-source-2.6.11new/net/ipv4/ipvs/ip_vs_core.c    2005-07-08
07:39:07.000000000 +0200
@@ -954,7 +954,7 @@
      *    Big tappo: only PACKET_HOST (neither loopback nor mcasts)
      *    ... don't know why 1st test DOES NOT include 2nd (?)
      */
- -    if (unlikely(skb->pkt_type != PACKET_HOST
+    if (!(hooknum == NF_IP_FORWARD || hooknum == NF_IP_LOCAL_OUT) &&
(skb->pkt_type != PACKET_HOST
              || skb->dev == &loopback_dev || skb->sk)) {
         IP_VS_DBG(12, "packet type=%d proto=%d daddr=%d.%d.%d.%d
ignored\n",
               skb->pkt_type,
@@ -1094,6 +1094,28 @@
     .priority       = 99,
 };
 
+/* On the forward hook, before any of the above support hooks,
+   filter forwarding packets for new routing.
+   Very powerfull in combination with fwmark */
+static struct nf_hook_ops ip_vs_forward_ops = {
+    .hook        = ip_vs_in,
+    .owner        = THIS_MODULE,
+    .pf        = PF_INET,
+    .hooknum        = NF_IP_FORWARD,
+    .priority       = 98,
+};
+
+/* Before local outgoing nat, but after mangle,
+   filter outgoing packets for new routing.
+   Very powerfull in combination with fwmark */
+static struct nf_hook_ops ip_vs_doout_ops = {
+    .hook        = ip_vs_in,
+    .owner        = THIS_MODULE,
+    .pf        = PF_INET,
+    .hooknum        = NF_IP_LOCAL_OUT,
+    .priority       = -125,
+};
+
 /* Before the netfilter connection tracking, exit from POST_ROUTING */
 static struct nf_hook_ops ip_vs_post_routing_ops = {
     .hook        = ip_vs_post_routing,
@@ -1137,11 +1159,23 @@
         goto cleanup_conn;
     }
 
- -    ret = nf_register_hook(&ip_vs_out_ops);
+    ret = nf_register_hook(&ip_vs_forward_ops);
     if (ret < 0) {
- -        IP_VS_ERR("can't register out hook.\n");
+        IP_VS_ERR("can't register in forward hook.\n");
         goto cleanup_inops;
     }
+
+    ret = nf_register_hook(&ip_vs_doout_ops);
+    if (ret < 0) {
+        IP_VS_ERR("can't register in post mangle out hook.\n");
+        goto cleanup_forwardops;
+    }
+
+    ret = nf_register_hook(&ip_vs_out_ops);
+    if (ret < 0) {
+        IP_VS_ERR("can't register nat out hook.\n");
+        goto cleanup_dooutops;
+    }
     ret = nf_register_hook(&ip_vs_post_routing_ops);
     if (ret < 0) {
         IP_VS_ERR("can't register post_routing hook.\n");
@@ -1160,6 +1194,10 @@
     nf_unregister_hook(&ip_vs_post_routing_ops);
   cleanup_outops:
     nf_unregister_hook(&ip_vs_out_ops);
+  cleanup_dooutops:
+    nf_unregister_hook(&ip_vs_doout_ops);
+  cleanup_forwardops:
+    nf_unregister_hook(&ip_vs_forward_ops);
   cleanup_inops:
     nf_unregister_hook(&ip_vs_in_ops);
   cleanup_conn:
@@ -1178,6 +1216,8 @@
     nf_unregister_hook(&ip_vs_forward_icmp_ops);
     nf_unregister_hook(&ip_vs_post_routing_ops);
     nf_unregister_hook(&ip_vs_out_ops);
+    nf_unregister_hook(&ip_vs_doout_ops);
+    nf_unregister_hook(&ip_vs_forward_ops);
     nf_unregister_hook(&ip_vs_in_ops);
     ip_vs_conn_cleanup();
     ip_vs_app_cleanup();
diff -wur kernel-source-2.6.11/net/ipv4/ipvs/ip_vs_xmit.c
kernel-source-2.6.11new/net/ipv4/ipvs/ip_vs_xmit.c
- --- kernel-source-2.6.11/net/ipv4/ipvs/ip_vs_xmit.c    2005-03-02
08:38:26.000000000 +0100
+++ kernel-source-2.6.11new/net/ipv4/ipvs/ip_vs_xmit.c    2005-07-08
07:19:41.000000000 +0200
@@ -482,6 +482,43 @@
     return NF_STOLEN;
 }
 
+/*
+ *      Reinjection transmitter
+ *      Used for ANY protocol
+ *    This version leaves routing to the rest of the network stack,
+ *    by just returning NF_ACCEPT.
+ *    This provides IPVS scheduling as a more general routing decision.
+ */
+int
+ip_vs_reinject_xmit(struct sk_buff *skb, struct ip_vs_conn *cp,
+          struct ip_vs_protocol *pp)
+{
+    struct rtable *rt;            /* Route to the other host */
+    struct iphdr  *iph = skb->nh.iph;
+
+    EnterFunction(10);
+
+    if (!(rt = __ip_vs_get_out_rt(cp, RT_TOS(iph->tos))))
+        goto tx_error_icmp;
+    if (unlikely((skb = skb_share_check(skb, GFP_ATOMIC)) == NULL)) {
+        ip_rt_put(rt);
+        return NF_STOLEN;
+    }
+
+    /* drop old route */
+    dst_release(skb->dst);
+    skb->dst = &rt->u.dst;
+
+    LeaveFunction(10);
+    return NF_ACCEPT;
+  tx_error_icmp:
+    dst_link_failure(skb);
+  tx_error:
+    kfree_skb(skb);
+    LeaveFunction(10);
+    return NF_STOLEN;
+}
+
 
 /*
  *    ICMP packet transmitter

- --
Ludo Stellingwerff

V&S B.V. The Netherlands
ProTactive firewall solution.
Tel: +31 172 416116
Fax: +31 172 416124

site: www.protactive.nl
demo: http://www.protactive.nl:81/netview.html
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.1 (GNU/Linux)

iD8DBQFC6iBvOF3sCpZ+AJgRAtVeAKDDw8STDRNP81YDBkmsBqbE8C1GDgCfT77k
22FRvl5lKhYPvmlfia1Roos=
=wG3c
-----END PGP SIGNATURE-----


<Prev in Thread] Current Thread [Next in Thread>
  • [PATCH 1/2 inlining] Using LVS as a way to provide load-balanced internet, Ludo Stellingwerff <=