diff options
author | Leonid Rosenboim <lrosenbo@wrs.com> | 2013-07-30 20:14:25 +0200 |
---|---|---|
committer | David Lamparter <equinox@opensourcerouting.org> | 2013-07-30 20:20:07 +0200 |
commit | 397b5bded5654a31b4bd3b904f091fd3859aecf7 (patch) | |
tree | 5b2a0f99bfa8dd6b774c1149948bc7a5aec3d7d5 /bgpd | |
parent | c423d413e464913ee88c1ee700e2c4037e6bdb24 (diff) |
bgpd: stricter packet handling in OpenSent
Keepalives and updates are not expected in OpenSent, prior to receiving
the peer's open message. Terminate the session with the proper
notification.
From: Leonid Rosenboim <lrosenbo@wrs.com>
[split off FSM changes, some reordering & cleanup. read handling needs
to be separately addressed]
Signed-off-by: David Lamparter <equinox@diac24.net>
Diffstat (limited to 'bgpd')
-rw-r--r-- | bgpd/bgp_fsm.c | 59 |
1 files changed, 41 insertions, 18 deletions
diff --git a/bgpd/bgp_fsm.c b/bgpd/bgp_fsm.c index d9200457..fba94276 100644 --- a/bgpd/bgp_fsm.c +++ b/bgpd/bgp_fsm.c @@ -592,6 +592,32 @@ bgp_stop_with_error (struct peer *peer) return 0; } + +/* something went wrong, send notify and tear down */ +static int +bgp_stop_with_notify (struct peer *peer, u_char code, u_char sub_code) +{ + /* Send notify to remote peer */ + bgp_notify_send (peer, code, sub_code); + + /* Sweep if it is temporary peer. */ + if (CHECK_FLAG (peer->sflags, PEER_STATUS_ACCEPT_PEER)) + { + zlog_info ("%s [Event] Accepting BGP peer is deleted", peer->host); + peer_delete (peer); + return -1; + } + + /* Clear start timer value to default. */ + peer->v_start = BGP_INIT_START_TIMER; + + /* bgp_stop needs to be invoked while in Established state */ + bgp_stop(peer); + + return 0; +} + + /* TCP connection open. Next we send open message to remote peer. And add read thread for reading open message. */ static int @@ -740,29 +766,26 @@ bgp_fsm_keepalive_expire (struct peer *peer) return 0; } +/* FSM error, unexpected event. This is error of BGP connection. So cut the + peer and change to Idle status. */ +static int +bgp_fsm_event_error (struct peer *peer) +{ + plog_err (peer->log, "%s [FSM] unexpected packet received in state %s", + peer->host, LOOKUP (bgp_status_msg, peer->status)); + + return bgp_stop_with_notify (peer, BGP_NOTIFY_FSM_ERR, 0); +} + /* Hold timer expire. This is error of BGP connection. So cut the peer and change to Idle status. */ static int bgp_fsm_holdtime_expire (struct peer *peer) { if (BGP_DEBUG (fsm, FSM)) - zlog (peer->log, LOG_DEBUG, "%s [FSM] Hold timer expire", peer->host); + plog_debug (peer->log, "%s [FSM] Hold timer expire", peer->host); - /* Send notify to remote peer. */ - bgp_notify_send (peer, BGP_NOTIFY_HOLD_ERR, 0); - - /* Sweep if it is temporary peer. */ - if (CHECK_FLAG (peer->sflags, PEER_STATUS_ACCEPT_PEER)) - { - zlog_info ("%s [Event] Accepting BGP peer is deleted", peer->host); - peer_delete (peer); - return -1; - } - - /* bgp_stop needs to be invoked while in Established state */ - bgp_stop(peer); - - return 0; + return bgp_stop_with_notify (peer, BGP_NOTIFY_HOLD_ERR, 0); } /* Status goes to Established. Send keepalive packet then make first @@ -977,8 +1000,8 @@ static const struct { {bgp_fsm_holdtime_expire, Idle}, /* Hold_Timer_expired */ {bgp_ignore, Idle}, /* KeepAlive_timer_expired */ {bgp_fsm_open, OpenConfirm}, /* Receive_OPEN_message */ - {bgp_ignore, Idle}, /* Receive_KEEPALIVE_message */ - {bgp_ignore, Idle}, /* Receive_UPDATE_message */ + {bgp_fsm_event_error, Idle}, /* Receive_KEEPALIVE_message */ + {bgp_fsm_event_error, Idle}, /* Receive_UPDATE_message */ {bgp_stop_with_error, Idle}, /* Receive_NOTIFICATION_message */ {bgp_ignore, Idle}, /* Clearing_Completed */ }, |