summaryrefslogtreecommitdiff
path: root/usr.sbin
diff options
context:
space:
mode:
authorClaudio Jeker <claudio@cvs.openbsd.org>2009-09-02 08:06:43 +0000
committerClaudio Jeker <claudio@cvs.openbsd.org>2009-09-02 08:06:43 +0000
commit7e3bc69c2b2ea8cda7a83e23564155fcf1ab816c (patch)
tree7c4d53e1bf0874ef493ff291abe34b8bcebd6e8a /usr.sbin
parentded67fece3e31c608ed2d8a8b46a7c25ec164c9b (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')
-rw-r--r--usr.sbin/bgpd/bgpd.89
-rw-r--r--usr.sbin/bgpd/control.c6
-rw-r--r--usr.sbin/bgpd/session.c36
-rw-r--r--usr.sbin/bgpd/session.h3
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 *);