Кросспостинг, оригинальная публикация

DMVPN является известным решением для построения топологий hub&spoke. В ряде случаев может понадобиться поддержка изолированной передачи трафика различных клиентов. Конечно, можно построить DMVPN туннель в каждом VRF; однако в реальной жизни такой подход не является достаточно масштабируемым. В такой ситуации на ум приходит MPLS, который зарекомендовал себя в корпоративных и провайдерских сетях.

GRE поддерживает инкапсуляцию различных PDU, в том числе и MPLS, поэтому, на первый взгляд, не должно возникнуть проблем на уровне передачи трафика. С управляющими протоколами, однако, ситуация обстоит несколько сложнее. LDP и RSVP должны установить соседство перед тем, как обменяться какими-либо данными. Масштабируемость этих протоколов обусловлена использованием мультикаста для обнаружения соседей и обмена с ними необходимыми параметрами протокола. Ручная настройка LDP/RSVP соседства в DMVPN сведёт на нет масштабируемость, поэтому такой сценарий статья не рассматривает. Использование же мультикаста ограничивает функциональность решения, поскольку spoke могут обмениваться такими сообщениями только с hub, что исключает наличие spoke-to-spoke связности с использованием MPLS.

Впрочем, существует третье решение, которое является достаточно масштабируемым, а также способно обеспечить MPLS-связность spoke-узлов между собой – это BGP labeled unicast (BGP LU). Существует несколько способов превратить spoke-маршрутизатор в PE (например, первый вариант – отправить пакет с VPN меткой напрямую другому spoke, аналог второй фазы DMVPN; второй вариант – hub принимает непосредственное участие в передаче пакета внутри VRF, выполняя перенаправление пакета, как в третьей фазе DMVPN); однако в определённых случаях может возникнуть необходимость разместить PE за spoke.

Как обычно, соберём лабу и итеративно построим рабочее решение. Ниже приведена используемая топология в рамках рассмотрения 2547oDMVPN:

Схема стенда
Схема стенда

Роли маршрутизаторов:

  • R1, R5, R7 (and R6 later) – MPLS PE;

  • R3 – провайдер для DMVPN;

  • R2 – DMVPN hub;

  • R4, R6 – DMVPN spokes.

Протоколы маршрутизации:

  • R1-R2, R4-R5, R6-R7 – OSPF на площадке организации;

  • R3 – OSPF провайдера, обеспечивающий связность между маршрутизаторами DMVPN;

  • R1, R5, R7 (R6) – MP-BGP VPNv4 AF;

  • R2, R4, R6 – MP-BGP IPv4 AF;

Loopback0 отвечает за идентификацию маршрутизатора в сети, например, за назначение OSPF RID. Loopback1 является интерфейсом, с которого маршрутизаторы устанавливают BGP LU сессии; причины такой настройки рассмотрены далее в статье. Loopback2 эмулирует клиентские сети внутри VRF.

Начнём с базовой конфигурации PE:

R1(config)# vrf definition A
R1(config-vrf)# rd 1:1
R1(config-vrf)# address-family ipv4
R1(config-vrf-af)# route-target export 1:1
R1(config-vrf-af)# route-target import 1:1
R1(config-if)# interface Loopback0
R1(config-if)# ip address 1.1.1.1 255.255.255.255
R1(config)# interface Loopback2
R1(config-if)# vrf forwarding A
R1(config-if)# ip address 1.1.1.1 255.255.255.255
R1(config)# interface FastEthernet0/0
R1(config-if)# ip address 192.168.12.1 255.255.255.0
R1(config-if)# mpls ldp router-id Loopback0
R1(config)# router ospf 1
R1(config-router)# mpls ldp autoconfig
R1(config-router)# router-id 1.1.1.1
R1(config-router)# network 0.0.0.0 255.255.255.255 area 0
R1(config)# router bgp 1
R1(config-router)# template peer-policy L3VPN
R1(config-router-ptmp)# send-community both
R1(config-router-ptmp)# exit-peer-policy
R1(config-router)# template peer-session SESSION
R1(config-router-stmp)# remote-as 1
R1(config-router-stmp)# update-source Loopback0
R1(config-router-stmp)# exit-peer-session
R1(config-router)# bgp router-id 1.1.1.1
R1(config-router)# no bgp default ipv4-unicast
R1(config-router)# neighbor 5.5.5.5 inherit peer-session SESSION
R1(config-router)# neighbor 7.7.7.7 inherit peer-session SESSION
R1(config-router)# address-family vpnv4
R1(config-router-af)# neighbor 5.5.5.5 activate
R1(config-router-af)# neighbor 5.5.5.5 send-community extended
R1(config-router-af)# neighbor 5.5.5.5 inherit peer-policy L3VPN
R1(config-router-af)# neighbor 7.7.7.7 activate
R1(config-router-af)# neighbor 7.7.7.7 send-community extended
R1(config-router-af)# neighbor 7.7.7.7 inherit peer-policy L3VPN
R1(config-router-af)# exit-address-family
R1(config-router)# address-family ipv4 vrf A
R1(config-router-af)# redistribute connected
R1(config-router-af)# exit-address-family
R5(config)# vrf definition A
R5(config-vrf)# rd 1:1
R5(config-vrf)# address-family ipv4
R5(config-vrf-af)# route-target export 1:1
R5(config-vrf-af)# route-target import 1:1
R5(config-vrf-af)# exit-address-family
R5(config-vrf)# interface Loopback0
R5(config-if)# ip address 5.5.5.5 255.255.255.255
R5(config-if)# interface Loopback2
R5(config-if)# vrf forwarding A
R5(config-if)# ip address 5.5.5.5 255.255.255.255
R5(config-if)# interface FastEthernet0/0
R5(config-if)# ip address 192.168.45.5 255.255.255.0
R5(config-if)# mpls ldp router-id Loopback0
R5(config)# router ospf 1
R5(config-router)# mpls ldp autoconfig
R5(config-router)# router-id 5.5.5.5
R5(config-router)# network 0.0.0.0 255.255.255.255 area 0
R5(config-router)# router bgp 1
R5(config-router)# template peer-policy L3VPN
R5(config-router-ptmp)# send-community both
R5(config-router-ptmp)# exit-peer-policy
R5(config-router)# template peer-session SESSION
R5(config-router-stmp)# remote-as 1
R5(config-router-stmp)# update-source Loopback0
R5(config-router-stmp)# exit-peer-session
R5(config-router)# bgp router-id 5.5.5.5
R5(config-router)# no bgp default ipv4-unicast
R5(config-router)# neighbor 1.1.1.1 inherit peer-session SESSION
R5(config-router)# neighbor 7.7.7.7 inherit peer-session SESSION
R5(config-router)# address-family vpnv4
R5(config-router-af)# neighbor 1.1.1.1 activate
R5(config-router-af)# neighbor 1.1.1.1 send-community extended
R5(config-router-af)# neighbor 1.1.1.1 inherit peer-policy L3VPN
R5(config-router-af)# neighbor 7.7.7.7 activate
R5(config-router-af)# neighbor 7.7.7.7 send-community extended
R5(config-router-af)# neighbor 7.7.7.7 inherit peer-policy L3VPN
R5(config-router-af)# exit-address-family
R5(config-router)# address-family ipv4 vrf A
R5(config-router-af)# redistribute connected
R5(config-router-af)# exit-address-family
R7(config)# vrf definition A
R7(config-vrf)# rd 1:1
R7(config-vrf)# address-family ipv4
R7(config-vrf-af)# route-target export 1:1
R7(config-vrf-af)# route-target import 1:1
R7(config-vrf-af)# exit-address-family
R7(config-vrf)# interface Loopback0
R7(config-if)# ip address 7.7.7.7 255.255.255.255
R7(config-if)# interface Loopback2
R7(config-if)# vrf forwarding A
R7(config-if)# ip address 7.7.7.7 255.255.255.255
R7(config-if)# interface FastEthernet0/0
R7(config-if)# ip address 192.168.67.7 255.255.255.0
R7(config-if)# mpls ldp router-id Loopback0
R7(config)# router ospf 1
R7(config-router)# mpls ldp autoconfig
R7(config-router)# router-id 7.7.7.7
R7(config-router)# network 0.0.0.0 255.255.255.255 area 0
R7(config-router)# router bgp 1
R7(config-router)# template peer-policy L3VPN
R7(config-router-ptmp)# send-community both
R7(config-router-ptmp)# exit-peer-policy
R7(config-router)# template peer-session SESSION
R7(config-router-stmp)# remote-as 1
R7(config-router-stmp)# update-source Loopback0
R7(config-router-stmp)# exit-peer-session
R7(config-router)# bgp router-id 7.7.7.7
R7(config-router)# bgp log-neighbor-changes
R7(config-router)# no bgp default ipv4-unicast
R7(config-router)# neighbor 1.1.1.1 inherit peer-session SESSION
R7(config-router)# neighbor 5.5.5.5 inherit peer-session SESSION
R7(config-router)# address-family ipv4
R7(config-router-af)# exit-address-family
R7(config-router)# address-family vpnv4
R7(config-router-af)# neighbor 1.1.1.1 activate
R7(config-router-af)# neighbor 1.1.1.1 send-community extended
R7(config-router-af)# neighbor 1.1.1.1 inherit peer-policy L3VPN
R7(config-router-af)# neighbor 5.5.5.5 activate
R7(config-router-af)# neighbor 5.5.5.5 send-community extended
R7(config-router-af)# neighbor 5.5.5.5 inherit peer-policy L3VPN
R7(config-router-af)# exit-address-family
R7(config-router)# address-family ipv4 vrf A
R7(config-router-af)# redistribute connected
R7(config-router-af)# exit-address-family

