VPP-179 Fix adjacency reference-count botches 58/1858/1
authorDave Barach <dave@barachs.net>
Tue, 5 Jul 2016 17:37:34 +0000 (13:37 -0400)
committerDave Barach <dave@barachs.net>
Tue, 5 Jul 2016 17:37:46 +0000 (13:37 -0400)
Change-Id: I3fe83a511064d73087c4526ef33cd7628f15b90f
Signed-off-by: Dave Barach <dave@barachs.net>
vnet/vnet/ip/ip4_forward.c
vnet/vnet/ip/ip6_forward.c

index 6008ec2..939835a 100644 (file)
@@ -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:
index 5ad26df..ced5f56 100644 (file)
@@ -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: