diff options
author | Claudio Jeker <claudio@cvs.openbsd.org> | 2009-09-02 08:06:43 +0000 |
---|---|---|
committer | Claudio Jeker <claudio@cvs.openbsd.org> | 2009-09-02 08:06:43 +0000 |
commit | 7e3bc69c2b2ea8cda7a83e23564155fcf1ab816c (patch) | |
tree | 7c4d53e1bf0874ef493ff291abe34b8bcebd6e8a /usr.sbin/bgpd | |
parent | ded67fece3e31c608ed2d8a8b46a7c25ec164c9b (diff) |
Implement all of RFC 4486 BGP Cease Notification Message Subcodes.
The other side should now see why a session was dropped. e.g:
bgpd: ... received notification: Cease, administratively down
OK henning
Diffstat (limited to 'usr.sbin/bgpd')
-rw-r--r-- | usr.sbin/bgpd/bgpd.8 | 9 | ||||
-rw-r--r-- | usr.sbin/bgpd/control.c | 6 | ||||
-rw-r--r-- | usr.sbin/bgpd/session.c | 36 | ||||
-rw-r--r-- | usr.sbin/bgpd/session.h | 3 |
4 files changed, 35 insertions, 19 deletions
diff --git a/usr.sbin/bgpd/bgpd.8 b/usr.sbin/bgpd/bgpd.8 index 7bb8d90e79f..ede30e8b695 100644 --- a/usr.sbin/bgpd/bgpd.8 +++ b/usr.sbin/bgpd/bgpd.8 @@ -1,4 +1,4 @@ -.\" $OpenBSD: bgpd.8,v 1.29 2009/08/06 08:53:11 claudio Exp $ +.\" $OpenBSD: bgpd.8,v 1.30 2009/09/02 08:06:42 claudio Exp $ .\" .\" Copyright (c) 2003, 2004 Henning Brauer <henning@openbsd.org> .\" @@ -14,7 +14,7 @@ .\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF .\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. .\" -.Dd $Mdocdate: August 6 2009 $ +.Dd $Mdocdate: September 2 2009 $ .Dt BGPD 8 .Os .Sh NAME @@ -190,6 +190,11 @@ control socket .%D April 2004 .Re .Rs +.%R RFC 4486 +.%T "BGP Cease Notification Message Subcodes" +.%D April 2006 +.Re +.Rs .%R RFC 4760 .%T "Multiprotocol Extensions for BGP-4" .%D January 2007 diff --git a/usr.sbin/bgpd/control.c b/usr.sbin/bgpd/control.c index e8097dda77f..6ae4eb97ccb 100644 --- a/usr.sbin/bgpd/control.c +++ b/usr.sbin/bgpd/control.c @@ -1,4 +1,4 @@ -/* $OpenBSD: control.c,v 1.61 2009/05/05 20:09:19 sthen Exp $ */ +/* $OpenBSD: control.c,v 1.62 2009/09/02 08:06:42 claudio Exp $ */ /* * Copyright (c) 2003, 2004 Henning Brauer <henning@openbsd.org> @@ -328,11 +328,11 @@ control_dispatch_msg(struct pollfd *pfd, u_int *ctl_cnt) control_result(c, CTL_RES_OK); break; case IMSG_CTL_NEIGHBOR_DOWN: - bgp_fsm(p, EVNT_STOP); + session_stop(p, ERR_CEASE_ADMIN_DOWN); control_result(c, CTL_RES_OK); break; case IMSG_CTL_NEIGHBOR_CLEAR: - bgp_fsm(p, EVNT_STOP); + session_stop(p, ERR_CEASE_ADMIN_RESET); timer_set(p, Timer_IdleHold, SESSION_CLEAR_DELAY); control_result(c, CTL_RES_OK); diff --git a/usr.sbin/bgpd/session.c b/usr.sbin/bgpd/session.c index 02ebb3c1324..6ed127a8d00 100644 --- a/usr.sbin/bgpd/session.c +++ b/usr.sbin/bgpd/session.c @@ -1,4 +1,4 @@ -/* $OpenBSD: session.c,v 1.295 2009/08/21 15:43:27 claudio Exp $ */ +/* $OpenBSD: session.c,v 1.296 2009/09/02 08:06:42 claudio Exp $ */ /* * Copyright (c) 2003, 2004, 2005 Henning Brauer <henning@openbsd.org> @@ -308,7 +308,7 @@ session_main(struct bgpd_config *config, struct peer *cpeers, /* reinit due? */ if (p->conf.reconf_action == RECONF_REINIT) { - bgp_fsm(p, EVNT_STOP); + session_stop(p, ERR_CEASE_ADMIN_RESET); timer_set(p, Timer_IdleHold, 0); } @@ -317,7 +317,7 @@ session_main(struct bgpd_config *config, struct peer *cpeers, if (p->demoted) session_demote(p, -1); p->conf.demote_group[0] = 0; - bgp_fsm(p, EVNT_STOP); + session_stop(p, ERR_CEASE_PEER_UNCONF); log_peer_warnx(&p->conf, "removed"); if (last != NULL) last->next = next; @@ -557,7 +557,7 @@ session_main(struct bgpd_config *config, struct peer *cpeers, while ((p = peers) != NULL) { peers = p->next; - bgp_fsm(p, EVNT_STOP); + session_stop(p, ERR_CEASE_ADMIN_DOWN); pfkey_remove(p); free(p); } @@ -746,7 +746,6 @@ bgp_fsm(struct peer *peer, enum session_events event) /* ignore */ break; case EVNT_STOP: - session_notification(peer, ERR_CEASE, 0, NULL, 0); change_state(peer, STATE_IDLE, event); break; case EVNT_CON_CLOSED: @@ -791,7 +790,6 @@ bgp_fsm(struct peer *peer, enum session_events event) /* ignore */ break; case EVNT_STOP: - session_notification(peer, ERR_CEASE, 0, NULL, 0); change_state(peer, STATE_IDLE, event); break; case EVNT_CON_CLOSED: @@ -826,7 +824,6 @@ bgp_fsm(struct peer *peer, enum session_events event) /* ignore */ break; case EVNT_STOP: - session_notification(peer, ERR_CEASE, 0, NULL, 0); change_state(peer, STATE_IDLE, event); break; case EVNT_CON_CLOSED: @@ -1481,7 +1478,6 @@ session_notification(struct peer *p, u_int8_t errcode, u_int8_t subcode, { struct bgp_msg *buf; u_int errs = 0; - u_int8_t null8 = 0; if (p->stats.last_sent_errcode) /* some notification already sent */ return; @@ -1493,10 +1489,7 @@ session_notification(struct peer *p, u_int8_t errcode, u_int8_t subcode, } errs += buf_add(buf->buf, &errcode, sizeof(errcode)); - if (errcode == ERR_CEASE) - errs += buf_add(buf->buf, &null8, sizeof(null8)); - else - errs += buf_add(buf->buf, &subcode, sizeof(subcode)); + errs += buf_add(buf->buf, &subcode, sizeof(subcode)); if (datalen > 0) errs += buf_add(buf->buf, data, datalen); @@ -2411,7 +2404,8 @@ session_dispatch_imsg(struct imsgbuf *ibuf, int idx, u_int *listener_cnt) bgp_fsm(p, EVNT_START); } else if (!depend_ok && p->depend_ok) { p->depend_ok = depend_ok; - bgp_fsm(p, EVNT_STOP); + session_stop(p, + ERR_CEASE_OTHER_CHANGE); } } break; @@ -2840,3 +2834,19 @@ session_demote(struct peer *p, int level) p->demoted += level; } + +void +session_stop(struct peer *peer, u_int8_t subcode) +{ + switch (peer->state) { + case STATE_OPENSENT: + case STATE_OPENCONFIRM: + case STATE_ESTABLISHED: + session_notification(peer, ERR_CEASE, subcode, NULL, 0); + break; + default: + /* session not open, no need to send notification */ + break; + } + bgp_fsm(peer, EVNT_STOP); +} diff --git a/usr.sbin/bgpd/session.h b/usr.sbin/bgpd/session.h index 9c33239d77a..11471e5dde3 100644 --- a/usr.sbin/bgpd/session.h +++ b/usr.sbin/bgpd/session.h @@ -1,4 +1,4 @@ -/* $OpenBSD: session.h,v 1.101 2009/06/05 20:26:38 claudio Exp $ */ +/* $OpenBSD: session.h,v 1.102 2009/09/02 08:06:42 claudio Exp $ */ /* * Copyright (c) 2003, 2004 Henning Brauer <henning@openbsd.org> @@ -236,6 +236,7 @@ struct peer *getpeerbyaddr(struct bgpd_addr *); struct peer *getpeerbydesc(const char *); int imsg_compose_parent(int, pid_t, void *, u_int16_t); int imsg_compose_rde(int, pid_t, void *, u_int16_t); +void session_stop(struct peer *, u_int8_t); /* log.c */ char *log_fmt_peer(const struct peer_config *); |