Оверлейные сети VXLAN: реализация BGP EVPN с Cumulus Quagga или FRR

Ранее мы уже писали о конфигурировании VXLAN в Linux. Представляем перевод еще одной англоязычной статьи “VXLAN: BGP EVPN with Cumulus Quagga (or FRR)” автора Vincent Bernat, которая может быть интересна разработчикам или администраторам, ищущим решение для реализации VXLAN в больших сетях, где недоступно мультивещание.

VXLAN (Virtual eXtensible Local Area Network) – оверлейная сеть для передачи трафика Ethernet по существующей (высокодоступной и масштабируемой, возможно Интернет) IP-сети. Полное определение VXLAN представлено в RFC 7348.

На картинке выше представлен пример использования VXLAN, в котором используются гипервизоры, на которых размещены виртуальные машины различных пользователей. Каждой машине предоставлен доступ к частному виртуальному сегменту Ethernet конкретного пользователя. Виртуальные машины ожидают, что они используют стандартные сети Ethernet: без ограничений MAC, с полным контролем над используемой ими схемой IP-адресации и наличием мультивещания.

В больших сетях VXLAN реализация двух следующих аспектов играет критическую роль:

  • как организовано обнаружение других конечных точек (VTEP), использующих один и тот же сегмент VXLAN, и
  • как производится ограничение количества BUM кадров (broadcast, unknown unicast и multicast), т.к. они должны передаваться всем VTEP в рамках VXLAN.

Решением по-умолчанию для первого аспекта является использование мультивещания, для второго – изучение адресов источников кадров.

Введение в BGP EVPN

BGP EVPN (RFC 7432 и RFC 8365 для его применения к VXLAN) – это стандартный протокол управления для эффективного решения вышеуказанных аспектов без использования мультивещания или изучения адресов источников кадров.

BGP EVPN основан на BGP (RFC 4271) и его расширениях MP-BGP (RFC 4760). BGP - это основной протокол динамической маршрутизации, который используется в Интернете. Он является высокомасштабируемым и интероперабельным. Также, он расширяемый, одним из его расширений является MP-BGP. Это расширение может передавать информацию о доступности сети (NLRI) для множества протоколов (IPv4, IPv6, L3VPN и в нашем случае EVPN). EVPN представляет собой семейство адресов BGP для передачи MAC-адресов и удаленного оборудования, к которому они присоединены.

Существует два типа информации о доступности сети, которую VTEP передает через BGP EVPN:

  • VNI, в которых они заинтересованы (маршруты L3);
  • локальный MAC-адрес для каждого VNI (маршруты L2).

Протокол также покрывает другие аспекты виртуальных сегментов Ethernet (информацию о доступности L3 из кэшей ARP/ND, поддержка MAC mobility и multi-homing), но мы их не будем здесь описывать.

Multi-homing может заменить частную реализацию MC-LAG, позволяя нескольким VTEP выполнять роль конечной точки для одной группы агрегирования каналов. В нашем сценарии это не требуется, т.к. в качестве VTEP выступают гипервизоры.

Для развертывания BGP EVPN обычно используются несколько серверов BGP типа route-reflector (как для избыточности данных, так и для масштабируемости), как показано ниже. Каждый VTEP открывает BGP-сеанс как минимум двум BGP RR, отправляет свою информацию (MAC и VNI) и получает информацию от других. Это уменьшает число настраиваемых BGP-сеансов.

По сравнению с другими решениями для развертывания VXLAN, BGP EVPN обладает тремя преимуществами:

  • совместимость с другими вендорами (в частности Juniper и Cisco);
  • проверенная масштабируемость (обычные маршрутизаторы BGP работают с несколькоми миллионами маршрутов);
  • возможность применения гибких политик маршрутизации.

Cumulus Quagga является достаточно полной реализацией BGP EVPN для Linux, которая поддерживает маршруты L3, необходимые для обнаружения VTEP, и маршруты L2 с адресами MAC или IP, поддержкой MAC-mobility, когда виртуальный хост переносится с одного VTEP на другой. При этом данная реализация легко настраивается.

