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

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, я бы хотел оставить её как домашнее задание для любознательных читателей.

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