]> git.ipfire.org Git - thirdparty/bird.git/commitdiff
Experimental code for route servers. rsmemopt
authorOndrej Filip <feela@network.cz>
Sun, 8 Apr 2012 19:15:14 +0000 (21:15 +0200)
committerOndrej Filip <feela@network.cz>
Sun, 8 Apr 2012 19:15:14 +0000 (21:15 +0200)
nest/rt-table.c
proto/bgp/bgp.c

index 27adde16203dd4ed076962d937ecdbd5a088d614..cc7ee5e5e6a83c2e264efc12da89150f6f00f1e4 100644 (file)
@@ -134,6 +134,17 @@ rte_do_cow(rte *r)
   return e;
 }
 
+static int
+rte_same(rte *x, rte *y)
+{
+  return
+    x->attrs == y->attrs &&
+    x->flags == y->flags &&
+    x->pflags == y->pflags &&
+    x->pref == y->pref &&
+    (!x->attrs->proto->rte_same || x->attrs->proto->rte_same(x, y));
+}
+
 static int                             /* Actually better or at least as good as */
 rte_better(rte *new, rte *old)
 {
@@ -190,6 +201,7 @@ do_rte_announce(struct announce_hook *a, int type UNUSED, net *net, rte *new, rt
   struct proto_stats *stats = &p->stats;
   rte *new0 = new;
   rte *old0 = old;
+  struct rta loca;
   int ok;
 
 #ifdef CONFIG_PIPE
@@ -230,6 +242,63 @@ do_rte_announce(struct announce_hook *a, int type UNUSED, net *net, rte *new, rt
   else
     stats->exp_withdraws_received++;
 
+#ifdef CONFIG_BGP
+  if ((p->proto == &proto_bgp) && (p->accept_ra_types == RA_ANY))
+    {
+       rte *x = net->routes;
+       rte *y = net->routes;
+       rte *xbest = NULL;
+       struct ea_list *xa;
+
+       /* Route Server Client */
+
+       if (p->debug) log(L_TRACE "XXX: %s - Entering my code", p->name);
+
+       while(x)
+         {
+           y = x;
+          xa = p->make_tmp_attrs ? p->make_tmp_attrs(x, rte_update_pool) : NULL;
+           if ( filter == FILTER_ACCEPT || (!filter) || (f_run(filter, &y, &xa, rte_update_pool, FF_FORCE_TMPATTR) == F_ACCEPT))
+             {
+               if (xbest)
+                 {
+                   if (rte_better(x , xbest)) xbest = x;       // XXX HERE
+                 }
+               else xbest = x;
+             }
+           x = x->next;
+         }
+       // Now, I should have the best route that went through the filter
+       if (xbest)
+         {
+           rte_trace_out(D_ROUTES, p, xbest, "XXX: best route found");
+           if (old && rte_same(xbest, old)) { if (p->debug) log(L_TRACE "XXX: DELETING BEST ROUTE");}
+           if ((new) && rte_better(xbest, new)) { if (p->debug) log(L_TRACE "XXX: Ignoring - add"); return;} // Ignore routes worse than 'best'.
+           if ((!new) && old && rte_better(xbest, old))  { if (p->debug) log(L_TRACE "XXX: Ignoring - remove"); return;}       // Ignore routes worse than 'best'.
+
+           if (!new)
+             {
+               if (p->debug) log(L_TRACE "XXX: So I am deleting the best route, hmm");
+               memcpy(&loca, xbest->attrs, sizeof(rta));
+               loca.aflags = 0;
+               loca.eattrs = xbest->attrs->eattrs;
+               loca.hostentry = NULL;
+               new = rte_get_temp(&loca);
+               new->net = xbest->net;
+               new->pflags = 0;
+               memcpy(&(new->u), &(xbest->u), sizeof(new->u));
+               new->pref = xbest->pref;
+               new->pflags = xbest->pflags;
+             }
+         }
+       else { if (p->debug) log(L_TRACE "XXX: No best route"); }
+
+       if (p->debug) log(L_TRACE "XXX: %s - Leaving my code", p->name);
+    }
+#endif
+
+
   /*
    * This is a tricky part - we don't know whether route 'old' was
    * exported to protocol 'p' or was filtered by the export filter.
@@ -410,17 +479,6 @@ rte_free_quick(rte *e)
   sl_free(rte_slab, e);
 }
 
-static int
-rte_same(rte *x, rte *y)
-{
-  return
-    x->attrs == y->attrs &&
-    x->flags == y->flags &&
-    x->pflags == y->pflags &&
-    x->pref == y->pref &&
-    (!x->attrs->proto->rte_same || x->attrs->proto->rte_same(x, y));
-}
-
 static void
 rte_recalculate(rtable *table, net *net, struct proto *p, struct proto *src, rte *new, ea_list *tmpa)
 {
index 4d3c32fba61011de791f8857d0b7bc853cda67a1..ba28f40545cda2b5f1b9bbfd53852d326da26689 100644 (file)
@@ -924,6 +924,7 @@ bgp_init(struct proto_config *C)
   p->remote_as = c->remote_as;
   p->is_internal = (c->local_as == c->remote_as);
   p->rs_client = c->rs_client;
+  if (c->rs_client) P->accept_ra_types = RA_ANY;
   p->rr_client = c->rr_client;
   p->igp_table = get_igp_table(c);