| 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";
 
 
  |