So the 'Last error:' message for sessions that failed do often not include
the suberror and also it is only shown for NOTIFICATIONS we sent but not
for received notifications. The following diff fixes this.
So instead of:
Last error: Cease
or
Last error: unknown error code
I now get:
Last error sent: Cease, recieved max-prefix exceeded
or
Last error received: Cease, recieved max-prefix exceeded
--
:wq Claudio
Index: bgpctl/bgpctl.c
===================================================================
RCS file: /cvs/src/usr.sbin/bgpctl/bgpctl.c,v
retrieving revision 1.256
diff -u -p -r1.256 bgpctl.c
--- bgpctl/bgpctl.c 9 Jan 2020 11:57:04 -0000 1.256
+++ bgpctl/bgpctl.c 21 Jan 2020 08:18:59 -0000
@@ -1300,36 +1300,68 @@ send_filterset(struct imsgbuf *i, struct
const char *
get_errstr(u_int8_t errcode, u_int8_t subcode)
{
- static const char *errstr = NULL;
+ static char errbuf[256];
+ const char *errstr = NULL;
+ const char *suberr = NULL;
+ int uk = 0;
- if (errcode && errcode < sizeof(errnames)/sizeof(char *))
+ if (errcode == 0) /* no error */
+ return NULL;
+
+ if (errcode < sizeof(errnames)/sizeof(char *))
errstr = errnames[errcode];
switch (errcode) {
case ERR_HEADER:
- if (subcode &&
- subcode < sizeof(suberr_header_names)/sizeof(char *))
- errstr = suberr_header_names[subcode];
+ if (subcode < sizeof(suberr_header_names)/sizeof(char *))
+ suberr = suberr_header_names[subcode];
+ else
+ uk = 1;
break;
case ERR_OPEN:
- if (subcode &&
- subcode < sizeof(suberr_open_names)/sizeof(char *))
- errstr = suberr_open_names[subcode];
+ if (subcode < sizeof(suberr_open_names)/sizeof(char *))
+ suberr = suberr_open_names[subcode];
+ else
+ uk = 1;
break;
case ERR_UPDATE:
- if (subcode &&
- subcode < sizeof(suberr_update_names)/sizeof(char *))
- errstr = suberr_update_names[subcode];
+ if (subcode < sizeof(suberr_update_names)/sizeof(char *))
+ suberr = suberr_update_names[subcode];
+ else
+ uk = 1;
break;
case ERR_HOLDTIMEREXPIRED:
+ if (subcode != 0)
+ uk = 1;
+ break;
case ERR_FSM:
+ if (subcode < sizeof(suberr_fsm_names)/sizeof(char *))
+ suberr = suberr_fsm_names[subcode];
+ else
+ uk = 1;
+ break;
case ERR_CEASE:
+ if (subcode < sizeof(suberr_cease_names)/sizeof(char *))
+ suberr = suberr_cease_names[subcode];
+ else
+ uk = 1;
break;
default:
- return ("unknown error code");
+ snprintf(errbuf, sizeof(errbuf),
+ "unknown error code %u subcode %u", errcode, subcode);
+ return (errbuf);
}
- return (errstr);
+ if (uk)
+ snprintf(errbuf, sizeof(errbuf),
+ "%s, unknown subcode %u", errstr, subcode);
+ else if (suberr == NULL)
+ return (errstr);
+ else
+ snprintf(errbuf, sizeof(errbuf),
+ "%s, %s", errstr, suberr);
+
+ return (errbuf);
}
void
Index: bgpctl/output.c
===================================================================
RCS file: /cvs/src/usr.sbin/bgpctl/output.c,v
retrieving revision 1.3
diff -u -p -r1.3 output.c
--- bgpctl/output.c 9 Jan 2020 11:57:04 -0000 1.3
+++ bgpctl/output.c 21 Jan 2020 08:18:59 -0000
@@ -221,12 +221,16 @@ show_neighbor_full(struct peer *p, struc
log_shutcomm(p->stats.last_shutcomm));
}
if (p->state == STATE_IDLE) {
- static const char *errstr;
+ const char *errstr;
errstr = get_errstr(p->stats.last_sent_errcode,
p->stats.last_sent_suberr);
if (errstr)
- printf(" Last error: %s\n\n", errstr);
+ printf(" Last error sent: %s\n\n", errstr);
+ errstr = get_errstr(p->stats.last_rcvd_errcode,
+ p->stats.last_rcvd_suberr);
+ if (errstr)
+ printf(" Last error received: %s\n\n", errstr);
} else {
printf(" Local host: %20s, Local port: %5u\n",
log_addr(&p->local), p->local_port);
Index: bgpd/bgpd.h
===================================================================
RCS file: /cvs/src/usr.sbin/bgpd/bgpd.h,v
retrieving revision 1.397
diff -u -p -r1.397 bgpd.h
--- bgpd/bgpd.h 9 Jan 2020 11:55:25 -0000 1.397
+++ bgpd/bgpd.h 21 Jan 2020 08:18:59 -0000
@@ -383,6 +383,7 @@ struct peer_config {
enum enforce_as enforce_as;
enum enforce_as enforce_local_as;
u_int16_t max_prefix_restart;
+ u_int16_t max_out_prefix_restart;
u_int16_t holdtime;
u_int16_t min_holdtime;
u_int16_t local_short_as;
@@ -574,7 +575,9 @@ enum suberr_cease {
ERR_CEASE_CONN_REJECT,
ERR_CEASE_OTHER_CHANGE,
ERR_CEASE_COLLISION,
- ERR_CEASE_RSRC_EXHAUST
+ ERR_CEASE_RSRC_EXHAUST,
+ ERR_CEASE_HARD_RESET,
+ ERR_CEASE_MAX_SENT_PREFIX
};
struct kroute_node;
@@ -1432,14 +1435,16 @@ static const char * const suberr_update_
static const char * const suberr_cease_names[] = {
"none",
- "max-prefix exceeded",
+ "recieved max-prefix exceeded",
"administratively down",
"peer unconfigured",
"administrative reset",
"connection rejected",
"other config change",
"collision",
- "resource exhaustion"
+ "resource exhaustion",
+ "hard reset",
+ "sent max-prefix exceeded"
};
static const char * const ctl_res_strerror[] = {
Index: bgpd/session.c
===================================================================
RCS file: /cvs/src/usr.sbin/bgpd/session.c,v
retrieving revision 1.396
diff -u -p -r1.396 session.c
--- bgpd/session.c 9 Jan 2020 11:51:18 -0000 1.396
+++ bgpd/session.c 21 Jan 2020 08:19:00 -0000
@@ -610,6 +610,8 @@ bgp_fsm(struct peer *peer, enum session_
peer->stats.last_sent_errcode = 0;
peer->stats.last_sent_suberr = 0;
+ peer->stats.last_rcvd_errcode = 0;
+ peer->stats.last_rcvd_suberr = 0;
if (!peer->depend_ok)
timer_stop(peer, Timer_ConnectRetry);
@@ -2189,6 +2191,8 @@ parse_notification(struct peer *peer)
log_notification(peer, errcode, subcode, p, datalen, "received");
peer->errcnt++;
+ peer->stats.last_rcvd_errcode = errcode;
+ peer->stats.last_rcvd_suberr = subcode;
if (errcode == ERR_OPEN && subcode == ERR_OPEN_CAPA) {
if (datalen == 0) { /* zebra likes to send those.. humbug */
Index: bgpd/session.h
===================================================================
RCS file: /cvs/src/usr.sbin/bgpd/session.h,v
retrieving revision 1.142
diff -u -p -r1.142 session.h
--- bgpd/session.h 9 Jan 2020 11:51:18 -0000 1.142
+++ bgpd/session.h 21 Jan 2020 08:19:00 -0000
@@ -171,6 +171,8 @@ struct peer_stats {
u_int32_t prefix_cnt;
u_int8_t last_sent_errcode;
u_int8_t last_sent_suberr;
+ u_int8_t last_rcvd_errcode;
+ u_int8_t last_rcvd_suberr;
char last_shutcomm[SHUT_COMM_LEN];
};