A l’intérieur d’un réseau L3VPN MPLS, le routage est seulement basé sur les labels, indépendamment des adresses IP transportées.

En bordure (edge), le PE d’entrée (ingress PE), la trame IP native est reçue et c’est évidemment une opération de routage IP qui est effectuée.

En revanche, le PE de sortie, (egress PE), reçoit des trames MPLS taggées avec le seul label de service, reflet dataplane des routes IP annoncées au réseau MPLS. Le PE a donc la possibilité

  • soit d’ignorer le label pour router les trames reçues (IP lookup),
  • soit d’utiliser ce label pour commuter le paquet. Ce qui revient à dire que le PE d’entrée « tunnelise » les trames jusqu’au CE distant.

Après 20 ans d’expertise sur les réseaux MPLS sans avoir à m’inquiéter pour ce PE de sortie, j’ai eu un cas d’usage où je pouvais résoudre un problème de scalabilité, si le comportement du PE de sortie est de type MPLS.

Le use case

J’ai un réseau de type hub and spoke avec plusieurs centaines de CE qui converge via une collecte de niveau 2 vers un couple de routeurs Hub, à droite je retrouve des centaines de CE colocalisés sur un même LAN non MPLS. Chaque CE gère une dizaine de VRFs.

Le Hub, tout en muscles, est un switch L3 qui gère les interfaces 100Gb/s.

Malheureusement, côté control plane, il est incapable de recevoir les milliers de sessions BGP. L’idée est d’ajouter un routeur déporté pour gérer les sessions BGP et piloter le Hub à travers la session MPLS (bgp vpnv4) pour lui donner les bons next-hop (labels), sans lui donner les routes clientes. Bref, séparer le control plane du data plane ou encore convertir mon PE en routeur P !

Maintenant, il me reste à espérer que le PE puisse utiliser les labels pour éviter le lookup IP !

Le lab

Plutôt que de me perdre dans la norme MPLS, je vais reproduire ce « dilemme du PE » sur un petit lab, composé de :

  • 2 routeurs formant le backbone MPLS
  • 1 routeur CE derrière le PE de sortie
  • 2 end points pour vérifier la connectivité de bout en bout

Mise en place du service L3VPN

Commençons par construire le service L3VPN classique. La configuration est sans surprise :

Construction du backbone MPLS

interface Loopback10
 description -- LDP --
 ip address 10.0.0.{{id}} 255.255.255.255

mpls ldp router-id Loopback10 
mpls label range 1{{id}}000 1{{id}}999	! tag the label origin
mpls label protocol ldp
mpls ip propagate-ttl	! ensure that mpls replies to tracert 

no mpls ldp advertise-labels	! advertise only looopback 10
ip access-list standard LDP
  permit 10.0.0.0 0.0.0.255
mpls ldp advertise-labels for LDP

interface GigabitEthernet3.10
 description -- mpls --
 encapsulation dot1Q 10
 ip address 10.0.1.{{id}} 255.255.255.254
 mpls ip

router eigrp 10
 network 10.0.0.0 0.0.0.255
 network 10.0.1.0 0.0.0.1
 passive-interface Loopback10
!
router bgp 10
 bgp log-neighbor-changes
 no bgp default ipv4-unicast
 neighbor 10.0.0.{{1-id}} remote-as 10
 neighbor 10.0.0.{{1-id}} update-source Loopback10
 !
 address-family ipv4
 exit-address-family
 !
 address-family vpnv4
  neighbor 10.0.0.{{1-id}} activate
  neighbor 10.0.0.{{1-id}} send-community both
 exit-address-family
 !

Construction de la VRF BLUE

vrf definition BLUE
 rd 10:1{{id}}00101
 route-target both 10:101
 address-family ipv4
 exit-address-family

interface GigabitEthernet2.101
 description -- to CE vrf BLUE --
 encapsulation dot1Q 101
 vrf forwarding BLUE
 ip address 10.0.101.1 255.255.255.252

router bgp 10
 address-family ipv4 vrf BLUE
  neighbor 10.0.101.2 remote-as 65000

Lecture des états

Tant que tout fonctionne encore correctement, nous notons les états sur les PE d’entrée et de sortie (pour le trafic allant de gauche à droite) :

