summaryrefslogtreecommitdiff
path: root/usr.sbin/bgpd
diff options
context:
space:
mode:
authorHenning Brauer <henning@cvs.openbsd.org>2004-01-09 13:47:09 +0000
committerHenning Brauer <henning@cvs.openbsd.org>2004-01-09 13:47:09 +0000
commit715650b30ccfc3f0aa534bc491db3fab23f000c1 (patch)
tree2d98a017e1af53f36e45edd0cc711283193de8de /usr.sbin/bgpd
parent7333e1e290962bbaaf8ff960f0c9c46a44ada85c (diff)
get us a stateful imsg relaying framework, and the first receiver,
IMSG_CTL_KROUTE, to have the kroute structs forming the fib sent to a control socket. ok claudio@
Diffstat (limited to 'usr.sbin/bgpd')
-rw-r--r--usr.sbin/bgpd/bgpd.c16
-rw-r--r--usr.sbin/bgpd/bgpd.h19
-rw-r--r--usr.sbin/bgpd/control.c32
-rw-r--r--usr.sbin/bgpd/imsg.c21
-rw-r--r--usr.sbin/bgpd/kroute.c89
-rw-r--r--usr.sbin/bgpd/session.c11
-rw-r--r--usr.sbin/bgpd/session.h4
7 files changed, 138 insertions, 54 deletions
diff --git a/usr.sbin/bgpd/bgpd.c b/usr.sbin/bgpd/bgpd.c
index f4eca515f70..173ea585360 100644
--- a/usr.sbin/bgpd/bgpd.c
+++ b/usr.sbin/bgpd/bgpd.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: bgpd.c,v 1.59 2004/01/08 16:17:12 henning Exp $ */
+/* $OpenBSD: bgpd.c,v 1.60 2004/01/09 13:47:07 henning Exp $ */
/*
* Copyright (c) 2003, 2004 Henning Brauer <henning@openbsd.org>
@@ -437,6 +437,12 @@ dispatch_imsg(struct imsgbuf *ibuf, int idx, struct mrt_head *mrtc)
else
kr_fib_decouple();
break;
+ case IMSG_CTL_KROUTE:
+ if (idx != PFD_PIPE_SESSION)
+ logit(LOG_CRIT, "kroute request not from SE");
+ else
+ kr_show_route(imsg.hdr.pid);
+ break;
default:
break;
}
@@ -467,3 +473,11 @@ send_nexthop_update(struct kroute_nexthop *msg)
msg, sizeof(struct kroute_nexthop)) == -1)
quit = 1;
}
+
+void
+send_imsg_session(int type, pid_t pid, void *data, u_int16_t datalen)
+{
+ imsg_compose_pid(&ibuf_se, type, pid, data, datalen);
+}
+
+
diff --git a/usr.sbin/bgpd/bgpd.h b/usr.sbin/bgpd/bgpd.h
index a1f8eb87f73..dcbbb74d2da 100644
--- a/usr.sbin/bgpd/bgpd.h
+++ b/usr.sbin/bgpd/bgpd.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: bgpd.h,v 1.58 2004/01/08 16:17:12 henning Exp $ */
+/* $OpenBSD: bgpd.h,v 1.59 2004/01/09 13:47:07 henning Exp $ */
/*
* Copyright (c) 2003, 2004 Henning Brauer <henning@openbsd.org>
@@ -48,6 +48,12 @@
#define SOCKET_NAME "/var/run/bgpd.sock"
+#define F_BGPD_INSERTED 0x0001
+#define F_KERNEL 0x0002
+#define F_CONNECTED 0x0004
+#define F_NEXTHOP 0x0008
+#define F_DOWN 0x0010
+
enum {
PROC_MAIN,
PROC_SE,
@@ -124,6 +130,7 @@ struct peer_config {
struct imsgbuf {
int sock;
+ pid_t pid;
struct buf_read r;
struct msgbuf w;
};
@@ -151,13 +158,15 @@ enum imsg_type {
IMSG_CTL_FIB_COUPLE,
IMSG_CTL_FIB_DECOUPLE,
IMSG_CTL_NEIGHBOR_UP,
- IMSG_CTL_NEIGHBOR_DOWN
+ IMSG_CTL_NEIGHBOR_DOWN,
+ IMSG_CTL_KROUTE
};
struct imsg_hdr {
enum imsg_type type;
u_int16_t len;
u_int32_t peerid;
+ pid_t pid;
};
struct imsg {
@@ -187,6 +196,8 @@ struct kroute {
in_addr_t prefix;
u_int8_t prefixlen;
in_addr_t nexthop;
+ u_int8_t flags;
+ u_short ifindex;
};
struct kroute_nexthop {
@@ -199,6 +210,7 @@ struct kroute_nexthop {
/* prototypes */
/* bgpd.c */
void send_nexthop_update(struct kroute_nexthop *);
+void send_imsg_session(int, pid_t, void *, u_int16_t);
/* buffer.c */
struct buf *buf_open(ssize_t);
@@ -230,6 +242,7 @@ void imsg_init(struct imsgbuf *, int);
int imsg_read(struct imsgbuf *);
int imsg_get(struct imsgbuf *, struct imsg *);
int imsg_compose(struct imsgbuf *, int, u_int32_t, void *, u_int16_t);
+int imsg_compose_pid(struct imsgbuf *, int, pid_t, void *, u_int16_t);
void imsg_free(struct imsg *);
/* kroute.c */
@@ -242,9 +255,11 @@ void kr_fib_decouple(void);
int kr_dispatch_msg(void);
int kr_nexthop_add(in_addr_t);
void kr_nexthop_delete(in_addr_t);
+void kr_show_route(pid_t);
/* control.c */
int control_init(void);
void control_cleanup(void);
+int control_imsg_relay(struct imsg *);
#endif /* __BGPD_H__ */
diff --git a/usr.sbin/bgpd/control.c b/usr.sbin/bgpd/control.c
index b889e491834..817dca5969a 100644
--- a/usr.sbin/bgpd/control.c
+++ b/usr.sbin/bgpd/control.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: control.c,v 1.13 2004/01/09 13:14:25 henning Exp $ */
+/* $OpenBSD: control.c,v 1.14 2004/01/09 13:47:07 henning Exp $ */
/*
* Copyright (c) 2003, 2004 Henning Brauer <henning@openbsd.org>
@@ -35,6 +35,7 @@ struct {
} control_state;
struct ctl_conn *control_connbyfd(int);
+struct ctl_conn *control_connbypid(pid_t);
int
control_init(void)
@@ -150,6 +151,18 @@ control_connbyfd(int fd)
return (c);
}
+struct ctl_conn *
+control_connbypid(pid_t pid)
+{
+ struct ctl_conn *c;
+
+ for (c = TAILQ_FIRST(&ctl_conns); c != NULL && c->ibuf.pid != pid;
+ c = TAILQ_NEXT(c, entries))
+ ; /* nothing */
+
+ return (c);
+}
+
void
control_close(int fd)
{
@@ -253,6 +266,11 @@ control_dispatch_msg(struct pollfd *pfd, int i)
logit(LOG_CRIT, "got IMSG_CTL_NEIGHBOR_DOWN "
"with wrong length");
break;
+ case IMSG_CTL_KROUTE:
+ c->ibuf.pid = imsg.hdr.pid;
+ imsg_compose_parent(IMSG_CTL_KROUTE, imsg.hdr.pid,
+ imsg.data, imsg.hdr.len - IMSG_HEADER_SIZE);
+ break;
default:
break;
}
@@ -261,3 +279,15 @@ control_dispatch_msg(struct pollfd *pfd, int i)
return (0);
}
+
+int
+control_imsg_relay(struct imsg *imsg)
+{
+ struct ctl_conn *c;
+
+ if ((c = control_connbypid(imsg->hdr.pid)) == NULL)
+ return (0);
+
+ return (imsg_compose_pid(&c->ibuf, imsg->hdr.type, imsg->hdr.pid,
+ imsg->data, imsg->hdr.len - IMSG_HEADER_SIZE));
+}
diff --git a/usr.sbin/bgpd/imsg.c b/usr.sbin/bgpd/imsg.c
index ec5b21a4b0d..94c6e52a0c0 100644
--- a/usr.sbin/bgpd/imsg.c
+++ b/usr.sbin/bgpd/imsg.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: imsg.c,v 1.19 2004/01/06 03:43:50 henning Exp $ */
+/* $OpenBSD: imsg.c,v 1.20 2004/01/09 13:47:07 henning Exp $ */
/*
* Copyright (c) 2003, 2004 Henning Brauer <henning@openbsd.org>
@@ -25,6 +25,9 @@
#include "bgpd.h"
+int imsg_compose_core(struct imsgbuf *, int, u_int32_t, void *, u_int16_t,
+ pid_t);
+
void
imsg_init(struct imsgbuf *ibuf, int sock)
{
@@ -32,6 +35,7 @@ imsg_init(struct imsgbuf *ibuf, int sock)
bzero(&ibuf->r, sizeof(ibuf->r));
ibuf->sock = sock;
ibuf->w.sock = sock;
+ ibuf->pid = getpid();
}
int
@@ -92,8 +96,22 @@ imsg_get(struct imsgbuf *ibuf, struct imsg *imsg)
int
imsg_compose(struct imsgbuf *ibuf, int type, u_int32_t peerid, void *data,
+ u_int16_t dlen)
+{
+ return (imsg_compose_core(ibuf, type, peerid, data, dlen, ibuf->pid));
+}
+
+int
+imsg_compose_pid(struct imsgbuf *ibuf, int type, pid_t pid, void *data,
u_int16_t datalen)
{
+ return (imsg_compose_core(ibuf, type, 0, data, datalen, pid));
+}
+
+int
+imsg_compose_core(struct imsgbuf *ibuf, int type, u_int32_t peerid, void *data,
+ u_int16_t datalen, pid_t pid)
+{
struct buf *wbuf;
struct imsg_hdr hdr;
int n;
@@ -101,6 +119,7 @@ imsg_compose(struct imsgbuf *ibuf, int type, u_int32_t peerid, void *data,
hdr.len = datalen + IMSG_HEADER_SIZE;
hdr.type = type;
hdr.peerid = peerid;
+ hdr.pid = pid;
wbuf = buf_open(hdr.len);
if (wbuf == NULL) {
logit(LOG_CRIT, "imsg_compose: buf_open error");
diff --git a/usr.sbin/bgpd/kroute.c b/usr.sbin/bgpd/kroute.c
index 47175ab392c..4ed39d2bd1d 100644
--- a/usr.sbin/bgpd/kroute.c
+++ b/usr.sbin/bgpd/kroute.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: kroute.c,v 1.58 2004/01/09 01:23:12 henning Exp $ */
+/* $OpenBSD: kroute.c,v 1.59 2004/01/09 13:47:07 henning Exp $ */
/*
* Copyright (c) 2003, 2004 Henning Brauer <henning@openbsd.org>
@@ -45,8 +45,6 @@ struct {
struct kroute_node {
RB_ENTRY(kroute_node) entry;
struct kroute r;
- u_int8_t flags;
- u_short ifindex;
};
struct knexthop_node {
@@ -116,13 +114,6 @@ RB_HEAD(kif_tree, kif_node) kif_tree, kit;
RB_PROTOTYPE(kif_tree, kif_node, entry, kif_compare);
RB_GENERATE(kif_tree, kif_node, entry, kif_compare);
-#define F_BGPD_INSERTED 0x0001
-#define F_KERNEL 0x0002
-#define F_CONNECTED 0x0004
-#define F_NEXTHOP 0x0008
-#define F_DOWN 0x0010
-
-
/*
* exported functions
*/
@@ -171,7 +162,7 @@ kr_change(struct kroute *kroute)
if ((kr = kroute_find(kroute->prefix, kroute->prefixlen)) !=
NULL) {
- if (kr->flags & F_BGPD_INSERTED)
+ if (kr->r.flags & F_BGPD_INSERTED)
action = RTM_CHANGE;
else /* a non-bgp route already exists. not a problem */
return (0);
@@ -188,7 +179,7 @@ kr_change(struct kroute *kroute)
kr->r.prefix = kroute->prefix;
kr->r.prefixlen = kroute->prefixlen;
kr->r.nexthop = kroute->nexthop;
- kr->flags = F_BGPD_INSERTED;
+ kr->r.flags = F_BGPD_INSERTED;
if (kroute_insert(kr) == -1)
free(kr);
@@ -206,7 +197,7 @@ kr_delete(struct kroute *kroute)
if ((kr = kroute_find(kroute->prefix, kroute->prefixlen)) == NULL)
return (0);
- if (!(kr->flags & F_BGPD_INSERTED))
+ if (!(kr->r.flags & F_BGPD_INSERTED))
return (0);
if (send_rtmsg(kr_state.fd, RTM_DELETE, kroute) == -1)
@@ -235,7 +226,7 @@ kr_fib_couple(void)
kr_state.fib_sync = 1;
RB_FOREACH(kr, kroute_tree, &krt)
- if ((kr->flags & F_BGPD_INSERTED))
+ if ((kr->r.flags & F_BGPD_INSERTED))
send_rtmsg(kr_state.fd, RTM_ADD, &kr->r);
logit(LOG_INFO, "kernel routing table coupled");
@@ -250,7 +241,7 @@ kr_fib_decouple(void)
return;
RB_FOREACH(kr, kroute_tree, &krt)
- if ((kr->flags & F_BGPD_INSERTED))
+ if ((kr->r.flags & F_BGPD_INSERTED))
send_rtmsg(kr_state.fd, RTM_DELETE, &kr->r);
kr_state.fib_sync = 0;
@@ -277,7 +268,7 @@ kr_nexthop_add(in_addr_t key)
nh.nexthop = key;
if (h->kroute != NULL) {
nh.valid = 1;
- nh.connected = h->kroute->flags & F_CONNECTED;
+ nh.connected = h->kroute->r.flags & F_CONNECTED;
nh.gateway = h->kroute->r.nexthop;
}
send_nexthop_update(&nh);
@@ -306,6 +297,16 @@ kr_nexthop_delete(in_addr_t key)
knexthop_remove(kn);
}
+void
+kr_show_route(pid_t pid)
+{
+ struct kroute_node *kr;
+
+ RB_FOREACH(kr, kroute_tree, &krt)
+ send_imsg_session(IMSG_CTL_KROUTE, pid, &kr->r, sizeof(kr->r));
+
+ send_imsg_session(IMSG_CTL_END, pid, NULL, 0);
+}
/*
* RB-tree compare functions
@@ -366,14 +367,14 @@ kroute_insert(struct kroute_node *kr)
return (-1);
}
- if (kr->flags & F_KERNEL) {
+ if (kr->r.flags & F_KERNEL) {
mask = 0xffffffff << (32 - kr->r.prefixlen);
ina = ntohl(kr->r.prefix);
RB_FOREACH(h, knexthop_tree, &knt)
if ((ntohl(h->nexthop) & mask) == ina)
knexthop_validate(h);
- if (kr->flags & F_CONNECTED)
+ if (kr->r.flags & F_CONNECTED)
if (kif_kr_insert(kr) == -1)
return (-1);
}
@@ -392,12 +393,12 @@ kroute_remove(struct kroute_node *kr)
}
/* check wether a nexthop depends on this kroute */
- if ((kr->flags & F_KERNEL) && (kr->flags & F_NEXTHOP))
+ if ((kr->r.flags & F_KERNEL) && (kr->r.flags & F_NEXTHOP))
RB_FOREACH(s, knexthop_tree, &knt)
if (s->kroute == kr)
knexthop_validate(s);
- if (kr->flags & F_CONNECTED)
+ if (kr->r.flags & F_CONNECTED)
if (kif_kr_remove(kr) == -1) {
free(kr);
return (-1);
@@ -483,9 +484,9 @@ kif_kr_insert(struct kroute_node *kr)
struct kif_node *kif;
struct kif_kr *kkr;
- if ((kif = kif_find(kr->ifindex)) == NULL) {
+ if ((kif = kif_find(kr->r.ifindex)) == NULL) {
logit(LOG_CRIT, "interface with index %u not found",
- kr->ifindex);
+ kr->r.ifindex);
return (0);
}
@@ -507,9 +508,9 @@ kif_kr_remove(struct kroute_node *kr)
struct kif_node *kif;
struct kif_kr *kkr;
- if ((kif = kif_find(kr->ifindex)) == NULL) {
+ if ((kif = kif_find(kr->r.ifindex)) == NULL) {
logit(LOG_CRIT, "interface with index %u not found",
- kr->ifindex);
+ kr->r.ifindex);
return (0);
}
@@ -519,7 +520,7 @@ kif_kr_remove(struct kroute_node *kr)
if (kkr == NULL) {
logit(LOG_CRIT, "can't remove connected route from interface "
- "with index %u: not found", kr->ifindex);
+ "with index %u: not found", kr->r.ifindex);
return (-1);
}
@@ -540,7 +541,7 @@ knexthop_validate(struct knexthop_node *kn)
struct kroute_nexthop n;
int was_valid = 0;
- if (kn->kroute != NULL && (!(kn->kroute->flags & F_DOWN)))
+ if (kn->kroute != NULL && (!(kn->kroute->r.flags & F_DOWN)))
was_valid = 1;
bzero(&n, sizeof(n));
@@ -551,13 +552,13 @@ knexthop_validate(struct knexthop_node *kn)
if (was_valid)
send_nexthop_update(&n);
} else { /* found match */
- if (kr->flags & F_DOWN) { /* but is down */
+ if (kr->r.flags & F_DOWN) { /* but is down */
if (was_valid)
send_nexthop_update(&n);
} else { /* valid route */
if (!was_valid) {
n.valid = 1;
- n.connected = kr->flags & F_CONNECTED;
+ n.connected = kr->r.flags & F_CONNECTED;
n.gateway = kr->r.nexthop;
send_nexthop_update(&n);
}
@@ -592,7 +593,7 @@ void
kroute_attach_nexthop(struct knexthop_node *kn, struct kroute_node *kr)
{
kn->kroute = kr;
- kr->flags |= F_NEXTHOP;
+ kr->r.flags |= F_NEXTHOP;
}
void
@@ -613,7 +614,7 @@ kroute_detach_nexthop(struct knexthop_node *kn)
; /* nothing */
if (s == NULL)
- kn->kroute->flags &= ~F_NEXTHOP;
+ kn->kroute->r.flags &= ~F_NEXTHOP;
kn->kroute = NULL;
}
@@ -636,7 +637,7 @@ protect_lo(void)
kr->r.prefix = inet_addr("127.0.0.1");
kr->r.prefixlen = 8;
kr->r.nexthop = 0;
- kr->flags = F_KERNEL|F_CONNECTED;
+ kr->r.flags = F_KERNEL|F_CONNECTED;
if (RB_INSERT(kroute_tree, &krt, kr) != NULL)
free(kr); /* kernel route already there, no problem */
@@ -704,15 +705,15 @@ if_change(u_short ifindex, int flags)
LIST_FOREACH(kkr, &kif->kroute_l, entry) {
if (flags & IFF_UP)
- kkr->kr->flags &= ~F_DOWN;
+ kkr->kr->r.flags &= ~F_DOWN;
else
- kkr->kr->flags |= F_DOWN;
+ kkr->kr->r.flags |= F_DOWN;
RB_FOREACH(n, knexthop_tree, &knt)
if (n->kroute == kkr->kr) {
bzero(&nh, sizeof(nh));
nh.nexthop = n->nexthop;
- if (!(kkr->kr->flags & F_DOWN)) {
+ if (!(kkr->kr->r.flags & F_DOWN)) {
nh.valid = 1;
nh.connected = 1;
nh.gateway = kkr->kr->r.nexthop;
@@ -840,7 +841,7 @@ fetchtable(void)
return (-1);
}
- kr->flags = F_KERNEL;
+ kr->r.flags = F_KERNEL;
switch (sa->sa_family) {
case AF_INET:
@@ -870,8 +871,8 @@ fetchtable(void)
((struct sockaddr_in *)sa)->sin_addr.s_addr;
break;
case AF_LINK:
- kr->flags |= F_CONNECTED;
- kr->ifindex = rtm->rtm_index;
+ kr->r.flags |= F_CONNECTED;
+ kr->r.ifindex = rtm->rtm_index;
break;
}
@@ -1026,17 +1027,17 @@ dispatch_rtmsg(void)
if ((kr = kroute_find(prefix, prefixlen)) !=
NULL) {
- if (kr->flags & F_KERNEL) {
+ if (kr->r.flags & F_KERNEL) {
kr->r.nexthop = nexthop;
- if (kr->flags & F_NEXTHOP)
+ if (kr->r.flags & F_NEXTHOP)
flags |= F_NEXTHOP;
- if ((kr->flags & F_CONNECTED) &&
+ if ((kr->r.flags & F_CONNECTED) &&
!(flags & F_CONNECTED))
kif_kr_remove(kr);
if ((flags & F_CONNECTED) &&
- !(kr->flags & F_CONNECTED))
+ !(kr->r.flags & F_CONNECTED))
kif_kr_insert(kr);
- kr->flags = flags;
+ kr->r.flags = flags;
}
} else {
if ((kr = calloc(1,
@@ -1047,7 +1048,7 @@ dispatch_rtmsg(void)
kr->r.prefix = prefix;
kr->r.prefixlen = prefixlen;
kr->r.nexthop = nexthop;
- kr->flags = flags;
+ kr->r.flags = flags;
kroute_insert(kr);
}
@@ -1055,7 +1056,7 @@ dispatch_rtmsg(void)
case RTM_DELETE:
if ((kr = kroute_find(prefix, prefixlen)) == NULL)
continue;
- if (!(kr->flags & F_KERNEL))
+ if (!(kr->r.flags & F_KERNEL))
continue;
if (kroute_remove(kr) == -1)
return (-1);
diff --git a/usr.sbin/bgpd/session.c b/usr.sbin/bgpd/session.c
index 1bb6355c5f6..1a3fc706951 100644
--- a/usr.sbin/bgpd/session.c
+++ b/usr.sbin/bgpd/session.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: session.c,v 1.75 2004/01/09 13:38:39 henning Exp $ */
+/* $OpenBSD: session.c,v 1.76 2004/01/09 13:47:08 henning Exp $ */
/*
* Copyright (c) 2003, 2004 Henning Brauer <henning@openbsd.org>
@@ -1410,6 +1410,11 @@ session_dispatch_imsg(struct imsgbuf *ibuf, int idx)
bzero(&mrt_allin, sizeof(mrt_allin));
}
break;
+ case IMSG_CTL_KROUTE:
+ case IMSG_CTL_END:
+ if (idx != PFD_PIPE_MAIN)
+ fatalx("reconf request not from parent");
+ control_imsg_relay(&imsg);
default:
break;
}
@@ -1449,7 +1454,7 @@ session_up(struct peer *peer)
}
int
-imsg_compose_parent(int type, u_int32_t peerid, void *data, u_int16_t datalen)
+imsg_compose_parent(int type, pid_t pid, void *data, u_int16_t datalen)
{
- return (imsg_compose(&ibuf_main, type, peerid, data, datalen));
+ return (imsg_compose_pid(&ibuf_main, type, pid, data, datalen));
}
diff --git a/usr.sbin/bgpd/session.h b/usr.sbin/bgpd/session.h
index 668e46d6d7a..777a2e49585 100644
--- a/usr.sbin/bgpd/session.h
+++ b/usr.sbin/bgpd/session.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: session.h,v 1.16 2004/01/06 23:14:58 henning Exp $ */
+/* $OpenBSD: session.h,v 1.17 2004/01/09 13:47:08 henning Exp $ */
/*
* Copyright (c) 2003, 2004 Henning Brauer <henning@openbsd.org>
@@ -157,7 +157,7 @@ int session_main(struct bgpd_config *, struct peer *, int[2],
int[2]);
void bgp_fsm(struct peer *, enum session_events);
struct peer *getpeerbyip(in_addr_t);
-int imsg_compose_parent(int, u_int32_t, void *, u_int16_t);
+int imsg_compose_parent(int, pid_t, void *, u_int16_t);
/* log.c */
void log_peer_err(const struct peer *, const char *, ...);