summaryrefslogtreecommitdiff
path: root/usr.sbin/bgpd/rde_rib.c
diff options
context:
space:
mode:
authorClaudio Jeker <claudio@cvs.openbsd.org>2006-01-20 16:06:13 +0000
committerClaudio Jeker <claudio@cvs.openbsd.org>2006-01-20 16:06:13 +0000
commit6d3200bf8194cf4ab129d80170fc7ccc846ae24b (patch)
tree4ada637be5719c952e20029bdf54a2d69103967d /usr.sbin/bgpd/rde_rib.c
parent440f6b4f15c12e02859a2ddc215f39b7e7978012 (diff)
Pass flags to prefix_move() so that a prefix that has both F_ORIGINAL and
F_LOCAL set can be moved correctly. This is more like a add as we have one prefix more afterwards. Looks good henning@
Diffstat (limited to 'usr.sbin/bgpd/rde_rib.c')
-rw-r--r--usr.sbin/bgpd/rde_rib.c39
1 files changed, 33 insertions, 6 deletions
diff --git a/usr.sbin/bgpd/rde_rib.c b/usr.sbin/bgpd/rde_rib.c
index b8bf8041028..2ac4b7854b1 100644
--- a/usr.sbin/bgpd/rde_rib.c
+++ b/usr.sbin/bgpd/rde_rib.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: rde_rib.c,v 1.78 2006/01/14 22:39:49 claudio Exp $ */
+/* $OpenBSD: rde_rib.c,v 1.79 2006/01/20 16:06:12 claudio Exp $ */
/*
* Copyright (c) 2003, 2004 Claudio Jeker <claudio@openbsd.org>
@@ -105,7 +105,7 @@ path_update(struct rde_peer *peer, struct rde_aspath *nasp,
/* if the prefix was found move it else add it to the aspath */
if (p != NULL)
- prefix_move(asp, p);
+ prefix_move(asp, p, F_LOCAL);
else
prefix_add(asp, prefix, prefixlen, F_LOCAL);
}
@@ -393,7 +393,7 @@ prefix_add(struct rde_aspath *asp, struct bgpd_addr *prefix, int prefixlen,
} else {
if (p->aspath != asp)
/* prefix belongs to a different aspath so move */
- return (prefix_move(asp, p));
+ return (prefix_move(asp, p, flags));
p->lastchange = time(NULL);
}
@@ -404,7 +404,7 @@ prefix_add(struct rde_aspath *asp, struct bgpd_addr *prefix, int prefixlen,
* Move the prefix to the specified as path, removes the old asp if needed.
*/
struct pt_entry *
-prefix_move(struct rde_aspath *asp, struct prefix *p)
+prefix_move(struct rde_aspath *asp, struct prefix *p, u_int32_t flags)
{
struct prefix *np;
struct rde_aspath *oasp;
@@ -418,7 +418,7 @@ prefix_move(struct rde_aspath *asp, struct prefix *p)
/* peer and prefix pointers are still equal */
np->prefix = p->prefix;
np->lastchange = time(NULL);
- np->flags = p->flags;
+ np->flags = flags;
/* add to new as path */
LIST_INSERT_HEAD(&asp->prefix_h, np, path_l);
@@ -429,6 +429,33 @@ prefix_move(struct rde_aspath *asp, struct prefix *p)
*/
/*
+ * fiddle around with the flags. If the p->flags is not equal
+ * to flags the old prefix p may not be removed but instead p->flags
+ * needs to be adjusted.
+ */
+ if (p->flags != flags) {
+ if ((p->flags & flags) == 0)
+ fatalx("prefix_move: "
+ "prefix is not part of desired RIB");
+
+ p->flags &= ~flags;
+ p->aspath->prefix_cnt--;
+ /* as before peer count needs no update because of move */
+
+ /* redo the route decision for p */
+ LIST_REMOVE(p, prefix_l);
+ /* If the prefix is the active one remove it first. */
+ if (p == p->prefix->active)
+ prefix_evaluate(NULL, p->prefix);
+ prefix_evaluate(p, p->prefix);
+
+ /* and now for np */
+ prefix_evaluate(np, np->prefix);
+
+ return (np->prefix);
+ }
+
+ /*
* First kick the old prefix node out of the prefix list,
* afterwards run the route decision for new prefix node.
* Because of this only one update is generated if the prefix
@@ -454,7 +481,7 @@ prefix_move(struct rde_aspath *asp, struct prefix *p)
if (path_empty(oasp))
path_destroy(oasp);
- return np->prefix;
+ return (np->prefix);
}
/*