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.
Без команды 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.
А теперь запустим трассировку до 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 (см рисунок ниже):
То есть в нашем случае маршрутизатор принял пакет с меткой из ядра сети, посмотрел в таблице mpls.0 что необходимо сделать с пакетом, снял метку и отправил в интерфейс в сторону клиента.
Если мы повесим какой-либо фильтр на нашем 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:
Примечание: О создании vt-интерфейса и добавлении его в vrf можно почитать тут
Теперь алгоритм обработки пакета будет изменен: маршрутизатор принял пакет с меткой из ядра сети, посмотрел в таблице mpls.0 что необходимо сделать с пакетом, снял метку и отправил в интерфейс vt, далее пакет из vt интерфейса снова попадает на PFE, но уже без метки и PFE может сделать ip lookup (и далее отправить в сторону клиента).
Но необходимость в туннельном 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
<instance_name> 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 адресах, но это уже совсем другая история.
Спасибо за внимание!
Комментарии (9)
Gem
12.06.2016 11:52Прочитал. Отлично, спасибо. Теперь интересно как оно автоматом создает lsi, как выбирает pic. Как это работает вместе с руками объявленными туннел сервис. И вообще на бэндвиче платы как сказывается?
Bormoglotx
12.06.2016 11:57Как автоматически создается lsi — ну это надо к разработчикам уже как они это реализовали)).
И вообще на бэндвиче платы как сказывается — на сколько я знаю производительность платы от этого не страдает. Поправьте, если не прав.
AllTheThingsUndone
12.06.2016 12:05Волею случая работаю и с JunOS, и со всеми «вкусами» IOS'а (NX-, -XE, -XR) и самыми удобными считаю JunOS и IOS-XR. В JunOS, конечно, раздражает необходимость проваливаться на шесть уровней вниз, чтобы сделать банальную вещь (как то присвоить адрес интерфейсу) или их идеология «конфигурировать все explicitly, а не implicitly, как Циско» (по умолчанию ничего не включено/присвоено/работает), но не настолько, чтобы предпочесть ей IOS-XE.
Ну и знаменитое «the only consistency in IOS is its inconsistency» делу не помогает (глядеть уровень оптического сигнала на порту тремя разными командами на 3 платформах одного вендора — это ад).
Про SR-OS ничего сказать не могу, но судя по конфигам, это дитя XR'а и JunOS'а.
Bormoglotx
12.06.2016 12:08А зачем проваливаться в уровень иерархии если конфигурите интерфейс? Одной командой, но очень длинной, все можно сделать. К примеру set interfaces xe-11/0/0 vlan-tagging unit 10 vlan-id 10 family inet address 10.0.0.1/30
А show run formal в xr по-моему стащили из JunOS — display set.AllTheThingsUndone
12.06.2016 12:16Видимо, мы друг друга недопоняли: я работаю с JunOS и умею его, как бы это сказать, конфигурировать, в том числе «одной командой, но очень длинной». Мне не нравится логическое представление конфигурации того же интерфейса 6 уровнями. Вкусовщина.
Bormoglotx
12.06.2016 12:23Понял теперь, мне наоборот больше нравится иерархичность JunOS в том числе и на уровне интерфейса. Но да, на вкус и цвет как говорится…
Balintrue
Я конечно дико извиняюсь. Но волей случая я занимаюсь администрированием сетевой инфраструктуры на cisco в «одной» компании. Сразу оговорюсь, что академиев я не кончал, т.е. cisco-вских сертификатов не имею, но вполне успешно (работодатель доволен) выполняю все хотелки заказчика. Я к чему: то, что вы Вы описали выполняется на cisco элементарно (реализовано как одна из хотелок заказчика), а у Вас, простите, хотел написать грубо, но потом опомнился — хабр все таки и мой первый камент — все как то с ног на голову. Возможно, я не достаточно проникся идеологией JunOS, но жизнь требует простых решений.
vasilevkirill
а по моему, всё очень чётко и доходчиво написано.
или вы про идеологию Juniper? ну так "не на кошках мир построен"
Bormoglotx
Холивары о том, что лучше, будут всегда и каждому нравится что то свое. Я лично люблю больше JunOS хотя бы за то, как он выводит конфиг (удобно, все разложено по полочкам, а не как в Cisco — тут читать, тут не читать, тут селедку заворачивали). К тому же JunOS не меняет синтаксис в отличии от других компаний — ios, ios-xe, ios-xe, nexus-os, asa; про Huawei вообще молчу.