Un brin de réseau


Tel un cahier de notes, ce blog propose des articles sur les technologies réseaux et leur utilisation pratique, le tout illustré avec des maquettes et des captures.

Python freeradius-api Python diffplus

MPLS LDP

Origine

LDP (Label Distribution Protocol) a été initialement évoqué dans la RFC 3031 décrivant l'architecture MPLS (Multiprotocol Label Switching) avant d'être spécifié dans la RFC 3036 :


      The MPLS architecture defines a label distribution protocol
      as a set of procedures by which one Label Switched Router (LSR)
      informs another of the meaning of labels used to forward traffic
      between and through them.
    

Son rôle est clair, à savoir assurer la distribution des labels entre LSR. Il est par la suite rappelé qu'il n'y a pas forcément qu'un seul protocole pour cela :


      The MPLS architecture does not assume a single label distribution
      protocol.  In fact, a number of different label distribution
      protocols are being standardized.
    

Toutefois, LDP est quasiment l'unique dans la pratique. Plus anciennement, il y avait aussi TDP (Tag Distribution Protocol) qui est, comme souvent, la version propriétaire de Cisco avant la standardisation établie par l'IETF (Internet Engineering Task Force). Est également évoquée l'utilisation de BGP (Border Gateway Protocol) pour la distribution des labels :


      If there is a standard, widely deployed routing algorithm which
      distributes those routes, it can be argued that label distribution is
      best achieved by piggybacking the label distribution on the
      distribution of the routes themselves.

      For example, BGP distributes such routes, and if a BGP speaker needs
      to also distribute labels to its BGP peers, using BGP to do the label
      distribution has a number of advantages.
    

En effet, ce dernier est tentant puisque son rôle primaire est justement la distribution des routes entre pairs. La distribution des labels viendrait s'adjoindre (piggybacking) aux routes distribuées. Ceci a été spécifié dans la RFC 3107. Finalement, BGP (MP-BGP pour être précis) est surtout utilisé dans la distribution des labels dédiés aux VPN (L2 et L3) sur MPLS : LDP distribue le premier niveau de label dédié à l'IGP—comme nous allons le voir ci-dessous—et MP-BGP le deuxième niveau de label dédié aux VPN—comme nous le verrons dans un prochain article. Enfin, noter que des travaux restés au statut de draft ont été menés pour distribuer les labels dans les IGP : draft-gredler-rtgwg-igp-label-advertisement, draft-gredler-isis-label-advertisement et draft-gredler-ospf-label-advertisement. C'est d'ailleurs de cette façon, dans les IGP, que sont distribués les labels dans le Segment Routing (technique de routage à la source qui utilise une stack de labels MPLS).

La maquette utilisée

Nous allons étudier comment sont alloués les labels puis distribués entre LSR à l'aide de la maquette suivante :

lab-mpls-ldp
Cette maquette simple se suffit de quatre LSR raccordés entre eux via des réseaux d'interco privés en /30. Chaque LSR possède de plus un ID unique privé en /32 (voir explication ci-dessous). Dans un véritable réseau opérateur, les réseaux d'interco et les LSR ID peuvent être publics ou privés, cela dépend des choix architecturaux—j'ai vu les deux. Nous pouvons par ailleurs considérer cet ensemble de routeurs comme un AS (Autonomous System) et le nommer backbone IP afin d'anticiper la suite de l'article.

Le lien avec IP

Cette section peut sembler évidente mais rappelons que MPLS est fortement lié au protocole L3 utilisé—bien souvent IP—comme le rappelle sa RFC :


      MPLS stands for "Multiprotocol" Label Switching, multiprotocol
      because its techniques are applicable to ANY network layer protocol.
      In this document, however, we focus on the use of IP as the network
      layer protocol.
    

Autrement dit, cela signifie qu'avant l'allocation des labels, leur distribution et le label switching proprement dit, il y a tout d'abord des réseaux IP—comme illustré dans la maquette précédente avec trois réseaux IP. Et c'est bien normal, les LSR parleront LDP via ces réseaux IP (plan de contrôle) avant de pouvoir parler MPLS sans utiliser IP (plan de données). Comme dans un AS, tous ces réseaux IP doivent être routés entre eux, soit statiquement soit dynamiquement avec un IGP. C'est une fois l'ensemble du routage IP opérationnel qu'il devient cohérent d'activer MPLS (et LDP) sur ce backbone IP alors nommé backbone IP/MPLS. Enfin, retenir que LDP constitue le plan de contrôle de MPLS (plan de données), à l'instar des IGP qui constituent le plan de contrôle d'IP (plan de données).

