summaryrefslogtreecommitdiff
path: root/usr.sbin/bgpd/rde_rib.c
diff options
context:
space:
mode:
authorClaudio Jeker <claudio@cvs.openbsd.org>2004-01-17 19:35:37 +0000
committerClaudio Jeker <claudio@cvs.openbsd.org>2004-01-17 19:35:37 +0000
commit0eb529cc1daeabd034c9b73afe31ea23ca92c3b5 (patch)
tree11adc3b098f54f3a8f6e276057376871e3e6e23d /usr.sbin/bgpd/rde_rib.c
parent4178e1c718887b538c0ca3a76328d50a17abfaea (diff)
Make it possible to announce own networks. In the RDE these prefixes are
attached to a pseudo peer and inserted like all other prefixes into the RIB. OK henning@
Diffstat (limited to 'usr.sbin/bgpd/rde_rib.c')
-rw-r--r--usr.sbin/bgpd/rde_rib.c65
1 files changed, 61 insertions, 4 deletions
diff --git a/usr.sbin/bgpd/rde_rib.c b/usr.sbin/bgpd/rde_rib.c
index c3dcd2931d3..6957ded483c 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.24 2004/01/13 16:08:04 claudio Exp $ */
+/* $OpenBSD: rde_rib.c,v 1.25 2004/01/17 19:35:36 claudio Exp $ */
/*
* Copyright (c) 2003, 2004 Claudio Jeker <claudio@openbsd.org>
@@ -762,6 +762,8 @@ prefix_add(struct rde_aspath *asp, struct bgpd_addr *prefix, int prefixlen)
if (needlink == 1)
prefix_link(p, pte, asp);
+ else
+ p->lastchange = time(NULL);
return pte;
}
@@ -843,7 +845,7 @@ prefix_remove(struct rde_peer *peer, struct bgpd_addr *prefix, int prefixlen)
return;
p = prefix_bypeer(pte, peer);
- if (p == NULL) /* Got a dummy withdrawn request. */
+ if (p == NULL) /* Got a dummy withdrawn request. */
return;
asp = p->aspath;
@@ -906,6 +908,38 @@ prefix_destroy(struct prefix *p)
}
/*
+ * helper function to clean up the connected networks after a reload
+ */
+void
+prefix_network_clean(struct rde_peer *peer, time_t reloadtime)
+{
+ struct rde_aspath *asp, *xasp;
+ struct prefix *p, *xp;
+ struct pt_entry *pte;
+
+ for (asp = LIST_FIRST(&peer->path_h);
+ asp != LIST_END(&peer->path_h);
+ asp = xasp) {
+ xasp = LIST_NEXT(asp, peer_l);
+ for (p = LIST_FIRST(&asp->prefix_h);
+ p != LIST_END(&asp->prefix_h);
+ p = xp) {
+ xp = LIST_NEXT(p, path_l);
+ if (reloadtime > p->lastchange) {
+ pte = p->prefix;
+ prefix_unlink(p);
+ prefix_free(p);
+
+ if (pt_empty(pte))
+ pt_remove(pte);
+ if (path_empty(asp))
+ path_destroy(asp);
+ }
+ }
+ }
+}
+
+/*
* Link a prefix into the different parent objects.
*/
static void
@@ -1030,7 +1064,8 @@ struct nexthop_table {
void
nexthop_init(u_long hashsize)
{
- u_long hs, i;
+ struct nexthop *nh;
+ u_long hs, i;
for (hs = 1; hs < hashsize; hs <<= 1)
;
@@ -1042,6 +1077,23 @@ nexthop_init(u_long hashsize)
LIST_INIT(&nexthoptable.nexthop_hashtbl[i]);
nexthoptable.nexthop_hashmask = hs - 1;
+
+ /* add dummy entry for connected networks */
+ nh = nexthop_alloc();
+ nh->state = NEXTHOP_REACH;
+ nh->exit_nexthop.af = AF_INET;
+ nh->exit_nexthop.v4.s_addr = INADDR_ANY;
+
+ LIST_INSERT_HEAD(NEXTHOP_HASH(nh->exit_nexthop.v4.s_addr), nh,
+ nexthop_l);
+
+ memcpy(&nh->true_nexthop, &nh->exit_nexthop,
+ sizeof(nh->true_nexthop));
+ nh->nexthop_netlen = 0;
+ nh->nexthop_net.af = AF_INET;
+ nh->nexthop_net.v4.s_addr = INADDR_ANY;
+
+ nh->flags = NEXTHOP_ANNOUNCE;
}
void
@@ -1080,6 +1132,10 @@ nexthop_remove(struct rde_aspath *asp)
/* see if list is empty */
nh = asp->nexthop;
+ /* never remove the dummy announce entry */
+ if (nh->flags & NEXTHOP_ANNOUNCE)
+ return;
+
if (LIST_EMPTY(&nh->path_h)) {
LIST_REMOVE(nh, nexthop_l);
rde_send_nexthop(&nh->exit_nexthop, 0);
@@ -1132,7 +1188,8 @@ nexthop_update(struct kroute_nexthop *msg)
nh->nexthop_net.af = AF_INET;
nh->nexthop_net.v4.s_addr = msg->kr.prefix;
- nh->connected = msg->connected;
+ if (msg->connected)
+ nh->flags |= NEXTHOP_CONNECTED;
LIST_FOREACH(asp, &nh->path_h, nexthop_l) {
path_updateall(asp, nh->state);