bird.conf 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411
  1. log syslog all;
  2. /* Definitionen fuer die Bitarithmetik der Schleifenverhinderungsmechanik */
  3. define OSPF_tag_sourcebits = 5; /* ld(32) */
  4. define OSPF_tag_pathbits = 32 - OSPF_tag_sourcebits;
  5. define OSPF_tag_pathvalue_div = 32 ; /* 2 ^ OSPF_tag_sourcebits */
  6. function fn_tag_to_source (int tagbits) {
  7. return tagbits - ((tagbits / OSPF_tag_pathvalue_div) * OSPF_tag_pathvalue_div);
  8. }
  9. function fn_tag_to_path (int tagbits) {
  10. return tagbits / OSPF_tag_pathvalue_div;
  11. }
  12. function fn_power_of_2 (int n) {
  13. # awk 'BEGIN { for ( i=0 ; i < 32 ; i++ ) print "\t\t" i ": return " 2^i ";" }'
  14. case n {
  15. 0: return 1;
  16. 1: return 2;
  17. 2: return 4;
  18. 3: return 8;
  19. 4: return 16;
  20. 5: return 32;
  21. 6: return 64;
  22. 7: return 128;
  23. 8: return 256;
  24. 9: return 512;
  25. 10: return 1024;
  26. 11: return 2048;
  27. 12: return 4096;
  28. 13: return 8192;
  29. 14: return 16384;
  30. 15: return 32768;
  31. 16: return 65536;
  32. 17: return 131072;
  33. 18: return 262144;
  34. 19: return 524288;
  35. 20: return 1048576;
  36. 21: return 2097152;
  37. 22: return 4194304;
  38. 23: return 8388608;
  39. 24: return 16777216;
  40. 25: return 33554432;
  41. 26: return 67108864;
  42. 27: return 134217728;
  43. 28: return 268435456;
  44. 29: return 536870912;
  45. 30: return 1073741824;
  46. 31: return 2147483648;
  47. else: return 0;
  48. }
  49. }
  50. function fn_instance_to_tagbit (int inst) {
  51. return fn_power_of_2(OSPF_tag_sourcebits - 1 + inst);
  52. }
  53. function fn_instancebit_is_set_in_ospf_tag (int inst)
  54. int instpathbits;
  55. {
  56. instpathbits = fn_tag_to_path(ospf_tag) / fn_power_of_2(inst-1);
  57. return (instpathbits / 2) * 2 != instpathbits;
  58. }
  59. function fn_reentrybit_is_set_in_ospf_tag() {
  60. return fn_instancebit_is_set_in_ospf_tag(fn_tag_to_source(ospf_tag));
  61. }
  62. function fn_set_reentrybit_in_ospf_tag() {
  63. ospf_tag = ospf_tag + fn_instance_to_tagbit(fn_tag_to_source(ospf_tag));
  64. }
  65. include "/usr/local/etc/bird.local.conf";
  66. /* Dort muss mindestens Folgendes definiert werden (Beispiel):
  67. router id 91.204.4.242;
  68. function fn_is_local_ospf_instance (int inst) {
  69. case inst {
  70. 1: return true;
  71. 2: return true;
  72. else: return false;
  73. }
  74. }
  75. function fn_any_local_instancebit_is_set_in_ospf_tag () {
  76. return fn_instancebit_is_set_in_ospf_tag(1) ||
  77. fn_instancebit_is_set_in_ospf_tag(2);
  78. }
  79. define Unrouted_local = [ 192.168.1.0/24+, 192.168.84.0/24+ ];
  80. */
  81. define Babel_WLAN_metric_base = 1000;
  82. define Babel_WLAN_metric_inactive = 999;
  83. define OSPF_metric2_max = 16777215;
  84. define OSPF_preference_local = 160; /* > OSPF default = 150 */
  85. define HOT = 0;
  86. define BEST = 1;
  87. define COLD = 2;
  88. ##### Definitionen fuer alle bekannten IGP Instanzen:
  89. include "/usr/local/etc/bird.inst.conf";
  90. # Dort muss mindestens Folgendes definiert werden:
  91. #define potato_ospf1 = BEST; [... et al. ...]
  92. #function fn_instance_to_potato (int inst) -> int (HOT, ...)
  93. #function fn_proto_to_instance (string from_proto) -> int (1, 2, ...)
  94. #function fn_instance_to_bgpospf (int inst) -> string ("bgpXospfX")
  95. /* XXX zwecks Einrechnung der Babel Metrik, gehoert hier aber nicht hin: */
  96. function fn_a_Babel_WLAN_routes () {
  97. return ifname = "tap9";
  98. };
  99. /* Bausteine fuer Filter. Namenskonventionen:
  100. f_... Filter (accept/reject)
  101. fn_... Funktion
  102. ..._a_... true => accept
  103. ..._r_... true => reject
  104. ..._am_... true => accept + modify
  105. */
  106. function fn_a_Routed () {
  107. return net ~ Routed;
  108. };
  109. filter f_a_Routed {
  110. if fn_a_Routed()
  111. then accept;
  112. else reject "Routed";
  113. };
  114. function fn_r_Unrouted () {
  115. return ! (net ~ Unrouted_global || net ~ Unrouted_local);
  116. };
  117. filter f_r_Unrouted {
  118. if fn_r_Unrouted()
  119. then accept;
  120. else reject "Unrouted";
  121. };
  122. function fn_a_acceptable_routes () {
  123. return fn_r_Unrouted() && fn_a_Routed();
  124. }
  125. /* Einrechnung der Babel Metrik: */
  126. function fn_include_Babel_WLAN_routes () {
  127. case gw {
  128. include "/var/run/bird.babeld.conf";
  129. else: ospf_metric1 = ospf_metric1 + Babel_WLAN_metric_base + Babel_WLAN_metric_inactive;
  130. }
  131. }
  132. function fn_debug_ospf_route (string str)
  133. {
  134. print str, " ", net, " ^", scope, " *", source,
  135. " !", from, " :", gw, " (", preference, ") ",
  136. igp_metric, "/", ospf_metric1, "/", ospf_metric2,
  137. " [", ospf_tag, "]";
  138. # Fuehrt zu:
  139. # bird: filters, line 169: Can't operate with values of incompatible types
  140. #" [", fn_tag_to_source(ospf_tag), "|", fn_tag_to_path(ospf_tag), "]";
  141. }
  142. function fn_debug_ospf_route_before (string str)
  143. {
  144. printn str; fn_debug_ospf_route("?");
  145. }
  146. function fn_debug_ospf_route_after (string str)
  147. {
  148. printn str; fn_debug_ospf_route("!");
  149. }
  150. function fn_am_local_to_ospf_table () {
  151. if ! (proto ~ "ospf*") &&
  152. fn_a_acceptable_routes()
  153. then if ifname ~ "lo0"
  154. then return false;
  155. else { if preference < OSPF_preference_local
  156. then preference = OSPF_preference_local;
  157. return true; }
  158. else return false;
  159. }
  160. function fn_am_local_to_ospf_export () {
  161. if ! (proto ~ "*ospf*") &&
  162. fn_a_acceptable_routes()
  163. then { if ifname ~ "lo0"
  164. then return false;
  165. else # geroutete loopback Adressen auch per OSPF stubnet!
  166. if ifname ~ "lo*"
  167. then ospf_metric1 = 1;
  168. else ospf_metric1 = 10;
  169. ospf_metric2 = 0;
  170. return true; }
  171. else return false;
  172. }
  173. function fn_import_ospf_master (int from_instance) {
  174. if ! fn_a_acceptable_routes()
  175. then return false;
  176. # Schleifenvermeidung: routes mit tags von OSPF-Instanzen,
  177. # an denen dieser Router teilnimmt, sind schonmal hier
  178. # durchgelaufen, und zwar mit tag = 0, d.h. ohne Uebergang
  179. # zwischen OSPF-Instanzen. (Evtl. Ausnahme: Partitionierung
  180. # der source Instanz, sodass die urspruengliche route nicht
  181. # mit source = 0 hier ankam, sondern nur per Transit.)
  182. else if ospf_tag != 0
  183. then {
  184. if fn_instance_to_potato(from_instance) = HOT
  185. # TBD || fn_instance_to_transit(from_instance) = false
  186. then # kein Transit durch hot potato Instanzen
  187. return false;
  188. else if fn_is_local_ospf_instance(fn_tag_to_source(ospf_tag)) ||
  189. fn_any_local_instancebit_is_set_in_ospf_tag()
  190. then # re-entry
  191. if ! fn_reentrybit_is_set_in_ospf_tag()
  192. then # wg. counting-to-infinity
  193. fn_set_reentrybit_in_ospf_tag();
  194. }
  195. case from_instance {
  196. /* XXX zwecks Einrechnung der Babel Metrik, gehoert hier aber nicht hin: */
  197. # metric mittels /var/run/bird.babeld.conf (hoch)setzen:
  198. 2: fn_include_Babel_WLAN_routes();
  199. }
  200. return true;
  201. }
  202. function fn_import_master_ospf (string from_proto) {
  203. return proto = from_proto;
  204. }
  205. /* Funktioniert nicht als Funktion, aber als Filter,
  206. s. protocol pipe master2ospfX in bird.instX.conf.
  207. Grumpf:-(bird 1.5.0)
  208. function fn_export_master_ospf () {
  209. if proto ~ "ospf*"
  210. then return false;
  211. else return fn_am_local_to_ospf_table();
  212. }
  213. */
  214. function fn_am_master_to_bgpospf (int dest_instance)
  215. int from_instance;
  216. {
  217. if fn_a_acceptable_routes()
  218. then { from_instance = fn_proto_to_instance(proto);
  219. if ospf_tag = 0 # (lokale Route, keine Transitroute)
  220. then { # route entstammt einer IGP Instanz, an der dieser
  221. # router teilnimmt. Beim Uebergang in eine andere
  222. # IGP Instanz muss diese route, die gerade ein
  223. # lokales IGP verlaesst, mit dem tag dieser Instanz
  224. # versehen werden. Kommt die route dann spaeter
  225. # per transit wieder zur Urprungs-Instanz zurueck,
  226. # kann sie dank des tags als Rundlauefer erkannt
  227. # und entsprechend schleifenbehandelt werden.
  228. ospf_tag = from_instance;
  229. return true;
  230. }
  231. else if fn_instance_to_potato(from_instance) = HOT
  232. # TBD || fn_instance_to_transit(from_instance) = false
  233. then # kein Transit durch HOT Instanzen wg. Verlust der ursprünglichen Metrik
  234. return false;
  235. else { if fn_reentrybit_is_set_in_ospf_tag() &&
  236. fn_instancebit_is_set_in_ospf_tag(dest_instance)
  237. then # kein counting-to-infinity
  238. return false;
  239. # Transit-IGP, aus dem die Route gerade kommt, in die Route "einkerben"
  240. if ! fn_instancebit_is_set_in_ospf_tag(from_instance)
  241. then ospf_tag = ospf_tag + fn_instance_to_tagbit(from_instance);
  242. return true;
  243. }
  244. }
  245. else return false;
  246. }
  247. function fn_export_master_bgpospf (string dest_proto)
  248. int dest_instance;
  249. {
  250. dest_instance = fn_proto_to_instance(dest_proto);
  251. printn "master2bgp"; fn_debug_ospf_route_before(dest_proto);
  252. if proto ~ "ospf*" &&
  253. proto != dest_proto &&
  254. fn_am_master_to_bgpospf(dest_instance)
  255. then { printn "master2bgp"; fn_debug_ospf_route_after(dest_proto);
  256. bgp_local_pref = preference;
  257. bgp_path.prepend(ospf_tag);
  258. # optimal:
  259. # -> E1 mit metric1 = Summe
  260. # hot potato ("closest exit"):
  261. # -> E1 mit metric1 = 0, # geht nicht: metric2 = Summe
  262. # retour: automatisch mit mit metric1 = Summe, metric2 = 0
  263. # cold potato ("best exit", RFC4451):
  264. # -> E2 mit metric2 = Summe
  265. # ?: wie geht retour E2 -> E1, d.h. wie funktioniert
  266. # eine Unterscheidung von ursprünglichen E2 routes?
  267. # flag im ospf_tag?
  268. if # XXX geht nicht: ospf_metric2 = 16777235
  269. ospf_metric2 = OSPF_metric2_max
  270. then
  271. bgp_med = ospf_metric1;
  272. else
  273. bgp_med = ospf_metric2 + ospf_metric1;
  274. # zZ unbenutzt, erscheint im show all als [ASXi]/[ASXe]
  275. if ospf_tag != 0
  276. then
  277. if fn_reentrybit_is_set_in_ospf_tag()
  278. then
  279. bgp_origin = 2;
  280. else
  281. bgp_origin = 1;
  282. else
  283. bgp_origin = 0;
  284. accept;
  285. }
  286. else reject;
  287. }
  288. function fn_import_bgpospf ()
  289. {
  290. preference = bgp_local_pref;
  291. return true;
  292. }
  293. function fn_export_ospf (int dest_instance)
  294. string proto_bgpospf;
  295. int potato_ospf;
  296. {
  297. proto_bgpospf = fn_instance_to_bgpospf(dest_instance);
  298. potato_ospf = fn_instance_to_potato(dest_instance);
  299. printn "export-", dest_instance; fn_debug_ospf_route_before("");
  300. if fn_am_local_to_ospf_export()
  301. then return true;
  302. else if proto = proto_bgpospf
  303. then { ospf_tag = bgp_path.first;
  304. # optimal:
  305. # -> E1 mit metric1 = Summe
  306. # hot potato ("closest exit"):
  307. # -> E1 mit metric1 = 0, metric2 = Summe
  308. # retour: automatisch mit mit metric1 = Summe, metric2 = 0
  309. # cold potato ("best exit", RFC4451):
  310. # -> E2 mit metric2 = Summe
  311. # ?: wie geht retour E2 -> E1, d.h. wie funktioniert
  312. # eine Unterscheidung von ursprünglichen E2 routes?
  313. # also flag im ospf_tag kodieren?
  314. # !: nein, keine E2 routen als E2 durchlassen,
  315. # weil das jede Instanz selbst entscheiden soll,
  316. # also nur bei cold potato auf E2 setzen (lassen)
  317. #
  318. if potato_ospf = BEST
  319. then {
  320. # igp_metric = bgp_med;
  321. # bgp_med = 0;
  322. # scope = SCOPE_ORGANIZATION;
  323. ospf_metric1 = bgp_med;
  324. }
  325. else if potato_ospf = HOT
  326. then {
  327. # geht nicht, wird beim Setzen von
  328. # von ospf_metric1 genichtet:
  329. # ospf_metric2 = bgp_med;
  330. ospf_metric1 = 0;
  331. # XXX instance mit hot potato
  332. # XXX darf kein Transit sein!
  333. # XXX => keine tag routes exportieren
  334. }
  335. else if potato_ospf = COLD
  336. then ospf_metric2 = bgp_med;
  337. printn "export-", dest_instance; fn_debug_ospf_route_after("");
  338. return true;
  339. }
  340. else return false;
  341. }
  342. protocol device {
  343. scan time 10;
  344. }
  345. /* wg. BSD: */
  346. protocol direct {
  347. }
  348. protocol kernel kernel0 {
  349. learn on;
  350. scan time 5;
  351. import filter f_r_Unrouted;
  352. export filter f_r_Unrouted;
  353. }
  354. /* XXX zwecks Einrechnung der Babel Metrik, gehoert hier aber nicht hin: */
  355. table fib4table;
  356. protocol kernel kernel4 {
  357. description "babel FIB 4";
  358. kernel table 4;
  359. table fib4table;
  360. learn on;
  361. scan time 10;
  362. }
  363. ##### Definition der IGP Instanzen, an denen dieser Router teilnimmt:
  364. include "/usr/local/etc/bird.inst.local.conf";