Date de publication du RFC : Juin 2013
Auteur(s) du RFC : W. Wang (Zhejiang Gongshang University), E. Haleplidis (University of Patras), K. Ogawa (NTT Corporation), C. Li (Hangzhou DPtech), J. Halpern (Ericsson)
Chemin des normes
Réalisé dans le cadre du groupe de travail IETF forces
Première rédaction de cet article le 29 juin 2013
Le protocole ForCES vise à permettre la création d'équipements réseaux (par exemple des routeurs) en assemblant des pièces d'origines diverses, parlant un protocole commun et pouvant donc interagir. Ce RFC marque l'achèvement de la première (et très longue) phase de ForCES, la normalisation complète de ce protocole. Notre RFC 6956 décrit la bibliothèque standard de ForCES, les parties d'un routeur qu'on trouvera partout et qui assurent les fonctions indispensables comme faire suivre un paquet IP.
ForCES peut servir à bien d'autres choses et il y aura aussi des bibliothèques pour d'autres équipements que les routeurs, et aussi des bibliothèques non-standard, développées par tel ou tel projet. Mais pour atteindre l'objectif premier de ForCES, créer un routeur par assemblage de pièces standards, cette bibliothèque « routeur » était le dernier élement manquant.
Avant de lire ce RFC 6956, il faut bien se pénétrer du cadre général (RFC 3746), du protocole (RFC 5810) et du modèle de données (RFC 5812). J'en extrais quelques termes qu'il faut connaître :
Ethernet/0/2
», etc). Un LFB est une fonction logique : dans la matériel, on ne
retrouve pas forcément ce concept.La bibliothèque composée des classes définies dans ce RFC 6956 permet de réaliser un routeur complet, mettant en œuvre toutes les fonctions obligatoires du RFC 1812, notamment :
Place maintenant au cœur de ce RFC, les classes qui y sont définies. Le choix du groupe de travail forces (section 3.2) a été de privilégier la souplesse en définissant plutôt trop de classes que pas assez. Chaque classe ne va donc effectuer qu'un minimum de fonctions, être logiquement séparée des autres classes et notre routeur devra donc mettre en œuvre beaucoup de classes. Cela rend donc le RFC très long et je ne vais donc pas parler de toutes les classes, seulement de quelques unes choisies comme exemples. Pour la totalité des classes, vous devez lire le RFC.
Les définitions des classes s'appuient sur un certain nombre de
types définis en section 4. Le RFC 5812 avait
normalisé les types de base comme uint32
,
char
ou
boolean
. Notre RFC y ajoute quelques types
atomiques comme IPv4Addr
,
IPv6Addr
, IEEEMAC
(une
adresse MAC),
PortStatusType
(permettant d'indiquer si le port
est activé ou non et s'il fonctionne), VlanIDType
pour le numéro de VLAN, etc. Il définit
également des types composés comme MACInStatsType
(une entrée dans le tableau de statistiques pour les paquets entrants, analysés à la
couche 2), IPv6PrefixInfoType
(un préfixe IPv6),
IPv4UcastLPMStatsType
(une entrée dans le tableau de
statistiques pour les paquets IPv4), etc. Logiquement, les
tableaux qui utilisent ces types sont également définis comme
IPv6PrefixTableType
(un tableau de préfixes IPv6)
ou VlanInputTableType
(un tableau de
VLAN).
Un NE manipule des paquets donc il y a évidemment des types de
paquets parmi lesquels EthernetII
,
IPv4
, IPv6
, et même
Arbitrary
pour des paquets quelconques.
Le tout est formellement décrit en XML dans la section 4.4. Ainsi, une adresse IPv4 est :
<dataTypeDef> <name>IPv4Addr</name> <synopsis>IPv4 address</synopsis> <typeRef>byte[4]</typeRef> </dataTypeDef>
et une IPv6 est :
<dataTypeDef> <name>IPv6Addr</name> <synopsis>IPv6 address</synopsis> <typeRef>byte[16]</typeRef> </dataTypeDef>
Un type atomique comme la capacité du lien est définie par :
<dataTypeDef> <name>LANSpeedType</name> <synopsis>LAN speed type</synopsis> <atomic> <baseType>uint32</baseType> <specialValues> <specialValue value="0x00000001"> <name>LAN_SPEED_10M</name> <synopsis>10M Ethernet</synopsis> </specialValue> <specialValue value="0x00000002"> <name>LAN_SPEED_100M</name> <synopsis>100M Ethernet</synopsis> </specialValue> ...
Même chose pour le PortStatusType
mentionné plus haut :
<dataTypeDef> <name>PortStatusType</name> <synopsis> Type for port status, used for both administrative and operative status. </synopsis> <atomic> <baseType>uchar</baseType> <specialValues> <specialValue value="0"> <name>Disabled</name> <synopsis>Port disabled</synopsis> </specialValue> <specialValue value="1"> <name>Up</name> <synopsis>Port up</synopsis> </specialValue> <specialValue value="2"> <name>Down</name> <synopsis>Port down</synopsis> </specialValue> </specialValues> </atomic> </dataTypeDef> <dataTypeDef>
Et les types structurés ? Un exemple est celui des statistiques sur les paquets sortants, qui a deux composants (les champs des objets), un pour les paquets transmis et un pour les paquets jetés :
<dataTypeDef> <name>MACOutStatsType</name> <synopsis> Data type defined for statistics in EtherMACOut LFB. </synopsis> <struct> <component componentID="1"> <name>NumPacketsTransmitted</name> <synopsis>Number of packets transmitted</synopsis> <typeRef>uint64</typeRef> </component> <component componentID="2"> <name>NumPacketsDropped</name> <synopsis>Number of packets dropped</synopsis> <typeRef>uint64</typeRef> </component> </struct> </dataTypeDef>
Un autre exemple est le préfixe IPv6, qui réutilise le type atomique IPv6Addr
:
<dataTypeDef> <name>IPv6PrefixInfoType</name> <synopsis>Data type for entry of IPv6 longest prefix match table in IPv6UcastLPM LFB. The destination IPv6 address of every input packet is used as a search key to look up the table to find out a next hop selector.</synopsis> <struct> <component componentID="1"> <name>IPv6Address</name> <synopsis>The destination IPv6 address</synopsis> <typeRef>IPv6Addr</typeRef> </component> <component componentID="2"> <name>Prefixlen</name> <synopsis>The prefix length</synopsis> <atomic> <baseType>uchar</baseType> <rangeRestriction> <allowedRange min="0" max="32"/> </rangeRestriction> </atomic> </component> ...
Une fois tous ces types définis (et cela prend un bon bout du RFC),
on peut les utiliser pour bâtir les classes (section 5). Chaque classe
va être un gabarit dont on tirera les instances. Premier exemple :
notre routeur ForCES va évidemment avoir besoin de connaître
Ethernet et de traiter des paquets Ethernet, en
envoi et en réception. Ethernet étant très varié, commençons par un
LFB (Logical Function Block) qui représente le
niveau physique, EtherPHYCop
. Ce LFB (cette
partie logique d'un routeur) a des composants pour indiquer l'état du
port (AdminStatus
et
OperStatus
), composants qui peuvent être lus et
modifiés via le protocole ForCES. Ce LFB peut aussi générer des
événements comme par exemple le changement d'état d'un port
(PHYPortStatusChanged
).
Au niveau au dessus (couche 2), il y a le
LFB EtherMACIn
. C'est par exemple là que se
trouve le composant LocalMACAddresses
qui indique
l'adresse MAC. ou bien le composant
PromiscuousMode
qui dit si on veut recevoir (ou
pas) tous les paquets, même adressés à une autre machine.
Rappelez-vous : cette bibliothèque standard de ForCES privilégie la
souplesse, et crée donc beaucoup de LFB, pour
pouvoir les arranger comme souhaité. Rien que pour Ethernet, il y en a
encore plusieurs comme EtherEncap
qui modélise
les fonctions d'encapsulation et de décapsulation des
trames (ajout ou retrait des en-têtes
Ethernet).
Mais on ne peut pas passer toute la journée sur les couches
basses. Pour « construire » un routeur par assemblage de LFB, il nous
faut maintenant des fonctions de manipulation
d'IP. C'est le cas du LFB
IPv6Validator
qui représente les fonctions de
validation d'un paquet (avant qu'on décide de le traiter, ou de le
jeter s'il est invalide). On suit le RFC 2460 et
on considère comme invalide (ne devant pas être transmis) les paquets
ayant une taile inférieure à la taille minimale, les paquets
ayant une adresse source ou destination inacceptable, etc. Il y a
aussi des paquets nommés « exceptionnels » qui, sans être à proprement
parler invalides, ne pourront pas être transmis normalement (par
exemple ceux avec un hop limit descendu à
zéro).
Et, ensuite, le travail sera fait par les LFB de transmission. Oui,
ils sont plusieurs. Pour IPv6, au moins IPv6UcastLPM
(trouver le LPM, Longest Prefix Match, dans la
table) et IPv6NextHop
(sélection du routeur
suivant), sans compter des futurs LFB optionnels, par exemple pour
mettre en œuvre RPF.
Les LFB sont eux aussi formalisés en XML
(section 6). Par exemple, le dernier que nous avons vu,
IPv6NextHop
, sera :
<LFBClassDef LFBClassID="13"> <name>IPv6NextHop</name> <synopsis> The LFB abstracts the process of next hop information application to IPv6 packets. It receives an IPv6 packet with an associated next hop identifier (HopSelector), uses the identifier as a table index to look up a next hop table to find an appropriate output port. </synopsis> <inputPorts> <inputPort group="false"> <name>PktsIn</name> <synopsis> A port for input of unicast IPv6 packets, along with a HopSelector metadata. </synopsis> ... </inputPort> </inputPorts> <outputPorts> ... </outputPorts> <components> <component componentID="1"> <name>IPv6NextHopTable</name> <synopsis> The IPv6NextHopTable component. A HopSelector is used to match the table index to find out a row which contains the next hop information result. </synopsis> <typeRef>IPv6NextHopTableType</typeRef> </component> </components> </LFBClassDef>
Si la tête commence à vous tourner sérieusement, c'est sans doute
normal et prévu. Les auteurs du RFC ont pensé à vous et inclus une
section 7 qui décrit comment on crée une fonction de haut niveau à
partir des LFB de cette bibiothèque standard. Leur premier exemple est
la transmission de paquets IPv4 et le dessin ne compte pas moins de
treize LFB... (Dont, il est vrai, neuf juste pour Ethernet.) Pour
ajouter ARP, cela prend sept LFB (certains sont
communs par exemple EtherEncap
est utilisé à la
fois par la transmission de paquets IPv4 et par ARP).
Les classes des LFB sont désormais dans un registre IANA, ce qui permettra d'en ajouter plus facilement d'autres.
Voilà, arrivé à ce stade, on a de quoi « fabriquer » un routeur ou plus exactement de quoi le modéliser. En pratique, les vrais routeurs seront bien différents mais ils exporteront aux clients ForCES des fonctions représentées par ces LFB standards, fonctions qu'on pourra configurer avec Forces.
Version PDF de cette page (mais vous pouvez aussi imprimer depuis votre navigateur, il y a une feuille de style prévue pour cela)
Source XML de cette page (cette page est distribuée sous les termes de la licence GFDL)