Следующий шаг – подключить DMVPN маршрутизаторы к локальным сегментам сети:

R2(config)# interface Loopback0
R2(config-if)# ip address 2.2.2.2 255.255.255.255
R2(config-if)# interface FastEthernet0/0
R2(config-if)# ip address 192.168.12.2 255.255.255.0
R2(config-if)# mpls ldp router-id Loopback0
R2(config)# router ospf 1
R2(config-router)# mpls ldp autoconfig
R2(config-router)# router-id 2.2.2.2
R2(config-router)# redistribute bgp 1 subnets
R2(config-router)# passive-interface default
R2(config-router)# no passive-interface FastEthernet0/0
R2(config-router)# no passive-interface Loopback0
R2(config-router)# network 0.0.0.0 255.255.255.255 area 0
R4(config)# interface Loopback0
R4(config-if)# ip address 4.4.4.4 255.255.255.255
R4(config-if)# interface FastEthernet0/0
R4(config-if)# ip address 192.168.45.4 255.255.255.0
R4(config-if)# mpls ldp router-id Loopback0
R4(config)#router ospf 1
R4(config-router)# mpls ldp autoconfig
R4(config-router)# router-id 4.4.4.4
R4(config-router)# redistribute bgp 1 subnets
R4(config-router)# passive-interface default
R4(config-router)# no passive-interface FastEthernet0/0
R4(config-router)# no passive-interface Loopback0
R4(config-router)# network 0.0.0.0 255.255.255.255 area 0
R6(config)# interface Loopback0
R6(config-if)# ip address 6.6.6.6 255.255.255.255
R6(config-if)# interface FastEthernet0/0
R6(config-if)# ip address 192.168.67.6 255.255.255.0
R6(config-if)# mpls ldp router-id Loopback0
R6(config)# router ospf 1
R6(config-router)# mpls ldp autoconfig
R6(config-router)# redistribute bgp 1 subnets
R6(config-router)# passive-interface default
R6(config-router)# no passive-interface FastEthernet0/0
R6(config-router)# no passive-interface Loopback0
R6(config-router)# network 0.0.0.0 255.255.255.255 area 0

