4. Routage inter-VLAN dans le système hôte

Dans ce premier exemple, toutes les décisions d'acheminement du trafic sont prises dans le sous-système réseau du système hôte. Au niveau commutation de circuits et de paquets, c'est Open vSwitch qui joue le rôle le plus important. Si on se réfère au Schéma de la topologie, l'essentiel de la configuration porte sur le commutateur dsw-host. Voyons par quelles étapes il faut passer.

4.1. Plan d'adressage

Tableau 1. plan d'adressage des périmètres

Nom VLAN Interface Préfixe réseau IP
Système hôte trunk vlan1 192.0.2.0/26
2001:db8:fe00:8175::/64
Orange 10 vlan10 198.51.100.0/24
fd6e:c073:b4a3:a::/64
Vert 20 vlan20 203.0.113.0/24
fd6e:c073:b4a3:14::/64

[Note] Note

Les préfixes réseau IPv4 des trois VLANs appartiennent à la catégorie TESTNET définie dans le document RFC5737 IPv4 Address Blocks Reserved for Documentation.

Les préfixes réseau IPv6 des deux VLANs Orange et Vert appartiennent à la famille ULA définie dans le document RFC4193 Unique Local IPv6 Unicast Addresses. Le préfixe de départ retenu est le fd00::/8. On lui adjoint une chaîne de 40 bits aléatoires obtenus à l'aide de la commande $ openssl rand -hex 5 pour arriver au préfixe fd6e:c073:b4a3::/48. Enfin, on utilise les numéros de VLANs pour obtenir les préfixes réseau sur 64 bits.

4.2. Commutateur et cordons de brassage

Une fois que les paquets nécessaires à la configuration sont installés, on peut passer au changement de configuration de l'interface réseau. On désactive l'interface eth0 avant de l'associer au commutateur.

  1. Désactivation de l'interface physique du système hôte.

    $ sudo ifdown eth0
  2. Création du commutateur dsw-host.

    $ sudo ovs-vsctl add-br dsw-host
  3. Brassage de l'interface physique du système hôte sur le commutateur dsw-host.

    $ sudo ovs-vsctl add-port dsw-host eth0

    Activation de l'interface physique au niveau liaison.

    $ sudo ip link set dev eth0 up
  4. Création et «activation» des deux cordons de brassage associés aux instances de machines virtuelles.

    $ sudo ip tuntap add mode tap dev tap0 group kvm multi_queue
    $ sudo ip link set dev tap0 up
    $ sudo ip tuntap add mode tap dev tap1 group kvm multi_queue
    $ sudo ip link set dev tap1 up
  5. Raccordement des cordons de brassage au commutateur.

    $ sudo ovs-vsctl add-port dsw-host tap0 tag=10
    $ sudo ovs-vsctl set port tap0 vlan_mode=access
    $ sudo ovs-vsctl add-port dsw-host tap1 tag=20
    $ sudo ovs-vsctl set port tap1 vlan_mode=access

4.3. Création des interfaces de type SVI

Une fois la partie commutation de circuits en place, on s'intéresse maintenant au routage des paquets dans le sous-système réseau du système hôte. On utilise ici des interfaces logicielles de routage appelées Switch virtual interface que l'on configure sur le commutateur dsw-host.

  1. Création de l'interface principale du système hôte : vlan1.

    $ sudo ovs-vsctl add-port dsw-host vlan1 -- set interface vlan1 type=internal
    $ sudo ovs-vsctl set port vlan1 vlan_mode=native-untagged
    $ sudo ip addr add 192.0.2.29/26 brd + dev vlan1
    $ sudo ip -6 addr add 2001:db8:fe00:8175::1d/64 dev vlan1
    $ sudo ip link set dev vlan1 up

    La dernière instruction associe l'interface au VLAN natif d'une interface en mode trunk. Toutes les trames sans étiquette IEEE 802.1q circulant dans un trunk appartiennent au VLAN natif.

    Une fois configurée au niveau réseau, cette interface fournit les informations suivantes.

    $ ip addr ls dev vlan1
    4: vlan1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UNKNOWN group default 
        link/ether 4a:cb:5b:38:d2:c2 brd ff:ff:ff:ff:ff:ff
        inet 192.0.2.29/26 brd 192.0.2.31 scope global vlan1
           valid_lft forever preferred_lft forever
        inet6 2001:db8:fe00:8175::1d/64 scope global mngtmpaddr dynamic 
           valid_lft 85994sec preferred_lft 13994sec
        inet6 fe80::48cb:5bff:fe38:d2c2/64 scope link 
           valid_lft forever preferred_lft forever
  2. Création de l'interface SVI du VLAN Orange.

    $ sudo ovs-vsctl add-port dsw-host vlan10 tag=10 -- set interface vlan10 type=internal
    $ sudo ovs-vsctl set port vlan10 vlan_mode=access
    $ sudo ip addr add 198.51.100.1/24 brd + dev vlan10
    $ sudo ip -6 addr add fd6e:c073:b4a3:a::1/64 dev vlan10
    $ sudo ip link set dev vlan10 up
  3. Création de l'interface SVI du VLAN Vert.

    $ sudo ovs-vsctl add-port dsw-host vlan20 tag=20 -- set interface vlan20 type=internal
    $ sudo ovs-vsctl set port vlan20 vlan_mode=access
    $ sudo ip addr add 203.0.113.1/24 brd + dev vlan20
    $ sudo ip -6 addr add fd6e:c073:b4a3:14::1/64 dev vlan20
    $ sudo ip link set dev vlan20 up

