lalahop
Categorie: Administration réseau

Maquetter des réseaux avec LXC

Ce billet va tenter de résumer la manière dont j'utilise LXC pour créer et utiliser des maquettes de grande taille pour tester des choses (protocoles, logiciels, ...) ayant trait aux réseaux informatiques.

Table des matières

Pourquoi maquetter ?

Cela peut être utile de simuler la présence et les interactions d'un nouvel élément avant sa mise en production effective sur le réseau physique voire de maquetter un nouveau réseau complet pour voir s'il répond aux objectifs fixés avant d'acheter le matériel.

Maquetter permet aussi de découvrir et d'apprendre : mettre en œuvre des techniques, des protocoles, ... dans une maquette permet de les découvrir plus efficacement que d'étudier simplement la théorie.

Maquetter est aussi utile dans la recherche, pour faire des expériences et les rendre reproductibles, savoir quels facteurs sont aggravants (en les isolant les uns après les autres), trouver des solutions et les tester.

Les avantages de LXC pour maquetter

Bien que LXC puisse être utilisé pour isoler des applications, notamment pour un usage serveur, il présente également des avantages pour maquetter les machines d'un réseau.

LXC reste plus léger que de la virtualisation de type KVM : un ordinateur portable relativement modeste avec 3G de RAM fait tourner une maquette de 40 routeurs qui font de l'OSPF, du BGP et s'échangent un peu de trafic.

Dans un milieu plus "apprentissage/découverte", LXC est meilleur que Netkit (et ses frontend graphiques comme Marionnet), à mon avis, car LXC est maintenu activement et il offre la possibilité d'utiliser un noyau plus récent (2.26 avec Netkit, 2.19 avec Marionnet), ce qui n'est pas négligage quand on veut tester des fonctionnalités nouvelles ou quand certaines applications (notamment des démons) ont trop évoluées et ne sont plus capables de se binder sur un vieux noyau (il me semble avoir vu un cas avec Apache httpd). Sans compter la facilité de modification du système de base dans le cas de LXC (alors que c'est un véritable calvaire avec Netkit). Je ne sais pas ce qu'apporte (ou non) LXC comparé à User Mode Linux utilisé directement, sans passer par Netkit. ÉDIT du 19/09/2013 à 19h05 : Comme le mentionne Kartoch dans les commentaires, on peut utiliser Netkit sans avoir les droits root (modulo que /dev/shm ne doit pas être en noexec), ce qui a son intérêt dans une salle de TP à la fac/IUT/autre. Fin de l'édit

Néanmoins, autant dans un usage d'isolation des applications sur un serveur, je peux entrevoir les limites de LXC, la sécurité (un conteneur compromis qui permettrait de remonter au noyau et de mettre le zouk dans le reste du système/des autres conteneurs, cela ne me surprendrait pas), autant j'avoue ne pas savoir dans quels cas le fait que ce soit le même noyau dans l'hôte et dans tous les conteneurs est nuisible à un maquettage. Je peux simplement dire que cela me semble être utile dans les expériences aux timings serrés ou pour faire des mesures car la vision du temps est identique dans tous les conteneurs : l'instant T est le même dans tous les conteneurs.

Mettre des conteneurs LXC en réseau

Pour relier les conteneurs entre eux, on peut utiliser un ou plusieurs bridges. C'est intégré de base dans LXC et cela permet de voir tout le trafic de la maquette en dumpant simplement le trafic qui passe sur le bridge avec tcpdump/wireshark. Très pratique pour débugger, faire des stats, ... De plus, comme un bridge mémorise les MAC, comme un switch physique, le trafic unicast n'est pas transféré aux conteneurs qui n'en sont pas les destinataires.

Si l'on a besoin de fonctionnalités plus avancées (VLAN, agrégation de liens, ...), on peut utiliser Open vSwitch. J'avais testé pour découvrir : la communication entre conteneurs LXC juste marche. J'ai entendu dire que VDE ne fonctionnait pas avec les interfaces TAP de LXC. N'ayant jamais eu besoin de plus qu'un bridge, je n'ai jamais vérifié.

J'ignore s'il est possible d'interfacer LXC avec des routeurs Cisco/Juniper émulés. Dynamips semble pouvoir utiliser VDE mais comme LXC semble ne pas pouvoir ...

Adressage

Pour adresser/nommer votre maquette, je vous conseille fortement d'utiliser les ressources réservées à l'IANA : IPv4/v6, ASN, TLD, ... Cela fait sérieux et évite les collisions avec le réseau local (quand vous aurez eu à dépatouiller un tel cas, vous vous mettrez à utiliser les ressources réservées, je vous le garantit !).

Rendre la maquette plus réaliste

Au niveau réseau, Netem (network emulator) permet de rajouter de la latence, de la perte, de la corruption, ... sur les liens entre les différents conteneurs LXC. Pour que cela ne fasse pas trop artificiel, il est possible de faire varier la latence, la perte, ... en utilisant une distribution à la normale. On trouve plein d'exemples sur le web : Netem | The Linux Foundation, Simuler un lien WAN sous Linux chez NicoLargo, ... Netem est juste indispensable dès lors que l'on essaye de reproduire des réseaux réels ou, au moins, des conditions réelles.

Au niveau de chaque conteneur, les cgroups (control groups) permettent d'affecter des priorités d'accès aux ressources (CPU, réseau, ...) différentes pour chaque conteneur. Cela permet de favoriser un conteneur plutôt qu'un autre. Dans le cadre de maquettes réseau, cela permet de tenir compte des disparités que l'on trouve sur un réseau physique : on n'a des modèles de routeurs différents avec des capacités de traitement différentes ... Cela permet aussi de mesurer le comportement d'algorithmes de routage dans des situations défavorables. LXC lui-même est basé sur les cgroups. Je n'ai pas encore utilisé les cgroups dans une maquette donc je n'ai pas de ressources à conseiller plus que d'autres.

Automatiser le tout

Je vais vous montrer comment j'automatise la création et la gestion d'une grosse maquette avec des conteneurs LXC. L'ennui, c'est qu'il y a du besoin spécifique dedans (routing, forward, ...). Je vais essayer de tout bien vous expliquer pour que vous puissiez adapter à vos projets.

Preseed-file

Mes conteneurs sont tous basés sur Debian puisque Debian, c'est la vie. Pour créer des dizaines de conteneurs LXC à la chaîne, il est nécessaire d'avoir un preseed-file bien foutu qui configurera une bonne partie du conteneur (login, logiciels supplémentaires à installer, ...) lors de la création dudit conteneur sans poser aucune question dans une interface semi-graphique (ça ne passe pas à l'échelle ce genre de chose). Or, un preseed-file bien foutu, qui juste marche, bah ça ne court pas le web.

Voici celui que j'utilise, issu de quelques trouvailles personnelles minoritaires et de la fusion de ces deux modèles : Creating a Debian sliver template sur wiki.confine-project.eu et Debian wheezy preseed file for lxc-create -t debian lxc version 0.9.0.alpha2.

Pour le résumer :

  • Les conteneurs auront l'architecture amd64 et seront créés à partir du dépôt sid ;
  • Packages supplémentaires : less iputils-ping iptables telnet traceroute wget nano rsyslog bash-completion quagga et openssh-server ;
  • Utilisation d'un bridge nommé br0 ;
  • MAC fixe (on la remplacera plus loin vu que LXC ne sait pas faire tout seul) ;
  • On ne supprime pas la capabilitie « sys_admin » car elle est nécessaire à Zebra ;
  • On ne crée pas un compte utilisateur normal ;
  • Le mot de passe root est « toor » ;
  • On utilise le fuseau horaire « Europe/Paris » ;
# # Debian preseed file for CONFINE sliver template
# Tested on lxc 0.9.0~alpha3-2 and live-debconfig 4.0~a17.
 
# ## Distribution and packages
lxc-debconfig lxc-debconfig/distribution string sid
lxc-debconfig lxc-debconfig/architecture string amd64
lxc-debconfig lxc-debconfig/archives multiselect none
lxc-debconfig lxc-debconfig/mirror string ftp://ftp2.fr.debian.org/debian/
lxc-debconfig lxc-debconfig/archive-areas multiselect main
lxc-debconfig lxc-debconfig/packages string less iputils-ping iptables telnet traceroute wget nano rsyslog bash-completion quagga
 
# ## Network
# Please adjust to the name of the bridge used in your host.
lxc-debconfig lxc-debconfig/eth0-bridge string br0
# Private MAC address, to be replaced on sliver creation.
lxc-debconfig lxc-debconfig/eth0-mac string 52:C0:A1:AB:BA:1A
# Private veth interface name, to be replaced on sliver creation.
#lxc-debconfig lxc-debconfig/eth0-veth string veth-sliver
 
# ## Other container options
lxc-debconfig lxc-debconfig/auto boolean false
# Use live-debconfig to further configure the container.
lxc-debconfig lxc-debconfig/lxc-debconfig-with-live-debconfig boolean true
lxc-debconfig lxc-debconfig/apt-recommends boolean false
# Avoid debconf questions.
lxc-debconfig lxc-debconfig/debconf-frontend select noninteractive
## (default value)
##lxc-debconfig lxc-debconfig/debconf-priority string medium
 
# For running commands in the container and host at the end.
#lxc-debconfig lxc-debconfig/late-command string
#lxc-debconfig lxc-debconfig/late-host-command string 
 
 
# Capabilities to be dropped from the container.
lxc-debconfig lxc-debconfig/capabilities string \
    audit_control audit_write ipc_lock mac_admin mac_override \
    sys_module sys_pacct sys_rawio sys_resource sys_time \
    syslog wake_alarm
 
# For mounting filesystems in container.
#lxc-debconfig lxc-debconfig/mount0/entry string
##lxc-debconfig lxc-debconfig/mount0/comment string \
##    Bind mount host path in container
 
# ## Live-debconfig scripts configuration
 
# (For some reason live-debconfig options must be on a single line
# or the following options are not interpreted correctly.)
 
live-debconfig live-debconfig/components multiselect openssh-server, passwd
 
# ### LXC (sysvinit)
# Perform LXC tweaks in the container.
live-debconfig live-debconfig/sysvinit/lxc-enable boolean true
## (default values)
##live-debconfig live-debconfig/sysvinit/lxc-consoles string 6
##live-debconfig live-debconfig/sysvinit/lxc-disable-services string checkroot.sh hwclockfirst.sh hwclock.sh kmod module-init-tools mountall.sh mountkernfs.sh umountfs umountroot
 
### Hardware clock access (util-linux)
live-debconfig live-debconfig/util-linux/hwclockaccess boolean false
 
# ### Host name (hostname)
# Host name, to be replaced on sliver creation.
live-debconfig live-debconfig/hostname/hostname string sliver
 
# ### Network configuration (ifupdown)
live-debconfig live-debconfig/ifupdown/lo-comment string The loopback interface
live-debconfig live-debconfig/ifupdown/lo-enable boolean true
 
# Private interface method, to be replaced on sliver creation.
live-debconfig live-debconfig/ifupdown/eth0-ipv4-comment string The private interface
live-debconfig live-debconfig/ifupdown/eth0-ipv4-method select dhcp
 
# For static configuration of network interfaces.
##live-debconfig live-debconfig/ifupdown/eth0-ipv4-method select static
##live-debconfig live-debconfig/ifupdown/eth0-ipv4-address string 1.2.3.4
##live-debconfig live-debconfig/ifupdown/eth0-ipv4-netmask string 255.255.255.0
##live-debconfig live-debconfig/ifupdown/eth0-ipv4-gateway string 1.2.3.1
##live-debconfig live-debconfig/ifupdown/eth0-ipv4-network string 1.2.3.0
##live-debconfig live-debconfig/ifupdown/eth0-ipv4-broadcast string 1.2.3.255
##live-debconfig live-debconfig/ifupdown/eth0-ipv4-mtu string 1500
##live-debconfig live-debconfig/ifupdown/eth0-ipv4-post-up string post-command
 
# For static configuration of DNS.
##live-debconfig live-debconfig/ifupdown/nameserver-addresses string 5.6.7.8 9.10.11.12
##live-debconfig live-debconfig/ifupdown/nameserver-domain string example.com
##live-debconfig live-debconfig/ifupdown/nameserver-search string lan example.com
##live-debconfig live-debconfig/ifupdown/nameserver-options string debug
 
# ### Users (passwd)
live-debconfig live-debconfig/passwd/shadow boolean true
live-debconfig live-debconfig/passwd/root-login boolean true
live-debconfig live-debconfig/passwd/make-user boolean false
live-debconfig live-debconfig/passwd/root-password string toor
live-debconfig live-debconfig/passwd/root-password-again string toor
 
# FUSEAU HORAIRE
tzdata tzdata/Areas select Europe
tzdata tzdata/Zones/Etc select UTC
tzdata tzdata/Zones/Europe select Paris

Depuis peu, il n'est plus possible d'utiliser un preseed-file avec le template Debian sauf à utiliser le package « lxc » qui se trouve dans le dépôt « experimental » de Debian. Voir : 0.9.0~alpha3-2+deb8u1 : “lxc” package : Debian .

Scripts

Ensuite, il faut des scripts pour automatiser la création, le démarrage, l'arrêt et l'éventuelle destruction des conteneurs. Ci-dessus, vous trouverez les scripts que j'utilise. Ce n'est pas du grand art mais ça fait ce qui doit être fait.

Commun

Commun est un fichier qui sert à positionner les variables et les tests utiles à plusieurs scripts comme le nom de tous les conteneurs de la maquette LXC ou vérifier les droits.

MACHINES="R1 R2 R3 R4"
 
if [ $USER != "root" ]
then
	echo "Vous devez exécuter ce script en étant root."
	exit 1
fi
Créer

Pour que vous puissiez comprendre ce script, je dois vous expliquer comment je hiérarchise les différents éléments qui permettent de créer la maquette.

Racine de la maquette
|-- network
|-- routing
|-- scripts
|-- tests

Network contient des fichiers nommés « config.$NOM_DU_ROUTER ». Chacun d'entre eux contient les instructions qui permettent de mettre en place le réseau sous LXC (« lxc.network.type », « lxc.network.ipv4 », « lxc.network.hwaddr », ...). Elles seront ajoutées au fichier « config » du conteneur correspondant lors de la création de la maquette. C'est aussi dans ce dossier que je stocke un fichier « hosts » qui fait la correspondance entre le nom de mes machines (voir des interfaces quand j'ai besoin d'une telle granularité (exemple : « 198.18.0.1 eth0.r1.local. »)) et leur adresse IP "principale" (une loopback, par exemple).

Routing contient, quand j'en ai besoin, les fichiers de configuration de Quagga. Exemple : bgpd.conf, ospfd.conf, zebra.conf, ... Tous sont suffixés avec le nom du conteneur LXC sur lequel devra être mis le fichier. Exemple : « zebra.conf.R1 ». Ils seront copiés dans le dossier /etc/quagga lors de la création de la maquette.

Scripts contient tous les scripts shell de gestion de la maquette. Typiquement ceux que je suis en train de vous présenter. 😛

Tests contient des scripts ou des binaires qui permettent d'effectuer des tests sur la maquette. Le script bash « pingall » (voir plus bas) est typiquement un de ces moyens de test. Ils seront copiés dans /root.

Ceci étant dit, voici le script le plus complet que j'ai écrit pour construire une maquette avec LXC :

#!/bin/bash
 
source commun
 
HERE=`pwd`
PARENT=$HERE/..
 
for i in $MACHINES
do
	# Création du conteneur
	lxc-create -n $i -t debian -- --preseed-file=$HERE/preseed-file
 
 
	# Proc doit être en RW pour permettre l'activation de l'ip_forward
	sed -i 's/proc proc proc ro/proc proc proc rw/' /var/lib/lxc/$i/config
 
 
	# Pour que SSH accepte les connexions
	sed -i 's/UsePAM yes/UsePAM no/' /var/lib/lxc/$i/rootfs/etc/ssh/sshd_config
 
 
	# Mise en place du réseau
	head -n-6 /var/lib/lxc/$i/config > /var/lib/lxc/$i/config.tmp
	mv /var/lib/lxc/$i/config.tmp /var/lib/lxc/$i/config
	cat $PARENT/network/config.$i >> /var/lib/lxc/$i/config
 
	# Toutes les interfaces sont sur le même bridge donc les réponses ARP ne venant 
	# pas de la bonne interface peuvent être gênantes. Pour eviter ça, on active arp_filter
	echo "net.ipv4.conf.all.arp_filter = 1" >> /var/lib/lxc/$i/rootfs/etc/sysctl.conf
	echo "net.ipv4.conf.default.arp_filter = 1" >> /var/lib/lxc/$i/rootfs/etc/sysctl.conf
 
	intSurCeRouteur=`grep -Eo "eth[0-9]" /var/lib/lxc/$i/config`
 
	for j in $intSurCeRouteur
	do
			echo "net.ipv4.conf.$j.arp_filter = 1" >> /var/lib/lxc/$i/rootfs/etc/sysctl.conf
	done
 
 
	# Associations IP<->nom
	cat $PARENT/network/hosts >> /var/lib/lxc/$i/rootfs/etc/hosts
 
 
	# Routing (on veut zebra + ospf + bgp)
	cp $PARENT/routing/zebra.conf.$i /var/lib/lxc/$i/rootfs/etc/quagga/zebra.conf
	cp $PARENT/routing/ospfd.conf.$i /var/lib/lxc/$i/rootfs/etc/quagga/ospfd.conf
	cp $PARENT/routing/bgpd.conf.$i /var/lib/lxc/$i/rootfs/etc/quagga/bgpd.conf
	sed -i 's/^zebra=no/zebra=yes/' /var/lib/lxc/$i/rootfs/etc/quagga/daemons
	sed -i 's/^ospfd=no/ospfd=yes/' /var/lib/lxc/$i/rootfs/etc/quagga/daemons
	sed -i 's/^bgpd=no/bgpd=yes/' /var/lib/lxc/$i/rootfs/etc/quagga/daemons
 
 
	# Forward
	sed -i 's/#net.ipv4.ip_forward=1/net.ipv4.ip_forward=1/' /var/lib/lxc/$i/rootfs/etc/sysctl.conf
 
 
	# Tests
	cp $PARENT/tests/pingall.sh /var/lib/lxc/$i/rootfs/root/
	chmod u+x /var/lib/lxc/$i/rootfs/root/pingall.sh
done
Lancer

On met en place ce qu'il faut (cgroups, création du bridge, on ne drop pas les paquets qui passent d'un conteneur à l'autre, ..) puis on lance les conteneurs et on vérifie qu'ils sont bien lancés.

#!/bin/bash
 
source commun
 
mount -t cgroup none /sys/fs/cgroup
 
brctl addbr br0 
ip link set up dev br0
 
iptables -P FORWARD ACCEPT
ip6tables -P FORWARD ACCEPT
 
for i in $MACHINES
do
	lxc-start -d -n $i
done
 
sleep 10
 
for i in $MACHINES
do
	echo "$i :"	
	lxc-info -n $i
	echo -e "\n"
done

Alors oui, ce script causera l'affichage d'erreurs lors d'utilisations successives car il n'y a pas de contrôles et que le bridge existe déjà et que les cgroups sont déjà montés. Rien de grave donc, juste trois lignes de textes sur la console. 😛

Stopper

On arrête les conteneurs et on vérifie qu'ils ont bien été arrêtés.

#!/bin/bash
 
source commun
 
for i in $MACHINES
do
	lxc-stop -n $i
done
 
sleep 10
 
for i in $MACHINES
do
	echo "$i :"	
	lxc-info -n $i
	echo -e "\n"
done

Je sens que je vais me faire troller sur l'utilisation de « lxc-stop » qui fait un arrêt violent des conteneurs en lieu et place de « lxc-halt » qui laisse les conteneurs s'éteindre par eux-mêmes. L'explication est simple : sur chacune de mes maquettes, lxc-halt fonctionne pour quelques conteneurs très minoritaires même en attendant et je dois lancer lxc-stop ensuite ... Et comme je n'ai remarqué aucun dégât en utilisant uniquement lxc-stop ... bah j'utilise uniquement lxc-stop.

Détruire

Permet de détruire tous les conteneurs LXC de la maquette.

#!/bin/bash
 
source commun
 
for i in $MACHINES
do
	lxc-destroy -n $i
done
Netem

Pour ajouter une latence calculée et différente entre chaque lien sans utiliser de distribution à la normale :

#!/bin/bash
 
# À lancer sur l'hôte, après que toutes les interfaces du lab 
# aient été créées ... soit environ start.sh + 10 secondes
 
modprobe sch_netem
 
# Un groupe de lignes = un routeur. Ici R1
tc qdisc add dev lxc_R1_R2 root netem delay 1.180890283ms
tc qdisc add dev lxc_R1_R3 root netem delay 2.3495148631ms
 
# R2
tc qdisc add dev lxc_R2_R1 root netem delay 1.180890283ms
 
# R3
tc qdisc add dev lxc_R3_R1 root netem delay 2.3495148631ms
tc qdisc add dev lxc_R3_R4 root netem delay 0.8994545122ms
 
# R4
tc qdisc add dev lxc_R4_R3 root netem delay 0.8994545122ms

Pour appliquer d'autres caractéristiques (perte, corruption) sur un ou plusieurs liens, il suffit d'ajouter des lignes à ce script.

Pingall

Pour vérifier que le réseau de mes maquettes est opérationnel, j'utilise, en premier lieu, un bête script qui ping toutes les adresses IPs allouées (en utilisant les noms, comme ça, on teste aussi la validé du fichier /etc/hosts 😉 ) et qui s'arrête à la première erreur rencontrée.

J'utilise souvent une loopback adressée sur chaque routeur. Cela permet de considérer les routeurs comme des destinations, ce qui est toujours utile (qui à dit MPLS ? 🙂 ). Cela permet aussi "d'accrocher" les protocoles de routage dynamiques (exemple : BGP et « update-source ») dessus.

#!/bin/bash
 
INTERFACES_PHY="eth0.r1.local eth1.r1.local eth0.r2.local eth0.r3.local eth1.r3.local eth0.r4.local "
 
INTERFACES_LO="lo.r1.local lo.r2.local lo.r3.local lo.r4.local"
 
 
echo -e "\033[0;32m\n\n---------- Testons d'abord chaque lien ----------\n\033[0;39;49m"
j=0
for i in $INTERFACES_PHY
do
	ping -c 2 -w 2 $i
 
	if [ $? -ne 0 ]
	then
		echo -e "\033[0;31m\n\n---------- ÉCHEC ----------\n\033[0;39;49m"
		exit 5
	fi
 
	echo -e "\n"
done
 
 
echo -e "\033[0;32m\n\n---------- Testons ensuite chaque loopback ----------\n\033[0;39;49m"
j=0
for i in $INTERFACES_LO
do
	ping -c 2 -w 2 $i
 
	if [ $? -ne 0 ]
	then 
		echo -e "\033[0;31m\n\n---------- ÉCHEC ----------\n\033[0;39;49m"
		exit 5
	fi
 
	echo -e "\n"
done
 
 
echo -e "\033[0;32m\n\n---------- SUCCÈS ----------\n\033[0;39;49m"
exit 0

Auto-hébergement sur OLinuXino

Aujourd'hui, je vous propose un billet sur les ordinateurs monocarte OLinuXino, concurrents (comme d'autres) du Raspberry Pi. On fera une comparaison des deux avant de voir comment on s'auto-héberge sur un OLinuXino.

Je vous conseille la lecture (ou au moins l'ouverture en parallèle) de mon billet sur comment s'auto-héberger avec un Raspberry Pi car je vais faire des parallèles et je tiendrai pour acquis la connaissance de certaines informations.

Je suis désolé pour la mise en forme minable de certaines parties ... On fait ce que l'on peut avec un WordPress. 😉

Table des matières

Quelle alternative libre au RPi ?

Il y a tout un tas d'ordinateurs monocarte concurrents du RPi sur le marché : OLinuXino, Cubieboard, Gooseberry, Hackberry, PandaBoard ... Lequel choisir ?

Tous les constructeurs utilisent plus ou moins les mêmes composants, notamment pour le CPU : les Allwinner AXX (exemples : A13, A20) et TI OMAPXX sont courants. Cela permet d'avoir plus de documentation pour une même erreur puisque l'erreur sera commune à plusieurs modèles d'ordinateurs monocarte. Cela rapproche aussi "les communautés" : j'ai remarqué ce fait entre la communauté autour des CubbieBoard et celle autour des OLinuXino.

Tous les fabricants prétendent faire de l'Open Source et de l'Open Hardware ...

Et tous les ordinateurs monocarte ont des inconvénients éthiques du point de vue de la liberté qu'ils accordent à leurs utilisateurs. Quelques exemples (tirés de : Single-board computers - Free Software Foundation) :

  • le GPU du RPi utilise un blob propriétaire ... et comme c'est lui qui fait l'amorçage du système ... ;
  • le chip WiFi des Cubieboard, Gooseberry et A13-OLinuXino-WIFI utilise un driver/firmware propriétaire ;
  • le GPU des BeagleBoard, OLinuXino, Cubieboard, Gooseberry, Hackberry et PandaBoard utilise un driver/firmware propriétaire. Le driver libre, Lima, n'est pas totalement abouti d'après ce je lis à droite et à gauche ;

Comme c'est bonnet blanc et blanc bonnet entre tous ces ordinateurs, je me suis contenté d'en choisir un parmi ceux :

  • qui ont des morceaux proprios uniquement dans les composants que je n'utilise pas et qui ont un comportement bien connu et attendu (exemple : le GPU sur OLinuXino ; contre-exemple : le GPU sur RPi qui sert aussi à booter le système d'exploitation) ;
  • qui sont distribués depuis la zone euro histoire d'éviter de me taper des conversions monétaires ;
  • qui ont un minimum de documentation potable.

C'est ainsi que j'ai choisi de me prendre un OLinuXino.

Quel OLinuXino choisir ?

Le modèle d'OLinuXino qui se rapproche le plus d'un Raspberry Pi modèle B, c'est l'OLinuXino A10S, le modèle sans la mémoire NAND 4G qui permet de se passer de SD pour booter/utiliser la carte mais dont le bootloader libre ne permet pas de tirer partie. L'OLinuXino A13 est supérieur au RPi en terme de puissance CPU, équivalent en terme de RAM disponible, ... mais ne dispose pas d'un port réseau. Il n'est donc pas comparable au RPi. L'OLinuXino iMX233 dispose d'un port réseau mais n'est pas comparable au RPi en terme de quantité de RAM disponible et de puissance CPU.

L'OLinuXino A10S coûte 54 € (TTC, hors frais de port) contre 37 € (TTC, hors frais de port) pour le RPi modèle B au moment où je l'ai acheté. Aujourd'hui, un RPi modèle B se trouve, dans la même boutique, pour 31 € (TTC, hors frais de port) donc l'écart se creuse mais nous verrons plus loin que la qualité des deux prestations n'est strictement pas équivalente. De même, il ne faut pas oublier que les prix du RPi sont tirés vers le bas à cause de sa popularité (popularité -> ils commandent des volumes plus gros de composants/production -> coûts tirés vers le bas -> gain répercuté sur le prix de vente).

Bien qu'un RPi modèle B soit déjà trop puissant pour faire office de petit serveur (DNS + mail + web + XMPP principalement) pour un ou pas beaucoup d'utilisateurs et que donc un OLinuXino A10S aurait largement suffit à ces usages, je me suis laissé tenté par un OLinuXino A20 à 66 € (TTC, hors frais de port). Un CPU double cœur, 1 GB de RAM, plus de connectique, ... Bref, tout ce qui sert à rien pour l'usage serveur précédemment décrit. 😀 Le surplus de puissance me permettra de monter du monitoring (usage qui à l'air d'être assez vorace sur un RPi), de tester des trucs, ce genre de choses ... Pour 10 € de plus, l'appel de l'usage futur est tentant. 🙂

Coût total d'acquisition

ÉDIT du 13/10/2014 à 19h55 : Ce billet date d'il y a plus d'un an donc les prix sont purement indicatifs toussa. L'OLinuXino A20 voit son coût total d'acquisition diminuer de plus de 13€, la gamme RPi a été renouvelée (RPi modèle B+) et voit son coût total d'acquisition diminuer d'environ 6€. Fin de l'édit

Pour ceux qui veulent se faire une idée du coût total d'acquisition (ie : quand on n'a ni l'adaptateur secteur, ni une carte SD, bref quand on n'a rien sous la main). Tous les prix sont TTC, souvent arrondis au supérieur. Bien sûr, ce qui suit est purement indicatif, vous trouverez peut-être des boutiques moins chères mais je ne rembourse pas deux fois la différence. 😛