Наконец последний этап подготовки к рассмотрению BGP LU – настройка DMVPN. В статье использован подход front-door VRF, чтобы уменьшить объём посторонней информации в глобальной таблице маршрутизации:

R3(config)# interface Loopback0
R3(config-if)# ip address 3.3.3.3 255.255.255.255
R3(config-if)# interface FastEthernet0/1
R3(config-if)# ip address 192.168.34.3 255.255.255.0
R3(config-if)# interface FastEthernet1/0
R3(config-if)# ip address 192.168.23.3 255.255.255.0
R3(config-if)# interface FastEthernet1/1
R3(config-if)# ip address 192.168.36.3 255.255.255.0
R3(config-if)# router ospf 1
R3(config-router)# router-id 3.3.3.3
R3(config-router)# network 0.0.0.0 255.255.255.255 area 0
R2(config)# vrf definition FVRF
R2(config-vrf)# rd 1:1
R2(config-vrf)# address-family ipv4
R2(config-vrf-af)# exit-address-family
R2(config-vrf)# interface Tunnel0
R2(config-if)# ip address 192.168.0.2 255.255.255.0
R2(config-if)# no ip redirects
R2(config-if)# ip nhrp map multicast dynamic
R2(config-if)# ip nhrp network-id 1
R2(config-if)# ip nhrp redirect
R2(config-if)# tunnel source FastEthernet1/0
R2(config-if)# tunnel mode gre multipoint
R2(config-if)# tunnel vrf FVRF
R2(config-if)# interface FastEthernet1/0
R2(config-if)# vrf forwarding FVRF
R2(config-if)# ip address 192.168.23.2 255.255.255.0
R2(config-if)# router ospf 2 vrf FVRF
R2(config-router)# router-id 192.168.23.2
R2(config-router)# network 0.0.0.0 255.255.255.255 area 0
R4(config)# vrf definition FVRF
R4(config-vrf)# rd 1:1
R4(config-vrf)# address-family ipv4
R4(config-vrf-af)# exit-address-family
R4(config-vrf)# interface Tunnel0
R4(config-if)# ip address 192.168.0.4 255.255.255.0
R4(config-if)# no ip redirects
R4(config-if)# ip nhrp network-id 1
R4(config-if)# ip nhrp nhs 192.168.0.2 nbma 192.168.23.2 multicast
R4(config-if)# ip nhrp shortcut
R4(config-if)# tunnel source FastEthernet0/1
R4(config-if)# tunnel mode gre multipoint
R4(config-if)# tunnel vrf FVRF
R4(config-if)# interface FastEthernet0/1
R4(config-if)# vrf forwarding FVRF
R4(config-if)# ip address 192.168.34.4 255.255.255.0
R4(config-if)# router ospf 2 vrf FVRF
R4(config-router)# router-id 192.168.34.4
R4(config-router)# network 0.0.0.0 255.255.255.255 area 0
R6(config)# vrf definition FVRF
R6(config-vrf)# rd 1:1
R6(config-vrf)# address-family ipv4
R6(config-vrf-af)# exit-address-family
R6(config-vrf)# interface Tunnel0
R6(config-if)# ip address 192.168.0.6 255.255.255.0
R6(config-if)# no ip redirects
R6(config-if)# ip nhrp network-id 1
R6(config-if)# ip nhrp nhs 192.168.0.2 nbma 192.168.23.2 multicast
R6(config-if)# ip nhrp shortcut
R6(config-if)# tunnel source FastEthernet1/1
R6(config-if)# tunnel mode gre multipoint
R6(config-if)# tunnel vrf FVRF
R6(config-if)# interface FastEthernet1/1
R6(config-if)# vrf forwarding FVRF
R6(config-if)# ip address 192.168.36.6 255.255.255.0
R6(config-if)# router ospf 2 vrf FVRF
R6(config-router)# network 0.0.0.0 255.255.255.255 area 0

