Hi,
after a very brief reading of ospfd sources I think I understand
why it touches the route on the external interface. (This might be
entirely wrong, but I think it does its spf dance and then puts the
best routes into the fib wether they changed or not.)
In any case since I understand ospfd a lot less then bgpd so I decided
to change bgpd by figuring out if the nexthop actually changed or not.
There is already this comment in prefix_updateall:
/*
* The state of the nexthop did not change. The only
* thing that may have changed is the true_nexthop
* or other internal infos. This will not change
* the routing decision so shortcut here.
*/
The following patch compares true_nexthop, flags, etc with the old
values and skips prefix_updateall if noting has changed.
This is either obviously correct or horribly wrong - but it fixes the
memory consumption in rde :)
Btw. I'm not sure about the style for the sizeof(oldtrue_nexthop) in
the memcmp call, should this be indented by an additional tab?
Index: rde_rib.c
===================================================================
RCS file: /opt/OpenBSD-CVS/src/usr.sbin/bgpd/rde_rib.c,v
retrieving revision 1.132
diff -u -r1.132 rde_rib.c
--- rde_rib.c 22 May 2012 20:44:06 -0000 1.132
+++ rde_rib.c 1 Jul 2012 10:29:35 -0000
@@ -1056,8 +1056,10 @@
nexthop_update(struct kroute_nexthop *msg)
{
struct nexthop *nh;
+ struct bgpd_addr oldtrue_nexthop, oldnexthop_net;
struct rde_aspath *asp;
enum nexthop_state oldstate;
+ u_int8_t oldflags, oldnexthop_netlen;
nh = nexthop_lookup(&msg->nexthop);
if (nh == NULL) {
@@ -1067,6 +1069,10 @@
}
oldstate = nh->state;
+ oldflags = nh->flags;
+ oldnexthop_netlen = nh->nexthop_netlen;
+ memcpy(&oldtrue_nexthop, &nh->true_nexthop, sizeof(oldtrue_nexthop));
+ memcpy(&oldnexthop_net, &nh->nexthop_net, sizeof(oldnexthop_net));
if (msg->valid)
nh->state = NEXTHOP_REACH;
else
@@ -1093,6 +1099,14 @@
* if the decision process is turned off there is no need
* for the aspath list walk.
*/
+ return;
+
+ if (oldstate == nh->state && oldflags == nh->flags
+ && memcmp(&oldtrue_nexthop, &nh->true_nexthop,
+ sizeof(oldtrue_nexthop)) == 0
+ && memcmp(&oldnexthop_net, &nh->nexthop_net,
+ sizeof(oldnexthop_net)) == 0)
+ /* nexthop didn't change */
return;
LIST_FOREACH(asp, &nh->path_h, nexthop_l) {
Thanks,
Florian