bgp_fsm.c 36 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205
  1. /* BGP-4 Finite State Machine
  2. From RFC1771 [A Border Gateway Protocol 4 (BGP-4)]
  3. Copyright (C) 1996, 97, 98 Kunihiro Ishiguro
  4. This file is part of GNU Zebra.
  5. GNU Zebra is free software; you can redistribute it and/or modify it
  6. under the terms of the GNU General Public License as published by the
  7. Free Software Foundation; either version 2, or (at your option) any
  8. later version.
  9. GNU Zebra is distributed in the hope that it will be useful, but
  10. WITHOUT ANY WARRANTY; without even the implied warranty of
  11. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  12. General Public License for more details.
  13. You should have received a copy of the GNU General Public License
  14. along with GNU Zebra; see the file COPYING. If not, write to the Free
  15. Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
  16. 02111-1307, USA. */
  17. #include <zebra.h>
  18. #include "linklist.h"
  19. #include "prefix.h"
  20. #include "vty.h"
  21. #include "sockunion.h"
  22. #include "thread.h"
  23. #include "log.h"
  24. #include "stream.h"
  25. #include "memory.h"
  26. #include "plist.h"
  27. #include "workqueue.h"
  28. #include "filter.h"
  29. #include "bgpd/bgpd.h"
  30. #include "bgpd/bgp_attr.h"
  31. #include "bgpd/bgp_debug.h"
  32. #include "bgpd/bgp_fsm.h"
  33. #include "bgpd/bgp_packet.h"
  34. #include "bgpd/bgp_network.h"
  35. #include "bgpd/bgp_route.h"
  36. #include "bgpd/bgp_dump.h"
  37. #include "bgpd/bgp_open.h"
  38. #include "bgpd/bgp_nht.h"
  39. #ifdef HAVE_SNMP
  40. #include "bgpd/bgp_snmp.h"
  41. #endif /* HAVE_SNMP */
  42. /* BGP FSM (finite state machine) has three types of functions. Type
  43. one is thread functions. Type two is event functions. Type three
  44. is FSM functions. Timer functions are set by bgp_timer_set
  45. function. */
  46. /* BGP event function. */
  47. int bgp_event (struct thread *);
  48. /* BGP thread functions. */
  49. static int bgp_start_timer (struct thread *);
  50. static int bgp_connect_timer (struct thread *);
  51. static int bgp_holdtime_timer (struct thread *);
  52. static int bgp_keepalive_timer (struct thread *);
  53. /* BGP FSM functions. */
  54. static int bgp_start (struct peer *);
  55. /* BGP start timer jitter. */
  56. static int
  57. bgp_start_jitter (int time)
  58. {
  59. return ((random () % (time + 1)) - (time / 2));
  60. }
  61. /* Check if suppress start/restart of sessions to peer. */
  62. #define BGP_PEER_START_SUPPRESSED(P) \
  63. (CHECK_FLAG ((P)->flags, PEER_FLAG_SHUTDOWN) \
  64. || CHECK_FLAG ((P)->sflags, PEER_STATUS_PREFIX_OVERFLOW))
  65. /* Hook function called after bgp event is occered. And vty's
  66. neighbor command invoke this function after making neighbor
  67. structure. */
  68. void
  69. bgp_timer_set (struct peer *peer)
  70. {
  71. int jitter = 0;
  72. switch (peer->status)
  73. {
  74. case Idle:
  75. /* First entry point of peer's finite state machine. In Idle
  76. status start timer is on unless peer is shutdown or peer is
  77. inactive. All other timer must be turned off */
  78. if (BGP_PEER_START_SUPPRESSED (peer) || ! peer_active (peer))
  79. {
  80. BGP_TIMER_OFF (peer->t_start);
  81. }
  82. else
  83. {
  84. jitter = bgp_start_jitter (peer->v_start);
  85. BGP_TIMER_ON (peer->t_start, bgp_start_timer,
  86. peer->v_start + jitter);
  87. }
  88. BGP_TIMER_OFF (peer->t_connect);
  89. BGP_TIMER_OFF (peer->t_holdtime);
  90. BGP_TIMER_OFF (peer->t_keepalive);
  91. BGP_TIMER_OFF (peer->t_routeadv);
  92. break;
  93. case Connect:
  94. /* After start timer is expired, the peer moves to Connect
  95. status. Make sure start timer is off and connect timer is
  96. on. */
  97. BGP_TIMER_OFF (peer->t_start);
  98. BGP_TIMER_ON (peer->t_connect, bgp_connect_timer, peer->v_connect);
  99. BGP_TIMER_OFF (peer->t_holdtime);
  100. BGP_TIMER_OFF (peer->t_keepalive);
  101. BGP_TIMER_OFF (peer->t_routeadv);
  102. break;
  103. case Active:
  104. /* Active is waiting connection from remote peer. And if
  105. connect timer is expired, change status to Connect. */
  106. BGP_TIMER_OFF (peer->t_start);
  107. /* If peer is passive mode, do not set connect timer. */
  108. if (CHECK_FLAG (peer->flags, PEER_FLAG_PASSIVE)
  109. || CHECK_FLAG (peer->sflags, PEER_STATUS_NSF_WAIT))
  110. {
  111. BGP_TIMER_OFF (peer->t_connect);
  112. }
  113. else
  114. {
  115. BGP_TIMER_ON (peer->t_connect, bgp_connect_timer, peer->v_connect);
  116. }
  117. BGP_TIMER_OFF (peer->t_holdtime);
  118. BGP_TIMER_OFF (peer->t_keepalive);
  119. BGP_TIMER_OFF (peer->t_routeadv);
  120. break;
  121. case OpenSent:
  122. /* OpenSent status. */
  123. BGP_TIMER_OFF (peer->t_start);
  124. BGP_TIMER_OFF (peer->t_connect);
  125. if (peer->v_holdtime != 0)
  126. {
  127. BGP_TIMER_ON (peer->t_holdtime, bgp_holdtime_timer,
  128. peer->v_holdtime);
  129. }
  130. else
  131. {
  132. BGP_TIMER_OFF (peer->t_holdtime);
  133. }
  134. BGP_TIMER_OFF (peer->t_keepalive);
  135. BGP_TIMER_OFF (peer->t_routeadv);
  136. break;
  137. case OpenConfirm:
  138. /* OpenConfirm status. */
  139. BGP_TIMER_OFF (peer->t_start);
  140. BGP_TIMER_OFF (peer->t_connect);
  141. /* If the negotiated Hold Time value is zero, then the Hold Time
  142. timer and KeepAlive timers are not started. */
  143. if (peer->v_holdtime == 0)
  144. {
  145. BGP_TIMER_OFF (peer->t_holdtime);
  146. BGP_TIMER_OFF (peer->t_keepalive);
  147. }
  148. else
  149. {
  150. BGP_TIMER_ON (peer->t_holdtime, bgp_holdtime_timer,
  151. peer->v_holdtime);
  152. BGP_TIMER_ON (peer->t_keepalive, bgp_keepalive_timer,
  153. peer->v_keepalive);
  154. }
  155. BGP_TIMER_OFF (peer->t_routeadv);
  156. break;
  157. case Established:
  158. /* In Established status start and connect timer is turned
  159. off. */
  160. BGP_TIMER_OFF (peer->t_start);
  161. BGP_TIMER_OFF (peer->t_connect);
  162. /* Same as OpenConfirm, if holdtime is zero then both holdtime
  163. and keepalive must be turned off. */
  164. if (peer->v_holdtime == 0)
  165. {
  166. BGP_TIMER_OFF (peer->t_holdtime);
  167. BGP_TIMER_OFF (peer->t_keepalive);
  168. }
  169. else
  170. {
  171. BGP_TIMER_ON (peer->t_holdtime, bgp_holdtime_timer,
  172. peer->v_holdtime);
  173. BGP_TIMER_ON (peer->t_keepalive, bgp_keepalive_timer,
  174. peer->v_keepalive);
  175. }
  176. break;
  177. case Deleted:
  178. BGP_TIMER_OFF (peer->t_gr_restart);
  179. BGP_TIMER_OFF (peer->t_gr_stale);
  180. BGP_TIMER_OFF (peer->t_pmax_restart);
  181. case Clearing:
  182. BGP_TIMER_OFF (peer->t_start);
  183. BGP_TIMER_OFF (peer->t_connect);
  184. BGP_TIMER_OFF (peer->t_holdtime);
  185. BGP_TIMER_OFF (peer->t_keepalive);
  186. BGP_TIMER_OFF (peer->t_routeadv);
  187. }
  188. }
  189. /* BGP start timer. This function set BGP_Start event to thread value
  190. and process event. */
  191. static int
  192. bgp_start_timer (struct thread *thread)
  193. {
  194. struct peer *peer;
  195. peer = THREAD_ARG (thread);
  196. peer->t_start = NULL;
  197. if (BGP_DEBUG (fsm, FSM))
  198. zlog (peer->log, LOG_DEBUG,
  199. "%s [FSM] Timer (start timer expire).", peer->host);
  200. THREAD_VAL (thread) = BGP_Start;
  201. bgp_event (thread); /* bgp_event unlocks peer */
  202. return 0;
  203. }
  204. /* BGP connect retry timer. */
  205. static int
  206. bgp_connect_timer (struct thread *thread)
  207. {
  208. struct peer *peer;
  209. peer = THREAD_ARG (thread);
  210. peer->t_connect = NULL;
  211. if (BGP_DEBUG (fsm, FSM))
  212. zlog (peer->log, LOG_DEBUG, "%s [FSM] Timer (connect timer expire)",
  213. peer->host);
  214. THREAD_VAL (thread) = ConnectRetry_timer_expired;
  215. bgp_event (thread); /* bgp_event unlocks peer */
  216. return 0;
  217. }
  218. /* BGP holdtime timer. */
  219. static int
  220. bgp_holdtime_timer (struct thread *thread)
  221. {
  222. struct peer *peer;
  223. peer = THREAD_ARG (thread);
  224. peer->t_holdtime = NULL;
  225. if (BGP_DEBUG (fsm, FSM))
  226. zlog (peer->log, LOG_DEBUG,
  227. "%s [FSM] Timer (holdtime timer expire)",
  228. peer->host);
  229. THREAD_VAL (thread) = Hold_Timer_expired;
  230. bgp_event (thread); /* bgp_event unlocks peer */
  231. return 0;
  232. }
  233. /* BGP keepalive fire ! */
  234. static int
  235. bgp_keepalive_timer (struct thread *thread)
  236. {
  237. struct peer *peer;
  238. peer = THREAD_ARG (thread);
  239. peer->t_keepalive = NULL;
  240. if (BGP_DEBUG (fsm, FSM))
  241. zlog (peer->log, LOG_DEBUG,
  242. "%s [FSM] Timer (keepalive timer expire)",
  243. peer->host);
  244. THREAD_VAL (thread) = KeepAlive_timer_expired;
  245. bgp_event (thread); /* bgp_event unlocks peer */
  246. return 0;
  247. }
  248. static int
  249. bgp_routeadv_timer (struct thread *thread)
  250. {
  251. struct peer *peer;
  252. peer = THREAD_ARG (thread);
  253. peer->t_routeadv = NULL;
  254. if (BGP_DEBUG (fsm, FSM))
  255. zlog (peer->log, LOG_DEBUG,
  256. "%s [FSM] Timer (routeadv timer expire)",
  257. peer->host);
  258. peer->synctime = bgp_clock ();
  259. BGP_WRITE_ON (peer->t_write, bgp_write, peer->fd);
  260. BGP_TIMER_ON (peer->t_routeadv, bgp_routeadv_timer,
  261. peer->v_routeadv);
  262. return 0;
  263. }
  264. /* BGP Peer Down Cause */
  265. const char *peer_down_str[] =
  266. {
  267. "",
  268. "Router ID changed",
  269. "Remote AS changed",
  270. "Local AS change",
  271. "Cluster ID changed",
  272. "Confederation identifier changed",
  273. "Confederation peer changed",
  274. "RR client config change",
  275. "RS client config change",
  276. "Update source change",
  277. "Address family activated",
  278. "Admin. shutdown",
  279. "User reset",
  280. "BGP Notification received",
  281. "BGP Notification send",
  282. "Peer closed the session",
  283. "Neighbor deleted",
  284. "Peer-group add member",
  285. "Peer-group delete member",
  286. "Capability changed",
  287. "Passive config change",
  288. "Multihop config change",
  289. "NSF peer closed the session"
  290. };
  291. static int
  292. bgp_graceful_restart_timer_expire (struct thread *thread)
  293. {
  294. struct peer *peer;
  295. afi_t afi;
  296. safi_t safi;
  297. peer = THREAD_ARG (thread);
  298. peer->t_gr_restart = NULL;
  299. /* NSF delete stale route */
  300. for (afi = AFI_IP ; afi < AFI_MAX ; afi++)
  301. for (safi = SAFI_UNICAST ; safi < SAFI_RESERVED_3 ; safi++)
  302. if (peer->nsf[afi][safi])
  303. bgp_clear_stale_route (peer, afi, safi);
  304. UNSET_FLAG (peer->sflags, PEER_STATUS_NSF_WAIT);
  305. BGP_TIMER_OFF (peer->t_gr_stale);
  306. if (BGP_DEBUG (events, EVENTS))
  307. {
  308. zlog_debug ("%s graceful restart timer expired", peer->host);
  309. zlog_debug ("%s graceful restart stalepath timer stopped", peer->host);
  310. }
  311. bgp_timer_set (peer);
  312. return 0;
  313. }
  314. static int
  315. bgp_graceful_stale_timer_expire (struct thread *thread)
  316. {
  317. struct peer *peer;
  318. afi_t afi;
  319. safi_t safi;
  320. peer = THREAD_ARG (thread);
  321. peer->t_gr_stale = NULL;
  322. if (BGP_DEBUG (events, EVENTS))
  323. zlog_debug ("%s graceful restart stalepath timer expired", peer->host);
  324. /* NSF delete stale route */
  325. for (afi = AFI_IP ; afi < AFI_MAX ; afi++)
  326. for (safi = SAFI_UNICAST ; safi < SAFI_RESERVED_3 ; safi++)
  327. if (peer->nsf[afi][safi])
  328. bgp_clear_stale_route (peer, afi, safi);
  329. return 0;
  330. }
  331. /* Called after event occurred, this function change status and reset
  332. read/write and timer thread. */
  333. void
  334. bgp_fsm_change_status (struct peer *peer, int status)
  335. {
  336. bgp_dump_state (peer, peer->status, status);
  337. /* Transition into Clearing or Deleted must /always/ clear all routes..
  338. * (and must do so before actually changing into Deleted..
  339. */
  340. if (status >= Clearing)
  341. {
  342. bgp_clear_route_all (peer);
  343. /* If no route was queued for the clear-node processing, generate the
  344. * completion event here. This is needed because if there are no routes
  345. * to trigger the background clear-node thread, the event won't get
  346. * generated and the peer would be stuck in Clearing. Note that this
  347. * event is for the peer and helps the peer transition out of Clearing
  348. * state; it should not be generated per (AFI,SAFI). The event is
  349. * directly posted here without calling clear_node_complete() as we
  350. * shouldn't do an extra unlock. This event will get processed after
  351. * the state change that happens below, so peer will be in Clearing
  352. * (or Deleted).
  353. */
  354. if (!work_queue_is_scheduled (peer->clear_node_queue))
  355. BGP_EVENT_ADD (peer, Clearing_Completed);
  356. }
  357. /* Preserve old status and change into new status. */
  358. peer->ostatus = peer->status;
  359. peer->status = status;
  360. if (BGP_DEBUG (normal, NORMAL))
  361. zlog_debug ("%s went from %s to %s",
  362. peer->host,
  363. LOOKUP (bgp_status_msg, peer->ostatus),
  364. LOOKUP (bgp_status_msg, peer->status));
  365. }
  366. /* Flush the event queue and ensure the peer is shut down */
  367. static int
  368. bgp_clearing_completed (struct peer *peer)
  369. {
  370. int rc = bgp_stop(peer);
  371. BGP_EVENT_FLUSH (peer);
  372. return rc;
  373. }
  374. /* Administrative BGP peer stop event. */
  375. /* May be called multiple times for the same peer */
  376. int
  377. bgp_stop (struct peer *peer)
  378. {
  379. afi_t afi;
  380. safi_t safi;
  381. char orf_name[BUFSIZ];
  382. /* Can't do this in Clearing; events are used for state transitions */
  383. if (peer->status != Clearing)
  384. {
  385. /* Delete all existing events of the peer */
  386. BGP_EVENT_FLUSH (peer);
  387. }
  388. /* Increment Dropped count. */
  389. if (peer->status == Established)
  390. {
  391. peer->dropped++;
  392. /* bgp log-neighbor-changes of neighbor Down */
  393. if (bgp_flag_check (peer->bgp, BGP_FLAG_LOG_NEIGHBOR_CHANGES))
  394. zlog_info ("%%ADJCHANGE: neighbor %s Down %s", peer->host,
  395. peer_down_str [(int) peer->last_reset]);
  396. /* graceful restart */
  397. if (peer->t_gr_stale)
  398. {
  399. BGP_TIMER_OFF (peer->t_gr_stale);
  400. if (BGP_DEBUG (events, EVENTS))
  401. zlog_debug ("%s graceful restart stalepath timer stopped", peer->host);
  402. }
  403. if (CHECK_FLAG (peer->sflags, PEER_STATUS_NSF_WAIT))
  404. {
  405. if (BGP_DEBUG (events, EVENTS))
  406. {
  407. zlog_debug ("%s graceful restart timer started for %d sec",
  408. peer->host, peer->v_gr_restart);
  409. zlog_debug ("%s graceful restart stalepath timer started for %d sec",
  410. peer->host, peer->bgp->stalepath_time);
  411. }
  412. BGP_TIMER_ON (peer->t_gr_restart, bgp_graceful_restart_timer_expire,
  413. peer->v_gr_restart);
  414. BGP_TIMER_ON (peer->t_gr_stale, bgp_graceful_stale_timer_expire,
  415. peer->bgp->stalepath_time);
  416. }
  417. else
  418. {
  419. UNSET_FLAG (peer->sflags, PEER_STATUS_NSF_MODE);
  420. for (afi = AFI_IP ; afi < AFI_MAX ; afi++)
  421. for (safi = SAFI_UNICAST ; safi < SAFI_RESERVED_3 ; safi++)
  422. peer->nsf[afi][safi] = 0;
  423. }
  424. /* set last reset time */
  425. peer->resettime = peer->uptime = bgp_clock ();
  426. #ifdef HAVE_SNMP
  427. bgpTrapBackwardTransition (peer);
  428. #endif /* HAVE_SNMP */
  429. /* Reset peer synctime */
  430. peer->synctime = 0;
  431. }
  432. /* Stop read and write threads when exists. */
  433. BGP_READ_OFF (peer->t_read);
  434. BGP_WRITE_OFF (peer->t_write);
  435. /* Stop all timers. */
  436. BGP_TIMER_OFF (peer->t_start);
  437. BGP_TIMER_OFF (peer->t_connect);
  438. BGP_TIMER_OFF (peer->t_holdtime);
  439. BGP_TIMER_OFF (peer->t_keepalive);
  440. BGP_TIMER_OFF (peer->t_routeadv);
  441. /* Stream reset. */
  442. peer->packet_size = 0;
  443. /* Clear input and output buffer. */
  444. if (peer->ibuf)
  445. stream_reset (peer->ibuf);
  446. if (peer->work)
  447. stream_reset (peer->work);
  448. if (peer->obuf)
  449. stream_fifo_clean (peer->obuf);
  450. /* Close of file descriptor. */
  451. if (peer->fd >= 0)
  452. {
  453. close (peer->fd);
  454. peer->fd = -1;
  455. }
  456. for (afi = AFI_IP ; afi < AFI_MAX ; afi++)
  457. for (safi = SAFI_UNICAST ; safi < SAFI_MAX ; safi++)
  458. {
  459. /* Reset all negotiated variables */
  460. peer->afc_nego[afi][safi] = 0;
  461. peer->afc_adv[afi][safi] = 0;
  462. peer->afc_recv[afi][safi] = 0;
  463. /* peer address family capability flags*/
  464. peer->af_cap[afi][safi] = 0;
  465. /* peer address family status flags*/
  466. peer->af_sflags[afi][safi] = 0;
  467. /* Received ORF prefix-filter */
  468. peer->orf_plist[afi][safi] = NULL;
  469. /* ORF received prefix-filter pnt */
  470. sprintf (orf_name, "%s.%d.%d", peer->host, afi, safi);
  471. prefix_bgp_orf_remove_all (afi, orf_name);
  472. }
  473. /* Reset keepalive and holdtime */
  474. if (CHECK_FLAG (peer->config, PEER_CONFIG_TIMER))
  475. {
  476. peer->v_keepalive = peer->keepalive;
  477. peer->v_holdtime = peer->holdtime;
  478. }
  479. else
  480. {
  481. peer->v_keepalive = peer->bgp->default_keepalive;
  482. peer->v_holdtime = peer->bgp->default_holdtime;
  483. }
  484. peer->update_time = 0;
  485. /* Until we are sure that there is no problem about prefix count
  486. this should be commented out.*/
  487. #if 0
  488. /* Reset prefix count */
  489. peer->pcount[AFI_IP][SAFI_UNICAST] = 0;
  490. peer->pcount[AFI_IP][SAFI_MULTICAST] = 0;
  491. peer->pcount[AFI_IP][SAFI_MPLS_VPN] = 0;
  492. peer->pcount[AFI_IP6][SAFI_UNICAST] = 0;
  493. peer->pcount[AFI_IP6][SAFI_MULTICAST] = 0;
  494. #endif /* 0 */
  495. return 0;
  496. }
  497. /* first-val * 2**x back-off, where x is the number of sucessive calls
  498. * originally used for peer v_start back-off
  499. */
  500. __attribute__((unused))
  501. static int
  502. back_off_exp2 (const int first, int val, const int max)
  503. {
  504. val <<= 1;
  505. return (val < max ? val : max);
  506. }
  507. /* exponential back off, but biased downward by the initial value.
  508. * this bias is significant at lower values, and tends to
  509. * insignificance fairly quickly, so it is equal to the previous at
  510. * scale. Is below first-val * 1.7**x at x == 6, and below first-val
  511. * * 1.75**x at x=10.
  512. *
  513. * I.e., this function is useful to get slower growth for the initial
  514. * points of x.
  515. */
  516. __attribute__((unused))
  517. static int
  518. back_off_exp2_bias (const int first, int val, const int max)
  519. {
  520. val = (val << 1) - (val > first ? first : 0);
  521. return (val < max ? val : max);
  522. }
  523. /* BGP peer is stoped by the error. */
  524. static int
  525. bgp_stop_with_error (struct peer *peer)
  526. {
  527. peer->v_start
  528. = back_off_exp2_bias (BGP_INIT_START_TIMER, peer->v_start, 60);
  529. bgp_stop (peer);
  530. return 0;
  531. }
  532. /* something went wrong, send notify and tear down */
  533. static int
  534. bgp_stop_with_notify (struct peer *peer, u_char code, u_char sub_code)
  535. {
  536. /* Send notify to remote peer */
  537. bgp_notify_send (peer, code, sub_code);
  538. /* Sweep if it is temporary peer. */
  539. if (CHECK_FLAG (peer->sflags, PEER_STATUS_ACCEPT_PEER))
  540. {
  541. zlog_info ("%s [Event] Accepting BGP peer is deleted", peer->host);
  542. peer_delete (peer);
  543. return -1;
  544. }
  545. /* Clear start timer value to default. */
  546. peer->v_start = BGP_INIT_START_TIMER;
  547. /* bgp_stop needs to be invoked while in Established state */
  548. bgp_stop(peer);
  549. return 0;
  550. }
  551. /* TCP connection open. Next we send open message to remote peer. And
  552. add read thread for reading open message. */
  553. static int
  554. bgp_connect_success (struct peer *peer)
  555. {
  556. struct peer *realpeer;
  557. if (peer->fd < 0)
  558. {
  559. zlog_err ("bgp_connect_success peer's fd is negative value %d",
  560. peer->fd);
  561. return -1;
  562. }
  563. BGP_READ_ON (peer->t_read, bgp_read, peer->fd);
  564. if (! CHECK_FLAG (peer->sflags, PEER_STATUS_ACCEPT_PEER))
  565. bgp_getsockname (peer);
  566. if (BGP_DEBUG (normal, NORMAL))
  567. {
  568. char buf1[SU_ADDRSTRLEN];
  569. if (! CHECK_FLAG (peer->sflags, PEER_STATUS_ACCEPT_PEER))
  570. zlog_debug ("%s open active, local address %s", peer->host,
  571. sockunion2str (peer->su_local, buf1, SU_ADDRSTRLEN));
  572. else
  573. zlog_debug ("%s passive open", peer->host);
  574. }
  575. /* Generally we want to send OPEN ASAP. Except, some partial BGP
  576. * implementations out there (e.g., conformance test tools / BGP
  577. * traffic generators) seem to be a bit funny about connection collisions,
  578. * and OPENs before they have sent.
  579. *
  580. * As a hack, delay sending OPEN on an inbound accept-peer session
  581. * _IF_ we locally have an outbound connection in progress, i.e.
  582. * we're in middle of a connection collision. If we delay, we delay until
  583. * an Open is received - as per old Quagga behaviour.
  584. */
  585. if (CHECK_FLAG (peer->sflags, PEER_STATUS_ACCEPT_PEER))
  586. {
  587. realpeer = peer_lookup (peer->bgp, &peer->su);
  588. if (realpeer->status > Idle && realpeer->status <= Established)
  589. {
  590. SET_FLAG (peer->sflags, PEER_STATUS_OPEN_DEFERRED);
  591. return 0;
  592. }
  593. }
  594. bgp_open_send (peer);
  595. return 0;
  596. }
  597. /* TCP connect fail */
  598. static int
  599. bgp_connect_fail (struct peer *peer)
  600. {
  601. bgp_stop (peer);
  602. return 0;
  603. }
  604. /* This function is the first starting point of all BGP connection. It
  605. try to connect to remote peer with non-blocking IO. */
  606. int
  607. bgp_start (struct peer *peer)
  608. {
  609. int status;
  610. int connected = 0;
  611. if (BGP_PEER_START_SUPPRESSED (peer))
  612. {
  613. if (BGP_DEBUG (fsm, FSM))
  614. plog_err (peer->log, "%s [FSM] Trying to start suppressed peer"
  615. " - this is never supposed to happen!", peer->host);
  616. return -1;
  617. }
  618. /* Scrub some information that might be left over from a previous,
  619. * session
  620. */
  621. /* Connection information. */
  622. if (peer->su_local)
  623. {
  624. sockunion_free (peer->su_local);
  625. peer->su_local = NULL;
  626. }
  627. if (peer->su_remote)
  628. {
  629. sockunion_free (peer->su_remote);
  630. peer->su_remote = NULL;
  631. }
  632. /* Clear remote router-id. */
  633. peer->remote_id.s_addr = 0;
  634. /* Clear peer capability flag. */
  635. peer->cap = 0;
  636. /* If the peer is passive mode, force to move to Active mode. */
  637. if (CHECK_FLAG (peer->flags, PEER_FLAG_PASSIVE))
  638. {
  639. BGP_EVENT_ADD (peer, TCP_connection_open_failed);
  640. return 0;
  641. }
  642. /* Register to be notified on peer up */
  643. if ((peer_ttl(peer) == 1 || peer->gtsm_hops == 1) &&
  644. ! CHECK_FLAG (peer->flags, PEER_FLAG_DISABLE_CONNECTED_CHECK))
  645. connected = 1;
  646. bgp_ensure_nexthop (NULL, peer, connected);
  647. status = bgp_connect (peer);
  648. switch (status)
  649. {
  650. case connect_error:
  651. if (BGP_DEBUG (fsm, FSM))
  652. plog_debug (peer->log, "%s [FSM] Connect error", peer->host);
  653. BGP_EVENT_ADD (peer, TCP_connection_open_failed);
  654. break;
  655. case connect_success:
  656. if (BGP_DEBUG (fsm, FSM))
  657. plog_debug (peer->log, "%s [FSM] Connect immediately success",
  658. peer->host);
  659. BGP_EVENT_ADD (peer, TCP_connection_open);
  660. break;
  661. case connect_in_progress:
  662. /* To check nonblocking connect, we wait until socket is
  663. readable or writable. */
  664. if (BGP_DEBUG (fsm, FSM))
  665. plog_debug (peer->log, "%s [FSM] Non blocking connect waiting result",
  666. peer->host);
  667. if (peer->fd < 0)
  668. {
  669. zlog_err ("bgp_start peer's fd is negative value %d",
  670. peer->fd);
  671. return -1;
  672. }
  673. BGP_READ_ON (peer->t_read, bgp_read, peer->fd);
  674. BGP_WRITE_ON (peer->t_write, bgp_write, peer->fd);
  675. break;
  676. }
  677. return 0;
  678. }
  679. /* Connect retry timer is expired when the peer status is Connect. */
  680. static int
  681. bgp_reconnect (struct peer *peer)
  682. {
  683. bgp_stop (peer);
  684. bgp_start (peer);
  685. return 0;
  686. }
  687. static int
  688. bgp_fsm_open (struct peer *peer)
  689. {
  690. /* Send keepalive and make keepalive timer */
  691. bgp_keepalive_send (peer);
  692. /* Reset holdtimer value. */
  693. BGP_TIMER_OFF (peer->t_holdtime);
  694. return 0;
  695. }
  696. /* Keepalive send to peer. */
  697. static int
  698. bgp_fsm_keepalive_expire (struct peer *peer)
  699. {
  700. bgp_keepalive_send (peer);
  701. return 0;
  702. }
  703. /* FSM error, unexpected event. This is error of BGP connection. So cut the
  704. peer and change to Idle status. */
  705. static int
  706. bgp_fsm_event_error (struct peer *peer)
  707. {
  708. plog_err (peer->log, "%s [FSM] unexpected packet received in state %s",
  709. peer->host, LOOKUP (bgp_status_msg, peer->status));
  710. return bgp_stop_with_notify (peer, BGP_NOTIFY_FSM_ERR, 0);
  711. }
  712. /* Hold timer expire. This is error of BGP connection. So cut the
  713. peer and change to Idle status. */
  714. static int
  715. bgp_fsm_holdtime_expire (struct peer *peer)
  716. {
  717. if (BGP_DEBUG (fsm, FSM))
  718. plog_debug (peer->log, "%s [FSM] Hold timer expire", peer->host);
  719. return bgp_stop_with_notify (peer, BGP_NOTIFY_HOLD_ERR, 0);
  720. }
  721. /* Status goes to Established. Send keepalive packet then make first
  722. update information. */
  723. static int
  724. bgp_establish (struct peer *peer)
  725. {
  726. struct bgp_notify *notify;
  727. afi_t afi;
  728. safi_t safi;
  729. int nsf_af_count = 0;
  730. /* Reset capability open status flag. */
  731. if (! CHECK_FLAG (peer->sflags, PEER_STATUS_CAPABILITY_OPEN))
  732. SET_FLAG (peer->sflags, PEER_STATUS_CAPABILITY_OPEN);
  733. /* Clear last notification data. */
  734. notify = &peer->notify;
  735. if (notify->data)
  736. XFREE (MTYPE_TMP, notify->data);
  737. memset (notify, 0, sizeof (struct bgp_notify));
  738. /* Clear start timer value to default. */
  739. peer->v_start = BGP_INIT_START_TIMER;
  740. /* Increment established count. */
  741. peer->established++;
  742. bgp_fsm_change_status (peer, Established);
  743. /* bgp log-neighbor-changes of neighbor Up */
  744. if (bgp_flag_check (peer->bgp, BGP_FLAG_LOG_NEIGHBOR_CHANGES))
  745. zlog_info ("%%ADJCHANGE: neighbor %s Up", peer->host);
  746. /* graceful restart */
  747. UNSET_FLAG (peer->sflags, PEER_STATUS_NSF_WAIT);
  748. for (afi = AFI_IP ; afi < AFI_MAX ; afi++)
  749. for (safi = SAFI_UNICAST ; safi < SAFI_RESERVED_3 ; safi++)
  750. {
  751. if (peer->afc_nego[afi][safi]
  752. && CHECK_FLAG (peer->cap, PEER_CAP_RESTART_ADV)
  753. && CHECK_FLAG (peer->af_cap[afi][safi], PEER_CAP_RESTART_AF_RCV))
  754. {
  755. if (peer->nsf[afi][safi]
  756. && ! CHECK_FLAG (peer->af_cap[afi][safi], PEER_CAP_RESTART_AF_PRESERVE_RCV))
  757. bgp_clear_stale_route (peer, afi, safi);
  758. peer->nsf[afi][safi] = 1;
  759. nsf_af_count++;
  760. }
  761. else
  762. {
  763. if (peer->nsf[afi][safi])
  764. bgp_clear_stale_route (peer, afi, safi);
  765. peer->nsf[afi][safi] = 0;
  766. }
  767. }
  768. if (nsf_af_count)
  769. SET_FLAG (peer->sflags, PEER_STATUS_NSF_MODE);
  770. else
  771. {
  772. UNSET_FLAG (peer->sflags, PEER_STATUS_NSF_MODE);
  773. if (peer->t_gr_stale)
  774. {
  775. BGP_TIMER_OFF (peer->t_gr_stale);
  776. if (BGP_DEBUG (events, EVENTS))
  777. zlog_debug ("%s graceful restart stalepath timer stopped", peer->host);
  778. }
  779. }
  780. if (peer->t_gr_restart)
  781. {
  782. BGP_TIMER_OFF (peer->t_gr_restart);
  783. if (BGP_DEBUG (events, EVENTS))
  784. zlog_debug ("%s graceful restart timer stopped", peer->host);
  785. }
  786. #ifdef HAVE_SNMP
  787. bgpTrapEstablished (peer);
  788. #endif /* HAVE_SNMP */
  789. /* Reset uptime, send keepalive, send current table. */
  790. peer->uptime = bgp_clock ();
  791. /* Send route-refresh when ORF is enabled */
  792. for (afi = AFI_IP ; afi < AFI_MAX ; afi++)
  793. for (safi = SAFI_UNICAST ; safi < SAFI_MAX ; safi++)
  794. if (CHECK_FLAG (peer->af_cap[afi][safi], PEER_CAP_ORF_PREFIX_SM_ADV))
  795. {
  796. if (CHECK_FLAG (peer->af_cap[afi][safi], PEER_CAP_ORF_PREFIX_RM_RCV))
  797. bgp_route_refresh_send (peer, afi, safi, ORF_TYPE_PREFIX,
  798. REFRESH_IMMEDIATE, 0);
  799. else if (CHECK_FLAG (peer->af_cap[afi][safi], PEER_CAP_ORF_PREFIX_RM_OLD_RCV))
  800. bgp_route_refresh_send (peer, afi, safi, ORF_TYPE_PREFIX_OLD,
  801. REFRESH_IMMEDIATE, 0);
  802. }
  803. if (peer->v_keepalive)
  804. bgp_keepalive_send (peer);
  805. /* First update is deferred until ORF or ROUTE-REFRESH is received */
  806. for (afi = AFI_IP ; afi < AFI_MAX ; afi++)
  807. for (safi = SAFI_UNICAST ; safi < SAFI_MAX ; safi++)
  808. if (CHECK_FLAG (peer->af_cap[afi][safi], PEER_CAP_ORF_PREFIX_RM_ADV))
  809. if (CHECK_FLAG (peer->af_cap[afi][safi], PEER_CAP_ORF_PREFIX_SM_RCV)
  810. || CHECK_FLAG (peer->af_cap[afi][safi], PEER_CAP_ORF_PREFIX_SM_OLD_RCV))
  811. SET_FLAG (peer->af_sflags[afi][safi], PEER_STATUS_ORF_WAIT_REFRESH);
  812. bgp_announce_route_all (peer);
  813. BGP_TIMER_ON (peer->t_routeadv, bgp_routeadv_timer, 1);
  814. return 0;
  815. }
  816. /* Keepalive packet is received. */
  817. static int
  818. bgp_fsm_keepalive (struct peer *peer)
  819. {
  820. /* peer count update */
  821. peer->keepalive_in++;
  822. BGP_TIMER_OFF (peer->t_holdtime);
  823. return 0;
  824. }
  825. /* Update packet is received. */
  826. static int
  827. bgp_fsm_update (struct peer *peer)
  828. {
  829. BGP_TIMER_OFF (peer->t_holdtime);
  830. return 0;
  831. }
  832. /* This is empty event. */
  833. static int
  834. bgp_ignore (struct peer *peer)
  835. {
  836. if (BGP_DEBUG (fsm, FSM))
  837. zlog (peer->log, LOG_DEBUG, "%s [FSM] bgp_ignore called", peer->host);
  838. return 0;
  839. }
  840. /* Finite State Machine structure */
  841. static const struct {
  842. int (*func) (struct peer *);
  843. int next_state;
  844. } FSM [BGP_STATUS_MAX - 1][BGP_EVENTS_MAX - 1] =
  845. {
  846. {
  847. /* Idle state: In Idle state, all events other than BGP_Start is
  848. ignored. With BGP_Start event, finite state machine calls
  849. bgp_start(). */
  850. {bgp_start, Connect}, /* BGP_Start */
  851. {bgp_stop, Idle}, /* BGP_Stop */
  852. {bgp_stop, Idle}, /* TCP_connection_open */
  853. {bgp_stop, Idle}, /* TCP_connection_closed */
  854. {bgp_ignore, Idle}, /* TCP_connection_open_failed */
  855. {bgp_stop, Idle}, /* TCP_fatal_error */
  856. {bgp_ignore, Idle}, /* ConnectRetry_timer_expired */
  857. {bgp_ignore, Idle}, /* Hold_Timer_expired */
  858. {bgp_ignore, Idle}, /* KeepAlive_timer_expired */
  859. {bgp_ignore, Idle}, /* Receive_OPEN_message */
  860. {bgp_ignore, Idle}, /* Receive_KEEPALIVE_message */
  861. {bgp_ignore, Idle}, /* Receive_UPDATE_message */
  862. {bgp_ignore, Idle}, /* Receive_NOTIFICATION_message */
  863. {bgp_ignore, Idle}, /* Clearing_Completed */
  864. {bgp_ignore, Idle}, /* BGP_Stop_with_error */
  865. },
  866. {
  867. /* Connect */
  868. {bgp_ignore, Connect}, /* BGP_Start */
  869. {bgp_stop, Idle}, /* BGP_Stop */
  870. {bgp_connect_success, OpenSent}, /* TCP_connection_open */
  871. {bgp_stop, Idle}, /* TCP_connection_closed */
  872. {bgp_connect_fail, Active}, /* TCP_connection_open_failed */
  873. {bgp_connect_fail, Idle}, /* TCP_fatal_error */
  874. {bgp_reconnect, Connect}, /* ConnectRetry_timer_expired */
  875. {bgp_ignore, Idle}, /* Hold_Timer_expired */
  876. {bgp_ignore, Idle}, /* KeepAlive_timer_expired */
  877. {bgp_ignore, Idle}, /* Receive_OPEN_message */
  878. {bgp_ignore, Idle}, /* Receive_KEEPALIVE_message */
  879. {bgp_ignore, Idle}, /* Receive_UPDATE_message */
  880. {bgp_stop, Idle}, /* Receive_NOTIFICATION_message */
  881. {bgp_ignore, Idle}, /* Clearing_Completed */
  882. {bgp_stop_with_error, Idle},/* BGP_Stop_with_error */
  883. },
  884. {
  885. /* Active, */
  886. {bgp_ignore, Active}, /* BGP_Start */
  887. {bgp_stop, Idle}, /* BGP_Stop */
  888. {bgp_connect_success, OpenSent}, /* TCP_connection_open */
  889. {bgp_stop, Idle}, /* TCP_connection_closed */
  890. {bgp_ignore, Active}, /* TCP_connection_open_failed */
  891. {bgp_ignore, Idle}, /* TCP_fatal_error */
  892. {bgp_start, Connect}, /* ConnectRetry_timer_expired */
  893. {bgp_ignore, Idle}, /* Hold_Timer_expired */
  894. {bgp_ignore, Idle}, /* KeepAlive_timer_expired */
  895. {bgp_ignore, Idle}, /* Receive_OPEN_message */
  896. {bgp_ignore, Idle}, /* Receive_KEEPALIVE_message */
  897. {bgp_ignore, Idle}, /* Receive_UPDATE_message */
  898. {bgp_stop_with_error, Idle}, /* Receive_NOTIFICATION_message */
  899. {bgp_ignore, Idle}, /* Clearing_Completed */
  900. {bgp_stop_with_error, Idle},/* BGP_Stop_with_error */
  901. },
  902. {
  903. /* OpenSent, */
  904. {bgp_ignore, OpenSent}, /* BGP_Start */
  905. {bgp_stop, Idle}, /* BGP_Stop */
  906. {bgp_stop, Active}, /* TCP_connection_open */
  907. {bgp_stop, Active}, /* TCP_connection_closed */
  908. {bgp_stop, Active}, /* TCP_connection_open_failed */
  909. {bgp_stop, Active}, /* TCP_fatal_error */
  910. {bgp_ignore, Idle}, /* ConnectRetry_timer_expired */
  911. {bgp_fsm_holdtime_expire, Idle}, /* Hold_Timer_expired */
  912. {bgp_ignore, Idle}, /* KeepAlive_timer_expired */
  913. {bgp_fsm_open, OpenConfirm}, /* Receive_OPEN_message */
  914. {bgp_fsm_event_error, Idle}, /* Receive_KEEPALIVE_message */
  915. {bgp_fsm_event_error, Idle}, /* Receive_UPDATE_message */
  916. {bgp_stop_with_error, Idle}, /* Receive_NOTIFICATION_message */
  917. {bgp_ignore, Idle}, /* Clearing_Completed */
  918. {bgp_stop_with_error, Idle},/* BGP_Stop_with_error */
  919. },
  920. {
  921. /* OpenConfirm, */
  922. {bgp_ignore, OpenConfirm}, /* BGP_Start */
  923. {bgp_stop, Idle}, /* BGP_Stop */
  924. {bgp_stop, Idle}, /* TCP_connection_open */
  925. {bgp_stop, Idle}, /* TCP_connection_closed */
  926. {bgp_stop, Idle}, /* TCP_connection_open_failed */
  927. {bgp_stop, Idle}, /* TCP_fatal_error */
  928. {bgp_ignore, Idle}, /* ConnectRetry_timer_expired */
  929. {bgp_fsm_holdtime_expire, Idle}, /* Hold_Timer_expired */
  930. {bgp_ignore, OpenConfirm}, /* KeepAlive_timer_expired */
  931. {bgp_ignore, Idle}, /* Receive_OPEN_message */
  932. {bgp_establish, Established}, /* Receive_KEEPALIVE_message */
  933. {bgp_ignore, Idle}, /* Receive_UPDATE_message */
  934. {bgp_stop_with_error, Idle}, /* Receive_NOTIFICATION_message */
  935. {bgp_ignore, Idle}, /* Clearing_Completed */
  936. {bgp_stop_with_error, Idle},/* BGP_Stop_with_error */
  937. },
  938. {
  939. /* Established, */
  940. {bgp_ignore, Established}, /* BGP_Start */
  941. {bgp_stop, Clearing}, /* BGP_Stop */
  942. {bgp_stop, Clearing}, /* TCP_connection_open */
  943. {bgp_stop, Clearing}, /* TCP_connection_closed */
  944. {bgp_stop, Clearing}, /* TCP_connection_open_failed */
  945. {bgp_stop, Clearing}, /* TCP_fatal_error */
  946. {bgp_stop, Clearing}, /* ConnectRetry_timer_expired */
  947. {bgp_fsm_holdtime_expire, Clearing}, /* Hold_Timer_expired */
  948. {bgp_fsm_keepalive_expire, Established}, /* KeepAlive_timer_expired */
  949. {bgp_stop, Clearing}, /* Receive_OPEN_message */
  950. {bgp_fsm_keepalive, Established}, /* Receive_KEEPALIVE_message */
  951. {bgp_fsm_update, Established}, /* Receive_UPDATE_message */
  952. {bgp_stop_with_error, Clearing}, /* Receive_NOTIFICATION_message */
  953. {bgp_ignore, Idle}, /* Clearing_Completed */
  954. {bgp_stop_with_error, Clearing}, /* BGP_Stop_with_error */
  955. },
  956. {
  957. /* Clearing, */
  958. {bgp_ignore, Clearing}, /* BGP_Start */
  959. {bgp_stop, Clearing}, /* BGP_Stop */
  960. {bgp_stop, Clearing}, /* TCP_connection_open */
  961. {bgp_stop, Clearing}, /* TCP_connection_closed */
  962. {bgp_stop, Clearing}, /* TCP_connection_open_failed */
  963. {bgp_stop, Clearing}, /* TCP_fatal_error */
  964. {bgp_stop, Clearing}, /* ConnectRetry_timer_expired */
  965. {bgp_stop, Clearing}, /* Hold_Timer_expired */
  966. {bgp_stop, Clearing}, /* KeepAlive_timer_expired */
  967. {bgp_stop, Clearing}, /* Receive_OPEN_message */
  968. {bgp_stop, Clearing}, /* Receive_KEEPALIVE_message */
  969. {bgp_stop, Clearing}, /* Receive_UPDATE_message */
  970. {bgp_stop, Clearing}, /* Receive_NOTIFICATION_message */
  971. {bgp_clearing_completed, Idle}, /* Clearing_Completed */
  972. {bgp_stop_with_error, Clearing}, /* BGP_Stop_with_error */
  973. },
  974. {
  975. /* Deleted, */
  976. {bgp_ignore, Deleted}, /* BGP_Start */
  977. {bgp_ignore, Deleted}, /* BGP_Stop */
  978. {bgp_ignore, Deleted}, /* TCP_connection_open */
  979. {bgp_ignore, Deleted}, /* TCP_connection_closed */
  980. {bgp_ignore, Deleted}, /* TCP_connection_open_failed */
  981. {bgp_ignore, Deleted}, /* TCP_fatal_error */
  982. {bgp_ignore, Deleted}, /* ConnectRetry_timer_expired */
  983. {bgp_ignore, Deleted}, /* Hold_Timer_expired */
  984. {bgp_ignore, Deleted}, /* KeepAlive_timer_expired */
  985. {bgp_ignore, Deleted}, /* Receive_OPEN_message */
  986. {bgp_ignore, Deleted}, /* Receive_KEEPALIVE_message */
  987. {bgp_ignore, Deleted}, /* Receive_UPDATE_message */
  988. {bgp_ignore, Deleted}, /* Receive_NOTIFICATION_message */
  989. {bgp_ignore, Deleted}, /* Clearing_Completed */
  990. {bgp_ignore, Deleted}, /* BGP_Stop_with_error */
  991. },
  992. };
  993. static const char *bgp_event_str[] =
  994. {
  995. NULL,
  996. "BGP_Start",
  997. "BGP_Stop",
  998. "TCP_connection_open",
  999. "TCP_connection_closed",
  1000. "TCP_connection_open_failed",
  1001. "TCP_fatal_error",
  1002. "ConnectRetry_timer_expired",
  1003. "Hold_Timer_expired",
  1004. "KeepAlive_timer_expired",
  1005. "Receive_OPEN_message",
  1006. "Receive_KEEPALIVE_message",
  1007. "Receive_UPDATE_message",
  1008. "Receive_NOTIFICATION_message",
  1009. "Clearing_Completed",
  1010. "BGP_Stop_with_error",
  1011. };
  1012. /* Execute event process. */
  1013. int
  1014. bgp_event (struct thread *thread)
  1015. {
  1016. int ret = 0;
  1017. int event;
  1018. int next;
  1019. struct peer *peer;
  1020. peer = THREAD_ARG (thread);
  1021. event = THREAD_VAL (thread);
  1022. /* Logging this event. */
  1023. next = FSM [peer->status -1][event - 1].next_state;
  1024. if (BGP_DEBUG (fsm, FSM) && peer->status != next)
  1025. plog_debug (peer->log, "%s [FSM] %s (%s->%s)", peer->host,
  1026. bgp_event_str[event],
  1027. LOOKUP (bgp_status_msg, peer->status),
  1028. LOOKUP (bgp_status_msg, next));
  1029. /* Call function. */
  1030. if (FSM [peer->status -1][event - 1].func)
  1031. ret = (*(FSM [peer->status - 1][event - 1].func))(peer);
  1032. /* When function do not want proceed next job return -1. */
  1033. if (ret >= 0)
  1034. {
  1035. /* If status is changed. */
  1036. if (next != peer->status)
  1037. bgp_fsm_change_status (peer, next);
  1038. /* Make sure timer is set. */
  1039. bgp_timer_set (peer);
  1040. }
  1041. return ret;
  1042. }