Время заняться делом. Необходимым условием для L3VPN является наличие рабочего LSP между PE. Поскольку ни LDP, ни RSVP в рамках DMVPN для этой задачи не подходят, используем MP-BGP для передачи следующей информации:

  • адреса loopback;

  • соответствующие им MPLS метки.

Звучит довольно просто. Что насчёт поддержки MPLS на интерфейсах?

R2# sho mpls interfaces
Interface              IP            Tunnel   BGP Static Operational
FastEthernet0/0        Yes (ldp)     No       No  No     Yes  

На Tunnel0 MPLS пока не работает. Нам нужно разрешить только поддержку MPLS пакетов, не включая LDP, поэтому к��манда “mpls ip” не подходит. Впрочем, существует ещё одна менее известная команда, отвечающая нашей задаче:

R2(config)#interface Tunnel0
R2(config-if)#mpls bgp forwarding

R2#sho mpls interfaces
Interface              IP            Tunnel   BGP Static Operational
FastEthernet0/0        Yes (ldp)     No       No  No     Yes        
Tunnel0                No            No       Yes No     Yes

После выполнения этой команды на всех spoke можно приступать к настройке BGP. В этой статье мы используем iBGP между hub и spoke; hub выполняет роль route-reflector и принимает входящие BGP-соединения:

R2(config)# router bgp 1
R2(config-router)# bgp router-id 2.2.2.2
R2(config-router)# bgp listen range 192.168.0.0/24 peer-group DMVPN
R2(config-router)# no bgp default ipv4-unicast
R2(config-router)# neighbor DMVPN peer-group
R2(config-router)# neighbor DMVPN remote-as 1
R2(config-router)# neighbor DMVPN update-source Tunnel0
R2(config-router)# address-family ipv4
R2(config-router-af)# network 1.1.1.1 mask 255.255.255.255
R2(config-router-af)# neighbor DMVPN activate
R2(config-router-af)# neighbor DMVPN route-reflector-client
R2(config-router-af)# neighbor DMVPN send-label
R4(config)# router bgp 1
R4(config-router)# bgp router-id 4.4.4.4
R4(config-router)# no bgp default ipv4-unicast
R4(config-router)# neighbor 192.168.0.2 remote-as 1
R4(config-router)# neighbor 192.168.0.2 update-source Tunnel0
R4(config-router)# address-family ipv4
R4(config-router-af)# network 5.5.5.5 mask 255.255.255.255
R4(config-router-af)# neighbor 192.168.0.2 activate
R4(config-router-af)# neighbor 192.168.0.2 send-label
R6(config)# router bgp 1
R6(config-router)# bgp router-id 6.6.6.6
R6(config-router)# no bgp default ipv4-unicast
R6(config-router)# neighbor 192.168.0.2 remote-as 1
R6(config-router)# neighbor 192.168.0.2 update-source Tunnel0
R6(config-router)# address-family ipv4
R6(config-router-af)# network 7.7.7.7 mask 255.255.255.255
R6(config-router-af)# neighbor 192.168.0.2 activate
R6(config-router-af)# neighbor 192.168.0.2 send-label

Проверим, есть ли IP-связность между PE:

R5#ping 1.1.1.1 so lo 0
Type escape sequence to abort.
Sending 5, 100-byte ICMP Echos to 1.1.1.1, timeout is 2 seconds:
Packet sent with a source address of 5.5.5.5
!!!!!
Success rate is 100 percent (5/5), round-trip min/avg/max = 48/57/64 ms

Достаточно ли этого для связности внутри VRF?

