summaryrefslogtreecommitdiff
path: root/usr.sbin
diff options
context:
space:
mode:
Diffstat (limited to 'usr.sbin')
-rw-r--r--usr.sbin/bgpctl/bgpctl.814
-rw-r--r--usr.sbin/bgpctl/bgpctl.c14
-rw-r--r--usr.sbin/bgpctl/parser.c24
-rw-r--r--usr.sbin/bgpctl/parser.h3
-rw-r--r--usr.sbin/bgpd/bgpd.835
-rw-r--r--usr.sbin/bgpd/bgpd.conf.515
-rw-r--r--usr.sbin/bgpd/bgpd.h6
-rw-r--r--usr.sbin/bgpd/control.c8
-rw-r--r--usr.sbin/bgpd/parse.y15
-rw-r--r--usr.sbin/bgpd/session.c52
-rw-r--r--usr.sbin/bgpd/session.h3
-rw-r--r--usr.sbin/bgpd/util.c12
12 files changed, 170 insertions, 31 deletions
diff --git a/usr.sbin/bgpctl/bgpctl.8 b/usr.sbin/bgpctl/bgpctl.8
index 6c2bae6ab90..239f6d0ca09 100644
--- a/usr.sbin/bgpctl/bgpctl.8
+++ b/usr.sbin/bgpctl/bgpctl.8
@@ -1,4 +1,4 @@
-.\" $OpenBSD: bgpctl.8,v 1.71 2016/10/26 17:24:13 jmc Exp $
+.\" $OpenBSD: bgpctl.8,v 1.72 2017/01/13 18:59:12 phessler Exp $
.\"
.\" Copyright (c) 2003 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: October 26 2016 $
+.Dd $Mdocdate: January 13 2017 $
.Dt BGPCTL 8
.Os
.Sh NAME
@@ -104,8 +104,16 @@ Destroy a previously cloned peer.
The peer must be down before calling this function.
.Ar peer
may be the neighbor's address or description.
-.It Cm neighbor Ar peer Cm down
+.It Cm neighbor Ar peer Cm down Op Ar reason
Take the BGP session to the specified neighbor down.
+If a
+.Ar reason
+is provided, the
+.Ar reason
+is sent as Administrative Shutdown Communication to the neighbor.
+The
+.Ar reason
+cannot exceed 128 octets.
.Ar peer
may be the neighbor's address or description.
.It Cm neighbor Ar peer Cm refresh
diff --git a/usr.sbin/bgpctl/bgpctl.c b/usr.sbin/bgpctl/bgpctl.c
index 91e2cbc70d2..eb14bfe73ef 100644
--- a/usr.sbin/bgpctl/bgpctl.c
+++ b/usr.sbin/bgpctl/bgpctl.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: bgpctl.c,v 1.190 2016/10/14 16:05:35 phessler Exp $ */
+/* $OpenBSD: bgpctl.c,v 1.191 2017/01/13 18:59:12 phessler Exp $ */
/*
* Copyright (c) 2003 Henning Brauer <henning@openbsd.org>
@@ -162,6 +162,7 @@ main(int argc, char *argv[])
memcpy(&neighbor.addr, &res->peeraddr, sizeof(neighbor.addr));
strlcpy(neighbor.descr, res->peerdesc, sizeof(neighbor.descr));
+ strlcpy(neighbor.shutcomm, res->shutcomm, sizeof(neighbor.shutcomm));
if ((fd = socket(AF_UNIX, SOCK_STREAM, 0)) == -1)
err(1, "control_init: socket");
@@ -722,6 +723,13 @@ show_neighbor_msg(struct imsg *imsg, enum neighbor_views nv)
inet_ntoa(ina));
printf("%s\n", print_auth_method(p->auth.method));
printf(" BGP state = %s", statenames[p->state]);
+ if (p->conf.down) {
+ printf(", marked down");
+ if (*(p->conf.shutcomm)) {
+ printf(" with shutdown reason \"%s\"",
+ log_shutcomm(p->conf.shutcomm));
+ }
+ }
if (p->stats.last_updown != 0)
printf(", %s for %s",
p->state == STATE_ESTABLISHED ? "up" : "down",
@@ -756,6 +764,10 @@ show_neighbor_msg(struct imsg *imsg, enum neighbor_views nv)
break;
print_neighbor_msgstats(p);
printf("\n");
+ if (*(p->stats.last_shutcomm)) {
+ printf(" Last received shutdown reason: \"%s\"\n",
+ log_shutcomm(p->stats.last_shutcomm));
+ }
if (p->state == STATE_IDLE) {
static const char *errstr;
diff --git a/usr.sbin/bgpctl/parser.c b/usr.sbin/bgpctl/parser.c
index 4b65785a0a6..f93881d2cee 100644
--- a/usr.sbin/bgpctl/parser.c
+++ b/usr.sbin/bgpctl/parser.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: parser.c,v 1.74 2016/10/14 16:05:35 phessler Exp $ */
+/* $OpenBSD: parser.c,v 1.75 2017/01/13 18:59:12 phessler Exp $ */
/*
* Copyright (c) 2003, 2004 Henning Brauer <henning@openbsd.org>
@@ -45,6 +45,7 @@ enum token_type {
PREFIX,
PEERDESC,
RIBNAME,
+ SHUTDOWN_COMMUNICATION,
COMMUNITY,
LARGE_COMMUNITY,
LOCALPREF,
@@ -245,9 +246,15 @@ static const struct token t_neighbor[] = {
{ ENDTOKEN, "", NONE, NULL}
};
+static const struct token t_nei_mod_shutc[] = {
+ { NOTOKEN, "", NONE, NULL},
+ { SHUTDOWN_COMMUNICATION, "", NONE, NULL},
+ { ENDTOKEN, "", NONE, NULL}
+};
+
static const struct token t_neighbor_modifiers[] = {
{ KEYWORD, "up", NEIGHBOR_UP, NULL},
- { KEYWORD, "down", NEIGHBOR_DOWN, NULL},
+ { KEYWORD, "down", NEIGHBOR_DOWN, t_nei_mod_shutc},
{ KEYWORD, "clear", NEIGHBOR_CLEAR, NULL},
{ KEYWORD, "refresh", NEIGHBOR_RREFRESH, NULL},
{ KEYWORD, "destroy", NEIGHBOR_DESTROY, NULL},
@@ -571,6 +578,16 @@ match_token(int *argc, char **argv[], const struct token table[])
t = &table[i];
}
break;
+ case SHUTDOWN_COMMUNICATION:
+ if (!match && word != NULL && wordlen > 0) {
+ if (strlcpy(res.shutcomm, word,
+ sizeof(res.shutcomm)) >=
+ sizeof(res.shutcomm))
+ errx(1, "shutdown reason too long");
+ match++;
+ t = &table[i];
+ }
+ break;
case COMMUNITY:
if (word != NULL && wordlen > 0 &&
parse_community(word, &res)) {
@@ -694,6 +711,9 @@ show_valid_args(const struct token table[])
case RIBNAME:
fprintf(stderr, " <rib name>\n");
break;
+ case SHUTDOWN_COMMUNICATION:
+ fprintf(stderr, " <shutdown reason>\n");
+ break;
case COMMUNITY:
fprintf(stderr, " <community>\n");
break;
diff --git a/usr.sbin/bgpctl/parser.h b/usr.sbin/bgpctl/parser.h
index cc66a04a4fc..33dfb94c1b0 100644
--- a/usr.sbin/bgpctl/parser.h
+++ b/usr.sbin/bgpctl/parser.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: parser.h,v 1.28 2016/10/14 16:05:35 phessler Exp $ */
+/* $OpenBSD: parser.h,v 1.29 2017/01/13 18:59:12 phessler Exp $ */
/*
* Copyright (c) 2003, 2004 Henning Brauer <henning@openbsd.org>
@@ -66,6 +66,7 @@ struct parse_result {
struct filter_largecommunity large_community;
char peerdesc[PEER_DESCR_LEN];
char rib[PEER_DESCR_LEN];
+ char shutcomm[SHUT_COMM_LEN];
char *irr_outdir;
int flags;
u_int rtableid;
diff --git a/usr.sbin/bgpd/bgpd.8 b/usr.sbin/bgpd/bgpd.8
index 9d78dab8293..a6668f5a312 100644
--- a/usr.sbin/bgpd/bgpd.8
+++ b/usr.sbin/bgpd/bgpd.8
@@ -1,4 +1,4 @@
-.\" $OpenBSD: bgpd.8,v 1.50 2016/11/10 10:01:33 phessler Exp $
+.\" $OpenBSD: bgpd.8,v 1.51 2017/01/13 18:59:12 phessler 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: November 10 2016 $
+.Dd $Mdocdate: January 13 2017 $
.Dt BGPD 8
.Os
.Sh NAME
@@ -238,17 +238,6 @@ control socket
.Re
.Pp
.Rs
-.%A J. Snijders
-.%A J. Heitz
-.%A K. Patel
-.%A I. Bagdonas
-.%A A. Simpson
-.%D September 2016
-.%R draft-ietf-idr-large-community
-.%T Large BGP Communities Attribute
-.Re
-.Pp
-.Rs
.%A A. Heffernan
.%D August 1998
.%R RFC 2385
@@ -381,6 +370,26 @@ control socket
.%R RFC 6608
.%T Subcodes for BGP Finite State Machine Error
.Re
+.Pp
+.Rs
+.%A J. Snijders
+.%A J. Heitz
+.%A K. Patel
+.%A I. Bagdonas
+.%A N. Hilliard
+.%D January 2017
+.%R draft-ietf-idr-large-community
+.%T BGP Large Communities Attribute
+.Re
+.Pp
+.Rs
+.%A J. Snijders
+.%A J. Heitz
+.%A J. Scudder
+.%D January 2017
+.%R draft-ietf-idr-shutdown
+.%T BGP Administrative Shutdown Communication
+.Re
.Sh HISTORY
The
.Nm
diff --git a/usr.sbin/bgpd/bgpd.conf.5 b/usr.sbin/bgpd/bgpd.conf.5
index e982eeeb083..312cf85b5c7 100644
--- a/usr.sbin/bgpd/bgpd.conf.5
+++ b/usr.sbin/bgpd/bgpd.conf.5
@@ -1,4 +1,4 @@
-.\" $OpenBSD: bgpd.conf.5,v 1.151 2016/10/30 16:50:22 phessler Exp $
+.\" $OpenBSD: bgpd.conf.5,v 1.152 2017/01/13 18:59:12 phessler Exp $
.\"
.\" Copyright (c) 2004 Claudio Jeker <claudio@openbsd.org>
.\" Copyright (c) 2003, 2004 Henning Brauer <henning@openbsd.org>
@@ -16,7 +16,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: October 30 2016 $
+.Dd $Mdocdate: January 13 2017 $
.Dt BGPD.CONF 5
.Os
.Sh NAME
@@ -737,9 +737,18 @@ The description is used when logging neighbor events, in status
reports, for specifying neighbors, etc., but has no further meaning to
.Xr bgpd 8 .
.Pp
-.It Ic down
+.It Ic down Op Ar reason
Do not start the session when bgpd comes up but stay in
.Em IDLE .
+If the session is cleared at runtime, after a
+.Ic down
+.Ar reason
+was configured at runtime, the
+.Ar reason
+is sent as Administrative Shutdown Communication.
+The
+.Ar reason
+cannot exceed 128 octets.
.Pp
.It Xo
.Ic dump
diff --git a/usr.sbin/bgpd/bgpd.h b/usr.sbin/bgpd/bgpd.h
index 87dd2d891b2..b105f3f48c9 100644
--- a/usr.sbin/bgpd/bgpd.h
+++ b/usr.sbin/bgpd/bgpd.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: bgpd.h,v 1.297 2016/10/14 16:05:35 phessler Exp $ */
+/* $OpenBSD: bgpd.h,v 1.298 2017/01/13 18:59:12 phessler Exp $ */
/*
* Copyright (c) 2003, 2004 Henning Brauer <henning@openbsd.org>
@@ -40,6 +40,7 @@
#define CONFFILE "/etc/bgpd.conf"
#define BGPD_USER "_bgpd"
#define PEER_DESCR_LEN 32
+#define SHUT_COMM_LEN 129
#define PFTABLE_LEN 32
#define TCP_MD5_KEY_LEN 80
#define IPSEC_ENC_KEY_LEN 32
@@ -299,6 +300,7 @@ struct peer_config {
struct capabilities capabilities;
char group[PEER_DESCR_LEN];
char descr[PEER_DESCR_LEN];
+ char shutcomm[SHUT_COMM_LEN];
char rib[PEER_DESCR_LEN];
char if_depend[IFNAMSIZ];
char demote_group[IFNAMSIZ];
@@ -586,6 +588,7 @@ struct ctl_show_nexthop {
struct ctl_neighbor {
struct bgpd_addr addr;
char descr[PEER_DESCR_LEN];
+ char shutcomm[SHUT_COMM_LEN];
int show_timers;
};
@@ -1084,6 +1087,7 @@ const char *log_sockaddr(struct sockaddr *);
const char *log_as(u_int32_t);
const char *log_rd(u_int64_t);
const char *log_ext_subtype(u_int8_t);
+const char *log_shutcomm(const char *);
int aspath_snprint(char *, size_t, void *, u_int16_t);
int aspath_asprint(char **, void *, u_int16_t);
size_t aspath_strlen(void *, u_int16_t);
diff --git a/usr.sbin/bgpd/control.c b/usr.sbin/bgpd/control.c
index 903892ca606..63f41ae8072 100644
--- a/usr.sbin/bgpd/control.c
+++ b/usr.sbin/bgpd/control.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: control.c,v 1.84 2017/01/08 23:04:42 krw Exp $ */
+/* $OpenBSD: control.c,v 1.85 2017/01/13 18:59:12 phessler Exp $ */
/*
* Copyright (c) 2003, 2004 Henning Brauer <henning@openbsd.org>
@@ -340,9 +340,15 @@ control_dispatch_msg(struct pollfd *pfd, u_int *ctl_cnt)
switch (imsg.hdr.type) {
case IMSG_CTL_NEIGHBOR_UP:
bgp_fsm(p, EVNT_START);
+ p->conf.down = 0;
+ p->conf.shutcomm[0] = '\0';
control_result(c, CTL_RES_OK);
break;
case IMSG_CTL_NEIGHBOR_DOWN:
+ p->conf.down = 1;
+ strlcpy(p->conf.shutcomm,
+ neighbor->shutcomm,
+ sizeof(neighbor->shutcomm));
session_stop(p, ERR_CEASE_ADMIN_DOWN);
control_result(c, CTL_RES_OK);
break;
diff --git a/usr.sbin/bgpd/parse.y b/usr.sbin/bgpd/parse.y
index 06d614b9f57..16b0fc87a4c 100644
--- a/usr.sbin/bgpd/parse.y
+++ b/usr.sbin/bgpd/parse.y
@@ -1,4 +1,4 @@
-/* $OpenBSD: parse.y,v 1.293 2017/01/05 13:53:09 krw Exp $ */
+/* $OpenBSD: parse.y,v 1.294 2017/01/13 18:59:12 phessler Exp $ */
/*
* Copyright (c) 2002, 2003, 2004 Henning Brauer <henning@openbsd.org>
@@ -1052,9 +1052,20 @@ peeropts : REMOTEAS as4number {
| PASSIVE {
curpeer->conf.passive = 1;
}
- | DOWN {
+ | DOWN {
curpeer->conf.down = 1;
}
+ | DOWN STRING {
+ curpeer->conf.down = 1;
+ if (strlcpy(curpeer->conf.shutcomm, $2,
+ sizeof(curpeer->conf.shutcomm)) >=
+ sizeof(curpeer->conf.shutcomm)) {
+ yyerror("shutdown reason too long");
+ free($2);
+ YYERROR;
+ }
+ free($2);
+ }
| RIB STRING {
if (!find_rib($2)) {
yyerror("rib \"%s\" does not exist.", $2);
diff --git a/usr.sbin/bgpd/session.c b/usr.sbin/bgpd/session.c
index 02f6a15012e..b710d27c135 100644
--- a/usr.sbin/bgpd/session.c
+++ b/usr.sbin/bgpd/session.c
@@ -1,7 +1,8 @@
-/* $OpenBSD: session.c,v 1.356 2016/12/19 07:19:55 claudio Exp $ */
+/* $OpenBSD: session.c,v 1.357 2017/01/13 18:59:12 phessler Exp $ */
/*
* Copyright (c) 2003, 2004, 2005 Henning Brauer <henning@openbsd.org>
+ * Copyright (c) 2017 Peter van Dijk <peter.van.dijk@powerdns.com>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
@@ -571,6 +572,9 @@ session_main(int debug, int verbose)
while ((p = peers) != NULL) {
peers = p->next;
+ strlcpy(p->conf.shutcomm,
+ "bgpd shutting down",
+ sizeof(p->conf.shutcomm));
session_stop(p, ERR_CEASE_ADMIN_DOWN);
pfkey_remove(p);
free(p);
@@ -2221,6 +2225,7 @@ parse_notification(struct peer *peer)
u_int8_t subcode;
u_int8_t capa_code;
u_int8_t capa_len;
+ u_int8_t shutcomm_len;
u_int8_t i;
/* just log */
@@ -2315,6 +2320,31 @@ parse_notification(struct peer *peer)
return (1);
}
+ if (errcode == ERR_CEASE && subcode == ERR_CEASE_ADMIN_DOWN) {
+ if (datalen >= sizeof(shutcomm_len)) {
+ memcpy(&shutcomm_len, p, sizeof(shutcomm_len));
+ p += sizeof(shutcomm_len);
+ datalen -= sizeof(shutcomm_len);
+ if(datalen < shutcomm_len) {
+ log_peer_warnx(&peer->conf,
+ "received truncated shutdown reason");
+ return (0);
+ }
+ if (shutcomm_len > (SHUT_COMM_LEN-1)) {
+ log_peer_warnx(&peer->conf,
+ "received overly long shutdown reason");
+ return (0);
+ }
+ memcpy(peer->stats.last_shutcomm, p, shutcomm_len);
+ peer->stats.last_shutcomm[shutcomm_len] = '\0';
+ log_peer_warnx(&peer->conf,
+ "received shutdown reason: \"%s\"",
+ log_shutcomm(peer->stats.last_shutcomm));
+ p += shutcomm_len;
+ datalen -= shutcomm_len;
+ }
+ }
+
return (0);
}
@@ -3195,11 +3225,29 @@ session_demote(struct peer *p, int level)
void
session_stop(struct peer *peer, u_int8_t subcode)
{
+ char data[SHUT_COMM_LEN];
+ uint8_t datalen;
+ uint8_t shutcomm_len;
+ char *communication;
+
+ datalen = 0;
+
+ communication = peer->conf.shutcomm;
+
+ if (subcode == ERR_CEASE_ADMIN_DOWN && communication &&
+ *communication) {
+ shutcomm_len = strlen(communication);
+ if(shutcomm_len < SHUT_COMM_LEN) {
+ data[0] = shutcomm_len;
+ datalen = shutcomm_len + sizeof(data[0]);
+ memcpy(data + 1, communication, shutcomm_len);
+ }
+ }
switch (peer->state) {
case STATE_OPENSENT:
case STATE_OPENCONFIRM:
case STATE_ESTABLISHED:
- session_notification(peer, ERR_CEASE, subcode, NULL, 0);
+ session_notification(peer, ERR_CEASE, subcode, data, datalen);
break;
default:
/* session not open, no need to send notification */
diff --git a/usr.sbin/bgpd/session.h b/usr.sbin/bgpd/session.h
index bd11ac4efe4..863d0535178 100644
--- a/usr.sbin/bgpd/session.h
+++ b/usr.sbin/bgpd/session.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: session.h,v 1.121 2015/10/25 18:49:01 claudio Exp $ */
+/* $OpenBSD: session.h,v 1.122 2017/01/13 18:59:12 phessler Exp $ */
/*
* Copyright (c) 2003, 2004 Henning Brauer <henning@openbsd.org>
@@ -168,6 +168,7 @@ struct peer_stats {
u_int32_t prefix_cnt;
u_int8_t last_sent_errcode;
u_int8_t last_sent_suberr;
+ char last_shutcomm[SHUT_COMM_LEN];
};
enum Timer {
diff --git a/usr.sbin/bgpd/util.c b/usr.sbin/bgpd/util.c
index 39ad7f1b538..a660f38a393 100644
--- a/usr.sbin/bgpd/util.c
+++ b/usr.sbin/bgpd/util.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: util.c,v 1.21 2016/06/03 17:36:37 benno Exp $ */
+/* $OpenBSD: util.c,v 1.22 2017/01/13 18:59:12 phessler Exp $ */
/*
* Copyright (c) 2006 Claudio Jeker <claudio@openbsd.org>
@@ -24,6 +24,7 @@
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
+#include <vis.h>
#include "bgpd.h"
#include "rde.h"
@@ -159,6 +160,15 @@ log_ext_subtype(u_int8_t subtype)
}
const char *
+log_shutcomm(const char *communication) {
+ static char buf[(SHUT_COMM_LEN - 1) * 4 + 1];
+
+ strnvis(buf, communication, sizeof(buf), VIS_NL | VIS_OCTAL);
+
+ return buf;
+}
+
+const char *
aspath_delim(u_int8_t seg_type, int closing)
{
static char db[8];