Проект является fork’ом проекта Quagga и сейчас используется в Cumulus Linux - сетевой операционной системе, основанной на Debian, для коммутаторов различных поставщиков. В какой-то момент поддержка BGP EVPN будет добавлена обратно в FRR, поддерживаемую сообществом реализацию проекта Quagga.

Разработка Quagga идет медленно и «закрыто». Работа над новой функциональностью часто останавливается. FRR находится под управлением Linux Foundation, в нем используется модель разработки GitHub и процесс выбора. В нем уже реализовано несколько интересных улучшений (в частности, BGP add-path, BGP unnumbered, MPLS и LDP).

Update 08.2017: Cumulus перешел с Quagga на FRR (с версии Cumulus Linux 3.4.0). Конфигурация, представленная здесь, также работает с FRR 4.0 с применением опции --enable-cumulus.

Следует отметить, что реализация BGP EVPN в Cumulus Quagga сейчас поддерживает только IPv4.

Настройка серверов BGP route reflector

Прежде чем настраивать VTEP для использования EBGP VPN, нужно настроить серверы BGP RR. Для этого есть несколько решений. Далее представлены некоторые из них:

  • использовать Cumulus Quagga;
  • использовать GoBGP, реализация BGP в Go;
  • использовать Juniper JunOS.

Для повышения надежности возможно использовать одну реализацию для одного сервера RR и другую для второго (по крайней мере на период тестирования это может быть оправдано).

Предложенные конфигурации довольно минималистичны. С помощью политик маршрутизации можно развить эти конфигурации до тонко управляемых (например, маршруты, тегированные неким community, могут быть анонсированы только некоторой группе VTEP).

Настройка RR с использованием Quagga

Предположим, сервер RR использует IP 203.0.113.254, настроенный для интерфейса loopback.

router bgp 65000
  bgp router-id 203.0.113.254
  bgp cluster-id 203.0.113.254
  bgp log-neighbor-changes
  no bgp default ipv4-unicast
  neighbor fabric peer-group
  neighbor fabric remote-as 65000
  neighbor fabric capability extended-nexthop
  neighbor fabric update-source 203.0.113.254
  bgp listen range 203.0.113.0/24 peer-group fabric
  !
  ! With FRR, use: address-family l2vpn evpn
  address-family evpn
   neighbor fabric activate
   neighbor fabric route-reflector-client
  exit-address-family
  !
  exit
!

Определяется группа соседей fabric, здесь мы эффективно используем функцию динамического определения соседства Cumulus Quagga: не нужно явно определять каждого соседа. Любой клиент из 203.0.113.0/24 и использующий AS65000 может подключиться. Все отправленные маршруты EVPN будут приняты и отражены другим соседям.

Нет необходимости запускать демона Zebra, общающегося с ядром. Вместо этого, запустите bgpd с флагом --no_kernel.

Update 04.2018: Если вам необходима поддержка нескольких реализаций BGP EVPN, не рекомендуется использовать Quagga в качестве рефлектора маршрута: она может исказить полученные маршруты.

Настройка RR с использованием GoBGP

GoBGP является чистой реализацией BGP в Go.

Прим.автора статьи: Я без энтузиазма отношусь к проектам, единственной целью которых является переписать что-то в Go. Однако, будучи довольно молодым, проект GoBGP очень ценен благодаря хорошей архитектуре и высокой производительности.

Он предоставляет RPC API для конфигурирования, вместе с тем, позволяет использовать файл конфигурации и утилиту комендной строки.

Начиная с версии GoBGP 1.21 реализована поддержка динамического определения соседей (см. пример конфигурации).

Можно использовать API, клиент командной строки или YaML для автоматизации анонса соседей. Конфигурация с одним соседом выглядит так:

global:
  config:
    as: 65000
    router-id: 203.0.113.254
    local-address-list:
      - 203.0.113.254
neighbors:
  - config:
      neighbor-address: 203.0.113.1
      peer-as: 65000
    afi-safis:
      - config:
          afi-safi-name: l2vpn-evpn
    route-reflector:
      config:
        route-reflector-client: true
        route-reflector-cluster-id: 203.0.113.254

