diff options
Diffstat (limited to 'proto')
-rw-r--r-- | proto/bgp/bgp.h | 1 | ||||
-rw-r--r-- | proto/bgp/config.Y | 30 | ||||
-rw-r--r-- | proto/bgp/packets.c | 10 |
3 files changed, 41 insertions, 0 deletions
diff --git a/proto/bgp/bgp.h b/proto/bgp/bgp.h index 1310582b..30424abb 100644 --- a/proto/bgp/bgp.h +++ b/proto/bgp/bgp.h @@ -118,6 +118,7 @@ struct bgp_config { unsigned error_delay_time_min; /* Time to wait after an error is detected */ unsigned error_delay_time_max; unsigned disable_after_error; /* Disable the protocol when error is detected */ + u32 disable_after_cease; /* Disable it when cease is received, bitfield */ char *password; /* Password used for MD5 authentication */ int check_link; /* Use iface link state for liveness detection */ diff --git a/proto/bgp/config.Y b/proto/bgp/config.Y index 04e6d666..41eaa729 100644 --- a/proto/bgp/config.Y +++ b/proto/bgp/config.Y @@ -32,6 +32,12 @@ CF_KEYWORDS(BGP, LOCAL, NEIGHBOR, AS, HOLD, TIME, CONNECT, RETRY, KEEPALIVE, %type <i32> bgp_afi +CF_KEYWORDS(CEASE, PREFIX, LIMIT, HIT, ADMINISTRATIVE, SHUTDOWN, RESET, PEER, + CONFIGURATION, CHANGE, DECONFIGURED, CONNECTION, REJECTED, COLLISION, + OUT, OF, RESOURCES) + +%type<i> bgp_cease_mask bgp_cease_list bgp_cease_flag + CF_GRAMMAR CF_ADDTO(proto, bgp_proto '}' ) @@ -74,6 +80,29 @@ bgp_nbr_opts: | bgp_nbr_opts AS expr { BGP_CFG->remote_as = $3; } ; +bgp_cease_mask: + /* true -> all except connection collision */ + bool { $$ = $1 ? ~(1 << 7) : 0; } + | '{' bgp_cease_list '}' { $$ = $2; } + ; + +bgp_cease_list: + bgp_cease_flag + | bgp_cease_list ',' bgp_cease_flag { $$ = $1 | $3; } + ; + +bgp_cease_flag: + CEASE { $$ = 1 << 0; } + | PREFIX LIMIT HIT { $$ = 1 << 1; } + | ADMINISTRATIVE SHUTDOWN { $$ = 1 << 2; } + | PEER DECONFIGURED { $$ = 1 << 3; } + | ADMINISTRATIVE RESET { $$ = 1 << 4; } + | CONNECTION REJECTED { $$ = 1 << 5; } + | CONFIGURATION CHANGE { $$ = 1 << 6; } + | CONNECTION COLLISION { $$ = 1 << 7; } + | OUT OF RESOURCES { $$ = 1 << 8; } + ; + bgp_proto: bgp_proto_start proto_name '{' | bgp_proto proto_item ';' @@ -117,6 +146,7 @@ bgp_proto: | bgp_proto ERROR FORGET TIME expr ';' { BGP_CFG->error_amnesia_time = $5; } | bgp_proto ERROR WAIT TIME expr ',' expr ';' { BGP_CFG->error_delay_time_min = $5; BGP_CFG->error_delay_time_max = $7; } | bgp_proto DISABLE AFTER ERROR bool ';' { BGP_CFG->disable_after_error = $5; } + | bgp_proto DISABLE AFTER CEASE bgp_cease_mask ';' { BGP_CFG->disable_after_cease = $5; } | bgp_proto ENABLE ROUTE REFRESH bool ';' { BGP_CFG->enable_refresh = $5; } | bgp_proto ENABLE AS4 bool ';' { BGP_CFG->enable_as4 = $4; } | bgp_proto ENABLE EXTENDED MESSAGES bool ';' { BGP_CFG->enable_extended_messages = $5; } diff --git a/proto/bgp/packets.c b/proto/bgp/packets.c index 95a974eb..aa08732d 100644 --- a/proto/bgp/packets.c +++ b/proto/bgp/packets.c @@ -2772,6 +2772,16 @@ bgp_rx_notification(struct bgp_conn *conn, byte *pkt, uint len) bgp_update_startup_delay(p); bgp_stop(p, 0, NULL, 0); } + else + { + uint subcode_bit = 1 << ((subcode <= 8) ? subcode : 0); + if (p->cf->disable_after_cease & subcode_bit) + { + log(L_INFO "%s: Disabled after Cease notification", p->p.name); + p->startup_delay = 0; + p->p.disabled = 1; + } + } } static void |