Étape 1 : l'allocation des labels

Les labels sont alloués localement par chaque LSR. Il y a une unicité locale mais pas globale (un même label peut être utilisé par différents LSR). Les règles sont les suivantes :

Exemple dans notre maquette :


                   R1                                    R2                                    R3                                    R4
    +-------------+------------+-------+  +-------------+------------+-------+  +-------------+------------+-------+  +-------------+------------+-------+
    | Route       | Type       | Label |  | Route       | Type       | Label |  | Route       | Type       | Label |  | Route       | Type       | Label |
    +-------------+------------+-------+  +-------------+------------+-------+  +-------------+------------+-------+  +-------------+------------+-------+
    | 10.0.0.0/30 | Connected  | 3     |  | 10.0.0.0/30 | Connected  | 3     |  | 10.0.0.4/30 | Connected  | 3     |  | 10.0.0.8/30 | Connected  | 3     |
    | 10.0.1.1/32 | Connected  | 3     |  | 10.0.0.4/30 | Connected  | 3     |  | 10.0.0.8/30 | Connected  | 3     |  | 10.0.1.4/32 | Connected  | 3     |
    | 10.0.0.4/30 | Static/IGP | 16    |  | 10.0.1.2/32 | Connected  | 3     |  | 10.0.1.3/32 | Connected  | 3     |  | 10.0.0.0/30 | Static/IGP | 16    |
    | 10.0.0.8/30 | Static/IGP | 17    |  | 10.0.0.8/30 | Static/IGP | 16    |  | 10.0.0.0/30 | Static/IGP | 19    |  | 10.0.0.4/30 | Static/IGP | 17    |
    | 10.0.1.2/32 | Static/IGP | 18    |  | 10.0.1.1/32 | Static/IGP | 17    |  | 10.0.1.1/32 | Static/IGP | 18    |  | 10.0.1.1/32 | Static/IGP | 18    |
    | 10.0.1.3/32 | Static/IGP | 19    |  | 10.0.1.3/32 | Static/IGP | 18    |  | 10.0.1.2/32 | Static/IGP | 17    |  | 10.0.1.2/32 | Static/IGP | 19    |
    | 10.0.1.4/32 | Static/IGP | 20    |  | 10.0.1.4/32 | Static/IGP | 19    |  | 10.0.1.4/32 | Static/IGP | 16    |  | 10.0.1.3/32 | Static/IGP | 20    |
    +-------------+------------+-------+  +-------------+------------+-------+  +-------------+------------+-------+  +-------------+------------+-------+
    

Les labels sont alloués au fur et à mesure de l'apparition des routes dans les routeurs. Cet ordre d'apparition dépend des annonces de l'IGP ainsi que des changements sur le réseau. Dans cette maquette simple, j'ai utilisé des routes statiques et dans un ordre volontairement inversé pour R3 afin d'avoir des labels différents, ce qui permettra de bien visualiser le label switching dans l'étape 3.

Plus généralement, les labels ne sont pas alloués à des routes mais à des FEC (Forwarding Equivalence Class). Une FEC est un groupe de paquets ayant des points communs. Chaque route est bien une FEC, le point commun des paquets étant le réseau de destination. La RFC de MPLS explique bien ceci :


      A label is a short, fixed length, locally significant identifier
      which is used to identify a FEC.

      Most commonly, a packet is assigned to a FEC based (completely or
      partially) on its network layer destination address.
    

Voici des extraits de R2 et de R3 (les labels ont seulement été alloués localement et non distribués encore) :