Добавить соседей можно из командной строки:

$  gobgp neighbor add 203.0.113.2 as 65000 \
          route-reflector-client 203.0.113.254 \
          --address-family evpn

GoBGP не добавляет маршруты в таблицу маршрутизации ядра, что хорошо подходит для использования в качестве RR.

Настройка RR с использованием Juniper JunOS

В качестве рефлекторов маршрута BGP можно использовать различные продукты Juniper, а именно:

  • Juniper QFX5100, коммутатор верхнего уровня,
  • Juniper MX240, высокопроизводительный маршрутизатор,
  • Juniper vRR, виртуальный маршрутизатор JunOS.

Главный фактор - CPU и память. QFX5100 имеет небольшой объем памяти и не поддерживает большие развертывания без некоторой дополнительной защиты.

Ниже представлена конфигурация, cхожая c конфигурацией Quagga:

interfaces {
    lo0 {
        unit 0 {
            family inet {
                address 203.0.113.254/32;
            }
        }
    }
}

protocols {
    bgp {
        group fabric {
            family evpn {
                signaling {
                    /* Do not try to install EVPN routes */
                    no-install;
                }
            }
            type internal;
            cluster 203.0.113.254;
            local-address 203.0.113.254;
            allow 203.0.113.0/24;
        }
    }
}

routing-options {
    router-id 203.0.113.254;
    autonomous-system 65000;
}

Настройка BGP на стороне VTEP

Следующим шагом является настройка каждого VTEP/гипервизора. Каждый VXLAN настроен локально с использованием моста (linux bridge) для локальных виртуальных интерфейсов, как показано на изображении ниже. Мост обслуживает локальные MAC-адреса (в частности, используя изучение адресов источников кадров), а интерфейс VXLAN – удаленные MAC-адреса (полученные с BGP EVPN).

Интерфесы VTEP для VXLAN можно создать следующим скриптом. Изучение адресов источников отключено, т.к. мы данную функцию передаем BGP EVPN.

for vni in 100 200; do
    # Create VXLAN interface
    ip link add vxlan${vni} type vxlan
        id ${vni} \
        dstport 4789 \
        local 203.0.113.2 \
        nolearning
    # Create companion bridge
    brctl addbr br${vni}
    brctl addif br${vni} vxlan${vni}
    brctl stp br${vni} off
    ip link set up dev br${vni}
    ip link set up dev vxlan${vni}
done
# Attach each VM to the appropriate segment
brctl addif br100 vnet10
brctl addif br100 vnet11
brctl addif br200 vnet12

Конфигурация Cumulus Quagga похожа на ту, что используется для рефлекторов маршрута, но имеет одно отличие: мы используем директиву advertise-all-vni для публикации всех локальных VNI.

router bgp 65000
  bgp router-id 203.0.113.2
  no bgp default ipv4-unicast
  neighbor fabric peer-group
  neighbor fabric remote-as 65000
  neighbor fabric capability extended-nexthop
  ! BGP sessions with route reflectors
  neighbor 203.0.113.253 peer-group fabric
  neighbor 203.0.113.254 peer-group fabric
  !
  ! With FRR, use: address-family l2vpn evpn
  address-family evpn
   neighbor fabric activate
   advertise-all-vni
  exit-address-family
  !
  exit
!

Если все работает, как ожидается, машины, использующие общий VNI, должны иметь возможность отправлять друг другу ping-запросы. Если на VM включен IPv6, то с помощью команды ping, использующей link-local адреса можно проверить доступность других узлов в рамках VXLAN:

$ ping -c10 -w1 -t1 ff02::1%eth0
PING ff02::1%eth0(ff02::1%eth0) 56 data bytes
64 bytes from fe80::5254:33ff:fe00:8%eth0: icmp_seq=1 ttl=64 time=0.016 ms
64 bytes from fe80::5254:33ff:fe00:b%eth0: icmp_seq=1 ttl=64 time=4.98 ms (DUP!)
64 bytes from fe80::5254:33ff:fe00:9%eth0: icmp_seq=1 ttl=64 time=4.99 ms (DUP!)
64 bytes from fe80::5254:33ff:fe00:a%eth0: icmp_seq=1 ttl=64 time=4.99 ms (DUP!)