4.4. Activation du routage sur le système hôte

Sur un système GNU/Linux, la fonction de routage est contrôlée par les paramètres du sous-système réseau du noyau. Le fichier principal de configuration des paramètres des sous-systèmes du noyau est : /etc/systcl. Voici la liste des paramètres à appliquer pour activer le routage IPv4 et le routage IPv6.

# egrep -v '(^#|^$)' /etc/sysctl.conf 
net.ipv4.conf.default.rp_filter=1
net.ipv4.conf.all.rp_filter=1
net.ipv4.ip_forward=1
net.ipv6.conf.all.forwarding=1
net.ipv4.conf.all.log_martians=1

Cette liste de paramètres n'est effective qu'après utilisation de l'instruction # sysctl -p.

Il est aussi possible le manipuler les paramètres individuellement à partir de la console à l'aide de commandes du type suivant :

# echo 1 > /proc/sys/net/ipv4/ip_forward
# echo 1 > /proc/sys/net/ipv6/conf/all/forwarding

4.5. Autoconfiguration des hôtes des VLANs Orange et Vert

Pour la partie IPv4, on fait appel à un démon DHCP sur le système hôte. On place ce démon en écoute sur les deux interfaces vlan10 et vlan20.

Après avoir installé le paquet du serveur DHCP, on restreint son usage aux deux VLANs de la maquette en éditant le fichier /etc/default/isc-dhcp-server. On obtient les résultats suivants.

# aptitude search ~idhcp-server
i   isc-dhcp-server      - ISC DHCP server for automatic IP address assignment

# egrep -v '(^#|^$)' /etc/default/isc-dhcp-server 
INTERFACES="vlan10 vlan20"

Côté configuration, on applique les éléments suivants dans le fichier /etc/dhcp/dhcpd.conf.

ddns-update-style none;

default-lease-time 600;
max-lease-time 7200;

authoritative;

log-facility local7;

subnet 198.51.100.0 netmask 255.255.255.0 {
  range 198.51.100.10 198.51.100.30;
  option domain-name-servers 192.0.2.1;
  option routers 198.51.100.1;
  option broadcast-address 198.51.100.255;
}

subnet 203.0.113.0 netmask 255.255.255.0 {
  range 203.0.113.10 203.0.113.30;
  option domain-name-servers 192.0.2.1;
  option routers 203.0.113.1;
  option broadcast-address 203.0.113.255;
}

Pour la partie IPv6, on fait appel au paquet radvd pour l'autoconfiguration des hôtes en mode SLAAC (Document RFC4862 IPv6 Stateless Address Autoconfiguration). On vérifie que le paquet est bien installé :

# aptitude search ~iradvd
i   radvd                - Démon d'information de routeur

Voici ensuite une copie du fichier /etc/radvd.conf du système hôte.

interface vlan10
{
   AdvSendAdvert on;
   prefix fd6e:c073:b4a3:a::/64
   {
       AdvOnLink on;
       AdvAutonomous on;
       AdvRouterAddr on;
   };

   RDNSS 2001:db8:fe00:8175::1
   {
   };
};

interface vlan20
{
   AdvSendAdvert on;
   prefix fd6e:c073:b4a3:14::/64
   {
       AdvOnLink on;
       AdvAutonomous on;
       AdvRouterAddr on;
   };

   RDNSS 2001:db8:fe00:8175::1
   {
   };
};

4.6. Affichage des tables de routage du système hôte

Les tables de routage font apparaître les correspondances entre les préfixes réseau définis plus haut et les interfaces configurées sur le commutateur Open vSwitch dsw-host.

La table de routage IPv4 est :

$ ip route ls
default via 192.0.2.1 dev vlan1 
192.0.2.0/26 dev vlan1  proto kernel  scope link  src 192.0.2.29 
198.51.100.0/24 dev vlan10  proto kernel  scope link  src 198.51.100.1 
203.0.113.0/24 dev vlan20  proto kernel  scope link  src 203.0.113.1

