diff options
author | Peter Hessler <phessler@cvs.openbsd.org> | 2017-01-13 18:59:13 +0000 |
---|---|---|
committer | Peter Hessler <phessler@cvs.openbsd.org> | 2017-01-13 18:59:13 +0000 |
commit | 711ecbd6e4eb80012d22a2cb2058c80b253433d2 (patch) | |
tree | 4ad6388d383f7b28271bf4fc10255212dad5d799 /usr.sbin | |
parent | 0ed25f9a076f2e5f91e48c5a09c23e4c4769cd43 (diff) |
Add support for draft-ietf-idr-shutdown
BGP state = Idle, marked down with shutdown reason "goodbye, we are
upgrading to openbsd 6.1", down for 00:00:17
developed by Peter van Dijk <peter.van.dijk@powerdns.com> and Job
Snijders <job@ntt.net>, thank you!
OK benno@
Diffstat (limited to 'usr.sbin')
-rw-r--r-- | usr.sbin/bgpctl/bgpctl.8 | 14 | ||||
-rw-r--r-- | usr.sbin/bgpctl/bgpctl.c | 14 | ||||
-rw-r--r-- | usr.sbin/bgpctl/parser.c | 24 | ||||
-rw-r--r-- | usr.sbin/bgpctl/parser.h | 3 | ||||
-rw-r--r-- | usr.sbin/bgpd/bgpd.8 | 35 | ||||
-rw-r--r-- | usr.sbin/bgpd/bgpd.conf.5 | 15 | ||||
-rw-r--r-- | usr.sbin/bgpd/bgpd.h | 6 | ||||
-rw-r--r-- | usr.sbin/bgpd/control.c | 8 | ||||
-rw-r--r-- | usr.sbin/bgpd/parse.y | 15 | ||||
-rw-r--r-- | usr.sbin/bgpd/session.c | 52 | ||||
-rw-r--r-- | usr.sbin/bgpd/session.h | 3 | ||||
-rw-r--r-- | usr.sbin/bgpd/util.c | 12 |
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]; |