RPi (37 €) + adaptateur secteur/USB (7,43 €) + câble USB A vers micro USB B (pour aller de l'adaptateur au RPi) (2,93 €) + une carte SD (environ 10-12 € pour un produit décent) + transport (15-20 € pour un service décent avec assurance) : 75-80 € au total.

OLinuXino A20 (66 €) + transfo électrique (8,31 €) + carte SD (10-12 €) + transport (15-20 €) : 100-105 € au total.

Pour un OLinuXino A10S, le coût total s'élève à 87-92 €.

Pour le RPi, on peut aussi ajouter un boîtier à 7 €. À ma connaissance, il n'existe rien de tel pour les OLinuXino (sauf pour les IMX233). ÉDIT du 13/10/2014 à 19h55 : Taziden me signale que des boîtiers sont en vente pour les OLinuXino A10 LIME et A20. Fin de l'édit

OLinuXino A20 versus Raspberry Pi modèle B

Éthique

  • Le RPi est un projet de la Raspberry Pi Foundation, une association sans but lucratif reconnue comme œuvre de bienfaisance basée en Angleterre. OLinuXino est un produit d'Olimex, une société basée en Bulgarie. J'ai entendu une remarque selon laquelle c'est mieux de s'équiper en RPi plutôt qu'en OLinuXino car cela aide une association reconnue comme œuvre de bienfaisance. Sauf que, pour l'instant, je n'ai pas vu la RPi Foundation effectuer une donation ou un projet humanitaire. Si l'argent reste dans la caisse, ça permet, certes, d'investir, mais où est l'œuvre de bienfaisance ? Simplement fournir un ordinateur monocarte avec de bons morceaux propriétaires dedans ? Obtenir des réductions fiscales ? Bref, ma conscience est tranquille même si j'ai acheté un produit auprès d'une saloperie de société capitaliste qui exploite des Bulgares (et des Chinois -> Allwinner AXX) !
  • OLinuXino, plus libre que RPi ? Vaste question. Voici quelques éléments de réponse :
    • Au niveau des packages installés par défaut, je n'ai rien vu venant de contrib ou de non-free sur l'OLinuXino A20 avec vrms. ÉDIT du 09/08/2014 à 18h25 : Sur la nouvelle image Debian distribuée par Olimex depuis mars 2014, « ULTIMATE A20 Debian 4GB SD-card image release-7 with hardware accelerated video », les packages firmware-ralink et firmware-realtek sont présents. Fin de l'édit

      Sur le RPi, les packages non-free suivants sont installés par défaut : firmware-atheros, firmware-brcm80211, firmware-libertas, firmware-ralink, firmware-realtek. Comme vous le voyez, il s'agit de firmwares pour cartes réseaux WiFi donc si vous n'utilisez pas de dongle WiFi, vous pouvez les désinstaller.

    • Sur le RPi, le GPU est totalement propriétaire. Donc le boot du système, l'affichage 2D/3D et le décodage/encodage vidéo matériel sont faits avec du logiciel sur lequel personne (sauf Broadcom) n'a le contrôle.

      Sur l'OLinuXino, le GPU et le chargement d'un OS depuis la flash interne (pour les modèles qui en sont équipés) sont totalement propriétaires. Donc l'affichage 2D/3D et le décodage/encodage vidéo matériel sont faits avec du logiciel sur lequel personne n'a le contrôle. Lima, le driver libre pour l'affichage 2D/3D ne semble pas être encore prêt pour mesa. Le VPU, un CedarX nécessite lui aussi des blobs propriétaires mais une alternative libre, basée sur du reverse engineering, est en train d'émerger mais reste encore à l'état de PoC bien que sachant déjà décoder le MPEG2 et H264. Notons que le GPU n'est pas responsable du chargement de l'OS donc, pour ceux qui veulent un serveur at home et pas un media center, l'OLinuXino me paraît être plus libre qu'un RPi.

    • Au niveau matériel, la RPi Foundation ne communique pas les schémas ni même les datasheet complètes (et pour cause, Broadcom les distribue uniquement sous NDA). Le RPi n'est donc pas un projet open hardware.

      Olimex semble distribuer l'intégralité des schémas et des datasheet. Voir :

      Olimex distribue tout ça sous licence CC-BY-SA. Les morceaux de code produits par Olimex sont sous GPL. Je vous laisse regarder le dépôt Github par vous même pour le reste des composants et les autres modèles d'OLinuXino.

      Je ne suis pas compétent pour affirmer si c'est de l'open hardware complet ou s'il manque des schémas ou des données techniques. J'émets néanmoins un bémol : on n'a pas les schémas des composants Allwinner (CPU,GPU,VPU). Comment fonctionnent-ils vraiment ? J'ai l'impression que seul le travail d'Olimex est distribué sous licence libre. Est-ce suffisant ?

    • Il est regrettable qu'Olimex utilise des formats de fichiers propriétaires et des services centralisés dans un projet qui se veut le plus ouvert et libre possible. Pour les services centralisés, je parle de Github (qui contient tous les documents importants) et de Google Docs (sur lequel sont stockés certains éléments comme les images Debian/Android des cartes SD). Un dépôt git, ça se met chez soi. Des images bien lourdes, ça se diffuse en torrent. Pour les formats de fichiers propriétaires, je parle principalement des rar disponibles ça et là dans le dépôt git. gzip, lzma, 7z existent ! Je ne jugerai pas l'usage du logiciel propriétaire Eagle vu que je suis un zéro pointé dès que l'on parle de conception de PCB. J'ai fait remonter ces griefs à Olimex. Réponse : « You are right that we still have some files in rar archives but those are files that we have already received as a rar from other sources (Allwinner technology and other manufacturers). In respect to their packaging we have kept the same package. All files modified or created by Olimex LTD are packed in zip archives. ». Ce à quoi je réponds : quid de l'image Debian pour carte SD qui est distribuée en rar via Google Docs ? ÉDIT du 13/09/2013 à 00h35 : « You are correct about the rar. We will try to upload files in 7-zip now on. » Fin de l'édit
    • Le dernier point problématique concerne le noyau fourni dans l'image officielle. Comme l'indique la page consacrée à l'OLinuXino A20 sur le wiki d'Olimex : « Note: Kernel 3.3 is based on Android SDK Kernel and may contain GPL violations which are behind our control, it's not recommended to use it nor to improve/contribute to it for this purpose better use Linux-Sunxi 3.4 kernel which have everything working exept the LCD touchscreen. We work on the TS issue to solve. »

      J'ai essayé de compiler le noyau 3.4. La compilation se passe bien mais le noyau ne boot pas : les fichiers de logs ne sont pas modifiés sur la carte SD. Je n'ai pas d'écran à brancher sur mon OLinuXino ni d'adaptateur série/USB sous la main donc je ne peux pas debugguer plus loin. Apparemment, je ne suis pas le seul à être en échec.

      Pour ceux qui voudraient essayer, je recommande les ressources suivantes :

      ÉDIT du 09/08/2014 à 18h35 : La nouvelle image Debian distribuée par Olimex depuis mars 2014, « ULTIMATE A20 Debian 4GB SD-card image release-7 with hardware accelerated video », contient Linux 3.4.X, version Sunxi, plus basée sur l'Android SDK. \o/ De là à dire qu'il n'y a plus de bouts propriétaires, je ne m'engagerai pas sur ce point car je n'ai pas assez de recul pour juger. Fin de l'édit

Technique

  • Comme je l'ai écrit plus haut, entre un RPi et un OLinuXino, on n'est clairement pas dans le même niveau de prestation :
    • L'OLinuXino est livré dans une boîte en carton alors que le RPi est livré nu.
    • Les OLinuXino A10 et A20 sont équipés d'une horloge matérielle (RTC) ... mais comme il n'y a pas de batterie de base (on peut en acheter une, il y a un port matériel pour la brancher), je n'en vois pas l'intérêt (avoir une plus grande précision ?) : l'horloge se perd en cas de coupure de l'alimentation électrique. Ce point n'est pas gênant dans un usage serveur puisque tout administrateur consciencieux utilise NTP sur ses serveurs.
    • L'OLinuXino possède plusieurs boutons. Certains sont fortement utiles (RESET/PWR) mais le reste est totalement futile à mon avis. En effet, les boutons restants servent dans un contexte de media-center. Or, dans un tel contexte, qui va se bouger le cul pour aller appuyer sur ces boutons ? Télécommande powa.
    • L'OLinuXino utilise des bus séparés pour les ports USB là où le RPi utilise un même bus ce qui peut s'avérer limitant pour certains usages fortement consommateurs en capacité de transfert (webcam (OpenCV par exemple) + disque dur c'est déjà trop) puisqu'elle est partagée entre tous les périphériques de tous les ports. De même, la carte réseau de l'OLinuXino n'est pas greffée sur un contrôleur USB, contrairement à celle du RPi.
    • Pour ceux qui veulent faire de l'électronique et non pas un serveur avec leur OLinuXino (ce qui est quand même la destinée première de ces ordinateurs), ce dernier possède plus d'entrée/sorties que le RPi : sur le RPi, on parle de 17 entrées/sorties (dont 2*i2c et 2*UART) dont 5 sont partagées sur un même bus (source : GNU Linux Magazine France numéro 156). Sur l'OLinuXino A20, on parle de 160 GPIO (répartis sur 3 bus) + 2*UEXT + 1*UART ... Reste à voir combien de GPIO sont exploitables en parallèle.
    • Le reste de la connectique (audio, HDMI, USB, ...) reste quand même bonnet blanc et blanc bonnet entre le RPi et l'OLinuXino, à mon avis.
    • Un boîtier acheté en supplément peut contenir le RPi. À ma connaissance, rien n'est commercialisé ni même prévu pour les OLinuXino, à l'exception de l'iMX233. La boîte en carton de livraison semi-ouverte + une mousse non-conductrice et antistatique (pour le surélever dans la boîte) permet de compenser un peu ce manque ... ÉDIT du 13/10/2014 à 19h55 : Taziden me signale que des boîtiers sont en vente pour les OLinuXino A10 LIME et A20. Fin de l'édit
    • À l'inverse du RPi, l'OLinuXino A20 dispose d'une unique LED allumée en permanence : celle qui indique que la carte est sous-tension. Elle est de couleur rouge donc, à l'inverse des LEDs oranges et vertes du RPi, elle est moins irritante la nuit. Et la LED de l'OLinuXino ne pulse pas, contrairement à celles du RPi qui éclairent la moitié d'une pièce.

      ÉDIT du 09/08/2014 à 18h45 : Avec la nouvelle image Debian distribuée par Olimex depuis mars 2014, « ULTIMATE A20 Debian 4GB SD-card image release-7 with hardware accelerated video », une LED verte discrète clignote à côté de la LED rouge. Ce clignotement est géré par un script custom d'Olimex : /opt/led_blink.sh. Sans ce script, la LED reste allumée en permanence. Si vous voulez l'éteindre en permanence, il faut ajouter ceci dans /etc/rc.local :

      echo 47 > /sys/class/gpio/export
      echo out > /sys/class/gpio/gpio47_ph2/direction
      echo 0 > /sys/class/gpio/gpio47_ph2/value

      Fin de l'édit

  • L'OLinuXino permet des transferts via le réseau plus rapides que le RPi.

    Pour l'envoi d'un fichier de 512 Mo, au contenu issu de /dev/zero, depuis mon RPi vers un desktop, en scp, j'obtiens un débit stable de 3,2 Mo/s.

    Ce n'est pas une limitation de la carte SD qui fournit 25 Mo/s environ en lecture. C'est une limitation du CPU du RPi :

    %Cpu(s): 51,8 us, 30,4 sy,  0,0 ni,  0,0 id,  0,0 wa,  1,3 hi, 16,6 si,  0,0 st
    25420 root    20   0  8912 1340  804 R  88,8  0,3   0:19.20 sshd                                                                  
    25421 root    20   0  2196  720  592 S   5,5  0,1   0:01.23 scp

    En utilisant netcat (« nc -vv -l -p 1234 > test » sur le desktop, « nc -vv <IP> 1234 < test » sur le RPi,), toujours sur TCP, pour transférer le même fichier, j'obtiens 5,6 Mo/s (mesuré avec iftop). Mais, même là, j'ai l'impression que le transfert est limité par la puissance du CPU du RPi :

    %Cpu(s):  4,5 us, 55,5 sy,  0,0 ni,  0,0 id,  0,6 wa,  2,9 hi, 36,5 si,  0,0 st
    25458 root    20   0  2344  724  600 R  89,3  0,1   0:41.71 nc
       36 root    20   0     0    0    0 S   4,5  0,0   3:43.15 mmcqd/0

    Sur mon OLinuXino A20, j'obtiens 5,2 Mo/s avec scp. On est CPU-limited : sshd n'utilise qu'un seul core, le CPU passe encore 40 % de son temps à idler :

    %Cpu(s): 31,5 us, 15,1 sy,  0,0 ni, 40,1 id,  0,0 wa,  0,0 hi, 13,3 si,  0,0 st
    2552 glucas    20   0  7892 1212  664 R  93,3  0,1   0:38.70 sshd
    2553 glucas    20   0  1772  648  520 R   9,3  0,1   0:03.06 scp

    Avec netcat, je ne suis plus limité par le CPU et j'obtiens 11,5 Mo/s.

  • La température de l'OLinuXino A20 est inférieure à celle du RPi. Je n'ai pas de thermomètre qui permettrait de prendre en compte uniquement la chaleur dégagée par l'ordinateur ni de caméra thermique donc c'est du pur ressenti bien subjectif. Peut-être que la plus grande surface de l'OLinuXino permet une dissipation thermique supérieure ...
  • Un RPi équipé de Raspbian utilise ses propres dépôts dont je ne sais pas si je peux avoir confiance (même si plein de miroirs sont hébergés par des gens sérieux, ça ne veut rien dire). J'ai tenté d'utiliser les dépôts Debian traditionnels sur mon RPi, je me suis pris une avalanche d'erreurs (même en désactivant la "branche" « RPi »), j'ai abandonné. Quid des mises à jour de sécurité ? En combien de temps sont-elles distribuées ? Je n'en sais rien, ce n'est pas documenté. Lors de la dernière faille de sécurité dans BIND, la mise à jour est apparue 1 jour plus tard que dans les dépôts Debian traditionnels. Ce délai peut être long dans le cas d'un usage serveur. ÉDIT du 09/08/2014 à 18h55 : Et que penser de ce type de listchanges : « --- Modifications pour openssl (libssl1.0.0 openssl) ---
    openssl (1.0.1e-2+rvt+deb7u11) wheezy-staging; urgency=low

    * Bump version number so it is above previous raspbian versions.
    (the change previously in the raspbian versions is now in Debian). » ? Ça fait quand même 4 DSA sur OpenSSL pour lesquels Raspbian nous assure que nous sommes tranquilles. Fin de l'édit

    L'OLinuXino utilise les dépôts Debian traditionnels pour les mises à jour/installations. Donc la team Debian, Debian-security, ....

    Notons que dans les deux cas, des logiciels sont installés en dehors du mécanisme apt. C'est le cas du noyau, par exemple. Il faudra voir ce que ça donne lorsqu'une faille de sécurité sera découverte sur ces logiciels là. ÉDIT du 23/01/2016 à 18h00 : On peut utiliser le noyau packagé par Debian (à partir de Debian Jessie) afin de bénéficier du suivi de la sécurité réalisée par la team Debian-security. Voir : Installer le noyau packagé par Debian sur une carte OLinuXino (et Raspberry Pi). FIN DE L'ÉDIT

Autre

  • En une semaine, c'est acheté et livré. Et je parle bien de l'intégralité de ma commande. Contrairement au RPi où j'ai attendu plus d'un mois et demi avant de tout recevoir ... Oui, l'adaptateur USB/secteur c'est moins utile sans RPi ... Et RPi + adaptateur, c'est moins utile sans le cable USB/micro USB ... Pourtant, je n'ai pas commandé mon RPi durant leur période de gloire où tout le monde en voulait un.

Les grandes lignes pour transformer son OLinuXino en serveur

J'utilise l'image Debian fournie par Olimex sur leur wiki.

  • Si vous avez acheté la carte SD avec l'image Debian dessus, le /etc/network/interfaces est incorrect : l'interface eth0 ne sera pas montée au boot car la ligne « auto eth0 » est commentée et même si elle ne l'était pas, l'interface est configurée avec un adressage statique en 192.168.0.244/24. Il faut donc changer ça en mettant la SD dans un lecteur de cartes mémoires puis en modifiant /etc/network/interfaces. Rien à signaler sur l'image téléchargée. J'ai fait remonter l'info au support d'Olimex. ÉDIT du 09/08/2014 à 18h55 : C'est un choix assumé : « Note: in the previous Debian releases the Ethernet was auto-detected and initialized during boot BUT this was causing big delays in the start-up of the board if you didn't want to use Ethernet or if there wasn't Ethernet cable connected. » Fin de l'édit
  • Pour faire booter la carte, il n'y a pas de manipulations compliquées, c'est comme avec le RPi : alimentez-la en électricité et ça part tout seul. Après quelques dizaines de secondes, un nmap -sV vous montrera qu'un serveur SSH tourne sur l'OLinuXino. Il suffit donc de s'y connecter : root/olimex.
  • Comme avec le RPi, la première chose à faire est de créer un utilisateur normal puis de changer le mot de passe du compte root pour un mot de passe fort. Puis déposer sa clé publique, modifier la configuration du serveur SSH pour ne pas autoriser les connexions en tant que root (su est là pour l'élévation de privilèges) et pour autoriser uniquement l'authentification par clés, ... Bref, tout ça c'est du classique.
  • Avec l'image « ULTIMATE A20 Debian 4GB SD-card image release-7 with hardware accelerated video », il y a un peu de ménage à faire :
    # Supprimer le compte utilisateur normal Olimex
    userdel olimex
    rm -rf /home/olimex
     
    # Supprimer des dossiers/fichiers vides/inutiles à la racine
    rm -rf /a /sunxi-tools /Desktop
     
    # Supprimer les sunxi-tools inutiles ici
    rm -rf /opt/sunxi-tools
     
    # Si vous ne voulez pas du script pour faire clignoter la LED verte
    rm /opt/led_blink.sh
    sed -i "s=\./opt/led_blink.sh&==" /etc/rc.local
     
    # Root est connecté automatiquement (sans demande de mdp) sur la console série (ttyS0)
    # Exemple : root     ttyS0                     21:56   1680days  0.08s  0.04s -bash
    # Pour désactiver ce comportement :  
    sed -i "s=T0:2345:respawn:/sbin/getty -L -a root ttyS0 115200 linux=#&=" /etc/inittab
  • Il convient de compléter le fichier /etc/apt/sources.list qui est notoirement incomplet : il manque les dépôts debian-security et volatile (renommé stable-updates depuis wheezy).
    # STABLE
    deb ftp://ftp.debian.org/debian/ wheezy main
     
    # STABLE-UPDATES (EX-VOLATILE)
    deb ftp://ftp.debian.org/debian/ wheezy-updates main
     
    # SECURITY
    deb ftp://security.debian.org/debian-security/ wheezy/updates main

    Bien sûr, il faudra faire un apt-get update, as usual.

  • Faire les mises à jour (sauf si l'installation est fraîche, of course) :
    apt-get -y update && apt-get -y upgrade &&  apt-get -y dist-upgrade && apt-get -y autoremove && apt-get -y autoclean
  • Changer (ou pas) d'IO scheduler pour un scheduler plus adapté aux mémoires flash :
    L'intérêt de cette manipulation fait souvent débat de ce que j'ai vu dans les forums. Je vous conseille de tester vous même car cela dépend de la carte SD. Pour moi, le résultat est sans appel :

    Avec le scheduler deadline :

    dd if=/dev/zero of=test bs=1M count=512
    512+0 records in
    512+0 records out
    536870912 bytes (537 MB) copied, 52.2637 s, 10.3 MB/s
     
    rm test
     
    timeout -s2 60 dd if=/dev/zero of=test
    1122023+0 records in
    1122023+0 records out
    574475776 bytes (574 MB) copied, 60.1867 s, 9.5 MB/s

    Avec le scheduler NOOP :

    dd if=/dev/zero of=test bs=1M count=512
    512+0 records in
    512+0 records out
    536870912 bytes (537 MB) copied, 44.4487 s, 12.1 MB/s
     
    rm test
     
    timeout -s2 60 dd if=/dev/zero of=test
    1167132+0 records in
    1167132+0 records out
    597571584 bytes (598 MB) copied, 63.1541 s, 9.5 MB/s

    De plus, j'ai un sentiment d'une meilleure réactivité du système, en cas de fortes lectures/écritures avec le scheduler noop.

    Pour voir le scheduler actif et le changer temporairement (pour modifier, il faut être root, of course) :

    echo noop > /sys/block/mmcblk0/queue/scheduler
    cat /sys/block/mmcblk0/queue/scheduler
    [noop] deadline

    Pour le changer définitivement, il faut créer un fichier « uEnv.txt » à la racine de la première partition de votre carte SD (là où il y a « script.bin » et « uImage ») qui contient :

    extraargs=elevator=noop

    Ce fichier est utilisé par U-boot pour compléter sa variable « bootargs » qui permet de passer des paramètres au noyau (cmdline).

    J'ai trouvé le mécanisme sur la page suivante : linux-sunxi/u-boot-sunxi.

    Normalement, lors du prochain reboot de votre OLinuXino, le scheduler noop sera utilisé et cat /proc/cmdline affichera ceci :

    console=ttyS0,115200 root=/dev/mmcblk0p2 rootwait loglevel=8 panic=10 elevator=noop
  • Changer le fuseau horaire : soit tzselect, soit :
    echo "Europe/Paris" > /etc/timezone 
    cp /usr/share/zoneinfo/Europe/Paris /etc/localtime
  • Configurer les applications pour le français :
    dpkg-reconfigure locales
     
    # Et comme ça ne fonctionne pas ...
    sed -i 's/LANG=en_US.UTF-8/LANG=fr_FR.UTF-8/' /etc/environment
  • Désinstaller l'inutile pour un serveur (gain : environ 550 Mo) :
    apt-get autoremove --purge gnome-* xserver-* desktop-* consolekit hicolor-icon-theme vim-* aspell aspell-en tsconf scratch notification-daemon dictionaries-common lightdm lightdm-gtk-greeter gcc g++ mplayer alsa-base alsa-utils gcc-4.6 gcc-4.6-base dosfstools esound-common wireless-tools wpasupplicant mpg321 mpg123 wdiff patch isc-dhcp-client slim midori consolekit hicolor-icon-theme leafpad vim-* aptitude aptitude-common aspell aspell-en xarchiver wpagui tsconf scratch samba-common nfs-common ppp openbox notification-daemon network-manager netsurf-common mupdf ncdu bluez cifs-utils dictionaries-common dillo dnsmasq-base fbset galculator gksu gpicview lightdm lightdm-gtk-greeter lxappearance lxinput lxpanel lxmenu-data lxpolkit lxrandr lxsession lxsession-edit lxshortcut lxtask lxterminal obex-data-server obexd-client gtk2-engines idle idle3 triggerhappy gcc g++ gdb gdbserver isc-dhcp-client alsa-base alsa-utils wireless-tools wpasupplicant xinit strace xterm blt firmware-* lksctp-tools xkb-data kbd fontconfig-config fonts-freefont-ttf ttf-freefont ttf-dejavu-core libblas3 libatlas3-base alsa-tools apt-listchanges autoconf automake autotools-dev cpio cpuburn cpufrequtils dialog git git-man glmark2-* i2c-tools linux-libc-dev lxde-icon-theme make mesa-* minicom ntfs-3g sshfs tasksel tasksel-data whiptail x11-common x11proto-* xorg-sgml-doctools isc-dhcp-common
  • Installer l'indispensable :
    apt-get install iptables telnet traceroute rsyslog bash-completion tcpdump ethtool dnsutils
  • Installer votre indispensable (screen/tmux, vim/nano/emacs, bash/dash/zsh, ...).
  • Installer vos logiciels serveur et les configurer avec vos réglages habituels. Ces configurations ne changent pas.

    ÉDIT du 09/08/2014 à 20h15 : Avec l'ancienne image fournie par Olimex (Linux 3.3 Android based, avant mars 2014), on obtient les erreurs suivantes lors du lancement de bind9 :

    Aug  8 20:38:19 A20 named[2635]: loading configuration from '/etc/bind/named.conf'
    Aug  8 20:38:19 A20 named[2635]: reading built-in trusted keys from file '/etc/bind/bind.keys'
    Aug  8 20:38:19 A20 named[2635]: using default UDP/IPv4 port range: [1024, 65535]
    Aug  8 20:38:19 A20 named[2635]: using default UDP/IPv6 port range: [1024, 65535]
    Aug  8 20:38:19 A20 named[2635]: net.c:142: unexpected error:
    Aug  8 20:38:19 A20 named[2635]: socket() failed: Permission denied
    Aug  8 20:38:19 A20 named[2635]: net.c:142: unexpected error:
    Aug  8 20:38:19 A20 named[2635]: socket() failed: Permission denied
    Aug  8 20:38:19 A20 named[2635]: no IPv6 interfaces found
    Aug  8 20:38:19 A20 named[2635]: no IPv4 interfaces found
    Aug  8 20:38:19 A20 named[2635]: not listening on any interfaces
    Aug  8 20:38:19 A20 named[2635]: generating session key for dynamic DNS
    Aug  8 20:38:19 A20 named[2635]: sizing zone task pool based on 5 zones
    Aug  8 20:38:19 A20 named[2635]: server.c:2466: unexpected error:
    Aug  8 20:38:19 A20 named[2635]: unable to obtain neither an IPv4 nor an IPv6 dispatch
    Aug  8 20:38:19 A20 named[2635]: loading configuration: unexpected error
    Aug  8 20:38:19 A20 named[2635]: exiting (due to fatal error)

    La solution : « groupadd -g 3003 aid_inet
    usermod -G aid_inet ntp
    usermod -G aid_inet bind
    usermod -G aid_inet mysql

    but this can be done after 1st failed installation attempt.
    Must figure out, can I create those users beforehand?

    Anyway, would it be mossible to remove kernel flag
    CONFIG_ANDROID_PARANOID_NETWORK to solve the issue? »

    Ou, encore plus facile : utiliser la nouvelle image fournie par Olimex depuis mars 2014 et son noyau 3.4 qui n'est plus Android-based.

    Ce paramètre de compilation du noyau affecte d'autres logiciels. Ejabberd :

    Aug  8 20:37:42 A20 epmd: epmd: error opening stream socket
    Aug  8 20:37:43 A20 epmd: epmd: error opening stream socket

    NTPd :

    Aug  8 20:37:41 A20 ntpd[2427]: ./../lib/isc/unix/ifiter_ioctl.c:348: unexpected error:
    Aug  8 20:37:41 A20 ntpd[2427]: making interface scan socket: Permission denied

    Fin de l'édit

Notes :

  • Pas besoin de charger le module ipv6, il est compilé "en dur" dans le noyau, contrairement au RPi.
  • Pour le split de la RAM entre CPU et GPU, je ne sais pas comment cela se passe sur OLinuXino. Je n'ai rien trouvé de convaincant à ce sujet. Pas même dans les fichiers scripts.(bin|fex). Je constate que j'ai 975 Mo de RAM adressables par le système. ÉDIT du 09/08/2014 à 19h15 : La réponse est là : Kernel arguments sur le wiki Linux-sunxi : il faut utiliser les paramètres : « sunxi_ve_mem_reserve=0 sunxi_g2d_mem_reserve=0 sunxi_no_mali_mem_reserve sunxi_fb_mem_reserve=16 ». Ils s'utilisent comme « elevator=noop" que l'on a vu ci-dessus. 😉 Bilan : 986M de RAM adressables par le système. Fin de l'édit

Les problèmes

Un manque de neutralité

Les problèmes liès à mon Fournisseur d'Accès à Internet, qui ne permet pas à ses clients d'installer un serveur et donc d'être vraiment sur Internet, restent évidemment inchangés entre mon RPi et mon OLinuXino. Je vous invite donc à lire la section « Les problèmes » de mon billet sur le RPi pour un usage serveur.

OpenDNSSEC/SoftHSM

SoftHSM ne segfault plus lors de l'initialisation des token mais l'erreur « error parsing RR at line » se manifeste ici aussi.

Un load average toujours supérieur ou égal à 1

Avec l'image Debian (apparemment, cela ne se produit pas avec l'image Android), on constate que la charge système ne cesse de monter dès le boot pour se stabiliser à 1 et ne plus jamais redescendre sous ce seuil quand bien même aucun service n'est lancé ... juste le noyau et les démons de base (log, sshd, ...).

Avec la commande top, on observe que c'est ksoftirqd, processus dédié à la mise en queue des interruptions logicielles (qui sont souvent traitées suite à des interruptions matérielles) lorsqu'il y en a trop, qui est le processus le plus consommateur de CPU. On observe également qu'environ 5 % du temps CPU part dans le traitement d'interruptions logicielles :

%Cpu(s):  0,3 us,  0,9 sy,  0,0 ni, 93,7 id,  0,0 wa,  0,0 hi,  5,1 si,  0,0 st

En regardant dans /proc/interrupts, on constate que deux interruptions se démarquent nettement et que leurs nombres de déclenchements progressent très rapidement (environ 100 par seconde) :

           CPU0       CPU1       
 29:      28685      43852       GIC  arch_timer
 30:          0          0       GIC  arch_timer
 32:          0          0       GIC  axp_mfd
 33:        161          0       GIC  serial
 37:          1          0       GIC  RemoteIR
 39:      14059          0       GIC  sun7i-i2c.0
 40:          0          0       GIC  sun7i-i2c.1
 41:          0          0       GIC  sun7i-i2c.2
 54:       3294          0       GIC  timer0
 56:          0          0       GIC  sunxi-rtc alarm
 59:          0          0       GIC  dma_irq
 64:      33270          0       GIC  sunxi-mmc
 67:          0          0       GIC  sunxi-mmc
 71:          0          0       GIC  ehci_hcd:usb2
 72:          0          0       GIC  ehci_hcd:usb4
 76:     151786          0       GIC  dev_name
 77:          0          0       GIC  dev_name
 79:      75888          0       GIC  dev_name
 80:          0          0       GIC  dev_name
 87:       6823          0       GIC  eth0
 96:          0          0       GIC  ohci_hcd:usb3
 97:          0          0       GIC  ohci_hcd:usb5
IPI0:          0          0  Timer broadcast interrupts
IPI1:      18364      17755  Rescheduling interrupts
IPI2:          0          0  Function call interrupts
IPI3:         23        109  Single function call interrupts
IPI4:          0          0  CPU stop interrupts
IPI5:          0          0  CPU backtrace
Err:          0

Évidemment, les dev' n'ont pas donné un nom représentatif à leurs interruptions, sinon ça serait trop facile.

La solution est détaillée ici : loadavg always >=1.00 on debian sur le forum Olimex. Cette surcharge est générée par port mini-USB (qui peut être utilisé en USB OTG) et par le fait que « The whole USB support is flawed in 3.3. » (et apparemment, le sous-système USB de la version 3.4 provoque d'autres bugs).

Voici comment contourner ce problème (tutoriel issu de la combinaison du lien précédent et de documentation related to script.bin/script.fex sur le forum Olimex) :

Il faut récupérer les sunxi-tools :

git clone https://github.com/linux-sunxi/sunxi-tools

Les compiler (non, pas de ./configure) :

cd sunxi-tools
make

La compilation va échouer pour des problèmes de dépendances. Mais ce n'est pas grave : les outils dont nous avons besoin, bin2fex et fex2bin, ont été compilés avec succès.

On transforme le fichier script.bin qui se trouve sur la première partition de votre carte SD en fichier humainement compréhensible (non, on n'est pas obligé de stocker le fichier script.fex sur la carte SD, je fais ça pour m'y retrouver et pour le conserver) :

./bin2fex /path/to/SD/card/script.bin > /path/to/SD/card/script.fex

On effectue les modifications. Pour rappel, ces modifications sont (le reste de la section « [usbc0] » reste inchangée) :

[usbc0]
usb_port_type = 1
usb_detect_type = 0
usb_host_init_state = 1

On fait une copie de sauvegarde puis on crée le nouveau script.bin :

cp /path/to/SD/card/script.bin ~/script.bin.save
./fex2bin /path/to/SD/card/script.fex > /path/to/SD/card/script.bin

En bootant l'OLinuXino, on se rend compte que le load average n'est plus bloqué à 1 mais qu'il est largement inférieur. Par contre, environ 5 % du temps CPU est encore occupé par les mêmes interruptions logicielles qui se déclenchent toujours à la même fréquence ...

Je ne comprends pas ...

D'une part, en regardant le fichier arch/arm/plat-sunxi/include/plat/irqs.h de linux-sunxi, on se rend compte que eth0 utilise l'interruption numéro 87 :

#define SW_INT_IRQNO_EMAC		(55 + SW_INT_START) // SW_INT_START = 32

Cela correspond donc bien à la réalité. En suivant la même logique, l'IRQ 76 (celle qui pose problème) est attribuée à SW_INT_IRQNO_LCDCTRL0 et l'IRQ 79 est attribuée à SW_INT_IRQNO_DEFEBE0. Pour l'IRQ 79, je ne sais pas aller plus loin. Mais pour l'IRQ 76, je peux dire que je n'ai pas d'écran LCD sur mon OLinuXino et que c'est peut-être ce qui pose problème.

J'ai tenté de désactiver lcd(0|1) dans script.(fex|bin) en passant la valeur de « lcd_used » à 0, en supprimant tout sauf cette ligne (sans les mapping, la carte ne devrait pas savoir exploiter l'éventuel LCD) ainsi que de passer la valeur de « disp_init_enable » à 0, mais rien n'y fait : la charge est toujours >= 1. Par contre, les interruptions 76 et 79 ne se déclenchent plus (« 0 » dans /proc/interrupts).

D'autre part, ce n'est pas les hi (hardware interrupts) qui prennent environ 5 % du temps CPU mais les si (software interrupts). Les interruptions logicielles sont souvent traitées suite à des interruptions matérielle mais sait-on jamais ... Donc le fichier à regarder est /proc/softirqs. Mais je ne vois rien d'anormale ... Les interruptions qui se déclenchent le plus sont TIMER et SCHED ... comme sur mon RPi ou sur mes desktop. Du coup, je ne vois pas comment elles peuvent consommer environ 5 % du temps CPU alors qu'elles consomment 0 % sur mes autres systèmes.

Mes compétences s'arrêtent ici.

ÉDIT du 09/08/2014 à 19h55 : Le problème continu avec la nouvelle image Debian distribuée par Olimex depuis mars 2014, « ULTIMATE A20 Debian 4GB SD-card image release-7 with hardware accelerated video » et son noyau en version 3.4.X. La pseudo-solution exposée ici fonctionne toujours. Fin de l'édit

ÉDIT du 23/01/2016 à 18h00 : Ce problème n'apparaît plus avec le noyau packagé dans Debian (à partir de Jessie). Voir : Installer le noyau packagé par Debian sur une carte OLinuXino (et Raspberry Pi). Fin de l'édit

Reproche

Mon seul reproche à Olimex sera l'utilisation d'un format de fichier propriétaire (rar) ainsi que l'hébergement de certains éléments, comme les images de carte SD, sur Google Docs ... Sérieusement ... Comme je l'ai écrit plus haut, j'ai fait remonter ces griefs au support d'Olimex.

TP réseaux d’opérateur III : VPRN BGP-MPLS

Aujourd'hui, suite et fin des travaux pratiques concernant des technologies utilisées par les opérateurs réseaux. Après BGP et MPLS : L3VPN/VPRN avec MPLS, BGP et les extensions Multiprotocol (MBGP).

Même si ces TPs se placent dans un cadre scolaire (« bouh c'est nul, on ne fait pas comme ça en vrai ! » diront certains), j'ai trouvé ces TPs géniaux justement par leur ouverture et parce qu'ils tendent à mettre en exergue les limites auxquelles certaines méthodes utilisables dans un TP seront confrontées « dans la vraie vie ». Ils sont extrêmement formateurs. C'est ce qui m'amène à les partager avec vous accompagnés de mes pistes de réflexion.

Ceux qui aiment bidouiller autour des réseaux devraient tenter de répondre aux questions avant de regarder mes pistes de réflexion. Vous ne devriez pas être déçus.

Table des matières

Énoncé

Architecture

Votre topologie devra être constitué d’un AS opérateur avec au minimum trois PE séparés par un routeur (P) non PE. L’AS opérateur utilisera OSPF comme routage interne. Définir au moins 2 VPN dont l’un utilisera RIP comme routage interne (notez que pour économiser des ressources, certains sites VPN peuvent être limités à une interface de loopback d’un PE), l'autre utilisera OSPF. La figure suivante synthétise l’architecture minimaliste (pour un des VPN) :

Une architecture VPN minimaliste

Une architecture VPN minimaliste.

VPN sans TE

  1. Q1. Vérifiez la connectivité (ping, traceroute) dans chaque VPN et les tables de routage (des routeurs de l’opérateur et des routeurs des VPN - ou des VRF associées).
  2. Q2. Les préfixes des VPN sont-ils visibles sur le routeur P ?
  3. Q3. Listez tous les labels utilisés et illustrez leurs utilisations (par exemple avec le cheminement d’un ping d’un VPN à travers le réseau opérateur - et la réponse associée). Y a-t-il du Penultimate Hop Popping ?
  4. Q4. Indiquez la signalisation échangée par tous protocoles (LDP, BGP, OSPF, RIP) en fonction de : l’ajout un nouveau PE, l’ajout d’un nouveau VPN sur un PE, et lors de l’ajout un nouveau préfixe dans un site VPN existant.
  5. Q5. Utilisez les deux types de topologie de base (mesh, étoile) et essayez d’en inventer une original. Mettez en évidence les différences.

VPN avec TE

L’objectif de cette seconde partie est de tester l’utilisation de l’ingénierie de trafic pour acheminer les
données des clients VPN.

  1. Q1. Mettre en place les mécanismes d’ingénierie de trafic avec MPLS, construire un tunnel TE avec route explicite qui ne passe pas par le plus court chemin (vérifiez quels paquets prennent ce tunnel). En est-il de même pour les paquets circulant en sens inverse ?
  2. Q2. Même question avec un tunnel qui ne prend pas le plus court chemin du fait de la capacité disponible (vérifiez quels paquets prennent ce tunnel).
  3. Q3. Est-il possible de définir des FEC à une granularité plus fine (src/dst IP, port TCP/UDP ou par VPN, interface, etc) ? Donnez les configurations si possible.
  4. Q4. Peut-on contrôler le type des Labels des PE pour définir la connexion avec le CE (par interface, par VRF, par routes). Définir des routes de QoS intra-VPN si possible.
  5. Q5. Montrez comment le trafic des VPN peut utiliser les tunnels construits par TE (vérifiez quels paquets prennent ce tunnel). Peut-on choisir des tunnels différents suivant le VPN (si oui, comment ?) ?

Cet énoncé est celui de Jean-Jacques Pansiot et Pascal Mérindol de l'université de Strasbourg.

Pour ceux qui préfèrent lire un si gros pavé en PDF : TP réseaux d'opérateur III : VPRN. Et comme à chaque fois, les sources LaTeX sont disponibles ici : sources LaTeX.

Avant de commencer

Adressage

ASN

En ce qui concerne les numéros d'AS que l'on doit utiliser avec BGP, j'ai décidé d'en choisir un parmi la plage d'ASN réservée à l'IANA pour la documentation (64496-64511,65536-65551) : 64501.

IPv4

Concernant l'adressage IP, j'ai décidé de choisir mon préfixe dans la plage réservée à l'IANA pour les tests : 198.18.0.0/15. Pour une plus grande facilité, j'ai décidé d'utiliser le sous-préfixe 198.18.0.0/16.

Pour faciliter l'adressage, j'ai décidé de découper ce préfixe en plusieurs préfixes de longueur /20 :

  1. 198.18.0.0/20 : services. Les loopback de mes routeurs seront dans ce sous-réseau.
  2. 198.18.16.0/20 : VPN A
  3. 198.18.32.0/20 : VPN B
  4. Le milieu est réservé pour un usage futur (expansion des "services", expansion des interconnexions, proposer de nouveaux VPN, ...).
  5. Le dernier /20, 198.18.240.0/20, est dédié aux interconnexions des routeurs internes. Il sera découpé en /31, chaque /31 étant dédié à une interconnexion.

Je ne prévois pas d'avoir plus de 2048 interconnexions internes mais si c'était le cas, je prendrais des préfixes dans le milieu en suivant mais en partant de la fin.

Les interconnexions se font en /31 car les IPv4 sont rares et il faut donc les économiser. Même si nous utilisons un préfixe de documentation/test, nous avons fait ce choix car, d'après nos renseignements, il s'agit d'une BCP donc pourquoi ne pas s'y conformer, même sur une maquette ? De plus, cela amène des avantages (pas de broadcast, ...).

Sur chaque routeur de l'opérateur, j'ai une loopback qui permet, entre autres, de raccrocher des démons (BGP) et de tester MPLS "de bout en bout". Les préfixes de mes loopback de services sont :

  • P - L1 : 198.18.0.1/32
  • PE1 - L1 : 198.18.0.2/32
  • PE2 - L1 : 198.18.0.3/32
  • PE3 - L1 : 198.18.0.4/32
  • PE4 - L1 : 198.18.0.5/32

Malgrè que l'on puisse utiliser le même adressage pour plusieurs VPN (le RD permet de faire la différence), j'ai décidé d'attribuer un préfixe par VPN pour faciliter un éventuel débugage.

Chaque préfixe dédié à un VPN (/20) sera découpé en /22, un pour chaque site. Le dernier /22 sera dédié aux interconnexions entre PE et CE, si besoin.

En pratique, pour le VPN A (198.18.16.0/20), on obtient :

  • 198.18.16.0/22 : site 1 (CE1)
  • 198.18.20.0/22 : site 2 (CE2)
  • 198.18.24.0/22 : site 3 (PE1)
  • 198.18.28.0/22 : interconnexions PE-CE. Détails :
    • 198.18.28.0/31 : PE2 <-> CE1
    • 198.18.28.2/31 : PE3 <-> CE2

Pour le VPN B (198.18.32.0/20), on obtient :

  • 198.18.32.0/22 : site 1 (PE4)
  • 198.18.36.0/22 : site 2 (PE3)
  • 198.18.40.0/22 : site 3 (CE3)
  • 198.18.44.0/22 : interconnexions PE-CE. Détails :
    • 198.18.44.0/31 : PE2 <-> CE3

Note : pour le VPN B, j'ai décidé d'avoir un CE pour que l'utilisation d'OSPF demandée (et des redistributions associées) fasse sens.

Sur chaque CE, j'ai également une loopback qui permet de faire comme si j'avais le réseau de mon client directement connecté :

  • CE1 : 198.18.19.254/22
  • CE2 : 198.18.23.254/22
  • CE3 : 198.18.43.254/22

Note : les sorties des commandes de vérification (show ...) seront allégées/tronquées pour ne garder que l'essentiel afin de ne pas surcharger ce rapport.

Schéma

En figure 1 se trouve le schéma donné dans l'énoncé complété avec mon plan d'adressage et les VPN.

Schéma de ma maquette

Figure 1 - Schéma de ma maquette. D'après l'énoncé.

VPN sans TE

Question 1

La configuration de dynagen pour ce TP est donnée en annexe 1.

La configuration des routeurs se fait assez facilement : il n'y a pas de commandes qui n'ont pas été données lors de la séance de TP. Les configurations intégrales de mes routeurs se trouvent en annexe 2.

D'abord, regardons la table de routage IP de P pour constater que le réseau de l'opérateur est opérationnel :

P#sh ip route
     198.18.240.0/31 is subnetted, 8 subnets
O       198.18.240.4 [110/2] via 198.18.240.13, 04:52:09, FastEthernet4/0
                     [110/2] via 198.18.240.2, 04:52:09, FastEthernet1/0
C       198.18.240.6 is directly connected, FastEthernet2/0
O       198.18.240.0 [110/2] via 198.18.240.6, 04:52:09, FastEthernet2/0
                     [110/2] via 198.18.240.2, 04:52:09, FastEthernet1/0
C       198.18.240.2 is directly connected, FastEthernet1/0
C       198.18.240.12 is directly connected, FastEthernet4/0
O       198.18.240.14 [110/2] via 198.18.240.13, 04:52:09, FastEthernet4/0
                      [110/2] via 198.18.240.11, 04:52:09, FastEthernet3/0
O       198.18.240.8 [110/2] via 198.18.240.11, 04:52:09, FastEthernet3/0
                     [110/2] via 198.18.240.6, 04:52:09, FastEthernet2/0
C       198.18.240.10 is directly connected, FastEthernet3/0
     198.18.0.0/32 is subnetted, 5 subnets
O       198.18.0.4 [110/2] via 198.18.240.13, 04:52:12, FastEthernet4/0
O       198.18.0.5 [110/2] via 198.18.240.6, 04:52:12, FastEthernet2/0
C       198.18.0.1 is directly connected, Loopback1
O       198.18.0.2 [110/2] via 198.18.240.2, 04:52:12, FastEthernet1/0
O       198.18.0.3 [110/2] via 198.18.240.11, 04:52:12, FastEthernet3/0

Ensuite, regardons les VRF de chaque PE pour vérifier que les VPN sont bien opérationnels :

PE1#sh ip route vrf vpna                                   
     198.18.28.0/31 is subnetted, 2 subnets
B       198.18.28.0 [200/0] via 198.18.0.3, 04:09:26
B       198.18.28.2 [200/0] via 198.18.0.4, 04:09:26
C    198.18.24.0/22 is directly connected, Loopback2
B    198.18.16.0/22 [200/1] via 198.18.0.3, 04:09:26
B    198.18.20.0/22 [200/1] via 198.18.0.4, 04:09:26
 
PE2#sh ip route vrf vpna
     198.18.28.0/31 is subnetted, 2 subnets
C       198.18.28.0 is directly connected, FastEthernet4/0
B       198.18.28.2 [200/0] via 198.18.0.4, 04:12:53
B    198.18.24.0/22 [200/0] via 198.18.0.2, 04:12:53
R    198.18.16.0/22 [120/1] via 198.18.28.1, 00:00:07, FastEthernet4/0
B    198.18.20.0/22 [200/1] via 198.18.0.4, 04:12:53
 
PE2#sh ip route vrf vpnb
     198.18.43.0/32 is subnetted, 1 subnets
O       198.18.43.254 [110/2] via 198.18.44.1, 04:13:59, FastEthernet5/0
     198.18.44.0/31 is subnetted, 1 subnets
C       198.18.44.0 is directly connected, FastEthernet5/0
B    198.18.32.0/22 [200/0] via 198.18.0.5, 04:12:58
B    198.18.36.0/22 [200/0] via 198.18.0.4, 04:12:58
 
PE3#sh ip route vrf vpna
     198.18.28.0/31 is subnetted, 2 subnets
B       198.18.28.0 [200/0] via 198.18.0.3, 04:13:58
C       198.18.28.2 is directly connected, FastEthernet4/0
B    198.18.24.0/22 [200/0] via 198.18.0.2, 04:13:58
B    198.18.16.0/22 [200/1] via 198.18.0.3, 04:13:58
R    198.18.20.0/22 [120/1] via 198.18.28.3, 00:00:02, FastEthernet4/0
 
PE3#sh ip route vrf vpnb
     198.18.43.0/32 is subnetted, 1 subnets
B       198.18.43.254 [200/2] via 198.18.0.3, 04:13:59
     198.18.44.0/31 is subnetted, 1 subnets
B       198.18.44.0 [200/0] via 198.18.0.3, 04:13:59
B    198.18.32.0/22 [200/0] via 198.18.0.5, 04:13:59
C    198.18.36.0/22 is directly connected, Loopback2
 
PE4#sh ip route vrf vpnb
     198.18.43.0/32 is subnetted, 1 subnets
B       198.18.43.254 [200/2] via 198.18.0.3, 04:14:48
     198.18.44.0/31 is subnetted, 1 subnets
B       198.18.44.0 [200/0] via 198.18.0.3, 04:14:48
C    198.18.32.0/22 is directly connected, Loopback2
B    198.18.36.0/22 [200/0] via 198.18.0.4, 04:14:48

Enfin, regardons la table de routage IP de nos CE pour vérifier que les redistributions internes à nos VPN sont opérationnelles :

CE1#sh ip route                            
     198.18.28.0/31 is subnetted, 2 subnets
C       198.18.28.0 is directly connected, FastEthernet1/0
R       198.18.28.2 [120/1] via 198.18.28.0, 00:00:24, FastEthernet1/0
R    198.18.24.0/22 [120/1] via 198.18.28.0, 00:00:24, FastEthernet1/0
C    198.18.16.0/22 is directly connected, Loopback1
R    198.18.20.0/22 [120/1] via 198.18.28.0, 00:00:24, FastEthernet1/0

 
CE2#sh ip route
     198.18.28.0/31 is subnetted, 2 subnets
R       198.18.28.0 [120/1] via 198.18.28.2, 00:00:18, FastEthernet1/0
C       198.18.28.2 is directly connected, FastEthernet1/0
R    198.18.24.0/22 [120/1] via 198.18.28.2, 00:00:18, FastEthernet1/0
R    198.18.16.0/22 [120/1] via 198.18.28.2, 00:00:18, FastEthernet1/0
C    198.18.20.0/22 is directly connected, Loopback1
 
CE3#sh ip route
     198.18.44.0/31 is subnetted, 1 subnets
C       198.18.44.0 is directly connected, FastEthernet1/0
C    198.18.40.0/22 is directly connected, Loopback1
O IA 198.18.32.0/22 [110/2] via 198.18.44.0, 04:19:58, FastEthernet1/0
O IA 198.18.36.0/22 [110/2] via 198.18.44.0, 04:19:58, FastEthernet1/0

Pour conclure, faisons quelques tests de connectivité à l'intérieur de chacun de nos VPN.

On effectue un traceroute à destination du site 1 du VPN A (CE1) depuis le site 3 du VPN A (L2 de PE1). On effectue ensuite un ping à destination du site 2 du VPN A (CE2) depuis le site 3 du VPN A (L2 de PE1) :

PE1#traceroute vrf vpna 198.18.19.254 source 198.18.27.254
  1 198.18.240.5 [MPLS: Labels 23/25 Exp 0] 12 msec
    198.18.240.3 [MPLS: Labels 22/25 Exp 0] 12 msec
    198.18.240.1 [MPLS: Labels 23/25 Exp 0] 12 msec
  2 198.18.28.0 [MPLS: Label 25 Exp 0] 12 msec 12 msec 12 msec
  3 198.18.28.1 20 msec *  24 msec
 
PE1#ping  vrf vpna 198.18.23.254 source 198.18.27.254
!!!!!
Success rate is 100 percent (5/5), round-trip min/avg/max = 12/12/16 ms

Notre VPN A est totalement fonctionnel.

On effectue un ping à destination du site 1 du VPN B (L2 de PE4) depuis le site 3 du VPN B (CE3). On effectue ensuite un traceroute à destination du site 2 du VPN B (L2 de PE3) depuis le site 3 du VPN B (CE3) :

CE3#ping 198.18.35.254 source 198.18.43.254
!!!!!
Success rate is 100 percent (5/5), round-trip min/avg/max = 4/8/12 ms
 
CE3#traceroute 198.18.39.254 source 198.18.43.254
  1 198.18.44.0 8 msec 8 msec 32 msec
  2 198.18.39.254 8 msec *  32 msec

Notre VPN B est totalement fonctionnel.

Question 2

Le routeur P effectue la commutation uniquement en se basant sur les labels MPLS de sommet de la pile. Il n'a pas conscience de l'empilement des labels MPLS. Il n'a donc pas connaisance des préfixes IP attribués aux différents VPN dans sa table de routage IP ni dans sa table de commutation MPLS.

Notons néanmoins que P reçoit l'intégralité des paquets qu'il doit commuter. Une capture du trafic réseau mettrait donc en évidence les préfixes IPs des VPN dans les couches supérieures.

Pour la vérification, voir la sortie de la commande show ip route donnée dans la réponse à la question 1.

Question 3

Pour illustrer mon raisonnement, j'ai décidé de faire un ping/traceroute à destination du site 1 du VPN A (CE1) depuis le site 3 de ce même VPN (L2 de PE1).

Pour commencer, regardons les tables de commutation pour en déduire le comportement :

PE1#show mpls forwarding-table 
Local  Outgoing    Prefix            Bytes tag  Outgoing   Next Hop    
tag    tag or VC   or Tunnel Id      switched   interface              
17     Pop tag     198.18.0.1/32     0          Fa2/0      198.18.240.3 
18     Pop tag     198.18.0.5/32     0          Fa1/0      198.18.240.1 
23     23          198.18.0.3/32     0          Fa3/0      198.18.240.5 
       22          198.18.0.3/32     0          Fa2/0      198.18.240.3 
       23          198.18.0.3/32     0          Fa1/0      198.18.240.1 
24     Pop tag     198.18.0.4/32     37495      Fa3/0      198.18.240.5            
 
PE1#show ip bgp vpnv4 all labels                           
   Network          Next Hop      In label/Out label
Route Distinguisher: 64501:1 (vpna)
   198.18.16.0/22   198.18.0.3      nolabel/25
   198.18.20.0/22   198.18.0.4      nolabel/25
   198.18.24.0/22   0.0.0.0         25/aggregate(vpna)
PE2#sh mpls forwarding-table         
Local  Outgoing    Prefix            Bytes tag  Outgoing   Next Hop    
tag    tag or VC   or Tunnel Id      switched   interface              
20     Pop tag     198.18.0.1/32     0          Fa2/0      198.18.240.10 
21     22          198.18.0.2/32     0          Fa3/0      198.18.240.14 
       16          198.18.0.2/32     0          Fa2/0      198.18.240.10 
       20          198.18.0.2/32     0          Fa1/0      198.18.240.8 
22     Pop tag     198.18.0.5/32     28695      Fa1/0      198.18.240.8 
24     Pop tag     198.18.0.4/32     56         Fa3/0      198.18.240.14 
 
PE2#sh ip bgp vpnv4 all labels       
   Network          Next Hop      In label/Out label
Route Distinguisher: 64501:1 (vpna)
   198.18.16.0/22   198.18.28.1     25/nolabel
   198.18.20.0/22   198.18.0.4      nolabel/25
   198.18.24.0/22   198.18.0.2      nolabel/25

Vu les tables ci-dessus, on devrait obtenir :

Aller : PE1 [22 ou 23,25] -> PE4, P ou PE3 [25] -> PE2 [plus de MPLS ici] -> CE1

Retour : CE1 [pas de MPLS ici] -> PE2 [22 ou 16 ou 20,25] -> PE4, P ou PE3 [25] -> PE1

Le fonctionnement de MPLS ne change pas. En conséquence, il y aura du Penultimate Hop Popping entre les PE. Seul le label qui identifie un VPN/une VRF/une route restera d'un bout à l'autre (du PE source au PE destination).

Vérification :

PE1#traceroute vrf vpna 198.18.19.254 source 198.18.27.254
  1 198.18.240.5 [MPLS: Labels 23/25 Exp 0] 16 msec
    198.18.240.3 [MPLS: Labels 22/25 Exp 0] 12 msec
    198.18.240.1 [MPLS: Labels 23/25 Exp 0] 16 msec
  2 198.18.28.0 [MPLS: Label 25 Exp 0] 12 msec 12 msec 12 msec
  3 198.18.28.1 12 msec *  24 msec

Vérification, sur PE1, avec un ping vrf vpna 198.18.19.254 source 198.18.27.254 :

En sortie de PE1, pour l'echo request, nous avons bien deux labels : le premier, 23, pour la commutation dans le réseau de l'opérateur, le deuxième, 25, pour identifier le VPN

Figure 2 - En sortie de PE1, pour l'echo request, nous avons bien deux labels : le premier, 23, pour la commutation dans le réseau de l'opérateur, le deuxième, 25, pour identifier le VPN.

En entrée de PE2, pour l'echo request, nous n'avons plus qu'un seul label : celui de fond de pile, 25, qui permet d'idenfitier le VPN. Le label de sommet de pile a été poper par PE3

Figure 3 - En entrée de PE2, pour l'echo request, nous n'avons plus qu'un seul label : celui de fond de pile, 25, qui permet d'idenfitier le VPN. Le label de sommet de pile a été poper par PE3.

En sortie de PE2, pour l'echo reply, nous avons deux labels : le premier, 16, pour la commutation dans le réseau de l'opérateur, le deuxième, 25, pour identifier le VPN

Figure 4 - En sortie de PE2, pour l'echo reply, nous avons deux labels : le premier, 16, pour la commutation dans le réseau de l'opérateur, le deuxième, 25, pour identifier le VPN.

En entrée de PE1, pour l'echo reply, nous n'avons plus que le label de fond de pile, 25, qui permet d'identifier le VPN. Le label de sommet de pile a été poper par P

Figure 5 - En entrée de PE1, pour l'echo reply, nous n'avons plus que le label de fond de pile, 25, qui permet d'identifier le VPN. Le label de sommet de pile a été poper par P.

Question 4

Ajout d'un PE

En théorie, lors de l'ajout d'un PE (sans VPN, sans liaisons iBGP, rien), les PE voisins (directement connectés), vont annoncer les nouveaux préfixes d'interconnexion au reste du réseau de l'opérateur. Puis, lorsque son initialisation sera complète, le nouveau PE s'annoncera lui-même, via OSPF, à ses voisins, qui relayeront cette annonce. Puis, de nouveaux labels seront assignés et distribués via LDP.

Si l'on configure aussi les sessions iBGP avec les autres PE sans qu'il n'y ait aucun site sur ce PE, alors on aura aussi des messages iBGP : ouverture des sessions et keepalive.

Vérification : j'introduis PE4 dans ma maquette.

PE1 annonce (à P dans notre cas), le nouveau préfixe d'interconnexion 198.18.240.0 entre lui et PE4

Figure 6 - PE1 annonce (à P dans notre cas), le nouveau préfixe d'interconnexion 198.18.240.0 entre lui et PE4.

À la fin de son initialisation, PE4 ouvre des sessions OSPF avec ses voisins (PE1 dans notre cas)

Figure 7 - À la fin de son initialisation, PE4 ouvre des sessions OSPF avec ses voisins (PE1 dans notre cas).

Les voisins de PE4 (PE1 dans notre cas) relayent les annonces de PE4 et marquent le préfixe d'interconnexion PE1<->PE4 comme un lien de transit vers d'autres préfixes

Figure 8 - Les voisins de PE4 (PE1 dans notre cas) relayent les annonces de PE4 et marquent le préfixe d'interconnexion PE1<->PE4 comme un lien de transit vers d'autres préfixes.

PE4 et ses voisins initient des sessions LDP. Ici on voit PE4->PE1, P->PE4, PE4->PE3

Figure 9 - PE4 et ses voisins initient des sessions LDP. Ici on voit PE4->PE1, P->PE4, PE4->PE3.

La loopback de PE4 (et les préfixes d'interconnexion) se voit attribuer un label. Ici, on voit les échanges entre P<->PE4 et P<->PE1

Figure 10 - La loopback de PE4 (et les préfixes d'interconnexion) se voit attribuer un label. Ici, on voit les échanges entre P<->PE4 et P<->PE1.

Ajout d'un nouveau VPN sur un PE

En théorie, lors de l'ajout d'un nouveau VPN sur un PE, on va créer la VRF, mettre en place le routage interne à ce site VPN et annoncer ce site via BGP (avec les extensions Multiprotocol). On aura donc la signalisation du routage interne (OSPF ou RIP dans notre cas) puis BGP entre les PE puis à nouveau le routage interne sur l'autre site (redistribution depuis BGP). Évidemment, si les autres sites ne sont pas configurés, les tentatives BGP échoueront. Évidemment, il n'y a pas d'échanges LDP, le label associé au VPN étant échangé via BGP.

Vérification : j'ajoute le VPN B sur PE2 qui, pour l'instant, est configuré uniquement pour le VPN A.

Le routage propre au VPN (ici, OSPF) se met en marche entre PE2 et CE3. PE2 va désormais avoir le nouveau site VPN B (L2 de CE3) et les préfixes d'interconnexions dans ses tables

Figure 11 - Le routage propre au VPN (ici, OSPF) se met en marche entre PE2 et CE3. PE2 va désormais avoir le nouveau site VPN B (L2 de CE3) et les préfixes d'interconnexions dans ses tables.

PE2 annonce le nouveau site VPN B (L2 de CE3) aux autres sites du VPN B (PE3 dans cette illustration) et apprend les préfixes des autres sites du VPN B

Figure 12 - PE2 annonce le nouveau site VPN B (L2 de CE3) aux autres sites du VPN B (PE3 dans cette illustration) et apprend les préfixes des autres sites du VPN B.

PE2 propage, à l'intérieur du site, les autres préfixes des sites distants du VPN B. Ici : le site 2 appris via PE3

Figure 13 - PE2 propage, à l'intérieur du site, les autres préfixes des sites distants du VPN B. Ici : le site 2 appris via PE3.

Ajout d'un nouveau préfixe dans un site existant

En théorie, lors de l'ajout d'un nouveau préfixe dans un site existant, le routage interne à ce site VPN (OSPF ou RIP dans notre cas) va propager le nouveau préfixe. Puis le PE, via BGP (et les extensions Multiprotocol), va propager ce nouveau préfixe entre les sites. Sur les autres sites, le préfixe sera propagé via le protocole de routage interne propre à ce site (OSPF/RIP). Évidemment, il n'y a pas d'échanges LDP, le label associé au préfixe du VPN étant échangé via BGP.

Vérification : on crée une nouvelle loopback sur CE3, L3 : 198.18.43.253/22

CE3 annonce, via OSPF, sa nouvelle loopback

Figure 14 - CE3 annonce, via OSPF, sa nouvelle loopback.

PE2 annonce, via iBGP, le nouveau préfixe existant sur le site VPN aux autres sites du VPN (ici : PE3)

Figure 15 - PE2 annonce, via iBGP, le nouveau préfixe existant sur le site VPN aux autres sites du VPN (ici : PE3).

Question 5

Note : entre chaque topologie, je reviens à la configuration initiale de ma maquette telle que présentée à la question 1.

Mesh

Avec cette topologie, chaque site peut communiquer directement avec tous les autres sites d'un même VPN. Illustration :

Principaux avantages/inconvénients :

  • + Toujours le chemin le plus court entre deux PE (donc entre deux sites)
  • + Redondance "par design"

La topologie actuelle de ma maquette est du full-mesh : pour un même VPN, chaque site (chaque PE) est relié directement à chaque autre site (à chaque autre PE). Pour chaque site, on utilise la même valeur de route-target en import et en export.

Hub

Avec cette topologie, chaque site peut communiquer directement uniquement avec le site central (le hub) d'un même VPN mais il ne peut pas communiquer directement (= sans passer par le hub) avec les autres sites d'un même VPN. Illustration :

Cette topologie peut se présenter sous deux sous-types distincts : soit on isole les sites "spoke", soit on leur permet de communiquer à la condition que les communications entre "spoke" passent par le hub.

Pour comprendre l'intérêt du premier sous-type, prenons un exemple (repris de http://www.brimbelle.org/mattieu/projects/bgpmpls/etat-art.htm et complété) : une société commerciale a son siège, son entrepôt, son usine, ses magasins, ... répartis partout en France. Depuis le siège social, où se trouve la direction informatique, on souhaite pouvoir se connecter à tous les sites (usine, entrepôts, chaque magasin, ...) pour recueillir des informations (monitoring) ou pour dépanner les utilisateurs. Chaque site doit donc pouvoir communiquer avec le siège mais pas avec les autres sites.

L'intérêt du deuxième sous-type est de permettre, plus que le premier sous-type, la centralisation des politiques (de communication entre sites, de sécurité, ...).

Principaux avantages/inconvénients :

  • + Centralisation des politiques
  • + Passage à l'échelle (full-mesh : explosion du nombre de liens entre PE)
  • - Pas toujours le plus court chemin entre deux PE

Pour obtenir cette topologie, il faut manipuler les route-target. Il nous faut deux communautés bien distinctes : 64501:1 et 64501:3. Le hub importe selon la communauté 64501:1 et exporte la communauté 64501:3. Les sites spoke importent selon la communauté 64501:3 et exportent selon la communauté 64501:1. Ainsi, deux sites spoke ne peuvent communiquer entre eux : ils vont refuser l'annonce de l'autre car ce n'est pas la bonne communauté (celle présentée : 64501:1, attendue : 64501:3). Seules les annonces du hub seront acceptées par les sites spoke.

Pour mettre cela en pratique, j'ai décidé que PE2 sera le hub du VPN A et qu'il n'y aura aucune communication entre les sites spoke.

Il faut donc adapter la configuration actuelle. Sur PE2 :

ip vrf vpna
  no route-target export 64501:1
  route-target export 64501:3

Sur PE1 et PE3 :

ip vrf vpna
  no route-target import 64501:1
  route-target import 64501:3

On obtient le comportement désiré, le hub possède tous les préfixes des sites du VPN A dans sa table :

PE2#sh ip route vrf vpna
     198.18.28.0/31 is subnetted, 2 subnets
C       198.18.28.0 is directly connected, FastEthernet4/0
B       198.18.28.2 [200/0] via 198.18.0.4, 00:00:13
B    198.18.24.0/22 [200/0] via 198.18.0.2, 00:00:28
R    198.18.16.0/22 [120/1] via 198.18.28.1, 00:00:10, FastEthernet4/0
B    198.18.20.0/22 [200/1] via 198.18.0.4, 00:00:13

Les sites spoke possèdent uniquement les préfixes du site 1 (PE2-CE1, hub) et ceux de leur propre site :

PE1#sh ip route vrf vpna
     198.18.28.0/31 is subnetted, 1 subnets
B       198.18.28.0 [200/0] via 198.18.0.3, 00:02:00
C    198.18.24.0/22 is directly connected, Loopback2
B    198.18.16.0/22 [200/1] via 198.18.0.3, 00:02:00
 
PE3#sh ip route vrf vpna
     198.18.28.0/31 is subnetted, 2 subnets
B       198.18.28.0 [200/0] via 198.18.0.3, 00:01:20
C       198.18.28.2 is directly connected, FastEthernet4/0
B    198.18.16.0/22 [200/1] via 198.18.0.3, 00:01:20
R    198.18.20.0/22 [120/1] via 198.18.28.3, 00:00:23, FastEthernet4/0

Le site 1 (hub) peut être joint depuis n'importe quel autre site (spoke) :

PE1#ping vrf vpna 198.18.19.254 source 198.18.27.254
!!!!!
Success rate is 100 percent (5/5), round-trip min/avg/max = 16/18/20 ms
 
CE2#ping 198.18.19.254 source 198.18.23.254
!!!!!
Success rate is 100 percent (5/5), round-trip min/avg/max = 4/12/16 ms

Mais la communication entre les deux sites spoke est interdite :

PE1#ping vrf vpna 198.18.23.254 source 198.18.27.254
.....
Success rate is 0 percent (0/5)
 
CE2#ping 198.18.27.254 source 198.18.23.254
.....
Success rate is 0 percent (0/5)

Pour que nos spokes puissent communiquer entre eux (en passant par le hub), il faudrait rajouter un PE et un CE qui seraient les deux composantes de notre hub. Selon la documentation de Cisco, la plupart du temps, on utilise (e|i)BGP entre le CE hub et le PE hub. La configuration semble se résumer à une configuration BGP puis à la création de VRF supplémentaires (une pour recevoir les préfixes des spoke, l'autre les préfixes du hub (ceux des spoke redistribués en réalité)). Je n'ai pas effectué cette configuration car c'est répétitif vis-à-vis des questions précédentes.

Configuration originale

Il existe un grand nombre de topologies (multi-VPN, multilevel Hub-and-spoke, managed network, extranet, ...) ainsi que des déclinaisons (mesh partiel, hub-and-spoke redondé, ...) ainsi que des combinaisons (hub-and-spoke + full-mesh, ...). Il est donc difficile de choisir quelle topologie choisir et illustrer.

J'ai d'abord éliminé les topologies complexes (combinaisons) et les topologies nécessitant plus de machines pour montrer l'intérêt. Parmi les topologies restantes, j'ai choisi l'overlapping VPN, site commun à plusieurs VPN simplement parce qu'il répondait à la question que je me posais : comment offrir un même service à tous les sites de tous (ou partie) des VPN ?

Avec cette topologie, on peut offrir un ou plusieurs services centralisés (connectivité vers Internet, résolveur DNS, station de monitoring, ...) à tous les sites de plusieurs VPN. Illustration :

Pour obtenir cette topologie, il faut manipuler les route-target. Le site commun doit importer et exporter les deux communautés : celle du VPN A et celle du VPN B.

Pour mettre cela en pratique, j'ai décidé que PE2 sera le PE commun. On créera une nouvelle loopback depuis laquelle on annoncera le préfixe qui devra être commun (198.18.48.0/22). On ne déploie pas de protocole de routage dynamique (RIP, OSPF) sur ce nouveau site car c'est répétitif vis-à-vis des questions précédentes.

Voici le bout de configuration à ajouter sur PE2 :

ip vrf vpnab 
 rd 64501:12
 route-target export 64501:1
 route-target export 64501:2
 route-target import 64501:1
 route-target import 64501:2
 

interface Loopback2
 ip vrf forwarding vpnab
 ip address 198.18.48.1 255.255.252.0
 
router bgp 64501
 address-family ipv4 vrf vpnab
  redistribute connected
 exit-address-family

On obtient le comportement désiré : notre site commun reçoit tous les préfixes de tous les autres sites, qu'il fasse partie du VPN A ou B.

PE2#sh ip route vrf vpnab
     198.18.43.0/32 is subnetted, 1 subnets
B       198.18.43.254 [20/2] via 198.18.44.1 (vpnb), 00:00:10, FastEthernet5/0
     198.18.44.0/31 is subnetted, 1 subnets
B       198.18.44.0 is directly connected, 00:00:10, FastEthernet5/0
     198.18.28.0/31 is subnetted, 2 subnets
B       198.18.28.0 is directly connected, 00:00:10, FastEthernet4/0
B       198.18.28.2 [200/0] via 198.18.0.4, 00:00:10
B    198.18.24.0/22 [200/0] via 198.18.0.2, 00:00:10
B    198.18.32.0/22 [200/0] via 198.18.0.5, 00:00:10
C    198.18.48.0/22 is directly connected, Loopback2
B    198.18.16.0/22 [20/1] via 198.18.28.1 (vpna), 00:00:10, FastEthernet4/0
B    198.18.36.0/22 [200/0] via 198.18.0.4, 00:00:11
B    198.18.20.0/22 [200/1] via 198.18.0.4, 00:00:11

Le préfixe du site commun est propagé dans tous les sites, VPN A ou B :

PE1#sh ip route vrf vpna
     198.18.28.0/31 is subnetted, 2 subnets
B       198.18.28.0 [200/0] via 198.18.0.3, 00:05:55
B       198.18.28.2 [200/0] via 198.18.0.4, 00:05:55
C    198.18.24.0/22 is directly connected, Loopback2
B    198.18.48.0/22 [200/0] via 198.18.0.3, 00:05:55
B    198.18.16.0/22 [200/1] via 198.18.0.3, 00:05:55
B    198.18.20.0/22 [200/1] via 198.18.0.4, 00:05:55
 
PE3#sh ip route vrf vpna
     198.18.28.0/31 is subnetted, 2 subnets
B       198.18.28.0 [200/0] via 198.18.0.3, 00:03:57
C       198.18.28.2 is directly connected, FastEthernet4/0
B    198.18.24.0/22 [200/0] via 198.18.0.2, 00:03:57
B    198.18.48.0/22 [200/0] via 198.18.0.3, 00:03:57
B    198.18.16.0/22 [200/1] via 198.18.0.3, 00:03:57
R    198.18.20.0/22 [120/1] via 198.18.28.3, 00:00:22, FastEthernet4/0

 
PE3#sh ip route vrf vpnb
     198.18.43.0/32 is subnetted, 1 subnets
B       198.18.43.254 [200/2] via 198.18.0.3, 00:04:03
     198.18.44.0/31 is subnetted, 1 subnets
B       198.18.44.0 [200/0] via 198.18.0.3, 00:04:03
B    198.18.32.0/22 [200/0] via 198.18.0.5, 00:04:03
B    198.18.48.0/22 [200/0] via 198.18.0.3, 00:04:03
C    198.18.36.0/22 is directly connected, Loopback2
 
PE4#sh ip route vrf vpnb
     198.18.43.0/32 is subnetted, 1 subnets
B       198.18.43.254 [200/2] via 198.18.0.3, 00:05:13
     198.18.44.0/31 is subnetted, 1 subnets
B       198.18.44.0 [200/0] via 198.18.0.3, 00:05:13
C    198.18.32.0/22 is directly connected, Loopback2
B    198.18.48.0/22 [200/0] via 198.18.0.3, 00:05:13
B    198.18.36.0/22 [200/0] via 198.18.0.4, 00:05:13

Chaque site, qu'il soit du VPN A ou B, peut joindre le préfixe commun :

CE1#ping 198.18.48.1 source 198.18.19.254
!!!!!
Success rate is 100 percent (5/5), round-trip min/avg/max = 4/12/36 ms
 
PE1#ping vrf vpna 198.18.48.1 source 198.18.27.254 
!!!!!
Success rate is 100 percent (5/5), round-trip min/avg/max = 8/10/12 ms
 
CE3#ping 198.18.48.1 source 198.18.43.254
!!!!!
Success rate is 100 percent (5/5), round-trip min/avg/max = 4/12/32 ms
 
PE4#ping vrf vpnb 198.18.48.1 source 198.18.35.254
!!!!!
Success rate is 100 percent (5/5), round-trip min/avg/max = 4/5/8 ms

VPN avec TE

Question 1

Les commandes supplémentaires (activation d'OSPF-TE, MPLS-TE, ...) pour répondre à cette question se trouvent en annexe. Nous ne configurerons pas la capacité réservable sur chaque lien pour l'instant. Comme nous l'avons vu lors du précédent TP, OSPF-TE annoncera donc des capacités réservables nulles.

Nous allons construire un tunnel explicite PE2 -> PE3. Voici les commandes à utiliser, sur PE2 :

interface Tunnel1
ip unnumbered Loopback1
tunnel destination 198.18.0.4
tunnel mode mpls traffic-eng
tunnel mpls traffic-eng priority 1 1
tunnel mpls traffic-eng autoroute announce 
 
ip explicit-path name explicitlongtunnel enable
next-address 198.18.240.8
next-address 198.18.240.0
next-address 198.18.240.5
exit
 
interface Tunnel1
tunnel mpls traffic-eng path-option 1 explicit name explicitlongtunnel
no sh

On constate que le tunnel est bien construit et suit le chemin que nous voulons :

sh mpls traffic-eng tunnels Tunnel1
 
Name: PE2_t1                              (Tunnel1) Destination: 198.18.0.4
  Status:
    Admin: up         Oper: up     Path: valid       Signalling: connected
 
    path option 1, type explicit explicitlongtunnel (Basis for Setup, path weight 3)
[...]
  InLabel  :  - 
  OutLabel : FastEthernet1/0, 26
  RSVP Signalling Info:
       Src 198.18.0.3, Dst 198.18.0.4, Tun_Id 1, Tun_Instance 1
    RSVP Path Info:
      My Address: 198.18.240.9   
      Explicit Route: 198.18.240.8 198.18.240.1 198.18.240.0 198.18.240.4 
                      198.18.240.5 198.18.0.4 
      Record Route:  NONE
[...]
  Shortest Unconstrained Path Info:
    Path Weight: 1 (TE)
    Explicit Route: 198.18.240.15 198.18.240.14 198.18.0.4 
  History:
    Tunnel:
      Time since created: 13 seconds
      Time since path change: 14 seconds
    Current LSP:
      Uptime: 14 seconds
 
PE2#traceroute 198.18.0.4              
  1 198.18.240.8 [MPLS: Label 26 Exp 0] 16 msec 12 msec 12 msec
  2 198.18.240.0 [MPLS: Label 26 Exp 0] 12 msec 12 msec 12 msec
  3 198.18.240.5 16 msec *  12 msec

On constate que tout le trafic qu'il est plus avantageux de faire passer par le tunnel passera par le tunnel. Pour les préfixes où le tunnel n'est pas plus avantageux, il est choisi comme chemin de secours :

PE2#sh ip route
     198.18.240.0/31 is subnetted, 8 subnets
O       198.18.240.4 [110/2] via 0.0.0.0, 00:11:45, Tunnel1
O       198.18.240.6 [110/2] via 198.18.240.10, 00:11:45, FastEthernet2/0
                     [110/2] via 198.18.240.8, 00:11:45, FastEthernet1/0
O       198.18.240.0 [110/2] via 198.18.240.8, 00:11:45, FastEthernet1/0
O       198.18.240.2 [110/2] via 198.18.240.10, 00:11:45, FastEthernet2/0
O       198.18.240.12 [110/2] via 198.18.240.10, 00:11:45, FastEthernet2/0
                      [110/2] via 0.0.0.0, 00:11:45, Tunnel1
C       198.18.240.14 is directly connected, FastEthernet3/0
C       198.18.240.8 is directly connected, FastEthernet1/0
C       198.18.240.10 is directly connected, FastEthernet2/0
     198.18.0.0/32 is subnetted, 5 subnets
O       198.18.0.4 [110/2] via 0.0.0.0, 00:11:45, Tunnel1
O       198.18.0.5 [110/2] via 198.18.240.8, 00:11:46, FastEthernet1/0
O       198.18.0.1 [110/2] via 198.18.240.10, 00:11:47, FastEthernet2/0
O       198.18.0.2 [110/3] via 198.18.240.10, 00:11:47, FastEthernet2/0
                   [110/3] via 198.18.240.8, 00:11:47, FastEthernet1/0
                   [110/3] via 0.0.0.0, 00:11:47, Tunnel1
C       198.18.0.3 is directly connected, Loopback1

Cela vaut aussi pour le trafic de nos VPN. Regardons la VRF associée au VPN A sur PE2 :

PE2#sh ip route vrf vpna
     198.18.28.0/31 is subnetted, 2 subnets
C       198.18.28.0 is directly connected, FastEthernet4/0
B       198.18.28.2 [200/0] via 198.18.0.4, 00:09:51
B    198.18.24.0/22 [200/0] via 198.18.0.2, 1d08h
R    198.18.16.0/22 [120/1] via 198.18.28.1, 00:00:09, FastEthernet4/0
B    198.18.20.0/22 [200/1] via 198.18.0.4, 00:09:51

Pour joindre 198.18.20.0/22, BGP nous a informés qu'il faut envoyer le trafic à 198.18.0.4. Qui est 198.18.0.4 ? Rien dans notre VRF. Regardons dans la table de routage IP globale :

PE2#sh ip route
O       198.18.0.4 [110/2] via 0.0.0.0, 00:11:45, Tunnel1

Donc pour joindre 198.18.0.4 qui nous permet de joindre un site distant du VPN A, il faut passer par Tunnel1. Vérifions :

PE2#traceroute vrf vpna 198.18.23.254
  1 198.18.240.8 [MPLS: Labels 26/25 Exp 0] 16 msec 16 msec 16 msec
  2 198.18.240.0 [MPLS: Labels 26/25 Exp 0] 12 msec 12 msec 16 msec
  3 198.18.28.2 [MPLS: Label 25 Exp 0] 12 msec 12 msec 12 msec
  4 198.18.28.3 16 msec *  20 msec

Néanmoins, la documentation de Cisco nous informe que les tunnels sont unidirectionnels. PE3 n'empruntera donc pas ce tunnel pour répondre à PE2. Cela se confirme en lisant la table de routage de PE3 :

PE3#sh ip route
(...]
O       198.18.0.3 [110/2] via 198.18.240.15, 03:08:08, FastEthernet3/0

Question 2

Pour répondre à cette question, nous supprimons le tunnel de la question précédente. Nous allons recréer ce tunnel PE2 -> PE3 mais cette fois-ci, non plus avec une exigence sur le chemin exact à suivre mais avec une exigence de capacité disponible : nous voulons une capacité disponible de 50 megas.

Comme nous avons déjà vu ce type de configuration lors du TP précédent et pour me simplifier la tâche, j'ai décidé que seul le chemin PE2->PE4->P->PE1->PE3 sera en mesure d'acheminer 50 megas. Ces liens seront en effet configurés comme disposant d'une capacité réservable de 60 megas. Tous les autres liens du réseau opérateur seront configurés comme permettant seulement 30 megas. Les commandes nécessaires à cette configuration sont disponibles en annexe.

Nous construisons notre tunnel :

interface Tunnel1
ip unnumbered Loopback1
tunnel destination 198.18.0.4
tunnel mode mpls traffic-eng
tunnel mpls traffic-eng priority 1 1
tunnel mpls traffic-eng autoroute announce 
tunnel mpls traffic-eng path-option 1 dynamic
no sh

On constate que notre tunnel est fonctionnel :

PE2#sh mpls traffic-eng tunnels tunnel 1
Name: PE2_t1                              (Tunnel1) Destination: 198.18.0.4
  Status:
    Admin: up         Oper: up     Path: valid       Signalling: connected
 
    path option 1, type dynamic (Basis for Setup, path weight 4)
 
  Config Parameters:
    Bandwidth: 50000    kbps (Global)  Priority: 1  1   Affinity: 0x0/0xFFFF
    Metric Type: TE (default)
    AutoRoute:  enabled   LockDown: disabled  Loadshare: 50000    bw-based
 
  InLabel  :  - 
  OutLabel : FastEthernet1/0, 26
  RSVP Signalling Info:
       Src 198.18.0.3, Dst 198.18.0.4, Tun_Id 1, Tun_Instance 20
    RSVP Path Info:
      My Address: 198.18.240.9   
      Explicit Route: 198.18.240.8 198.18.240.6 198.18.240.7 198.18.240.3 
                      198.18.240.2 198.18.240.4 198.18.240.5 198.18.0.4 
      Record Route:  NONE
      Tspec: ave rate=50000 kbits, burst=1000 bytes, peak rate=50000 kbits
    RSVP Resv Info:
      Record Route:  NONE
      Fspec: ave rate=50000 kbits, burst=1000 bytes, peak rate=50000 kbits
  Shortest Unconstrained Path Info:
    Path Weight: 1 (TE)
    Explicit Route: 198.18.240.15 198.18.240.14 198.18.0.4 
 
PE2#traceroute 198.18.0.4  
  1 198.18.240.8 [MPLS: Label 26 Exp 0] 12 msec 12 msec 16 msec
  2 198.18.240.7 [MPLS: Label 24 Exp 0] 16 msec 12 msec 12 msec
  3 198.18.240.2 [MPLS: Label 26 Exp 0] 16 msec 12 msec 12 msec
  4 198.18.240.5 12 msec *  28 msec

 
PE2#traceroute vrf vpnb 198.18.39.254                     
  1 198.18.240.8 [MPLS: Labels 26/27 Exp 0] 16 msec 16 msec 16 msec
  2 198.18.240.7 [MPLS: Labels 24/27 Exp 0] 12 msec 12 msec 12 msec
  3 198.18.240.2 [MPLS: Labels 26/27 Exp 0] 20 msec 12 msec 12 msec
  4 198.18.39.254 16 msec *  36 msec

On constate que ce tunnel est toujours unidirectionnel et que le trafic acheminable via ce tunnel est toujours le même :

  • trafic à destination de 198.18.0.4 ou de toute autre loopback de PE3 et de tout autre préfixe disponible uniquement en passant par PE3 ;
  • ce qui inclu le trafic à destination du site 2 du VPN A et du site 2 du VPN B.

Question 3

En théorie, il est possible de définir des FEC avec une granularité plus fine, c'est même un des objectifs de MPLS : appliquer un traitement différencié, assurer une qualité de service différente à des flux critiques.

Néanmoins, mes recherches montrent que les commandes IOS nécessaires ne sont pas disponibles sur l'image IOS que nous utilisons.

Remarquons néanmoins que, dans la pratique, ce type de configuration est difficilement (main)tenable sur un réseau d'opérateur. Les opérateurs préfèrent donc utiliser les classes de trafic établies par le groupe de travail DiffServ (voir : http://www.cisco.com/en/US/docs/ios/12_2s/feature/guide/fsdserv3.html).

Question 4

La question est ambiguë : nous n'avons pas de MPLS entre nos CE et nos PE car les CE sont destinées à être installé chez le client et doivent donc avoir une configuration simple.

Il existe plusieurs modes pour choisir les labels MPLS :

  • par VRF Egress ;
  • par interface de sortie. Ce mode permet d'éviter une itération dans la table de routage en réception ;
  • par préfixe. Seul ce mode permet de faire de la QoS.

Sur des routeurs Cisco, la commande « mpls label mode {vrf vrf-name | all-vrfs} protocol bgp-vpnv4 {per-prefix | per-vrf} » permet de choisir une attribution par VRF ou par préfixe. Cette commande est disponible sur la série 6500 et/ou à partir de la version 15 de l'IOS. Cette commande n'est donc pas disponible sur l'image IOS que nous utilisons.

Nous remarquons que, sur nos routeurs, le choix des labels se fait par préfixe. Exemple, sur PE2, pour le VPN A :

PE2#sh ip vrf detail vpna
VRF vpna; default RD 64501:1; default VPNID <not set>
  Interfaces:
    Fa4/0                   
  Connected addresses are not in global routing table
  Export VPN route-target communities
    RT:64501:1              
 
  Import VPN route-target communities
    RT:64501:1              
  No import route-map
  No export route-map
  VRF label distribution protocol: not configured
  VRF label allocation mode: per-prefix

Question 5

Comme je l'ai déjà écrit pour les questions 1 et 2, si le next-hop dans la VRF est aussi la destination d'un tunnel TE, alors le trafic du VPN passera par aussi le tunnel sans configuration supplémentaire.

Pour pouvoir choisir un tunnel différent par VPN (mes exemples se basent sur PE2 et PE3), il faudrait :

  • Que PE2 ait une loopback supplémentaire, loopback 2 ;
  • Que PE2 annonce, à PE3, son préfixe VPN A avec, comme next-hop, l'adresse de sa loopback 1 et son préfixe VPN B avec, comme next-hop, l'adresse de sa loopback 2 ;
  • Que PE3 construise 2 tunnels, un à destination de la loopback 1 de PE2 et l'autre, à destination de la loopback 2.

Même si l'on arrivait à re-écrire le next-hop (avec une route-map, ou avec la commande bgp next-hop dans notre VRF, par exemple), on ne pourra pas créer les deux tunnels TE. En effet, comme nous l'avons montré dans la première et la deuxième question, le tunnel TE englobe toutes les loopback d'un routeur. Donc PE3 empruntera aussi le premier tunnel TE pour joindre la deuxième loopback de PE2.

Donc il n'est pas possible de choisir des tunnels TE différents en fonction du VPN si les sites distants de chaque VPN sont sur le même PE.

En revanche, il est tout à fait possible de le faire quand que les PE source et destination n'ont pas plusieurs VPN. Ainsi, sur ma maquette, un tunnel TE PE2->PE1 permet de faire passer le trafic à destination du site 3 du VPN A alors qu'un tunnel TE PE2->PE4 permet de faire passer le trafic à destination du site 1 du VPN B. Les deux tunnels ne sont pas incompatibles.

Bibliographie

Dans l'ordre d'utilisation.

Annexes

Fichier de configuration Dynagen pour tout le TP

[localhost]
    [[7200]]
        image = ./C7200-AD.BIN
        ram = 256
	idlepc = 0x607335f0
 
    [[ROUTER P]]
        model = 7200
        f1/0 = PE1 f2/0
        f2/0 = PE4 f2/0
	f3/0 = PE2 f2/0
	f4/0 = PE3 f2/0
 

    [[ROUTER PE1]]
        model = 7200
        f1/0 = PE4 f1/0
	f3/0 = PE3 f1/0
 
    [[ROUTER PE2]]
        model = 7200
	f1/0 = PE4 f3/0
	f3/0 = PE3 f3/0
	f4/0 = CE1 f1/0
	f5/0 = CE3 f1/0  
 
    [[ROUTER PE3]]
        model = 7200
	f4/0 = CE2 f1/0
 
    [[ROUTER PE4]]
        model = 7200
 
    [[ROUTER CE1]]
        model = 7200
 
    [[ROUTER CE2]]
        model = 7200

 
    [[ROUTER CE3]]
        model = 7200

Commandes IOS pour effectuer la configuration "de base" des routeurs pour tout le TP

P
enable
conf t
hostname P
no ip domain lookup
line console 0
exec-timeout 0 0
logging synchronous
exit
 
int fastEthernet 1/0
ip address 198.18.240.3 255.255.255.254
mpls ip
no shutdown
exit
int fastEthernet 2/0
ip address 198.18.240.7 255.255.255.254
mpls ip
no shutdown
exit
int fastEthernet 3/0
ip address 198.18.240.10 255.255.255.254
mpls ip
no shutdown
exit
int fastEthernet 4/0
ip address 198.18.240.12 255.255.255.254
mpls ip
no shutdown
exit
int loopback 1
ip address 198.18.0.1 255.255.255.255
no shutdown
exit
 
router ospf 1
network 198.18.0.0 0.0.255.255 area 0
exit
 
ip cef
mpls label protocol ldp

 
exit
copy r s
PE1
enable
conf t
hostname PE1
no ip domain lookup
line console 0
exec-timeout 0 0
logging synchronous
exit
 
ip vrf vpna
rd 64501:1
route-target both 64501:1
exit
 
int fastEthernet 1/0
ip address 198.18.240.0 255.255.255.254
mpls ip
no shutdown
exit
int fastEthernet 2/0
ip address 198.18.240.2 255.255.255.254
mpls ip
no shutdown
exit
int fastEthernet 3/0
ip address 198.18.240.4 255.255.255.254
mpls ip
no shutdown
exit
int loopback 1
ip address 198.18.0.2 255.255.255.255
no shutdown
exit
int loopback 2
ip vrf forwarding vpna
ip address 198.18.27.254 255.255.252.0
no shutdown
exit
 
router ospf 1
network 198.18.0.0 0.0.255.255 area 0
exit
 
ip cef
mpls label protocol ldp
 

router rip
version 2
address-family ipv4 vrf vpna
network 198.18.24.0
network 198.18.25.0
network 198.18.26.0
network 198.18.27.0
no auto-summary
redistribute bgp 64501 metric 1
exit
exit
 
router bgp 64501
neighbor 198.18.0.3 remote-as 64501
neighbor 198.18.0.3 update-source loopback1
neighbor 198.18.0.4 remote-as 64501
neighbor 198.18.0.4 update-source loopback1
 
address-family vpnv4
neighbor 198.18.0.3 activate
neighbor 198.18.0.3 send-community extended
neighbor 198.18.0.4 activate
neighbor 198.18.0.4 send-community extended
exit
 
address-family ipv4 vrf vpna
redistribute rip ! ou network 198.18.24.0 mask 255.255.252.0 car RIP se justifie pas vraiment
exit
exit
exit
copy r s
PE2
enable
conf t
hostname PE2
no ip domain lookup
line console 0
exec-timeout 0 0
logging synchronous
exit
 
ip vrf vpna
rd 64501:1
route-target both 64501:1
exit
 
ip vrf vpnb
rd 64501:2
route-target both 64501:2
exit

 
int fastEthernet 1/0
ip address 198.18.240.9 255.255.255.254
mpls ip
no shutdown
exit
int fastEthernet 2/0
ip address 198.18.240.11 255.255.255.254
mpls ip
no shutdown
exit
int fastEthernet 3/0
ip address 198.18.240.15 255.255.255.254
mpls ip
no shutdown
exit
interface F4/0
ip vrf forwarding vpna
ip address 198.18.28.0 255.255.255.254
no shutdown
exit
int F5/0
ip vrf forwarding vpnb
ip address 198.18.44.0 255.255.255.254
no sh
exit
int loopback 1
ip address 198.18.0.3 255.255.255.255
no shutdown
exit
 
router ospf 1
network 198.18.0.0 0.0.255.255 area 0
exit
 
ip cef
mpls label protocol ldp
 
 
router rip
version 2
address-family ipv4 vrf vpna
network 198.18.28.0
no auto-summary
redistribute bgp 64501 metric 1
exit
exit
 
router ospf 2 vrf vpnb
network 198.18.44.0 0.0.3.255 area 0
redistribute bgp 64501 subnets
exit
 
router bgp 64501
neighbor 198.18.0.2 remote-as 64501
neighbor 198.18.0.2 update-source loopback1
neighbor 198.18.0.4 remote-as 64501
neighbor 198.18.0.4 update-source loopback1
neighbor 198.18.0.5 remote-as 64501
neighbor 198.18.0.5 update-source loopback1
 
address-family vpnv4
neighbor 198.18.0.2 activate
neighbor 198.18.0.2 send-community extended
neighbor 198.18.0.4 activate
neighbor 198.18.0.4 send-community extended
neighbor 198.18.0.5 activate
neighbor 198.18.0.5 send-community extended
exit
 
address-family ipv4 vrf vpna
redistribute rip
exit

 
address-family ipv4 vrf vpnb
redistribute ospf 2 vrf vpnb
exit
exit
exit
copy r s
PE3
enable
conf t
hostname PE3
no ip domain lookup
line console 0
exec-timeout 0 0
logging synchronous
exit
 
ip vrf vpna
rd 64501:1
route-target both 64501:1
exit
 
ip vrf vpnb
rd 64501:2
route-target both 64501:2
exit
 
int fastEthernet 1/0
ip address 198.18.240.5 255.255.255.254
mpls ip
no shutdown
exit
int fastEthernet 2/0
ip address 198.18.240.13 255.255.255.254
mpls ip
no shutdown
exit
int fastEthernet 3/0
ip address 198.18.240.14 255.255.255.254
mpls ip
no shutdown
exit
interface F4/0
ip vrf forwarding vpna
ip address 198.18.28.2 255.255.255.254
no shutdown
exit
int loopback 1
ip address 198.18.0.4 255.255.255.255
no shutdown
exit
int loopback 2
ip vrf forwarding vpnb
ip address 198.18.39.254 255.255.252.0
no shutdown
exit
 
router ospf 1
network 198.18.0.0 0.0.255.255 area 0
exit
 

ip cef
mpls label protocol ldp
 
router rip
version 2
address-family ipv4 vrf vpna
network 198.18.28.0
no auto-summary
redistribute bgp 64501 metric 1
exit
exit
 
router ospf 2 vrf vpnb
network 198.18.36.0 0.0.3.255  area 0
redistribute bgp 64501 subnets
exit
 
router bgp 64501
neighbor 198.18.0.2 remote-as 64501
neighbor 198.18.0.2 update-source loopback1
neighbor 198.18.0.3 remote-as 64501
neighbor 198.18.0.3 update-source loopback1
neighbor 198.18.0.5 remote-as 64501
neighbor 198.18.0.5 update-source loopback1
 
address-family vpnv4
neighbor 198.18.0.2 activate
neighbor 198.18.0.2 send-community extended
neighbor 198.18.0.3 activate
neighbor 198.18.0.3 send-community extended
neighbor 198.18.0.5 activate
neighbor 198.18.0.5 send-community extended
exit
 
address-family ipv4 vrf vpna
redistribute rip
exit
 
address-family ipv4 vrf vpnb
redistribute ospf 2 vrf vpnb
exit
exit
exit
copy r s
PE4
enable
conf t
hostname PE4
no ip domain lookup
line console 0
exec-timeout 0 0
logging synchronous
exit
 
ip vrf vpnb
rd 64501:2
route-target both 64501:2
exit
 
int fastEthernet 1/0
ip address 198.18.240.1 255.255.255.254
mpls ip
no shutdown
exit
int fastEthernet 2/0
ip address 198.18.240.6 255.255.255.254
mpls ip
no shutdown
exit
int fastEthernet 3/0
ip address 198.18.240.8 255.255.255.254
mpls ip
no shutdown
exit
int loopback 1
ip address 198.18.0.5 255.255.255.255
no shutdown
exit
int loopback 2
ip vrf forwarding vpnb
ip address 198.18.35.254 255.255.252.0
no shutdown
exit
 
router ospf 1
network 198.18.0.0 0.0.255.255 area 0
exit
 
ip cef
mpls label protocol ldp
 
router ospf 2 vrf vpnb
network 198.18.32.0 0.0.3.255 area 0
redistribute bgp 64501 subnets
exit
 
router bgp 64501
neighbor 198.18.0.3 remote-as 64501
neighbor 198.18.0.3 update-source loopback1
neighbor 198.18.0.4 remote-as 64501
neighbor 198.18.0.4 update-source loopback1
 
address-family vpnv4
neighbor 198.18.0.3 activate
neighbor 198.18.0.3 send-community extended
neighbor 198.18.0.4 activate
neighbor 198.18.0.4 send-community extended
exit
 

address-family ipv4 vrf vpnb
redistribute ospf 2 vrf vpnb
exit
exit
exit
copy r s
CE1
enable
conf t
hostname CE1
no ip domain lookup
line console 0
exec-timeout 0 0
logging synchronous
exit 
 
int loopback 1
ip address 198.18.19.254 255.255.252.0
no shutdown
int fastEthernet 1/0
ip address 198.18.28.1 255.255.255.254
no shutdown
exit
 
router rip
network 198.18.16.0
network 198.18.17.0
network 198.18.18.0
network 198.18.19.0
network 198.18.28.0
no auto-summary
version 2
exit
exit
copy r s
CE2
enable
conf t
hostname CE2
no ip domain lookup
line console 0
exec-timeout 0 0
logging synchronous
exit

 
int fastEthernet 1/0
ip address 198.18.28.3 255.255.255.254
no shutdown
exit
int loopback 1
ip address 198.18.23.254 255.255.252.0
no shutdown
exit
 
router rip
network 198.18.20.0
network 198.18.21.0
network 198.18.22.0
network 198.18.23.0
network 198.18.28.0
no auto-summary
version 2
exit
exit
copy r s
CE3
enable
conf t
hostname CE3
no ip domain lookup
line console 0
exec-timeout 0 0
logging synchronous
exit
 
 
int F1/0
ip address 198.18.44.1 255.255.255.254
no sh
exit
int loopback 1
ip address 198.18.43.254 255.255.252.0
no sh
exit
 
router ospf 1
network 198.18.40.0 0.0.3.255 area 0
network 198.18.44.0 0.0.3.255 area 0
exit
exit
copy r s

Commandes IOS pour effectuer la configuration supplémentaire pour la première question de la seconde partie

P
conf t
mpls traffic-eng tunnels 
router ospf 1
mpls traffic-eng router-id Loopback1
mpls traffic-eng area 0
exit
 
int F1/0
mpls traffic-eng tunnels
int F2/0
mpls traffic-eng tunnels
int F3/0
mpls traffic-eng tunnels
int F4/0
mpls traffic-eng tunnels
exit
exit
PE1
conf t
mpls traffic-eng tunnels 
router ospf 1
mpls traffic-eng router-id Loopback1
mpls traffic-eng area 0
exit
 
int F1/0
mpls traffic-eng tunnels
int F2/0
mpls traffic-eng tunnels
int F3/0
mpls traffic-eng tunnels
exit
exit
PE2
conf t
mpls traffic-eng tunnels 
router ospf 1
mpls traffic-eng router-id Loopback1
mpls traffic-eng area 0
exit
 
int F1/0
mpls traffic-eng tunnels
int F2/0
mpls traffic-eng tunnels
int F3/0
mpls traffic-eng tunnels
exit
exit
PE3
conf t
mpls traffic-eng tunnels 
router ospf 1
mpls traffic-eng router-id Loopback1
mpls traffic-eng area 0
exit
 
int F1/0
mpls traffic-eng tunnels
int F2/0
mpls traffic-eng tunnels
int F3/0
mpls traffic-eng tunnels
exit
exit
PE4
conf t
mpls traffic-eng tunnels 
router ospf 1
mpls traffic-eng router-id Loopback1
mpls traffic-eng area 0
exit
 
int F1/0
mpls traffic-eng tunnels
int F2/0
mpls traffic-eng tunnels
int F3/0
mpls traffic-eng tunnels
exit
exit

Commandes IOS pour effectuer la configuration supplémentaire pour la deuxième question de la seconde partie

P
conf t
int F1/0
ip rsvp bandwidth 60000 60000
 
int F2/0
ip rsvp bandwidth 60000 60000
 

int F3/0
ip rsvp bandwidth 30000 30000
 
int F4/0
ip rsvp bandwidth 30000 30000
exit
exit
PE1
conf t
int F1/0
ip rsvp bandwidth 30000 30000
 
int F2/0
ip rsvp bandwidth 60000 60000
 
int F3/0
ip rsvp bandwidth 60000 60000
exit
exit
PE2
conf t
int F1/0
ip rsvp bandwidth 60000 60000
 
int F2/0
ip rsvp bandwidth 30000 30000
 
int F3/0
ip rsvp bandwidth 30000 30000
exit
exit
PE3
conf t
int F1/0
ip rsvp bandwidth 60000 60000
 
int F2/0
ip rsvp bandwidth 30000 30000
 
int F3/0
ip rsvp bandwidth 30000 30000
exit
exit
PE4
conf t
int F1/0
ip rsvp bandwidth 30000 30000
 
int F2/0
ip rsvp bandwidth 60000 60000
 
int F3/0
ip rsvp bandwidth 30000 30000
exit
exit

Table des figures

Figure 1 - Schéma de ma maquette. D'après l'énoncé.
Figure 2 - En sortie de PE1, pour l'echo request, nous avons bien deux labels : le premier, 23, pour la commutation dans le réseau de l'opérateur, le deuxième, 25, pour identifier le VPN.
Figure 3 - En entrée de PE2, pour l'echo request, nous n'avons plus qu'un seul label : celui de fond de pile, 25, qui permet d'idenfitier le VPN. Le label de sommet de pile a été poper par PE3.
Figure 4 - En sortie de PE2, pour l'echo reply, nous avons deux labels : le premier, 16, pour la commutation dans le réseau de l'opérateur, le deuxième, 25, pour identifier le VPN.
Figure 5 - En entrée de PE1, pour l'echo reply, nous n'avons plus que le label de fond de pile, 25, qui permet d'identifier le VPN. Le label de sommet de pile a été poper par P.
Figure 6 - PE1 annonce (à P dans notre cas), le nouveau préfixe d'interconnexion 198.18.240.0 entre lui et PE4.
Figure 7 - À la fin de son initialisation, PE4 ouvre des sessions OSPF avec ses voisins (PE1 dans notre cas).
Figure 8 - Les voisins de PE4 (PE1 dans notre cas) relayent les annonces de PE4 et marquent le préfixe d'interconnexion PE1<->PE4 comme un lien de transit vers d'autres préfixes.
Figure 9 - PE4 et ses voisins initient des sessions LDP. Ici on voit PE4->PE1, P->PE4, PE4->PE3.
Figure 10 - La loopback de PE4 (et les préfixes d'interconnexion) se voit attribuer un label. Ici, on voit les échanges entre P<->PE4 et P<->PE1.
Figure 11 - Le routage propre au VPN (ici, OSPF) se met en marche entre PE2 et CE3. PE2 va désormais avoir le nouveau site VPN B (L2 de CE3) et les préfixes d'interconnexions dans ses tables.
Figure 12 - PE2 annonce le nouveau site VPN B (L2 de CE3) aux autres sites du VPN B (PE3 dans cette illustration) et apprend les préfixes des autres sites du VPN B.
Figure 13 - PE2 propage, à l'intérieur du site, les autres préfixes des sites distants du VPN B. Ici : le site 2 appris via PE3.
Figure 14 - CE3 annonce, via OSPF, sa nouvelle loopback.
Figure 15 - PE2 annonce, via iBGP, le nouveau préfixe existant sur le site VPN aux autres sites du VPN (ici : PE3).
Figure 16 - Une topologie full-mesh. Source : https://www.juniper.net/techpubs/software/erx/junose93/swconfig-bgp-mpls/using-route-targets-to-configure-vpn-topologies.html.
Figure 17 - Une topologie Hub-and-Spoke. D'après : https://www.juniper.net/techpubs/software/erx/junose93/swconfig-bgp-mpls/using-route-targets-to-configure-vpn-topologies.html.
Figure 18 - Une topologie avec un site commun (Overlapping VPN). Source : https://www.juniper.net/techpubs/software/erx/junose93/swconfig-bgp-mpls/using-route-targets-to-configure-vpn-topologies.html.

TP réseaux d’opérateur II : MPLS/MPLS-TE

Aujourd'hui, suite des travaux pratiques concernant des technologies utilisées par les opérateurs réseaux. Après BGP : MPLS.

Même si ces TPs se placent dans un cadre scolaire (« bouh c'est nul, on ne fait pas comme ça en vrai ! » diront certains), j'ai trouvé ces TPs géniaux justement par leur ouverture et parce qu'ils tendent à mettre en exergue les limites auxquelles certaines méthodes utilisables dans un TP seront confrontées « dans la vraie vie ». Ils sont extrêmement formateurs. C'est ce qui m'amène à les partager avec vous accompagnés de mes pistes de réflexion.

Ceux qui aiment bidouiller autour des réseaux devraient tenter de répondre aux questions avant de regarder mes pistes de réflexion. Vous ne devriez pas être déçus.

Table des matières

Énoncé

Déployer MPLS sur un réseau de test

Topologie plus complexe.

  1. Q1. Dans l’environnement dynamips/dynagen, construire le réseau ci-dessus (le lien R5-R6 a un débit plus faible que les autres). Configurez l’adressage IP et le routage OSPF, ainsi que des adresses de loopback sur chaque routeur. Après avoir vérifié que le réseau IP fonctionne, activez MPLS sur les réseaux d’interconnexion. Visualisez les tables de label des différents routeurs.
  2. Q2. Pour le préfixe P4 de l’interface de loopback de R4, donnez le contenu des tables de routage et de labels des différents routeurs. En déduire les paquets (avec leurs labels) qui vont transiter de R1à R4 (et retour) si on exécute ping P4 depuis R1. Vérifiez (ou infirmez) ce comportement avec des captures de trames analysées avec wireshark et avec traceroute.
  3. Q3. Les labels utilisés de R2 à R3 (pour un même préfixe, par exemple P4) dépendent-ils de l’interface d’entrée dans R2 ? Un label peut-il être utilisé dans les deux sens sur le même lien ? Peut-il être utilisé sur plusieurs liens d’un même routeur ?
  4. Q4. Les routeurs utilisent-ils le penultimate popping ? Montrez l’effet sur le plus long tunnel.
  5. Q5. Étudiez et montrez l’effet de la commande de configuration : [no] mpls ip propagate-ttl
  6. Q6. Étudiez et montrez l’effet de la commande de configuration : [no] mpls ip ttl-expiration pop labels
  7. Q7. Quels sont les types de tunnels que vous pouvez construire via ces commandes ? Qu’observez vous au niveau des chemins A/R ?
  8. Q8. Un nouveau préfixe P5 est ajouté sur R4 (interface lo1 sur R4). Décrivez tous les échanges de protocole (OSPF, LDP, etc) qui ont lieu suite à cette configuration. L’affectation des labels est elle downstream on demand (justifiez votre réponse) ?
  9. Q9. De même si le lien R1-R2 est coupé, quels sont les échanges des différents protocoles ?
  10. Q10. Demo de routage contraint : illustrez l’algorithme CSPF/MPLS-TE via avec les chemins et les capacités de votre choix.

Cet énoncé est celui de Jean-Jacques Pansiot et Pascal Mérindol de l'université de Strasbourg.

Pour ceux qui préfèrent lire un si gros pavé en PDF : TP réseaux d'opérateur II : MPLS. Et comme à chaque fois, les sources LaTeX sont disponibles ici : sources LaTeX.

Le travail ci-dessous a été réalisé conjointement avec Hamza HMAMA.

Avant de commencer

Adressage IPv4

Concernant l'adressage IP, nous avons décidé de choisir notre préfixe dans la plage réservée à l'IANA pour les tests : 198.18.0.0/15. Pour une plus grande facilité, nous avons décidé d'utiliser le sous-préfixe 198.18.0.0/16.

Pour faciliter l'adressage, nous avons décidé de découper ce préfixe en plusieurs préfixes de longueur /20 :

  1. Les premiers /20 sont dédiés aux "services" : chacune des loopback demandées dans l'énoncé se trouvera dans un /20 différent.
  2. Le milieu est réservé pour un usage futur (expansion des "services", expansion des interconnexions, ...).
  3. Le dernier /20 est dédié aux interconnexions des routeurs internes. Il sera découpé en /31, chaque /31 étant dédié à une interconnexion.

Nous ne prévoyons pas d'avoir plus de 2048 interconnexions internes mais si c'était le cas, on prendrait des préfixes dans le milieu en suivant mais en partant de la fin.

Les interconnexions se font en /31 car les IPv4 sont rares et il faut donc les économiser. Même si nous utilisons un préfixe de documentation/test, nous avons fait ce choix car, d'après nos renseignements, il s'agit d'une BCP donc pourquoi ne pas s'y conformer, même sur une maquette ? De plus, cela amène des avantages (pas de broadcast, ...).

Les préfixes de nos loopback seront :

  • R1 - P1 : 198.18.15.254/20
  • R2 - P2 : 198.18.31.254/20
  • R3 - P3 : 198.18.47.254/20
  • R4 - P4 : 198.18.63.254/20
  • R5 - P5 : 198.18.79.254/20
  • R6 - P6 : 198.18.95.254/20

Note : les sorties des commandes de vérification (show ...) seront allégées/tronquées pour ne garder que l'essentiel afin de ne pas surcharger ce rapport.

Schéma

En figure 1 se trouve le schéma donné dans l'énoncé complété avec notre plan d'adressage.

Schéma de notre maquette

Figure 1 - Schéma de notre maquette. D'après l'énoncé.

Question 1

La configuration de dynagen pour ce TP est donnée en annexe 1.

La configuration des routeurs se fait facilement : il n'y a pas de commandes que nous n'avons pas vues lors du premier TP ou qui n'ont pas été données lors de la séance de TP. Les configurations intégrales de nos routeurs se trouvent en annexe 2.

Pour illustration, voici un extrait de la LIB (Label Information Base) et la LFIB (Label Forwarding Information Base) de notre routeur R1 :

R1#show mpls ldp bindings 
[...]
  tib entry: 198.18.31.254/32, rev 8
	local binding:  tag: 16
	remote binding: tsr: 198.18.79.254:0, tag: 26
  tib entry: 198.18.47.254/32, rev 24
	local binding:  tag: 23
	remote binding: tsr: 198.18.79.254:0, tag: 19
	remote binding: tsr: 198.18.31.254:0, tag: 23
  tib entry: 198.18.63.254/32, rev 26
	local binding:  tag: 24
	remote binding: tsr: 198.18.79.254:0, tag: 27
	remote binding: tsr: 198.18.31.254:0, tag: 24
[...]
  tib entry: 198.18.240.10/31, rev 18
        local binding:  tag: 20
        remote binding: tsr: 198.18.79.254:0, tag: 22
        remote binding: tsr: 198.18.31.254:0, tag: 19
  tib entry: 198.18.240.12/31, rev 16
        local binding:  tag: 19
        remote binding: tsr: 198.18.79.254:0, tag: 18
        remote binding: tsr: 198.18.31.254:0, tag: 20
  tib entry: 198.18.240.14/31, rev 20
        local binding:  tag: 21
        remote binding: tsr: 198.18.79.254:0, tag: 23
        remote binding: tsr: 198.18.31.254:0, tag: 21
 
 
R1#show mpls forwarding-table
Local  Outgoing    Prefix            Bytes tag  Outgoing   Next Hop    
tag    tag or VC   or Tunnel Id      switched   interface              
16     Untagged    198.18.31.254/32  0          Fa1/0      198.18.240.1 
17     Pop tag     198.18.240.4/31   0          Fa2/0      198.18.240.3 
       Pop tag     198.18.240.4/31   0          Fa1/0      198.18.240.1 
18     Pop tag     198.18.240.6/31   0          Fa1/0      198.18.240.1 
19     20          198.18.240.12/31  0          Fa1/0      198.18.240.1 
20     19          198.18.240.10/31  0          Fa1/0      198.18.240.1 
21     21          198.18.240.14/31  0          Fa1/0      198.18.240.1 
22     Pop tag     198.18.240.8/31   0          Fa2/0      198.18.240.3 
23     23          198.18.47.254/32  0          Fa1/0      198.18.240.1 
24     24          198.18.63.254/32  0          Fa1/0      198.18.240.1 
25     Untagged    198.18.79.254/32  0          Fa2/0      198.18.240.3 
26     26          198.18.95.254/32  0          Fa1/0      198.18.240.1 
27     27          198.18.111.254/32 0          Fa1/0      198.18.240.1

On observe aussi que chaque routeur crée automatiquement un LSP vers la loopback de chaque autre routeur, ce qui est le comportement attendu.

Question 2

Pour répondre à cette question, nous nous sommes mis dans la situation où nous pingons P4 en mettant P1 en adresse source. Il est toujours mieux de pinger d'une loopback à l'autre. Nous ferons ainsi pour le reste de ce TP.

On interroge récursivement les LFIB de nos routeurs. D'abord pour l'aller :

R1#show mpls forwarding-table 198.18.63.254           
24     24          198.18.63.254/32  0          Fa1/0      198.18.240.1 ! -> R2
 
R2#show mpls forwarding-table 198.18.63.254            
24     24          198.18.63.254/32  0          Fa3/0      198.18.240.7 ! -> R3 
 
R3#show mpls forwarding-table 198.18.63.254      
24     Untagged    198.18.63.254/32  0          Fa2/0      198.18.240.11 ! -> R4

Puis pour le retour :

R4#show mpls forwarding-table 198.18.15.254        
22     22          198.18.15.254/32  0          Fa1/0      198.18.240.10 ! -> R3
 
R3#show mpls forwarding-table 198.18.15.254            
22     16          198.18.15.254/32  0          Fa1/0      198.18.240.6 ! -> R2
 
R2#show mpls forwarding-table 198.18.15.254     
16     Untagged    198.18.15.254/32  0          Fa1/0      198.18.240.0 ! -> R1

À l'aller, on aura donc le chemin et les labels MPLS suivants :
R1 -> [24] -> R2 -> [24] -> R3 -> [] -> R4

Au retour, on aura le chemin et les labels MPLS suivants :
R4 -> [22] -> R3 -> [16] -> R2 -> [] -> R1

Vérifications avec des traceroute :

R1#traceroute 198.18.63.254 source 198.18.15.254
  1 198.18.240.1 [MPLS: Label 24 Exp 0] 8 msec 20 msec 12 msec
  2 198.18.240.7 [MPLS: Label 24 Exp 0] 8 msec 8 msec 8 msec
  3 198.18.240.11 44 msec *  16 msec
 
R4#traceroute 198.18.15.254 source 198.18.63.254
  1 198.18.240.10 [MPLS: Label 22 Exp 0] 12 msec 44 msec 44 msec
  2 198.18.240.6 [MPLS: Label 16 Exp 0] 40 msec 8 msec 12 msec
  3 198.18.240.0 8 msec *  16 msec

Vérification avec nos captures réseau. À l'aller :

Capture réseau. Ping P4 (198.18.63.254) depuis P1 (198.18.15.254). Aller

Figure 2 - Capture réseau. Ping P4 (198.18.63.254) depuis P1 (198.18.15.254). Aller.

Au retour :

Capture réseau. Ping P4 (198.18.63.254) depuis P1 (198.18.15.254). Retour

Figure 3 - Capture réseau. Ping P4 (198.18.63.254) depuis P1 (198.18.15.254). Retour.

Question 3

Avant de répondre, regardons les LFIB de R1, R5, R2 et R3 :

R1#show mpls forwarding-table 198.18.63.254           
24     24          198.18.63.254/32  0          Fa1/0      198.18.240.1
 

R5#show mpls forwarding-table 198.18.63.254
27     24          198.18.63.254/32  0          Fa2/0      198.18.240.4
 
R2#show mpls forwarding-table 198.18.63.254            
24     24          198.18.63.254/32  0          Fa3/0      198.18.240.7
 
R3#show mpls forwarding-table 198.18.63.254
24     Untagged    198.18.63.254/32  2474       Fa2/0      198.18.240.11

On constate bien que, quelle que soit l'interface d'entrée dans R2, un paquet à destination de P4 sera toujours tagué avec le label 24. Pour commuter un paquet destiné à P4, R3 attend qu'il soit tagué avec le label 24, peu importe quel routeur, "caché" derrière R2, a envoyé ce paquet. Cela est tout à fait logique : il y a un label par destination par routeur.

Un même label ne peut pas être utilisé dans deux sens sur un même lien car il y a un label par destination et il faut éviter la formation de boucles. Supposons que, pour le retour de la question 2, R4 aurait envoyé un paquet tagué avec le label 24 à R3. Pour R3, 24 est associé à 198.18.63.254 via R4. R3 aurait donc transféré ce paquet à R4, non à R2 (pour que lui-même transmette à R1).

Un même label peut être utilisé sur plusieurs liens d'un même routeur mais pour une même destination uniquement. Illustration :

R5#traceroute 198.18.111.254 source 198.18.79.254 
  1 198.18.240.9 [MPLS: Label 26 Exp 0] 12 msec 12 msec 12 msec
  2 198.18.240.12 [MPLS: Label 26 Exp 0] 12 msec 12 msec 12 msec
  3 198.18.240.11 8 msec *  28 msec

Ici, on a coupé les liens R2<->R3 et R6<->R4. On constate qu'entre R5 et R6, le label utilisé est 26 qui est le même entre R6 et R3. On a donc deux liens, partant du même routeur (R6), qui portent le même label pour une même destination.

Question 4

La fonctionnalité penultimate hop popping permet de faire supprimer le label non pas par le routeur de sortie, l'Egress, mais par l'avant-dernier. Cela permet d'éviter au routeur Egress une double itération : l'une dans sa LFIB et l'autre dans sa table de routage IP. L'opération de recherche sur le label dans sa LFIB est inutile, car dans tous les cas le routeur devra effectuer une recherche dans sa table de routage IP. En utilisant la fonctionnalité PHP, l'Egress doit simplement faire une recherche dans sa table de routage IP.

Par défaut, les routeurs Cisco font du penultimate popping. Source : http://www.cisco.com/en/US/docs/routers/asr9000/software/mpls/configuration/guide/gcasr9kldp.html.

Pour constater ce phénomène, il suffit de revenir à la question 2 : quand R1 veut joindre la loopback de R4, c'est R3, qui est directement connecté à R4, qui supprime le label. On a donc du penultimate hop popping.

Si l'on faisait un traceroute entre deux adresses IP de lien (pas des loopback), comme 198.18.240.0->198.18.240.11, on observerait que l'on perd un label MPLS supplémentaire (R2 supprimerait le label) ce qui correspond bien au comportement du PHP.

Question 5

Cette commande permet d'activer ou de désactiver la propagation du TTL depuis le paquet IP original vers le header MPLS. La désactivation de cette propagation est utilisée par les opérateurs qui veulent masquer les tunnels MPLS de leurs réseaux.

Par défaut, les routeurs Cisco propagent le TTL IP vers MPLS. Source : http://www.cisco.com/en/US/docs/ios/mpls/command/reference/mp_m1.html#wp1013846

Quand la fonctionnalité est activée, un traceroute met en évidence tous les routeurs d'un chemin comme nous l'avons vu lors des questions précédentes.

Il suffit de désactiver la fonctionnalité sur l'Ingress pour qu'elle soit prise en compte. En effet, quelle que soit la configuration des autres routeurs, seule celle de l'Ingress compte : si ce dernier met un TTL fixe (255 sur Cisco, mais cela change selon les équipementiers) car la propagation est désactivée, il est ensuite trop tard pour revenir sur ce choix.

Illustration : nous désactivons le propagate-ttl sur R1 et nous faisons un traceroute vers R4 :

traceroute 198.18.63.254 source 198.18.15.254
  1 198.18.240.7 [MPLS: Label 23 Exp 0] 12 msec 8 msec 8 msec
  2 198.18.240.11 48 msec *  8 msec

On constate bien que l'absence de la propagation du TTL du paquet IP original vers le header MPLS. Cela fait que les routeurs intermédiaires du tunnel MPLS (ici : R2) disparaissent du traceroute.

Question 6

Cette commande permet de spécifier comment une réponse ICMP à un paquet ayant un TTL expiré est renvoyée : on utilise MPLS ou la table de routage IP ? Plus précisément, elle permet de définir un seuil. Si le nombre de labels dans le paquet reçu est supérieur à ce seuil, alors le paquet sera commuté avec MPLS. Sinon, on utilisera le routage IP classique.

La commande mpls ip ttl-expiration pop 1 est la commande la plus utilisée par les opérateurs pour activer le transfert (forward) basé sur plusieurs labels.

Le détail de la fonctionnalité est donné en : http://www.cisco.com/en/US/docs/ios/mpls/command/reference/mp_m1.html#wp1013945.

Vérification :

Dans un premier temps, on utilise la configuration par défaut, c'est-à-dire sans la fonctionnalité ttl-expiration pop.

On fait alors un traceroute de 100 paquets avec un TTL fixé à 1 entre la loopback de R1 et celle de R4. R2 va recevoir les paquets. Il va le supprimer et générer un message ICMP TTL exceeded pour chacun des 100 paquets. Ces paquets vont être transférés jusqu'à R4 qui va les renvoyer à R1 via R3 et R2.

Pour illustrer cela, nous regardons les statistiques de l'interface f1/0 (qui est connectée à R3) de R4 : on remarque que R4 a reçu les 100 paquets ICMP et les a retransmis par la même interface.

Avant (ligne « Route cache ») :

R4#show int F1/0 stats
FastEthernet1/0
          Switching path    Pkts In   Chars In   Pkts Out  Chars Out
               Processor      35903    3130038      35580    3065492
              Route cache      1012     184184       1030     191580 
                   Total      36915    3314222      36610    3257072

Commande utilisée :

R1#traceroute          
Protocol [ip]: 
Target IP address: 198.18.63.254
Source address: 198.18.15.254
Numeric display [n]: 
Timeout in seconds [3]: 1
Probe count [3]: 100
Minimum Time to Live [1]: 1
Maximum Time to Live [30]: 1
Port Number [33434]: 
Loose, Strict, Record, Timestamp, Verbose[none]: 
Type escape sequence to abort.
Tracing the route to 198.18.63.254
 
  1 198.18.240.1 [MPLS: Label 24 Exp 0] 68 msec 44 msec 12 msec 12 msec 12 msec 
8 msec 12 msec 8 msec 52 msec 8 msec 12 msec 44 msec 40 msec 8 msec 12 msec 
12 msec 8 msec 44 msec 44 msec 12 msec 12 msec 12 msec 8 msec 12 msec 12 msec 
[...]

Après (ligne « Route cache ») :

R4#show int F1/0 stats
FastEthernet1/0
          Switching path    Pkts In   Chars In   Pkts Out  Chars Out
               Processor      35912    3130722      35588    3066070
             Route cache       1112     202384       1130     210180 
                   Total      37024    3333106      36718    3276250

On voit bien qu'il y a eu précisément 100 paquets reçus et réémis.

Illustration :

On observe que R4 reçoit bien les paquets ICMP exceeded

Figure 4 - On observe que R4 reçoit bien les paquets ICMP exceeded.

Dans un deuxième temps, on utilise la fonctionnalité ttl-expiration pop 1 et on reproduit l'expérience donnée ci-dessus. R2 va donc recevoir les 100 paquets. Puisqu'on a un seul label, R2 va poper le label et émettre des messages ICMP TTL exceeded en utilisant la table de routage IP. Cela fait que, dans ce cas, les messages ICMP vont être retransmis directement à R1 sans passer par R3 et R4.

Avant :

R4#show int F1/0 stats
FastEthernet1/0
          Switching path    Pkts In   Chars In   Pkts Out  Chars Out
               Processor      35966    3135652      35640    3070754
             Route cache       1112     202384       1130     210180 
                   Total      37078    3338036      36770    3280934

Commande utilisée :

R1#traceroute   
Protocol [ip]:           
Target IP address: 198.18.63.254
Source address: 198.18.15.254
Numeric display [n]:              
Timeout in seconds [3]: 1
Probe count [3]: 100
Minimum Time to Live [1]: 1
Maximum Time to Live [30]: 1
Port Number [33434]: 
Loose, Strict, Record, Timestamp, Verbose[none]: 
Type escape sequence to abort.
Tracing the route to 198.18.63.254
 
  1 198.18.240.1 [MPLS: Label 24 Exp 0] 32 msec 4 msec 4 msec 4 msec 4 msec 4 msec
 8 msec 32 msec 4 msec 4 msec 4 msec 8 msec 8 msec 32 msec 4 msec 4 msec 8 msec
4 msec 4 msec 4 msec 40 msec 4 msec 4 msec 4 msec 4 msec 4 msec 40 msec 4 msec
[...]

On remarque un RTT moyen inférieur à celui obtenu lors de la première étape ce qui tend à confirmer, dans le contexte de notre maquette (la réalité demanderait plus de prudence), que le chemin de retour est raccourci.

Après :

R4#show int F1/0 stats
FastEthernet1/0
          Switching path    Pkts In   Chars In   Pkts Out  Chars Out
               Processor      35968    3135822      35644    3071060
             Route cache       1112     202384       1130     210180 
                   Total      37080    3338206      36774    3281240

Question 7

Il y a quatre types de tunnels :

  1. Explicit : support du RFC 4950 et activation du propagate-ttl. On voit donc chaque routeur et l'on sait qu'il y a un tunnel MPLS.
  2. Implicit : pas de support du RFC 4950 et activation du propagate-ttl. On voit donc chaque routeur mais l'on ne sait pas qu'il y a un tunnel MPLS.
  3. Opaque : support du RFC 4950 et désactivation du propagate-ttl. On voit donc uniquement le dernier routeur du tunnel MPLS ainsi que la destination et l'on sait qu'il y a un tunnel MPLS sans avoir les détails du tunnel (routeurs intermédiaires).
  4. Invisible : pas de support du RFC 4950 et désactivation du propagate-ttl. On ne voit pas les routeurs intermédiaires du tunnel et l'on ne sait pas qu'il y a un tunnel MPLS sur le chemin.
Les différents types de tunnels MPLS en fonction des fonctions supportées/activées

Figure 5 - Les différents types de tunnels MPLS en fonction des fonctions supportées/activées. Source : http://www.slideshare.net/edge7/slides-mpls-tunnel.

Quand on utilise propagate-ttl sur l'Ingress, on obtient un tunnel explicit. Exemple : de la loopback de R1 à celle de R4.

R1#traceroute 198.18.63.254 source 198.18.15.254
  1 198.18.240.1 [MPLS: Label 24 Exp 0] 8 msec 8 msec 8 msec
  2 198.18.240.7 [MPLS: Label 23 Exp 0] 8 msec 8 msec 8 msec
  3 198.18.240.11 8 msec *  16 msec

Quand on désactive propagate-ttl sur l'Ingress, on obtient un tunnel opaque. Exemple : de la loopback de R1 à celle de R4.

R1#traceroute 198.18.63.254 source 198.18.15.254
  1 198.18.240.7 [MPLS: Label 23 Exp 0] 8 msec 8 msec 44 msec
  2 198.18.240.11 8 msec *  8 msec

On ne peut pas obtenir les deux autres types de tunnels car cela nécessite de désactiver les extensions du RFC 4950 et il n'y a pas de commandes sur l'IOS pour faire ça. La seule solution est d'utiliser une ancienne image de l'IOS sortie avant la publication du RFC 4950.

Nous avons essayé quelques images (localisées avec un moteur de recherche et « intitle:"index of" IOS [7200] ») sans succès : même la version 12.0 de l'IOS de la série 7200 supporte les extensions du RFC 4950 ! Comme ce point n'est pas le plus fondamental de ce TP, nous n'avons pas insisté.

Par défaut, c'est-à-dire avec la propagation du TTL IP vers MPLS et la fonctionnalité ttl-expiration pop désactivée, les réponses echo-reply seront directement émises et transmises à la source (la machine qui a lancé l'echo request) alors que les messages ICMP TTL-exceeded seront transmis à la source en passant d'abord par le dernier routeur du tunnel. C'est ce que résume l'illustration suivante :

Différence de chemin A/R entre un echo request/reply et un ttl-exceeded

Figure 6 - Différence de chemin A/R entre un echo request/reply et un ttl-exceeded. Source : http://www.caida.org/publications/papers/2012/revealing_mpls_tunnels/revealing_mpls_tunnels.pdf.

Illustration entre la loopback de R1 et celle de R4 :

R1#traceroute   
Protocol [ip]:           
Target IP address: 198.18.63.254
Source address: 198.18.15.254
Numeric display [n]:              
Timeout in seconds [3]: 1            
Probe count [3]: 1
Minimum Time to Live [1]: 
Maximum Time to Live [30]: 
Port Number [33434]: 
Loose, Strict, Record, Timestamp, Verbose[none]: 
Type escape sequence to abort.
Tracing the route to 198.18.63.254
 
  1 198.18.240.1 [MPLS: Label 23 Exp 0] 32 msec
  2 198.18.240.7 [MPLS: Label 23 Exp 0] 48 msec
  3 198.18.240.11 8 msec

Avec une capture réseau, nous voyons que le message ICMP TTL-exceeded de R2 (198.18.240.1) revient avec un TTL de 251 :

Quand R1 fait un traceroute vers R4, R2 envoie un ICMP TTL-exceeded avec un TTL de 251

Figure 7 - Quand R1 fait un traceroute vers R4, R2 envoie un ICMP TTL-exceeded avec un TTL de 251.

Or, un ping direct sur 198.18.240.1 nous indique qu'il n'y a pas de routeur intermédiaire entre R1 et R2 :

Quand R1 fait ping vers 198.18.240.1, on observe un TTL de 255

Figure 8 - Quand R1 fait ping vers 198.18.240.1, on observe un TTL de 255.

Donc le message ICMP ttl-exceeded a fait le tour de notre tunnel MPLS alors que l'echo reply est revenu directement.

Concernant le traceroute, R2 a reçu un paquet IP avec un TTL de 1. Il effectue la décrémentation avant transfert. Il se rend compte que le TTL est de 0. Il détruit le paquet et émet un message ICMP TTL-exceeded à destination de R1. Ce nouveau paquet IP a donc un TTL de 255. Le paquet arrive en R3, qui va décrémenter le TTL (254) puis transmettre le paquet à R4 qui va décrémenter le TTL (253) puis transmettre le paquet à R3 qui va décrémenter à nouveau le TTL (252) puis transmettre le paquet à R2 qui va décrémenter le TTL (251) puis transmettre à R1.

En excluant le dernier saut R2-> R1 du message ICMP, on se rend compte qu'il y a 3 routeurs intermédiaires et que 198.18.240.11 est l'Egress d'un tunnel MPLS et que R2 et R3 sont aussi traversés par ce tunnel.

On pourra confirmer cela en analysant les TTL des autres messages ICMP TTL-exceeded (ceux de R3 et R4).

C'est sur cette différence entre les TTL que se base la détection des tunnels MPLS implicit.

Question 8

Le nouveau préfixe P5 sera 198.18.111.254.

Théoriquement, R4 devra annoncer la nouvelle loopback via OSPF puis on devrait avoir des échanges LDP.

Vérification : on obtient bien le comportement décrit ci-dessus.

R4 annonce sa nouvelle loopback en OSPF

Figure 9 - R4 annonce sa nouvelle loopback en OSPF.

R4 annonce sa nouvelle loopback via LDP

Figure 10 - R4 annonce sa nouvelle loopback via LDP.

Attribution des labels pour la nouvelle loopback : pour transmettre des paquets à destination de la nouvelle loopback, R3 attend qu'ils soient tagués avec le label 26

Figure 11 - Attribution des labels pour la nouvelle loopback : pour transmettre des paquets à destination de la nouvelle loopback, R3 attend qu'ils soient tagués avec le label 26.

Non, l'attribution des labels n'est pas downstream on demand car, dans ce mode-là, un PDU LDP Request descend depuis l'Ingress et une réponse LDP Mapping remonte jusqu'à l'Ingress.

Or, dans notre cas, R4 ne répond pas à une requête mais informe spontanément ses voisins. On est donc dans un mode unsollicited downstream où c'est l'Egress qui initie le mapping.

Question 9

Théoriqement, des messages OSPF de type LS UPDATE seront émis et l'on constatera la disparition du lien R1<->R2. Puis, des échanges LDP devront aussi indiquer la disparition du voisin.

Vérification : on "éteint" l'interface f1/0 de R1.

R2 émet un LS UPDATE dans lequel il n'annonce plus avoir un lien avec R1 (absence de 198.18.240.0 et de 198.18.15.254)

Figure 12 - R2 émet un LS UPDATE dans lequel il n'annonce plus avoir un lien avec R1 (absence de 198.18.240.0 et de 198.18.15.254).

R2 annonce à R3 la disparition de R1 (198.18.240.0) avec un message LDP Withdrawal. R3 annonce la disparition d'un routeur en amont (R1) avec un message LDP Release

Figure 13 - R2 annonce à R3 la disparition de R1 (198.18.240.0) avec un message LDP Withdrawal. R3 annonce la disparition d'un routeur en amont (R1) avec un message LDP Release.

Dans le même temps, R1 annoncera aussi, à R5, en OSPF et via LDP, sa perte de connectivité avec R2.

On observe le même comportement (LS UPDATE puis LDP Withdrawal puis LDP Release) sur R5. Sur les autres routeurs, on aura LS UPDATE et LDP Release.

Question 10

Voici le schéma de notre maquette avec la capacité réservable pour chaque lien.

Schéma de notre maquette avec la capacité réservable sur chaque lien

Figure 14 - Schéma de notre maquette avec la capacité réservable sur chaque lien. D'après l'énoncé.

Notes :

  • Sur chaque lien, nous n'avons pas l'égalité « capacité réservable = capacité réelle » car nous avons laissons de la place pour le trafic best-effort comme cela est recommandé.
  • Dans un premier temps, nous avons un seul niveau de priorité.

Pour mettre en œuvre l'ingénierie de trafic sur notre maquette, il faut activer les tunnels TE et OSPF-TE puis indiquer, pour chaque lien, la capacité réservable. Sur les routeurs Cisco, cela se fait avec les commandes suivantes (ici, sur R1) :

!Tunnels TE
mpls traffic-eng
 
!OSPF-TE
router ospf 1
mpls traffic-eng router-id Loopback1
mpls traffic-eng area 0
 
!Pour chaque lien, la capacité réservable
interface FastEthernet1/0
mpls ip
mpls traffic-eng tunnels
ip rsvp bandwidth 50000 50000

Les configurations intégrales de nos routeurs se trouvent en annexe 3.

On remarque que, dès l'activation d'OSPF-TE sur R1, celui-ci annonce de nouveaux LSA, des LSA-TE, qui se propagent dans toute notre maquette. Ici, sur R4 :

R1 annonce la capacité du lien R1<->R2 mais indique une capacité réservable nulle

Figure 15 - R1 annonce la capacité du lien R1<->R2 mais indique une capacité réservable nulle.

Puis, quand on configure la capacité réservable sur le lien R1<->R2, R1 l'annonce dans ses LSA-TE. Toujours sur R4 :

Maintenant, R1 annonce aussi la capacité réservable sur le lien R1<->R2

Figure 16 - Maintenant, R1 annonce aussi la capacité réservable sur le lien R1<->R2.

Nous pouvons maintenant construire nos tunnels. Nous avons choisi de construire 3 tunnels :

  1. T0, de R1 jusqu'à P4 : 30. Ce tunnel nous permettra de constater que ce n'est pas toujours le chemin le plus court qui est sélectionné mais celui qui répond d'abord à la contrainte de capacité.
  2. T1, de R1 jusqu'à P3 : 3. Ce tunnel nous permettra de constater ce qui arrive quand le lien R2<->R3 n'a plus de capacité réservable.
  3. T2, de R1 jusqu'à P6 : 15. Ce tunnel nous permettra de constater ce qui arrive quand une contrainte ne peut pas être satisfaite.

Créons T0 :

interface Tunnel0
ip unnumbered Loopback1
tunnel destination 198.18.63.254
tunnel mode mpls traffic-eng
tunnel mpls traffic-eng autoroute announce 
tunnel mpls traffic-eng priority 1 1 
tunnel mpls traffic-eng bandwidth 30000
tunnel mpls traffic-eng path-option 1 dynamic
no routing dynamic

Nous constatons qu'un PDU RSVP-TE de type PATH part de R1 jusqu'à R4 en passant par R2, R3 et R6. Illustrations sur R1 et R2 :

R1 fait sa demande de tunnel avec un PDU RSVP-TE de type PATH

Figure 17 - R1 fait sa demande de tunnel avec un PDU RSVP-TE de type PATH.

R2 transmet simplement la demande de tunnel de R1

Figure 18 - R2 transmet simplement la demande de tunnel de R1.

R4 est en mesure de satisfaire la demande et il répond donc à R1 avec un PDU RSVP-TE de type RESV. Cette fois-ci, le message est adressé au prochain nœud du chemin : R6.

R4 émet un PDU RSVP-TE de type RESV à destination de R6

Figure 19 - R4 émet un PDU RSVP-TE de type RESV à destination de R6.

R6 peut satisfaire la demande et émet donc un nouveau PDU RSVP-TE RESV à R3.

R6 émet un PDU RSVP-TE de type RESV à destination de R3

Figure 20 - R6 émet un PDU RSVP-TE de type RESV à destination de R3.

Cela continue jusqu'à R1 :

R1 reçoit le PDU RSVP-TE RESV de R2 et sait donc que son tunnel TE est prêt

Figure 21 - R1 reçoit le PDU RSVP-TE RESV de R2 et sait donc que son tunnel TE est prêt.

En parallèle, OSPF propage les nouvelles métriques TE pour tenir compte des changements concernant la capacité réservable sur les liens traversés. Exemple : R2 annonce qu'on ne peut plus réserver de capacité sur le lien R2<->R3 sauf si l'on est plus prioritaire que le précédent demandeur (comme R1 était en priorité 1, il faut être en priorité 0) :

R2 annonce, en OSPF, que plus aucune capacité n'est réservable sur le lien R2<->R3

Figure 22 - R2 annonce, en OSPF, que plus aucune capacité n'est réservable sur le lien R2<->R3.

On vérifie la bonne création du tunnel sur R1 :

R1#show mpls traffic-eng tunnels Tunnel 0
Name: R1_t0                               (Tunnel0) Destination: 198.18.63.254
  Status:
    Admin: up         Oper: up     Path: valid       Signalling: connected
 

    path option 1, type dynamic (Basis for Setup, path weight 4)
 
  InLabel  :  - 
  OutLabel : FastEthernet1/0, 18
  RSVP Signalling Info:
       Src 198.18.15.254, Dst 198.18.63.254, Tun_Id 0, Tun_Instance 86
    RSVP Path Info:
      My Address: 198.18.240.0   
      Explicit Route: 198.18.240.1 198.18.240.6 198.18.240.7 198.18.240.12 
                      198.18.240.13 198.18.240.15 198.18.240.14 198.18.63.254 
      Record Route:  NONE
      Tspec: ave rate=30000 kbits, burst=1000 bytes, peak rate=30000 kbits
    RSVP Resv Info:
      Record Route:  NONE
      Fspec: ave rate=30000 kbits, burst=1000 bytes, peak rate=30000 kbits
  Shortest Unconstrained Path Info:
    Path Weight: 3 (TE)
    Explicit Route: 198.18.240.0 198.18.240.1 198.18.240.6 198.18.240.7 
                    198.18.240.10 198.18.240.11 198.18.63.254 
 
R1#traceroute 198.18.63.254 source 198.18.15.254
  1 198.18.240.1 [MPLS: Label 16 Exp 0] 20 msec 40 msec 40 msec
  2 198.18.240.7 [MPLS: Label 27 Exp 0] 80 msec 12 msec 12 msec
  3 198.18.240.13 [MPLS: Label 27 Exp 0] 80 msec 44 msec 40 msec
  4 198.18.240.14 44 msec *  56 msec

On constate que le tunnel est en cours de fonctionnement et que, comme prévu, le chemin suivi n'est pas le plus court mais celui qui respecte la contrainte de capacité : R1<->R2<->R3<->R6<->R4.

Créons notre deuxième tunnel (T1) :

interface Tunnel1
ip unnumbered Loopback1
tunnel destination 198.18.47.254
tunnel mode mpls traffic-eng
tunnel mpls traffic-eng autoroute announce 
tunnel mpls traffic-eng priority 1 1 
tunnel mpls traffic-eng bandwidth 4000 
tunnel mpls traffic-eng path-option 1 dynamic
no routing dynamic

Nous passons le processus et nous regardons directement le résultat sur R1 :

R1#show mpls traffic-eng tunnels Tunnel 1
Name: R1_t1                               (Tunnel1) Destination: 198.18.47.254
  Status:
    Admin: up         Oper: up     Path: valid       Signalling: connected
 
    path option 1, type dynamic (Basis for Setup, path weight 12)
 
  InLabel  :  - 
  OutLabel : FastEthernet2/0, 16
  RSVP Signalling Info:
       Src 198.18.15.254, Dst 198.18.47.254, Tun_Id 1, Tun_Instance 12
    RSVP Path Info:
      My Address: 198.18.240.2   
      Explicit Route: 198.18.240.3 198.18.240.8 198.18.240.9 198.18.240.13 
                      198.18.240.12 198.18.47.254 
      Record Route:  NONE
      Tspec: ave rate=4000 kbits, burst=1000 bytes, peak rate=4000 kbits
    RSVP Resv Info:
      Record Route:  NONE
      Fspec: ave rate=4000 kbits, burst=1000 bytes, peak rate=4000 kbits
  Shortest Unconstrained Path Info:
    Path Weight: 2 (TE)
    Explicit Route: 198.18.240.0 198.18.240.1 198.18.240.6 198.18.240.7 
                    198.18.47.254
R1#traceroute 198.18.47.254 source 198.18.15.254
  1 198.18.240.3 [MPLS: Label 16 Exp 0] 44 msec 8 msec 8 msec
  2 198.18.240.9 [MPLS: Label 28 Exp 0] 8 msec 12 msec 12 msec
  3 198.18.240.12 8 msec *  8 msec

On constate que le tunnel est fonctionnel. Comme il n'y a plus de capacité disponible sur le lien R2<->3 et que l'on n'est pas plus prioritaire que le créateur du tunnel précédent, on passe par le lien R5<->R6 qui, là encore, n'est pas le plus court chemin mais celui qui satisfait notre contrainte de capacité.

Créons notre dernier tunnel :

interface Tunnel2
ip unnumbered Loopback1
tunnel destination 198.18.95.254
tunnel mode mpls traffic-eng
tunnel mpls traffic-eng autoroute announce 
tunnel mpls traffic-eng priority 1 1 
tunnel mpls traffic-eng bandwidth 15000 
tunnel mpls traffic-eng path-option 1 dynamic
no routing dynamic

Regardons le résultat sur R1 :

R1#show mpls traffic-eng tunnels Tunnel 2
Name: R1_t2                               (Tunnel2) Destination: 198.18.95.254
  Status:
    Admin: up         Oper: down   Path: not valid   Signalling: Down
    path option 1, type dynamic
  Config Parameters:
    Bandwidth: 15000    kbps (Global)  Priority: 1  1   Affinity: 0x0/0xFFFF
    Metric Type: TE (default)
    AutoRoute:  enabled   LockDown: disabled  Loadshare: 15000    bw-based
    auto-bw: disabled
  Shortest Unconstrained Path Info:
    Path Weight: 3 (TE)
    Explicit Route: 198.18.240.0 198.18.240.1 198.18.240.6 198.18.240.7 
                    198.18.240.12 198.18.240.13 198.18.95.254 
      Last Error: PCALC:: No path to destination, 198.18.95.254

Le tunnel n'est pas fonctionnel car la contrainte TE n'a pas pu être satisfaite : le lien R2<->R3 est "plein" et nous ne sommes pas plus prioritaires. De plus, la capacité que nous demandons ne peut pas être réservée sur le lien R5<->R6.

Notons qu'au niveau réseau, aucun paquet RSVP-TE n'a été émis. C'est tout à fait logique : en effectuant l'algorithme CSPF, R1 s'est rendu compte qu'aucun chemin respectant la contrainte n'était disponible.

Comme dernier exercice, augmentons la priorité de notre dernier tunnel :

interface Tunnel2
tunnel mpls traffic-eng priority 0 0 
shutdown
no shutdown

Cette fois-ci, notre demande a pu être satisfaite :

R1#show mpls traffic-eng tunnels Tunnel 2
Name: R1_t2                               (Tunnel2) Destination: 198.18.95.254
  Status:
    Admin: up         Oper: up     Path: valid       Signalling: connected
 
    path option 1, type dynamic (Basis for Setup, path weight 3)
 
  Config Parameters:
    Bandwidth: 15000    kbps (Global)  Priority: 0  0   Affinity: 0x0/0xFFFF
    Metric Type: TE (default)
    AutoRoute:  enabled   LockDown: disabled  Loadshare: 15000    bw-based
    auto-bw: disabled

 
  InLabel  :  - 
  OutLabel : FastEthernet1/0, 16
  RSVP Signalling Info:
       Src 198.18.15.254, Dst 198.18.95.254, Tun_Id 2, Tun_Instance 40
    RSVP Path Info:
      My Address: 198.18.240.0   
      Explicit Route: 198.18.240.1 198.18.240.6 198.18.240.7 198.18.240.12 
                      198.18.240.13 198.18.95.254 
      Record Route:  NONE
      Tspec: ave rate=15000 kbits, burst=1000 bytes, peak rate=15000 kbits
    RSVP Resv Info:
      Record Route:  NONE
      Fspec: ave rate=15000 kbits, burst=1000 bytes, peak rate=15000 kbits
  Shortest Unconstrained Path Info:
    Path Weight: 3 (TE)
    Explicit Route: 198.18.240.0 198.18.240.1 198.18.240.6 198.18.240.7 
                    198.18.240.12 198.18.240.13 198.18.95.254

Quelques instants plus tard, notre premier tunnel tombe : réception d'un PDU RSVP-TE PATH ERROR : notre demande n'étant plus la plus prioritaire et en l'absence de liens alternatifs disposant d'une capacité réservable suffisante, il n'est plus possible de réserver 30 mégas sur le lien R2<->R3. Illustration :

R1 reçoit un PDU RSVP-TE PATH ERROR pour notre premier tunnel dont la contrainte ne peut plus être satisfaite

Figure 23 - R1 reçoit un PDU RSVP-TE PATH ERROR pour notre premier tunnel dont la contrainte ne peut plus être satisfaite.

Vérifions sur R1 :

R1#show mpls traffic-eng tunnels Tunnel 0
Name: R1_t0                               (Tunnel0) Destination: 198.18.63.254
  Status:
    Admin: up         Oper: down   Path: not valid   Signalling: Down
    path option 1, type dynamic
  Config Parameters:
    Bandwidth: 30000    kbps (Global)  Priority: 1  1   Affinity: 0x0/0xFFFF
  Shortest Unconstrained Path Info:
    Path Weight: 3 (TE)
    Explicit Route: 198.18.240.0 198.18.240.1 198.18.240.6 198.18.240.7 
                    198.18.240.10 198.18.240.11 198.18.63.254 
    Prior LSP:
      ID: path option 1 [63]
      Removal Trigger: path error

Dès que l'on démonte/"éteint" ce dernier tunnel, le premier tunnel est remonté automatiquement.

Pour terminer, nous voulions faire des demandes de réservation de tunnels depuis plusieurs routeurs, pas seulement depuis R1. Après avoir supprimé le dernier tunnel de R1, nous avons tenté de le faire depuis R5 et avons obtenu le même résultat : sans priorité, on ne passe pas. Avec une priorité plus forte, on passe et le premier tunnel sur R1 tombe.

Bibliographie

Dans l'ordre d'utilisation.

Annexes

Fichier de configuration Dynagen pour tout le TP

[localhost]
    [[7200]]
        image = ./C7200-AD.BIN
        ram = 256
        idlepc = 0x607335f0
 
    [[ROUTER R1]]
        model = 7200
        f1/0 = R2 f1/0
        f2/0 = R5 f1/0
 

    [[ROUTER R2]]
        model = 7200
        f2/0 = R5 f2/0
        f3/0 = R3 f1/0
 
    [[ROUTER R3]]
        model = 7200
        f2/0 = R4 f1/0
        f3/0 = R6 f2/0
 
    [[ROUTER R4]]
        model = 7200
        f2/0 = R6 f3/0
 
    [[ROUTER R5]]
        model = 7200
        f3/0 = R6 f1/0
 
    [[ROUTER R6]]
        model = 7200

Commandes IOS pour tout le TP

R1
enable
conf t
hostname R1
no ip domain lookup
 
int fastEthernet 1/0
ip address 198.18.240.0 255.255.255.254
mpls ip
no shutdown
exit
int fastEthernet 2/0
ip address 198.18.240.2 255.255.255.254
mpls ip
no shutdown
exit
int loopback 1
ip address 198.18.15.254 255.255.240.0
no shutdown
exit
 
router ospf 1
network 198.18.0.0 0.0.255.255 area 0
exit
 
ip cef
mpls label protocol ldp
R2
enable
conf t
hostname R2
no ip domain lookup
 

int fastEthernet 1/0
ip address 198.18.240.1 255.255.255.254
mpls ip
no shutdown
exit
int fastEthernet 2/0
ip address 198.18.240.4 255.255.255.254
mpls ip
no shutdown
exit
int fastEthernet 3/0
ip address 198.18.240.6 255.255.255.254
mpls ip
no shutdown
exit
int loopback 1
ip address 198.18.31.254 255.255.240.0
no shutdown
exit
 
router ospf 1
network 198.18.0.0 0.0.255.255 area 0
exit
 
ip cef
mpls label protocol ldp
R3
enable
conf t
hostname R3
no ip domain lookup
 
int fastEthernet 1/0
ip address 198.18.240.7 255.255.255.254
mpls ip
no shutdown
exit
int fastEthernet 2/0
ip address 198.18.240.10 255.255.255.254
mpls ip
no shutdown
exit
int fastEthernet 3/0
ip address 198.18.240.12 255.255.255.254
mpls ip
no shutdown
exit
int loopback 1
ip address 198.18.47.254 255.255.240.0
no shutdown
exit
 
 
router ospf 1
network 198.18.0.0 0.0.255.255 area 0
exit
 

ip cef
mpls label protocol ldp
R4
enable
conf t
hostname R4
no ip domain lookup
 
int fastEthernet 1/0
ip address 198.18.240.11 255.255.255.254
mpls ip
no shutdown
exit
int fastEthernet 2/0
ip address 198.18.240.14 255.255.255.254
mpls ip
no shutdown
exit
int loopback 1
ip address 198.18.63.254 255.255.240.0
no shutdown
exit
 
router ospf 1
network 198.18.0.0 0.0.255.255 area 0
exit
 
ip cef
mpls label protocol ldp
R5
enable
conf t
hostname R5
no ip domain lookup
 
int fastEthernet 1/0
ip address 198.18.240.3 255.255.255.254
mpls ip
no shutdown
exit
int fastEthernet 2/0
ip address 198.18.240.5 255.255.255.254
mpls ip
no shutdown
exit
int fastEthernet 3/0
bandwidth 10000 !restreindre le lien R5-R6 à 10 mégas
ip address 198.18.240.8 255.255.255.254
mpls ip
no shutdown
exit
int loopback 1
ip address 198.18.79.254 255.255.240.0
no shutdown
exit
 
router ospf 1
network 198.18.0.0 0.0.255.255 area 0
exit
 
ip cef
mpls label protocol ldp
R6
enable
conf t
hostname R6
no ip domain lookup
 
int fastEthernet 1/0
ip address 198.18.240.9 255.255.255.254
bandwidth 10000 !restreindre le lien R5-R6 à 10 mégas
mpls ip
no shutdown
exit
int fastEthernet 2/0
ip address 198.18.240.13 255.255.255.254
mpls ip
no shutdown
exit
int fastEthernet 3/0
ip address 198.18.240.15 255.255.255.254
mpls ip
no shutdown
exit
int loopback 1
ip address 198.18.95.254 255.255.240.0
no shutdown
exit
 

router ospf 1
network 198.18.0.0 0.0.255.255 area 0
exit
 
ip cef
mpls label protocol ldp

Commandes IOS supplémentaires spécifiques à la question 10

R1
en
conf t
mpls traffic-eng tunnels
router ospf 1
mpls traffic-eng router-id Loopback1
mpls traffic-eng area 0
exit
 
interface FastEthernet1/0
mpls ip
mpls traffic-eng tunnels
ip rsvp bandwidth 50000 50000
 
interface FastEthernet2/0
mpls ip
mpls traffic-eng tunnels
ip rsvp bandwidth 60000 60000
exit
exit
R2
en
conf t
mpls traffic-eng tunnels
router ospf 1
mpls traffic-eng router-id Loopback1
mpls traffic-eng area 0
exit
 
interface FastEthernet1/0
mpls ip
mpls traffic-eng tunnels
ip rsvp bandwidth 50000 50000
 
interface FastEthernet2/0
mpls ip
mpls traffic-eng tunnels
ip rsvp bandwidth 70000 70000
 
interface FastEthernet3/0
mpls ip
mpls traffic-eng tunnels
ip rsvp bandwidth 30000 30000
exit
exit
R3
en
conf t
mpls traffic-eng tunnels
router ospf 1
mpls traffic-eng router-id Loopback1
mpls traffic-eng area 0
exit
 

interface FastEthernet1/0
mpls ip
mpls traffic-eng tunnels
ip rsvp bandwidth 30000 30000
 
interface FastEthernet2/0
mpls ip
mpls traffic-eng tunnels
ip rsvp bandwidth 20000 20000
 
interface FastEthernet3/0
mpls ip
mpls traffic-eng tunnels
ip rsvp bandwidth 50000 50000
exit
exit
R4
en
conf t
mpls traffic-eng tunnels
router ospf 1
mpls traffic-eng router-id Loopback1
mpls traffic-eng area 0
exit
 
interface FastEthernet1/0
mpls ip
mpls traffic-eng tunnels
ip rsvp bandwidth 20000 20000
 
interface FastEthernet2/0
mpls ip
mpls traffic-eng tunnels
ip rsvp bandwidth 80000 80000
exit
exit
R5
en
conf t
mpls traffic-eng tunnels
router ospf 1
mpls traffic-eng router-id Loopback1
mpls traffic-eng area 0
exit
 
interface FastEthernet1/0
mpls ip
mpls traffic-eng tunnels
ip rsvp bandwidth 60000 60000
 
interface FastEthernet2/0
mpls ip
mpls traffic-eng tunnels
ip rsvp bandwidth 70000 70000
 
interface FastEthernet3/0
mpls ip
mpls traffic-eng tunnels
ip rsvp bandwidth 7000 7000
exit
exit
R6
en
conf t
mpls traffic-eng tunnels
router ospf 1
mpls traffic-eng router-id Loopback1
mpls traffic-eng area 0
exit
 

interface FastEthernet1/0
mpls ip
mpls traffic-eng tunnels
ip rsvp bandwidth 7000 7000
 
interface FastEthernet2/0
mpls ip
mpls traffic-eng tunnels
ip rsvp bandwidth 50000 50000
 
interface FastEthernet3/0
mpls ip
mpls traffic-eng tunnels
ip rsvp bandwidth 80000 80000
exit
exit

Table des figures

Figure 1 - Schéma de notre maquette. D'après l'énoncé.
Figure 2 - Capture réseau. Ping P4 (198.18.63.254) depuis P1 (198.18.15.254). Aller.
Figure 3 - Capture réseau. Ping P4 (198.18.63.254) depuis P1 (198.18.15.254). Retour.
Figure 4 - On observe que R4 reçoit bien les paquets ICMP exceeded.
Figure 5 - Les différents types de tunnels MPLS en fonction des fonctions supportées/activées. Source : http://www.slideshare.net/edge7/slides-mpls-tunnel.
Figure 6 - Différence de chemin A/R entre un echo request/reply et un ttl-exceeded. Source : http://www.caida.org/publications/papers/2012/revealing_mpls_tunnels/revealing_mpls_tunnels.pdf.
Figure 7 - Quand R1 fait un traceroute vers R4, R2 envoie un ICMP TTL-exceeded avec un TTL de 251.
Figure 8 - Quand R1 fait ping vers 198.18.240.1, on observe un TTL de 255.
Figure 9 - R4 annonce sa nouvelle loopback en OSPF.
Figure 10 - R4 annonce sa nouvelle loopback via LDP.
Figure 11 - Attribution des labels pour la nouvelle loopback : pour transmettre des paquets à destination de la nouvelle loopback, R3 attend qu'ils soient tagués avec le label 26.
Figure 12 - R2 émet un LS UPDATE dans lequel il n'annonce plus avoir un lien avec R1 (absence de 198.18.240.0 et de 198.18.15.254).
Figure 13 - R2 annonce à R3 la disparition de R1 (198.18.240.0) avec un message LDP Withdrawal. R3 annonce la disparition d'un routeur en amont (R1) avec un message LDP Release.
Figure 14 - Schéma de notre maquette avec la capacité réservable sur chaque lien. D'après l'énoncé.
Figure 15 - R1 annonce la capacité du lien R1<->R2 mais indique une capacité réservable nulle.
Figure 16 - Maintenant, R1 annonce aussi la capacité réservable sur le lien R1<->R2.
Figure 17 - R1 fait sa demande de tunnel avec un PDU RSVP-TE de type PATH.
Figure 18 - R2 transmet simplement la demande de tunnel de R1.
Figure 19 - R4 émet un PDU RSVP-TE de type RESV à destination de R6.
Figure 20 - R6 émet un PDU RSVP-TE de type RESV à destination de R3.
Figure 21 - R1 reçoit le PDU RSVP-TE RESV de R2 et sait donc que son tunnel TE est prêt.
Figure 22 - R2 annonce, en OSPF, que plus aucune capacité n'est réservable sur le lien R2<->R3.
Figure 23 - R1 reçoit un PDU RSVP-TE PATH ERROR pour notre premier tunnel dont la contrainte ne peut plus être satisfaite.

TP réseaux d’opérateur I : BGP

Aujourd'hui et dans les jours qui viennent, je vais vous proposer trois travaux pratiques en rapport avec des technologies utilisées par les opérateurs réseaux : BGP, MPLS et L3VPN. Commençons avec BGP.

Même si ces TPs se placent dans un cadre scolaire (« bouh c'est nul, on ne fait pas comme ça en vrai ! » diront certains), j'ai trouvé ces TPs géniaux justement par leur ouverture et parce qu'ils tendent à mettre en exergue les limites auxquelles certaines méthodes utilisables dans un TP seront confrontées « dans la vraie vie ». Ils sont extrêmement formateurs. C'est ce qui m'amène à les partager avec vous accompagnés de mes pistes de réflexion.

Ceux qui aiment bidouiller autour des réseaux devraient tenter de répondre aux questions avant de regarder mes pistes de réflexion. Vous ne devriez pas être déçus.

Table des matières

Énoncé

Créez le fichiez file.net décrivant la configuration d’interconnexion des routeurs :

Topologie plus complexe

Topologie plus complexe.

Lancez Dynagen avec cette configuration.

Il ne reste plus qu’à se connecter sur les routeurs et à les configurer... Lors des expérimentations, gardez les résultats utiles pour le rapport (configurations, résultats de ping, traceroute, tcpdump, etc.).

Exercice 3 : Configuration de base sans politique

  1. Q1. Créez une configuration de 2 AS et 6 routeurs suivant le schéma ci-dessus, les routeurs internes n’utilisant pas BGP, mais un routage IGP interne : OSPF.
  2. Q2. Créez deux préfixes (via loopback) à annoncer sur chaque routeur interne.
  3. Q3. Assurez-vous que le routage interne de chaque AS fonctionne.
  4. Q4. Activez BGP sur les 4 routeurs inter-domaines et vérifiez que les quatre préfixes sont accessibles depuis chaque routeur BGP. Assurez vous notamment que toutes les adresses IP alloués soient joignables et justifiez vos choix d’adressage IP au niveau inter-domaine.
  5. Q5. Déterminez par quelles routes passent les paquets pour chaque sous-réseau. Peut-on observer des routes asymétriques ? Pourquoi ? Comment changer ça ?
  6. Q6. Vérifiez ce qu’il se passe quand l’un des deux liens inter-domaines est coupé (messages BGP, OSPF, ...).
  7. Q7. Même question si l’un des préfixes associés à une interface de loopback est désactivé.
  8. Q8. Reprenez votre configuration avec un des deux AS contenant 4 routeurs avec un découpage en zone. Deux d’entres eux seront dans la zone backbone et les deux autres dans deux zones tierces. Commentez alors l’échange des LSA dans cet AS.

Exercice 4 : Configuration avec politiques de routage BGP

Attention : dans cet exercice, on se considère root uniquement sur l'AS sur lequel porte la question. On ne se considère pas root sur les deux AS en même temps pour tenter de résoudre plus facilement un problème (le trafic entrant d'un AS étant le trafic sortant de l'autre 😉 ).

  1. Q1. L’AS2 souhaite que le trafic provenant de l’AS1 passe de préférence par le lien de gauche, mais en gardant la connectivité en cas de coupure de ce lien. Configurez le routage de l’AS2 à cette fin et vérifiez son bon fonctionnement dans tous les cas. En admettant que l’AS1 soit un AS de transit, la préférence du lien gauche ne devra s’appliquer que pour le trafic issu de l’AS1 lui-même.
  2. Q2. L’AS2 souhaite que le trafic qu’il dirige vers l’AS1 utilise de préférence le lien de droite. Configurez le routage de l’AS2 en conséquence.
  3. Q3. Pour le trafic sortant de l’AS2, peut-on préférer le lien de droite uniquement pour le trafic destiné à l’AS1 lui-même (ou réciproquement uniquement pour le trafic transitant par l’AS1) ? Si oui, comment (donnez les configurations requises) ?
  4. Q4. Configurez 3 préfixes dans l’AS1 (P1, P2, P3) et implantez la politique de l’AS2 : P1 doit être accessible de préférence via le lien gauche, le préfixe P2 de préférence via le lien droit, et P3 uniquement par le lien droit. Testez dans tous les cas.
  5. Q5. Reprendre la question 1 en utilisant la technique de l’AS prepending.
  6. Q6. Reprendre la question 2 en utilisant l’attribut community.
  7. Q7. Reprendre le TP en utilisant 2 PC (1 par AS) en faisant communiquer les dynamips des 2 PC.

Cet énoncé est extrait de celui de Jean-Jacques Pansiot et Pascal Mérindol de l'université de Strasbourg.

Pour ceux qui préfèrent lire un si gros pavé en PDF : TP réseaux d'opérateur I : BGP. Et comme à chaque fois, les sources LaTeX sont disponibles ici : sources LaTeX.

Avant de commencer

Adressage

ASN

En ce qui concerne les numéros d'AS, j'ai décidé d'en choisir deux parmi la plage d'ASN réservés à l'IANA pour la documentation : 64496-64511,65536-65551.

  • AS 1 devient AS 64501
  • AS 2 devient AS 64502
IPv4

Concernant l'adressage IP, j'ai décidé de choisir mes préfixes dans le préfixe réservé à l'IANA pour les tests : 198.18.0.0/15. Ayant deux réseaux à adresser, il m'a paru naturel de découper ce préfixe /15 en deux préfixes /16 de telle sorte de pouvoir attribuer un préfixe /16 à chacun de mes deux AS.

  • AS 64501 reçoit l'allocation 198.18.0.0/16
  • AS 64502 reçoit l'allocation 198.19.0.0/16

J'ai ensuite décidé que chacun de mes AS va découper son allocation en plusieurs préfixes de longueur /20 :

  1. Le premier /20 est dédié aux services que l'AS met à disposition du public.
  2. Le milieu est réservé pour un usage futur (expansion des services, expansion des interconnexions, ...).
  3. L'avant-dernier /20 est dédié aux interconnexions des routeurs internes. Il sera découpé en /31, chaque /31 étant dédié à une interconnexion.
  4. Le dernier /20 est dédié aux interconnexions externes (inter-AS). Il sera découpé en /31, chaque /31 étant dédié à une interconnexion.

Je ne prévois pas que mes AS aient plus de 2048 interconnexions externes ni plus 2048 interconnexions internes mais si c'était le cas, on prendrait des préfixes dans le milieu en suivant la même logique : avant-dernier préfixe pris pour les interconnexions internes, dernier préfixe pour les interconnexions externes.

Les interconnexions se font en /31 car les IPv4 sont rares et il faut donc les économiser. Même si j'utilise un préfixe de documentation/test, je fais ce choix car, d'après mes renseignements, il s'agit d'une BCP donc pourquoi ne pas s'y conformer, même sur une maquette ? De plus, cela amène des avantages (pas de broadcast, ...).

En pratique, pour l'AS 64501, ce découpage donnera :

  1. 198.18.0.0/20 - Services.
  2. 198.18.16-208.0/20 - Réservés pour un usage futur.
  3. 198.18.224.0/20 - Interconnexions internes.
  4. 198.18.240.0/20 - Interconnexions inter-AS.

Le découpage est similaire pour l'AS 64502, seul le deuxième octet des préfixes change.

Schéma

Voici le schéma donné dans l'énoncé complété avec mon plan d'adressage :

Schéma de ma maquette

Figure 1 - Schéma de ma maquette. D'après l'énoncé.

Note : les sorties des commandes de vérification (show ...) seront allégées pour ne garder que l'essentiel afin de ne pas surcharger ce rapport.

Exercice 3

Questions 1 et 2

Voir en annexe la liste des commandes néccesaires à la réalisation de ces questions.

Question 3

D'abord, on observe que les routeurs se redistribuent bien les routes dont ils ont connaissance via OSPF. Exemple :

Ici, on voit IR2, dont le démon OSPF vient de démarrer, s'initialiser et annoncer les routes qu'il connaît

Figure 2 - Ici, on voit IR2, dont le démon OSPF vient de démarrer, s'initialiser et annoncer les routes qu'il connaît.

Ensuite, sur les trois routeurs de chaque AS, on observe que les tables de routage se sont construites. Par exemple, sur ASBR3 :

ASBR3#show ip route
     198.18.224.0/31 is subnetted, 2 subnets
O       198.18.224.0 [110/2] via 198.18.224.2, 00:00:00, FastEthernet1/0
C       198.18.224.2 is directly connected, FastEthernet1/0
     198.19.240.0/31 is subnetted, 1 subnets
C       198.19.240.0 is directly connected, FastEthernet2/0
     198.18.240.0/31 is subnetted, 1 subnets
O       198.18.240.0 [110/3] via 198.18.224.2, 00:00:00, FastEthernet1/0
     198.18.15.0/32 is subnetted, 1 subnets
O       198.18.15.254 [110/2] via 198.18.224.2, 00:00:00, FastEthernet1/0

Enfin, en utilisant la commande ping, on arrive à la même conclusion : toutes les adresses IP attribuées au sein de l'AS 64501 sont joignables depuis n'importe quel routeur de l'AS. Exemple depuis ASBR1 :

ASBR3#show ip route
     198.18.224.0/31 is subnetted, 2 subnets
O       198.18.224.0 [110/2] via 198.18.224.2, 00:00:00, FastEthernet1/0
C       198.18.224.2 is directly connected, FastEthernet1/0
     198.19.240.0/31 is subnetted, 1 subnets
C       198.19.240.0 is directly connected, FastEthernet2/0
     198.18.240.0/31 is subnetted, 1 subnets
O       198.18.240.0 [110/3] via 198.18.224.2, 00:00:00, FastEthernet1/0
     198.18.15.0/32 is subnetted, 1 subnets
O       198.18.15.254 [110/2] via 198.18.224.2, 00:00:00, FastEthernet1/0

Il en va de même dans l'AS 64502. Nous n'allons pas recommencer toute la démonstration et nous allons donc simplement afficher la table de routage d'ASBR4 :

ASBR4#show ip route
     198.19.224.0/31 is subnetted, 2 subnets
C       198.19.224.0 is directly connected, FastEthernet2/0
O       198.19.224.2 [110/2] via 198.19.224.1, 01:45:51, FastEthernet2/0
     198.19.240.0/31 is subnetted, 1 subnets
O       198.19.240.0 [110/3] via 198.19.224.1, 01:45:51, FastEthernet2/0
     198.18.240.0/31 is subnetted, 1 subnets
C       198.18.240.0 is directly connected, FastEthernet1/0
     198.19.15.0/32 is subnetted, 1 subnets
O       198.19.15.254 [110/2] via 198.19.224.1, 01:45:51, FastEthernet2/0

Question 4

Plusieurs méthodes sont à notre disposition pour redistribuer nos préfixes dans BGP, parmi lesquelles :

  • Annoncer uniquement les préfixes réellement utilisés (pour chaque AS : trois /31 + la loopback).
  • Annoncer toute notre allocation (un /16 par AS).

J'ai choisi d'annoncer toute l'allocation de chaque AS : l'AS 64501 annoncera 198.18.0.0/16 et l'AS 64502 annoncera 198.19.0.0/16.

D'une part, c'est totalement légitime (un /16 a été attribué, pourquoi ne pas l'annoncer dans sa globalité ?). Si des préfixes entiers sont non utilisés, c'est un problème de routage interne qui est à l'entière discrétion de notre AS, pas à celle des autres AS. D'autre part, cela évite l'encombrement de nos tables de routage (une entrée, le /16 au lieu de quatre, les 3 * /31 + loopback).

Pour qu'un routeur Cisco accepte d'émettre une annonce BGP pour une route, il faut avoir une entrée correspondante dans la table de routage. Pour cela, j'utilise une interface Null. Lorsque l'on fera communiquer nos routeurs entre eux, si les routeurs de bordure connaissent une route plus spécifique (via OSPF), ils transmettront les paquets. Sinon, les paquets finiront chez Dave Null et l'émetteur recevra un ICMP Destination Unreachable.

Pour que toutes les adresses IP soient joignables depuis n'importe quel routeur, et notamment pour que les routeurs internes puissent joindre les machines de l'autre AS, il convient de faire de la redistribution BGP dans OSPF.

Concernant les préfixes d'interconnexion : dans la vraie vie, dans le cadre d'un GIX, le préfixe d'interconnexion est fourni par le GIX lui-même.

Dans le cadre d'un accord transitaire-client, le transitaire fournit généralement le préfixe d'interconnexion (/30 ou /31 ).

Dans le cadre d'une interconnexion privée, les parties se mettent d'accord sur l'adressage.

Dans notre cas, on considérera que les AS se sont mis d'accord pour fournir, chacun, un des deux préfixes d'interconnexion dans leur allocation respective.

Voir les annexes pour les commandes basiques nécessaires à la mise en place de BGP.

D'abord, on observe que les routeurs de bordure se redistribuent bien leurs préfixes respectifs via BGP. Exemple :

Ici, on voit ASBR6, dont le démon BGP vient de démarrer, initialiser une session BGP avec ASBR3 (TCP handshake + PDU BGP OPEN). Puis vient l'échange des préfixes (PDU BGP UPDATE)

Figure 3 - Ici, on voit ASBR6, dont le démon BGP vient de démarrer, initialiser une session BGP avec ASBR3 (TCP handshake + PDU BGP OPEN). Puis vient l'échange des préfixes (PDU BGP UPDATE).

Ensuite, on observe que les tables de routage se sont construites. Par exemple, sur ASBR3 :

ASBR3>show ip route
B    198.19.0.0/16 [20/0] via 198.19.240.0, 00:04:32
S    198.18.0.0/16 is directly connected, Null0

Ou bien encore sur ASBR4 :

ASBR4#show ip route
S    198.19.0.0/16 is directly connected, Null0
B    198.18.0.0/16 [20/0] via 198.18.240.0, 02:41:16

Enfin, en utilisant la commande ping, on arrive à la conclusion que toutes les adresses IP attribuées sont joignables. Illustration depuis IR5 :

IR5>ping 198.19.224.0
Success rate is 100 percent (5/5), round-trip min/avg/max = 8/8/8 ms
 
IR5>ping 198.19.224.3
Success rate is 100 percent (5/5), round-trip min/avg/max = 8/8/12 ms
 
IR5>ping 198.19.240.0
Success rate is 100 percent (5/5), round-trip min/avg/max = 4/15/32 ms
 
IR5>ping 198.19.240.1
Success rate is 100 percent (5/5), round-trip min/avg/max = 8/12/28 ms
 
IR5>ping 198.18.240.1
Success rate is 100 percent (5/5), round-trip min/avg/max = 8/8/8 ms
 
IR5>ping 198.18.240.0
Success rate is 100 percent (5/5), round-trip min/avg/max = 8/12/28 ms
 
IR5>ping 198.18.224.0
Success rate is 100 percent (5/5), round-trip min/avg/max = 8/12/20 ms
 
IR5>ping 198.18.224.1
Success rate is 100 percent (5/5), round-trip min/avg/max = 12/15/28 ms
 
IR5>ping 198.18.224.2
Success rate is 100 percent (5/5), round-trip min/avg/max = 8/15/28 ms
 
IR5>ping 198.18.224.3
Success rate is 100 percent (5/5), round-trip min/avg/max = 8/10/16 ms
 
IR5>ping 198.18.15.254
Success rate is 100 percent (5/5), round-trip min/avg/max = 12/13/20 ms

Question 5

Les routes empruntées ne dépendent pas que du sous-préfixe de destination mais aussi de la machine émettrice et des calculs de l'IGP, comme nous allons le voir.

Oui, on peut observer des chemins asymétriques :

  • Entre les routeurs de la même diagonale, c'est-à-dire entre ASBR1 et ASBR6 ou entre ASBR3 et ASBR4.
  • En fonction des chemins sélectionnés par l'IGP, ici OSPF, les routeurs internes peuvent aussi avoir des chemins asymétriques pour les routeurs de l'autre AS.

Une petite illustration de l'asymétrie entre ASBR1 et ASBR6 : que se passe-t-il si ASBR1 veut pinguer ASBR6 ?

ASBR1#show ip route
B    198.19.0.0/16 [20/0] via 198.18.240.1, 01:15:43

Donc le paquet sera transmis à 198.18.18.240.1 (ASBR4) qui le transmettra à IR2 puis à ASBR6.

Pour le retour maintenant :

ASBR6#show ip route
B    198.18.0.0/16 [20/0] via 198.19.240.1, 01:16:35

Donc la réponse sera envoyée à ASBR3, pas à ASBR4.

Cela se vérifie avec deux captures réseau : l'une sur l'interface f1/0 d'ASBR1, l'autre sur l'interface f2/0 d'ASBR1. Lors d'un ping 198.19.224.3 (f1/0 ASBR6) depuis ASBR1 :

ether.src : ca:00:53:1e:00:38 (f2/0 de ASBR1) -> ether.dst = ca:03:53:1e:00:1c (f1/0 de ASBR4).

Figure 4 - ether.src : ca:00:53:1e:00:38 (f2/0 de ASBR1) -> ether.dst = ca:03:53:1e:00:1c (f1/0 de ASBR4).

ether.src = ca:01:53:1e:00:1c (f1/0 d'IR2) -> ether.dst = ca:00:53:1e:00:1c (f1/0 d'ASBR1)

Figure 5 - ether.src = ca:01:53:1e:00:1c (f1/0 d'IR2) -> ether.dst = ca:00:53:1e:00:1c (f1/0 d'ASBR1).

Ce comportement est tout à fait normal et s'explique par la politique dite de la patate chaude : on cherche à faire sortir de notre réseau, le plus tôt possible, un paquet destiné à un autre réseau. Ceci est la politique par défaut de BGP car elle nous protège contre un AS malveillant. Si l'on applique la politique de la patate froide mais que l'AS "d'en face" suit la politique de la patate chaude, on se retrouve à acheminer l'aller et le retour par notre réseau. Si l'on suit la politique de la patate chaude, quoi que fasse l'AS "d'en face", patate chaude (on est à égalité, chacun a acheminé une partie de la communication) ou patate froide (on est gagnant, l'AS "d'en face" a tout acheminé sur son réseau), on n'est jamais perdant. La patate chaude permet une certaine justice. Sauf dans le cas de trafic asymétrique mais ce n'est pas le sujet.

Il est parfois utile de convenir, avec son(ses) transitaire(s), d'un routage en patate froide. Cela peut servir à faire de l'ingénierie de trafic. Exemples : faire privilégier un chemin plus direct, moins couteux ou plus rapide.

On peut donc changer le comportement du routage en jouant sur la politique de routage : utiliser l'attribut MED, utiliser la méthode de l'AS-Prepending, faire en sorte que notre préfixe ne soit annoncé que depuis un transitaire à la fois et garder l'autre transitaire en sauvegarde, ...

Question 6

En théorie, quand un lien inter-domaine tombe, BGP s'en rend compte (à cause de l'absence de messages KEEPALIVE et des ACK TCP associés) et la session tombe totalement après le délai "hold-time" (180 secondes par défaut sur les Cisco). L'IGP, OSPF dans notre cas, recalculera les chemins disponibles et le trafic inter-domaine sera redirigé vers le lien inter-domaine restant.

Pour mettre ça en pratique, nous allons éteindre l'interface f1/0 d'ASBR4.

Dans un premier temps, les messages KEEPALIVE d'ASBR1 ne sont pas acquittés par ASBR4 donc sa pile TCP les réémet :

Les PDU KEEPALIVE d'ASBR1 ne sont pas acquittés par ASBR4 donc sa pile TCP les réémet

Figure 6 - Les PDU KEEPALIVE d'ASBR1 ne sont pas acquittés par ASBR4 donc sa pile TCP les réémet.

Comme la situation ne se rétablit pas avant l'expiration du délai "hold-time", ASBR1 abandonne la session BGP :

%BGP-5-ADJCHANGE: neighbor 198.18.240.1 Down BGP Notification sent
%BGP-3-NOTIFICATION: sent to neighbor 198.18.240.1 4/0 (hold time expired)

ASBR1 indique aux autres routeurs de l'AS 64501, via OSPF, qu'il a perdu la connectivité pour 198.19.0.0/16.

ASBR1 perd la connectivité vers 198.19.0.0/16 : la métrique explose puis la route ne sera plus annoncée via OSPF

Figure 7 - ASBR1 perd la connectivité vers 198.19.0.0/16 : la métrique explose puis la route ne sera plus annoncée via OSPF.

ASBR1 choisit donc la route qu'IR2 lui annonce pour joindre 198.19.0.0/16 : IR2 -> ASBR3 -> ASBR6

IR2 annonce à ASBR1 la route qu'il connaît pour joindre 198.19.0.0/16 : IR2 -> ASBR3 -> ASBR6

Figure 8 - IR2 annonce à ASBR1 la route qu'il connaît pour joindre 198.19.0.0/16 : IR2 -> ASBR3 -> ASBR6.

On constate que les tables de routage d'ASBR1 et d'ASBR4 se sont mises à jour :

ASBR1#show ip route 
O E2 198.19.0.0/16 [110/1] via 198.18.224.1, 00:00:50, FastEthernet1/0
 
ASBR4#show ip route
O E2 198.18.0.0/16 [110/1] via 198.19.224.1, 00:04:53, FastEthernet2/0

Question 7

En théorie, quand l'une des loopback sera désactivée, l'annonce OSPF du routeur interne contiendra une annonce de moins. Les autres routeurs de l'AS seront informés, par OSPF, du fait que le préfixe associé à la loopback n'est plus joignable. Rien ne se passera au niveau de BGP : l'annonce porte sur le sur-réseau /16. Il y aurait eu des UPDATE BGP si j'avais choisi d'annoncer uniquement les préfixes réellement attribués.

Pour la mise en pratique, on va éteindre l'interface loopback 1 d'IR2. La table de routage d'IR2 se met à jour puis IR2 n'annonce plus le préfixe de la loopback via OSPF.

IR2 n'annonce plus sa loopback en OSPF

Figure 9 - IR2 n'annonce plus sa loopback en OSPF.

Les autres routeurs de l'AS (ASBR1 et ASBR3) mettent à jour leur table de routage. Si un routeur de l'AS 64502 essaye de joindre le préfixe de la loopback, il recevra un message ICMP Destination Unreachable de la part d'un des routeurs de bordures de l'AS 64501. Exemple :

ASBR6 tente de pinger la loopback 1 d'IR2. ASBR3, auquel ASBR6 a envoyé le paquet, ne connaît aucune route pour aller à cette adresse donc il émet un ICMP dst unreachable

Figure 10 - ASBR6 tente de pinger la loopback 1 d'IR2. ASBR3, auquel ASBR6 a envoyé le paquet, ne connaît aucune route pour aller à cette adresse donc il émet un ICMP dst unreachable.

Quand on remonte l'interface loopback, IR2 l'annonce à nouveau en OSPF et tout rentre dans l'ordre.

IR2 annonce, à nouveau, sa loopback via OSPF

Figure 11 - IR2 annonce, à nouveau, sa loopback via OSPF.

Question 8

J'ai choisi d'adapter mon AS 64501. Voici un schéma qui représente la nouvelle configuration interne de cet AS :

Schéma de la nouvelle configuration interne de l'AS 64501

Figure 12 - Schéma de la nouvelle configuration interne de l'AS 64501.

Comme toujours, il y a plusieurs topologies qui répondent à l'énoncé. J'ai choisi celle-ci car elle me paraît intelligible : il est évident qu'ASBR1 et ASBR3 forment la dorsale de l'AS 64501 puisqu'ils ont la connectivité vers l'extérieur. IR2 et IR7 ne sont que des routeurs "secondaires" de l'AS. C'est pour cette raison que je les ai mis dans des zones OSPF différentes.

Les commandes de configuration nécessaires sont présentées en annexe.

Regardons l'une des tables de routage, celle d'ASBR1, par exemple :

ASBR1#show ip route
     198.18.224.0/31 is subnetted, 3 subnets
O IA    198.18.224.4 [110/2] via 198.18.224.1, 00:23:29, FastEthernet1/0
C       198.18.224.0 is directly connected, FastEthernet1/0
C       198.18.224.2 is directly connected, FastEthernet3/0
     198.18.31.0/32 is subnetted, 1 subnets
O IA    198.18.31.254 [110/3] via 198.18.224.1, 00:23:24, FastEthernet1/0
     198.18.240.0/31 is subnetted, 1 subnets
C       198.18.240.0 is directly connected, FastEthernet2/0
     198.18.15.0/32 is subnetted, 1 subnets
O       198.18.15.254 [110/2] via 198.18.224.3, 00:23:41, FastEthernet3/0

La commande ping nous permet de vérifier que tout notre routage, interne et inter-AS, fonctionne :

IR2#ping 198.18.224.2
Success rate is 100 percent (5/5), round-trip min/avg/max = 8/16/36 ms
 
IR2#ping 198.18.224.0
Success rate is 100 percent (5/5), round-trip min/avg/max = 8/20/36 ms
 
IR2#ping 198.18.224.1
Success rate is 100 percent (5/5), round-trip min/avg/max = 8/12/24 ms
 
IR2#ping 198.18.224.4
Success rate is 100 percent (5/5), round-trip min/avg/max = 8/13/28 ms
 
IR2#ping 198.18.224.5
Success rate is 100 percent (5/5), round-trip min/avg/max = 12/17/28 ms
 
IR2#ping 198.18.31.254
Success rate is 100 percent (5/5), round-trip min/avg/max = 8/12/24 ms
 
IR2#ping 198.18.240.0
Success rate is 100 percent (5/5), round-trip min/avg/max = 8/10/20 ms
 
IR2#ping 198.18.240.1
Success rate is 100 percent (5/5), round-trip min/avg/max = 12/17/40 ms
 
IR2#ping 198.19.224.0
Success rate is 100 percent (5/5), round-trip min/avg/max = 8/12/24 ms
 
IR2#ping 198.19.224.1
Success rate is 100 percent (5/5), round-trip min/avg/max = 8/12/16 ms
 
IR2#ping 198.19.224.2
Success rate is 100 percent (5/5), round-trip min/avg/max = 12/14/24 ms
 
IR2#ping 198.19.224.3
Success rate is 100 percent (5/5), round-trip min/avg/max = 12/18/24 ms
 
IR2#ping 198.19.240.0
Success rate is 100 percent (5/5), round-trip min/avg/max = 8/18/32 ms
 
IR2#ping 198.19.240.1
Success rate is 100 percent (5/5), round-trip min/avg/max = 8/16/24 ms

En ce qui concerne, les échanges des LSA, on remarque que, à l'intérieur de chaque aire, rien n'a changé : on a toujours les types de LSA 1 (router), 2 (network) et 5 (external). Mais maintenant, ASBR1 et ASBR3 portent pleinement leurs noms : ils sont à la fois des routeurs de la dorsale (backbone), des routeurs inter-aires (ABR) et des routeurs qui injectent des routes externes (ASBR). On a donc des échanges supplémentaires : les échanges inter-aires (3-summary ; 4-interarea summary), assurés par ASBR1 et ASBR3.

Au niveau OSPF, ASBR1 et ASBR3 maintiennent une base des données topologiques des aires auxquelles ils appartiennent (ASBR 1 : aire 0 et 1 ; ASBR2 : aire 0 et 2). De plus, comme ils sont aussi des routeurs de la dorsale, ils redistribueront les informations de la topologie aux autres aires (1 et 2). Pour les deux autres routeurs, le fonctionnement est identique à celui que nous avions avant.

Quelques captures qui présentent les échanges inter-aires :

ASBR3 annonce, dans l'aire 0, les routes de l'aire 2

Figure 13 - ASBR3 annonce, dans l'aire 0, les routes de l'aire 2.

Quelques secondes plus tard, ASBR1 redistribue les routes de l'aire 2 dans l'aire 1

Figure 14 - Quelques secondes plus tard, ASBR1 redistribue les routes de l'aire 2 dans l'aire 1.

Exercice 4

Avant de commencer

Avant de commencer cet exercice, on établit des sessions iBGP entre tous les routeurs de bordure d'un même AS (ASBR1<->ASBR3 ; ASBR4<->ASBR6) afin qu'ils s'échangent les meilleures routes et s'accordent sur les valeurs associées (métrique, préférence locale, ...). Cela se fait simplement en utilisant la commande habituelle « neighbor » mais avec notre numéro d'AS. Exemple, sur ASBR1 :

router bgp 64501
        neighbor 198.18.224.3 remote-as 64501

De plus, la commande suivante permet d'appliquer les modifications (route-map, ...) plus rapidement :

clear ip bgp <*|ASN> all

Pour cet exercice, la configuration de Dynagen est la même que celle utilisée pour l'exercice 3 hors aires OSPF. La configuration des routeurs est aussi celle de l'exercice 3 hors aires OSPF. Ces deux configurations sont disponibles en annexes.

Sauf mention contraire, j'ai considéré que les questions étaient indépendantes et je reviens donc à la configuration "de base" (celle de l'exercice 3 hors aires OSPF + iBGP présenté ci-dessus) entre chaque question.

Question 1

Pour tenter de contrôler le lien par lequel les flux entrent dans notre AS, nous avons plusieurs outils à notre disposition :

  • L'attribut Multi-Exit Discriminator
  • La méthode de l'AS prepending
  • Les communautés
  • Subnetter l'allocation, annoncer des préfixes plus précis et ainsi pouvoir définir des comportements plus précis pour les flux entrants dans notre AS.

Comme l'AS prepending sera demandé à la question 7 et que la dernière méthode est à utiliser en dernier ressort seulement (inflation de la table de routage globale), j'ai choisi d'utiliser l'attribut MED qui est prévu pour privilégier, de manière propre, un lien parmi plusieurs disponibles (possiblement géographiquement répartis) entre deux AS.

Par défaut, sur Cisco, la métrique est de 0 et elle est considérée comme étant la meilleure. Donc, si ASBR6 annonce, à ASBR3, une métrique de 10 pour 198.19.0.0/16, tout le trafic à destination de l'AS 64502 sera redirigé vers le lien de gauche. Cela se fait avec les commandes suivantes :

neighbor 198.19.240.1 route-map setmed out
 
route-map setmed permit 10
        set metric 10

On constate que les tables de routage se mettent à jour en conséquence. Ici, sur IR2 :

IR2#show ip route
O E2 198.19.0.0/16 [110/1] via 198.18.224.0, 00:03:13, FastEthernet1/0

Ou encore sur ASBR3 :

ASBR3#show ip route
O E2 198.19.0.0/16 [110/1] via 198.18.224.2, 00:03:41, FastEthernet1/0

Pour pouvoir tester ma configuration concernant la deuxième partie de la question, faire en sorte que la préférence du lien de gauche ne s'applique qu'au trafic issu de l'AS 64501 lui-même, je rajoute un AS 64503 à ma maquette. Le préfixe qu'il annonce est 10.0.0.0/8. Cet AS est composé de deux routeurs, ASBR7 et ASBR8 qui communiquent entre eux en iBGP. ASBR7 est raccordé à ASBR1 et ASBR8 est raccordé à ASBR3.

On constate que, lorsque ASBR7 veut joindre 198.19.0.0/16 (AS 64502), il passe par ASBR1 puis par le lien de gauche. En revanche, quand ASBR8 veut faire la même chose, il passe par ASBR3. Mais, à cause de la modification de la MED, ASBR3 envoie tout à ASBR1 et tout passe par le lien de gauche alors que le lien de droite serait mieux dans le cas présent.

Le comportement est logique et résulte de notre modification. On se rend compte que le problème est "local" à ASBR3, et qu'il est dépendant de la manière dont sa table de routage est construite.

Il n'est pas possible de répondre à cette contrainte sans intervenir sur l'AS 64501. On peut influencer le trafic entrant dans notre AS mais on ne peut pas le différencier en fonction de son origine "présumée" pour ensuite influencer son entrée dans notre AS depuis l'AS 64502 car aucun outil purement BGP ne permet de le faire. En effet, les route-map et autres outils de capture d'éléments dont j'ai connaissance permettent de prendre des décisions et d'agir uniquement sur les annonces BGP envoyées/reçues par l'AS lui-même, pas sur des paramètres connus seulement par un autre AS. Une "condition" du type "bon, AS1, si le trafic vient de toi, MED = 10, sinon MED = 0", envoyée par AS 64502, n'est pas possible car on ne peut pas matcher l'inconnu et car il y a une dualité à exprimer.

Même si l'on avait le contrôle de l'AS 64501, imposer cette contrainte me paraît extrêmement difficile en utilisant les outils purement BGP (pas de MPLS, ...) car cela signifie qu'il faut modifier la table de routage "à la demande", en temps réel : si le trafic vient d'un autre AS et s'il est à destination de l'AS 64502, il faut router sur le lien de droite mais le reste du temps, la table de routage doit contenir une entrée pour router via ASBR1.

J'ai quand même pensé à plusieurs solutions basées sur l'attribut MED, sur la préférence locale et sur la communauté no-advertise (entre ASBR1 et ASBR3) mais toutes échoueront en théorie (à cause de la distribution OSPF, à cause du manque de redondance si un lien tombe, ...) donc je ne les ai pas mises en pratique.

Question 2

Pour influencer les flux sortants de notre AS, plusieurs outils sont à notre disposition :

  • L'attribut local-preference
  • Les communautés
  • Jouer sur les poids des métriques dans l'IGP

J'ai choisi d'utiliser la manière de faire la plus courante et la plus facile d'utilisation : définir la préférence locale. En définissant une préférence locale plus faible sur ASBR4, le trafic sortant sera dirigé vers ASBR6.

On peut redéfinir la valeur par défaut de la préférence locale sur ASBR4 :

router bgp 64502
        bgp default local-preference 90

Ainsi, on a le choix entre une route avec une préférence locale de 90 propagée par ASBR4 et une route avec une préférence locale de 100 (par défaut) propagée par ASBR6. ASBR6 sera choisi comme routeur de sortie de l'AS 64502 pour toutes les destinations annoncées ou relayées par l'AS 64501.

Table de routage avant/après sur ASBR4 :

ASBR4#show ip bgp
*> 198.18.0.0/16    198.18.240.0             0             0 64501 i
* i                 198.19.240.1             0    100      0 64501 i
*> 198.19.0.0/16    0.0.0.0                  0         32768 i
* i                 198.19.224.3             0    100      0 i
 
----
 
r  198.18.0.0/16    198.18.240.0             0             0 64501 i
r>i                 198.19.240.1             0    100      0 64501 i
*> 198.19.0.0/16    0.0.0.0                  0         32768 i
* i                 198.19.224.3             0    100      0 i

ASBR4#show ip route
O E2 198.18.0.0/16 [110/1] via 198.19.224.1, 00:07:47, FastEthernet2/0
 
----
 
ASBR4#traceroute 198.18.224.0
  1 198.19.224.1 8 msec 4 msec 4 msec
  2 198.19.224.3 12 msec 12 msec 12 msec
  3 198.19.240.1 16 msec 16 msec 16 msec
  4 198.18.224.2 12 msec 12 msec 16 msec
  5 198.18.224.0 16 msec *  24 msec

On constate qu'IR5 aussi passera par ASBR6 pour joindre 198.18.0.0/16 :

IR5#show ip route
O E2 198.18.0.0/16 [110/1] via 198.19.224.3, 00:07:11, FastEthernet2/0

On notera que, pour obtenir le même résultat, on aurait aussi pu créer, sur ASBR4, une route-map contenant un « set local-preference 90 » sans filtrer les préfixes auxquels elle s'applique que l'on appliquerait sur les préfixes en provenance de ASBR1.

Question 3

Pour utiliser le lien de droite uniquement pour le trafic sortant vers l'AS 64501 lui-même, il suffit de reprendre le raisonnement de la question précédente mais en appliquant la préférence locale uniquement à l'AS 64501 et à ses préfixes.

Pour se faire, on utilise les commandes suivantes sur ASBR4 :

ip prefix-list as64501 permit 198.18.0.0/16
 
route-map liendroite permit 10
        match ip address prefix-list as64501
        set local-preference 90
 
route-map liendroite permit 20
        set local-preference 110  !pour attirer le trafic pour 10.0.0.0/8, pas obligatoire.
 
router bgp 64502
        neighbor 198.18.240.0 route-map liendroite in

Pour éviter des mises à jour fastidieuses dans le cas où l'AS 64501 aurait de nouveaux préfixes, on peut aussi faire une sélection basée sur le chemin d'AS :

ip as-path access-list 1 permit ^64501$ ! AS-PATH contient uniquement 64501
 
route-map liendroite permit 10
        match as-path 1
        set local-preference 90
 
route-map liendroite permit 20
        set local-preference 110  !pour attirer le trafic pour 10.0.0.0/8, pas obligatoire.
 
router bgp 64502
        neighbor 198.18.240.0 route-map liendroite in

Pour tester, on reprend notre configuration avec trois AS et huit routeurs présentée à la question 1 et l'on regarde les tables de routage :

ASBR4#show ip route
B    10.0.0.0/8 [20/0] via 198.18.240.0, 00:01:17
O E2 198.18.0.0/16 [110/1] via 198.19.224.1, 00:04:53, FastEthernet2/0
 
----
 
IR5#show ip route
O E2 10.0.0.0/8 [110/1] via 198.19.224.0, 00:01:41, FastEthernet1/0
O E2 198.18.0.0/16 [110/1] via 198.19.224.3, 00:05:17, FastEthernet2/0
 
----
 
ASBR6#show ip route
O E2 10.0.0.0/8 [110/1] via 198.19.224.2, 00:01:56, FastEthernet1/0
B    198.18.0.0/16 [20/0] via 198.19.240.1, 00:50:13

Les traceroute pour 198.18.0.0/16 donnent les mêmes résultats qu'à la question précédente. Voici pour 10.0.0.0/8 :

ASBR4#traceroute 10.0.0.1 
  1 198.18.240.0 24 msec 8 msec 4 msec
  2 198.18.240.3 32 msec 12 msec 12 msec

Question 4

Voici la correspondance entre les préfixes et leur nom dans l'énoncé :

  • P1 : 198.18.15.254/32
  • P2 : 198.18.31.254/32
  • P3 : 198.18.47.254/32

Ces préfixes seront attribués à des interfaces loopback sur IR2. P1 est déjà attribué à la loopback 1. Pour les autres préfixes :

int loopback 2
	ip address 198.18.31.254 255.255.240.0
 
int loopback 3
	ip address 198.18.47.254 255.255.240.0

Il y a au moins deux manières d'aborder le problème :

  1. Si l'AS d'origine diffuse des préfixes plus spécifiques pour certains de ses services, il suffit d'utiliser une route-map et d'appliquer une préférence locale pour diriger le trafic sortant sur le lien qui nous convient. Dans la vraie vie, d'après mes informations, l'annonce de préfixes plus spécifiques semble être courante pour les gros services. Exemple : Youtube est dans un /24. Cela permet donc de différencier le trafic à destination de Google Search de celui à destination de Youtube.
  2. Si l'AS d'origine ne diffuse pas des préfixes plus spécifiques, il faut alors se débrouiller en local pour désagréger l'annonce plus générale à l'aide de routes statiques, d'annonces conditionnelles et d'autres joyeusetés.

Dans un premier temps, seule la première solution était réellement fonctionnelle dans ma maquette. Voici la configuration que j'utilisais :

ASBR1#network 198.18.15.254 mask 255.255.255.255
ASBR1#network 198.18.31.254 mask 255.255.255.255
 
ASBR3#network 198.18.15.254 mask 255.255.255.255
ASBR3#network 198.18.31.254 mask 255.255.255.255
 
ASBR4#ip prefix-list p1 permit 198.18.15.254/32
 
ASBR4#route-map setlocalpref permit 10
ASBR4#match ip address prefix-list p1
ASBR4#set local-preference 110
ASBR4#route-map setlocalpref permit 20
 
ASBR4#neighbor 198.18.240.0 route-map setlocalpref in
 
ASBR6#ip prefix-list p2 permit 198.18.31.254/32
 
ASBR6#route-map setlocalpref permit 10
ASBR6#match ip address prefix-list p2
ASBR6#set local-preference 110
ASBR6#route-map setlocalpref permit 20
 
ASBR6#neighbor 198.19.240.1 route-map setlocalpref in

En temps normal, le trafic pour P1 passe sur le lien de gauche et le trafic pour P2 passe sur le lien de droite. En cas de coupure d'un lien, le trafic est correctement redirigé sur le lien inter-domaines restant.

Dans un deuxième temps, je me suis souvenu qu'avec certains routeurs purement logiciels, notamment BIRD, il est possible de créer des routes quasiment statiques dont l'existence est conditionnée par l'existence d'une route BGP. Malgré mes recherches, je n'ai rien trouvé de comparable chez Cisco.

Dans un troisième temps, je me suis penché sur les routes statiques et les annonces conditionnelles. Je vais developper le raisonnement pour P1, il est identique pour P2.

L'idée de la manipulation est que, si ASBR4 reçoit une route pour 198.18.0.0/16, depuis ASBR1, alors il annonce, à ASBR6, en iBGP, une meilleure route pour 198.18.15.254. La route étant plus spécifique, elle l'emporte. Si l'un des deux liens tombe, le routeur restant doit annoncer la route.

Sur Cisco, pour annoncer une route via BGP, il faut posséder une entrée correspondante dans la table de routage. On crée donc une route statique sur ASBR4 et sur ASBR6, pas une interface Null sinon on devient des trous noirs.

Sur ASBR4 :

ip route 198.18.15.254 255.255.255.255 198.18.240.0
 
ip prefix-list p1 permit 198.18.15.254/32
route-map filterfuites deny 10
        match ip address prefix-list p1
route-map filterfuites permit 20
 
access-list 1 permit 198.18.15.254 0.0.0.0
access-list 2 permit 198.18.0.0 0.0.255.255
ip prefix-list ROUTE_SOURCE permit 198.18.240.0/32
 
route-map ADV permit 10
        match ip address 1
        set ip next-hop 198.19.224.0
        set community no-export !évite qu'ASBR6 ne fasse fuiter
 
route-map NotThere permit 10
        match ip address 2
        match ip route-source prefix-list ROUTE_SOURCE
 
router bgp 64502
	neighbor 198.18.240.0 route-map filterfuites out ! on évite que les annonces fuitent vers AS1
        neighbor 198.19.224.3 advertise-map ADV exist-map NotThere
        neighbor 198.19.224.3 send-community ! sans ça, les communautés ne sont pas tranmises
        redistribute static ! on distribue nos routes statiques en (i)BGP
 
#Il faut redistribuer nos routes statiques via OSPF pour IR5
router ospf 1
        redistribute static subnets

Sur ASBR6 :

ip route 198.18.15.254 255.255.255.255 198.19.240.1 110
 
#Pour qu'une route iBGP soit préférée à une route OSPF, il faut diminuer la distance 
#administrative par défaut d'iBGP (200 -> 100 < 110 (OSPF)).
router bgp 64502
        distance bgp 20 100 100
 
#Il faut redistribuer nos routes statiques via OSPF pour IR5
router ospf 1
        redistribute static-subnets

On regarde le résultat quand les deux liens sont opérationnels :

ASBR4#show ip route
     198.18.15.0/32 is subnetted, 1 subnets
S       198.18.15.254 [1/0] via 198.18.240.0
B    198.18.0.0/16 [20/0] via 198.18.240.0, 00:05:02
 
IR5#show ip route
O E2    198.18.15.254 [110/20] via 198.19.224.0, 00:02:37, FastEthernet1/0
 
ASBR6#show ip route
     198.18.15.0/32 is subnetted, 1 subnets
B       198.18.15.254 [100/0] via 198.19.224.0, 00:01:51
B    198.18.0.0/16 [20/0] via 198.19.240.1, 00:14:45
 
ASBR6#traceroute 198.18.15.254
  1 198.19.224.2 20 msec 4 msec 8 msec
  2 198.19.224.0 28 msec 12 msec 44 msec
  3 198.18.240.0 [AS 64501] 48 msec 28 msec 52 msec
  4 198.18.224.1 [AS 64501] 48 msec *  60 msec

On regarde le résultat quand le lien de gauche tombe :

ASBR4#show ip route
     198.18.15.0/32 is subnetted, 1 subnets
S       198.18.15.254 [1/0] via 198.18.240.0
O E2 198.18.0.0/16 [110/1] via 198.19.224.1, 00:01:31, FastEthernet2/0
 
IR5#show ip route
O E2    198.18.15.254 [110/20] via 198.19.224.3, 00:01:22, FastEthernet2/0
                      [110/20] via 198.19.224.0, 00:01:22, FastEthernet1/0
O E2 198.18.0.0/16 [110/1] via 198.19.224.3, 00:01:57, FastEthernet2/0
 
ASBR6#show ip route
     198.18.15.0/32 is subnetted, 1 subnets
S       198.18.15.254 [110/0] via 198.19.240.1
B    198.18.0.0/16 [20/0] via 198.19.240.1, 00:08:45
 
IR5#traceroute 198.18.15.254
  1 198.19.224.3 4 msec
  2 198.19.240.1 24 msec * 
  3 198.18.224.2 40 msec *  36 msec

Et pour P2 ? La démarche est la même : ASBR4 et ASBR6 auront des routes statiques, ASBR6 fera une annonce conditionnelle, ...

Cette solution présente, selon moi, deux inconvénients :

  1. C'est une solution palliative, du bidouillage : on modifie des paramètres (les distances administratives iBGP par exemple) qui auront sûrement un impact sur d'autres comportements attendus. Comme notre maquette est limitée, on ne voit rien mais dans un vrai déploiement ...
  2. On remarque que ASBR4 garde toujours sa route statique pour P1 et qu'ASBR6 fait de même pour P2. Quand le lien tombe, le routeur ne peut plus joindre le préfixe associé (ie : ASBR4 ne peut plus joindre 198.18.15.254). On peut se dire que ce n'est pas grave car au moment où un lien tombe, le routeur associé ne sert plus à rien : il ne reçoit plus de trafic car l'IGP bascule sur l'autre routeur. L'impact est donc limité au routeur lui-même. Malgré mes tentatives, je n'ai pas trouvé une solution à ce problème :
    • Même en changeant les distances administratives ou le poids des routes, j'arrive toujours à "une boucle" ou plutôt à un problème d'amorçage (il faut une route dans la table de routage pour que le processus BGP Cisco accepte d'annoncer une route). Soit un routeur préfère une route OSPF à sa statique et on se retrouve à vouloir injecter de l'OSPF dans BGP, ce qui est déconseillé, soit un router préfère une route iBGP à sa statique et on se retrouve à vouloir réinjecter une route apprise en iBGP dans iBGP, ce qui n'est pas possible : formation d'une boucle.
    • On peut aussi demander la suppression de la route statique en fonction d'un événement comme une adresse IP qui n'est plus joignable (exemple). Mais comme on a une double connectivité, toutes les adresses sont joignables en permanence donc la route statique restera en permanence car le test retournera toujours vrai.

Enfin, j'ai découvert la fonctionnalité « inject-map » de l'IOS qui permet de désagréger, sous conditions, un préfixe donné en préfixes plus spécifiques. Si ASBR4 reçoit une route pour 198.18.0.0/16, via BGP, de la part d'ASBR1 alors il désagrège et annonce 198.18.15.254. Le raisonnement est identique pour ASBR6 et 198.18.31.254.

Voici la configuration que j'utilise :

ASBR4#ip prefix-list ROUTE permit 198.18.0.0/16
ASBR4#ip prefix-list ROUTE_SOURCE permit 198.18.240.0/32
ASBR4#ip prefix-list UNAGGREGATED_ROUTE permit 198.18.15.254/32
 
ASBR4#route-map ORIGINATE permit 10
ASBR4#set ip address prefix-list UNAGGREGATED_ROUTE
 
ASBR4#route-map LEARNED_ROUTE permit 10
ASBR4#match ip address prefix-list ROUTE
ASBR4#match ip route-source prefix-list ROUTE_SOURCE
 
ASBR4#bgp inject-map ORIGINATE exist-map LEARNED_ROUTE
 
ASBR6#ip prefix-list ROUTE permit 198.18.0.0/16
ASBR6#ip prefix-list ROUTE_SOURCE permit 198.19.240.1/32
ASBR6#ip prefix-list UNAGGREGATED_ROUTE permit 198.18.31.254/32
 
ASBR6#route-map ORIGINATE permit 10
ASBR6#set ip address prefix-list NAGGREGATED_ROUTE
 
 
ASBR6#route-map LEARNED_ROUTE permit 10
ASBR6#match ip address prefix-list ROUTE
ASBR6#match ip route-source prefix-list ROUTE_SOURCE
 
ASBR6#bgp inject-map ORIGINATE exist-map LEARNED_ROUTE

Attention : la désagrégation prend un peu de temps avant d'être effective.

Pour éviter les fuites des routes plus spécifiques vers l'AS 64501, on les filtre en sortie sur les 2 routeurs de l'AS 64502. Ci-dessous les commandes pour ASBR4 :

ip prefix-list ctrl permit 198.18.15.254/32
ip prefix-list ctrl permit 198.18.31.254/32
 
route-map filterfuites deny 10
        match ip address prefix-list ctrl
route-map filterfuites permit 20
 
neighbor 198.18.240.0 route-map filterfuites out

On regarde les tables de routage :

ASBR4#show ip route
     198.18.31.0/32 is subnetted, 1 subnets
O E2    198.18.31.254 [110/1] via 198.19.224.1, 00:07:18, FastEthernet2/0
     198.18.15.0/32 is subnetted, 1 subnets
B       198.18.15.254 [20/0] via 198.18.240.0, 00:31:26
B    198.18.0.0/16 [20/0] via 198.18.240.0, 00:31:39
 
IR5#show ip route
     198.18.31.0/32 is subnetted, 1 subnets
O E2    198.18.31.254 [110/1] via 198.19.224.3, 00:07:43, FastEthernet2/0
     198.18.15.0/32 is subnetted, 1 subnets
O E2    198.18.15.254 [110/1] via 198.19.224.0, 00:31:51, FastEthernet1/0
 
 
 
ASBR6#show ip route
     198.18.31.0/32 is subnetted, 1 subnets
B       198.18.31.254 [20/0] via 198.19.240.1, 00:07:58
     198.18.15.0/32 is subnetted, 1 subnets
O E2    198.18.15.254 [110/1] via 198.19.224.2, 00:32:06, FastEthernet1/0
B    198.18.0.0/16 [20/0] via 198.19.240.1, 00:08:32

Quelques traceroute pour vérifier :

IR5#traceroute 198.18.15.254
  1 198.19.224.0 20 msec 76 msec 20 msec
  2 198.18.240.0 24 msec 36 msec 12 msec
  3 198.18.224.1 300 msec *  20 msec
 
IR5#traceroute 198.18.31.254
  1 198.19.224.3 108 msec 36 msec 12 msec
  2 198.19.240.1 84 msec 464 msec 28 msec
  3 198.18.224.2 28 msec *  40 msec
 
ASBR4#traceroute 198.18.15.254
  1 198.18.240.0 [AS 64501] 80 msec 40 msec 52 msec
  2 198.18.224.1 [AS 64501] 8 msec *  4 msec
 
ASBR4#traceroute 198.18.31.254
  1 198.19.224.1 8 msec 32 msec 28 msec
  2 198.19.224.3 32 msec 32 msec 24 msec
  3 198.19.240.1 196 msec 48 msec 36 msec
  4 198.18.224.2 [AS 64501] 16 msec *  172 msec

On constate que chaque préfixe passe par le lien désiré.

Quand le lien de gauche tombe, P1 disparaît et la route moins-spécifique reprend le dessus :

ASBR4#show ip route
     198.18.31.0/32 is subnetted, 1 subnets
O E2    198.18.31.254 [110/1] via 198.19.224.1, 00:13:08, FastEthernet2/0
O E2 198.18.0.0/16 [110/1] via 198.19.224.1, 00:02:22, FastEthernet2/0
 
IR5#show ip route
     198.18.31.0/32 is subnetted, 1 subnets
O E2    198.18.31.254 [110/1] via 198.19.224.3, 00:13:42, FastEthernet2/0
O E2 198.18.0.0/16 [110/1] via 198.19.224.3, 00:02:55, FastEthernet2/0
 
ASBR6#show ip route
     198.18.31.0/32 is subnetted, 1 subnets
B       198.18.31.254 [20/0] via 198.19.240.1, 00:13:59
B    198.18.0.0/16 [20/0] via 198.19.240.1, 00:14:33
 
IR5#traceroute 198.18.15.254
  1 198.19.224.3 20 msec 8 msec 12 msec
  2 198.19.240.1 40 msec 28 msec 28 msec
  3 198.18.224.2 24 msec *  208 msec
 
IR5#traceroute 198.18.31.254
  1 198.19.224.3 76 msec 28 msec 20 msec
  2 198.19.240.1 16 msec 24 msec 20 msec
  3 198.18.224.2 44 msec *  208 msec

On constate que tout a bien été redirigé vers le lien de droite.

On se doute qu'une situation similaire va se produire si c'est le lien de droite qui tombe à la place du lien de gauche. Vérification concise :

IR5#traceroute 198.18.15.254
  1 198.19.224.0 16 msec 12 msec 4 msec
  2 198.18.240.0 32 msec 12 msec 28 msec
  3 198.18.224.1 36 msec *  16 msec
 
IR5#traceroute 198.18.31.254
  1 198.19.224.0 28 msec 4 msec 16 msec
  2 198.18.240.0 8 msec 28 msec 36 msec
  3 198.18.224.1 20 msec *  208 msec

Et concernant P3 ? BGP, comme tout protocole de construction dynamique de tables de routage a pour but de s'adapter aux fluctuations afin de maintenir, tant que possible, une connectivité. Il n'est donc pas le candidat idéal pour forcer le trafic sur un lien même quand celui-ci tombe. Dans un genre similaire : dans une configurations multi-homée, il est toujours délicat de forcer le trafic à entrer/sortir d'un AS via un seul upstream. Par exemple, cela en fait une thématique récurrente sur FRnOG. Exemples choisis : Session BGP priorité et multihome BGP avec annonces conditionnelles et statiques

Dans notre cas, une route statique, mise en place sur ASBR6 me paraît être une méthode plus cohérente en raison de sa plus grande priorité administrative.

Mise en œuvre :

ip route 198.18.47.254 255.255.255.255 198.19.240.1
 
router ospf 1	#Il faut redistribuer notre route statique, via OSPF, pour IR5/ASBR4
        resdistribute static subnets

On constate la bonne mise en place de la route :

ASBR4#show ip route
     198.18.47.0/32 is subnetted, 1 subnets
O E2    198.18.47.254 [110/20] via 198.19.224.1, 00:07:17, FastEthernet2/0
 
ASBR4#traceroute 198.18.47.254
  1 198.19.224.1 4 msec 8 msec 8 msec
  2 198.19.224.3 8 msec 8 msec 12 msec
  3 198.19.240.1 12 msec 12 msec 12 msec
  4 198.18.224.2 [AS 64501] 16 msec *  64 msec

Quand le lien de droite tombe, ASBR6 continue d'annoncer une route vers P3 et devient ainsi un trou noir pour ce préfixe pour tout l'AS, comme désiré. Vérification :

IR5#show ip route
     198.18.47.0/32 is subnetted, 1 subnets
O E2    198.18.47.254 [110/20] via 198.19.224.3, 00:17:48, FastEthernet2/0
O E2 198.18.0.0/16 [110/1] via 198.19.224.0, 00:03:30, FastEthernet1/0
 
IR5#traceroute 198.18.47.254
  1 198.19.224.3 24 msec 8 msec 32 msec
  2  *  *  * 
  3  *  *  * 
  4  *  *  * 
  5  *  *  * 
  6  *  *  * 
  7  *  *  * 
  8  *  *  * 
  9  *  *  * 
 10  *  *  * 
...

Question 5

Il suffit de rallonger le chemin d'AS pour les annonces qu'ASBR6 distribuent à ASBR3.

route-map asprepending permit 10
        set as-path prepend 64502 64502 !une seule fois suffirait mais par sécurité ...
 
router bgp 64502
        neighbor 198.19.240.1 route-map asprepending out

On regarde le résultat sur les routeurs de l'AS 64501 :

ASBR3>show ip bgp
r  198.19.0.0/16    198.19.240.0             0             0 64502 64502 64502 i
r>i                 198.18.240.1             0    100      0 64502 i
 
ASBR3#show ip route
O E2 198.19.0.0/16 [110/1] via 198.18.224.2, 00:06:49, FastEthernet1/0
 
IR2#show ip route
O E2 198.19.0.0/16 [110/1] via 198.18.224.0, 00:06:40, FastEthernet1/0

Un traceroute confirme le résultat :

ASBR3#traceroute 198.19.15.254
  1 198.18.224.2 8 msec 8 msec 8 msec
  2 198.18.224.0 12 msec 12 msec 8 msec
  3 198.18.240.1 12 msec 16 msec 12 msec
  4 198.19.224.1 16 msec *  52 msec

Question 6

Les communautés sont des marques inter-AS positionnées par un AS sur les routes, qui permettent de déclencher une action spécifique dans un autre AS (affecter une préférence locale, ne pas ré-annoncer le préfixe, ne pas annoncer sur tel GIX, as-prepend vers tel peer, ...). Les listes des communautés disponibles au sein d'un AS sont échangées lorsque deux AS "contractualisent" (peering ou transit) en même temps que l'accord sur un préfixe d'interconnexion.

Dans notre cas, et comme toujours, il y a au moins deux manières de procéder :

  1. Soit ASBR6 positionne une communauté pour le préfixe de l'AS 64501. ASBR4 l'interprète et affecte une préférence locale plus élevée à cette route. Méthode un peu inutile car on peut positionner directement une préférence locale sur une session iBGP, ce qu'on ne peut pas faire en eBGP.
  2. Soit l'AS 64501 positionne une communauté pour son préfixe. Seul ASBR6 l'interprète et affecte une préférence locale plus élevée à cette route. On remarquera que si l'on met ça en place, d'un point de vue de l'AS 64501, cela lui permet d'influencer le trafic entrant sur son AS (réflexion relative à la question 1).

La deuxième méthode me paraît plus cohérente mais comme l'énoncé précise que l'on ne doit pas toucher aux deux AS en même temps, il ne reste donc que la première méthode.

Voici la configuration sur ASBR6 :

ip bgp-community new-format ! communauté de la forme ASN:xxxxx
ip prefix-list as64501 permit 198.18.0.0/16
 
route-map setcomm permit 10
        match ip address prefix-list as64501
        set community 64502:110
route-map setcomm permit 20
 
router bgp 64502
        neighbor 198.19.224.0 route-map setcomm out
        neighbor 198.19.224.0 send-community ! sans ça, les communautés ne sont pas tranmises

Voici la configuration sur ASBR4 :

ip bgp-community new-format ! communauté de la forme ASN:xxxxx
ip community-list 1 permit 64502:110
 
route-map getcomm permit 10
        match community 1
        set local-preference 110 
route-map getcomm permit 20
 
router bgp 64502
        neighbor 198.19.224.3 route-map getcomm in

On remarque qu'avec cette configuration, on aura le même comportement qu'à la question 3 : seul le trafic destiné à 198.18.0.0/16 passera par le lien de droite, pas les autres préfixes. Pour obtenir strictement le même comportement qu'à la question 2, il suffit qu'ASBR6 tague toutes les routes (pas de match par préfixe ou autre) ou plus simplement, de ne pas utiliser les communautés de cette manière.

On vérifie les tables de routage :

ASBR4#show ip route
O E2 198.18.0.0/16 [110/1] via 198.19.224.1, 00:06:10, FastEthernet2/0
 
----
 
IR5#show ip route
O E2 198.18.0.0/16 [110/1] via 198.19.224.3, 00:05:43, FastEthernet2/0
 
----
 
ASBR6#show ip route
B    198.18.0.0/16 [20/0] via 198.19.240.1, 00:46:59

Question 7

Seule la configuration de Dynagen change dans cette question. Le nouveau fichier utilisé est annexé au présent document.

La topologie réelle est celle-ci :

  • PC1 - 192.168.1.2 - AS 64501
  • PC2 - 192.168.1.8 - AS 64502

Dynamips crée 2 sockets UDP par liaison pour y encapsuler les échanges. Nous avons 4 liens par AS. Nous aurons donc 6 sockets par machines (4*2 - 2, car la terminaison de deux liaisons sont dans l'autre AS).

Vérification, sur PC1, avec netstat :

PC1#netstat -taupn | grep dynamips
tcp 0 0 0.0.0.0:2000	  0.0.0.0:*         LISTEN      12460/dynamips  
tcp 0 0 0.0.0.0:2001	  0.0.0.0:*         LISTEN      12460/dynamips  
tcp 0 0 0.0.0.0:2002	  0.0.0.0:*         LISTEN      12460/dynamips  
tcp 0 0 0.0.0.0:7200	  0.0.0.0:*         LISTEN      12460/dynamips  
tcp 0 0 192.168.1.2:2001  192.168.1.2:39539 ESTABLISHED 12460/dynamips  
tcp 0 0 192.168.1.2:2002  192.168.1.2:60981 ESTABLISHED 12460/dynamips  
tcp 0 0 192.168.1.2:7200  192.168.1.2:49847 ESTABLISHED 12460/dynamips  
tcp 0 0 192.168.1.2:2000  192.168.1.2:50270 ESTABLISHED 12460/dynamips  
udp 0 0 127.0.0.1:10000   127.0.0.1:10001   ESTABLISHED 12460/dynamips  
udp 0 0 127.0.0.1:10001   127.0.0.1:10000   ESTABLISHED 12460/dynamips  
udp 0 0 192.168.1.2:10002 192.168.1.8:10000 ESTABLISHED 12460/dynamips  
udp 0 0 127.0.0.1:10003   127.0.0.1:10004   ESTABLISHED 12460/dynamips  
udp 0 0 127.0.0.1:10004   127.0.0.1:10003   ESTABLISHED 12460/dynamips  
udp 0 0 192.168.1.2:10005 192.168.1.8:10001 ESTABLISHED 12460/dynamips

On a donc les liens 1000<-> 1001 et 1003<->10004 pour les liaisons ASBR1<->IR2<->ASBR3. On a les connexions 192.168.1.2:10002<->192.168.1.8:10000 et 192.168.1.2:10005<->192.168.1.8:10001 pour les liaisons ASBR1<->ASBR4 et ASBR3<->ASBR6 respectivement. Le reste des sockets est habituel : pour les liaisons séries (200X) et pour se brancher à l'hyperviseur (7200).

Avec la commande ping, on constate que les liaisons inter-AS (et donc inter-PC) sont fonctionnelles. Exemple :

ASBR1#ping 198.18.240.1
Success rate is 100 percent (5/5), round-trip min/avg/max = 8/8/8 ms

En faisant une capture du trafic réseau sur les interfaces physiques des PC utilisés, on remarque bien l'échange de paquets entre les 2 dynamips donc entre les deux routeurs de nos 2 AS. Exemple :

ASBR1, sur PC1, ping ASBR4, sur PC2. Dynamips encapsule le trafic dans des datagrammes UDP

Figure 15 - ASBR1, sur PC1, ping ASBR4, sur PC2. Dynamips encapsule le trafic dans des datagrammes UDP.

Bibliographie

Dans l'ordre d'utilisation.

Exercice 3

Exercice 4

Annexes

Fichier de configuration Dynagen pour l'exercice 3/4 (sauf question 8)

[localhost]
    [[7200]]
        image = ./C7200-AD.BIN
        ram = 256
        idlepc = 0x607335f0
 
    [[ROUTER ASBR1]]
        model = 7200
        f1/0 = IR2 f1/0
        f2/0 = ASBR4 f1/0
 
    [[ROUTER IR2]]
        model = 7200
        f2/0 = ASBR3 f1/0
 
    [[ROUTER ASBR3]]
        model = 7200
        f2/0 = ASBR6 f2/0
 
    [[ROUTER ASBR4]]
        model = 7200
        f2/0 = IR5 f1/0
 
    [[ROUTER IR5]]
        model = 7200
        f2/0 = ASBR6 f1/0
 
    [[ROUTER ASBR6]]
        model = 7200

Commandes IOS pour l'exercice 3 (sauf question 8)

ASBR1
enable
conf t
hostname ASBR1
no ip domain lookup !pas de réso DNS = gain de temps traceroute, ping, ...
 
int fastEthernet 1/0
ip address 198.18.224.0 255.255.255.254
no shutdown
exit
int fastEthernet 2/0
ip address 198.18.240.0 255.255.255.254
no shutdown
exit
 
router ospf 1
network 198.18.0.0 0.0.255.255 area 0
passive-interface F2/0 !aucun routeur ne répondra ici, pas la peine de gâcher des ressources
redistribute bgp 64501 subnets
exit
 
ip route 198.18.0.0 255.255.0.0 Null 0
router bgp 64501
network 198.18.0.0 mask 255.255.0.0
neighbor 198.18.240.1 remote-as 64502
IR2
enable
conf t
hostname IR2
no ip domain lookup !pas de réso DNS = gain de temps traceroute, ping, ...
 
int fastEthernet 1/0
ip address 198.18.224.1 255.255.255.254
no shutdown
exit
int fastEthernet 2/0
ip address 198.18.224.2 255.255.255.254
no shutdown
exit
int loopback 1
ip address 198.18.15.254 255.255.240.0
exit
 
router ospf 1
network 198.18.0.0 0.0.255.255 area 0
exit
ASBR3
enable
conf t
hostname ASBR3
no ip domain lookup !pas de réso DNS = gain de temps traceroute, ping, ...
 
int fastEthernet 1/0
ip address 198.18.224.3 255.255.255.254
no shutdown
exit
int fastEthernet 2/0
ip address 198.19.240.1 255.255.255.254
no shutdown
exit
 
router ospf 1
network 198.18.0.0 0.0.255.255 area 0
passive-interface F2/0 !aucun routeur ne répondra ici, pas la peine de gâcher des ressources
redistribute bgp 64501 subnets
exit
 
ip route 198.18.0.0 255.255.0.0 Null 0
router bgp 64501
network 198.18.0.0 mask 255.255.0.0
neighbor 198.19.240.0 remote-as 64502
ASBR4
enable
conf t
hostname ASBR4
no ip domain lookup !pas de réso DNS = gain de temps traceroute, ping, ...
 
int fastEthernet 1/0
ip address 198.18.240.1 255.255.255.254
no shutdown
exit
int fastEthernet 2/0
ip address 198.19.224.0 255.255.255.254
no shutdown
exit
 
router ospf 1
network 198.19.0.0 0.0.255.255 area 0
passive-interface F1/0 !aucun routeur ne répondra ici, pas la peine de gâcher des ressources
redistribute bgp 64502 subnets
exit
 
ip route 198.19.0.0 255.255.0.0 Null 0
router bgp 64502
network 198.19.0.0 mask 255.255.0.0
neighbor 198.18.240.0 remote-as 64501
IR5
enable
conf t
hostname IR5
no ip domain lookup !pas de réso DNS = gain de temps traceroute, ping, ...
 
int fastEthernet 1/0
ip address 198.19.224.1 255.255.255.254
no shutdown
exit
int fastEthernet 2/0
ip address 198.19.224.2 255.255.255.254
no shutdown
exit
int loopback 1
ip address 198.19.15.254 255.255.240.0
exit
 
router ospf 1
network 198.19.0.0 0.0.255.255 area 0
exit
ASBR6
enable
conf t
hostname ASBR6
no ip domain lookup !pas de réso DNS = gain de temps traceroute, ping, ...
 
int fastEthernet 1/0
ip address 198.19.224.3 255.255.255.254
no shutdown
exit
int fastEthernet 2/0
ip address 198.19.240.0 255.255.255.254
no shutdown
exit
 
router ospf 1
network 198.19.0.0 0.0.255.255 area 0
passive-interface F2/0 !aucun routeur ne répondra ici, pas la peine de gâcher des ressources
redistribute bgp 64502 subnets
exit
 
ip route 198.19.0.0 255.255.0.0 Null 0
router bgp 64502
network 198.19.0.0 mask 255.255.0.0
neighbor 198.19.240.1 remote-as 64501

Fichier de configuration Dynagen pour la question 8 de l'exercice 3

[localhost]
    [[7200]]
        image = ./C7200-AD.BIN
        ram = 256
        idlepc = 0x607335f0
 
    [[ROUTER ASBR1]]
        model = 7200
        f1/0 = ASBR3 f1/0
        f2/0 = ASBR4 f1/0
        f3/0 = IR2 f1/0
 
    [[ROUTER IR2]]
        model = 7200
 
    [[ROUTER ASBR3]]
        model = 7200
        f2/0 = ASBR6 f2/0
        f3/0 = IR7 f1/0
 
    [[ROUTER ASBR4]]
        model = 7200
        f2/0 = IR5 f1/0
 
    [[ROUTER IR5]]
        model = 7200
        f2/0 = ASBR6 f1/0
 
    [[ROUTER ASBR6]]
        model = 7200
 
    [[ROUTER IR7]]
        model = 7200

Commandes IOS pour la question 8 de l'exercice 3

ASBR1
router ospf 1
network 198.18.224.0 0.0.0.1 area 0
network 198.18.224.2 0.0.0.1 area 1
passive-interface F2/0 !aucun routeur ne répondra ici, pas la peine de gâcher des ressources
exit
IR2
router ospf 1
network 198.18.224.2 0.0.0.1 area 1
network 198.18.0.0 0.0.15.255 area 1
exit
ASBR3
router ospf 1
network 198.18.224.0 0.0.0.1 area 0
network 198.18.224.4 0.0.0.1 area 2
passive-interface F2/0 !aucun routeur ne répondra ici, pas la peine de gâcher des ressources
exit
IR7
router ospf 1
network 198.18.224.4 0.0.0.1 area 2
network 198.18.16.0 0.0.15.255 area 2
exit

Fichier de configuration Dynagen pour la question 7 de l'exercice 4

[192.168.1.2]
    udp=10000
 
    [[7200]]
        image = ./C7200-AD.BIN
        ram = 256
        idlepc = 0x607335f0
 
    [[ROUTER ASBR1]]
        model = 7200
        f1/0 = IR2 f1/0
        f2/0 = ASBR4 f1/0
 
    [[ROUTER IR2]]
        model = 7200
        f2/0 = ASBR3 f1/0
 
    [[ROUTER ASBR3]]
        model = 7200
        f2/0 = ASBR6 f2/0
 
[192.168.1.8]
    udp=10000
 
    [[7200]]
        image = ./C7200-AD.BIN
        ram = 256
        idlepc = 0x607335f0
 
    [[ROUTER ASBR4]]
        model = 7200
        f2/0 = IR5 f1/0
 
    [[ROUTER IR5]]
        model = 7200
        f2/0 = ASBR6 f1/0
 
    [[ROUTER ASBR6]]
        model = 7200

Table des figures

Figure 1 - Schéma de ma maquette. D'après l'énoncé.
Figure 2 - Ici, on voit IR2, dont le démon OSPF vient de démarrer, s'initialiser et annoncer les routes qu'il connaît.
Figure 3 - Ici, on voit ASBR6, dont le démon BGP vient de démarrer, initialiser une session BGP avec ASBR3 (TCP handshake + PDU BGP OPEN). Puis vient l'échange des préfixes (PDU BGP UPDATE).
Figure 4 - ether.src : ca:00:53:1e:00:38 (f2/0 de ASBR1) -> ether.dst = ca:03:53:1e:00:1c (f1/0 de ASBR4).
Figure 5 - ether.src = ca:01:53:1e:00:1c (f1/0 d'IR2) -> ether.dst = ca:00:53:1e:00:1c (f1/0 d'ASBR1).
Figure 6 - Les PDU KEEPALIVE d'ASBR1 ne sont pas acquittés par ASBR4 donc sa pile TCP les réémet.
Figure 7 - ASBR1 perd la connectivité vers 198.19.0.0/16 : la métrique explose puis la route ne sera plus annoncée via OSPF.
Figure 8 - IR2 annonce à ASBR1 la route qu'il connaît pour joindre 198.19.0.0/16 : IR2 -> ASBR3 -> ASBR6.
Figure 9 - IR2 n'annonce plus sa loopback en OSPF.
Figure 10 - ASBR6 tente de pinger la loopback 1 d'IR2. ASBR3, auquel ASBR6 a envoyé le paquet, ne connaît aucune route pour aller à cette adresse donc il émet un ICMP dst unreachable.
Figure 11 - IR2 annonce, à nouveau, sa loopback via OSPF.
Figure 12 - Schéma de la nouvelle configuration interne de l'AS 64501.
Figure 13 - ASBR3 annonce, dans l'aire 0, les routes de l'aire 2.
Figure 14 - Quelques secondes plus tard, ASBR1 redistribue les routes de l'aire 2 dans l'aire 1.
Figure 15 - ASBR1, sur PC1, ping ASBR4, sur PC2. Dynamips encapsule le trafic dans des datagrammes UDP.

Les commandes de la fin

Pour avoir un term sur chacun des routeurs de manière pratique, on peut utiliser la commande suivante (si vous utilisez gnome 🙂 ) :

gnome-terminal \
	--tab-with-profile=labRO \
	--tab-with-profile=labRO -t "ASBR1" -e "telnet localhost 2000" \
	--tab-with-profile=labRO -t "IR2" -e "telnet localhost 2001" \
	--tab-with-profile=labRO -t "ASBR3" -e "telnet localhost 2002" \
	--tab-with-profile=labRO -t "ASBR4" -e "telnet localhost 2003" \
	--tab-with-profile=labRO -t "IR5" -e "telnet localhost 2004" \
	--tab-with-profile=labRO -t "ASBR6" -e "telnet localhost 2005" \

Cette commande vient de johndescs. Attention, le profile avec le nom correspondant (ici : « labRO ») doit exister, voir dans Édition -> Préférences du profil. Le premier onglet contient un terminal vide qui permet d'exécuter des commandes, au cas où ...

On peut aussi utiliser screen pour produire le même résultat :

screen -AdmS labRO -t tab0 bash
screen -S labRO -X screen -t ASBR1 telnet localhost 2000
screen -S labRO -X screen -t IR2 telnet localhost 2001
screen -S labRO -X screen -t ASBR3 telnet localhost 2002
screen -S labRO -X screen -t ASBR4 telnet localhost 2003
screen -S labRO -X screen -t IR5 telnet localhost 2004
screen -S labRO -X screen -t ASBR6 telnet localhost 2005
screen -S labRO -X caption always "%{= wk}%-w%{= BW}%n %t%{-}%+w %-="

Le premier onglet contient un terminal vide qui permet d'exécuter des commandes, au cas où ... Les commandes nécéssaires sont les classiques « screen -Rd » pour attacher la session, « screen -S labRO -X quit » pour la quitter de l'extérieur, Ctrl+A + :quit pour quitter la session de l'intérieur, Ctrl+a+d pour détacher screen, Ctrl+a+(n|p|[0-6]) pour naviguer dans les onglets.