VPP-130: LoadBal: Add lookup bypass and fix adjacency format function
Change-Id: Ib83c6ba04c41dbb80603c6a08c324d71eb44a102 Signed-off-by: Pierre Pfister <ppfister@cisco.com>
This commit is contained in:
@ -16,6 +16,47 @@
|
||||
#include <lb/lb.h>
|
||||
#include <lb/util.h>
|
||||
|
||||
static clib_error_t *
|
||||
lb_bypass_command_fn (vlib_main_t * vm,
|
||||
unformat_input_t * input, vlib_cli_command_t * cmd)
|
||||
{
|
||||
unformat_input_t _line_input, *line_input = &_line_input;
|
||||
ip46_address_t vip_prefix, as_addr;
|
||||
u8 vip_plen;
|
||||
u32 vip_index;
|
||||
u8 disable = 0;
|
||||
int ret;
|
||||
|
||||
if (!unformat_user (input, unformat_line_input, line_input))
|
||||
return 0;
|
||||
|
||||
if (!unformat(line_input, "%U", unformat_ip46_prefix, &vip_prefix, &vip_plen, IP46_TYPE_ANY))
|
||||
return clib_error_return (0, "invalid vip prefix: '%U'",
|
||||
format_unformat_error, line_input);
|
||||
|
||||
if ((ret = lb_vip_find_index(&vip_prefix, vip_plen, &vip_index)))
|
||||
return clib_error_return (0, "lb_vip_find_index error %d", ret);
|
||||
|
||||
if (!unformat(line_input, "%U", unformat_ip46_address, &as_addr, IP46_TYPE_ANY))
|
||||
return clib_error_return (0, "invalid as address: '%U'",
|
||||
format_unformat_error, line_input);
|
||||
|
||||
if (unformat(line_input, "disable"))
|
||||
disable = 1;
|
||||
|
||||
if ((ret = lb_as_lookup_bypass(vip_index, &as_addr, disable)))
|
||||
return clib_error_return (0, "lb_as_lookup_bypass error %d", ret);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
VLIB_CLI_COMMAND (lb_bypass_command, static) =
|
||||
{
|
||||
.path = "lb bypass",
|
||||
.short_help = "lb bypass <prefix> <address> [disable]",
|
||||
.function = lb_bypass_command_fn,
|
||||
};
|
||||
|
||||
static clib_error_t *
|
||||
lb_vip_command_fn (vlib_main_t * vm,
|
||||
unformat_input_t * input, vlib_cli_command_t * cmd)
|
||||
|
@ -143,10 +143,12 @@ u8 *format_lb_vip_detailed (u8 * s, va_list * args)
|
||||
u32 *as_index;
|
||||
pool_foreach(as_index, vip->as_indexes, {
|
||||
as = &lbm->ass[*as_index];
|
||||
s = format(s, "%U %U %d buckets %d flows %s\n", format_white_space, indent,
|
||||
s = format(s, "%U %U %d buckets %d flows adj:%u %s\n",
|
||||
format_white_space, indent,
|
||||
format_ip46_address, &as->address, IP46_TYPE_ANY,
|
||||
count[as - lbm->ass],
|
||||
vlib_refcount_get(&lbm->as_refcount, as - lbm->ass),
|
||||
as->adj_index,
|
||||
(as->flags & LB_AS_FLAGS_USED)?"used":" removed");
|
||||
});
|
||||
|
||||
@ -447,6 +449,7 @@ next:
|
||||
//Update reused ASs
|
||||
vec_foreach(ip, to_be_updated) {
|
||||
lbm->ass[*ip].flags = LB_AS_FLAGS_USED;
|
||||
lbm->ass[*ip].adj_index = ~0;
|
||||
}
|
||||
vec_free(to_be_updated);
|
||||
|
||||
@ -458,6 +461,7 @@ next:
|
||||
as->address = addresses[*ip];
|
||||
as->flags = LB_AS_FLAGS_USED;
|
||||
as->vip_index = vip_index;
|
||||
as->adj_index = ~0;
|
||||
pool_get(vip->as_indexes, as_index);
|
||||
*as_index = as - lbm->ass;
|
||||
}
|
||||
@ -531,6 +535,59 @@ int lb_vip_del_ass(u32 vip_index, ip46_address_t *addresses, u32 n)
|
||||
return ret;
|
||||
}
|
||||
|
||||
int lb_as_lookup_bypass(u32 vip_index, ip46_address_t *address, u8 is_disable)
|
||||
{
|
||||
lb_get_writer_lock();
|
||||
lb_main_t *lbm = &lb_main;
|
||||
u32 as_index;
|
||||
lb_as_t *as;
|
||||
lb_vip_t *vip;
|
||||
|
||||
if (!(vip = lb_vip_get_by_index(vip_index)) ||
|
||||
lb_as_find_index_vip(vip, address, &as_index)) {
|
||||
lb_put_writer_lock();
|
||||
return VNET_API_ERROR_NO_SUCH_ENTRY;
|
||||
}
|
||||
|
||||
as = &lbm->ass[as_index];
|
||||
|
||||
if (is_disable) {
|
||||
as->adj_index = ~0;
|
||||
} else if (lb_vip_is_gre4(vip)) {
|
||||
uword *p = ip4_get_route (&ip4_main, 0, 0, as->address.ip4.as_u8, 32);
|
||||
if (p == 0) {
|
||||
lb_put_writer_lock();
|
||||
return VNET_API_ERROR_NO_SUCH_ENTRY;
|
||||
}
|
||||
u32 ai = (u32)p[0];
|
||||
ip_lookup_main_t *lm4 = &ip4_main.lookup_main;
|
||||
ip_adjacency_t *adj4 = ip_get_adjacency (lm4, ai);
|
||||
if (adj4->lookup_next_index != IP_LOOKUP_NEXT_REWRITE) {
|
||||
lb_put_writer_lock();
|
||||
return VNET_API_ERROR_INCORRECT_ADJACENCY_TYPE;
|
||||
}
|
||||
|
||||
as->adj_index = ai;
|
||||
} else {
|
||||
u32 ai = ip6_get_route (&ip6_main, 0, 0, &as->address.ip6, 128);
|
||||
if (ai == 0) {
|
||||
lb_put_writer_lock();
|
||||
return VNET_API_ERROR_NO_SUCH_ENTRY;
|
||||
}
|
||||
|
||||
ip_lookup_main_t *lm6 = &ip6_main.lookup_main;
|
||||
ip_adjacency_t *adj6 = ip_get_adjacency (lm6, ai);
|
||||
if (adj6->lookup_next_index != IP_LOOKUP_NEXT_REWRITE) {
|
||||
lb_put_writer_lock();
|
||||
return VNET_API_ERROR_INCORRECT_ADJACENCY_TYPE;
|
||||
}
|
||||
|
||||
as->adj_index = ai;
|
||||
}
|
||||
lb_put_writer_lock();
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Add the VIP adjacency to the ip4 or ip6 fib
|
||||
@ -733,6 +790,7 @@ lb_init (vlib_main_t * vm)
|
||||
lbm->ass = 0;
|
||||
pool_get(lbm->ass, default_as);
|
||||
default_as->flags = 0;
|
||||
default_as->adj_index = ~0;
|
||||
default_as->vip_index = ~0;
|
||||
default_as->address.ip6.as_u64[0] = 0xffffffffffffffffL;
|
||||
default_as->address.ip6.as_u64[1] = 0xffffffffffffffffL;
|
||||
|
@ -54,6 +54,13 @@ typedef struct {
|
||||
*/
|
||||
ip46_address_t address;
|
||||
|
||||
/**
|
||||
* Second ip lookup can be avoided by sending directly the packet
|
||||
* to ip-rewrite with a configured adjacency.
|
||||
* When set to ~0, the packets are sent to ip6-lookup.
|
||||
*/
|
||||
u32 adj_index;
|
||||
|
||||
/**
|
||||
* ASs are indexed by address and VIP Index.
|
||||
* Which means there will be duplicated if the same server
|
||||
@ -295,6 +302,12 @@ int lb_vip_find_index(ip46_address_t *prefix, u8 plen, u32 *vip_index);
|
||||
int lb_vip_add_ass(u32 vip_index, ip46_address_t *addresses, u32 n);
|
||||
int lb_vip_del_ass(u32 vip_index, ip46_address_t *addresses, u32 n);
|
||||
|
||||
/**
|
||||
* Updates the adjacency index stored in the AS such that the second
|
||||
* IP lookup (after encap) can be bypassed.
|
||||
*/
|
||||
int lb_as_lookup_bypass(u32 vip_index, ip46_address_t *address, u8 is_disable);
|
||||
|
||||
u32 lb_hash_time_now(vlib_main_t * vm);
|
||||
|
||||
void lb_garbage_collection();
|
||||
|
@ -38,6 +38,7 @@ static char *lb_error_strings[] = {
|
||||
|
||||
typedef enum {
|
||||
LB_NEXT_LOOKUP,
|
||||
LB_NEXT_REWRITE,
|
||||
LB_NEXT_DROP,
|
||||
LB_N_NEXT,
|
||||
} lb_next_t;
|
||||
@ -47,14 +48,14 @@ typedef struct {
|
||||
u32 as_index;
|
||||
} lb_trace_t;
|
||||
|
||||
u8 *lb_format_adjacency(u8 * s,
|
||||
struct ip_lookup_main_t * lm,
|
||||
ip_adjacency_t *adj)
|
||||
u8 *lb_format_adjacency(u8 * s, va_list * va)
|
||||
{
|
||||
lb_main_t *lbm = &lb_main;
|
||||
__attribute((unused)) ip_lookup_main_t *lm = va_arg (*va, ip_lookup_main_t *);
|
||||
ip_adjacency_t *adj = va_arg (*va, ip_adjacency_t *);
|
||||
lb_adj_data_t *ad = (lb_adj_data_t *) &adj->opaque;
|
||||
__attribute__((unused)) lb_vip_t *vip = pool_elt_at_index (lbm->vips, ad->vip_index);
|
||||
return format(s, "idx:%d", ad->vip_index);
|
||||
return format(s, "vip idx:%d", ad->vip_index);
|
||||
}
|
||||
|
||||
u8 *
|
||||
@ -251,6 +252,9 @@ lb_node_fn (vlib_main_t * vm,
|
||||
clib_host_to_net_u16(0x0800):
|
||||
clib_host_to_net_u16(0x86DD);
|
||||
|
||||
vnet_buffer(p0)->ip.adj_index[VLIB_TX] = as0->adj_index;
|
||||
next0 = (as0->adj_index != ~0)?LB_NEXT_REWRITE:next0;
|
||||
|
||||
if (PREDICT_FALSE (p0->flags & VLIB_BUFFER_IS_TRACED))
|
||||
{
|
||||
lb_trace_t *tr = vlib_add_trace (vm, node, p0, sizeof (*tr));
|
||||
@ -310,6 +314,7 @@ VLIB_REGISTER_NODE (lb6_gre6_node) =
|
||||
.next_nodes =
|
||||
{
|
||||
[LB_NEXT_LOOKUP] = "ip6-lookup",
|
||||
[LB_NEXT_REWRITE] = "ip6-rewrite",
|
||||
[LB_NEXT_DROP] = "error-drop"
|
||||
},
|
||||
};
|
||||
@ -334,6 +339,7 @@ VLIB_REGISTER_NODE (lb6_gre4_node) =
|
||||
.next_nodes =
|
||||
{
|
||||
[LB_NEXT_LOOKUP] = "ip4-lookup",
|
||||
[LB_NEXT_REWRITE]= "ip4-rewrite-transit",
|
||||
[LB_NEXT_DROP] = "error-drop"
|
||||
},
|
||||
};
|
||||
@ -358,6 +364,7 @@ VLIB_REGISTER_NODE (lb4_gre6_node) =
|
||||
.next_nodes =
|
||||
{
|
||||
[LB_NEXT_LOOKUP] = "ip6-lookup",
|
||||
[LB_NEXT_REWRITE] = "ip6-rewrite",
|
||||
[LB_NEXT_DROP] = "error-drop"
|
||||
},
|
||||
};
|
||||
@ -382,6 +389,7 @@ VLIB_REGISTER_NODE (lb4_gre4_node) =
|
||||
.next_nodes =
|
||||
{
|
||||
[LB_NEXT_LOOKUP] = "ip4-lookup",
|
||||
[LB_NEXT_REWRITE]= "ip4-rewrite-transit",
|
||||
[LB_NEXT_DROP] = "error-drop"
|
||||
},
|
||||
};
|
||||
|
Reference in New Issue
Block a user