aboutsummaryrefslogtreecommitdiffstats
path: root/vnet
diff options
context:
space:
mode:
authorDave Barach <dave@barachs.net>2016-07-05 13:37:34 -0400
committerDave Barach <dave@barachs.net>2016-07-05 13:37:46 -0400
commit2195706fef482cf7f295cd2e8c416541161c1724 (patch)
tree731767877ebea3416aedce3ffd021cdbff133b2c /vnet
parent55bf5c938585f0cc91b848ec37a5abfaf01f9515 (diff)
VPP-179 Fix adjacency reference-count botches
Change-Id: I3fe83a511064d73087c4526ef33cd7628f15b90f Signed-off-by: Dave Barach <dave@barachs.net>
Diffstat (limited to 'vnet')
-rw-r--r--vnet/vnet/ip/ip4_forward.c13
-rw-r--r--vnet/vnet/ip/ip6_forward.c13
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: