vrf-table-label

Сегодня речь пойдет о команде vrf-table-label. Вначале вспомним о способах генерации vrf меток. Метки могут быть сгенерированны тремя способами — per-vrf, per-prefix и per-next-hop.

per-prefix — одна метка — один клиентский префикс, то есть если у нас 100 клиентских vrf и у каждого клиента по 100 префиксов, то мы получим 100×100=10 000 меток, что очень расточительно по сегодняшним меркам. Данный метод распределения меток vrf по дефолту используется в маршрутизаторах Cisco.

per-next-hop — одна метка на все префиксы клиента, которые имеют один и тот же next-hop. Если клиентский маршрутизатор подключен к PE маршрутизатору одним линком, то все префиксы будут иметь один и тот же next-hop, а значит одну и ту же метку. Данный механизм распределения меток vrf по дефолту в JunOS.

per-vrf — одна метка на весь vrf. С точки зрения распределения меток этот режим очень экономичен: если у нас 100 клиентских vrf и у каждого клиента по 100 префиксов, то мы получим 100×1=100 меток. При таком распределении меток vrf маршрутизатор должен делать помимо mpls lookup еще и ip lookup.

Как было написано выше, по умолчанию JunOS использует распределение меток per-next-hop. Если вы хотите изменить это поведение, то вам придется дать команду vrf-table-label (для любителей замороченных конфигураций механизм распределения меток можно задать с помощью политики) либо использовать тоннельный PIC. Теперь разберем как все работает с данной командой и без нее. Будем использовать вот такую схему с Option C.
545f464824d64ac3941662e34f366f6c.jpg
Без команды vrf-table label (и создания vt-интерфейса).
Конфигурация vrf на PE1 выглядит следующим образом:

bormoglotx@PE1> show configuration routing-instances CE1
instance-type vrf;
interface ge-0/0/3.10;
interface ge-0/0/3.20;
route-distinguisher 1:1;
vrf-target {
    import target:2:100;
    export target:2:100;
}
protocols {
    ospf {
        export ospf-export;
        area 0.0.0.0 {
            interface ge-0/0/3.10;
            interface ge-0/0/3.20;
        }
    }
}

bormoglotx@PE1> show configuration interfaces ge-0/0/3
description "to SW1";
vlan-tagging;
unit 10 {
    description "to CE1 site 1";
    vlan-id 10;
    family inet {
        address 10.0.0.1/24;
    }
}
unit 20 {
    description "to CE1 site 2";
    vlan-id 20;
    family inet {
        address 20.0.0.1/24;
    }
}


Соответственно маршрутизатор начинает генерировать vpnv4 префиксы и передавать их на роутрефлекторы. В нашем случае роутрефлектор имеет адрес 10.0.10.10:

bormoglotx@PE1> show route advertising-protocol bgp 10.0.10.10

CE1.inet.0: 9 destinations, 9 routes (9 active, 0 holddown, 0 hidden)
  Prefix                  Nexthop              MED     Lclpref    AS path
* 10.0.0.0/24             Self                         100        I
* 10.1.1.1/32             Self                 2       100        I
* 20.0.0.0/24             Self                         100        I
* 20.1.1.1/32             Self                 2       100        I


PE1 отдает на рефлектор четыре маршрута: две connected сети и два /32 (лупбеки CE маршрутизаторов), которые получает по ospf. Посмотрим, какие метки были сгенерированны для данных префиксов:

bormoglotx@PE1> show route advertising-protocol bgp 10.0.10.10 detail

CE1.inet.0: 9 destinations, 9 routes (9 active, 0 holddown, 0 hidden)
* 10.0.0.0/24 (1 entry, 1 announced)
 BGP group RR type Internal
     Route Distinguisher: 1:1
     VPN Label: 299888
     Nexthop: Self
     Flags: Nexthop Change
     Localpref: 100
     AS path: [1] I
     Communities: target:2:100

* 10.1.1.1/32 (1 entry, 1 announced)
 BGP group RR type Internal
     Route Distinguisher: 1:1
     VPN Label: 299888
     Nexthop: Self
     Flags: Nexthop Change
     MED: 2
     Localpref: 100
     AS path: [1] I
     Communities: target:2:100 rte-type:0.0.0.0:1:0

* 20.0.0.0/24 (1 entry, 1 announced)
 BGP group RR type Internal
     Route Distinguisher: 1:1
     VPN Label: 299904
     Nexthop: Self
     Flags: Nexthop Change
     Localpref: 100
     AS path: [1] I
     Communities: target:2:100

* 20.1.1.1/32 (1 entry, 1 announced)
 BGP group RR type Internal
     Route Distinguisher: 1:1
     VPN Label: 299904
     Nexthop: Self
     Flags: Nexthop Change
     MED: 2
     Localpref: 100
     AS path: [1] I
     Communities: target:2:100 rte-type:0.0.0.0:1:0


Для наглядности выделим из выводов только значения меток:

bormoglotx@PE1> show route advertising-protocol bgp 10.0.10.10 detail | match label
     VPN Label: 299888
     VPN Label: 299888
     VPN Label: 299904
     VPN Label: 299904


Видно, что для префиксов из диапазона 10.0.0.0/8 сгенерирована метка 299888, а для префиксов из диапазона 20.0.0.0/8 метка 299904. Но есть один не очень приятный нюанс — в данном случае JunOS не производит ip lookup. Чем это грозит? Вы не сможете использовать фильтры, так как ip заголовок не анализируется.

Проверим это на практике.
Согласно представленному ниже выводу, PE1, получив пакет с меткой 299904 просто отправляет его в интерфейс ge-0/0/3.20:

bormoglotx@PE1> show route table mpls.0 label 299904

mpls.0: 11 destinations, 11 routes (11 active, 0 holddown, 0 hidden)
+ = Active Route, - = Last Active, * = Both

299904             *[VPN/170] 00:46:19
                    > to 20.0.0.2 via ge-0/0/3.20, Pop



а для пакетов с меткой 299888 — в интерфейс ge-0/0/3.10:

bormoglotx@PE1> show route table mpls.0 label 299888

mpls.0: 11 destinations, 11 routes (11 active, 0 holddown, 0 hidden)
+ = Active Route, - = Last Active, * = Both

299888             *[VPN/170] 00:46:25
                    > to 10.0.0.2 via ge-0/0/3.10, Pop


Как видите, маршрутизатор будет снимать метку и отправлять пакет в интерфейс в зависимости от входящей метки, не делая ip lookup-а, в чем мы сейчас и убедимся.

Проверим наличие vpnv4 маршрутов на PE2:

PE2#sh ip bgp vpnv4 rd 1:1 labels
   Network          Next Hop      In label/Out label
Route Distinguisher: 1:1
   10.0.0.0/24      10.0.10.1       nolabel/299888
   10.1.1.1/32      10.0.10.1       nolabel/299888
   20.0.0.0/24      10.0.10.1       nolabel/299904
   20.1.1.1/32      10.0.10.1       nolabel/299904


Теперь посмотрим таблицу маршрутизации на CE2:

CE2#sh ip rou | b Ga
Gateway of last resort is not set

      10.0.0.0/8 is variably subnetted, 5 subnets, 2 masks
O E2     10.0.0.0/24 [110/10] via 10.0.1.1, 00:22:32, GigabitEthernet1/0.10
C        10.0.1.0/24 is directly connected, GigabitEthernet1/0.10
L        10.0.1.2/32 is directly connected, GigabitEthernet1/0.10
O E2     10.1.1.1/32 [110/10] via 10.0.1.1, 00:22:32, GigabitEthernet1/0.10
C        10.1.1.2/32 is directly connected, Loopback0
      20.0.0.0/8 is variably subnetted, 2 subnets, 2 masks
O E2     20.0.0.0/24 [110/10] via 10.0.1.1, 00:22:32, GigabitEthernet1/0.10
O E2     20.1.1.1/32 [110/10] via 10.0.1.1, 00:22:32, GigabitEthernet1/0.10


Все отлично — маршруты есть. Теперь можем запустить трассировку до 20.0.0.2 — адрес CE1–2:

CE2#traceroute 20.0.0.2

Type escape sequence to abort.
Tracing the route to 20.0.0.2

  1 10.0.1.1 36 msec 32 msec 8 msec
  2 10.1.3.2 [MPLS: Labels 20/18/299904 Exp 0] 56 msec 64 msec 60 msec
  3 10.1.2.1 [MPLS: Labels 18/299904 Exp 0] 72 msec 108 msec 40 msec
  4 10.2.0.1 [MPLS: Labels 299952/299904 Exp 0] 60 msec 88 msec 60 msec
  5 10.0.3.2 [MPLS: Labels 299808/299904 Exp 0] 76 msec 68 msec 64 msec
  6 10.0.2.1 [MPLS: Label 299904 Exp 0] 60 msec 52 msec 64 msec
  7 20.0.0.2 60 msec 60 msec 56 msec


Все предсказуемо — стандартная трассировка через Option C.
17f8823c238c4440a1fbdfb411ff288d.jpg
А теперь запустим трассировку до 20.0.0.1 — это адрес интерфейса PE1 в сторону клиента (в самом начале статьи показана настройка интерфейса):

CE2#traceroute 20.0.0.1

Type escape sequence to abort.
Tracing the route to 20.0.0.1

  1 10.0.1.1 40 msec 4 msec 16 msec
  2 10.1.3.2 [MPLS: Labels 20/18/299904 Exp 0] 80 msec 64 msec 60 msec
  3 10.1.2.1 [MPLS: Labels 18/299904 Exp 0] 56 msec 60 msec 72 msec
  4 10.2.0.1 [MPLS: Labels 299952/299904 Exp 0] 48 msec 76 msec 112 msec
  5 10.0.3.2 [MPLS: Labels 299808/299904 Exp 0] 68 msec 96 msec 64 msec
  6 10.0.2.1 [MPLS: Label 299904 Exp 0] 80 msec 68 msec 4 msec
  7 20.0.0.2 92 msec 72 msec 64 msec
  8 20.0.0.1 96 msec 48 msec 88 msec


Сравнивая вывод с предыдущим, мы видим что до 20.0.0.1 на один хоп больше. Как так, ведь 20.0.0.1 — шлюз для сети 20.0.0.0/24? Если смотреть внимательнее, то мы видим, что пакет с PE-маршрутизатора (10.0.2.1 — core facing interface) был отправлен на CE маршрутизатор (адрес 20.0.0.2) и вернулся обратно на PE-маршрутизатор (20.0.0.1). Как я и сказал, JunOS не сделал ip lookup и просто переслал пакет в интерфейс клиента, а вот уже клиентский маршрутизатор проверил адрес назначения ip пакета и отправил его обратно на PE1 (см рисунок ниже):
96072b371f884f37b28cc69d7554fb4c.jpg
То есть в нашем случае маршрутизатор принял пакет с меткой из ядра сети, посмотрел в таблице mpls.0 что необходимо сделать с пакетом, снял метку и отправил в интерфейс в сторону клиента.
7375bcf7680e4449b71ddd6002a097c5.jpg
Если мы повесим какой-либо фильтр на нашем PE маршрутизаторе на клиентский интерфейс или настроим qos, то ввиду вышесказанного трафик не будет обрабатываться согласно установленным фильтрам.

Повесим на интерфейс в сторону клиента фильтр:

bormoglotx@PE1# show firewall family inet filter To-CE1-2
term 1 {
    from {
        destination-address {
            20.0.0.0/24;
        }
    }
    then {
        reject;
    }
}
term 2 {
    then accept;
}

[edit]
bormoglotx@PE1# show interfaces ge-0/0/3.20
description "to CE1 site 2";
vlan-id 20;
family inet {
    filter {
        output To-CE1-2;
    }
    address 20.0.0.1/24;
}


И теперь запустим пинг до сети 20.0.0.0/24 с CE2:

CE2#ping 20.0.0.2

Type escape sequence to abort.
Sending 5, 100-byte ICMP Echos to 20.0.0.2, timeout is 2 seconds:
!!!!!
Success rate is 100 percent (5/5), round-trip min/avg/max = 64/69/72 ms


Фильтр есть, но он не работает. Изменим эту ситуацию, включив опцию vrf-table label:

[edit]
bormoglotx@PE1# set routing-instances CE1 vrf-table-label


Попробуем снова запустить пинг до сети 20.0.0.0/24 с CE2:

CE2#ping 20.0.0.2

Type escape sequence to abort.
Sending 5, 100-byte ICMP Echos to 20.0.0.2, timeout is 2 seconds:
UUUUU
Success rate is 0 percent (0/5)


Теперь хост недостижим — фильтр отрабатывает. Снимем фильтр и снова запустим пинг для проверки:

[edit]
bormoglotx@PE1# deactivate interfaces ge-0/0/3.20 family inet filter

[edit]
bormoglotx@PE1# show | compare
[edit interfaces ge-0/0/3 unit 20 family inet]
!        inactive: filter { ... }

CE2#ping 20.0.0.2

Type escape sequence to abort.
Sending 5, 100-byte ICMP Echos to 20.0.0.2, timeout is 2 seconds:
!!!!!
Success rate is 100 percent (5/5), round-trip min/avg/max = 60/88/148 ms


Все отлично. Теперь мы увидели наглядно, какие подводные камни нас ожидают при дефолтном механизме распределения меток vrf в JunOS. Так как выше мы уже дали команду vrf-table-label и деактивировали фильтр, то приступим к обсуждению работы маршрутизатора с включенной опцией vrf-table-label.

Посмотрим маршруты, которые PE1 анонсирует на роутрефлектор:
bormoglotx@PE1> show route advertising-protocol bgp 10.0.10.10

CE1.inet.0: 9 destinations, 9 routes (9 active, 0 holddown, 0 hidden)
  Prefix                  Nexthop              MED     Lclpref    AS path
* 10.0.0.0/24             Self                         100        I
* 10.1.1.1/32             Self                 2       100        I
* 20.0.0.0/24             Self                         100        I
* 20.1.1.1/32             Self                 2       100        I

bormoglotx@PE1> show route advertising-protocol bgp 10.0.10.10 detail

CE1.inet.0: 9 destinations, 9 routes (9 active, 0 holddown, 0 hidden)
* 10.0.0.0/24 (1 entry, 1 announced)
 BGP group RR type Internal
     Route Distinguisher: 1:1
     VPN Label: 16
     Nexthop: Self
     Flags: Nexthop Change
     Localpref: 100
     AS path: [1] I
     Communities: target:2:100

* 10.1.1.1/32 (1 entry, 1 announced)
 BGP group RR type Internal
     Route Distinguisher: 1:1
     VPN Label: 16
     Nexthop: Self
     Flags: Nexthop Change
     MED: 2
     Localpref: 100
     AS path: [1] I
     Communities: target:2:100 rte-type:0.0.0.0:1:0

* 20.0.0.0/24 (1 entry, 1 announced)
 BGP group RR type Internal
     Route Distinguisher: 1:1
     VPN Label: 16
     Nexthop: Self
     Flags: Nexthop Change
     Localpref: 100
     AS path: [1] I
     Communities: target:2:100

* 20.1.1.1/32 (1 entry, 1 announced)
 BGP group RR type Internal
     Route Distinguisher: 1:1
     VPN Label: 16
     Nexthop: Self
     Flags: Nexthop Change
     MED: 2
     Localpref: 100
     AS path: [1] I
     Communities: target:2:100 rte-type:0.0.0.0:1:0


Как видите, теперь у нас только одна метка на все маршруты из vrf CE1:

bormoglotx@PE1> show route advertising-protocol bgp 10.0.10.10 detail | match label
     VPN Label: 16
     VPN Label: 16
     VPN Label: 16
     VPN Label: 16


Снова запустим трассировку с CE2 до 20.0.0.1:

CE2#traceroute 20.0.0.1

