提交 bba54de5 编写于 作者: J Julian Anastasov 提交者: Simon Horman

ipvs: provide iph to schedulers

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: NJulian Anastasov <ja@ssi.bg>
Acked-by: NHans Schillstrom <hans@schillstrom.com>
Signed-off-by: NSimon Horman <horms@verge.net.au>
上级 681f130f
...@@ -197,31 +197,6 @@ ip_vs_fill_iph_skb(int af, const struct sk_buff *skb, struct ip_vs_iphdr *iphdr) ...@@ -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, static inline void ip_vs_addr_copy(int af, union nf_inet_addr *dst,
const union nf_inet_addr *src) const union nf_inet_addr *src)
{ {
...@@ -814,7 +789,8 @@ struct ip_vs_scheduler { ...@@ -814,7 +789,8 @@ struct ip_vs_scheduler {
/* selecting a server from the given service */ /* selecting a server from the given service */
struct ip_vs_dest* (*schedule)(struct ip_vs_service *svc, 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 */ /* The persistence engine object */
......
...@@ -305,7 +305,7 @@ ip_vs_sched_persist(struct ip_vs_service *svc, ...@@ -305,7 +305,7 @@ ip_vs_sched_persist(struct ip_vs_service *svc,
* return *ignored=0 i.e. ICMP and NF_DROP * return *ignored=0 i.e. ICMP and NF_DROP
*/ */
sched = rcu_dereference(svc->scheduler); sched = rcu_dereference(svc->scheduler);
dest = sched->schedule(svc, skb); dest = sched->schedule(svc, skb, iph);
if (!dest) { if (!dest) {
IP_VS_DBG(1, "p-schedule: no dest found.\n"); IP_VS_DBG(1, "p-schedule: no dest found.\n");
kfree(param.pe_data); kfree(param.pe_data);
...@@ -452,7 +452,7 @@ ip_vs_schedule(struct ip_vs_service *svc, struct sk_buff *skb, ...@@ -452,7 +452,7 @@ ip_vs_schedule(struct ip_vs_service *svc, struct sk_buff *skb,
} }
sched = rcu_dereference(svc->scheduler); sched = rcu_dereference(svc->scheduler);
dest = sched->schedule(svc, skb); dest = sched->schedule(svc, skb, iph);
if (dest == NULL) { if (dest == NULL) {
IP_VS_DBG(1, "Schedule: no dest found.\n"); IP_VS_DBG(1, "Schedule: no dest found.\n");
return NULL; return NULL;
......
...@@ -214,18 +214,16 @@ static inline int is_overloaded(struct ip_vs_dest *dest) ...@@ -214,18 +214,16 @@ static inline int is_overloaded(struct ip_vs_dest *dest)
* Destination hashing scheduling * Destination hashing scheduling
*/ */
static struct ip_vs_dest * 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_dest *dest;
struct ip_vs_dh_state *s; 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__); IP_VS_DBG(6, "%s(): Scheduling...\n", __func__);
s = (struct ip_vs_dh_state *) svc->sched_data; 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 if (!dest
|| !(dest->flags & IP_VS_DEST_F_AVAILABLE) || !(dest->flags & IP_VS_DEST_F_AVAILABLE)
|| atomic_read(&dest->weight) <= 0 || atomic_read(&dest->weight) <= 0
...@@ -235,7 +233,7 @@ ip_vs_dh_schedule(struct ip_vs_service *svc, const struct sk_buff *skb) ...@@ -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_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), IP_VS_DBG_ADDR(svc->af, &dest->addr),
ntohs(dest->port)); ntohs(dest->port));
......
...@@ -487,19 +487,17 @@ is_overloaded(struct ip_vs_dest *dest, struct ip_vs_service *svc) ...@@ -487,19 +487,17 @@ is_overloaded(struct ip_vs_dest *dest, struct ip_vs_service *svc)
* Locality-Based (weighted) Least-Connection scheduling * Locality-Based (weighted) Least-Connection scheduling
*/ */
static struct ip_vs_dest * 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_lblc_table *tbl = svc->sched_data;
struct ip_vs_iphdr iph;
struct ip_vs_dest *dest = NULL; struct ip_vs_dest *dest = NULL;
struct ip_vs_lblc_entry *en; struct ip_vs_lblc_entry *en;
ip_vs_fill_iph_addr_only(svc->af, skb, &iph);
IP_VS_DBG(6, "%s(): Scheduling...\n", __func__); IP_VS_DBG(6, "%s(): Scheduling...\n", __func__);
/* First look in our cache */ /* 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) { if (en) {
/* We only hold a read lock, but this is atomic */ /* We only hold a read lock, but this is atomic */
en->lastuse = jiffies; en->lastuse = jiffies;
...@@ -529,12 +527,12 @@ ip_vs_lblc_schedule(struct ip_vs_service *svc, const struct sk_buff *skb) ...@@ -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 */ /* If we fail to create a cache entry, we'll just use the valid dest */
spin_lock_bh(&svc->sched_lock); spin_lock_bh(&svc->sched_lock);
if (!tbl->dead) 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); spin_unlock_bh(&svc->sched_lock);
out: out:
IP_VS_DBG_BUF(6, "LBLC: destination IP address %s --> server %s:%d\n", 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)); IP_VS_DBG_ADDR(svc->af, &dest->addr), ntohs(dest->port));
return dest; return dest;
......
...@@ -655,19 +655,17 @@ is_overloaded(struct ip_vs_dest *dest, struct ip_vs_service *svc) ...@@ -655,19 +655,17 @@ is_overloaded(struct ip_vs_dest *dest, struct ip_vs_service *svc)
* Locality-Based (weighted) Least-Connection scheduling * Locality-Based (weighted) Least-Connection scheduling
*/ */
static struct ip_vs_dest * 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_lblcr_table *tbl = svc->sched_data;
struct ip_vs_iphdr iph;
struct ip_vs_dest *dest; struct ip_vs_dest *dest;
struct ip_vs_lblcr_entry *en; struct ip_vs_lblcr_entry *en;
ip_vs_fill_iph_addr_only(svc->af, skb, &iph);
IP_VS_DBG(6, "%s(): Scheduling...\n", __func__); IP_VS_DBG(6, "%s(): Scheduling...\n", __func__);
/* First look in our cache */ /* 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) { if (en) {
en->lastuse = jiffies; en->lastuse = jiffies;
...@@ -718,12 +716,12 @@ ip_vs_lblcr_schedule(struct ip_vs_service *svc, const struct sk_buff *skb) ...@@ -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 */ /* If we fail to create a cache entry, we'll just use the valid dest */
spin_lock_bh(&svc->sched_lock); spin_lock_bh(&svc->sched_lock);
if (!tbl->dead) 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); spin_unlock_bh(&svc->sched_lock);
out: out:
IP_VS_DBG_BUF(6, "LBLCR: destination IP address %s --> server %s:%d\n", 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)); IP_VS_DBG_ADDR(svc->af, &dest->addr), ntohs(dest->port));
return dest; return dest;
......
...@@ -26,7 +26,8 @@ ...@@ -26,7 +26,8 @@
* Least Connection scheduling * Least Connection scheduling
*/ */
static struct ip_vs_dest * 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; struct ip_vs_dest *dest, *least = NULL;
unsigned int loh = 0, doh; unsigned int loh = 0, doh;
......
...@@ -55,7 +55,8 @@ ip_vs_nq_dest_overhead(struct ip_vs_dest *dest) ...@@ -55,7 +55,8 @@ ip_vs_nq_dest_overhead(struct ip_vs_dest *dest)
* Weighted Least Connection scheduling * Weighted Least Connection scheduling
*/ */
static struct ip_vs_dest * 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; struct ip_vs_dest *dest, *least = NULL;
unsigned int loh = 0, doh; unsigned int loh = 0, doh;
......
...@@ -55,7 +55,8 @@ static int ip_vs_rr_del_dest(struct ip_vs_service *svc, struct ip_vs_dest *dest) ...@@ -55,7 +55,8 @@ static int ip_vs_rr_del_dest(struct ip_vs_service *svc, struct ip_vs_dest *dest)
* Round-Robin Scheduling * Round-Robin Scheduling
*/ */
static struct ip_vs_dest * 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 list_head *p;
struct ip_vs_dest *dest, *last; struct ip_vs_dest *dest, *last;
......
...@@ -59,7 +59,8 @@ ip_vs_sed_dest_overhead(struct ip_vs_dest *dest) ...@@ -59,7 +59,8 @@ ip_vs_sed_dest_overhead(struct ip_vs_dest *dest)
* Weighted Least Connection scheduling * Weighted Least Connection scheduling
*/ */
static struct ip_vs_dest * 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; struct ip_vs_dest *dest, *least;
unsigned int loh, doh; unsigned int loh, doh;
......
...@@ -227,18 +227,16 @@ static inline int is_overloaded(struct ip_vs_dest *dest) ...@@ -227,18 +227,16 @@ static inline int is_overloaded(struct ip_vs_dest *dest)
* Source Hashing scheduling * Source Hashing scheduling
*/ */
static struct ip_vs_dest * 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_dest *dest;
struct ip_vs_sh_state *s; 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"); IP_VS_DBG(6, "ip_vs_sh_schedule(): Scheduling...\n");
s = (struct ip_vs_sh_state *) svc->sched_data; 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 if (!dest
|| !(dest->flags & IP_VS_DEST_F_AVAILABLE) || !(dest->flags & IP_VS_DEST_F_AVAILABLE)
|| atomic_read(&dest->weight) <= 0 || atomic_read(&dest->weight) <= 0
...@@ -248,7 +246,7 @@ ip_vs_sh_schedule(struct ip_vs_service *svc, const struct sk_buff *skb) ...@@ -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_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), IP_VS_DBG_ADDR(svc->af, &dest->addr),
ntohs(dest->port)); ntohs(dest->port));
......
...@@ -31,7 +31,8 @@ ...@@ -31,7 +31,8 @@
* Weighted Least Connection scheduling * Weighted Least Connection scheduling
*/ */
static struct ip_vs_dest * 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; struct ip_vs_dest *dest, *least;
unsigned int loh, doh; unsigned int loh, doh;
......
...@@ -162,7 +162,8 @@ static int ip_vs_wrr_dest_changed(struct ip_vs_service *svc, ...@@ -162,7 +162,8 @@ static int ip_vs_wrr_dest_changed(struct ip_vs_service *svc,
* Weighted Round-Robin Scheduling * Weighted Round-Robin Scheduling
*/ */
static struct ip_vs_dest * 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_dest *dest, *last, *stop = NULL;
struct ip_vs_wrr_mark *mark = svc->sched_data; struct ip_vs_wrr_mark *mark = svc->sched_data;
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册