]> git.ipfire.org Git - thirdparty/bird.git/commitdiff
Hostentry application locking
authorMaria Matejka <mq@ucw.cz>
Mon, 28 Aug 2023 13:36:40 +0000 (15:36 +0200)
committerMaria Matejka <mq@ucw.cz>
Tue, 29 Aug 2023 08:24:54 +0000 (10:24 +0200)
Due to a race condition between rta_apply_hostentry() and rt_update_hostentry(),
happening when a new route is inserted to a table, this commit makes it mandatory
to lock the next hop resolution table while resolving the next hop.

This may be slow, we'll fix it better in some future release

nest/rt-table.c
nest/rt.h

index c1bb1588e2561072b1257fc9a65003644c20eef0..6d99a7b3e6473f0ebae7a7f98aa0422f543d6c97 100644 (file)
@@ -3416,7 +3416,7 @@ ea_set_hostentry(ea_list **to, rtable *dep, rtable *src, ip_addr gw, ip_addr ll,
 
 
 static void
-rta_apply_hostentry(ea_list **to, struct hostentry_adata *head)
+rta_apply_hostentry(struct rtable_private *tab UNUSED, ea_list **to, struct hostentry_adata *head)
 {
   struct hostentry *he = head->he;
   u32 *labels = head->labels;
@@ -3544,7 +3544,8 @@ rt_next_hop_update_rte(rte *old, rte *new)
     return 0;
 
   *new = *old;
-  rta_apply_hostentry(&new->attrs, head);
+  RT_LOCKED(head->he->owner, tab)
+    rta_apply_hostentry(tab, &new->attrs, head);
   return 1;
 }
 
@@ -3557,7 +3558,8 @@ rt_next_hop_resolve_rte(rte *r)
 
   struct hostentry_adata *head = (struct hostentry_adata *) heea->u.ptr;
 
-  rta_apply_hostentry(&r->attrs, head);
+  RT_LOCKED(head->he->owner, tab)
+    rta_apply_hostentry(tab, &r->attrs, head);
 }
 
 #ifdef CONFIG_BGP
@@ -4875,6 +4877,7 @@ rt_get_hostentry(struct rtable_private *tab, ip_addr a, ip_addr ll, rtable *dep)
   if (!he)
   {
     he = hc_new_hostentry(hc, tab->rp, a, link, dep, k);
+    he->owner = RT_PUB(tab);
     rt_update_hostentry(tab, he);
   }
 
index 76d33ec788415ac434642eb6efdf1cba4aa0887b..a251b3a58ff810c141de66efc7efab213789ee88 100644 (file)
--- a/nest/rt.h
+++ b/nest/rt.h
@@ -489,6 +489,7 @@ struct hostentry {
   ip_addr link;                                /* (link-local) IP address of host, used as gw
                                           if host is directly attached */
   rtable *tab;                         /* Dependent table, part of key */
+  rtable *owner;                       /* Nexthop owner table */
   struct hostentry *next;              /* Next in hash chain */
   unsigned hash_key;                   /* Hash key */
   unsigned uc;                         /* Use count */