diff options
author | Dave Barach <dave@barachs.net> | 2016-07-05 13:37:34 -0400 |
---|---|---|
committer | Dave Barach <dave@barachs.net> | 2016-07-05 13:37:46 -0400 |
commit | 2195706fef482cf7f295cd2e8c416541161c1724 (patch) | |
tree | 731767877ebea3416aedce3ffd021cdbff133b2c | |
parent | 55bf5c938585f0cc91b848ec37a5abfaf01f9515 (diff) |
VPP-179 Fix adjacency reference-count botches
Change-Id: I3fe83a511064d73087c4526ef33cd7628f15b90f
Signed-off-by: Dave Barach <dave@barachs.net>
-rw-r--r-- | vnet/vnet/ip/ip4_forward.c | 13 | ||||
-rw-r--r-- | vnet/vnet/ip/ip6_forward.c | 13 |
2 files changed, 24 insertions, 2 deletions
diff --git a/vnet/vnet/ip/ip4_forward.c b/vnet/vnet/ip/ip4_forward.c index 6008ec222c5..939835ae66a 100644 --- a/vnet/vnet/ip/ip4_forward.c +++ b/vnet/vnet/ip/ip4_forward.c @@ -403,8 +403,10 @@ ip4_add_del_route_next_hop (ip4_main_t * im, to existing non-multipath adjacency */ if (dst_adj_index == ~0 && next_hop_weight == 1 && next_hop_sw_if_index == ~0) { - /* create new adjacency */ + /* create / delete additional mapping of existing adjacency */ ip4_add_del_route_args_t a; + ip_adjacency_t * nh_adj = ip_get_adjacency (lm, nh_adj_index); + a.table_index_or_table_id = fib_index; a.flags = ((is_del ? IP4_ROUTE_FLAG_DEL : IP4_ROUTE_FLAG_ADD) | IP4_ROUTE_FLAG_FIB_INDEX @@ -419,6 +421,9 @@ ip4_add_del_route_next_hop (ip4_main_t * im, ip4_add_del_route (im, &a); + /* adjust share count. This cannot be the only use of the adjacency */ + nh_adj->share_count += is_del ? -1 : 1; + goto done; } @@ -446,6 +451,8 @@ ip4_add_del_route_next_hop (ip4_main_t * im, if (old_mp != new_mp) { ip4_add_del_route_args_t a; + ip_adjacency_t * adj; + a.table_index_or_table_id = fib_index; a.flags = ((is_del && ! new_mp ? IP4_ROUTE_FLAG_DEL : IP4_ROUTE_FLAG_ADD) | IP4_ROUTE_FLAG_FIB_INDEX @@ -458,6 +465,10 @@ ip4_add_del_route_next_hop (ip4_main_t * im, a.n_add_adj = 0; ip4_add_del_route (im, &a); + + adj = ip_get_adjacency (lm, new_mp ? new_mp->adj_index : dst_adj_index); + if (adj->n_adj == 1) + adj->share_count += is_del ? -1 : 1; } done: diff --git a/vnet/vnet/ip/ip6_forward.c b/vnet/vnet/ip/ip6_forward.c index 5ad26df97d0..ced5f562be8 100644 --- a/vnet/vnet/ip/ip6_forward.c +++ b/vnet/vnet/ip/ip6_forward.c @@ -457,8 +457,10 @@ ip6_add_del_route_next_hop (ip6_main_t * im, to existing non-multipath adjacency */ if (dst_adj_index == ~0 && next_hop_weight == 1 && next_hop_sw_if_index == ~0) { - /* create new adjacency */ + /* create / delete additional mapping of existing adjacency */ ip6_add_del_route_args_t a; + ip_adjacency_t * nh_adj = ip_get_adjacency (lm, nh_adj_index); + a.table_index_or_table_id = fib_index; a.flags = ((is_del ? IP6_ROUTE_FLAG_DEL : IP6_ROUTE_FLAG_ADD) | IP6_ROUTE_FLAG_FIB_INDEX @@ -472,6 +474,9 @@ ip6_add_del_route_next_hop (ip6_main_t * im, a.n_add_adj = 0; ip6_add_del_route (im, &a); + /* adjust share count. This cannot be the only use of the adjacency */ + nh_adj->share_count += is_del ? -1 : 1; + goto done; } @@ -500,6 +505,8 @@ ip6_add_del_route_next_hop (ip6_main_t * im, if (old_mp != new_mp) { ip6_add_del_route_args_t a; + ip_adjacency_t * adj; + a.table_index_or_table_id = fib_index; a.flags = ((is_del ? IP6_ROUTE_FLAG_DEL : IP6_ROUTE_FLAG_ADD) | IP6_ROUTE_FLAG_FIB_INDEX @@ -512,6 +519,10 @@ ip6_add_del_route_next_hop (ip6_main_t * im, a.n_add_adj = 0; ip6_add_del_route (im, &a); + + adj = ip_get_adjacency (lm, new_mp ? new_mp->adj_index : dst_adj_index); + if (adj->n_adj == 1) + adj->share_count += is_del ? -1 : 1; } done: |