R2 R3

  R2#show running-config

  ! LSR ID and subnet configuration
  interface Loopback0
   ip address 10.0.1.2 255.255.255.255
  interface FastEthernet0/0
   ip address 10.0.0.2 255.255.255.252
   mpls ip ! enable both MPLS and LDP
  interface FastEthernet0/1
   ip address 10.0.0.5 255.255.255.252
   mpls ip ! enable both MPLS and LDP

  ! The IP routes configuration
  ip route 10.0.0.8 255.255.255.252 10.0.0.6
  ip route 10.0.1.1 255.255.255.255 10.0.0.1
  ip route 10.0.1.3 255.255.255.255 10.0.0.6
  ip route 10.0.1.4 255.255.255.255 10.0.0.6

  ! Show the IP Routing Information Base (RIB)
  R2#show ip route
  Codes: C - connected, S - static, (…)
  C       10.0.0.0/30 is directly connected, FastEthernet0/0
  C       10.0.0.4/30 is directly connected, FastEthernet0/1
  C       10.0.1.2/32 is directly connected, Loopback0
  S       10.0.0.8/30 [1/0] via 10.0.0.6
  S       10.0.1.1/32 [1/0] via 10.0.0.1
  S       10.0.1.3/32 [1/0] via 10.0.0.6
  S       10.0.1.4/32 [1/0] via 10.0.0.6

  ! Show the LDP Label Information Base (LIB)
  R2#show mpls ip binding
    10.0.0.0/30
          in label:     imp-null
    10.0.0.4/30
          in label:     imp-null
    10.0.0.8/30
          in label:     16
    10.0.1.1/32
          in label:     17
    10.0.1.2/32
          in label:     imp-null
    10.0.1.3/32
          in label:     18
    10.0.1.4/32
          in label:     19

  ! Show the Label Forwarding Information Base (LFIB)
  R2#show mpls forwarding-table
  Local  Outgoing    Prefix            Bytes tag  Outgoing   Next Hop
  tag    tag or VC   or Tunnel Id      switched   interface
  16     Untagged    10.0.0.8/30       0          Fa0/1      10.0.0.6
  17     Untagged    10.0.1.1/32       0          Fa0/0      10.0.0.1
  18     Untagged    10.0.1.3/32       0          Fa0/1      10.0.0.6
  19     Untagged    10.0.1.4/32       0          Fa0/1      10.0.0.6
              

  R3#show running-config

  ! LSR ID and subnet configuration
  interface Loopback0
   ip address 10.0.1.3 255.255.255.255
  interface FastEthernet0/0
   ip address 10.0.0.6 255.255.255.252
   mpls ip ! enable both MPLS and LDP
  interface FastEthernet0/1
   ip address 10.0.0.9 255.255.255.252
   mpls ip ! enable both MPLS and LDP

  ! The IP routes configuration
  ip route 10.0.0.0 255.255.255.252 10.0.0.5
  ip route 10.0.1.1 255.255.255.255 10.0.0.5
  ip route 10.0.1.2 255.255.255.255 10.0.0.5
  ip route 10.0.1.4 255.255.255.255 10.0.0.10

  ! Show the IP Routing Information Base (RIB)
  R3#show ip route
  Codes: C - connected, S - static, (…)
  C       10.0.0.4/30 is directly connected, FastEthernet0/0
  C       10.0.0.8/30 is directly connected, FastEthernet0/1
  C       10.0.1.3/32 is directly connected, Loopback0
  S       10.0.0.0/30 [1/0] via 10.0.0.5
  S       10.0.1.1/32 [1/0] via 10.0.0.5
  S       10.0.1.2/32 [1/0] via 10.0.0.5
  S       10.0.1.4/32 [1/0] via 10.0.0.10

  ! Show the LDP Label Information Base (LIB)
  R3#show mpls ip binding
    10.0.0.0/30
          in label:     19
    10.0.0.4/30
          in label:     imp-null
    10.0.0.8/30
          in label:     imp-null
    10.0.1.1/32
          in label:     18
    10.0.1.2/32
          in label:     17
    10.0.1.3/32
          in label:     imp-null
    10.0.1.4/32
          in label:     16

  ! Show the Label Forwarding Information Base (LFIB)
  R3#show mpls forwarding-table
  Local  Outgoing    Prefix            Bytes tag  Outgoing   Next Hop
  tag    tag or VC   or Tunnel Id      switched   interface
  16     Untagged    10.0.1.4/32       0          Fa0/1      10.0.0.10
  17     Untagged    10.0.1.2/32       0          Fa0/0      10.0.0.5
  18     Untagged    10.0.1.1/32       0          Fa0/0      10.0.0.5
  19     Untagged    10.0.0.0/30       0          Fa0/0      10.0.0.5
              

Pour les curieux, voici les FIB de R2 et R3 :

