ipvs: provide iph to schedulers
authorJulian Anastasov <ja@ssi.bg>
Sun, 16 Jun 2013 06:09:36 +0000 (09:09 +0300)
committerSimon Horman <horms@verge.net.au>
Wed, 26 Jun 2013 09:01:45 +0000 (18:01 +0900)
Before now the schedulers needed access only to IP
addresses and it was easy to get them from skb by
using ip_vs_fill_iph_addr_only.

New changes for the SH scheduler will need the protocol
and ports which is difficult to get from skb for the
IPv6 case. As we have all the data in the iph structure,
to avoid the same slow lookups provide the iph to schedulers.

Signed-off-by: Julian Anastasov <ja@ssi.bg>
Acked-by: Hans Schillstrom <hans@schillstrom.com>
Signed-off-by: Simon Horman <horms@verge.net.au>
12 files changed:
include/net/ip_vs.h
net/netfilter/ipvs/ip_vs_core.c
net/netfilter/ipvs/ip_vs_dh.c
net/netfilter/ipvs/ip_vs_lblc.c
net/netfilter/ipvs/ip_vs_lblcr.c
net/netfilter/ipvs/ip_vs_lc.c
net/netfilter/ipvs/ip_vs_nq.c
net/netfilter/ipvs/ip_vs_rr.c
net/netfilter/ipvs/ip_vs_sed.c
net/netfilter/ipvs/ip_vs_sh.c
net/netfilter/ipvs/ip_vs_wlc.c
net/netfilter/ipvs/ip_vs_wrr.c

index 4405886980c71dca160e19bf88cfde8f5419b216..f5faf859876ebb8eaa19c27ca110e2c77ca9b1a7 100644 (file)
@@ -197,31 +197,6 @@ ip_vs_fill_iph_skb(int af, const struct sk_buff *skb, struct ip_vs_iphdr *iphdr)
        }
 }
 
-/* This function is a faster version of ip_vs_fill_iph_skb().
- * Where we only populate {s,d}addr (and avoid calling ipv6_find_hdr()).
- * This is used by the some of the ip_vs_*_schedule() functions.
- * (Mostly done to avoid ABI breakage of external schedulers)
- */
-static inline void
-ip_vs_fill_iph_addr_only(int af, const struct sk_buff *skb,
-                        struct ip_vs_iphdr *iphdr)
-{
-#ifdef CONFIG_IP_VS_IPV6
-       if (af == AF_INET6) {
-               const struct ipv6hdr *iph =
-                       (struct ipv6hdr *)skb_network_header(skb);
-               iphdr->saddr.in6 = iph->saddr;
-               iphdr->daddr.in6 = iph->daddr;
-       } else
-#endif
-       {
-               const struct iphdr *iph =
-                       (struct iphdr *)skb_network_header(skb);
-               iphdr->saddr.ip = iph->saddr;
-               iphdr->daddr.ip = iph->daddr;
-       }
-}
-
 static inline void ip_vs_addr_copy(int af, union nf_inet_addr *dst,
                                   const union nf_inet_addr *src)
 {
@@ -814,7 +789,8 @@ struct ip_vs_scheduler {
 
        /* selecting a server from the given service */
        struct ip_vs_dest* (*schedule)(struct ip_vs_service *svc,
-                                      const struct sk_buff *skb);
+                                      const struct sk_buff *skb,
+                                      struct ip_vs_iphdr *iph);
 };
 
 /* The persistence engine object */
