diff options
author | Claudio Jeker <claudio@cvs.openbsd.org> | 2003-12-25 23:22:14 +0000 |
---|---|---|
committer | Claudio Jeker <claudio@cvs.openbsd.org> | 2003-12-25 23:22:14 +0000 |
commit | 04caca02d32d49591e39b12c20bbff3856cf7f16 (patch) | |
tree | 12bc73f6db7ed918506598fce2a810b55dab5539 /usr.sbin | |
parent | ace6e29365b585df8eba49386d9463030bd32a5c (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.h | 7 | ||||
-rw-r--r-- | usr.sbin/bgpd/rde.c | 20 | ||||
-rw-r--r-- | usr.sbin/bgpd/rde.h | 9 | ||||
-rw-r--r-- | usr.sbin/bgpd/rde_rib.c | 101 |
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); } } |