R2 R3

  ! Show the Forwarding Information Base (FIB)
  R2#show ip cef
  Prefix              Next Hop         Interface
  0.0.0.0/0           drop             Null0 (default route handler entry)
  0.0.0.0/8           drop
  0.0.0.0/32          receive
  10.0.0.0/30         attached         FastEthernet0/0
  10.0.0.0/32         receive
  10.0.0.2/32         receive
  10.0.0.3/32         receive
  10.0.0.4/30         attached         FastEthernet0/1
  10.0.0.4/32         receive
  10.0.0.5/32         receive
  10.0.0.7/32         receive
  10.0.0.8/30         10.0.0.6         FastEthernet0/1
  10.0.1.1/32         10.0.0.1         FastEthernet0/0
  10.0.1.2/32         receive
  10.0.1.3/32         10.0.0.6         FastEthernet0/1
  10.0.1.4/32         10.0.0.6         FastEthernet0/1
  127.0.0.0/8         drop
  224.0.0.0/4         drop
  224.0.0.0/24        receive
  240.0.0.0/4         drop
  255.255.255.255/32  receive
              

  ! Show the Forwarding Information Base (FIB)
  R3#show ip cef
  Prefix              Next Hop         Interface
  0.0.0.0/0           drop             Null0 (default route handler entry)
  0.0.0.0/8           drop
  0.0.0.0/32          receive
  10.0.0.0/30         10.0.0.5         FastEthernet0/0
  10.0.0.4/30         attached         FastEthernet0/0
  10.0.0.4/32         receive
  10.0.0.6/32         receive
  10.0.0.7/32         receive
  10.0.0.8/30         attached         FastEthernet0/1
  10.0.0.8/32         receive
  10.0.0.9/32         receive
  10.0.0.11/32        receive
  10.0.1.1/32         10.0.0.5         FastEthernet0/0
  10.0.1.2/32         10.0.0.5         FastEthernet0/0
  10.0.1.3/32         receive
  10.0.1.4/32         10.0.0.10        FastEthernet0/1
  127.0.0.0/8         drop
  224.0.0.0/4         drop
  224.0.0.0/24        receive
  240.0.0.0/4         drop
  255.255.255.255/32  receive
              

Étape 2 : la distribution des labels

Maintenant que chaque LSR a alloué des labels à chaque FEC (chaque route), il leur reste à les distribuer aux voisins :

lab-mpls-ldp-lmm
Une fois les labels alloués localement, chaque LSR les annonce à son (ses) voisin(s) avec les FEC associés. Nous retrouvons finalement les tableaux présentés plus haut (sans la colonne du type de route) lesquels sont envoyés via des messages LDP Label Mapping Message.

Voyons une capture pour analyser concrètement un message LDP Label Mapping Message :

cap-mpls-ldp-label-mapping-message
Nous retrouvons la distribution de labels de R2 à R3. Premier constat et sans surprise, LDP utilise bien IP pour transporter ses messages (via TCP), d'où la nécessité d'avoir avant tout un routage fonctionnel dans l'AS (comme expliqué précédemment). Autrement, pas de plan de contrôle MPLS et donc pas de MPLS. Deuxième constat, un même message LDP peut contenir plusieurs Label Mapping Message, sept en l'occurrence, chacun correspondant à une FEC (une route) de R2. Comme anticipé plus haut, à la FEC 10.0.0.8/30 a été alloué le label 0x00010 (base hexadécimale) soit 16 (base décimale). Télécharger la capture pour visualiser les autres Label Mapping Message.

Voici les LIB et les LFIB de R2 et R3 après distribution des labels :