index 05565d2b3a61b530acad48cfeda90b2af4b3adda..e9b0330f220dd80cd920be1eb6773456600cce13 100644 (file)
@@ -305,7 +305,7 @@ ip_vs_sched_persist(struct ip_vs_service *svc,
                 * return *ignored=0 i.e. ICMP and NF_DROP
                 */
                sched = rcu_dereference(svc->scheduler);
-               dest = sched->schedule(svc, skb);
+               dest = sched->schedule(svc, skb, iph);
                if (!dest) {
                        IP_VS_DBG(1, "p-schedule: no dest found.\n");
                        kfree(param.pe_data);
@@ -452,7 +452,7 @@ ip_vs_schedule(struct ip_vs_service *svc, struct sk_buff *skb,
        }
 
        sched = rcu_dereference(svc->scheduler);
-       dest = sched->schedule(svc, skb);
+       dest = sched->schedule(svc, skb, iph);
        if (dest == NULL) {
                IP_VS_DBG(1, "Schedule: no dest found.\n");
                return NULL;
index ccab120df45e378dfe480e01f58e383f22277ac4..c3b84546ea9e2b385878f07eeae926495890ad1f 100644 (file)
@@ -214,18 +214,16 @@ static inline int is_overloaded(struct ip_vs_dest *dest)
  *      Destination hashing scheduling
  */
 static struct ip_vs_dest *
-ip_vs_dh_schedule(struct ip_vs_service *svc, const struct sk_buff *skb)
+ip_vs_dh_schedule(struct ip_vs_service *svc, const struct sk_buff *skb,
+                 struct ip_vs_iphdr *iph)
 {
        struct ip_vs_dest *dest;
        struct ip_vs_dh_state *s;
-       struct ip_vs_iphdr iph;
-
-       ip_vs_fill_iph_addr_only(svc->af, skb, &iph);
 
        IP_VS_DBG(6, "%s(): Scheduling...\n", __func__);
 
        s = (struct ip_vs_dh_state *) svc->sched_data;
-       dest = ip_vs_dh_get(svc->af, s, &iph.daddr);
+       dest = ip_vs_dh_get(svc->af, s, &iph->daddr);
        if (!dest
            || !(dest->flags & IP_VS_DEST_F_AVAILABLE)
            || atomic_read(&dest->weight) <= 0
@@ -235,7 +233,7 @@ ip_vs_dh_schedule(struct ip_vs_service *svc, const struct sk_buff *skb)
        }
 
        IP_VS_DBG_BUF(6, "DH: destination IP address %s --> server %s:%d\n",
-                     IP_VS_DBG_ADDR(svc->af, &iph.daddr),
+                     IP_VS_DBG_ADDR(svc->af, &iph->daddr),
                      IP_VS_DBG_ADDR(svc->af, &dest->addr),
                      ntohs(dest->port));
 
index 44595b8ae37f683d669fbdca7353cfa986984477..1383b0eadc0e777d5ff6dbce2a2ded451a3ae296 100644 (file)
@@ -487,19 +487,17 @@ is_overloaded(struct ip_vs_dest *dest, struct ip_vs_service *svc)
  *    Locality-Based (weighted) Least-Connection scheduling
  */
 static struct ip_vs_dest *
-ip_vs_lblc_schedule(struct ip_vs_service *svc, const struct sk_buff *skb)
+ip_vs_lblc_schedule(struct ip_vs_service *svc, const struct sk_buff *skb,
+                   struct ip_vs_iphdr *iph)
 {
        struct ip_vs_lblc_table *tbl = svc->sched_data;
-       struct ip_vs_iphdr iph;
        struct ip_vs_dest *dest = NULL;
        struct ip_vs_lblc_entry *en;
 
-       ip_vs_fill_iph_addr_only(svc->af, skb, &iph);
-
        IP_VS_DBG(6, "%s(): Scheduling...\n", __func__);
 
        /* First look in our cache */
-       en = ip_vs_lblc_get(svc->af, tbl, &iph.daddr);
+       en = ip_vs_lblc_get(svc->af, tbl, &iph->daddr);
        if (en) {
                /* We only hold a read lock, but this is atomic */
                en->lastuse = jiffies;
@@ -529,12 +527,12 @@ ip_vs_lblc_schedule(struct ip_vs_service *svc, const struct sk_buff *skb)
        /* If we fail to create a cache entry, we'll just use the valid dest */
        spin_lock_bh(&svc->sched_lock);
        if (!tbl->dead)
-               ip_vs_lblc_new(tbl, &iph.daddr, dest);
+               ip_vs_lblc_new(tbl, &iph->daddr, dest);
        spin_unlock_bh(&svc->sched_lock);
 
 out:
        IP_VS_DBG_BUF(6, "LBLC: destination IP address %s --> server %s:%d\n",
-                     IP_VS_DBG_ADDR(svc->af, &iph.daddr),
+                     IP_VS_DBG_ADDR(svc->af, &iph->daddr),
                      IP_VS_DBG_ADDR(svc->af, &dest->addr), ntohs(dest->port));
 
        return dest;
index 876937db0bf46d5227b41b9084bddbca4e36e483..3cd85b2fc67c83e7f4a12b6fa35765d8ebc986ec 100644 (file)
@@ -655,19 +655,17 @@ is_overloaded(struct ip_vs_dest *dest, struct ip_vs_service *svc)
  *    Locality-Based (weighted) Least-Connection scheduling
  */
 static struct ip_vs_dest *
-ip_vs_lblcr_schedule(struct ip_vs_service *svc, const struct sk_buff *skb)
+ip_vs_lblcr_schedule(struct ip_vs_service *svc, const struct sk_buff *skb,
+                    struct ip_vs_iphdr *iph)
 {
        struct ip_vs_lblcr_table *tbl = svc->sched_data;
-       struct ip_vs_iphdr iph;
        struct ip_vs_dest *dest;
        struct ip_vs_lblcr_entry *en;
 
-       ip_vs_fill_iph_addr_only(svc->af, skb, &iph);
-
        IP_VS_DBG(6, "%s(): Scheduling...\n", __func__);
 
        /* First look in our cache */
-       en = ip_vs_lblcr_get(svc->af, tbl, &iph.daddr);
+       en = ip_vs_lblcr_get(svc->af, tbl, &iph->daddr);
        if (en) {
                en->lastuse = jiffies;
 
@@ -718,12 +716,12 @@ ip_vs_lblcr_schedule(struct ip_vs_service *svc, const struct sk_buff *skb)
        /* If we fail to create a cache entry, we'll just use the valid dest */
        spin_lock_bh(&svc->sched_lock);
        if (!tbl->dead)
-               ip_vs_lblcr_new(tbl, &iph.daddr, dest);
+               ip_vs_lblcr_new(tbl, &iph->daddr, dest);
        spin_unlock_bh(&svc->sched_lock);
 
 out:
        IP_VS_DBG_BUF(6, "LBLCR: destination IP address %s --> server %s:%d\n",
-                     IP_VS_DBG_ADDR(svc->af, &iph.daddr),
+                     IP_VS_DBG_ADDR(svc->af, &iph->daddr),
                      IP_VS_DBG_ADDR(svc->af, &dest->addr), ntohs(dest->port));
 
        return dest;
index 5128e338a749dc8dd9c2846607fc95f25ac59054..2bdcb1cf21279db80ebb0af0b091f600e8b4921b 100644 (file)
@@ -26,7 +26,8 @@
  *     Least Connection scheduling
  */
 static struct ip_vs_dest *
-ip_vs_lc_schedule(struct ip_vs_service *svc, const struct sk_buff *skb)
+ip_vs_lc_schedule(struct ip_vs_service *svc, const struct sk_buff *skb,
+                 struct ip_vs_iphdr *iph)
 {
        struct ip_vs_dest *dest, *least = NULL;
        unsigned int loh = 0, doh;
index 646cfd4baa73b2dcd954cc20ce975bd2bd39967a..d8d9860934fee1e7f59505eeefa094307b2d58c3 100644 (file)
@@ -55,7 +55,8 @@ ip_vs_nq_dest_overhead(struct ip_vs_dest *dest)
  *     Weighted Least Connection scheduling
  */
 static struct ip_vs_dest *
-ip_vs_nq_schedule(struct ip_vs_service *svc, const struct sk_buff *skb)
+ip_vs_nq_schedule(struct ip_vs_service *svc, const struct sk_buff *skb,
+                 struct ip_vs_iphdr *iph)
 {
        struct ip_vs_dest *dest, *least = NULL;
        unsigned int loh = 0, doh;
index c35986c793d903d3565be462321c6e953acf556e..176b87c35e34ea2b438739d21a3439f1ebade995 100644 (file)
@@ -55,7 +55,8 @@ static int ip_vs_rr_del_dest(struct ip_vs_service *svc, struct ip_vs_dest *dest)
  * Round-Robin Scheduling
  */
 static struct ip_vs_dest *
-ip_vs_rr_schedule(struct ip_vs_service *svc, const struct sk_buff *skb)
+ip_vs_rr_schedule(struct ip_vs_service *svc, const struct sk_buff *skb,
+                 struct ip_vs_iphdr *iph)
 {
        struct list_head *p;
        struct ip_vs_dest *dest, *last;
index f3205925359acc19790795fdd67d87970b58e3b7..a5284cc3d88279923b6a28b1f8a8f87bfc2a6a0f 100644 (file)
@@ -59,7 +59,8 @@ ip_vs_sed_dest_overhead(struct ip_vs_dest *dest)
  *     Weighted Least Connection scheduling
  */
 static struct ip_vs_dest *
-ip_vs_sed_schedule(struct ip_vs_service *svc, const struct sk_buff *skb)
+ip_vs_sed_schedule(struct ip_vs_service *svc, const struct sk_buff *skb,
+                  struct ip_vs_iphdr *iph)
 {
        struct ip_vs_dest *dest, *least;
        unsigned int loh, doh;
index a65edfe4b16c91d6adb0ee9a54ee345d9bc5fa80..e0d5d165356640c91e6f5734d22af51dcfd3c12d 100644 (file)
@@ -227,18 +227,16 @@ static inline int is_overloaded(struct ip_vs_dest *dest)
  *      Source Hashing scheduling
  */
 static struct ip_vs_dest *
-ip_vs_sh_schedule(struct ip_vs_service *svc, const struct sk_buff *skb)
+ip_vs_sh_schedule(struct ip_vs_service *svc, const struct sk_buff *skb,
+                 struct ip_vs_iphdr *iph)
 {
        struct ip_vs_dest *dest;
        struct ip_vs_sh_state *s;
-       struct ip_vs_iphdr iph;
-
-       ip_vs_fill_iph_addr_only(svc->af, skb, &iph);
 
        IP_VS_DBG(6, "ip_vs_sh_schedule(): Scheduling...\n");
 
        s = (struct ip_vs_sh_state *) svc->sched_data;
-       dest = ip_vs_sh_get(svc->af, s, &iph.saddr);
+       dest = ip_vs_sh_get(svc->af, s, &iph->saddr);
        if (!dest
            || !(dest->flags & IP_VS_DEST_F_AVAILABLE)
            || atomic_read(&dest->weight) <= 0
@@ -248,7 +246,7 @@ ip_vs_sh_schedule(struct ip_vs_service *svc, const struct sk_buff *skb)
        }
 
        IP_VS_DBG_BUF(6, "SH: source IP address %s --> server %s:%d\n",
-                     IP_VS_DBG_ADDR(svc->af, &iph.saddr),
+                     IP_VS_DBG_ADDR(svc->af, &iph->saddr),
                      IP_VS_DBG_ADDR(svc->af, &dest->addr),
                      ntohs(dest->port));
 
index c60a81c4ce9add5b801fdff53e0596b6c77e036a..6dc1fa1288409067de8a19f53a32e174caa9adc9 100644 (file)
@@ -31,7 +31,8 @@
  *     Weighted Least Connection scheduling
  */
 static struct ip_vs_dest *
-ip_vs_wlc_schedule(struct ip_vs_service *svc, const struct sk_buff *skb)
+ip_vs_wlc_schedule(struct ip_vs_service *svc, const struct sk_buff *skb,
+                  struct ip_vs_iphdr *iph)
 {
        struct ip_vs_dest *dest, *least;
        unsigned int loh, doh;
index 0e68555bceb9122a00283c147c977fbba01e4079..0546cd572d6b84bfe3d9feaea40d78e88cd6d23c 100644 (file)
@@ -162,7 +162,8 @@ static int ip_vs_wrr_dest_changed(struct ip_vs_service *svc,
  *    Weighted Round-Robin Scheduling
  */
 static struct ip_vs_dest *
-ip_vs_wrr_schedule(struct ip_vs_service *svc, const struct sk_buff *skb)
+ip_vs_wrr_schedule(struct ip_vs_service *svc, const struct sk_buff *skb,
+                  struct ip_vs_iphdr *iph)
 {
        struct ip_vs_dest *dest, *last, *stop = NULL;
        struct ip_vs_wrr_mark *mark = svc->sched_data;