R5#ping vrf A 1.1.1.1 so lo 0
Type escape sequence to abort.
Sending 5, 100-byte ICMP Echos to 1.1.1.1, timeout is 2 seconds:
Packet sent with a source address of 5.5.5.5
.....
Success rate is 0 percent (0/5)

К сожалению, решение несколько сложнее, чем могло бы показаться на первый взгляд. Причина отсутствия связности – нерабочий LSP между PE:

R5#ping mpls ipv4 1.1.1.1/32 source 5.5.5.5
Sending 5, 100-byte MPLS Echos to 1.1.1.1/32,
     timeout is 2 seconds, send interval is 0 msec:

Codes: '!' - success, 'Q' - request not sent, '.' - timeout,
  'L' - labeled output interface, 'B' - unlabeled output interface,
  'D' - DS Map mismatch, 'F' - no FEC mapping, 'f' - FEC mismatch,
  'M' - malformed request, 'm' - unsupported tlvs, 'N' - no label entry,
  'P' - no rx intf label prot, 'p' - premature termination of LSP,
  'R' - transit router, 'I' - unknown upstream index,
  'X' - unknown return code, 'x' - return code 0

Type escape sequence to abort.
BBBBB
Success rate is 0 percent (0/5)

Если быть точным, место отказа – R4:

R4#sho mpls forwarding-table 1.1.1.1 32
Local      Outgoing   Prefix           Bytes Label   Outgoing   Next Hop    
Label      Label      or Tunnel Id     Switched      interface              
19         No Label   1.1.1.1/32       1125          Tu0        192.168.0.2

Впрочем, является ли R4 местом возникновения проблемы? Разве R2 не должен был послать R4 префикс вместе с меткой?

R4#sho ip bgp labels
   Network          Next Hop      In label/Out label
   1.1.1.1/32       192.168.12.1   nolabel/nolabel
   2.2.2.2/32       192.168.0.2    nolabel/imp-null
   <output omitted>

Важное наблюдение: 1.1.1.1/32 не имеет сопутствующей MPLS метки, однако 2.2.2.2/32 ведёт себя так, как и было задумано. Также стоит обратить внимание на next-hop для 1.1.1.1/32 – это адрес R1, а не R2. R2 импортировал маршрут в BGP, сохранив оригинальный next-hop из таблицы маршрутизации. Поскольку сессия между R2 и R4 – iBGP, значение next-hop для 1.1.1.1/32 не меняется. Для 2.2.2.2/32 значение next-hop – адрес R2. Это тонкое отличие, однако, является ключевым: BGP назначает префиксу MPLS метку только в том случае, когда BGP маршрутизатор является next-hop’ом для этого префикса, т.е. входит в LSP.

В нашем случае нужно назначать метку только префиксам, импортированным локально, и не менять информацию от spoke:

R2(config)#router bgp 1
R2(config-router)#address-family ipv4
R2(config-router-af)#neighbor PEER next-hop-self ?  
  all  Enable next-hop-self for both eBGP and iBGP received paths
  <cr>

R2(config-router-af)#neighbor PEER next-hop-self

Эта команда – довольно хитрая. По умолчанию она заставляет R2 изменять next-hop для маршрутов, которые импортированы локально или получены через eBGP; если нужно изменить next-hop для всех префиксов, включая те, которые получены по iBGP, нужно добавить ключевое слово “all”. Появилась ли связность?