R2 R3

  ! The LDP Label Information Base (LIB)
  R2#show mpls ip binding
    10.0.0.0/30
          in label:     imp-null
          out label:    imp-null  lsr: 10.0.1.1:0
          out label:    19        lsr: 10.0.1.3:0
    10.0.0.4/30
          in label:     imp-null
          out label:    16        lsr: 10.0.1.1:0
          out label:    imp-null  lsr: 10.0.1.3:0
    10.0.0.8/30
          in label:     16
          out label:    17        lsr: 10.0.1.1:0
          out label:    imp-null  lsr: 10.0.1.3:0       inuse
    10.0.1.1/32
          in label:     17
          out label:    imp-null  lsr: 10.0.1.1:0       inuse
          out label:    18        lsr: 10.0.1.3:0
    10.0.1.2/32
          in label:     imp-null
          out label:    18        lsr: 10.0.1.1:0
          out label:    17        lsr: 10.0.1.3:0
    10.0.1.3/32
          in label:     18
          out label:    19        lsr: 10.0.1.1:0
          out label:    imp-null  lsr: 10.0.1.3:0       inuse
    10.0.1.4/32
          in label:     19
          out label:    20        lsr: 10.0.1.1:0
          out label:    16        lsr: 10.0.1.3:0       inuse

  ! Show the Label Forwarding Information Base (LFIB)
  R2#show mpls forwarding-table
  Local  Outgoing    Prefix            Bytes tag  Outgoing   Next Hop
  tag    tag or VC   or Tunnel Id      switched   interface
  16     Pop tag     10.0.0.8/30       0          Fa0/1      10.0.0.6
  17     Pop tag     10.0.1.1/32       0          Fa0/0      10.0.0.1
  18     Pop tag     10.0.1.3/32       0          Fa0/1      10.0.0.6
  19     16          10.0.1.4/32       0          Fa0/1      10.0.0.6
              

  ! The LDP Label Information Base (LIB)
  R3#show mpls ip binding
    10.0.0.0/30
          in label:     19
          out label:    imp-null  lsr: 10.0.1.2:0       inuse
          out label:    16        lsr: 10.0.1.4:0
    10.0.0.4/30
          in label:     imp-null
          out label:    imp-null  lsr: 10.0.1.2:0
          out label:    17        lsr: 10.0.1.4:0
    10.0.0.8/30
          in label:     imp-null
          out label:    16        lsr: 10.0.1.2:0
          out label:    imp-null  lsr: 10.0.1.4:0
    10.0.1.1/32
          in label:     18
          out label:    17        lsr: 10.0.1.2:0       inuse
          out label:    18        lsr: 10.0.1.4:0
    10.0.1.2/32
          in label:     17
          out label:    imp-null  lsr: 10.0.1.2:0       inuse
          out label:    19        lsr: 10.0.1.4:0
    10.0.1.3/32
          in label:     imp-null
          out label:    18        lsr: 10.0.1.2:0
          out label:    20        lsr: 10.0.1.4:0
    10.0.1.4/32
          in label:     16
          out label:    19        lsr: 10.0.1.2:0
          out label:    imp-null  lsr: 10.0.1.4:0       inuse

  ! Show the Label Forwarding Information Base (LFIB)
  R3#show mpls forwarding-table
  Local  Outgoing    Prefix            Bytes tag  Outgoing   Next Hop
  tag    tag or VC   or Tunnel Id      switched   interface
  16     Pop tag     10.0.1.4/32       0          Fa0/1      10.0.0.10
  17     Pop tag     10.0.1.2/32       0          Fa0/0      10.0.0.5
  18     17          10.0.1.1/32       0          Fa0/0      10.0.0.5
  19     Pop tag     10.0.0.0/30       0          Fa0/0      10.0.0.5
              

Nous retrouvons dans les LIB, pour chaque FEC, les labels distribués par chaque LSR voisin. Par exemple, pour la FEC 10.0.1.4/32, R2 a :

R2 a reçu deux labels pour une même FEC. Le flag inuse indique lequel est utilisé dans le plan de données (LFIB). Le choix est effectué selon ses propres routes : le nexthop de 10.0.1.4/32 étant R3 pour R2, c'est donc naturellement le label associé qui a été choisi et qui apparaît dans la LFIB. Apparaît aussi dans cette dernière le label qui sera appliqué en sortie vers R3 : si R2 reçoit un paquet à destination de 10.0.1.4/32 de la part de R1, ce sera avec le label 19, lequel sera changé en label 16 vers R3—c'est le label switching proprement dit du plan de données.

Remarquer enfin le terme de Pop tag dans les LFIB de R2 et de R3 qui est évidemment lié au label particulier Implicit NULL évoqué plus haut. Nous reviendrons dessus dans l'étape suivante, une illustration permettant plus facilement de comprendre le mécanisme.

Étape 3 : le label switching

Voyons maintenant ce qu'il se passe si R1 ping R4 avec des captures :

cap-mpls-ldp-label-mapping-message
Capture sur le lien R1 — R2. Noter le paquet IP encapsulé dans MPLS.
cap-mpls-ldp-label-mapping-message
Capture sur le lien R2 — R3. Noter le paquet IP encapsulé dans MPLS.
cap-mpls-ldp-label-mapping-message
Capture sur le lien R3 — R4. Noter l'absence de MPLS mais seulement la présence du paquet IP.

