summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorClaudio Jeker <claudio@cvs.openbsd.org>2004-03-02 19:29:02 +0000
committerClaudio Jeker <claudio@cvs.openbsd.org>2004-03-02 19:29:02 +0000
commit4f66842855ac46ad2eb084b7ac5e3d7440343c43 (patch)
treec9cbd683d87cfb064aa43696b8692d4c2853a8fc
parentfd132de7c26e445b04edcaf93889474be016d485 (diff)
Framework for rib lookups by prefix. OK henning@
-rw-r--r--usr.sbin/bgpd/bgpd.h3
-rw-r--r--usr.sbin/bgpd/control.c3
-rw-r--r--usr.sbin/bgpd/rde.c70
-rw-r--r--usr.sbin/bgpd/rde_filter.c5
-rw-r--r--usr.sbin/bgpd/rde_prefix.c18
5 files changed, 77 insertions, 22 deletions
diff --git a/usr.sbin/bgpd/bgpd.h b/usr.sbin/bgpd/bgpd.h
index ff87df617c8..4220ae093ff 100644
--- a/usr.sbin/bgpd/bgpd.h
+++ b/usr.sbin/bgpd/bgpd.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: bgpd.h,v 1.102 2004/03/01 16:02:01 claudio Exp $ */
+/* $OpenBSD: bgpd.h,v 1.103 2004/03/02 19:29:01 claudio Exp $ */
/*
* Copyright (c) 2003, 2004 Henning Brauer <henning@openbsd.org>
@@ -57,6 +57,7 @@
#define F_NEXTHOP 0x08
#define F_DOWN 0x10
#define F_STATIC 0x20
+#define F_LONGER 0x40
enum {
PROC_MAIN,
diff --git a/usr.sbin/bgpd/control.c b/usr.sbin/bgpd/control.c
index a8099a3324b..7e862b42807 100644
--- a/usr.sbin/bgpd/control.c
+++ b/usr.sbin/bgpd/control.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: control.c,v 1.24 2004/02/29 22:48:01 henning Exp $ */
+/* $OpenBSD: control.c,v 1.25 2004/03/02 19:29:01 claudio Exp $ */
/*
* Copyright (c) 2003, 2004 Henning Brauer <henning@openbsd.org>
@@ -283,6 +283,7 @@ control_dispatch_msg(struct pollfd *pfd, int i)
break;
case IMSG_CTL_SHOW_RIB:
case IMSG_CTL_SHOW_RIB_AS:
+ case IMSG_CTL_SHOW_RIB_PREFIX:
c->ibuf.pid = imsg.hdr.pid;
imsg_compose_rde(imsg.hdr.type, imsg.hdr.pid,
imsg.data, imsg.hdr.len - IMSG_HEADER_SIZE);
diff --git a/usr.sbin/bgpd/rde.c b/usr.sbin/bgpd/rde.c
index 70ac977c552..b939f9452e5 100644
--- a/usr.sbin/bgpd/rde.c
+++ b/usr.sbin/bgpd/rde.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: rde.c,v 1.92 2004/03/01 16:02:01 claudio Exp $ */
+/* $OpenBSD: rde.c,v 1.93 2004/03/02 19:29:01 claudio Exp $ */
/*
* Copyright (c) 2003, 2004 Henning Brauer <henning@openbsd.org>
@@ -45,10 +45,12 @@ int rde_update_get_prefix(u_char *, u_int16_t, struct bgpd_addr *,
u_int8_t *);
void rde_update_err(struct rde_peer *, u_int8_t , u_int8_t,
void *, u_int16_t);
-void rde_dump_rib(struct prefix *, pid_t);
-void rde_dump_prefix(struct prefix *, pid_t);
+void rde_dump_rib_as(struct prefix *, pid_t);
+void rde_dump_rib_prefix(struct prefix *, pid_t);
void rde_dump_upcall(struct pt_entry *, void *);
void rde_dump_as(struct as_filter *, pid_t);
+void rde_dump_prefix_upcall(struct pt_entry *, void *);
+void rde_dump_prefix(struct ctl_show_rib_prefix *, pid_t);
void rde_update_log(const char *,
const struct rde_peer *, const struct attr_flags *,
const struct bgpd_addr *, u_int8_t);
@@ -239,6 +241,16 @@ rde_dispatch_imsg_session(struct imsgbuf *ibuf)
rde_dump_as(imsg.data, pid);
imsg_compose_pid(&ibuf_se, IMSG_CTL_END, pid, NULL, 0);
break;
+ case IMSG_CTL_SHOW_RIB_PREFIX:
+ if (imsg.hdr.len - IMSG_HEADER_SIZE !=
+ sizeof(struct ctl_show_rib_prefix)) {
+ log_warnx("rde_dispatch: wrong imsg len");
+ break;
+ }
+ pid = imsg.hdr.pid;
+ rde_dump_prefix(imsg.data, pid);
+ imsg_compose_pid(&ibuf_se, IMSG_CTL_END, pid, NULL, 0);
+ break;
default:
break;
}
@@ -604,7 +616,7 @@ rde_update_log(const char *message,
* control specific functions
*/
void
-rde_dump_rib(struct prefix *p, pid_t pid)
+rde_dump_rib_as(struct prefix *p, pid_t pid)
{
struct ctl_show_rib rib;
struct buf *wbuf;
@@ -648,7 +660,7 @@ rde_dump_rib(struct prefix *p, pid_t pid)
}
void
-rde_dump_prefix(struct prefix *p, pid_t pid)
+rde_dump_rib_prefix(struct prefix *p, pid_t pid)
{
struct ctl_show_rib_prefix prefix;
@@ -678,7 +690,7 @@ rde_dump_upcall(struct pt_entry *pt, void *ptr)
memcpy(&pid, ptr, sizeof(pid));
LIST_FOREACH(p, &pt->prefix_h, prefix_l)
- rde_dump_rib(p, pid);
+ rde_dump_rib_as(p, pid);
}
void
@@ -687,7 +699,7 @@ rde_dump_as(struct as_filter *a, pid_t pid)
extern struct path_table pathtable;
struct rde_aspath *asp;
struct prefix *p;
- u_long i;
+ u_int32_t i;
i = pathtable.path_hashmask;
do {
@@ -696,14 +708,54 @@ rde_dump_as(struct as_filter *a, pid_t pid)
continue;
/* match found */
ENSURE(!path_empty(asp));
- rde_dump_rib(LIST_FIRST(&asp->prefix_h), pid);
+ rde_dump_rib_as(LIST_FIRST(&asp->prefix_h), pid);
for (p = LIST_NEXT(LIST_FIRST(&asp->prefix_h), path_l);
p != NULL; p = LIST_NEXT(p, path_l))
- rde_dump_prefix(p, pid);
+ rde_dump_rib_prefix(p, pid);
}
} while (i-- != 0);
}
+void
+rde_dump_prefix_upcall(struct pt_entry *pt, void *ptr)
+{
+ struct {
+ pid_t pid;
+ struct ctl_show_rib_prefix *pref;
+ } *ctl = ptr;
+ struct prefix *p;
+ in_addr_t mask;
+
+ mask = htonl(0xffffffff << (32 - ctl->pref->prefixlen));
+ if (ctl->pref->prefixlen <= pt->prefixlen &&
+ (ctl->pref->prefix.v4.s_addr & mask) ==
+ (pt->prefix.v4.s_addr & mask))
+ LIST_FOREACH(p, &pt->prefix_h, prefix_l)
+ rde_dump_rib_as(p, ctl->pid);
+}
+
+void
+rde_dump_prefix(struct ctl_show_rib_prefix *pref, pid_t pid)
+{
+ struct pt_entry *pt;
+ struct {
+ pid_t pid;
+ struct ctl_show_rib_prefix *pref;
+ } ctl;
+
+ if (pref->prefixlen == 32) {
+ if ((pt = pt_lookup(&pref->prefix)) != NULL)
+ rde_dump_upcall(pt, &pid);
+ } else if (pref->flags & F_LONGER) {
+ ctl.pid = pid;
+ ctl.pref = pref;
+ pt_dump(rde_dump_prefix_upcall, &ctl);
+ } else {
+ if ((pt = pt_get(&pref->prefix, pref->prefixlen)) != NULL)
+ rde_dump_upcall(pt, &pid);
+ }
+}
+
/*
* kroute specific functions
*/
diff --git a/usr.sbin/bgpd/rde_filter.c b/usr.sbin/bgpd/rde_filter.c
index ff720878608..328283df97f 100644
--- a/usr.sbin/bgpd/rde_filter.c
+++ b/usr.sbin/bgpd/rde_filter.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: rde_filter.c,v 1.5 2004/03/01 23:07:09 deraadt Exp $ */
+/* $OpenBSD: rde_filter.c,v 1.6 2004/03/02 19:29:01 claudio Exp $ */
/*
* Copyright (c) 2004 Claudio Jeker <claudio@openbsd.org>
@@ -91,8 +91,7 @@ rde_filter_match(struct filter_rule *f, struct attr_flags *attrs,
f->match.prefix.addr.af == prefix->af) {
switch (f->match.prefix.addr.af) {
case AF_INET:
- mask = 0xffffffff << (32 - f->match.prefix.len);
- mask = htonl(mask);
+ mask = htonl(0xffffffff << (32 - f->match.prefix.len));
if ((prefix->v4.s_addr & mask) !=
(f->match.prefix.addr.v4.s_addr & mask))
return (0);
diff --git a/usr.sbin/bgpd/rde_prefix.c b/usr.sbin/bgpd/rde_prefix.c
index 9a0e9a9a95b..3fc87522bcc 100644
--- a/usr.sbin/bgpd/rde_prefix.c
+++ b/usr.sbin/bgpd/rde_prefix.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: rde_prefix.c,v 1.10 2004/02/09 01:56:18 henning Exp $ */
+/* $OpenBSD: rde_prefix.c,v 1.11 2004/03/02 19:29:01 claudio Exp $ */
/*
* Copyright (c) 2003, 2004 Claudio Jeker <claudio@openbsd.org>
@@ -182,22 +182,24 @@ pt_remove(struct pt_entry *pte)
struct pt_entry *
pt_lookup(struct bgpd_addr *prefix)
{
+ struct bgpd_addr pmasked;
struct pt_entry *p;
+ u_int32_t addr_hbo;
int i;
PT_STAT(pt_lookup);
+ bzero(&pmasked, sizeof(pmasked));
+ pmasked.af = AF_INET;
+ addr_hbo = ntohl(prefix->v4.s_addr);
for (i = MAX_PREFIX; i >= MIN_PREFIX; i--) {
- p = pt_get(prefix, i);
+ pmasked.v4.s_addr = htonl(addr_hbo & (0xffffffff << (32 - i)));
+ p = pt_get(&pmasked, i);
if (p != NULL)
- return p;
+ return (p);
}
- return NULL;
+ return (NULL);
}
-/*
- * XXX We need a redblack tree to get an ordered output.
- * XXX A nicer upcall interface wouldn't be luxus too.
- */
void
pt_dump(void (*upcall)(struct pt_entry *, void *), void *arg)
{