egress-PE#sh mpls forwarding-table
Local      Outgoing   Prefix           Bytes Label   Outgoing   Next Hop
Label      Label      or Tunnel Id     Switched      interface
10001      Pop Label  10.0.0.1/32      0             Gi3.10     10.0.1.1
10002      No Label   172.16.101.0/24[V]   \
                                       590           Gi2.101    10.0.101.2

ingress-PE#sh ip cef vrf BLUE 172.16.101.10 det
172.16.101.0/24, epoch 2, flags [rib defined all labels]
  recursive via 10.0.0.0 label 10002
    nexthop 10.0.1.0 GigabitEthernet3.10

Le PE de sortie a affecté le label 10002 à la route L3VPN et semble l’utiliser pour commuter le paquet reçu, car le compteur « Bytes Label Switched » s’incrémente.

Altération du routage

Comme notre problème se ramène à créer une route MPLS sur le PE de sortie sans la route IP correspondante, afin d’avoir un dataplane MPLS correct, nous allons supprimer l’annonce du réseau 172.16.101.0/24 sur le CE :

CE#conf t
CE(config)#router bgp 65000
CE(config-router)#no network 172.16.101.0 m 255.255.255.0
CE(config-router)#end

Afin de produire un label sur le PE de sortie, nous redistribuons le réseau d’interconnexion entre le PE et le CE :

egress-PE#conf t
egress-PE(config)#router bgp 10
egress-PE(config-router)#address-family ipv4 vrf BLUE
egress-PE(config-router-af)#network 10.0.101.0 m 255.255.255.252
egress-PE(config-router-af)#end
egress-PE#

Enfin, sur le PE d’entrée nous ajoutons la route VRF du CE, en donnant comme next-hop l’interconnexion PE-CE que nous venons d’annoncer dans le backbone :

ingress-PE#conf t
ingress-PE(config)#ip route vrf BLUE 172.16.101.0 255.255.255.0 10.0.101.2 name --remote-CE--
ingress-PE(config)#

Tests

Nos modifications ont bien été prises en compte, car le ping s’est arrêté ! Il va falloir débugger.

Le traceroute effectué depuis la source indique bien un problème sur le PE de sortie :

Source#traceroute 172.16.101.10
Type escape sequence to abort.
Tracing the route to 172.16.101.10
VRF info: (vrf in name/id, vrf out name/id)
  1 192.168.101.1 1 msec 1 msec 1 msec
  2 10.0.101.1 3 msec 1 msec 1 msec
  3 10.0.1.0 !H  *  !H
Source#

Lecture des états

Sur le PE d’entrée, le routeur attribue correctement un label, avec une récursion de plus :

ingress-PE#sh ip cef vrf BLUE 172.16.101.0 detail
172.16.101.0/24, epoch 2
  recursive via 10.0.101.2
    recursive via 10.0.101.0/30
      recursive via 10.0.0.0 label 10003
        nexthop 10.0.1.0 GigabitEthernet3.10
ingress-PE# 

Cote PE de sortie, le label attribué est de type aggregate et le compteur Bytes Label Swaped reste scotché à 0, confirmant l’échec du ping.

egress-PE#sh mpls forwarding-table
Local      Outgoing   Prefix           Bytes Label   Outgoing   Next Hop
Label      Label      or Tunnel Id     Switched      interface
10001      Pop Label  10.0.0.1/32      0             Gi3.10     10.0.1.1
10003      No Label   10.0.101.0/30[V] 0             aggregate/BLUE
egress-PE#

Remise en fonctionnement

La voie IP

Si nous ajoutons la route sur le PE de sortie (sans la redistribuer), le ping reprend :

egress-PE#conf t
egress-PE(config)#ip route vrf BLUE 172.16.101.0 255.255.255.0 10.0.101.2
egress-PE(config)#

et le compteur Bytes Label Switched s’incrémente, indiquant que le label est utilisé, même si à l’évidence c’est un routage IP qui est effectué.

egress-PE#sh mpls forwarding-table
Local      Outgoing   Prefix           Bytes Label   Outgoing   Next Hop
Label      Label      or Tunnel Id     Switched      interface
10001      Pop Label  10.0.0.1/32      0             Gi3.10     10.0.1.1
10003      No Label   10.0.101.0/30[V] 10148         aggregate/BLUE

Nous avons donc la confirmation que le routeur effectue un lookup IP et le label est utilisé dans le seul but de mémoriser la VRF d’appartenance afin de pointer sur la bonne table de routage.

La voie MPLS

