summaryrefslogtreecommitdiff
path: root/proto/bgp
diff options
context:
space:
mode:
Diffstat (limited to 'proto/bgp')
-rw-r--r--proto/bgp/bgp.c23
-rw-r--r--proto/bgp/bgp.h2
2 files changed, 20 insertions, 5 deletions
diff --git a/proto/bgp/bgp.c b/proto/bgp/bgp.c
index 470c6ff5..cfc31ed0 100644
--- a/proto/bgp/bgp.c
+++ b/proto/bgp/bgp.c
@@ -422,7 +422,7 @@ bgp_update_startup_delay(struct bgp_proto *p)
}
static void
-bgp_graceful_close_conn(struct bgp_conn *conn, uint subcode, byte *data, uint len)
+bgp_graceful_close_conn(struct bgp_conn *conn, int subcode, byte *data, uint len)
{
switch (conn->state)
{
@@ -438,7 +438,13 @@ bgp_graceful_close_conn(struct bgp_conn *conn, uint subcode, byte *data, uint le
case BS_OPENSENT:
case BS_OPENCONFIRM:
case BS_ESTABLISHED:
- bgp_error(conn, 6, subcode, data, len);
+ if (subcode < 0)
+ {
+ bgp_conn_enter_close_state(conn);
+ bgp_schedule_packet(conn, NULL, PKT_SCHEDULE_CLOSE);
+ }
+ else
+ bgp_error(conn, 6, subcode, data, len);
return;
default:
@@ -501,7 +507,7 @@ bgp_spawn(struct bgp_proto *pp, ip_addr remote_ip)
}
void
-bgp_stop(struct bgp_proto *p, uint subcode, byte *data, uint len)
+bgp_stop(struct bgp_proto *p, int subcode, byte *data, uint len)
{
proto_notify_state(&p->p, PS_STOP);
bgp_graceful_close_conn(&p->outgoing_conn, subcode, data, len);
@@ -1555,7 +1561,7 @@ static int
bgp_shutdown(struct proto *P)
{
struct bgp_proto *p = (struct bgp_proto *) P;
- uint subcode = 0;
+ int subcode = 0;
char *message = NULL;
byte *data = NULL;
@@ -1576,6 +1582,7 @@ bgp_shutdown(struct proto *P)
case PDC_CMD_DISABLE:
case PDC_CMD_SHUTDOWN:
+ shutdown:
subcode = 2; // Errcode 6, 2 - administrative shutdown
message = P->message;
break;
@@ -1585,6 +1592,14 @@ bgp_shutdown(struct proto *P)
message = P->message;
break;
+ case PDC_CMD_GR_DOWN:
+ if ((p->cf->gr_mode != BGP_GR_ABLE) &&
+ (p->cf->llgr_mode != BGP_LLGR_ABLE))
+ goto shutdown;
+
+ subcode = -1; // Do not send NOTIFICATION, just close the connection
+ break;
+
case PDC_RX_LIMIT_HIT:
case PDC_IN_LIMIT_HIT:
subcode = 1; // Errcode 6, 1 - max number of prefixes reached
diff --git a/proto/bgp/bgp.h b/proto/bgp/bgp.h
index d8c9fe94..d7f7427f 100644
--- a/proto/bgp/bgp.h
+++ b/proto/bgp/bgp.h
@@ -488,7 +488,7 @@ void bgp_graceful_restart_done(struct bgp_channel *c);
void bgp_refresh_begin(struct bgp_channel *c);
void bgp_refresh_end(struct bgp_channel *c);
void bgp_store_error(struct bgp_proto *p, struct bgp_conn *c, u8 class, u32 code);
-void bgp_stop(struct bgp_proto *p, uint subcode, byte *data, uint len);
+void bgp_stop(struct bgp_proto *p, int subcode, byte *data, uint len);
struct rte_source *bgp_find_source(struct bgp_proto *p, u32 path_id);
struct rte_source *bgp_get_source(struct bgp_proto *p, u32 path_id);