Pour les deux premières captures, aucune surprise, le label switching a bien opéré conformément aux LFIB de R1 et de R2 : R1 a encapsulé le paquet IP dans MPLS en appliquant le label 19, lequel a été changé par R2 en label 16. Ce que nous voyons sur ces captures, c'est le fameux LSP (Label Switch Path) qui en pratique s'étend à plus de deux sauts.

Sur la dernière capture cependant, nous ne voyons plus de MPLS. R3 a enlevé le label avant d'envoyer le paquet à R4 qui est le routeur de destination. En d'autres termes, l'avant-dernier (penultimate) routeur a enlevé le label avant d'envoyer le paquet au dernier (ultimate) routeur du LSP. Ce mécanisme bien connu s'appelle PHP (Penultimate Hop Popping) et a été décrit dans l'architecture MPLS :


      Once R[n-1] has decided to send the packet to Rn, the label
      no longer has any function, and need no longer be carried.

      There is also a practical advantage to doing penultimate hop popping.
      If one does not do this, then when the LSP egress receives a packet,
      it first looks up the top label, and determines as a result of that
      lookup that it is indeed the LSP egress.  Then it must pop the stack,
      and examine what remains of the packet.  If there is another label on
      the stack, the egress will look this up and forward the packet based
      on this lookup.  (In this case, the egress for the packet's level m
      LSP is also an intermediate node for its level m-1 LSP.)  If there is
      no other label on the stack, then the packet is forwarded according
      to its network layer destination address.  Note that this would
      require the egress to do TWO lookups, either two label lookups or a
      label lookup followed by an address lookup.
    

Pour résumer cet extrait, rien n'empêche en réalité de conserver le label et de l'envoyer au dernier routeur—ce mécanisme existe et s'appelle UHP (Ultimate Hop Popping) par opposition au PHP. Cependant, cela ne présente aucun intérêt : nous voyons bien que R3 est adjacent à R4, autant enlever le label pour lui éviter ce travail. Car en effet, sans cette manipulation préalable, R4 devrait effectuer deux opérations : enlever le label et interpréter le paquet IP (ou interpréter le label suivant s'il s'agit d'une stack de labels, par exemple dans le cas de VPN sur MPLS qui sera abordé dans un prochain article), ce qui requiert du temps processeur alors que le but de MPLS est justement d'optimiser les réseaux. R3 sait qu'il faut enlever (to pop) le label car la route 10.0.1.4/32 lui a été annoncé avec le label Implicit NULL dont le rôle est finalement de permettre le PHP—voici donc l'explication de ce label particulier.

Voici un exemple du mécanisme UHP :

R4 R3

  ! Advertise Explicit Null label in place of Implicit Null
  R4(config)#mpls ldp explicit-null

  ! R4 distribue dorénavant ses routes directement connectées
  ! avec le label 0, ce qui sera visible sur R3.
              

  ! The LDP Label Information Base (LIB)
  R3#show mpls ip binding
    10.0.0.0/30
          in label:     19
          out label:    imp-null  lsr: 10.0.1.2:0       inuse
          out label:    16        lsr: 10.0.1.4:0
    10.0.0.4/30
          in label:     imp-null
          out label:    imp-null  lsr: 10.0.1.2:0
          out label:    17        lsr: 10.0.1.4:0
    10.0.0.8/30
          in label:     imp-null
          out label:    16        lsr: 10.0.1.2:0
          out label:    exp-null  lsr: 10.0.1.4:0
    10.0.1.1/32
          in label:     18
          out label:    17        lsr: 10.0.1.2:0       inuse
          out label:    18        lsr: 10.0.1.4:0
    10.0.1.2/32
          in label:     17
          out label:    imp-null  lsr: 10.0.1.2:0       inuse
          out label:    19        lsr: 10.0.1.4:0
    10.0.1.3/32
          in label:     imp-null
          out label:    18        lsr: 10.0.1.2:0
          out label:    20        lsr: 10.0.1.4:0
    10.0.1.4/32
          in label:     16
          out label:    19        lsr: 10.0.1.2:0
          out label:    exp-null  lsr: 10.0.1.4:0       inuse

  ! Show the Label Forwarding Information Base (LFIB)
  R3#show mpls forwarding-table
  Local  Outgoing    Prefix            Bytes tag  Outgoing   Next Hop
  tag    tag or VC   or Tunnel Id      switched   interface
  16     0           10.0.1.4/32       0          Fa0/1      10.0.0.10
  17     Pop tag     10.0.1.2/32       0          Fa0/0      10.0.0.5
  18     17          10.0.1.1/32       0          Fa0/0      10.0.0.5
  19     Pop tag     10.0.0.0/30       0          Fa0/0      10.0.0.5
              

