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: Julian Anastasov <ja@ssi.bg> Acked-by: Hans Schillstrom <hans@schillstrom.com> Signed-off-by: Simon Horman <horms@verge.net.au>
This commit is contained in:
Родитель
681f130f39
Коммит
bba54de5bd
|
@ -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 */
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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));
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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));
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
Загрузка…
Ссылка в новой задаче