Advertisement
Guest User

Route Server - SYD

a guest
Apr 16th, 2020
36
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 20.32 KB | None | 0 0
  1.  
  2. #
  3. # Bird v2 Route Server configuration generated by IXP Manager
  4. #
  5. # Do not edit this file, it will be overwritten. Please see:
  6. #
  7. # https://github.com/inex/IXP-Manager/wiki/Route-Server
  8. #
  9. # Generated: 2020-04-16 10:54:14
  10. #
  11.  
  12. # For VLAN: CIX-AUS Sydney (Tag: 2, Database ID: 1)
  13.  
  14. # standardise time formats:
  15. timeformat base iso long;
  16. timeformat log iso long;
  17. timeformat protocol iso long;
  18. timeformat route iso long;
  19.  
  20.  
  21. log "/var/log/bird/rs-cixaus-syd-ipv4.log" all;
  22. log syslog all;
  23.  
  24. define routeserverasn = 37980;
  25. define routeserveraddress = 103.149.217.2;
  26.  
  27.  
  28. router id 103.149.217.2;
  29.  
  30. # ignore interface up/down events
  31. protocol device { }
  32.  
  33. # This function excludes weird networks
  34. # rfc1918, class D, class E, too long and too short prefixes
  35. function avoid_martians()
  36. prefix set martians;
  37. {
  38.  
  39. martians = [
  40. 10.0.0.0/8+,
  41. 169.254.0.0/16+,
  42. 172.16.0.0/12+,
  43. 192.0.0.0/24+,
  44. 192.0.2.0/24+,
  45. 192.168.0.0/16+,
  46. 198.18.0.0/15+,
  47. 198.51.100.0/24+,
  48. 203.0.113.0/24+,
  49. 224.0.0.0/4+,
  50. 240.0.0.0/4+,
  51. 0.0.0.0/32-,
  52. 0.0.0.0/0{25,32},
  53. 0.0.0.0/0{0,7}
  54. ];
  55.  
  56.  
  57. # Avoid RFC1918 and similar networks
  58. if net ~ martians then
  59. return false;
  60.  
  61. return true;
  62. }
  63.  
  64.  
  65. ########################################################################################
  66. ########################################################################################
  67. #
  68. # Community filtering definitions for use with looking glasses
  69. #
  70. # Current implementation based on:
  71. #
  72. # https://github.com/euro-ix/rs-workshop-july-2017/wiki/Route-Server-BGP-Community-usage
  73. #
  74. ########################################################################################
  75. ########################################################################################
  76.  
  77.  
  78.  
  79. # These will all be filtered and not piped to the master table:
  80.  
  81. define IXP_LC_FILTERED_PREFIX_LEN_TOO_LONG = ( routeserverasn, 1101, 1 );
  82. define IXP_LC_FILTERED_PREFIX_LEN_TOO_SHORT = ( routeserverasn, 1101, 2 );
  83. define IXP_LC_FILTERED_BOGON = ( routeserverasn, 1101, 3 );
  84. define IXP_LC_FILTERED_BOGON_ASN = ( routeserverasn, 1101, 4 );
  85. define IXP_LC_FILTERED_AS_PATH_TOO_LONG = ( routeserverasn, 1101, 5 );
  86. define IXP_LC_FILTERED_AS_PATH_TOO_SHORT = ( routeserverasn, 1101, 6 );
  87. define IXP_LC_FILTERED_FIRST_AS_NOT_PEER_AS = ( routeserverasn, 1101, 7 );
  88. define IXP_LC_FILTERED_NEXT_HOP_NOT_PEER_IP = ( routeserverasn, 1101, 8 );
  89. define IXP_LC_FILTERED_IRRDB_PREFIX_FILTERED = ( routeserverasn, 1101, 9 );
  90. define IXP_LC_FILTERED_IRRDB_ORIGIN_AS_FILTERED = ( routeserverasn, 1101, 10 );
  91. define IXP_LC_FILTERED_PREFIX_NOT_IN_ORIGIN_AS = ( routeserverasn, 1101, 11 );
  92.  
  93. define IXP_LC_FILTERED_RPKI_UNKNOWN = ( routeserverasn, 1101, 12 );
  94. define IXP_LC_FILTERED_RPKI_INVALID = ( routeserverasn, 1101, 13 );
  95. define IXP_LC_FILTERED_TRANSIT_FREE_ASN = ( routeserverasn, 1101, 14 );
  96. define IXP_LC_FILTERED_TOO_MANY_COMMUNITIES = ( routeserverasn, 1101, 15 );
  97.  
  98.  
  99.  
  100.  
  101. # Informational prefixes
  102.  
  103. define IXP_LC_INFO_RPKI_VALID = ( routeserverasn, 1000, 1 );
  104. define IXP_LC_INFO_RPKI_UNKNOWN = ( routeserverasn, 1000, 2 );
  105. define IXP_LC_INFO_RPKI_NOT_CHECKED = ( routeserverasn, 1000, 3 );
  106.  
  107. define IXP_LC_INFO_IRRDB_VALID = ( routeserverasn, 1001, 1 );
  108. define IXP_LC_INFO_IRRDB_NOT_CHECKED = ( routeserverasn, 1001, 2 );
  109. define IXP_LC_INFO_IRRDB_MORE_SPECIFIC = ( routeserverasn, 1001, 3 );
  110.  
  111. define IXP_LC_INFO_IRRDB_FILTERED_LOOSE = ( routeserverasn, 1001, 1000 );
  112. define IXP_LC_INFO_IRRDB_FILTERED_STRICT = ( routeserverasn, 1001, 1001 );
  113. define IXP_LC_INFO_IRRDB_PREFIX_EMPTY = ( routeserverasn, 1001, 1002 );
  114.  
  115. define IXP_LC_INFO_SAME_AS_NEXT_HOP = ( routeserverasn, 1001, 1200 );
  116.  
  117. # ( routeserverasn, 1010, peerasn ) -> route learnt from peerasn via routeserverasn
  118. # ( routeserverasn, 1011, originasn ) -> route origin asn via routeserverasn
  119.  
  120.  
  121. # And the filter for examing routes in the peers import table being exported
  122. # to the master table
  123.  
  124. filter f_export_to_master
  125. {
  126.  
  127. if bgp_large_community ~ [( routeserverasn, 1101, * )] then reject;
  128.  
  129. accept;
  130. }
  131.  
  132.  
  133.  
  134.  
  135.  
  136.  
  137. ########################################################################################
  138. ########################################################################################
  139. #
  140. # Standard IXP community filter
  141. #
  142. ########################################################################################
  143. ########################################################################################
  144.  
  145.  
  146. function ixp_community_filter(int peerasn)
  147. {
  148. if !(source = RTS_BGP) then
  149. return false;
  150.  
  151. # AS path prepending
  152. if (routeserverasn, 103, peerasn) ~ bgp_large_community then {
  153. bgp_path.prepend( bgp_path.first );
  154. bgp_path.prepend( bgp_path.first );
  155. bgp_path.prepend( bgp_path.first );
  156. } else if (routeserverasn, 102, peerasn) ~ bgp_large_community then {
  157. bgp_path.prepend( bgp_path.first );
  158. bgp_path.prepend( bgp_path.first );
  159. } else if (routeserverasn, 101, peerasn) ~ bgp_large_community then {
  160. bgp_path.prepend( bgp_path.first );
  161. }
  162.  
  163.  
  164. # support for BGP Large Communities
  165. if (routeserverasn, 0, peerasn) ~ bgp_large_community then
  166. return false;
  167. if (routeserverasn, 1, peerasn) ~ bgp_large_community then
  168. return true;
  169. if (routeserverasn, 0, 0) ~ bgp_large_community then
  170. return false;
  171. if (routeserverasn, 1, 0) ~ bgp_large_community then
  172. return true;
  173.  
  174. # it's unwise to conduct a 32-bit check on a 16-bit value
  175. if peerasn > 65535 then
  176. return true;
  177.  
  178. # Implement widely used community filtering schema.
  179. if (0, peerasn) ~ bgp_community then
  180. return false;
  181. if (routeserverasn, peerasn) ~ bgp_community then
  182. return true;
  183. if (0, routeserverasn) ~ bgp_community then
  184. return false;
  185.  
  186. return true;
  187. }
  188.  
  189.  
  190.  
  191.  
  192. ########################################################################################
  193. ########################################################################################
  194. #
  195. # RPKI protocol configuration
  196. #
  197. ########################################################################################
  198. ########################################################################################
  199.  
  200.  
  201.  
  202. # RPKI not enabled for this router
  203.  
  204.  
  205.  
  206.  
  207.  
  208.  
  209. ########################################################################################
  210. ########################################################################################
  211. #
  212. # Filter known transit networks
  213. #
  214. # Inspired by: http://bgpfilterguide.nlnog.net/guides/no_transit_leaks/
  215. #
  216. ########################################################################################
  217. ########################################################################################
  218.  
  219.  
  220. define TRANSIT_ASNS = [ 174, # Cogent
  221. 209, # Qwest (HE carries this on IXPs IPv6 (Jul 12 2018))
  222. 701, # UUNET
  223. 702, # UUNET
  224. 1239, # Sprint
  225. 1299, # Telia
  226. 2914, # NTT Communications
  227. 3257, # GTT Backbone
  228. 3320, # Deutsche Telekom AG (DTAG)
  229. 3356, # Level3
  230. 3549, # Level3
  231. 3561, # Savvis / CenturyLink
  232. 4134, # Chinanet
  233. 5511, # Orange opentransit
  234. 6453, # Tata Communications
  235. 6762, # Seabone / Telecom Italia
  236. 7018 ]; # AT&T
  237.  
  238. function filter_has_transit_path()
  239. int set transit_asns;
  240. {
  241. transit_asns = TRANSIT_ASNS;
  242. if (bgp_path ~ transit_asns) then {
  243. bgp_large_community.add( IXP_LC_FILTERED_TRANSIT_FREE_ASN );
  244. return true;
  245. }
  246.  
  247. return false;
  248. }
  249.  
  250.  
  251. ########################################################################################
  252. ########################################################################################
  253. #
  254. # Route Server client configuration
  255. #
  256. ########################################################################################
  257. ########################################################################################
  258.  
  259.  
  260. template bgp tb_rsclient {
  261. local as routeserverasn;
  262. source address routeserveraddress;
  263. strict bind yes;
  264.  
  265. # give RPKI-RTR a chance to start and populate
  266. # (RPKI is /really/ quick)
  267. connect delay time 30;
  268.  
  269. ipv4 {
  270. export all;
  271. };
  272.  
  273. rs client;
  274. }
  275.  
  276.  
  277.  
  278.  
  279. ########################################################################################
  280. ########################################################################################
  281. #
  282. # Route server clients
  283. #
  284. ########################################################################################
  285. ########################################################################################
  286.  
  287.  
  288. ########################################################################################
  289. ########################################################################################
  290. ###
  291. ### AS6939 - Hurricane Electric - VLAN Interface #3
  292.  
  293. ipv4 table t_0003_as6939;
  294.  
  295.  
  296.  
  297. filter f_import_as6939
  298. prefix set allnet;
  299. ip set allips;
  300. int set allas;
  301. {
  302.  
  303.  
  304. # Filter small prefixes
  305. if ( net ~ [ 0.0.0.0/0{25,32} ] ) then {
  306. bgp_large_community.add( IXP_LC_FILTERED_PREFIX_LEN_TOO_LONG );
  307. accept;
  308. }
  309.  
  310.  
  311. if !(avoid_martians()) then {
  312. bgp_large_community.add( IXP_LC_FILTERED_BOGON );
  313. accept;
  314. }
  315.  
  316. # Belt and braces: must have at least one ASN in the path
  317. if( bgp_path.len < 1 ) then {
  318. bgp_large_community.add( IXP_LC_FILTERED_AS_PATH_TOO_SHORT );
  319. accept;
  320. }
  321.  
  322. # Peer ASN == route's first ASN?
  323. if (bgp_path.first != 6939 ) then {
  324. bgp_large_community.add( IXP_LC_FILTERED_FIRST_AS_NOT_PEER_AS );
  325. accept;
  326. }
  327.  
  328. # set of all IPs this ASN uses to peer with on this VLAN
  329. allips = [ 103.149.217.12 ];
  330.  
  331. # Prevent BGP NEXT_HOP Hijacking
  332. if !( from = bgp_next_hop ) then {
  333.  
  334. # need to differentiate between same ASN next hop or actual next hop hijacking
  335. if( bgp_next_hop ~ allips ) then {
  336. bgp_large_community.add( IXP_LC_INFO_SAME_AS_NEXT_HOP );
  337. } else {
  338. # looks like hijacking (intentional or not)
  339. bgp_large_community.add( IXP_LC_FILTERED_NEXT_HOP_NOT_PEER_IP );
  340. accept;
  341. }
  342. }
  343.  
  344.  
  345. # Filter Known Transit Networks
  346. if filter_has_transit_path() then accept;
  347.  
  348. # Belt and braces: no one needs an ASN path with > 64 hops, that's just broken
  349. if( bgp_path.len > 64 ) then {
  350. bgp_large_community.add( IXP_LC_FILTERED_AS_PATH_TOO_LONG );
  351. accept;
  352. }
  353.  
  354.  
  355.  
  356. allas = [ 6939 ];
  357.  
  358.  
  359. # Ensure origin ASN is in the neighbors AS-SET
  360. if !(bgp_path.last_nonaggregated ~ allas) then {
  361. bgp_large_community.add( IXP_LC_FILTERED_IRRDB_ORIGIN_AS_FILTERED );
  362. accept;
  363. }
  364.  
  365.  
  366.  
  367. # Skipping RPKI check -> RPKI not enabled / configured correctly.
  368. bgp_large_community.add( IXP_LC_INFO_RPKI_NOT_CHECKED );
  369.  
  370.  
  371.  
  372.  
  373. # Deny everything because the IRR database returned nothing
  374. bgp_large_community.add( IXP_LC_FILTERED_IRRDB_PREFIX_FILTERED );
  375. bgp_large_community.add( IXP_LC_INFO_IRRDB_PREFIX_EMPTY );
  376. accept;
  377.  
  378.  
  379.  
  380. accept;
  381. }
  382.  
  383.  
  384. # The route server export filter exists as the export gateway on the BGP protocol.
  385. #
  386. # Remember that standard IXP community filtering has already happened on the
  387. # master -> bgp protocol pipe.
  388.  
  389. filter f_export_as6939{
  390.  
  391.  
  392.  
  393. # we should strip our own communities which we used for the looking glass
  394. bgp_large_community.delete( [( routeserverasn, *, * )] );
  395. bgp_community.delete( [( routeserverasn, * )] );
  396.  
  397. # default position is to accept:
  398. accept;
  399.  
  400. }
  401.  
  402.  
  403.  
  404.  
  405.  
  406.  
  407.  
  408. protocol pipe pp_0003_as6939 {
  409. description "Pipe for AS6939 - Hurricane Electric - VLAN Interface 3";
  410. table master4;
  411. peer table t_0003_as6939;
  412. import filter f_export_to_master;
  413. export where ixp_community_filter(6939);
  414. }
  415.  
  416. protocol bgp pb_0003_as6939 from tb_rsclient {
  417. description "AS6939 - Hurricane Electric";
  418. neighbor 103.149.217.12 as 6939;
  419. ipv4 {
  420. import limit 202800 action restart;
  421. import filter f_import_as6939;
  422. table t_0003_as6939;
  423. export filter f_export_as6939;
  424. };
  425.  
  426. }
  427.  
  428.  
  429. ########################################################################################
  430. ########################################################################################
  431. ###
  432. ### AS32590 - Valve Corporation - VLAN Interface #4
  433.  
  434. ipv4 table t_0004_as32590;
  435.  
  436.  
  437.  
  438. filter f_import_as32590
  439. prefix set allnet;
  440. ip set allips;
  441. int set allas;
  442. {
  443.  
  444.  
  445. # Filter small prefixes
  446. if ( net ~ [ 0.0.0.0/0{25,32} ] ) then {
  447. bgp_large_community.add( IXP_LC_FILTERED_PREFIX_LEN_TOO_LONG );
  448. accept;
  449. }
  450.  
  451.  
  452. if !(avoid_martians()) then {
  453. bgp_large_community.add( IXP_LC_FILTERED_BOGON );
  454. accept;
  455. }
  456.  
  457. # Belt and braces: must have at least one ASN in the path
  458. if( bgp_path.len < 1 ) then {
  459. bgp_large_community.add( IXP_LC_FILTERED_AS_PATH_TOO_SHORT );
  460. accept;
  461. }
  462.  
  463. # Peer ASN == route's first ASN?
  464. if (bgp_path.first != 32590 ) then {
  465. bgp_large_community.add( IXP_LC_FILTERED_FIRST_AS_NOT_PEER_AS );
  466. accept;
  467. }
  468.  
  469. # set of all IPs this ASN uses to peer with on this VLAN
  470. allips = [ 103.149.217.11 ];
  471.  
  472. # Prevent BGP NEXT_HOP Hijacking
  473. if !( from = bgp_next_hop ) then {
  474.  
  475. # need to differentiate between same ASN next hop or actual next hop hijacking
  476. if( bgp_next_hop ~ allips ) then {
  477. bgp_large_community.add( IXP_LC_INFO_SAME_AS_NEXT_HOP );
  478. } else {
  479. # looks like hijacking (intentional or not)
  480. bgp_large_community.add( IXP_LC_FILTERED_NEXT_HOP_NOT_PEER_IP );
  481. accept;
  482. }
  483. }
  484.  
  485.  
  486. # Filter Known Transit Networks
  487. if filter_has_transit_path() then accept;
  488.  
  489. # Belt and braces: no one needs an ASN path with > 64 hops, that's just broken
  490. if( bgp_path.len > 64 ) then {
  491. bgp_large_community.add( IXP_LC_FILTERED_AS_PATH_TOO_LONG );
  492. accept;
  493. }
  494.  
  495.  
  496.  
  497. allas = [ 32590 ];
  498.  
  499.  
  500. # Ensure origin ASN is in the neighbors AS-SET
  501. if !(bgp_path.last_nonaggregated ~ allas) then {
  502. bgp_large_community.add( IXP_LC_FILTERED_IRRDB_ORIGIN_AS_FILTERED );
  503. accept;
  504. }
  505.  
  506.  
  507.  
  508. # Skipping RPKI check -> RPKI not enabled / configured correctly.
  509. bgp_large_community.add( IXP_LC_INFO_RPKI_NOT_CHECKED );
  510.  
  511.  
  512.  
  513.  
  514. # Deny everything because the IRR database returned nothing
  515. bgp_large_community.add( IXP_LC_FILTERED_IRRDB_PREFIX_FILTERED );
  516. bgp_large_community.add( IXP_LC_INFO_IRRDB_PREFIX_EMPTY );
  517. accept;
  518.  
  519.  
  520.  
  521. accept;
  522. }
  523.  
  524.  
  525. # The route server export filter exists as the export gateway on the BGP protocol.
  526. #
  527. # Remember that standard IXP community filtering has already happened on the
  528. # master -> bgp protocol pipe.
  529.  
  530. filter f_export_as32590{
  531.  
  532.  
  533.  
  534. # we should strip our own communities which we used for the looking glass
  535. bgp_large_community.delete( [( routeserverasn, *, * )] );
  536. bgp_community.delete( [( routeserverasn, * )] );
  537.  
  538. # default position is to accept:
  539. accept;
  540.  
  541. }
  542.  
  543.  
  544.  
  545.  
  546.  
  547.  
  548.  
  549. protocol pipe pp_0004_as32590 {
  550. description "Pipe for AS32590 - Valve Corporation - VLAN Interface 4";
  551. table master4;
  552. peer table t_0004_as32590;
  553. import filter f_export_to_master;
  554. export where ixp_community_filter(32590);
  555. }
  556.  
  557. protocol bgp pb_0004_as32590 from tb_rsclient {
  558. description "AS32590 - Valve Corporation";
  559. neighbor 103.149.217.11 as 32590;
  560. ipv4 {
  561. import limit 120 action restart;
  562. import filter f_import_as32590;
  563. table t_0004_as32590;
  564. export filter f_export_as32590;
  565. };
  566.  
  567. }
  568.  
  569.  
  570. ########################################################################################
  571. ########################################################################################
  572. ###
  573. ### AS132269 - CommSphere - VLAN Interface #7
  574.  
  575. ipv4 table t_0007_as132269;
  576.  
  577.  
  578.  
  579. filter f_import_as132269
  580. prefix set allnet;
  581. ip set allips;
  582. int set allas;
  583. {
  584.  
  585.  
  586. # Filter small prefixes
  587. if ( net ~ [ 0.0.0.0/0{25,32} ] ) then {
  588. bgp_large_community.add( IXP_LC_FILTERED_PREFIX_LEN_TOO_LONG );
  589. accept;
  590. }
  591.  
  592.  
  593. if !(avoid_martians()) then {
  594. bgp_large_community.add( IXP_LC_FILTERED_BOGON );
  595. accept;
  596. }
  597.  
  598. # Belt and braces: must have at least one ASN in the path
  599. if( bgp_path.len < 1 ) then {
  600. bgp_large_community.add( IXP_LC_FILTERED_AS_PATH_TOO_SHORT );
  601. accept;
  602. }
  603.  
  604. # Peer ASN == route's first ASN?
  605. if (bgp_path.first != 132269 ) then {
  606. bgp_large_community.add( IXP_LC_FILTERED_FIRST_AS_NOT_PEER_AS );
  607. accept;
  608. }
  609.  
  610. # set of all IPs this ASN uses to peer with on this VLAN
  611. allips = [ 103.149.217.10 ];
  612.  
  613. # Prevent BGP NEXT_HOP Hijacking
  614. if !( from = bgp_next_hop ) then {
  615.  
  616. # need to differentiate between same ASN next hop or actual next hop hijacking
  617. if( bgp_next_hop ~ allips ) then {
  618. bgp_large_community.add( IXP_LC_INFO_SAME_AS_NEXT_HOP );
  619. } else {
  620. # looks like hijacking (intentional or not)
  621. bgp_large_community.add( IXP_LC_FILTERED_NEXT_HOP_NOT_PEER_IP );
  622. accept;
  623. }
  624. }
  625.  
  626.  
  627. # Filter Known Transit Networks
  628. if filter_has_transit_path() then accept;
  629.  
  630. # Belt and braces: no one needs an ASN path with > 64 hops, that's just broken
  631. if( bgp_path.len > 64 ) then {
  632. bgp_large_community.add( IXP_LC_FILTERED_AS_PATH_TOO_LONG );
  633. accept;
  634. }
  635.  
  636.  
  637.  
  638. allas = [ 132269
  639. ];
  640.  
  641.  
  642. # Ensure origin ASN is in the neighbors AS-SET
  643. if !(bgp_path.last_nonaggregated ~ allas) then {
  644. bgp_large_community.add( IXP_LC_FILTERED_IRRDB_ORIGIN_AS_FILTERED );
  645. accept;
  646. }
  647.  
  648.  
  649.  
  650. # Skipping RPKI check -> RPKI not enabled / configured correctly.
  651. bgp_large_community.add( IXP_LC_INFO_RPKI_NOT_CHECKED );
  652.  
  653.  
  654.  
  655.  
  656. # Deny everything because the IRR database returned nothing
  657. bgp_large_community.add( IXP_LC_FILTERED_IRRDB_PREFIX_FILTERED );
  658. bgp_large_community.add( IXP_LC_INFO_IRRDB_PREFIX_EMPTY );
  659. accept;
  660.  
  661.  
  662.  
  663. accept;
  664. }
  665.  
  666.  
  667. # The route server export filter exists as the export gateway on the BGP protocol.
  668. #
  669. # Remember that standard IXP community filtering has already happened on the
  670. # master -> bgp protocol pipe.
  671.  
  672. filter f_export_as132269{
  673.  
  674.  
  675.  
  676. # we should strip our own communities which we used for the looking glass
  677. bgp_large_community.delete( [( routeserverasn, *, * )] );
  678. bgp_community.delete( [( routeserverasn, * )] );
  679.  
  680. # default position is to accept:
  681. accept;
  682.  
  683. }
  684.  
  685.  
  686.  
  687.  
  688.  
  689.  
  690.  
  691. protocol pipe pp_0007_as132269 {
  692. description "Pipe for AS132269 - CommSphere - VLAN Interface 7";
  693. table master4;
  694. peer table t_0007_as132269;
  695. import filter f_export_to_master;
  696. export where ixp_community_filter(132269);
  697. }
  698.  
  699. protocol bgp pb_0007_as132269 from tb_rsclient {
  700. description "AS132269 - CommSphere";
  701. neighbor 103.149.217.10 as 132269;
  702. ipv4 {
  703. import limit 12000 action restart;
  704. import filter f_import_as132269;
  705. table t_0007_as132269;
  706. export filter f_export_as132269;
  707. };
  708.  
  709. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement