123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411 |
- log syslog all;
- /* Definitionen fuer die Bitarithmetik der Schleifenverhinderungsmechanik */
- define OSPF_tag_sourcebits = 5; /* ld(32) */
- define OSPF_tag_pathbits = 32 - OSPF_tag_sourcebits;
- define OSPF_tag_pathvalue_div = 32 ; /* 2 ^ OSPF_tag_sourcebits */
- function fn_tag_to_source (int tagbits) {
- return tagbits - ((tagbits / OSPF_tag_pathvalue_div) * OSPF_tag_pathvalue_div);
- }
- function fn_tag_to_path (int tagbits) {
- return tagbits / OSPF_tag_pathvalue_div;
- }
- function fn_power_of_2 (int n) {
- # awk 'BEGIN { for ( i=0 ; i < 32 ; i++ ) print "\t\t" i ": return " 2^i ";" }'
- case n {
- 0: return 1;
- 1: return 2;
- 2: return 4;
- 3: return 8;
- 4: return 16;
- 5: return 32;
- 6: return 64;
- 7: return 128;
- 8: return 256;
- 9: return 512;
- 10: return 1024;
- 11: return 2048;
- 12: return 4096;
- 13: return 8192;
- 14: return 16384;
- 15: return 32768;
- 16: return 65536;
- 17: return 131072;
- 18: return 262144;
- 19: return 524288;
- 20: return 1048576;
- 21: return 2097152;
- 22: return 4194304;
- 23: return 8388608;
- 24: return 16777216;
- 25: return 33554432;
- 26: return 67108864;
- 27: return 134217728;
- 28: return 268435456;
- 29: return 536870912;
- 30: return 1073741824;
- 31: return 2147483648;
- else: return 0;
- }
- }
- function fn_instance_to_tagbit (int inst) {
- return fn_power_of_2(OSPF_tag_sourcebits - 1 + inst);
- }
- function fn_instancebit_is_set_in_ospf_tag (int inst)
- int instpathbits;
- {
- instpathbits = fn_tag_to_path(ospf_tag) / fn_power_of_2(inst-1);
- return (instpathbits / 2) * 2 != instpathbits;
- }
- function fn_reentrybit_is_set_in_ospf_tag() {
- return fn_instancebit_is_set_in_ospf_tag(fn_tag_to_source(ospf_tag));
- }
- function fn_set_reentrybit_in_ospf_tag() {
- ospf_tag = ospf_tag + fn_instance_to_tagbit(fn_tag_to_source(ospf_tag));
- }
- include "/usr/local/etc/bird.local.conf";
- /* Dort muss mindestens Folgendes definiert werden (Beispiel):
- router id 91.204.4.242;
- function fn_is_local_ospf_instance (int inst) {
- case inst {
- 1: return true;
- 2: return true;
- else: return false;
- }
- }
- function fn_any_local_instancebit_is_set_in_ospf_tag () {
- return fn_instancebit_is_set_in_ospf_tag(1) ||
- fn_instancebit_is_set_in_ospf_tag(2);
- }
- define Unrouted_local = [ 192.168.1.0/24+, 192.168.84.0/24+ ];
- */
- define Babel_WLAN_metric_base = 1000;
- define Babel_WLAN_metric_inactive = 999;
- define OSPF_metric2_max = 16777215;
- define OSPF_preference_local = 160; /* > OSPF default = 150 */
- define HOT = 0;
- define BEST = 1;
- define COLD = 2;
- ##### Definitionen fuer alle bekannten IGP Instanzen:
- include "/usr/local/etc/bird.inst.conf";
- # Dort muss mindestens Folgendes definiert werden:
- #define potato_ospf1 = BEST; [... et al. ...]
- #function fn_instance_to_potato (int inst) -> int (HOT, ...)
- #function fn_proto_to_instance (string from_proto) -> int (1, 2, ...)
- #function fn_instance_to_bgpospf (int inst) -> string ("bgpXospfX")
- /* XXX zwecks Einrechnung der Babel Metrik, gehoert hier aber nicht hin: */
- function fn_a_Babel_WLAN_routes () {
- return ifname = "tap9";
- };
- /* Bausteine fuer Filter. Namenskonventionen:
- f_... Filter (accept/reject)
- fn_... Funktion
- ..._a_... true => accept
- ..._r_... true => reject
- ..._am_... true => accept + modify
- */
- function fn_a_Routed () {
- return net ~ Routed;
- };
- filter f_a_Routed {
- if fn_a_Routed()
- then accept;
- else reject "Routed";
- };
- function fn_r_Unrouted () {
- return ! (net ~ Unrouted_global || net ~ Unrouted_local);
- };
- filter f_r_Unrouted {
- if fn_r_Unrouted()
- then accept;
- else reject "Unrouted";
- };
- function fn_a_acceptable_routes () {
- return fn_r_Unrouted() && fn_a_Routed();
- }
-
- /* Einrechnung der Babel Metrik: */
- function fn_include_Babel_WLAN_routes () {
- case gw {
- include "/var/run/bird.babeld.conf";
- else: ospf_metric1 = ospf_metric1 + Babel_WLAN_metric_base + Babel_WLAN_metric_inactive;
- }
- }
- function fn_debug_ospf_route (string str)
- {
- print str, " ", net, " ^", scope, " *", source,
- " !", from, " :", gw, " (", preference, ") ",
- igp_metric, "/", ospf_metric1, "/", ospf_metric2,
- " [", ospf_tag, "]";
- # Fuehrt zu:
- # bird: filters, line 169: Can't operate with values of incompatible types
- #" [", fn_tag_to_source(ospf_tag), "|", fn_tag_to_path(ospf_tag), "]";
- }
- function fn_debug_ospf_route_before (string str)
- {
- printn str; fn_debug_ospf_route("?");
- }
- function fn_debug_ospf_route_after (string str)
- {
- printn str; fn_debug_ospf_route("!");
- }
- function fn_am_local_to_ospf_table () {
- if ! (proto ~ "ospf*") &&
- fn_a_acceptable_routes()
- then if ifname ~ "lo0"
- then return false;
- else { if preference < OSPF_preference_local
- then preference = OSPF_preference_local;
- return true; }
- else return false;
- }
- function fn_am_local_to_ospf_export () {
- if ! (proto ~ "*ospf*") &&
- fn_a_acceptable_routes()
- then { if ifname ~ "lo0"
- then return false;
- else # geroutete loopback Adressen auch per OSPF stubnet!
- if ifname ~ "lo*"
- then ospf_metric1 = 1;
- else ospf_metric1 = 10;
- ospf_metric2 = 0;
- return true; }
- else return false;
- }
- function fn_import_ospf_master (int from_instance) {
- if ! fn_a_acceptable_routes()
- then return false;
- # Schleifenvermeidung: routes mit tags von OSPF-Instanzen,
- # an denen dieser Router teilnimmt, sind schonmal hier
- # durchgelaufen, und zwar mit tag = 0, d.h. ohne Uebergang
- # zwischen OSPF-Instanzen. (Evtl. Ausnahme: Partitionierung
- # der source Instanz, sodass die urspruengliche route nicht
- # mit source = 0 hier ankam, sondern nur per Transit.)
- else if ospf_tag != 0
- then {
- if fn_instance_to_potato(from_instance) = HOT
- # TBD || fn_instance_to_transit(from_instance) = false
- then # kein Transit durch hot potato Instanzen
- return false;
- else if fn_is_local_ospf_instance(fn_tag_to_source(ospf_tag)) ||
- fn_any_local_instancebit_is_set_in_ospf_tag()
- then # re-entry
- if ! fn_reentrybit_is_set_in_ospf_tag()
- then # wg. counting-to-infinity
- fn_set_reentrybit_in_ospf_tag();
- }
- case from_instance {
- /* XXX zwecks Einrechnung der Babel Metrik, gehoert hier aber nicht hin: */
- # metric mittels /var/run/bird.babeld.conf (hoch)setzen:
- 2: fn_include_Babel_WLAN_routes();
- }
- return true;
- }
- function fn_import_master_ospf (string from_proto) {
- return proto = from_proto;
- }
- /* Funktioniert nicht als Funktion, aber als Filter,
- s. protocol pipe master2ospfX in bird.instX.conf.
- Grumpf:-(bird 1.5.0)
- function fn_export_master_ospf () {
- if proto ~ "ospf*"
- then return false;
- else return fn_am_local_to_ospf_table();
- }
- */
- function fn_am_master_to_bgpospf (int dest_instance)
- int from_instance;
- {
- if fn_a_acceptable_routes()
- then { from_instance = fn_proto_to_instance(proto);
- if ospf_tag = 0 # (lokale Route, keine Transitroute)
- then { # route entstammt einer IGP Instanz, an der dieser
- # router teilnimmt. Beim Uebergang in eine andere
- # IGP Instanz muss diese route, die gerade ein
- # lokales IGP verlaesst, mit dem tag dieser Instanz
- # versehen werden. Kommt die route dann spaeter
- # per transit wieder zur Urprungs-Instanz zurueck,
- # kann sie dank des tags als Rundlauefer erkannt
- # und entsprechend schleifenbehandelt werden.
- ospf_tag = from_instance;
- return true;
- }
- else if fn_instance_to_potato(from_instance) = HOT
- # TBD || fn_instance_to_transit(from_instance) = false
- then # kein Transit durch HOT Instanzen wg. Verlust der ursprünglichen Metrik
- return false;
- else { if fn_reentrybit_is_set_in_ospf_tag() &&
- fn_instancebit_is_set_in_ospf_tag(dest_instance)
- then # kein counting-to-infinity
- return false;
- # Transit-IGP, aus dem die Route gerade kommt, in die Route "einkerben"
- if ! fn_instancebit_is_set_in_ospf_tag(from_instance)
- then ospf_tag = ospf_tag + fn_instance_to_tagbit(from_instance);
- return true;
- }
- }
- else return false;
- }
- function fn_export_master_bgpospf (string dest_proto)
- int dest_instance;
- {
- dest_instance = fn_proto_to_instance(dest_proto);
- printn "master2bgp"; fn_debug_ospf_route_before(dest_proto);
- if proto ~ "ospf*" &&
- proto != dest_proto &&
- fn_am_master_to_bgpospf(dest_instance)
- then { printn "master2bgp"; fn_debug_ospf_route_after(dest_proto);
- bgp_local_pref = preference;
- bgp_path.prepend(ospf_tag);
- # optimal:
- # -> E1 mit metric1 = Summe
- # hot potato ("closest exit"):
- # -> E1 mit metric1 = 0, # geht nicht: metric2 = Summe
- # retour: automatisch mit mit metric1 = Summe, metric2 = 0
- # cold potato ("best exit", RFC4451):
- # -> E2 mit metric2 = Summe
- # ?: wie geht retour E2 -> E1, d.h. wie funktioniert
- # eine Unterscheidung von ursprünglichen E2 routes?
- # flag im ospf_tag?
- if # XXX geht nicht: ospf_metric2 = 16777235
- ospf_metric2 = OSPF_metric2_max
- then
- bgp_med = ospf_metric1;
- else
- bgp_med = ospf_metric2 + ospf_metric1;
- # zZ unbenutzt, erscheint im show all als [ASXi]/[ASXe]
- if ospf_tag != 0
- then
- if fn_reentrybit_is_set_in_ospf_tag()
- then
- bgp_origin = 2;
- else
- bgp_origin = 1;
- else
- bgp_origin = 0;
- accept;
- }
- else reject;
- }
- function fn_import_bgpospf ()
- {
- preference = bgp_local_pref;
- return true;
- }
- function fn_export_ospf (int dest_instance)
- string proto_bgpospf;
- int potato_ospf;
- {
- proto_bgpospf = fn_instance_to_bgpospf(dest_instance);
- potato_ospf = fn_instance_to_potato(dest_instance);
- printn "export-", dest_instance; fn_debug_ospf_route_before("");
- if fn_am_local_to_ospf_export()
- then return true;
- else if proto = proto_bgpospf
- then { ospf_tag = bgp_path.first;
- # optimal:
- # -> E1 mit metric1 = Summe
- # hot potato ("closest exit"):
- # -> E1 mit metric1 = 0, metric2 = Summe
- # retour: automatisch mit mit metric1 = Summe, metric2 = 0
- # cold potato ("best exit", RFC4451):
- # -> E2 mit metric2 = Summe
- # ?: wie geht retour E2 -> E1, d.h. wie funktioniert
- # eine Unterscheidung von ursprünglichen E2 routes?
- # also flag im ospf_tag kodieren?
- # !: nein, keine E2 routen als E2 durchlassen,
- # weil das jede Instanz selbst entscheiden soll,
- # also nur bei cold potato auf E2 setzen (lassen)
- #
- if potato_ospf = BEST
- then {
- # igp_metric = bgp_med;
- # bgp_med = 0;
- # scope = SCOPE_ORGANIZATION;
- ospf_metric1 = bgp_med;
- }
- else if potato_ospf = HOT
- then {
- # geht nicht, wird beim Setzen von
- # von ospf_metric1 genichtet:
- # ospf_metric2 = bgp_med;
- ospf_metric1 = 0;
- # XXX instance mit hot potato
- # XXX darf kein Transit sein!
- # XXX => keine tag routes exportieren
- }
- else if potato_ospf = COLD
- then ospf_metric2 = bgp_med;
- printn "export-", dest_instance; fn_debug_ospf_route_after("");
- return true;
- }
- else return false;
- }
- protocol device {
- scan time 10;
- }
- /* wg. BSD: */
- protocol direct {
- }
- protocol kernel kernel0 {
- learn on;
- scan time 5;
- import filter f_r_Unrouted;
- export filter f_r_Unrouted;
- }
- /* XXX zwecks Einrechnung der Babel Metrik, gehoert hier aber nicht hin: */
- table fib4table;
- protocol kernel kernel4 {
- description "babel FIB 4";
- kernel table 4;
- table fib4table;
- learn on;
- scan time 10;
- }
- ##### Definition der IGP Instanzen, an denen dieser Router teilnimmt:
- include "/usr/local/etc/bird.inst.local.conf";
|