--- ff02::1%eth0 ping statistics ---
1 packets transmitted, 1 received, +3 duplicates, 0% packet loss, time 0ms
rtt min/avg/max/mdev = 0.016/3.745/4.991/2.152 ms

Проверка конфигурации

Шаг за шагом проверим, как все вместе работает.

Получение информации VXLAN от ядра

На каждом VTEP сервер Quagga должен иметь возможность получать информацию о сконфигурированных VXLAN. Проверить это можно с помощью vtysh:

#  show interface vxlan100
Interface vxlan100 is up, line protocol is up
  Link ups:       1    last: 2017/04/29 20:01:33.43
  Link downs:     0    last: (never)
  PTM status: disabled
  vrf: Default-IP-Routing-Table
  index 11 metric 0 mtu 1500
  flags: <UP,BROADCAST,RUNNING,MULTICAST>
  Type: Ethernet
  HWaddr: 62:42:7a:86:44:01
  inet6 fe80::6042:7aff:fe86:4401/64
  Interface Type Vxlan
  VxLAN Id 100                                     # < VNI=100
  Access VLAN Id 1                                
  Master (bridge) ifindex 9 ifp 0x56536e3f3470     # < обнаружен связанный bridge 

Сервер Quagga также должен получать информацию о локальных MAC-адресах:

#  show evpn mac vni 100
Number of MACs (local and remote) known for this VNI: 2
MAC               Type   Intf/Remote VTEP      VLAN
50:54:33:00:00:0a local  eth1.100
50:54:33:00:00:0b local  eth2.100

Сеансы BGP

Каждый VTEP должен установить BGP-сеанс с каждым сконфигурированным сервером BGP RR. На VTEP это можно проверить, запустив vtysh:

#  show bgp neighbors 203.0.113.254
BGP neighbor is 203.0.113.254, remote AS 65000, local AS 65000, internal link
 Member of peer-group fabric for session parameters
  BGP version 4, remote router ID 203.0.113.254
  BGP state = Established, up for 00:00:45                           # < established
  Neighbor capabilities:
    4 Byte AS: advertised and received
    AddPath:
      L2VPN EVPN: RX advertised L2VPN EVPN
    Route refresh: advertised and received(new)
    Address family L2VPN EVPN: advertised and received
    Hostname Capability: advertised
    Graceful Restart Capabilty: advertised
[...]
 For address family: L2VPN EVPN                                      # < L2VPN
  fabric peer-group member
  Update group 1, subgroup 1
  Packet Queue length 0
  Community attribute sent to this neighbor(both)
  8 accepted prefixes                                                # < количество маршрутов

  Connections established 1; dropped 0
  Last reset never
Local host: 203.0.113.2, Local port: 37603
Foreign host: 203.0.113.254, Foreign port: 179

Состояние сеанса BGP также можно проверить с сервера BGP RR. Для GoBGP используйте следующую команду:

#  gobgp neighbor 203.0.113.2
BGP neighbor is 203.0.113.2, remote AS 65000, route-reflector-client
  BGP version 4, remote router ID 203.0.113.2
  BGP state = established, up for 00:04:30
  BGP OutQ = 0, Flops = 0
  Hold time is 9, keepalive interval is 3 seconds
  Configured hold time is 90, keepalive interval is 30 seconds
  Neighbor capabilities:
    multiprotocol:
        l2vpn-evpn:     advertised and received
    route-refresh:      advertised and received
    graceful-restart:   received
    4-octet-as: advertised and received
    add-path:   received
    UnknownCapability(73):      received
    cisco-route-refresh:        received
[...]
  Route statistics:
    Advertised:             8
    Received:               5
    Accepted:               5

Для JunOS используйте следующую команду:

>  show bgp neighbor 203.0.113.2
Peer: 203.0.113.2+38089 AS 65000 Local: 203.0.113.254+179 AS 65000
  Group: fabric                Routing-Instance: master
  Forwarding routing-instance: master
  Type: Internal    State: Established
  Last State: OpenConfirm   Last Event: RecvKeepAlive
  Last Error: None
  Options: <Preference LocalAddress Cluster AddressFamily Rib-group Refresh>
  Address families configured: evpn
  Local Address: 203.0.113.254 Holdtime: 90 Preference: 170
  NLRI evpn: NoInstallForwarding
  Number of flaps: 0
  Peer ID: 203.0.113.2     Local ID: 203.0.113.254     Active Holdtime: 9
  Keepalive Interval: 3          Group index: 0    Peer index: 2
  I/O Session Thread: bgpio-0 State: Enabled
  BFD: disabled, down
  NLRI for restart configured on peer: evpn
  NLRI advertised by peer: evpn
  NLRI for this session: evpn
  Peer supports Refresh capability (2)
  Stale routes from peer are kept for: 300
  Peer does not support Restarter functionality
  NLRI that restart is negotiated for: evpn
  NLRI of received end-of-rib markers: evpn
  NLRI of all end-of-rib markers sent: evpn
  Peer does not support LLGR Restarter or Receiver functionality
  Peer supports 4 byte AS extension (peer-as 65000)
  NLRI's for which peer can receive multiple paths: evpn
  Table bgp.evpn.0 Bit: 20000
    RIB State: BGP restart is complete
    RIB State: VPN restart is complete
    Send state: in sync
    Active prefixes:              5
    Received prefixes:            5
    Accepted prefixes:            5
    Suppressed due to damping:    0
    Advertised prefixes:          8
  Last traffic (seconds): Received 276  Sent 170  Checked 276
  Input messages:  Total 61     Updates 3       Refreshes 0     Octets 1470
  Output messages: Total 62     Updates 4       Refreshes 0     Octets 1775
  Output Queue[1]: 0            (bgp.evpn.0, evpn)

Если BGP-сеанс установить невозможно, причина должна быть указана в логах каждого BGP-демона.

Отправленные маршруты

С каждого VTEP сервер Quagga должен отправить:

  • один маршрут L3 для каждого локального VNI;
  • один маршрут L2 для каждого локального MAC-адреса.

Лучше всего проверять полученные маршруты на одном из рефлекторов маршрута. При использовании JunOS маршруты, полученные от указанного VTEP, можно посмотреть с помощью:

> show route table bgp.evpn.0 receive-protocol bgp 203.0.113.2

bgp.evpn.0: 10 destinations, 10 routes (10 active, 0 holddown, 0 hidden)
Prefix Nexthop MED Lclpref AS path
2:203.0.113.2:100::0::50:54:33:00:00:0a/304 MAC/IP
* 203.0.113.2 100 I
2:203.0.113.2:100::0::50:54:33:00:00:0b/304 MAC/IP
* 203.0.113.2 100 I
3:203.0.113.2:100::0::203.0.113.2/304 IM
* 203.0.113.2 100 I
3:203.0.113.2:200::0::203.0.113.2/304 IM
* 203.0.113.2 100 I

У нас есть один маршрут L3 для VNI100 и один для VNI200, а также два маршрута L2 для двух MAC-адресов на VNI100. Для получения более подробной информации можно добавить extensive. Маршрут L3 анонсирует 203.0.113.2 в качестве VTEP для VNI100 следующим образом:

>  show route table bgp.evpn.0 receive-protocol bgp 203.0.113.2 extensive

bgp.evpn.0: 11 destinations, 11 routes (11 active, 0 holddown, 0 hidden)
* 3:203.0.113.2:100::0::203.0.113.2/304 IM (1 entry, 1 announced)
     Accepted
     Route Distinguisher: 203.0.113.2:100
     Nexthop: 203.0.113.2
     Localpref: 100
     AS path: I
     Communities: target:65000:268435556 encapsulation:vxlan(0x8)