Toutefois, nous n’avons pas reproduit exactement les mêmes états dataplane, dans la mesure où le label utilisé a changé de type pour devenir aggregate.

Un moyen de forcer la génération d’un label de type nonaggregate est d’utiliser une route de type host en /32 en utilisant la curieuse syntaxe suivante :

egress-PE#conf t
egress-PE(config)#ip route vrf BLUE 10.0.101.2  255.255.255.255 Gi2.101 10.0.101.2
egress-PE(config)#no ip route vrf BLUE 172.16.101.0 255.255.255.0 10.0.101.2
egress-PE(config)#router bgp 10
egress-PE(config-router)#addr
egress-PE(config-router)#address-family ipv4 vrf BLUE
egress-PE(config-router-af)#network 10.0.101.2 m 255.255.255.255
egress-PE(config-router-af)#

Le label généré est bien de type nonaggregate,

egress-PE#
cisco on vty0 (193.105.90.11)sh mpls forwarding-table
Local      Outgoing   Prefix           Bytes Label   Outgoing   Next Hop
Label      Label      or Tunnel Id     Switched      interface
10001      Pop Label  10.0.0.1/32      0             Gi3.10     10.0.1.1
10002      No Label   10.101.0.0/30    0             Gi2.101    10.0.100.2
10003      No Label   10.0.101.0/30[V] 10148         aggregate/BLUE
10004      No Label   10.101.0.2/32[V] 0             drop
10005      No Label   10.0.101.2/32[V] 23600         Gi2.101    10.0.101.2
egress-PE#

Le PE d’entrée, en recevant un next-hop plus précis /32 utilise notre nouveau label :

ingress-PE#sh ip cef vrf BLUE 172.16.101.1 detail
172.16.101.0/24, epoch 2
  recursive via 10.0.101.2
    recursive via 10.0.0.0 label 10005
      nexthop 10.0.1.0 GigabitEthernet3.10
ingress-PE#

et la connexion de bout en bout est restaurée alors que le PE de sortie ne connaît pas la route IP transportée. La trace effectuée depuis le end point source indique bien l’utilisation de ce nouveau label :

Source#traceroute 172.16.101.10
Type escape sequence to abort.
Tracing the route to 172.16.101.10
VRF info: (vrf in name/id, vrf out name/id)
  1 192.168.101.1 1 msec 1 msec 1 msec
  2 10.0.101.1 [MPLS: Label 10005 Exp 0] 1 msec 1 msec 1 msec
  3 10.0.101.2 1 msec 2 msec 1 msec
  4 172.16.101.10 1 msec 1 msec 1 msec
Source#

Epilogue

A notre dilemme routage ou commutation, MPLS a sagement choisi une 3ème voie en laissant ouvertes les 2 possibilités. C’est l’état du label qui détermine l’opération faite par le dernier routeur.

En outre, en rajoutant la route statique 172.16.101.0/24, les 2 labels aggregate et nonaggregate sont présents sur le routeur, le traceroute, comme les compteurs, indique que la commutation est privilégiée : le fonctionnement intra protocole est préféré.

Après avoir compris cette différence, une recherche sur les labels aggregate/nonaggregate pointe sur un extrait du livre MPLS Fundamentals (https://www.ciscopress.com/articles/article.asp?p=680824) qui confirme nos conclusions :

To recap the label operations:

  • Pop—The top label is removed. The packet is forwarded with the remaining label stack or as an unlabeled packet.
  • Swap—The top label is removed and replaced with a new label.
  • Push—The top label is replaced with a new label (swapped), and one or more labels are added (pushed) on top of the swapped label.
  • Untagged/No Label—The stack is removed, and the packet is forwarded unlabeled.
  • Aggregate—The label stack is removed, and an IP lookup is done on the IP packet.

Ainsi mon design initial, tout exotique qu’il soit, respecte la norme MPLS !

Author

Philippe est architecte réseau chez un opérateur depuis 20 ans. Il a le double rôle de concevoir des réseaux pour les clients, puis de les faire fonctionner. Bien que passionné par l'innovation, il reste un fervent supporter de la RFC 1925 et garde tout son sens critique par rapport au hype et aux promesses féeriques des constructeurs. Ancien développeur, il tente de garder la main en programmant des Arduino en C ou des utilitaires opensource en Ruby. On peut également le croiser en randonnée dans les collines ou dans un club de bridge.

Write A Comment