summaryrefslogtreecommitdiff
path: root/usr.sbin/bgpd
diff options
context:
space:
mode:
authorClaudio Jeker <claudio@cvs.openbsd.org>2004-07-30 14:44:31 +0000
committerClaudio Jeker <claudio@cvs.openbsd.org>2004-07-30 14:44:31 +0000
commit6f31625bc9c9324e216ae595bf936070a14ed0ad (patch)
treec9ea2d93a187ad06df2e36ddb687f3d2a5e42fe1 /usr.sbin/bgpd
parent306decf1e1aa0fee1e041fd60f3ddb4b1b3ec1ef (diff)
Add new announce type "default-route" which will only announce the default
route to the specified neighbor. Idea and OK henning@
Diffstat (limited to 'usr.sbin/bgpd')
-rw-r--r--usr.sbin/bgpd/bgpd.h3
-rw-r--r--usr.sbin/bgpd/parse.y5
-rw-r--r--usr.sbin/bgpd/rde.c7
-rw-r--r--usr.sbin/bgpd/rde.h3
-rw-r--r--usr.sbin/bgpd/rde_update.c95
5 files changed, 94 insertions, 19 deletions
diff --git a/usr.sbin/bgpd/bgpd.h b/usr.sbin/bgpd/bgpd.h
index ed27696b4c2..1c01fcdecbe 100644
--- a/usr.sbin/bgpd/bgpd.h
+++ b/usr.sbin/bgpd/bgpd.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: bgpd.h,v 1.136 2004/07/27 15:26:45 henning Exp $ */
+/* $OpenBSD: bgpd.h,v 1.137 2004/07/30 14:44:30 claudio Exp $ */
/*
* Copyright (c) 2003, 2004 Henning Brauer <henning@openbsd.org>
@@ -146,6 +146,7 @@ enum announce_type {
ANNOUNCE_UNDEF,
ANNOUNCE_SELF,
ANNOUNCE_NONE,
+ ANNOUNCE_DEFAULT_ROUTE,
ANNOUNCE_ALL
};
diff --git a/usr.sbin/bgpd/parse.y b/usr.sbin/bgpd/parse.y
index 6214224936f..0947501c2e7 100644
--- a/usr.sbin/bgpd/parse.y
+++ b/usr.sbin/bgpd/parse.y
@@ -1,4 +1,4 @@
-/* $OpenBSD: parse.y,v 1.127 2004/07/28 17:05:08 henning Exp $ */
+/* $OpenBSD: parse.y,v 1.128 2004/07/30 14:44:30 claudio Exp $ */
/*
* Copyright (c) 2002, 2003, 2004 Henning Brauer <henning@openbsd.org>
@@ -537,6 +537,9 @@ peeropts : REMOTEAS asnumber {
curpeer->conf.announce_type = ANNOUNCE_NONE;
else if (!strcmp($2, "all"))
curpeer->conf.announce_type = ANNOUNCE_ALL;
+ else if (!strcmp($2, "default-route"))
+ curpeer->conf.announce_type =
+ ANNOUNCE_DEFAULT_ROUTE;
else {
free($2);
YYERROR;
diff --git a/usr.sbin/bgpd/rde.c b/usr.sbin/bgpd/rde.c
index 247bd52b400..54499d1ac62 100644
--- a/usr.sbin/bgpd/rde.c
+++ b/usr.sbin/bgpd/rde.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: rde.c,v 1.129 2004/07/29 17:05:13 claudio Exp $ */
+/* $OpenBSD: rde.c,v 1.130 2004/07/30 14:44:30 claudio Exp $ */
/*
* Copyright (c) 2003, 2004 Henning Brauer <henning@openbsd.org>
@@ -1432,6 +1432,11 @@ peer_dump(u_int32_t id, u_int16_t afi, u_int8_t safi)
if (afi == AFI_ALL || afi == AFI_IPv4)
if (safi == SAFI_ALL || safi == SAFI_UNICAST ||
safi == SAFI_BOTH) {
+ if (peer->conf.announce_type ==
+ ANNOUNCE_DEFAULT_ROUTE) {
+ up_generate_default(peer, AF_INET);
+ return;
+ }
pt_dump(up_dump_upcall, peer, AF_INET);
return;
}
diff --git a/usr.sbin/bgpd/rde.h b/usr.sbin/bgpd/rde.h
index edee7b77d54..370c169c9ef 100644
--- a/usr.sbin/bgpd/rde.h
+++ b/usr.sbin/bgpd/rde.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: rde.h,v 1.46 2004/07/28 16:02:14 claudio Exp $ */
+/* $OpenBSD: rde.h,v 1.47 2004/07/30 14:44:30 claudio Exp $ */
/*
* Copyright (c) 2003, 2004 Claudio Jeker <claudio@openbsd.org> and
@@ -315,6 +315,7 @@ void up_init(struct rde_peer *);
void up_down(struct rde_peer *);
void up_generate_updates(struct rde_peer *,
struct prefix *, struct prefix *);
+void up_generate_default(struct rde_peer *, sa_family_t);
int up_dump_prefix(u_char *, int, struct uplist_prefix *,
struct rde_peer *);
int up_dump_attrnlri(u_char *, int, struct rde_peer *);
diff --git a/usr.sbin/bgpd/rde_update.c b/usr.sbin/bgpd/rde_update.c
index 5a712d28498..e44648a443e 100644
--- a/usr.sbin/bgpd/rde_update.c
+++ b/usr.sbin/bgpd/rde_update.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: rde_update.c,v 1.23 2004/07/13 17:57:20 jaredy Exp $ */
+/* $OpenBSD: rde_update.c,v 1.24 2004/07/30 14:44:30 claudio Exp $ */
/*
* Copyright (c) 2004 Claudio Jeker <claudio@openbsd.org>
@@ -233,12 +233,6 @@ up_generate_updates(struct rde_peer *peer,
if (peer->state != PEER_UP)
return;
- /*
- * Filtering should be hooked up here.
- * With filtering the decision if withdraw, update or nothing
- * needs to be done on a per peer basis -- actually per filter
- * set.
- */
if (new == NULL || new->aspath->nexthop == NULL ||
new->aspath->nexthop->state != NEXTHOP_REACH) {
@@ -261,7 +255,7 @@ up_generate_updates(struct rde_peer *peer,
if (old->aspath->peer->conf.ebgp == 0 && peer->conf.ebgp == 0) {
/*
- * redistribution rules:
+ * route reflector redistribution rules:
* 1. if announce is set -> announce
* 2. old non-client, new non-client -> no
* 3. old client, new non-client -> yes
@@ -280,6 +274,7 @@ up_generate_updates(struct rde_peer *peer,
switch (peer->conf.announce_type) {
case ANNOUNCE_UNDEF:
case ANNOUNCE_NONE:
+ case ANNOUNCE_DEFAULT_ROUTE:
return;
case ANNOUNCE_ALL:
break;
@@ -306,7 +301,7 @@ up_generate_updates(struct rde_peer *peer,
/*
* don't send messages back to originator
- * XXX this is not specified in the RFC but seems logical.
+ * NOTE this is not specified in the RFC but seems logical.
*/
if ((atr = attr_optget(&old->aspath->flags,
ATTR_ORIGINATOR_ID)) != NULL) {
@@ -330,7 +325,7 @@ up_generate_updates(struct rde_peer *peer,
/* withdraw prefix */
p = calloc(1, sizeof(struct update_prefix));
if (p == NULL)
- fatal("up_queue_update");
+ fatal("up_generate_updates");
p->prefix = addr;
p->prefixlen = old->prefix->prefixlen;
@@ -356,7 +351,7 @@ up_generate_updates(struct rde_peer *peer,
if (new->aspath->peer->conf.ebgp == 0 && peer->conf.ebgp == 0) {
/*
- * redistribution rules:
+ * route reflector redistribution rules:
* 1. if announce is set -> announce
* 2. old non-client, new non-client -> no
* 3. old client, new non-client -> yes
@@ -377,7 +372,11 @@ up_generate_updates(struct rde_peer *peer,
switch (peer->conf.announce_type) {
case ANNOUNCE_UNDEF:
case ANNOUNCE_NONE:
- up_generate_updates(peer, NULL, old);
+ case ANNOUNCE_DEFAULT_ROUTE:
+ /*
+ * no need to withdraw old prefix as this will be
+ * filtered out to.
+ */
return;
case ANNOUNCE_ALL:
break;
@@ -423,7 +422,7 @@ up_generate_updates(struct rde_peer *peer,
/*
* don't send messages back to originator
- * XXX this is not specified in the RFC but seems logical.
+ * NOTE this is not specified in the RFC but seems logical.
*/
if ((atr = attr_optget(&new->aspath->flags,
ATTR_ORIGINATOR_ID)) != NULL) {
@@ -438,11 +437,11 @@ up_generate_updates(struct rde_peer *peer,
/* generate update */
p = calloc(1, sizeof(struct update_prefix));
if (p == NULL)
- fatal("up_queue_update");
+ fatal("up_generate_updates");
a = calloc(1, sizeof(struct update_attr));
if (a == NULL)
- fatal("up_queue_update");
+ fatal("up_generate_updates");
if (up_generate_attr(peer, a, &attrs,
new->aspath->nexthop) == -1) {
@@ -468,6 +467,72 @@ up_generate_updates(struct rde_peer *peer,
}
}
+void
+up_generate_default(struct rde_peer *peer, sa_family_t af)
+{
+ struct update_attr *a;
+ struct update_prefix *p;
+ struct attr_flags attrs;
+ struct bgpd_addr addr;
+ struct nexthop nexthop;
+
+ bzero(&attrs, sizeof(attrs));
+ bzero(&addr, sizeof(addr));
+ bzero(&nexthop, sizeof(nexthop));
+
+ attrs.aspath = aspath_create(NULL, 0);
+ attrs.nexthop.s_addr = INADDR_ANY;
+ /* med = 0 */
+ attrs.lpref = DEFAULT_LPREF;
+ attrs.origin = ORIGIN_IGP;
+ TAILQ_INIT(&attrs.others);
+
+ nexthop.state = NEXTHOP_REACH;
+ nexthop.flags = NEXTHOP_ANNOUNCE;
+ nexthop.exit_nexthop.af = af;
+ nexthop.true_nexthop.af = af;
+
+ /* apply default overrides. Not yet possible */
+
+ /* filter as usual */
+ addr.af = AF_INET;
+ if (rde_filter(peer, &attrs, &addr, 0, DIR_OUT) == ACTION_DENY) {
+ attr_free(&attrs);
+ return;
+ }
+
+ /* generate update */
+ p = calloc(1, sizeof(struct update_prefix));
+ if (p == NULL)
+ fatal("up_generate_default");
+
+ a = calloc(1, sizeof(struct update_attr));
+ if (a == NULL)
+ fatal("up_generate_default");
+
+ if (up_generate_attr(peer, a, &attrs, &nexthop) == -1) {
+ log_warnx("generation of bgp path attributes failed");
+ free(a);
+ free(p);
+ return;
+ }
+
+ /*
+ * use aspath_hash as attr_hash, this may be unoptimal
+ * but currently I don't care.
+ */
+ a->attr_hash = aspath_hash(attrs.aspath);
+ p->prefix = addr;
+ p->prefixlen = 0; /* default route */
+
+ /* no longer needed */
+ attr_free(&attrs);
+
+ if (up_add(peer, p, a) == -1)
+ log_warnx("queuing update failed.");
+
+}
+
u_char up_attr_buf[4096];
int