Nous voyons dans la LIB de R3 que pour joindre les routes directement connectées de R4, le label Explicit NULL sera appliqué, ce que nous pouvons vérifier avec le même ping que précédemment (de R1 à R4) :

cap-mpls-ping-r1-r4-3-exp-null
Capture sur le lien R3 — R4. Noter cette fois la présence de MPLS avec le label Explicit NULL soit 0.

Bonus #1 : l'ECMP (Equal-Cost Multi-path Routing)

La résilience des réseaux est souvent assurée par plusieurs routes possibles vers la même destination. Lorsque ces routes sont à coût égal, le mécanisme d'ECMP est fréquemment appliqué : du load balancing a alors lieu entre ces routes, généralement en mode per-flow par opposition au mode per-packet. Dans le premier mode, un même flux—défini par le couple L3 (IPsource, IPdestination) auquel peut s'ajouter le couple L4 (Portsource, Portdestination) dans le cas TCP ou UDP—emprunte toujours le même chemin, ce qui garantit l'ordre d'arrivée des paquets (nécessaire pour la VoIP par exemple). Dans le deuxième mode, un même flux emprunte des chemins différents—ce qui a souvent pour conséquence des paquets out-of-order à la destination.

Pour illustrer l'ECMP (en mode per-flow mais cela n'a pas d'importance ici), ajoutons un routeur R5 à la maquette :

lab-mpls-ldp-ecmp
R1 a dorénavant deux routes possibles à coût égal vers R4 (via R2 et via R5). De même, R3 a dorénavant deux routes possibles à coût égal vers R1 (via R2 et via R5).

Affichons les extraits de configuration pertinents de R1 et R3 (rien de particulier sur R5, voir les configurations précédentes) :

R1 R3

  R1#show running-config

  ! LSR ID and subnet configuration
  (…)
  interface FastEthernet0/1
   ip address 10.0.0.13 255.255.255.252
   mpls ip ! enable both MPLS and LDP

  ! The IP routes configuration
  (…)
  ip route 10.0.1.4 255.255.255.255 10.0.0.2
  ip route 10.0.1.4 255.255.255.255 10.0.0.14
  ip route 10.0.1.5 255.255.255.255 10.0.0.14

  ! Show the IP Routing Information Base (RIB)
  R1#show ip route
  Codes: C - connected, S - static, (…)
  (…)
  C       10.0.0.12/30 is directly connected, FastEthernet0/1
  S       10.0.1.4/32 [1/0] via 10.0.0.14
                      [1/0] via 10.0.0.2
  S       10.0.1.5/32 [1/0] via 10.0.0.14

  ! Show the IP Forwarding Information Base (FIB)
  R1#show ip cef
  Prefix              Next Hop             Interface
  (…)
  10.0.0.12/30        attached             FastEthernet0/1
  10.0.0.12/32        receive
  10.0.0.13/32        receive
  10.0.0.14/32        10.0.0.14            FastEthernet0/1
  10.0.0.15/32        receive
  10.0.1.4/32         10.0.0.14            FastEthernet0/1
                      10.0.0.2             FastEthernet0/0
  10.0.1.5/32         10.0.0.14            FastEthernet0/1
  (…)
              

  R3#show running-config

  ! LSR ID and subnet configuration
  (…)
  interface FastEthernet1/0
   ip address 10.0.0.18 255.255.255.252
   mpls ip ! enable both MPLS and LDP

  ! The IP routes configuration
  (…)
  ip route 10.0.1.1 255.255.255.255 10.0.0.5
  ip route 10.0.1.1 255.255.255.255 10.0.0.17
  ip route 10.0.1.5 255.255.255.255 10.0.0.17

  ! Show the IP Routing Information Base (RIB)
  R3#show ip route
  Codes: C - connected, S - static, (…)
  (…)
  C       10.0.0.16/30 is directly connected, FastEthernet1/0
  S       10.0.1.1/32 [1/0] via 10.0.0.17
                      [1/0] via 10.0.0.5
  S       10.0.1.5/32 [1/0] via 10.0.0.17

  ! Show the IP Forwarding Information Base (FIB)
  R3#show ip cef
  Prefix              Next Hop             Interface
  (…)
  10.0.0.16/30        attached             FastEthernet1/0
  10.0.0.16/32        receive
  10.0.0.17/32        10.0.0.17            FastEthernet1/0
  10.0.0.18/32        receive
  10.0.0.19/32        receive
  10.0.1.1/32         10.0.0.17            FastEthernet1/0
                      10.0.0.5             FastEthernet0/0
  10.0.1.5/32         10.0.0.17            FastEthernet1/0
  (…)
              