[...]

Значение 100, используемое в определении маршрута (203.0.113.2:100), не является номером VNI, хотя и совпадает с ним. VNI кодируется в целевом маршруте (65000:268435556) в 24 менее значимых битах (268435556 & 0xffffff равные 100). Но пока VNI уникальны, нет необходимости вникать в эти подробности.

Маршрут 2 типа анонсирует расположение MAC-адреса 50:54:33:00:00:0a для VNI100 следующим образом:

>  show route table bgp.evpn.0 receive-protocol bgp 203.0.113.2 extensive

bgp.evpn.0: 11 destinations, 11 routes (11 active, 0 holddown, 0 hidden)
* 2:203.0.113.2:100::0::50:54:33:00:00:0a/304 MAC/IP (1 entry, 1 announced)
     Accepted
     Route Distinguisher: 203.0.113.2:100
     Route Label: 100
     ESI: 00:00:00:00:00:00:00:00:00:00
     Nexthop: 203.0.113.2
     Localpref: 100
     AS path: I
     Communities: target:65000:268435556 encapsulation:vxlan(0x8)
[...]

При использовании Quagga, подобный ответ можно получить с помощью vtysh:

#  show bgp evpn route
BGP table version is 0, local router ID is 203.0.113.1
Status codes: s suppressed, d damped, h history, * valid, > best, i - internal
Origin codes: i - IGP, e - EGP, ? - incomplete
EVPN type-2 prefix: [2]:[ESI]:[EthTag]:[MAClen]:[MAC]
EVPN type-3 prefix: [3]:[EthTag]:[IPlen]:[OrigIP]

   Network          Next Hop            Metric LocPrf Weight Path
Route Distinguisher: 203.0.113.2:100
*>i[2]:[0]:[0]:[48]:[50:54:33:00:00:0a]
                    203.0.113.2                   100      0 i
*>i[2]:[0]:[0]:[48]:[50:54:33:00:00:0b]
                    203.0.113.2                   100      0 i
*>i[3]:[0]:[32]:[203.0.113.2]
                    203.0.113.2                   100      0 i
Route Distinguisher: 203.0.113.2:200
*>i[3]:[0]:[32]:[203.0.113.2]
                    203.0.113.2                   100      0 i
[...]

Для GoBGP воспользуйтесь следующей командой:

#  gobgp global rib -a evpn | grep rd:203.0.113.2:200
    Network  Next Hop             AS_PATH              Age        Attrs
*>  [type:macadv][rd:203.0.113.2:100][esi:single-homed][etag:0][mac:50:54:33:00:00:0a][ip:<nil>][labels:[100]]203.0.113.2                               00:00:17   [{Origin: i} {LocalPref: 100} {Extcomms: [VXLAN], [65000:268435556]}]
*>  [type:macadv][rd:203.0.113.2:100][esi:single-homed][etag:0][mac:50:54:33:00:00:0b][ip:<nil>][labels:[100]]203.0.113.2                               00:00:17   [{Origin: i} {LocalPref: 100} {Extcomms: [VXLAN], [65000:268435556]}]
*>  [type:macadv][rd:203.0.113.2:200][esi:single-homed][etag:0][mac:50:54:33:00:00:0a][ip:<nil>][labels:[200]]203.0.113.2                               00:00:17   [{Origin: i} {LocalPref: 100} {Extcomms: [VXLAN], [65000:268435656]}]
*>  [type:multicast][rd:203.0.113.2:100][etag:0][ip:203.0.113.2]203.0.113.2                               00:00:17   [{Origin: i} {LocalPref: 100} {Extcomms: [VXLAN], [65000:268435556]}]
*>  [type:multicast][rd:203.0.113.2:200][etag:0][ip:203.0.113.2]203.0.113.2                               00:00:17   [{Origin: i} {LocalPref: 100} {Extcomms: [VXLAN], [65000:268435656]}]

Полученные маршруты

Каждый VTEP должен был получить от других VTEP маршруты L2 и L3 через серверы RR. Проверить это можно с помощью команды show bgp evpn route из vtysh.

