diff options
author | Henning Brauer <henning@cvs.openbsd.org> | 2004-01-10 17:04:08 +0000 |
---|---|---|
committer | Henning Brauer <henning@cvs.openbsd.org> | 2004-01-10 17:04:08 +0000 |
commit | f0b84a5e2f08a1782396a922a2dbd19bcae884e0 (patch) | |
tree | d5fa9d3025a3dd4d41ddc1da24038a958ac8fb07 | |
parent | 30a469312bb43b8befd0441370ef1cfddffa3bae (diff) |
send out UPDATE messages to the peer(s) that we receive from the RDE
ok claudio@
-rw-r--r-- | usr.sbin/bgpd/session.c | 79 |
1 files changed, 73 insertions, 6 deletions
diff --git a/usr.sbin/bgpd/session.c b/usr.sbin/bgpd/session.c index 2a2d915ab8c..61cc7df0ec3 100644 --- a/usr.sbin/bgpd/session.c +++ b/usr.sbin/bgpd/session.c @@ -1,4 +1,4 @@ -/* $OpenBSD: session.c,v 1.77 2004/01/09 19:08:50 henning Exp $ */ +/* $OpenBSD: session.c,v 1.78 2004/01/10 17:04:07 henning Exp $ */ /* * Copyright (c) 2003, 2004 Henning Brauer <henning@openbsd.org> @@ -65,7 +65,7 @@ void session_accept(int); int session_connect(struct peer *); void session_open(struct peer *); void session_keepalive(struct peer *); -void session_update(struct peer *); +void session_update(u_int32_t, void *, size_t); void session_notification(struct peer *, u_int8_t, u_int8_t, void *, ssize_t); int session_dispatch_msg(struct pollfd *, struct peer *); @@ -78,6 +78,8 @@ void session_dispatch_imsg(struct imsgbuf *, int); void session_up(struct peer *); void session_down(struct peer *); +struct peer *getpeerbyid(u_int32_t); + struct bgpd_config *conf, *nconf = NULL; struct peer *npeers; volatile sig_atomic_t session_quit = 0; @@ -912,10 +914,51 @@ session_keepalive(struct peer *peer) } void -session_update(struct peer *peer) +session_update(u_int32_t peerid, void *data, size_t datalen) { - start_timer_keepalive(peer); - peer->stats.msg_sent_update++; + struct peer *p; + struct msg_header msg; + struct buf *buf; + ssize_t len; + int errs = 0, n; + + if ((p = getpeerbyid(peerid)) == NULL) { + logit(LOG_CRIT, "no such peer: id=%u", peerid); + return; + } + + len = MSGSIZE_HEADER + datalen; + + memset(&msg.marker, 0xff, sizeof(msg.marker)); + msg.len = htons(len); + msg.type = UPDATE; + + if ((buf = buf_open(len)) == NULL) { + bgp_fsm(p, EVNT_CON_FATAL); + return; + } + errs += buf_add(buf, &msg.marker, sizeof(msg.marker)); + errs += buf_add(buf, &msg.len, sizeof(msg.len)); + errs += buf_add(buf, &msg.type, sizeof(msg.type)); + errs += buf_add(buf, data, datalen); + + if (errs > 0) { + buf_free(buf); + bgp_fsm(p, EVNT_CON_FATAL); + return; + } + + if ((n = buf_close(&p->wbuf, buf)) < 0) { + if (n == -2) + log_peer_errx(p, "Connection closed"); + else + log_peer_err(p, "Write error"); + buf_free(buf); + bgp_fsm(p, EVNT_CON_FATAL); + } + + start_timer_keepalive(p); + p->stats.msg_sent_update++; } void @@ -1414,8 +1457,19 @@ session_dispatch_imsg(struct imsgbuf *ibuf, int idx) case IMSG_CTL_KROUTE_ADDR: case IMSG_CTL_END: if (idx != PFD_PIPE_MAIN) - fatalx("reconf request not from parent"); + fatalx("ctl kroute request not from parent"); control_imsg_relay(&imsg); + case IMSG_UPDATE: + if (idx != PFD_PIPE_ROUTE) + fatalx("update request not from RDE"); + if (imsg.hdr.len > IMSG_HEADER_SIZE + + MAX_PKTSIZE - MSGSIZE_HEADER || + imsg.hdr.len < IMSG_HEADER_SIZE + + MSGSIZE_UPDATE_MIN - MSGSIZE_HEADER) + logit(LOG_CRIT, "RDE sent invalid update"); + else + session_update(imsg.hdr.peerid, imsg.data, + imsg.hdr.len - IMSG_HEADER_SIZE); default: break; } @@ -1436,6 +1490,19 @@ getpeerbyip(in_addr_t ip) return (p); } +struct peer * +getpeerbyid(u_int32_t peerid) +{ + struct peer *p; + + /* we might want a more effective way to find peers by IP */ + for (p = peers; p != NULL && + p->conf.id != peerid; p = p->next) + ; /* nothing */ + + return (p); +} + void session_down(struct peer *peer) { |