summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--usr.sbin/bgpd/rde.c21
-rw-r--r--usr.sbin/bgpd/rde.h6
-rw-r--r--usr.sbin/bgpd/rde_decide.c124
3 files changed, 86 insertions, 65 deletions
diff --git a/usr.sbin/bgpd/rde.c b/usr.sbin/bgpd/rde.c
index 75152aec191..f79709b9058 100644
--- a/usr.sbin/bgpd/rde.c
+++ b/usr.sbin/bgpd/rde.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: rde.c,v 1.60 2004/01/11 22:08:04 henning Exp $ */
+/* $OpenBSD: rde.c,v 1.61 2004/01/13 13:18:03 claudio Exp $ */
/*
* Copyright (c) 2003, 2004 Henning Brauer <henning@openbsd.org>
@@ -627,6 +627,24 @@ rde_send_nexthop(struct bgpd_addr *next, int valid)
*/
u_char queue_buf[4096];
+void
+rde_generate_updates(struct prefix *new, struct prefix *old)
+{
+ struct rde_peer *peer;
+
+ if ((old == NULL || old->aspath->nexthop == NULL ||
+ old->aspath->nexthop->state != NEXTHOP_REACH) &&
+ (new == NULL || new->aspath->nexthop == NULL ||
+ new->aspath->nexthop->state != NEXTHOP_REACH))
+ return;
+
+ LIST_FOREACH(peer, &peerlist, peer_l) {
+ if (peer->state != PEER_UP)
+ continue;
+ up_generate_updates(peer, new, old);
+ }
+}
+
u_int16_t
rde_local_as(void)
{
@@ -796,6 +814,7 @@ peer_up(u_int32_t id, struct session_up *sup)
sizeof(peer->remote_addr));
peer->state = PEER_UP;
up_init(peer);
+ pt_dump(up_dump_upcall, peer);
}
void
diff --git a/usr.sbin/bgpd/rde.h b/usr.sbin/bgpd/rde.h
index 0848897d4b4..32ae77acef0 100644
--- a/usr.sbin/bgpd/rde.h
+++ b/usr.sbin/bgpd/rde.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: rde.h,v 1.16 2004/01/12 13:33:16 claudio Exp $ */
+/* $OpenBSD: rde.h,v 1.17 2004/01/13 13:18:03 claudio Exp $ */
/*
* Copyright (c) 2003, 2004 Claudio Jeker <claudio@openbsd.org> and
@@ -207,6 +207,7 @@ struct prefix {
/* rde.c */
void rde_send_kroute(struct prefix *, struct prefix *);
void rde_send_nexthop(struct bgpd_addr *, int);
+void rde_generate_updates(struct prefix *, struct prefix *);
u_int16_t rde_local_as(void);
/* rde_rib.c */
@@ -259,9 +260,12 @@ void nexthop_update(struct kroute_nexthop *);
void prefix_evaluate(struct prefix *, struct pt_entry *);
void up_init(struct rde_peer *);
void up_down(struct rde_peer *);
+void up_generate_updates(struct rde_peer *,
+ struct prefix *, struct prefix *);
int up_dump_prefix(u_char *, int, struct uplist_prefix *,
struct rde_peer *);
int up_dump_attrnlri(u_char *, int, struct rde_peer *);
+void up_dump_upcall(struct pt_entry *, void *);
/* rde_prefix.c */
void pt_init(void);
diff --git a/usr.sbin/bgpd/rde_decide.c b/usr.sbin/bgpd/rde_decide.c
index 4a0fda63470..35f20e972e0 100644
--- a/usr.sbin/bgpd/rde_decide.c
+++ b/usr.sbin/bgpd/rde_decide.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: rde_decide.c,v 1.17 2004/01/13 12:38:50 claudio Exp $ */
+/* $OpenBSD: rde_decide.c,v 1.18 2004/01/13 13:18:03 claudio Exp $ */
/*
* Copyright (c) 2003, 2004 Claudio Jeker <claudio@openbsd.org>
@@ -29,7 +29,6 @@
#include "session.h"
int prefix_cmp(struct prefix *, struct prefix *);
-void up_generate_updates(struct prefix *, struct prefix *);
int up_generate_attr(struct rde_peer *, struct update_attr *,
struct attr_flags *, struct nexthop *);
int up_set_prefix(u_char *, int, struct bgpd_addr *, u_int8_t);
@@ -226,7 +225,7 @@ prefix_evaluate(struct prefix *p, struct pt_entry *pte)
* has an unreachable nexthop. This decision has to be made
* by the called functions.
*/
- up_generate_updates(xp, pte->active);
+ rde_generate_updates(xp, pte->active);
rde_send_kroute(xp, pte->active);
if (xp == NULL || xp->aspath->nexthop == NULL ||
@@ -409,74 +408,64 @@ up_add(struct rde_peer *peer, struct update_prefix *p, struct update_attr *a)
}
void
-up_generate_updates(struct prefix *new, struct prefix *old)
+up_generate_updates(struct rde_peer *peer,
+ struct prefix *new, struct prefix *old)
{
- extern struct rde_peer_head peerlist;
- struct rde_peer *peer;
struct update_attr *a;
struct update_prefix *p;
- if ((old == NULL || old->aspath->nexthop == NULL ||
- old->aspath->nexthop->state != NEXTHOP_REACH) &&
- (new == NULL || new->aspath->nexthop == NULL ||
- new->aspath->nexthop->state != NEXTHOP_REACH))
- return;
+ ENSURE(peer->state == PEER_UP);
+ /*
+ * Filtering should be hooked up here.
+ * With filtering the decision if withdraw, update or nothing
+ * needs to be done on a per peer basis -- acctually per filter
+ * set.
+ */
- LIST_FOREACH(peer, &peerlist, peer_l) {
- if (peer->state != PEER_UP)
- continue;
- /*
- * Filtering should be hooked up here.
- * With filtering the decision if withdraw, update or nothing
- * needs to be done on a per peer basis -- acctually per filter
- * set.
- */
+ if (new == NULL || new->aspath->nexthop == NULL ||
+ new->aspath->nexthop->state != NEXTHOP_REACH) {
+ if (peer == old->peer)
+ /* Do not send routes back to sender */
+ return;
+
+ /* withdraw prefix */
+ p = calloc(1, sizeof(struct update_prefix));
+ if (p == NULL)
+ fatal("up_queue_update");
+
+ p->prefix = old->prefix->prefix;
+ p->prefixlen = old->prefix->prefixlen;
+ if (up_add(peer, p, NULL) == -1)
+ logit(LOG_CRIT, "queuing update failed.");
+ } else {
+ if (peer == new->peer)
+ /* Do not send routes back to sender */
+ return;
- if (new == NULL || new->aspath->nexthop == NULL ||
- new->aspath->nexthop->state != NEXTHOP_REACH) {
- if (peer == old->peer)
- /* Do not send routes back to sender */
- continue;
-
- /* withdraw prefix */
- p = calloc(1, sizeof(struct update_prefix));
- if (p == NULL)
- fatal("up_queue_update");
-
- p->prefix = old->prefix->prefix;
- p->prefixlen = old->prefix->prefixlen;
- if (up_add(peer, p, NULL) == -1)
- logit(LOG_CRIT, "queuing update failed.");
- } else {
- if (peer == new->peer)
- /* Do not send routes back to sender */
- continue;
-
- /* generate update */
- p = calloc(1, sizeof(struct update_prefix));
- if (p == NULL)
- fatal("up_queue_update");
-
- a = calloc(1, sizeof(struct update_attr));
- if (a == NULL)
- fatal("up_queue_update");
-
- if (up_generate_attr(peer, a, &new->aspath->flags,
- new->aspath->nexthop) == -1)
- logit(LOG_CRIT,
- "generation of bgp path attributes failed");
+ /* generate update */
+ p = calloc(1, sizeof(struct update_prefix));
+ if (p == NULL)
+ fatal("up_queue_update");
- /*
- * use aspath_hash as attr_hash, this may be unoptimal
- * but currently I don't care.
- */
- a->attr_hash = aspath_hash(new->aspath->flags.aspath);
- p->prefix = new->prefix->prefix;
- p->prefixlen = new->prefix->prefixlen;
+ a = calloc(1, sizeof(struct update_attr));
+ if (a == NULL)
+ fatal("up_queue_update");
- if (up_add(peer, p, a) == -1)
- logit(LOG_CRIT, "queuing update failed.");
- }
+ if (up_generate_attr(peer, a, &new->aspath->flags,
+ new->aspath->nexthop) == -1)
+ logit(LOG_CRIT,
+ "generation of bgp path attributes failed");
+
+ /*
+ * use aspath_hash as attr_hash, this may be unoptimal
+ * but currently I don't care.
+ */
+ a->attr_hash = aspath_hash(new->aspath->flags.aspath);
+ p->prefix = new->prefix->prefix;
+ p->prefixlen = new->prefix->prefixlen;
+
+ if (up_add(peer, p, a) == -1)
+ logit(LOG_CRIT, "queuing update failed.");
}
}
@@ -699,3 +688,12 @@ up_dump_attrnlri(u_char *buf, int len, struct rde_peer *peer)
return (wpos);
}
+void
+up_dump_upcall(struct pt_entry *pt, void *ptr)
+{
+ struct rde_peer *peer = ptr;
+
+ if (pt->active == NULL)
+ return;
+ up_generate_updates(peer, pt->active, NULL);
+}