La table de routage IPv6 est :

$ ip -6 route ls
2001:db8:fe00:8175::/64 dev vlan1  proto kernel  metric 256  pref medium
fd6e:c073:b4a3:a::/64 dev vlan10  proto kernel  metric 256  pref medium
fd6e:c073:b4a3:14::/64 dev vlan20  proto kernel  metric 256  pref medium
fe80::/64 dev vlan1  proto kernel  metric 256  pref medium
fe80::/64 dev eth0  proto kernel  metric 256  pref medium
fe80::/64 dev vlan10  proto kernel  metric 256  pref medium
fe80::/64 dev vlan20  proto kernel  metric 256  pref medium
fe80::/64 dev tap0  proto kernel  metric 256  pref medium
fe80::/64 dev tap1  proto kernel  metric 256  pref medium
default via 2001:db8:fe00:8175::1 dev vlan1  metric 1024  pref medium

4.7. Traduction d'adresses source sur le système hôte

Les VLANs Orange et Vert utilisent des préfixes réseau non routables sur l'Internet. On a donc recours à un artifice pour accéder au réseau public : la traduction des adresses sources (S-NAT) avec les deux protocoles IPv4 et IPv6.

Voici une copie des fichiers de règles pour les deux protocoles de couche réseau.

#
*filter
:INPUT ACCEPT [0:0]
:FORWARD ACCEPT [0:0]
:OUTPUT ACCEPT [0:0]
COMMIT
#
*nat
:PREROUTING ACCEPT [0:0]
:INPUT ACCEPT [0:0]
:OUTPUT ACCEPT [0:0]
:POSTROUTING ACCEPT [0:0]
-A POSTROUTING -p tcp -m tcp --syn -m tcpmss --mss 1400:1536 -j TCPMSS --clamp-mss-to-pmtu
-A POSTROUTING -o vlan1 -j SNAT --to-source 192.0.2.29
COMMIT
#
*filter
:INPUT ACCEPT [0:0]
:FORWARD ACCEPT [0:0]
:OUTPUT ACCEPT [0:0]
COMMIT
#
*nat
:PREROUTING ACCEPT [0:0]
:INPUT ACCEPT [0:0]
:OUTPUT ACCEPT [0:0]
:POSTROUTING ACCEPT [0:0]
-A POSTROUTING -p tcp -m tcp --syn -m tcpmss --mss 1400:1536 -j TCPMSS --clamp-mss-to-pmtu
-A POSTROUTING -o vlan1 -s fd00::/8 -j SNAT --to-source 2001:db8:fe00:8175::1d
COMMIT

De façon usuelle, il faut «surveiller» les compteurs associés à chaque règle pour en mesurer l'utilisation. À partir des deux jeux de règles donnés ci-dessus, on obtient les résultats suivants.

# iptables -t nat -vnL POSTROUTING
Chain POSTROUTING (policy ACCEPT 10 packets, 975 bytes)
 pkts bytes target     prot opt in     out     source       destination         
    7   420 TCPMSS     tcp  --  *      *       0.0.0.0/0    0.0.0.0/0    tcp flags:0x17/0x02 tcpmss match 1400:1536 TCPMSS clamp to PMTU
  143  9668 SNAT       all  --  *      vlan1   0.0.0.0/0    0.0.0.0/0    to:192.0.2.29
# ip6tables -t nat -vnL POSTROUTING
Chain POSTROUTING (policy ACCEPT 117 packets, 11199 bytes)
 pkts bytes target     prot opt in     out     source       destination         
   94  7520 TCPMSS     tcp      *      *       ::/0         ::/0         tcp flags:0x17/0x02 tcpmss match 1400:1536 TCPMSS clamp to PMTU
   12  1112 SNAT       all      *      vlan1   fd00::/8     ::/0         to:2001:db8:fe00:8175::1d

4.8. Lancement des systèmes virtuels

On lance deux instances de systèmes virtuels dans chacun des deux VLANs Orange et Vert à l'aide du script suivant :

#!/bin/bash

../scripts/ovs-startup.sh orange.qed 1024 0
../scripts/ovs-startup.sh green.qed 1024 1

Le code du script de lancement d'une machine virtuelle raccordée à un commutateur Open vSwitch est donné dans le guide Virtualisation système et enseignement.

Dans ce script, l'instance orange.qed utilise le cordon de brassage tap0. Ce cordon a été brassé sur un port en mode accès associé au VLAN 10. Son adresse MAC est générée automatiquement en fonction du numéro du cordon : ba:ad:ca:fe:00:00.

