BIRD conté un llenguatge simple de programació. (No, aquest no pot llegir correus
. Hi han dos objectes en aquest llenguatge: filtres i funcions. Els filtres són interpretats pel cor de BIRD quan una ruta ha començat a passar entre protocols i taules d'encaminament. El llenguatge de filtratge conté estructures de control if's i switch's, però no permet bucles. Un exemple de l'utilització de moltes característiques d'un filtre poden trobar-se a filter/test.conf.
Els filtres obtenen la ruta, miren els seus atributs i en modifiquen alguns d'ells si es desitja. Al final, aquest decideix si passa la ruta canviada (utilitzant accept o si es refusa reject. Mireu aquí un filtre simple:
filter not_too_far
int var;
{
if defined( rip_metric ) then
var = rip_metric;
else {
var = 1;
rip_metric = 1;
}
if rip_metric > 10 then
reject "La mètrica RIP és massa gran";
else
accept "ok";
}
Com pots veure, un filtre té una capçalera, una llista de variables locals, i un cos. La capçalera consisteix amb la paraula clau filter seguirda per un nom de filtre (únic). La llista de variables locals consisteix de parells de type name on cada parell defineix un variable local. El cos consisteix de { statements } .Cada statement s'acaba amb un ;. Tu pots agrupar diferents sentències en una sentència composta utilitzant claus ({ sentències }) que són utilitzades si vols per un bloc de codi condicional major.
BIRD suporta funcions, així no tens que repetir els mateixos blocs de codi un cop i un altre. Les funcions poder tenir zero o més paràmetres i no tenen variables locals. La recursivitat no està permesa. Mireu com son les definicions de funcions:
function name ()
int local_variable;
{
local_variable = 5;
}
function with_parameters (int parameter)
{
print parameter;
}
A diferència de C, les variables estan declarades després de la linia function, però abans del primer { (Per qui tingui curiositat, això forma part d'una norma, que ara mateix no recordo). Pots declarar els blocs que necessitis. Les funcions són cridades com en C: name(); with_parameters(5);. La funció pot retornar valors utlitzants la comanda return [expr]. Retornant un valor de sortida des de la funció actual (això és semblant a C).
Els filtres estan declarats d'una forma similar a les funcions exceptes que no poden tenir paràmetres explícits. Ells obtenen una entrada a la taula d'encaminament com a paràmetre implícit, aquest és passat automàticament a qualsevol funció cridada. El filtre a d'acabar amb la sentència accept o reject. Si hi ha un error d'execució en el filtre, la ruta es refusada.
Un bon truc per depurar filtres és utilitzar show route filter name des de la linia de comandes del client. Un exemple d'una sessió semblant seria:
pavel@bug:~/bird$ ./birdc -s bird.ctl
BIRD 0.0.0 ready.
bird> show route
10.0.0.0/8 dev eth0 [direct1 23:21] (240)
195.113.30.2/32 dev tunl1 [direct1 23:21] (240)
127.0.0.0/8 dev lo [direct1 23:21] (240)
bird> show route ?
show route [] [table ] [filter ] [all] [primary]...
bird> show route filter { if 127.0.0.5 ~ net then accept; }
127.0.0.0/8 dev lo [direct1 23:21] (240)
bird>
Cada variable i cada valor tenen un cert tipus. Els booleans, enters i enumeracions són incompatibles entre ells (això és així per evitar que ens disparis als peus).
Aquest és el tipus booleà, aquest només pot tenir dos valors,
trueifalse. El booleà és l'únic tipus que tu pots utilitzar en les sentènciesif.
Aquest és un tipues enter genèric, pots guardar-hi valors des de -2000000000 fins +2000000000. Valors que exedeixin no seràn comprobat. Pots utlitzar la sintàxi
0x1234per escriure valors hexagesimals.
Aquest és una parella de dos enters curts. Cada component pot tenir valors entre 0 i 65535. Els literals d'aquest tipus s'escriuen així
(1234,5678).
Aquest és una cadena de caràcters. No hi ha forma de modificar els strings en els filtres. Pots passar-los entre funcions, assignar-los a variables de tipus
string, imprimir-los com variables, però no pots encadenar dos strings. Els literals string s'escriuen com"Això és una constant string".
Aquest tipus pot incloure una única adreça IP. Depenent de la comfiguració a l'hora de la compilació de BIRD serà utilitzat, aquestes són adreces IPv4 o IPv6. Les adreces IP estan escrites en la notació estàndard (
10.20.30.40ofec0:3:4::1. Tu pots aplicar operadors especials.mask(num)en valors de tipus ip. Aquestes màscares indiquen tots els primers num bits de l'adreça IP. Així1.2.3.4.mask(seria correcte.= 1.0.0.0
Aquest tipus pot incloure un prefixe de xarxa que consisteix amb una adreça IP i un prefix de longitud. Els literals de prefix s'escriuen així
ipadress|pxlenoipadress|netmask. Hi han dos operadors especials per a prefixes:.ipque extreu l'adreça IP del parell, i.len, que separa la longitud del prefixe del parell. Així1.2.0.0/16.pxlen = 16és cert.
Els filtres reconeixen cuatre tipus de conjunts. Els conjunts son semblants als strings: tu pots passar-los però no pots modificar-los. Els literals de tipus
set intés així[ 1, 2, 5..7]. Tal com pots veure, els valors simples i els rangs estan permesos en els conjunts. Els sets de prefixes són especials: pots especificar quines longituds de prefixe han de coincidir utilitzant[ 1.0.0.0/8+, 2.0.0.0/8-, 3.0.0.0/8{5,6} ].3.0.0.0/8{5,6}coincideixen amb els preficex 3.x.x.x on la longitud del prefixe és 5 o 6.address/num+és un abreujament deaddress/{0,num},address/num-és un abreujament deaddress/{0,num-1}. Per exemple,1.2.0..0/16 ~ [ 1.0.0.0/8{15,17}]és cert, però1.0.0.0/8 ~ [ 1.0.0.0/8- ]és fals.
Els tipus enumeració fixen un conjunt de possibilitats. No pots definir les teves pròpies variables del tipus, però alguns atributs de ruta són de tipus enumeració.
Una ruta BGP és una llista de nombre d'un sistema autònom. Tu no pots escriure literals d'aquest tipus.
Els màscares BGP són patrons equivalents utilitzats pels camis BGP (utilitzant la sintàxi
path ~/2 3 5 ?/). Les màscares s'asemblen a patrons de comodins utilitzats en shells UNIX. Els números dels sistemes autònoms coincideixen amb ells,?equival a qualsevol (excepte buit) seqüència de nombres AS arbritaris (*no pot escollir-se, perquè/*és el començament d'un comentari). Per exemple:/4 3 2 1/ ~ /? 4 3 ?/és cert, però/4 3 2 1/ ~ /? 4 5 ?/és fals.
Llista de comunitat similar al conjunt de parells, excepte que aquest no és com els altres conjunts. Aquest pot ser modificat. No existeixen literals d'aquest tipus.
El llenguatge de filtratege suporta operadors d'enters comuns (+, -, *, /), parèntesis (a*(b+c)), comparació (a=b, a!=b, a<b, a>=b). Les operacions lògiques inclouen l'operador unari no (!), i (&&) i or (||). Els operadors especials inclouen ~ per la operació "és un element d'un conjunt" - aquest pot utilitzar-se en un element set d'elements del mateix tipus (retornant cert si l'element hi és en el conjunt indicat), o en IP i prefices (retornant cert si la IP esta dins el rang definit per aquest prefix), o un prefix i prefix (retornant cert si el primer prefix es més específic que el segon) o en bgppqth i bgpmask (retornant cert si el cami equival a la màscara) o un parell de clist (retornant cert si la comunitatés un elements de la llista de la comunitat).
Els filtres permeten dues estructures de control: condicions i sel·leccions de coincidència.
La sintàxi de una condició és: if boolean expression then command1; else command2; i pots utilitzar { command1; command2; ... } enlloc de cada commanda. La clausula else pot omètre's. Si la boolean expression és certa, el command1 s'executa, altrament s'executa el command2.
El cas és similar al case de Pascal. La sintàxi és case expre { else | num_or_prefix [ .. num_or_prefix]: statement ; [ ... ] }. La expressió de després del case por ser del qualsevol tipus que pugui estar al costat esquerre de l'operadors ~ i algun que hagi de ser membre del conjunt anteriorment permes :. Es permeten múltiples comandes sense l'agrupament {}. Si la expressió ecpr coincideix amb alguna clàusula :, les sentències de després de else: són executades.
Aquest és un exemple que utilitza les estructures if i cased:
case arg1 {
2: print "dos"; print "Pots possar més comandes sense {}";
3 .. 5: print "de tres a cinc";
else: print "algun altre";
}
if 1234 = i then printn "."; else {
print "no és 1234";
print "Necessites {} al voltant de múltiples comandes";
}
A un filtre se li passa implícitament una ruta, i pot accedir als seus atributs com si fosin accesos a variables. Els intents per accedir a atributs indefinits dona com a resultat a un error d'execució; pots comprovar si un atribut està definit utilitzant l'operador defined (atribut).
prefix net
La xarxa de la ruta de que es parla. Le només lectura. (Mireu el capítol sobre les taules d'encaminament.)
enum scope
L'ambit de l'adreça de la xarxa (
SCOPE_HOSTper adreces locals a aquest client,SCOPE_LINKper els específics per un enllaç físic,SCOPE_SITEiSCOPE_ORGANIZATIONper adreces privades,SCOPE_UNIVERSEper la globalitat de les adreces visibles).
int preference
La preferència d'una ruta. (Mireu el capítol sobre les taules d'encaminament).
ip from
L'encaminador des del qual s'ha originat la ruta. Només de lectura.
ip gw
El pròxim salt dels paquets encaminats utilitzant aquesta ruta on han de ser reenviats.
enum source
quin protocol m'ha explicat aquesta ruta. Els valors possibles són:
RTS_DUMMY, RTS_STATIC, RTS_INHERIT, RTS_DEVICE, RTS_STATIC_DEVICE, RTS_REDIRECT, RTS_RIP, RTS_OSPF, RTS_OSPF_EXT, RTS_OSPF_IA, RTS_OSPF_BOUNDARY, RTS_BGP, RTS_PIPE.
enum cast
Tipus de ruta (
RTC_UNICASTper rutes normals,RTC_BROADCAST, RTC_MULTICAST, RTC_ANYCASTper rutes broadcast, multicast i anycast respectivament). De només lectura.
enum dest
Tipus de destí dels paquests on han d'enviar-se a (
RTD_ROUTERper reenviament a un encaminador veí,RTD_NETWORKper encaminar-lo a una xarxa directament connectada,RTD_BLACKHOLEper paquest que s'han de descartar sense notificar-ho,RTD_UNREACHABLE, RTD_PROHIBITper paquets que han de ser retornats amb un ICMP de client innaccesible / o un missatge ICMP d'administrativament prohibit). Només de lectura.
També existeixen alguns atributs espècífics d'un protocol que seràn descrits en les seccions del protocol corresponents.
Les següents sentències estan disponibles:
variable = expr
Activa una variable donant-li un valor.
accept|reject [expr]
Accepta o refusa una ruta, amb la possibilitat d'imprimir expr.
return expr
Retorn expr des de la posició actual, la funció finalitza en aquest punt.
print|printn expr [, expr...]
Imprimeix les expressions donades; s'utilitzen principalment mentre els filtres estanen depuració. La variant
printnno fa un final de linia.
quitbird
Finalitza BIRD. Utilitzat quan es depura l'intèrpret del filtre.