Type escape sequence to abort.
Tracing the route to 20.0.0.1

  1 10.0.1.1 32 msec 16 msec 20 msec
  2 10.1.3.2 [MPLS: Labels 20/18/16 Exp 0] 76 msec 48 msec 68 msec
  3 10.1.2.1 [MPLS: Labels 18/16 Exp 0] 68 msec 48 msec 56 msec
  4 10.2.0.1 [MPLS: Labels 299952/16 Exp 0] 52 msec 48 msec 52 msec
  5 10.0.3.2 [MPLS: Labels 299808/16 Exp 0] 52 msec 52 msec 52 msec
  6 20.0.0.1 76 msec 52 msec 72 msec


Теперь icmp пакеты не идут петлей через CE1–2.
Сам маршрут на PE1 теперь выглядит несколько иначе:

bormoglotx@PE1> show route table mpls.0 label 16

mpls.0: 10 destinations, 10 routes (10 active, 0 holddown, 0 hidden)
+ = Active Route, - = Last Active, * = Both

16                 *[VPN/0] 00:04:23
                      to table CE1.inet.0, Pop


Говоря обычным языком, при получении пакета с меткой 16 необходимо снять метку и сделать ip lookup в таблице CE1.inet.0. Почему же в Juniper данная функция не реализована при генерации меток per-nex-hop? Дело в архитектуре оборудования Juniper — PFE не может сделать и mpls и ip lookup одновременно. Для реализации двойного lookup-а нам понадобится так называемый Tunnel Services PIC, далее туннельный PIC (интерфейс vt-fpc/pic/port.unit-number). Вот так выглядит PIC в составе шасси M120:
18f533b66f8341ba9ca432e8abfc3e18.jpg
Примечание: О создании vt-интерфейса и добавлении его в vrf можно почитать тут

Теперь алгоритм обработки пакета будет изменен: маршрутизатор принял пакет с меткой из ядра сети, посмотрел в таблице mpls.0 что необходимо сделать с пакетом, снял метку и отправил в интерфейс vt, далее пакет из vt интерфейса снова попадает на PFE, но уже без метки и PFE может сделать ip lookup (и далее отправить в сторону клиента).
44bd21a887a646458208ef1293f32a10.jpg
Но необходимость в туннельном PIC накладывает определенные ограничения на использование данной функции. Поэтому, если у вас нет такого PIC, то вы можете дать команду vrf-table-label и JunOS автоматически создает виртуальный интерфейс lsi (label switching interface) (поддерживается платформами ACX, M, MX, T Series), который выполняет точно такую же функцию, что и vt-интерфейс:

bormoglotx@PE1> show interfaces terse | match lsi
lsi                     up    up
lsi.0                   up    up   inet


Данный интерфейс не доступен для конфигурирования. На каждый vrf создается отдельный lsi интерфейс, который ассоциируется с генерируемой для данного vrf меткой. К примеру, создадим еще один vrf и посмотрим, сколько lsi интерфейсов теперь:

bormoglotx@PE1> show configuration routing-instances ?
Possible completions:
  <[Enter]>            Execute this command
        Routing instance name
  CE1                  Routing instance name
  CE2                  Routing instance name
+ apply-groups         Groups from which to inherit configuration data
+ apply-groups-except  Don't inherit configuration data from these groups
  |                    Pipe through a command


bormoglotx@PE1> show interfaces terse | match lsi
lsi                     up    up
lsi.0                   up    up   inet
lsi.1                   up    up   inet

Посмотреть какой lsi unit соответствует какой-либо routing instance можно командой: show interfaces lsi routing-instance instance-name, к примеру в нашем случае:

bormoglotx@PE1> show interfaces lsi routing-instance CE1 | match logical
  Logical interface lsi.0 (Index 71) (SNMP ifIndex 524)

bormoglotx@PE1> show interfaces lsi routing-instance CE2 | match logical
  Logical interface lsi.1 (Index 81) (SNMP ifIndex 525)


Интерфейс lsi создается и для vpls routing-instance (команда no-tunnel-services), трафик в таком случае обрабатывается как описано выше, за исключением того, что vpls оперирует исключительно mac адресами, не зная ничего о клиентских ip адресах, но это уже совсем другая история.

Спасибо за внимание!

© Habrahabr.ru