Проверим, верно ли Quagga понимает полученные маршруты. Маршруты L3 отображаются в связку VTEP и VNI:

#  show evpn vni
Number of VNIs: 2
VNI        VxLAN IF              VTEP IP         # MACs   # ARPs   Remote VTEPs
100        vxlan100              203.0.113.2     4        0        203.0.113.3
                                                                   203.0.113.1
200        vxlan200              203.0.113.2     3        0        203.0.113.3
                                                                   203.0.113.1

Маршруты L2 отображаются в связку MAC-адреса и VTEP:

#  show evpn mac vni 100
Number of MACs (local and remote) known for this VNI: 4
MAC               Type   Intf/Remote VTEP      VLAN
50:54:33:00:00:09 remote 203.0.113.1
50:54:33:00:00:0a local  eth1.100
50:54:33:00:00:0b local  eth2.100
50:54:33:00:00:0c remote 203.0.113.3

Конфигурация FDB

На заключительном шаге убедимся, что Quagga правильно экспортировала полученную информацию в ядро. Проверить это можно с помощью команды bridge:

#  bridge fdb show dev vxlan100 | grep dst
00:00:00:00:00:00 dst 203.0.113.1 self permanent
00:00:00:00:00:00 dst 203.0.113.3 self permanent
50:54:33:00:00:0c dst 203.0.113.3 self
50:54:33:00:00:09 dst 203.0.113.1 self

Все хорошо! Первые две строки - это трансляция маршрутов 3 типа (любой BUM-кадр будет отправлен на 203.0.113.1 и 203.0.113.3), а две последние строки - трансляция маршрутов 2 типа.

Совместимость

Одним из преимуществ BGP EVPN является совместимость с другими вендорами сетевого оборудования. Чтобы продемонстрировать, что она работает корректно, сконфигурируем Juniper vMX версии 16.1R1.7 d в качестве VTEP.

Update (04.2018): Необходимо подключить следующие патчи для FRR: bgpd: add an option for RT auto-derivation to use RFC 8635 и bgpd: add basic support for ETI and ESI for BGP EVPN. Также, в FRR необходимо включить флаг autort rfc8365-compatible. Первый патч можно удалить, если цели маршрута настроены вручную на стороне Juniper. Без второго можно обойтись, если настроить отдельный экземпляр вирутального коммутатора Juniper для каждого VNI, которые имеют выделенные разделители маршрутов. Для Cumulus Quagga можно применить упрощенную версию данных патчей (первый патч, второй патч, третий патч, четвертый патч).

Сперва необходимо настроить физический мост.

По некоторым причинам использование виртуального коммутатора обязательно. Это относится к платформе vMX. Коммутатор QFX этого не требует.

Настройка напоминает использование ip link и brctl в Linux. Настраиваем только один физический интерфейс с двумя традиционными VLAN с соответствующими VNI.

interfaces {
    ge-0/0/1 {
        unit 0 {
            family bridge {
                interface-mode trunk;
                vlan-id-list [ 100 200 ];
            }
        }
    }
}

routing-instances {
    switch {
        instance-type virtual-switch;
        interface ge-0/0/1.0;
        bridge-domains {
            vlan100 {
                domain-type bridge;
                vlan-id 100;
                no-arp-suppression;
                vxlan vni 100;
            }
            vlan200 {
                domain-type bridge;
                vlan-id 200;
                no-arp-suppression;
                vxlan vni 200;
            }
        }
    }
}

Далее настроим BGP EVPN для анонса всех известных VNI. Настройка очень похожа на ту, что мы использовали для Quagga:

protocols {
    bgp {
        group fabric {
            type internal;
            multihop;
            family evpn signaling;
            local-address 203.0.113.3;
            neighbor 203.0.113.253;
            neighbor 203.0.113.254;
        }
    }
}

