summaryrefslogtreecommitdiff
path: root/usr.sbin
diff options
context:
space:
mode:
authorClaudio Jeker <claudio@cvs.openbsd.org>2003-12-25 23:22:14 +0000
committerClaudio Jeker <claudio@cvs.openbsd.org>2003-12-25 23:22:14 +0000
commit04caca02d32d49591e39b12c20bbff3856cf7f16 (patch)
tree12bc73f6db7ed918506598fce2a810b55dab5539 /usr.sbin
parentace6e29365b585df8eba49386d9463030bd32a5c (diff)
RDE part of the nexthop verification puzzle.
The RDE just tracks the nexthop IPs and reacts on nexthop messages from the parent. ok henning@
Diffstat (limited to 'usr.sbin')
-rw-r--r--usr.sbin/bgpd/bgpd.h7
-rw-r--r--usr.sbin/bgpd/rde.c20
-rw-r--r--usr.sbin/bgpd/rde.h9
-rw-r--r--usr.sbin/bgpd/rde_rib.c101
4 files changed, 72 insertions, 65 deletions
diff --git a/usr.sbin/bgpd/bgpd.h b/usr.sbin/bgpd/bgpd.h
index be7be7af8df..c6faedb393c 100644
--- a/usr.sbin/bgpd/bgpd.h
+++ b/usr.sbin/bgpd/bgpd.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: bgpd.h,v 1.26 2003/12/25 23:15:58 henning Exp $ */
+/* $OpenBSD: bgpd.h,v 1.27 2003/12/25 23:22:13 claudio Exp $ */
/*
* Copyright (c) 2003 Henning Brauer <henning@openbsd.org>
@@ -213,7 +213,10 @@ enum imsg_type {
IMSG_MRT_MSG,
IMSG_MRT_END,
IMSG_KROUTE_CHANGE,
- IMSG_KROUTE_DELETE
+ IMSG_KROUTE_DELETE,
+ IMSG_NEXTHOP_ADD,
+ IMSG_NEXTHOP_REMOVE,
+ IMSG_NEXTHOP_UPDATE
};
struct imsg_hdr {
diff --git a/usr.sbin/bgpd/rde.c b/usr.sbin/bgpd/rde.c
index c761cbc1869..0d3e0718853 100644
--- a/usr.sbin/bgpd/rde.c
+++ b/usr.sbin/bgpd/rde.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: rde.c,v 1.29 2003/12/25 02:24:26 henning Exp $ */
+/* $OpenBSD: rde.c,v 1.30 2003/12/25 23:22:13 claudio Exp $ */
/*
* Copyright (c) 2003 Henning Brauer <henning@openbsd.org>
@@ -238,6 +238,10 @@ rde_dispatch_imsg(struct imsgbuf *ibuf, int idx)
fatal("session msg not from session engine", 0);
peer_down(imsg.hdr.peerid);
break;
+ case IMSG_NEXTHOP_UPDATE:
+ if (idx != PFD_PIPE_MAIN)
+ fatal("nexthop response not from parent", 0);
+ break;
case IMSG_MRT_REQ:
if (idx != PFD_PIPE_MAIN)
fatal("mrt request not from parent", 0);
@@ -531,6 +535,20 @@ rde_send_kroute(struct prefix *new, struct prefix *old)
}
/*
+ * nexthop specific functions
+ */
+void
+rde_send_nexthop(in_addr_t next, int valid)
+{
+ if (valid)
+ imsg_compose(&ibuf_main, IMSG_NEXTHOP_ADD, 0,
+ &next, sizeof(next));
+ else
+ imsg_compose(&ibuf_main, IMSG_NEXTHOP_REMOVE, 0,
+ &next, sizeof(next));
+}
+
+/*
* peer functions
*/
struct peer_table {
diff --git a/usr.sbin/bgpd/rde.h b/usr.sbin/bgpd/rde.h
index d76de99698f..db264c6b335 100644
--- a/usr.sbin/bgpd/rde.h
+++ b/usr.sbin/bgpd/rde.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: rde.h,v 1.6 2003/12/23 15:59:02 claudio Exp $ */
+/* $OpenBSD: rde.h,v 1.7 2003/12/25 23:22:13 claudio Exp $ */
/*
* Copyright (c) 2003 Claudio Jeker <claudio@openbsd.org> and
@@ -131,7 +131,7 @@ struct attr_flags {
enum origins origin;
struct aspath *aspath;
struct astags *astags;
- struct in_addr nexthop;
+ struct in_addr nexthop; /* exit nexthop */
u_int32_t med; /* multi exit disc */
u_int32_t lpref; /* local pref */
u_int8_t aggr_atm; /* atomic aggregate */
@@ -140,6 +140,7 @@ struct attr_flags {
};
enum nexthop_state {
+ NEXTHOP_LOOKUP,
NEXTHOP_UNREACH,
NEXTHOP_REACH
};
@@ -193,6 +194,7 @@ struct prefix {
/* prototypes */
/* rde.c */
void rde_send_kroute(struct prefix *, struct prefix *);
+void rde_send_nexthop(in_addr_t, int);
/* rde_rib.c */
int attr_equal(struct attr_flags *, struct attr_flags *);
@@ -234,8 +236,7 @@ void prefix_destroy(struct prefix *);
void nexthop_init(u_long);
void nexthop_add(struct rde_aspath *);
void nexthop_remove(struct rde_aspath *);
-void nexthop_invalidate(struct in_addr, int);
-void nexthop_validate(struct in_addr, int);
+void nexthop_update(struct kroute_nexthop *);
/* rde_decide.c */
void prefix_evaluate(struct prefix *, struct pt_entry *);
diff --git a/usr.sbin/bgpd/rde_rib.c b/usr.sbin/bgpd/rde_rib.c
index 88ee3a4c59d..556393d197f 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.6 2003/12/24 11:39:43 henning Exp $ */
+/* $OpenBSD: rde_rib.c,v 1.7 2003/12/25 23:22:13 claudio Exp $ */
/*
* Copyright (c) 2003 Claudio Jeker <claudio@openbsd.org>
@@ -60,8 +60,7 @@ struct rib_stats {
u_int64_t prefix_free;
u_int64_t nexthop_add;
u_int64_t nexthop_remove;
- u_int64_t nexthop_invalidate;
- u_int64_t nexthop_validate;
+ u_int64_t nexthop_update;
u_int64_t nexthop_get;
u_int64_t nexthop_alloc;
u_int64_t nexthop_free;
@@ -887,21 +886,29 @@ prefix_free(struct prefix *pref)
* hash table has more benefits and the table walk should not happen too often.
*/
-static struct nexthop *nexthop_get(struct in_addr);
-static void nexthop_updateall(struct in_addr, int,
- enum nexthop_state);
-static inline void nexthop_update(struct nexthop *, enum nexthop_state);
+static struct nexthop *nexthop_get(in_addr_t);
static struct nexthop *nexthop_alloc(void);
static void nexthop_free(struct nexthop *);
+/*
+ * In BGP there exist two nexthops: the exit nexthop which was announced via
+ * BGP and the true nexthop which is used in the FIB -- forward information
+ * base a.k.a kernel routing table. When sending updates it is even more
+ * confusing. In IBGP we pass the unmodified exit nexthop to the neighbors
+ * while in EBGP normaly the address of the router is sent. The exit nexthop
+ * may be passed to the external neighbor if the neighbor and the exit nexthop
+ * reside in the same subnet -- directly connected.
+ */
struct nexthop {
+ LIST_ENTRY(nexthop) nexthop_l;
enum nexthop_state state;
#if 0
u_int32_t costs;
#endif
struct aspath_head path_h;
- struct in_addr nexthop;
- LIST_ENTRY(nexthop) nexthop_l;
+ struct in_addr exit_nexthop;
+ struct in_addr true_nexthop;
+ u_int8_t connected;
};
struct nexthop_table {
@@ -910,7 +917,7 @@ struct nexthop_table {
} nexthoptable;
#define NEXTHOP_HASH(x) \
- &nexthoptable.nexthop_hashtbl[x.s_addr & nexthoptable.nexthop_hashmask]
+ &nexthoptable.nexthop_hashtbl[(x) & nexthoptable.nexthop_hashmask]
void
nexthop_init(u_long hashsize)
@@ -938,21 +945,17 @@ nexthop_add(struct rde_aspath *asp)
ENSURE(asp != NULL);
if ((nh = asp->nexthop) == NULL)
- nh = nexthop_get(asp->flags.nexthop);
+ nh = nexthop_get(asp->flags.nexthop.s_addr);
if (nh == NULL) {
nh = nexthop_alloc();
- /*
- * XXX nexthop_lookup()
- * currently I assume that the nexthop is reachable.
- * Getting that info could end with a big pain in the ass.
- */
+ //nh->state = NEXTHOP_LOOKUP;
nh->state = NEXTHOP_REACH;
- nh->nexthop = asp->flags.nexthop;
- LIST_INSERT_HEAD(NEXTHOP_HASH(asp->flags.nexthop), nh,
+ nh->exit_nexthop = asp->flags.nexthop;
+ LIST_INSERT_HEAD(NEXTHOP_HASH(asp->flags.nexthop.s_addr), nh,
nexthop_l);
+ rde_send_nexthop(nh->exit_nexthop.s_addr, 1);
}
asp->nexthop = nh;
- asp->state = nh->state;
LIST_INSERT_HEAD(&nh->path_h, asp, nexthop_l);
}
@@ -971,68 +974,50 @@ nexthop_remove(struct rde_aspath *asp)
if (LIST_EMPTY(&nh->path_h)) {
LIST_REMOVE(nh, nexthop_l);
+ rde_send_nexthop(nh->exit_nexthop.s_addr, 0);
nexthop_free(nh);
}
}
-void
-nexthop_invalidate(struct in_addr prefix, int prefixlen)
-{
- RIB_STAT(nexthop_invalidate);
-
- nexthop_updateall(prefix, prefixlen, NEXTHOP_UNREACH);
-}
-
-void
-nexthop_validate(struct in_addr prefix, int prefixlen)
-{
- RIB_STAT(nexthop_validate);
-
- nexthop_updateall(prefix, prefixlen, NEXTHOP_REACH);
-}
-
static struct nexthop *
-nexthop_get(struct in_addr nexthop)
+nexthop_get(in_addr_t nexthop)
{
struct nexthop *nh;
RIB_STAT(nexthop_get);
LIST_FOREACH(nh, NEXTHOP_HASH(nexthop), nexthop_l) {
- if (nh->nexthop.s_addr == nexthop.s_addr)
+ if (nh->exit_nexthop.s_addr == nexthop)
return nh;
}
return NULL;
}
-static void
-nexthop_updateall(struct in_addr prefix, int prefixlen,
- enum nexthop_state state)
+void
+nexthop_update(struct kroute_nexthop *msg)
{
- struct nexthop *nh;
- u_long ul;
+ struct nexthop *nh;
+ struct rde_aspath *asp;
- /* XXX probably I get shot for this code ... (: */
- prefix.s_addr >>= (32-prefixlen);
+ RIB_STAT(nexthop_update);
- for (ul = nexthoptable.nexthop_hashmask; ul >= 0; ul--) {
- LIST_FOREACH(nh, &nexthoptable.nexthop_hashtbl[ul], nexthop_l) {
- if (prefix.s_addr ==
- nh->nexthop.s_addr >> (32-prefixlen)) {
- nh->state = state;
- nexthop_update(nh, state);
- }
- }
+ nh = nexthop_get(msg->nexthop);
+ if (nh == NULL) {
+ logit(LOG_INFO, "nexthop_update: non-existent nexthop");
+ return;
}
-}
+ ENSURE(nh->exit_nexthop.s_addr == msg->nexthop);
-static inline void
-nexthop_update(struct nexthop *nh, enum nexthop_state mode)
-{
- struct rde_aspath *asp;
+ if (msg->valid)
+ nh->state = NEXTHOP_REACH;
+ else
+ nh->state = NEXTHOP_UNREACH;
+
+ nh->true_nexthop.s_addr = msg->gateway;
+ nh->connected = msg->connected;
LIST_FOREACH(asp, &nh->path_h, nexthop_l) {
- path_updateall(asp, mode);
+ path_updateall(asp, nh->state);
}
}