aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/net/ip_vs.h28
-rw-r--r--net/netfilter/ipvs/ip_vs_core.c4
-rw-r--r--net/netfilter/ipvs/ip_vs_dh.c10
-rw-r--r--net/netfilter/ipvs/ip_vs_lblc.c12
-rw-r--r--net/netfilter/ipvs/ip_vs_lblcr.c12
-rw-r--r--net/netfilter/ipvs/ip_vs_lc.c3
-rw-r--r--net/netfilter/ipvs/ip_vs_nq.c3
-rw-r--r--net/netfilter/ipvs/ip_vs_rr.c3
-rw-r--r--net/netfilter/ipvs/ip_vs_sed.c3
-rw-r--r--net/netfilter/ipvs/ip_vs_sh.c10
-rw-r--r--net/netfilter/ipvs/ip_vs_wlc.c3
-rw-r--r--net/netfilter/ipvs/ip_vs_wrr.c3
12 files changed, 34 insertions, 60 deletions
diff --git a/include/net/ip_vs.h b/include/net/ip_vs.h
index 4405886980c7..f5faf859876e 100644
--- a/include/net/ip_vs.h
+++ b/include/net/ip_vs.h
@@ -197,31 +197,6 @@ ip_vs_fill_iph_skb(int af, const struct sk_buff *skb, struct ip_vs_iphdr *iphdr)
197 } 197 }
198} 198}
199 199
200/* This function is a faster version of ip_vs_fill_iph_skb().
201 * Where we only populate {s,d}addr (and avoid calling ipv6_find_hdr()).
202 * This is used by the some of the ip_vs_*_schedule() functions.
203 * (Mostly done to avoid ABI breakage of external schedulers)
204 */
205static inline void
206ip_vs_fill_iph_addr_only(int af, const struct sk_buff *skb,
207 struct ip_vs_iphdr *iphdr)
208{
209#ifdef CONFIG_IP_VS_IPV6
210 if (af == AF_INET6) {
211 const struct ipv6hdr *iph =
212 (struct ipv6hdr *)skb_network_header(skb);
213 iphdr->saddr.in6 = iph->saddr;
214 iphdr->daddr.in6 = iph->daddr;
215 } else
216#endif
217 {
218 const struct iphdr *iph =
219 (struct iphdr *)skb_network_header(skb);
220 iphdr->saddr.ip = iph->saddr;
221 iphdr->daddr.ip = iph->daddr;
222 }
223}
224
225static inline void ip_vs_addr_copy(int af, union nf_inet_addr *dst, 200static inline void ip_vs_addr_copy(int af, union nf_inet_addr *dst,
226 const union nf_inet_addr *src) 201 const union nf_inet_addr *src)
227{ 202{
@@ -814,7 +789,8 @@ struct ip_vs_scheduler {
814 789
815 /* selecting a server from the given service */ 790 /* selecting a server from the given service */
816 struct ip_vs_dest* (*schedule)(struct ip_vs_service *svc, 791 struct ip_vs_dest* (*schedule)(struct ip_vs_service *svc,
817 const struct sk_buff *skb); 792 const struct sk_buff *skb,
793 struct ip_vs_iphdr *iph);
818}; 794};
819 795
820/* The persistence engine object */ 796/* The persistence engine object */
diff --git a/net/netfilter/ipvs/ip_vs_core.c b/net/netfilter/ipvs/ip_vs_core.c
index 05565d2b3a61..e9b0330f220d 100644
--- a/net/netfilter/ipvs/ip_vs_core.c
+++ b/net/netfilter/ipvs/ip_vs_core.c
@@ -305,7 +305,7 @@ ip_vs_sched_persist(struct ip_vs_service *svc,
305 * return *ignored=0 i.e. ICMP and NF_DROP 305 * return *ignored=0 i.e. ICMP and NF_DROP
306 */ 306 */
307 sched = rcu_dereference(svc->scheduler); 307 sched = rcu_dereference(svc->scheduler);
308 dest = sched->schedule(svc, skb); 308 dest = sched->schedule(svc, skb, iph);
309 if (!dest) { 309 if (!dest) {
310 IP_VS_DBG(1, "p-schedule: no dest found.\n"); 310 IP_VS_DBG(1, "p-schedule: no dest found.\n");
311 kfree(param.pe_data); 311 kfree(param.pe_data);
@@ -452,7 +452,7 @@ ip_vs_schedule(struct ip_vs_service *svc, struct sk_buff *skb,
452 } 452 }
453 453
454 sched = rcu_dereference(svc->scheduler); 454 sched = rcu_dereference(svc->scheduler);
455 dest = sched->schedule(svc, skb); 455 dest = sched->schedule(svc, skb, iph);
456 if (dest == NULL) { 456 if (dest == NULL) {
457 IP_VS_DBG(1, "Schedule: no dest found.\n"); 457 IP_VS_DBG(1, "Schedule: no dest found.\n");
458 return NULL; 458 return NULL;
diff --git a/net/netfilter/ipvs/ip_vs_dh.c b/net/netfilter/ipvs/ip_vs_dh.c
index ccab120df45e..c3b84546ea9e 100644
--- a/net/netfilter/ipvs/ip_vs_dh.c
+++ b/net/netfilter/ipvs/ip_vs_dh.c
@@ -214,18 +214,16 @@ static inline int is_overloaded(struct ip_vs_dest *dest)
214 * Destination hashing scheduling 214 * Destination hashing scheduling
215 */ 215 */
216static struct ip_vs_dest * 216static struct ip_vs_dest *
217ip_vs_dh_schedule(struct ip_vs_service *svc, const struct sk_buff *skb) 217ip_vs_dh_schedule(struct ip_vs_service *svc, const struct sk_buff *skb,
218 struct ip_vs_iphdr *iph)
218{ 219{
219 struct ip_vs_dest *dest; 220 struct ip_vs_dest *dest;
220 struct ip_vs_dh_state *s; 221 struct ip_vs_dh_state *s;
221 struct ip_vs_iphdr iph;
222
223 ip_vs_fill_iph_addr_only(svc->af, skb, &iph);
224 222
225 IP_VS_DBG(6, "%s(): Scheduling...\n", __func__); 223 IP_VS_DBG(6, "%s(): Scheduling...\n", __func__);
226 224
227 s = (struct ip_vs_dh_state *) svc->sched_data; 225 s = (struct ip_vs_dh_state *) svc->sched_data;
228 dest = ip_vs_dh_get(svc->af, s, &iph.daddr); 226 dest = ip_vs_dh_get(svc->af, s, &iph->daddr);
229 if (!dest 227 if (!dest
230 || !(dest->flags & IP_VS_DEST_F_AVAILABLE) 228 || !(dest->flags & IP_VS_DEST_F_AVAILABLE)
231 || atomic_read(&dest->weight) <= 0 229 || atomic_read(&dest->weight) <= 0
@@ -235,7 +233,7 @@ ip_vs_dh_schedule(struct ip_vs_service *svc, const struct sk_buff *skb)
235 } 233 }
236 234
237 IP_VS_DBG_BUF(6, "DH: destination IP address %s --> server %s:%d\n", 235 IP_VS_DBG_BUF(6, "DH: destination IP address %s --> server %s:%d\n",
238 IP_VS_DBG_ADDR(svc->af, &iph.daddr), 236 IP_VS_DBG_ADDR(svc->af, &iph->daddr),
239 IP_VS_DBG_ADDR(svc->af, &dest->addr), 237 IP_VS_DBG_ADDR(svc->af, &dest->addr),
240 ntohs(dest->port)); 238 ntohs(dest->port));
241 239
diff --git a/net/netfilter/ipvs/ip_vs_lblc.c b/net/netfilter/ipvs/ip_vs_lblc.c
index 44595b8ae37f..1383b0eadc0e 100644
--- a/net/netfilter/ipvs/ip_vs_lblc.c
+++ b/net/netfilter/ipvs/ip_vs_lblc.c
@@ -487,19 +487,17 @@ is_overloaded(struct ip_vs_dest *dest, struct ip_vs_service *svc)
487 * Locality-Based (weighted) Least-Connection scheduling 487 * Locality-Based (weighted) Least-Connection scheduling
488 */ 488 */
489static struct ip_vs_dest * 489static struct ip_vs_dest *
490ip_vs_lblc_schedule(struct ip_vs_service *svc, const struct sk_buff *skb) 490ip_vs_lblc_schedule(struct ip_vs_service *svc, const struct sk_buff *skb,
491 struct ip_vs_iphdr *iph)
491{ 492{
492 struct ip_vs_lblc_table *tbl = svc->sched_data; 493 struct ip_vs_lblc_table *tbl = svc->sched_data;
493 struct ip_vs_iphdr iph;
494 struct ip_vs_dest *dest = NULL; 494 struct ip_vs_dest *dest = NULL;
495 struct ip_vs_lblc_entry *en; 495 struct ip_vs_lblc_entry *en;
496 496
497 ip_vs_fill_iph_addr_only(svc->af, skb, &iph);
498
499 IP_VS_DBG(6, "%s(): Scheduling...\n", __func__); 497 IP_VS_DBG(6, "%s(): Scheduling...\n", __func__);
500 498
501 /* First look in our cache */ 499 /* First look in our cache */
502 en = ip_vs_lblc_get(svc->af, tbl, &iph.daddr); 500 en = ip_vs_lblc_get(svc->af, tbl, &iph->daddr);
503 if (en) { 501 if (en) {
504 /* We only hold a read lock, but this is atomic */ 502 /* We only hold a read lock, but this is atomic */
505 en->lastuse = jiffies; 503 en->lastuse = jiffies;
@@ -529,12 +527,12 @@ ip_vs_lblc_schedule(struct ip_vs_service *svc, const struct sk_buff *skb)
529 /* If we fail to create a cache entry, we'll just use the valid dest */ 527 /* If we fail to create a cache entry, we'll just use the valid dest */
530 spin_lock_bh(&svc->sched_lock); 528 spin_lock_bh(&svc->sched_lock);
531 if (!tbl->dead) 529 if (!tbl->dead)
532 ip_vs_lblc_new(tbl, &iph.daddr, dest); 530 ip_vs_lblc_new(tbl, &iph->daddr, dest);
533 spin_unlock_bh(&svc->sched_lock); 531 spin_unlock_bh(&svc->sched_lock);
534 532
535out: 533out:
536 IP_VS_DBG_BUF(6, "LBLC: destination IP address %s --> server %s:%d\n", 534 IP_VS_DBG_BUF(6, "LBLC: destination IP address %s --> server %s:%d\n",
537 IP_VS_DBG_ADDR(svc->af, &iph.daddr), 535 IP_VS_DBG_ADDR(svc->af, &iph->daddr),
538 IP_VS_DBG_ADDR(svc->af, &dest->addr), ntohs(dest->port)); 536 IP_VS_DBG_ADDR(svc->af, &dest->addr), ntohs(dest->port));
539 537
540 return dest; 538 return dest;
diff --git a/net/netfilter/ipvs/ip_vs_lblcr.c b/net/netfilter/ipvs/ip_vs_lblcr.c
index 876937db0bf4..3cd85b2fc67c 100644
--- a/net/netfilter/ipvs/ip_vs_lblcr.c
+++ b/net/netfilter/ipvs/ip_vs_lblcr.c
@@ -655,19 +655,17 @@ is_overloaded(struct ip_vs_dest *dest, struct ip_vs_service *svc)
655 * Locality-Based (weighted) Least-Connection scheduling 655 * Locality-Based (weighted) Least-Connection scheduling
656 */ 656 */
657static struct ip_vs_dest * 657static struct ip_vs_dest *
658ip_vs_lblcr_schedule(struct ip_vs_service *svc, const struct sk_buff *skb) 658ip_vs_lblcr_schedule(struct ip_vs_service *svc, const struct sk_buff *skb,
659 struct ip_vs_iphdr *iph)
659{ 660{
660 struct ip_vs_lblcr_table *tbl = svc->sched_data; 661 struct ip_vs_lblcr_table *tbl = svc->sched_data;
661 struct ip_vs_iphdr iph;
662 struct ip_vs_dest *dest; 662 struct ip_vs_dest *dest;
663 struct ip_vs_lblcr_entry *en; 663 struct ip_vs_lblcr_entry *en;
664 664
665 ip_vs_fill_iph_addr_only(svc->af, skb, &iph);
666
667 IP_VS_DBG(6, "%s(): Scheduling...\n", __func__); 665 IP_VS_DBG(6, "%s(): Scheduling...\n", __func__);
668 666
669 /* First look in our cache */ 667 /* First look in our cache */
670 en = ip_vs_lblcr_get(svc->af, tbl, &iph.daddr); 668 en = ip_vs_lblcr_get(svc->af, tbl, &iph->daddr);
671 if (en) { 669 if (en) {
672 en->lastuse = jiffies; 670 en->lastuse = jiffies;
673 671
@@ -718,12 +716,12 @@ ip_vs_lblcr_schedule(struct ip_vs_service *svc, const struct sk_buff *skb)
718 /* If we fail to create a cache entry, we'll just use the valid dest */ 716 /* If we fail to create a cache entry, we'll just use the valid dest */
719 spin_lock_bh(&svc->sched_lock); 717 spin_lock_bh(&svc->sched_lock);
720 if (!tbl->dead) 718 if (!tbl->dead)
721 ip_vs_lblcr_new(tbl, &iph.daddr, dest); 719 ip_vs_lblcr_new(tbl, &iph->daddr, dest);
722 spin_unlock_bh(&svc->sched_lock); 720 spin_unlock_bh(&svc->sched_lock);
723 721
724out: 722out:
725 IP_VS_DBG_BUF(6, "LBLCR: destination IP address %s --> server %s:%d\n", 723 IP_VS_DBG_BUF(6, "LBLCR: destination IP address %s --> server %s:%d\n",
726 IP_VS_DBG_ADDR(svc->af, &iph.daddr), 724 IP_VS_DBG_ADDR(svc->af, &iph->daddr),
727 IP_VS_DBG_ADDR(svc->af, &dest->addr), ntohs(dest->port)); 725 IP_VS_DBG_ADDR(svc->af, &dest->addr), ntohs(dest->port));
728 726
729 return dest; 727 return dest;
diff --git a/net/netfilter/ipvs/ip_vs_lc.c b/net/netfilter/ipvs/ip_vs_lc.c
index 5128e338a749..2bdcb1cf2127 100644
--- a/net/netfilter/ipvs/ip_vs_lc.c
+++ b/net/netfilter/ipvs/ip_vs_lc.c
@@ -26,7 +26,8 @@
26 * Least Connection scheduling 26 * Least Connection scheduling
27 */ 27 */
28static struct ip_vs_dest * 28static struct ip_vs_dest *
29ip_vs_lc_schedule(struct ip_vs_service *svc, const struct sk_buff *skb) 29ip_vs_lc_schedule(struct ip_vs_service *svc, const struct sk_buff *skb,
30 struct ip_vs_iphdr *iph)
30{ 31{
31 struct ip_vs_dest *dest, *least = NULL; 32 struct ip_vs_dest *dest, *least = NULL;
32 unsigned int loh = 0, doh; 33 unsigned int loh = 0, doh;
diff --git a/net/netfilter/ipvs/ip_vs_nq.c b/net/netfilter/ipvs/ip_vs_nq.c
index 646cfd4baa73..d8d9860934fe 100644
--- a/net/netfilter/ipvs/ip_vs_nq.c
+++ b/net/netfilter/ipvs/ip_vs_nq.c
@@ -55,7 +55,8 @@ ip_vs_nq_dest_overhead(struct ip_vs_dest *dest)
55 * Weighted Least Connection scheduling 55 * Weighted Least Connection scheduling
56 */ 56 */
57static struct ip_vs_dest * 57static struct ip_vs_dest *
58ip_vs_nq_schedule(struct ip_vs_service *svc, const struct sk_buff *skb) 58ip_vs_nq_schedule(struct ip_vs_service *svc, const struct sk_buff *skb,
59 struct ip_vs_iphdr *iph)
59{ 60{
60 struct ip_vs_dest *dest, *least = NULL; 61 struct ip_vs_dest *dest, *least = NULL;
61 unsigned int loh = 0, doh; 62 unsigned int loh = 0, doh;
diff --git a/net/netfilter/ipvs/ip_vs_rr.c b/net/netfilter/ipvs/ip_vs_rr.c
index c35986c793d9..176b87c35e34 100644
--- a/net/netfilter/ipvs/ip_vs_rr.c
+++ b/net/netfilter/ipvs/ip_vs_rr.c
@@ -55,7 +55,8 @@ static int ip_vs_rr_del_dest(struct ip_vs_service *svc, struct ip_vs_dest *dest)
55 * Round-Robin Scheduling 55 * Round-Robin Scheduling
56 */ 56 */
57static struct ip_vs_dest * 57static struct ip_vs_dest *
58ip_vs_rr_schedule(struct ip_vs_service *svc, const struct sk_buff *skb) 58ip_vs_rr_schedule(struct ip_vs_service *svc, const struct sk_buff *skb,
59 struct ip_vs_iphdr *iph)
59{ 60{
60 struct list_head *p; 61 struct list_head *p;
61 struct ip_vs_dest *dest, *last; 62 struct ip_vs_dest *dest, *last;
diff --git a/net/netfilter/ipvs/ip_vs_sed.c b/net/netfilter/ipvs/ip_vs_sed.c
index f3205925359a..a5284cc3d882 100644
--- a/net/netfilter/ipvs/ip_vs_sed.c
+++ b/net/netfilter/ipvs/ip_vs_sed.c
@@ -59,7 +59,8 @@ ip_vs_sed_dest_overhead(struct ip_vs_dest *dest)
59 * Weighted Least Connection scheduling 59 * Weighted Least Connection scheduling
60 */ 60 */
61static struct ip_vs_dest * 61static struct ip_vs_dest *
62ip_vs_sed_schedule(struct ip_vs_service *svc, const struct sk_buff *skb) 62ip_vs_sed_schedule(struct ip_vs_service *svc, const struct sk_buff *skb,
63 struct ip_vs_iphdr *iph)
63{ 64{
64 struct ip_vs_dest *dest, *least; 65 struct ip_vs_dest *dest, *least;
65 unsigned int loh, doh; 66 unsigned int loh, doh;
diff --git a/net/netfilter/ipvs/ip_vs_sh.c b/net/netfilter/ipvs/ip_vs_sh.c
index a65edfe4b16c..e0d5d1653566 100644
--- a/net/netfilter/ipvs/ip_vs_sh.c
+++ b/net/netfilter/ipvs/ip_vs_sh.c
@@ -227,18 +227,16 @@ static inline int is_overloaded(struct ip_vs_dest *dest)
227 * Source Hashing scheduling 227 * Source Hashing scheduling
228 */ 228 */
229static struct ip_vs_dest * 229static struct ip_vs_dest *
230ip_vs_sh_schedule(struct ip_vs_service *svc, const struct sk_buff *skb) 230ip_vs_sh_schedule(struct ip_vs_service *svc, const struct sk_buff *skb,
231 struct ip_vs_iphdr *iph)
231{ 232{
232 struct ip_vs_dest *dest; 233 struct ip_vs_dest *dest;
233 struct ip_vs_sh_state *s; 234 struct ip_vs_sh_state *s;
234 struct ip_vs_iphdr iph;
235
236 ip_vs_fill_iph_addr_only(svc->af, skb, &iph);
237 235
238 IP_VS_DBG(6, "ip_vs_sh_schedule(): Scheduling...\n"); 236 IP_VS_DBG(6, "ip_vs_sh_schedule(): Scheduling...\n");
239 237
240 s = (struct ip_vs_sh_state *) svc->sched_data; 238 s = (struct ip_vs_sh_state *) svc->sched_data;
241 dest = ip_vs_sh_get(svc->af, s, &iph.saddr); 239 dest = ip_vs_sh_get(svc->af, s, &iph->saddr);
242 if (!dest 240 if (!dest
243 || !(dest->flags & IP_VS_DEST_F_AVAILABLE) 241 || !(dest->flags & IP_VS_DEST_F_AVAILABLE)
244 || atomic_read(&dest->weight) <= 0 242 || atomic_read(&dest->weight) <= 0
@@ -248,7 +246,7 @@ ip_vs_sh_schedule(struct ip_vs_service *svc, const struct sk_buff *skb)
248 } 246 }
249 247
250 IP_VS_DBG_BUF(6, "SH: source IP address %s --> server %s:%d\n", 248 IP_VS_DBG_BUF(6, "SH: source IP address %s --> server %s:%d\n",
251 IP_VS_DBG_ADDR(svc->af, &iph.saddr), 249 IP_VS_DBG_ADDR(svc->af, &iph->saddr),
252 IP_VS_DBG_ADDR(svc->af, &dest->addr), 250 IP_VS_DBG_ADDR(svc->af, &dest->addr),
253 ntohs(dest->port)); 251 ntohs(dest->port));
254 252
diff --git a/net/netfilter/ipvs/ip_vs_wlc.c b/net/netfilter/ipvs/ip_vs_wlc.c
index c60a81c4ce9a..6dc1fa128840 100644
--- a/net/netfilter/ipvs/ip_vs_wlc.c
+++ b/net/netfilter/ipvs/ip_vs_wlc.c
@@ -31,7 +31,8 @@
31 * Weighted Least Connection scheduling 31 * Weighted Least Connection scheduling
32 */ 32 */
33static struct ip_vs_dest * 33static struct ip_vs_dest *
34ip_vs_wlc_schedule(struct ip_vs_service *svc, const struct sk_buff *skb) 34ip_vs_wlc_schedule(struct ip_vs_service *svc, const struct sk_buff *skb,
35 struct ip_vs_iphdr *iph)
35{ 36{
36 struct ip_vs_dest *dest, *least; 37 struct ip_vs_dest *dest, *least;
37 unsigned int loh, doh; 38 unsigned int loh, doh;
diff --git a/net/netfilter/ipvs/ip_vs_wrr.c b/net/netfilter/ipvs/ip_vs_wrr.c
index 0e68555bceb9..0546cd572d6b 100644
--- a/net/netfilter/ipvs/ip_vs_wrr.c
+++ b/net/netfilter/ipvs/ip_vs_wrr.c
@@ -162,7 +162,8 @@ static int ip_vs_wrr_dest_changed(struct ip_vs_service *svc,
162 * Weighted Round-Robin Scheduling 162 * Weighted Round-Robin Scheduling
163 */ 163 */
164static struct ip_vs_dest * 164static struct ip_vs_dest *
165ip_vs_wrr_schedule(struct ip_vs_service *svc, const struct sk_buff *skb) 165ip_vs_wrr_schedule(struct ip_vs_service *svc, const struct sk_buff *skb,
166 struct ip_vs_iphdr *iph)
166{ 167{
167 struct ip_vs_dest *dest, *last, *stop = NULL; 168 struct ip_vs_dest *dest, *last, *stop = NULL;
168 struct ip_vs_wrr_mark *mark = svc->sched_data; 169 struct ip_vs_wrr_mark *mark = svc->sched_data;