R5#ping mpls ipv4 1.1.1.1/32 source 5.5.5.5
<output omitted>
Type escape sequence to abort.
!!!!!
Success rate is 100 percent (5/5), round-trip min/avg/max = 56/65/72 ms
R5#
R5#ping vrf A 1.1.1.1 so lo 0              
Type escape sequence to abort.
Sending 5, 100-byte ICMP Echos to 1.1.1.1, timeout is 2 seconds:
Packet sent with a source address of 5.5.5.5
!!!!!
Success rate is 100 percent (5/5), round-trip min/avg/max = 52/80/108 ms
R5#
R5#ping mpls ipv4 7.7.7.7/32 source 5.5.5.5
<output omitted>
Type escape sequence to abort.
!!!!!
Success rate is 100 percent (5/5), round-trip min/avg/max = 56/60/64 ms
R5#
R5#ping vrf A 7.7.7.7 so lo 2              
Type escape sequence to abort.
Sending 5, 100-byte ICMP Echos to 7.7.7.7, timeout is 2 seconds:
Packet sent with a source address of 5.5.5.5
!!!!!
Success rate is 100 percent (5/5), round-trip min/avg/max = 48/79/104 ms
R5#
R5#traceroute 7.7.7.7 so lo 0
Type escape sequence to abort.
Tracing the route to 7.7.7.7
VRF info: (vrf in name/id, vrf out name/id)
  1 192.168.45.4 [MPLS: Label 22 Exp 0] 88 msec 80 msec 80 msec
  2 192.168.0.6 [MPLS: Label 16 Exp 0] 52 msec 64 msec 52 msec
  3 192.168.67.7 40 msec 64 msec 64 msec

Мы добились работы L3VPN поверх DMVPN. Впрочем, внимательный читатель, который повторял описанные шаги в собственной лабе, мог заметить следующее предупреждение, возникающее при настройке BGP LU:

R4(config-router-af)#neighbor 192.168.0.2 send-label
%BGP: For distributing MPLS labels to IBGP peers, the 
update source should be set to a loopback interface

Несмотря на то, что сообщение намекает на потенциальные проблемы, в нашей топологии они остались незамеченными. Рассмотрим следующую схему:

В рамках этого примера R1 устанавливает BGP сессию со своего интерфейса f0/0 до loopback интерфейса на R3, повторяя схему DMVPN. Control plane в данном случае будет работать без ошибок, тогда как связность на data plane – LSP – будет нарушена. Причина – PHP, penultimate hop popping. Интерфейс f0/0 лежит в directly connected сети для R2, который анонсирует её с меткой implicit-null. Рассмотрим, что происходит с пакетом, который R3 отправит на R1:

  1. R3 добавляет VPN метку (например, 16) к пакету;

  2. R3 добавляет транспортную метку (implicit-null) к полученному MPLS кадру;

  3. R3 отправляет полученный кадр в сторону R2, при этом VPN метка находится на вершине стека.

Далее возможны два исхода: R2 не знает, что делать с кадром (VPN метка отсутствует в LFIB), и отбрасывает его, или же R2 шлёт кадр в неверном направлении (случайное совпадение VPN метки в кадре и транспортной метки в LFIB). В любом случае шансы R1 на получение кадра ничтожно малы. Стоит отметить, что использование explicit-null не решит проблему, поскольку для передачи кадра всё так же будет использована нижележащая VPN метка.

Впрочем, какое это имеет отношение к нашей изначальной топологии? Описанная проблема относится к некорректно настроенным PE-маршрутизаторам. Однако эта проблема становится актуальной и в нашей топологии, если spoke превратить в PE, поскольку BGP использует Tunnel0 для установления сессии. Можно попробовать перенастроить BGP на использование loopback, хотя это ни к чему хорошему не приведёт: LSP будет разорван, т.к. некому анонсировать метки для самих loopback – обычно это задача LSP/RSVP. Впрочем, решение довольно простое: можно использовать loopback только для VPNv4 AF сессий и анонсировать соответствующие метки с помощью BGP LU:

