summaryrefslogtreecommitdiff
path: root/usr.sbin/bgpd
diff options
context:
space:
mode:
authorClaudio Jeker <claudio@cvs.openbsd.org>2004-02-26 16:16:42 +0000
committerClaudio Jeker <claudio@cvs.openbsd.org>2004-02-26 16:16:42 +0000
commit892286cd9843a11eba4c3219b764664e7129d166 (patch)
treed0026e2b88662dc74e6115e2357643330d0f351c /usr.sbin/bgpd
parente913099e805d9aa49ce0bdf297f4c0cf05465549 (diff)
show rib infrastructure. At least full dumps and per as dumps. Per prefix
dump need some more work. OK henning@
Diffstat (limited to 'usr.sbin/bgpd')
-rw-r--r--usr.sbin/bgpd/bgpd.h59
-rw-r--r--usr.sbin/bgpd/control.c8
-rw-r--r--usr.sbin/bgpd/rde.c130
-rw-r--r--usr.sbin/bgpd/rde.h7
-rw-r--r--usr.sbin/bgpd/rde_rib.c7
-rw-r--r--usr.sbin/bgpd/session.c18
-rw-r--r--usr.sbin/bgpd/session.h3
7 files changed, 208 insertions, 24 deletions
diff --git a/usr.sbin/bgpd/bgpd.h b/usr.sbin/bgpd/bgpd.h
index 0339b077619..6da7baca2ff 100644
--- a/usr.sbin/bgpd/bgpd.h
+++ b/usr.sbin/bgpd/bgpd.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: bgpd.h,v 1.100 2004/02/26 14:00:33 claudio Exp $ */
+/* $OpenBSD: bgpd.h,v 1.101 2004/02/26 16:16:41 claudio Exp $ */
/*
* Copyright (c) 2003, 2004 Henning Brauer <henning@openbsd.org>
@@ -215,7 +215,10 @@ enum imsg_type {
IMSG_CTL_KROUTE,
IMSG_CTL_KROUTE_ADDR,
IMSG_CTL_SHOW_NEXTHOP,
- IMSG_CTL_SHOW_INTERFACE
+ IMSG_CTL_SHOW_INTERFACE,
+ IMSG_CTL_SHOW_RIB,
+ IMSG_CTL_SHOW_RIB_AS,
+ IMSG_CTL_SHOW_RIB_PREFIX
};
struct imsg_hdr {
@@ -306,6 +309,46 @@ struct ctl_show_nexthop {
u_int8_t valid;
};
+#define F_RIB_ELIGIBLE 0x01
+#define F_RIB_ACTIVE 0x02
+#define F_RIB_INTERNAL 0x04
+#define F_RIB_ANNOUNCE 0x08
+
+struct ctl_show_rib {
+ time_t lastchange;
+ u_int32_t local_pref;
+ u_int32_t med;
+ u_int16_t prefix_cnt;
+ u_int16_t active_cnt;
+ struct bgpd_addr nexthop;
+ struct bgpd_addr prefix;
+ u_int8_t prefixlen;
+ u_int8_t origin;
+ u_int8_t flags;
+ u_int16_t aspath_len;
+ /* plus a aspath_len bytes long aspath */
+};
+
+struct ctl_show_rib_prefix {
+ time_t lastchange;
+ struct bgpd_addr prefix;
+ u_int8_t prefixlen;
+ u_int8_t flags;
+};
+
+enum as_spec {
+ AS_NONE,
+ AS_ALL,
+ AS_SOURCE,
+ AS_TRANSIT,
+ AS_EMPTY
+};
+
+struct as_filter {
+ u_int16_t as;
+ enum as_spec type;
+};
+
enum filter_actions {
ACTION_NONE,
ACTION_ALLOW,
@@ -324,13 +367,6 @@ enum from_spec {
FROM_GROUP
};
-enum as_spec {
- AS_NONE,
- AS_ALL,
- AS_SOURCE,
- AS_TRANSIT
-};
-
enum comp_ops {
OP_NONE,
OP_RANGE,
@@ -366,10 +402,7 @@ struct filter_match {
u_int8_t len_min;
u_int8_t len_max;
} prefixlen;
- struct {
- u_int16_t as;
- enum as_spec type;
- } as;
+ struct as_filter as;
};
TAILQ_HEAD(filter_head, filter_rule);
diff --git a/usr.sbin/bgpd/control.c b/usr.sbin/bgpd/control.c
index 005d75c7138..93fc06eaf1c 100644
--- a/usr.sbin/bgpd/control.c
+++ b/usr.sbin/bgpd/control.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: control.c,v 1.21 2004/02/02 23:17:34 henning Exp $ */
+/* $OpenBSD: control.c,v 1.22 2004/02/26 16:16:41 claudio Exp $ */
/*
* Copyright (c) 2003, 2004 Henning Brauer <henning@openbsd.org>
@@ -277,6 +277,12 @@ control_dispatch_msg(struct pollfd *pfd, int i)
imsg_compose_parent(imsg.hdr.type, imsg.hdr.pid,
imsg.data, imsg.hdr.len - IMSG_HEADER_SIZE);
break;
+ case IMSG_CTL_SHOW_RIB:
+ case IMSG_CTL_SHOW_RIB_AS:
+ c->ibuf.pid = imsg.hdr.pid;
+ imsg_compose_rde(imsg.hdr.type, imsg.hdr.pid,
+ imsg.data, imsg.hdr.len - IMSG_HEADER_SIZE);
+ break;
default:
break;
}
diff --git a/usr.sbin/bgpd/rde.c b/usr.sbin/bgpd/rde.c
index 38444f5a210..6322619511e 100644
--- a/usr.sbin/bgpd/rde.c
+++ b/usr.sbin/bgpd/rde.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: rde.c,v 1.88 2004/02/26 14:00:33 claudio Exp $ */
+/* $OpenBSD: rde.c,v 1.89 2004/02/26 16:16:41 claudio Exp $ */
/*
* Copyright (c) 2003, 2004 Henning Brauer <henning@openbsd.org>
@@ -45,6 +45,10 @@ 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_upcall(struct pt_entry *, void *);
+void rde_dump_as(struct as_filter *, pid_t);
void rde_update_log(const char *,
const struct rde_peer *, const struct attr_flags *,
const struct bgpd_addr *, u_int8_t);
@@ -189,6 +193,7 @@ rde_dispatch_imsg_session(struct imsgbuf *ibuf)
{
struct imsg imsg;
struct session_up sup;
+ pid_t pid;
int n;
if ((n = imsg_read(ibuf)) == -1)
@@ -215,6 +220,25 @@ rde_dispatch_imsg_session(struct imsgbuf *ibuf)
case IMSG_SESSION_DOWN:
peer_down(imsg.hdr.peerid);
break;
+ case IMSG_CTL_SHOW_RIB:
+ if (imsg.hdr.len != IMSG_HEADER_SIZE) {
+ log_warnx("rde_dispatch: wrong imsg len");
+ break;
+ }
+ pid = imsg.hdr.pid;
+ pt_dump(rde_dump_upcall, &pid);
+ imsg_compose_pid(&ibuf_se, IMSG_CTL_END, pid, NULL, 0);
+ break;
+ case IMSG_CTL_SHOW_RIB_AS:
+ if (imsg.hdr.len - IMSG_HEADER_SIZE !=
+ sizeof(struct as_filter)) {
+ log_warnx("rde_dispatch: wrong imsg len");
+ break;
+ }
+ pid = imsg.hdr.pid;
+ rde_dump_as(imsg.data, pid);
+ imsg_compose_pid(&ibuf_se, IMSG_CTL_END, pid, NULL, 0);
+ break;
default:
break;
}
@@ -571,6 +595,110 @@ rde_update_log(const char *message,
}
/*
+ * control specific functions
+ */
+void
+rde_dump_rib(struct prefix *p, pid_t pid)
+{
+ struct ctl_show_rib rib;
+ struct buf *wbuf;
+
+ rib.lastchange = p->lastchange;
+ rib.local_pref = p->aspath->flags.lpref;
+ rib.med = p->aspath->flags.med;
+ rib.prefix_cnt = p->aspath->prefix_cnt;
+ rib.active_cnt = p->aspath->active_cnt;
+ memcpy(&rib.nexthop, &p->aspath->nexthop->true_nexthop,
+ sizeof(rib.nexthop));
+ memcpy(&rib.prefix, &p->prefix->prefix, sizeof(rib.prefix));
+ rib.prefixlen = p->prefix->prefixlen;
+ rib.origin = p->aspath->flags.origin;
+ rib.flags = 0;
+ if (p->aspath->nexthop->state == NEXTHOP_REACH)
+ rib.flags |= F_RIB_ELIGIBLE;
+ if (p->prefix->active == p)
+ rib.flags |= F_RIB_ACTIVE;
+ if (p->peer->conf.ebgp == 0)
+ rib.flags |= F_RIB_INTERNAL;
+ if (p->aspath->nexthop->flags & NEXTHOP_ANNOUNCE)
+ rib.flags |= F_RIB_ANNOUNCE;
+ rib.aspath_len = aspath_length(p->aspath->flags.aspath);
+
+ if ((wbuf = imsg_create_pid(&ibuf_se, IMSG_CTL_SHOW_RIB, pid,
+ sizeof(rib) + rib.aspath_len)) == NULL) {
+ log_warnx("rde_dump_upcall: imsg_create error");
+ return;
+ }
+ if (imsg_add(wbuf, &rib, sizeof(rib)) == -1 ||
+ imsg_add(wbuf, aspath_dump(p->aspath->flags.aspath),
+ rib.aspath_len) == -1) {
+ log_warnx("rde_dump_upcall: imsg_add error");
+ return;
+ }
+ if (imsg_close(&ibuf_se, wbuf) == -1) {
+ log_warnx("rde_dump_upcall: imsg_close error");
+ return;
+ }
+}
+
+void
+rde_dump_prefix(struct prefix *p, pid_t pid)
+{
+ struct ctl_show_rib_prefix prefix;
+
+ prefix.lastchange = p->lastchange;
+ memcpy(&prefix.prefix, &p->prefix->prefix, sizeof(prefix.prefix));
+ prefix.prefixlen = p->prefix->prefixlen;
+ prefix.flags = 0;
+ if (p->aspath->nexthop->state == NEXTHOP_REACH)
+ prefix.flags |= F_RIB_ELIGIBLE;
+ if (p->prefix->active == p)
+ prefix.flags |= F_RIB_ACTIVE;
+ if (p->peer->conf.ebgp == 0)
+ prefix.flags |= F_RIB_INTERNAL;
+ if (p->aspath->nexthop->flags & NEXTHOP_ANNOUNCE)
+ prefix.flags |= F_RIB_ANNOUNCE;
+ if (imsg_compose_pid(&ibuf_se, IMSG_CTL_SHOW_RIB_PREFIX, pid,
+ &prefix, sizeof(prefix)) == -1)
+ log_warnx("rde_dump_as: imsg_compose error");
+}
+
+void
+rde_dump_upcall(struct pt_entry *pt, void *ptr)
+{
+ struct prefix *p;
+ pid_t pid;
+
+ memcpy(&pid, ptr, sizeof(pid));
+
+ LIST_FOREACH(p, &pt->prefix_h, prefix_l)
+ rde_dump_rib(p, pid);
+}
+
+void
+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;
+
+ i = pathtable.path_hashmask;
+ do {
+ LIST_FOREACH(asp, &pathtable.path_hashtbl[i], path_l) {
+ if (!aspath_match(asp->flags.aspath, a->type, a->as))
+ continue;
+ /* match found */
+ ENSURE(!LIST_EMPTY(&asp->prefix_h));
+ rde_dump_rib(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);
+ }
+ } while (i-- != 0);
+}
+
+/*
* kroute specific functions
*/
void
diff --git a/usr.sbin/bgpd/rde.h b/usr.sbin/bgpd/rde.h
index 4b173ce7b6a..7c2b2f0599f 100644
--- a/usr.sbin/bgpd/rde.h
+++ b/usr.sbin/bgpd/rde.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: rde.h,v 1.30 2004/02/26 14:00:33 claudio Exp $ */
+/* $OpenBSD: rde.h,v 1.31 2004/02/26 16:16:41 claudio Exp $ */
/*
* Copyright (c) 2003, 2004 Claudio Jeker <claudio@openbsd.org> and
@@ -168,6 +168,11 @@ struct nexthop {
#define NEXTHOP_ANNOUNCE 0x2
};
+struct path_table {
+ struct aspath_head *path_hashtbl;
+ u_int32_t path_hashmask;
+};
+
LIST_HEAD(prefix_head, prefix);
struct rde_aspath {
diff --git a/usr.sbin/bgpd/rde_rib.c b/usr.sbin/bgpd/rde_rib.c
index 31268f03876..cbaac73598f 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.35 2004/02/19 23:07:00 claudio Exp $ */
+/* $OpenBSD: rde_rib.c,v 1.36 2004/02/26 16:16:41 claudio Exp $ */
/*
* Copyright (c) 2003, 2004 Claudio Jeker <claudio@openbsd.org>
@@ -77,10 +77,7 @@ static void path_unlink(struct rde_aspath *);
static struct rde_aspath *path_alloc(void);
static void path_free(struct rde_aspath *);
-struct path_table {
- struct aspath_head *path_hashtbl;
- u_int32_t path_hashmask;
-} pathtable;
+struct path_table pathtable;
#define PATH_HASH(x) \
&pathtable.path_hashtbl[aspath_hash((x)) & pathtable.path_hashmask]
diff --git a/usr.sbin/bgpd/session.c b/usr.sbin/bgpd/session.c
index 53fec83f75b..c72b899d3c1 100644
--- a/usr.sbin/bgpd/session.c
+++ b/usr.sbin/bgpd/session.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: session.c,v 1.120 2004/02/25 19:48:18 claudio Exp $ */
+/* $OpenBSD: session.c,v 1.121 2004/02/26 16:16:41 claudio Exp $ */
/*
* Copyright (c) 2003, 2004 Henning Brauer <henning@openbsd.org>
@@ -1577,11 +1577,19 @@ session_dispatch_imsg(struct imsgbuf *ibuf, int idx)
case IMSG_CTL_KROUTE_ADDR:
case IMSG_CTL_SHOW_NEXTHOP:
case IMSG_CTL_SHOW_INTERFACE:
- case IMSG_CTL_END:
if (idx != PFD_PIPE_MAIN)
fatalx("ctl kroute request not from parent");
control_imsg_relay(&imsg);
break;
+ case IMSG_CTL_SHOW_RIB:
+ case IMSG_CTL_SHOW_RIB_PREFIX:
+ if (idx != PFD_PIPE_ROUTE)
+ fatalx("ctl rib request not from RDE");
+ control_imsg_relay(&imsg);
+ break;
+ case IMSG_CTL_END:
+ control_imsg_relay(&imsg);
+ break;
case IMSG_UPDATE:
if (idx != PFD_PIPE_ROUTE)
fatalx("update request not from RDE");
@@ -1716,6 +1724,12 @@ imsg_compose_parent(int type, pid_t pid, void *data, u_int16_t datalen)
return (imsg_compose_pid(&ibuf_main, type, pid, data, datalen));
}
+int
+imsg_compose_rde(int type, pid_t pid, void *data, u_int16_t datalen)
+{
+ return (imsg_compose_pid(&ibuf_rde, type, pid, data, datalen));
+}
+
static struct sockaddr *
addr2sa(struct bgpd_addr *addr, u_int16_t port)
{
diff --git a/usr.sbin/bgpd/session.h b/usr.sbin/bgpd/session.h
index 1868f80dd67..7968952a75c 100644
--- a/usr.sbin/bgpd/session.h
+++ b/usr.sbin/bgpd/session.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: session.h,v 1.30 2004/02/16 12:53:15 claudio Exp $ */
+/* $OpenBSD: session.h,v 1.31 2004/02/26 16:16:41 claudio Exp $ */
/*
* Copyright (c) 2003, 2004 Henning Brauer <henning@openbsd.org>
@@ -157,6 +157,7 @@ int session_main(struct bgpd_config *, struct peer *, int[2],
void bgp_fsm(struct peer *, enum session_events);
struct peer *getpeerbyip(in_addr_t);
int imsg_compose_parent(int, pid_t, void *, u_int16_t);
+int imsg_compose_rde(int, pid_t, void *, u_int16_t);
/* log.c */
void log_statechange(const struct peer *, enum session_state,