add no_route_to_host_fix switch to turn on/off the fix in bpf mode

Test case
	1) conn_reuse_mode = 1 && no_route_to_host_fix==1
	result: wrk performance good
	2) conn_reuse_mode = 1 && no_route_to_host_fix==0
	result: wrk performance bad, packet loss
	3) conn_reuse_mode = 0 && no_route_to_host_fix==0
	result: wrk performance good. icmp no route to host error
	4) conn_reuse_mode = 0 && no_route_to_host_fix==1
	result: wrk performance good. no icmp no route to host error

Signed-off-by: jianmingfan <jianmingfan@tencent.com>
This commit is contained in:
jianmingfan 2020-05-26 00:59:47 +08:00 committed by Xiaoming Gao
parent ef8004f8fe
commit 8ec35911f7
4 changed files with 76 additions and 8 deletions

View File

@ -1704,6 +1704,7 @@ struct bpf_sym_addrs {
extern struct bpf_sym_addrs resolve_addrs;
extern struct bpf_map *conntrack_map;
extern bool bpf_mode_on;
extern bool no_route_to_host_fix;
extern __be32 major_nic_ip;
int ip_vs_bpf_put(void);

View File

@ -54,7 +54,7 @@ __be32 major_nic_ip;
static int ip_local_port_begin;
static int ip_local_port_end;
struct bpf_map *conntrack_map;
bool no_route_to_host_fix;
struct ip_vs_iter_state {
struct seq_net_private p;
struct hlist_head *l;
@ -667,6 +667,58 @@ static ssize_t ip_vs_port_write(struct file *file,
return count;
}
static ssize_t ip_vs_bpf_fix_write(struct file *file,
const char __user *ubuf,
size_t count,
loff_t *ppos)
{
char buf[10];
int fix;
memset(buf, 0, sizeof(buf));
if (*ppos > 0) {
pr_err("%s %d\n", __func__, __LINE__);
return -EFAULT;
}
if (copy_from_user(buf, ubuf, count)) {
pr_err("%s %d\n", __FILE__, __LINE__);
return -EFAULT;
}
if (kstrtoint(buf, 0, &fix) != 0) {
pr_err("%s %d\n", __FILE__, __LINE__);
return -EINVAL;
}
if (fix != 1 && fix != 0) {
pr_err("%s %d\n", __FILE__, __LINE__);
return -EINVAL;
}
no_route_to_host_fix = fix;
return count;
}
static ssize_t ip_vs_bpf_fix_read(struct file *file,
char __user *ubuf,
size_t count,
loff_t *ppos)
{
int len = 0;
char buf[10];
memset(buf, 0, sizeof(buf));
if (*ppos > 0) {
/* return 0 to sigal eof to user */
return 0;
}
/* snprintf need tail to save null bytes */
len = snprintf(buf, sizeof(buf), "0x%d\n", no_route_to_host_fix);
if (copy_to_user(ubuf, buf, len))
return -EFAULT;
/* so next time ppos will be bigger than 0 and return 0 */
*ppos = len;
return len;
}
static const struct file_operations ip_vs_svc_fops = {
.owner = THIS_MODULE,
.open = ip_vs_svc_open,
@ -694,6 +746,12 @@ static const struct file_operations ip_vs_port_fops = {
.write = ip_vs_port_write,
};
static const struct file_operations ip_vs_bpf_fix_fops = {
.owner = THIS_MODULE,
.read = ip_vs_bpf_fix_read,
.write = ip_vs_bpf_fix_write,
};
struct ip_vs_err_map {
int errno;
const char *name;
@ -774,9 +832,14 @@ int ip_vs_svc_proc_init(struct netns_ipvs *ipvs)
if (!proc_create("ip_vs_bpf_stat", S_IRUGO, ipvs->net->proc_net,
&ip_vs_bpf_stat_fops))
goto out_bpf_stat;
if (!proc_create("ip_vs_bpf_fix", 0600,
ipvs->net->proc_net, &ip_vs_bpf_fix_fops))
goto out_bpf_fix;
return 0;
out_bpf_fix:
remove_proc_entry("ip_vs_bpf_stat", ipvs->net->proc_net);
out_bpf_stat:
remove_proc_entry("ip_vs_port_range", ipvs->net->proc_net);
out_port_range:
@ -796,5 +859,6 @@ int ip_vs_svc_proc_cleanup(struct netns_ipvs *ipvs)
remove_proc_entry("ip_vs_devip", ipvs->net->proc_net);
remove_proc_entry("ip_vs_port_range", ipvs->net->proc_net);
remove_proc_entry("ip_vs_bpf_stat", ipvs->net->proc_net);
remove_proc_entry("ip_vs_bpf_fix", ipvs->net->proc_net);
return 0;
}

View File

@ -270,7 +270,7 @@ static void ip_vs_unlink_bpf(struct ip_vs_conn *cp)
return;
}
if (atomic_dec_return(&v->ref) != 0)
if (no_route_to_host_fix && atomic_dec_return(&v->ref) != 0)
return;
reply.sip = cp->dest->addr.ip;
reply.sport = cp->dest->port;
@ -1125,10 +1125,12 @@ static bool ip_vs_conn_new_bpf(struct ip_vs_dest *dest,
* otherwise, it doesn't reschedule. in such case, the following code
* will not run.
*/
v = map->ops->map_lookup_elem(map, &key);
if (v) {
atomic_inc(&v->ref);
return true;
if (no_route_to_host_fix) {
v = map->ops->map_lookup_elem(map, &key);
if (v) {
atomic_inc(&v->ref);
return true;
}
}
lip = alloc_localip();

View File

@ -1994,8 +1994,9 @@ ip_vs_in(struct netns_ipvs *ipvs, unsigned int hooknum, struct sk_buff *skb, int
* as zero rs may be killed already.
* Only enable in bpf mode currently. Shall promote to IPVS mode later.
*/
if (bpf_mode_on && cp && unlikely(!atomic_read(&cp->dest->weight)) &&
is_new_conn(skb, &iph) && !iph.fragoffs) {
if (no_route_to_host_fix && bpf_mode_on && cp &&
unlikely(!atomic_read(&cp->dest->weight)) &&
is_new_conn(skb, &iph) && !iph.fragoffs) {
ip_vs_conn_expire_now(cp);
__ip_vs_conn_put(cp);
cp = NULL;