De la même façon, l'instance green.qed utilise le cordon de brassage tap1. Ce cordon a été brassé sur un autre port en mode accès associé au VLAN 20. Son adresse MAC est générée automatiquement en fonction du numéro du cordon : ba:ad:ca:fe:00:01.

On visualise l'état des connexions en consultant la table CAM ( Content-addressable memory) du commutateur dsw-host.

$ sudo ovs-appctl fdb/show dsw-host
 port  VLAN  MAC                Age
    4    20  ba:ad:ca:fe:00:01    3
    5    10  66:d2:01:39:4a:21    3
    3    10  ba:ad:ca:fe:00:00    3
    6    20  ee:8f:84:8e:cb:a8    3
    1     0  de:56:80:40:1d:ed    0
    2     0  42:d9:5d:6c:89:d8    0

4.9. Tests d'interconnexion entre réseaux

Depuis le système virtuel dans le VLAN Orange, on effectue une série de tests ICMP et HTTP.

  1. Vers le système virtuel du VLAN Vert :

    $ ping6 -c 2 fd6e:c073:b4a3:14:b8ad:caff:fefe:1
    PING fd6e:c073:b4a3:14:b8ad:caff:fefe:1(fd6e:c073:b4a3:14:b8ad:caff:fefe:1) 56 data bytes
    64 bytes from fd6e:c073:b4a3:14:b8ad:caff:fefe:1: icmp_seq=1 ttl=63 time=0.986 ms
    64 bytes from fd6e:c073:b4a3:14:b8ad:caff:fefe:1: icmp_seq=2 ttl=63 time=1.10 ms
    
    --- fd6e:c073:b4a3:14:b8ad:caff:fefe:1 ping statistics ---
    2 packets transmitted, 2 received, 0% packet loss, time 1001ms
    rtt min/avg/max/mdev = 0.986/1.047/1.108/0.061 ms
  2. Vers un hôte situé sur l'Internet :

    $ ping6 -nc 2 www.iana.org
    PING www.iana.org(2620:0:2d0:200::8) 56 data bytes
    64 bytes from 2620:0:2d0:200::8: icmp_seq=1 ttl=51 time=183 ms
    64 bytes from 2620:0:2d0:200::8: icmp_seq=2 ttl=51 time=182 ms
    
    --- www.iana.org ping statistics ---
    2 packets transmitted, 2 received, 0% packet loss, time 1001ms
    rtt min/avg/max/mdev = 182.993/183.289/183.585/0.296 ms
  3. Chargement de page web.

    $ wget -6 -O /dev/null http://inetdoc.net
    --2015-10-21 14:03:05--  http://inetdoc.net/
    Résolution de inetdoc.net (inetdoc.net)… 2a01:6600:8083:c300::1
    Connexion à inetdoc.net (inetdoc.net)|2a01:6600:8083:c300::1|:80… connecté.
    requête HTTP transmise, en attente de la réponse… 200 OK
    Taille : 27201 (27K) [text/html]
    Sauvegarde en : « /dev/null »
    
    /dev/null          100%[=================>]  26,56K  --.-KB/s   ds 0,06s  
    
    2015-10-21 14:03:06 (416 KB/s) — « /dev/null » sauvegardé [27201/27201]

Enfin, il est possible de faire des tests de performances réseau avec l'outil iperf. Voici un échantillon de mesures entre les deux VLANs Orange et Vert.

  • Serveur côté VLAN Vert :

    etu@green-clnt:~$ iperf -w 320k -V -s
    ------------------------------------------------------------
    Server listening on TCP port 5001
    TCP window size:  320 KByte
    ------------------------------------------------------------
    [  4] local fd6e:c073:b4a3:14:b8ad:caff:fefe:1 port 5001 connected with 
                    fd6e:c073:b4a3:a:b8ad:caff:fefe:0 port 48032
    [ ID] Interval       Transfer     Bandwidth
    [  4]  0.0-30.0 sec  6.06 GBytes  1.74 Gbits/sec
  • Client côté VLAN Orange :

    etu@orange-clnt:~$ iperf -w 320k -P 8 -i 2 -t 30 -V \
            -c fd6e:c073:b4a3:14:b8ad:caff:fefe:1
    ------------------------------------------------------------
    Client connecting to fd6e:c073:b4a3:14:b8ad:caff:fefe:1, TCP port 5001
    TCP window size:  320 KByte
    ------------------------------------------------------------
    [  3] local fd6e:c073:b4a3:a:b8ad:caff:fefe:0 port 48032 connected with
                    fd6e:c073:b4a3:14:b8ad:caff:fefe:1 port 5001
    [ ID] Interval       Transfer     Bandwidth
    <snip/>
    [  3]  0.0-30.0 sec  6.06 GBytes  1.74 Gbits/sec