From 715650b30ccfc3f0aa534bc491db3fab23f000c1 Mon Sep 17 00:00:00 2001 From: Henning Brauer Date: Fri, 9 Jan 2004 13:47:09 +0000 Subject: 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@ --- usr.sbin/bgpd/bgpd.c | 16 ++++++++- usr.sbin/bgpd/bgpd.h | 19 +++++++++-- usr.sbin/bgpd/control.c | 32 +++++++++++++++++- usr.sbin/bgpd/imsg.c | 21 +++++++++++- usr.sbin/bgpd/kroute.c | 89 +++++++++++++++++++++++++------------------------ usr.sbin/bgpd/session.c | 11 ++++-- usr.sbin/bgpd/session.h | 4 +-- 7 files changed, 138 insertions(+), 54 deletions(-) (limited to 'usr.sbin/bgpd') 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 @@ -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 @@ -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 @@ -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 @@ -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,7 +96,21 @@ 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; @@ -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 @@ -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 @@ -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 @@ -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 *, ...); -- cgit v1.2.3