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

Reply via email to