R6(config)# vrf definition A
R6(config-vrf)# rd 2:2
R6(config-vrf)# address-family ipv4
R6(config-vrf-af)# route-target export 1:1
R6(config-vrf-af)# route-target import 1:1
R6(config-vrf-af)# exit-address-family
R6(config-vrf)# interface Loopback1
R6(config-if)# ip address 100.0.0.6 255.255.255.255
R6(config-if)# interface Loopback2
R6(config-if)# vrf forwarding A
R6(config-if)# ip address 6.6.6.6 255.255.255.255
R6(config-if)# router bgp 1
R6(config-router)# template peer-policy L3VPN
R6(config-router-ptmp)# send-community both
R6(config-router-ptmp)# exit-peer-policy
R6(config-router)# template peer-session SESSION
R6(config-router-stmp)# remote-as 1
R6(config-router-stmp)# update-source Loopback1
R6(config-router-stmp)# exit-peer-session
R6(config-router)# neighbor 1.1.1.1 inherit peer-session SESSION
R6(config-router)# neighbor 5.5.5.5 inherit peer-session SESSION
R6(config-router)# neighbor 7.7.7.7 inherit peer-session SESSION
R6(config-router)# address-family ipv4
R6(config-router-af)# network 100.0.0.6 mask 255.255.255.255
R6(config-router-af)# exit-address-family
R6(config-router)# address-family vpnv4
R6(config-router-af)# neighbor 1.1.1.1 activate
R6(config-router-af)# neighbor 1.1.1.1 send-community extended
R6(config-router-af)# neighbor 1.1.1.1 inherit peer-policy L3VPN
R6(config-router-af)# neighbor 5.5.5.5 activate
R6(config-router-af)# neighbor 5.5.5.5 send-community extended
R6(config-router-af)# neighbor 5.5.5.5 inherit peer-policy L3VPN
R6(config-router-af)# neighbor 7.7.7.7 activate
R6(config-router-af)# neighbor 7.7.7.7 send-community extended
R6(config-router-af)# neighbor 7.7.7.7 inherit peer-policy L3VPN
R6(config-router-af)# exit-address-family
R6(config-router)# address-family ipv4 vrf A
R6(config-router-af)# redistribute connected
R6(config-router-af)# exit-address-family

Теперь R6 участвует в L3VPN, и можно проверить наличие связности внутри VRF:

R6#tclsh                                                      
R6(tcl)#foreach x {1.1.1.1 5.5.5.5 7.7.7.7} {ping vrf A $x so lo 2}
Type escape sequence to abort.
Sending 5, 100-byte ICMP Echos to 1.1.1.1, timeout is 2 seconds:
Packet sent with a source address of 6.6.6.6
!!!!!
Success rate is 100 percent (5/5), round-trip min/avg/max = 28/59/84 ms
Type escape sequence to abort.
Sending 5, 100-byte ICMP Echos to 5.5.5.5, timeout is 2 seconds:
Packet sent with a source address of 6.6.6.6
!!!!!
Success rate is 100 percent (5/5), round-trip min/avg/max = 4/32/44 ms
Type escape sequence to abort.
Sending 5, 100-byte ICMP Echos to 7.7.7.7, timeout is 2 seconds:
Packet sent with a source address of 6.6.6.6
!!!!!
Success rate is 100 percent (5/5), round-trip min/avg/max = 1/9/16 ms

Наконец-то L3VPN поверх DMVPN работает так, как мы ожидали. Мне кажется, сложности описанной конструкции заключаются в следующем:

  • обладание тайным знанием о существовании BGP LU;

  • назначение MPLS метки только в том случае, если маршрутизатор является next-hop’ом для префикса;

  • понимание, в каких случаях PHP способен сломать LSP.

В этой статье мы обсудили настройку MPLS L3VPN поверх DMVPN (2547oDMVPN) с использованием iBGP LU для распространения MPLS меток в рамках опорной сети. Отличие от документированных способов – это возможность разместить PE-маршрутизатор за hub/spokes без нарушения spoke-to-spoke связности поверх DMVPN. Что касается настройки с помощью eBGP, я бы хотел оставить её как домашнее задание для любознательных читателей.

Спасибо за рецензию: Анастасии Куралевой, Максиму Климанову