routing-instances {
    switch {
        vtep-source-interface lo0.0;
        route-distinguisher 203.0.113.3:1; # ❶
        vrf-import EVPN-VRF-VXLAN;
        vrf-target {
            target:65000:1;
            auto;
        }
        protocols {
            evpn {
                encapsulation vxlan;
                extended-vni-list all;
                multicast-mode ingress-replication;
            }
        }
    }
}

routing-options {
    router-id 203.0.113.3;
    autonomous-system 65000;
}

policy-options {
    policy-statement EVPN-VRF-VXLAN {
        then accept;
    }
}

Маршруты, отправленные данной настройкой, очень похожи на те, что были отправлены Quagga. Основные различия в следующем:

  • на JunOS определитель маршрута настроен статично (в ❶);
  • на JunOS VNI зашифрован также, как и ID тега Ethernet.

Так выглядит маршрут L3 в том виде, в котором его отправляет JunOS:

> show route table bgp.evpn.0 receive-protocol bgp 203.0.113.3 extensive

bgp.evpn.0: 13 destinations, 13 routes (13 active, 0 holddown, 0 hidden)
* 3:203.0.113.3:1::100::203.0.113.3/304 IM (1 entry, 1 announced)
Accepted
Route Distinguisher: 203.0.113.3:1
Nexthop: 203.0.113.3
Localpref: 100
AS path: I
Communities: target:65000:268435556 encapsulation:vxlan(0x8)
PMSI: Flags 0x0: Label 6: Type INGRESS-REPLICATION 203.0.113.3
[...]

А так - маршрут L2:

> show route table bgp.evpn.0 receive-protocol bgp 203.0.113.3 extensive

bgp.evpn.0: 13 destinations, 13 routes (13 active, 0 holddown, 0 hidden)
* 2:203.0.113.3:1::200::50:54:33:00:00:0f/304 MAC/IP (1 entry, 1 announced)
Accepted
Route Distinguisher: 203.0.113.3:1
Route Label: 200
ESI: 00:00:00:00:00:00:00:00:00:00
Nexthop: 203.0.113.3
Localpref: 100
AS path: I
Communities: target:65000:268435656 encapsulation:vxlan(0x8)
[...]

Можно проверить, что vMX может понять маршруты, которые он получает от своих соседей, на которых работает Quagga:

>  show evpn database l2-domain-id 100
Instance: switch
VLAN  DomainId  MAC address        Active source                  Timestamp        IP address
     100        50:54:33:00:00:0c  203.0.113.1                    Apr 30 12:46:20
     100        50:54:33:00:00:0d  203.0.113.2                    Apr 30 12:32:42
     100        50:54:33:00:00:0e  203.0.113.2                    Apr 30 12:46:20
     100        50:54:33:00:00:0f  ge-0/0/1.0                     Apr 30 12:45:55

С другой стороны, если мы посмотрим на один из VTEP в Quagga, мы сможем проверить, что полученные маршруты поняты верно:

#  show evpn vni 100
VNI: 100
 VxLAN interface: vxlan100 ifIndex: 9 VTEP IP: 203.0.113.1
 Remote VTEPs for this VNI:
  203.0.113.3
  203.0.113.2
 Number of MACs (local and remote) known for this VNI: 4
 Number of ARPs (IPv4 and IPv6, local and remote) known for this VNI: 0
 show evpn mac vni 100
Number of MACs (local and remote) known for this VNI: 4
MAC               Type   Intf/Remote VTEP      VLAN
50:54:33:00:00:0c local  eth1.100
50:54:33:00:00:0d remote 203.0.113.2
50:54:33:00:00:0e remote 203.0.113.2
50:54:33:00:00:0f remote 203.0.113.3

Update (03.2018): BGP EVPN также может обрабатывать сегменты Ethernet с несколькими интерфейсами: совокупность каналов может охватывать несколько VTEP. Хотя это поддерживается в Juniper, Quagga / FRR не поддерживает такую настройку и будет игнорировать удаленные многоинтерфейсные сегменты. Подробнее о настройке Juniper смотрите в серии статей “EVPN-VXLAN lab” Александра Григоренко, а также в whitepaper от Juniper.

Если вам понравился этот пост, поделитесь им с друзьями.