summaryrefslogtreecommitdiff
path: root/usr.sbin/bgpd/rde.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.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.c')
-rw-r--r--usr.sbin/bgpd/rde.c81
1 files changed, 71 insertions, 10 deletions
diff --git a/usr.sbin/bgpd/rde.c b/usr.sbin/bgpd/rde.c
index 4faa851c14c..082f67df21b 100644
--- a/usr.sbin/bgpd/rde.c
+++ b/usr.sbin/bgpd/rde.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: rde.c,v 1.63 2004/01/13 13:45:49 claudio Exp $ */
+/* $OpenBSD: rde.c,v 1.64 2004/01/17 19:35:36 claudio Exp $ */
/*
* Copyright (c) 2003, 2004 Henning Brauer <henning@openbsd.org>
@@ -57,9 +57,14 @@ struct rde_peer *peer_get(u_int32_t);
void peer_up(u_int32_t, struct session_up *);
void peer_down(u_int32_t);
+void network_init(struct network_head *);
+void network_add(struct network_config *);
+
volatile sig_atomic_t rde_quit = 0;
struct bgpd_config *conf, *nconf;
+time_t reloadtime;
struct rde_peer_head peerlist;
+struct rde_peer peerself;
struct imsgbuf ibuf_se;
struct imsgbuf ibuf_main;
@@ -81,8 +86,8 @@ u_long pathhashsize = 1024;
u_long nexthophashsize = 64;
int
-rde_main(struct bgpd_config *config, struct peer *peer_l, int pipe_m2r[2],
- int pipe_s2r[2])
+rde_main(struct bgpd_config *config, struct peer *peer_l,
+ struct network_head *net_l, int pipe_m2r[2], int pipe_s2r[2])
{
pid_t pid;
struct passwd *pw;
@@ -124,13 +129,16 @@ rde_main(struct bgpd_config *config, struct peer *peer_l, int pipe_m2r[2],
close(pipe_m2r[0]);
/* initialize the RIB structures */
- peer_init(peer_l, peerhashsize);
- path_init(pathhashsize);
- nexthop_init(nexthophashsize);
- pt_init();
imsg_init(&ibuf_se, pipe_s2r[1]);
imsg_init(&ibuf_main, pipe_m2r[1]);
+ pt_init();
+ path_init(pathhashsize);
+ nexthop_init(nexthophashsize);
+ peer_init(peer_l, peerhashsize);
+
+ network_init(net_l);
+
logit(LOG_INFO, "route decision engine ready");
while (rde_quit == 0) {
@@ -235,6 +243,7 @@ rde_dispatch_imsg_parent(struct imsgbuf *ibuf)
switch (imsg.hdr.type) {
case IMSG_RECONF_CONF:
+ reloadtime = time(NULL);
if ((nconf = malloc(sizeof(struct bgpd_config))) ==
NULL)
fatal(NULL);
@@ -249,6 +258,9 @@ rde_dispatch_imsg_parent(struct imsgbuf *ibuf)
sizeof(struct peer_config));
p->conf.reconf_action = RECONF_KEEP;
break;
+ case IMSG_RECONF_NETWORK:
+ network_add(imsg.data);
+ break;
case IMSG_RECONF_DONE:
if (nconf == NULL)
fatalx("got IMSG_RECONF_DONE but no config");
@@ -270,6 +282,7 @@ rde_dispatch_imsg_parent(struct imsgbuf *ibuf)
memcpy(conf, nconf, sizeof(struct bgpd_config));
free(nconf);
nconf = NULL;
+ prefix_network_clean(&peerself, reloadtime);
logit(LOG_INFO, "RDE reconfigured");
break;
case IMSG_NEXTHOP_UPDATE:
@@ -588,13 +601,16 @@ rde_send_kroute(struct prefix *new, struct prefix *old)
enum imsg_type type;
if ((old == NULL || old->aspath->nexthop == NULL ||
- old->aspath->nexthop->state != NEXTHOP_REACH) &&
+ old->aspath->nexthop->state != NEXTHOP_REACH ||
+ old->aspath->nexthop->flags & NEXTHOP_ANNOUNCE) &&
(new == NULL || new->aspath->nexthop == NULL ||
- new->aspath->nexthop->state != NEXTHOP_REACH))
+ new->aspath->nexthop->state != NEXTHOP_REACH ||
+ new->aspath->nexthop->flags & NEXTHOP_ANNOUNCE))
return;
if (new == NULL || new->aspath->nexthop == NULL ||
- new->aspath->nexthop->state != NEXTHOP_REACH) {
+ new->aspath->nexthop->state != NEXTHOP_REACH ||
+ new->aspath->nexthop->flags & NEXTHOP_ANNOUNCE) {
type = IMSG_KROUTE_DELETE;
p = old;
kr.nexthop = 0;
@@ -853,3 +869,48 @@ peer_down(u_int32_t id)
if (peer->conf.reconf_action == RECONF_DELETE)
peer_remove(peer);
}
+
+/*
+ * network announcement stuff
+ */
+void
+network_init(struct network_head *net_l)
+{
+ struct network *n;
+
+ reloadtime = time(NULL);
+ bzero(&peerself, sizeof(peerself));
+ peerself.state = PEER_UP;
+ peerself.remote_bgpid = conf->bgpid;
+ peerself.conf.max_prefix = ULONG_MAX;
+ peerself.conf.remote_as = conf->as;
+ snprintf(peerself.conf.descr, sizeof(peerself.conf.descr),
+ "LOCAL AS %hd", conf->as);
+
+ for (n = TAILQ_FIRST(net_l); n != TAILQ_END(net_l);
+ n = TAILQ_FIRST(net_l)) {
+ TAILQ_REMOVE(net_l, n, network_l);
+ network_add(&n->net);
+ free(n);
+ }
+}
+
+void
+network_add(struct network_config *nc)
+{
+ struct attr_flags attrs;
+
+ bzero(&attrs, sizeof(attrs));
+
+ attrs.aspath = aspath_create(NULL, 0);
+ attrs.nexthop = INADDR_ANY;
+ /* med = 0 */
+ /* lpref = 0 */
+ attrs.origin = ORIGIN_IGP;
+ TAILQ_INIT(&attrs.others);
+
+ logit(LOG_DEBUG, "adding network %s/%d",
+ inet_ntoa(nc->prefix.v4), nc->prefixlen);
+ path_update(&peerself, &attrs, &nc->prefix, nc->prefixlen);
+}
+