Une fois encore, avant même d'aborder MPLS et LDP, nous voyons que l'ECMP est présent point de vue IP : R1 et R3 ont bien chacun deux routes possibles à coût égal vers la même destination, ce qui est visible dans leur RIB et dans leur FIB. Regardons maintenant point de vue LIB et LFIB :

R1 R3

  ! The LDP Label Information Base (LIB)
  R1#show mpls ip binding
    (…)
    10.0.1.4/32
          in label:     20
          out label:    18        lsr: 10.0.1.5:0       inuse
          out label:    19        lsr: 10.0.1.2:0       inuse
    (…)


  ! Show the Label Forwarding Information Base (LFIB)
  R1#show mpls forwarding-table
  Local  Outgoing    Prefix            Bytes tag  Outgoing   Next Hop
  tag    tag or VC   or Tunnel Id      switched   interface
  (…)
  20     18          10.0.1.4/32       0          Fa0/1      10.0.0.14
         19          10.0.1.4/32       0          Fa0/0      10.0.0.2
  (…)
              

  ! The LDP Label Information Base (LIB)
  R3#show mpls ip binding
    (…)
    10.0.1.1/32
          in label:     18
          out label:    18        lsr: 10.0.1.4:0
          out label:    17        lsr: 10.0.1.2:0       inuse
          out label:    16        lsr: 10.0.1.5:0       inuse
    (…)

  ! Show the Label Forwarding Information Base (LFIB)
  R1#show mpls forwarding-table
  Local  Outgoing    Prefix            Bytes tag  Outgoing   Next Hop
  tag    tag or VC   or Tunnel Id      switched   interface
  (…)
  18     16          10.0.1.1/32       0          Fa1/0      10.0.0.17
         17          10.0.1.1/32       0          Fa0/0      10.0.0.5
  (…)
              

R1 a bien les deux labels actifs en même temps, ce qui est visible dans la LIB avec le flag inuse doublement présent et dans la LFIB avec les deux entrées pour la même FEC. Même constat pour R3 (avec une troisième entrée dans la LIB qui correspond à l'annonce de R4 et qui n'est évidemment pas utilisé). L'ECMP est donc bien présent également point de vue MPLS. Le load balancing sera ensuite visible dans le plan de données. Si R1 ping R4, la requête ICMP sera routée vers R2 ou R5. Lorsque R4 répondra à R1, la réponse ICMP sera d'abord forcément routée vers R3 (car c'est son seul nexthop), qui, à son tour, la routera vers R2 ou R5. Noter donc que du routage asymétrique peut avoir lieu : la requête ICMP peut passer par R2 et la réponse revenir par R5. Ce n'est pas gênant mais ça a le mérite d'être constaté.

Bonus #2 : la libération de labels

Naturellement, LDP gère à la fois l'allocation et la libération de labels car les topologies réseaux sont amenées à changer. Imaginons que le lien entre R3 et R4 disparaît (via un shutdown sur l'interface de R3 vers R4 par exemple). Voyons une capture pour analyser concrètement un message LDP de libération :

cap-mpls-lwm
R3 signale à R2 qu'il faut libérer les labels associés aux FEC 10.0.0.8/30 et 10.0.1.4/32. Télécharger la capture pour visualiser les deux Label Withdraw Message.
cap-mpls-lrm
R2 indique à R3 qu'il a libéré les labels associés aux FEC 10.0.0.8/30 et 10.0.1.4/32. Télécharger la capture pour visualiser les deux Label Release Message.