L3VPN: различия между версиями
Строка 373: | Строка 373: | ||
==Hub-and-spoke== | ==Hub-and-spoke== | ||
[[Файл: | [[Файл:Hub_and_spoke_topology.png]] |
Версия 15:18, 20 ноября 2016
Routing (Control plane)
Рассмотрим такую схему:
CE1 <static> PE1 <mpls> P <mpls> PE2 <static> CE2
Между CE и PE - маршрутизация (static, bgp, ospf). CE присылает свои префиксы, но ISP должен отделить эти префиксы от других и поместить с отдельную таблицу. Для этого клиент заводится в routing-instance (vrf).
PE должен передать принятые префиксы от клиента другому PE на удаленный конец, и затем отдать их удаленному CE2. Используем iBGP. В момент отправки префиксов с PE, нужно пометить их. Добавляем некое число - route-destinguisher (RD) - не идентифицирует клиента, просто делает префикс уникальным внутри процесса BGP. RD должен быть уникальным в пределах всей сети, поэтому зачастую используют IDrouter:число. RD - часть NLRI.
Типы RD:
- 2 byte: AS, 4 byte: идентификатор клиента
- 4 byte: router-ID, 2 byte: идентификатор клиента - можно руками не задавать, а поручить это маршрутизатору.
- 4 byte: 4 byte AS, 2 byte: идентификатор клиента
В inet.0 хранятся IPv4, не получится туда залить наши префиксы, т.к. они имеют совсем другую структуру.
NLRI - абстрактная структура данных. Роутеры до установления сессии должны совпадать хотя бы по 2-м address family.
Включаем protocols bgp family inet-vpn any - только после этого BGP будет способен передавать новые NLRI. По умолчанию, если включается какая-то конкретная family, то требуется указать все family, которые будут передаваться через MP-BGP. То есть добавляем сюда и family inet обязательно.
Под новые NLRI создается своя таблица: bgp.l3vpn.0. Префиксы хранятся вместе с RD. Таблица используется только на control plane, не для форвардинга. Для форвардинга будет использоваться отдельная таблица для VRF. В ней префиксы будут храниться в обычном IPv4 формате. Для этого нужно убрать RD и разложить префиксы по нужным VRF. То есть в сети должен существовать некий идентификатор клиента.
Route target (RT) - не часть NLRI, это атрибут, который передается внутри объекта вместе с NLRI. RT - extended community типа 2. По сути будет определять какому VRF относится префикс.
С помощью RT можно для клиента обеспечить связность не только full mesh, но и более сложные топологии: 1 ко всем, 2 между собой, 3-й только с конкретным сайтом.
NLRI с RT прилетает на удаленный PE, префикс запихивается в нужный VRF, убирается RD, сохраняем префикс в виде IPv4. По настроенному протоколу PE<>CE передает префикс CE.
BGP: по дефолту передает только маршруты, полученные по BGP. Но с VRF другое поведение: если конфигурируем VRF и в VRF пишет target, а не policy, то роутер берет все маршруты из этого VRF, присоединяет к ним target, и отправляет по MP-BGP.
Когда проанонсированный префикс прилетает соседу (используя vpn family), тот: смотрит на target, ищет у себя target. Если VRF с таким target нет, то BGP-update отбрасывается (даже не попадают в hidden), он не знает в какую таблицу его запихнуть. Как проверить, что все-таки update прилетает: включить traceoptions. Т.е. на P роутере prefix клиента отбросится. Но до PE2 по iBGP все-равно анонс долетит, но будет скрытым (не отрезолвился next-hop, он не попал в inet.3). Если prefix все-таки не прилетает даже в hidden, то скорей всего проблема с RT.
Forwarding
Допустим, к CE1 подключено устройство с default route, пакет идет на CE1. CE1 по BGP передает трафик к PE1. На PE1 пакет попадает в vrf1.table.inet.0, т.к. на PE1 интерфейс в сторону CE1 добавлен в VRF клиента. Forwarding next-hop: P-router (по IGP). P-router принимает пакет и не знает что с ним дальше делать. Схема не рабочая
Будем туннелировать пакеты от PE1 (не обязательно в mpls). Но рассматриваем mpls.
- LSP на PE1 в inet.3: PE2: push 20 -> P. BGP резолвит next-hop для PE2, подставляет в inet.0.
- P смотрит в mpls.0: 20 pop.
- На PE2 прилетает голый ip пакет. PE2 делает lookup в inet.0, т.к. интерфейс, с которого пришел пакет - принадлежит master RI и сам пакет - просто ip. В inet.0 не будет нужного маршрута => тоже схема не рабочая.
Делаем так, чтобы PE2 понял, что lookup нужно производить внутри VRF. RT и RD не проканают, т.к. они существуют только на уровне control plane, и не причастны к передаче трафика.
Какой-нибудь header можем использовать как идентификатор, что нужно смотреть в определенной таблице. Берем MPLS заголовок.
- Исходный VRF каждому пакету выделяет уникальную для себя метку. Пакет будет иметь следующий вид: label:RD:prefix/mask.
- Добавлять метку будет egress, удаленный PE2 роутер. Поэтому выделенную метку нужно проанонсировать с PE1 на PE2 по MP-BGP. Family vpn: label:prefix/mask.
- Т.к. на PE2 префикс прилетает с меткой (смотрим в таблицу bgp.l3vpn vpn label), то для PE2 это означает, что с другой стороны пакеты ждут с этой меткой. Т.е. PE2 добавляет выделенную метку, затем resolve next-hop. В нашем случае произойдет следующее: push 20 (для LSP) push 50 (для VRF) -> P.
- На P делается 20 pop.
- На PE1 приходит пакет: 50:RD:prefix/mask. Пакет попадает в mpls.0, где должна быть запись: 50: pop -> vrf1. Такая запись будет создана, как только будет создан сам VRF (ему назначается определенная метка и запись инсталлируется в mpls.0).
- На PE1 далее метка снимается, RD снимается, пакет идет на второй lookup внутри таблицы vrf1. И далее пакет направляется к нужному next-hop, согласно таблицы vrf1.
На PE2 делается 2 lookup.
Такая схема будет работать только если включить vrf-table-label.
В каких случаях нам может потребоваться делать второй lookup внутри VRF: если хотим осуществлять какие-то дополнительные функции для клиентов на основании ip внутри VRF - посчитать трафик, пофильтровать, пополисить... по ip заголовку. vrf-table-label заставляет роутер назначать метку на VRF и делать второй lookup. В основном этой схемой и пользуются.
Но на самом деле Juniper по дефолту работает так: метка назначается не на VRF, а на next-hop, с которого исходно пришли клиентские маршруты. Каждому next-hop своя метка. Т.о. на PE2 в mpls.0: 51 pop -> CE1 next-hop, 52 pop -> CE2 next-hop. Это позволяет не делать второй lookup.
Cisco по дефолту назначает метки для prefix. Но это не очень удобно, когда от клиента приходит много префиксов и тем самым занимается ASIC для хранения всех этих меток.
CE<>PE eBGP
В настройке особенностей нет, но возникают проблемы с AS.
У клиента одна и та же AS с двух сторон (AS 65000) => PE1 (AS 10) получает префикс с AS-path 65000 * => на PE2 сработает split horizing, и он не будет анонсировать CE2 => решаем проблему.
- На PE1 в VRF под протоколом BGP: advertise peer-as - отключает split horizont. AS path поменяется: 10 65000 *. СЕ2 принимает маршрут, но по идее должен его отбросить, т.к. в AS-path видит свою AS. => на CE2 отключаем проверку на loop: routing-options autonomous-system loops 2.
- На РЕ1 в VRF под протоколом BGP: as-override - отключает split horizing + ищет в AS-path соседскую AS и заменяет ее на свою. Новый AS-path: 10 10. На CE2 проблемы не возникнет.
- Если у клиентов private AS => remove private. Можно включить в разных местах.
- На PE1 внутри VRF настраиваем AS CE1: routing-options autonomous-system <AS-CE1> + routing-instance <instance> routing-options autonomous-system independent-domain - исходные атрибуты BGP от CE1 сохраняются в новый атрибут: outer-set, который добавится при анонсе в iBGP провайдера. На PE2 тоже настраиваем independent-domain, который раскроет outer-set. Т.о. при передаче префикса CE2 AS-path не будет заполнен (при iBGP AS-path пустой). Внутри VRF настраиваем internal BGP. Также этот способ дает возможность сохранить local-preference от CE1.
CE<>PE OSPF
Общие сведения об OSPF
- Внутри area - LSA1 (router), LSA2(network) - описание топологии.
- Между area - LSA3 (summary) - внутренние сети.
- LSA 5 (external) - внешние маршруты.
Внутренний порядок выбора маршрутов, до попадания в routing-table:
- intra-area (LSA1, LSA2)
- inter-area (LSA3)
- external (LSA5)
Split horizont: area 0 - центральная. Все остальные area могут подключаться только через area 0. Все, что пришло из некой внешней area - не передается в area 0, т.к. оно впринцепе может прийти только из area 0.
Sham-link
Если все это применить к L3VPN.
Внутри VRF настраиваем OSPF, включаем в него интерфейс в сторону клиента. В core - iBGP, LSP.
- A: отправляет свой Lo 10.0.0.1 в area как LSA1.
- PE1: в RI попадает 10.0.0.1 как LSA3.
- PE1: inet.0: 10.0.0.1/32 - [OSPF] -> B.
- Все маршруты из RI передаются по iBGP.
- PE2 получит анонос сети 10.0.0.1/32 ререз BGP. vrf.inet.0: 10.0.0.1/32 - [BGP] -> LSP.
- Требуется сеть из BGP переместить в OSPF. Пишем policy.
- PE2 из RI сеть будет передаваться к клиенту как LSA3.
- !!Проблема 1: при поднятии OSPF клиенту требуется одна area.
- !!Проблема 2: по факту клиенту требуется объединить 2 своих роутера в одну сеть => маршруты от СЕ1 должны приходить как LSA1.
Делаем так, чтобы из PE2 VRF к клиенту вылетела LSA1. LSA1 содержит в себе линки, а мы при передаче от клиента к RI превратили эту информацию в маршруты, которые дальше стали анонсироваться по BGP. Из маршрутов линки обратно сделать не получится. Как исправить?
- Придумать новый NLRI, повторяющий структуру LSA1. Но ведь итак для L3VPN уже есть свой NLRI, засовывать в него еще NLRI - уже страшно. Поэтому...
- PE1 и PE2 требуется соединить с помощью sham-link. Роутеры при этом будут как бы в одной area и будут флудить между собой LSA1.
Задаем sham-link:
- Создаем отдельный unit на Lo, заносим его в RI. PE1: 1.1.1.1, PE2: 1.1.1.2
- Указываем local-end, remote-end.
- Чтобы роутеры установили соседство - нужно отправить hello в LSP (между PE) => Lo уделанного PE мы должны получить по iBGP.
PE1: inet.0: 1.1.1.2 - [BGP] -> LSP.
Обязательно нужно в policy (vrf-import, vrf-export) добавить адреса Lo!!, иначе ничего не заработает.
Все заработало, к CE2 улетел LSA1.
НО! произошло небольшое изменение: маршрут 10.0.0.1/32 прилетел на PE2 в RI, как известный по OSPF и был выбран активным.
PE2: vrf.inet.0: *10.0.0.1/32 - [OSPF/10] -> shamlink.0 10.0.0.1/32 - [BGP/170] -> LSP
При отправке пакета с dest = 10.0.0.1/32 будет также выбран маршрут, изученный по OSPF. Но shamlink - некая абстракция и в передаче трафика не участвует.
На самом деле умный роутер делает все маршруты, доступные через shamlink - скрытыми, чтобы их нельзя было использовать. А изученные по BGP - станут активными.
НО! на удаленный PE2 обязательно должен прийти маршрут CE1, полученные по BGP (для форвардинга) и OSFP (для распространения LSA1).
- Если используем vrf-target - то все само прийдет.
- Если используем policy, то нужно не забыть, что OSPF маршрут нужно отправить по BGP на удаленный PE.
Sham-link годится только в случае, когда объединяются роутеры клиента в одной area и когда критично принимать именно LSA1, как было бы без вмешательства ISP.
Configuration
blair> show configuration routing-instances beer { instance-type vrf; interface ge-0/0/0.510; interface lo0.1; route-distinguisher 10.200.86.1:500; vrf-target target:1111:500; protocols { ospf { export beer-l3vpn; sham-link local 1.1.1.1; area 0.0.0.0 { sham-link-remote 2.2.2.2; interface ge-0/0/0.510 { interface-type p2p; } interface lo0.1; blair> show configuration interfaces lo0.1 family inet { address 1.1.1.1/32;
Со стороны удаленного РЕ конфиг аналочигный.
Проверка
До включения sham-link
blair> show ospf database instance beer OSPF database, Area 0.0.0.0 Type ID Adv Rtr Seq Age Opt Cksum Len Router 1.1.1.1 1.1.1.1 0x80000017 59 0x22 0x310f 60 Router *172.17.0.2 172.17.0.2 0x80000017 55 0x22 0xcffa 60 Summary 172.17.0.1 1.1.1.1 0x80000004 39 0xa2 0x4ca9 28 OSPF AS SCOPE link state database Type ID Adv Rtr Seq Age Opt Cksum Len Extern 2.2.2.2 1.1.1.1 0x80000002 66 0xa2 0xa157 36 Extern 192.168.86.52 1.1.1.1 0x80000004 39 0xa2 0x7697 36
blair> show route table beer.inet.0 beer.inet.0: 8 destinations, 8 routes (8 active, 0 holddown, 0 hidden) + = Active Route, - = Last Active, * = Both 1.1.1.1/32 *[Direct/0] 00:15:29 > via lo0.1 2.2.2.2/32 *[BGP/170] 00:03:09, localpref 100, from 10.200.86.7 AS path: I > to 192.168.86.10 via ge-0/0/0.60, label-switched-path blair-to-lagavulin 172.17.0.1/32 *[BGP/170] 00:00:11, MED 1, localpref 100, from 10.200.86.7 AS path: I > to 192.168.86.10 via ge-0/0/0.60, label-switched-path blair-to-lagavulin 172.17.0.2/32 *[OSPF/10] 00:00:21, metric 1 > to 192.168.86.58 via ge-0/0/0.510 192.168.86.52/30 *[BGP/170] 00:00:11, localpref 100, from 10.200.86.7 AS path: I > to 192.168.86.10 via ge-0/0/0.60, label-switched-path blair-to-lagavulin 192.168.86.56/30 *[Direct/0] 01:30:08 > via ge-0/0/0.510 192.168.86.57/32 *[Local/0] 01:30:08 Local via ge-0/0/0.510 224.0.0.5/32 *[OSPF/10] 01:30:11, metric 1 MultiRecv
После включения sham-link
blair> show ospf neighbor instance beer Address Interface State ID Pri Dead 192.168.86.58 ge-0/0/0.510 Full 172.17.0.2 128 33 2.2.2.2 shamlink.0 Full 2.2.2.2 0 3
blair> show ospf database instance beer OSPF database, Area 0.0.0.0 Type ID Adv Rtr Seq Age Opt Cksum Len Router *1.1.1.1 1.1.1.1 0x8000001c 6 0x22 0x3b7b 60 Router 2.2.2.2 2.2.2.2 0x80000017 7 0x22 0xdbe4 60 Router 172.17.0.1 172.17.0.1 0x8000001f 8 0x22 0x3f8a 60 Router 172.17.0.2 172.17.0.2 0x80000019 7 0x22 0xcbfc 60 OSPF AS SCOPE link state database Type ID Adv Rtr Seq Age Opt Cksum Len Extern 1.1.1.1 2.2.2.2 0x80000006 7 0xa2 0xa94b 36 Extern *2.2.2.2 1.1.1.1 0x80000005 6 0xa2 0x9b5a 36
blair> show route table beer.inet.0 beer.inet.0: 8 destinations, 10 routes (8 active, 0 holddown, 2 hidden) 1.1.1.1/32 *[Direct/0] 00:20:59 > via lo0.1 2.2.2.2/32 *[BGP/170] 00:08:39, localpref 100, from 10.200.86.7 AS path: I > to 192.168.86.10 via ge-0/0/0.60, label-switched-path blair-to-lagavulin 172.17.0.1/32 *[BGP/170] 00:03:14, MED 1, localpref 100, from 10.200.86.7 AS path: I > to 192.168.86.10 via ge-0/0/0.60, label-switched-path blair-to-lagavulin 172.17.0.2/32 *[OSPF/10] 00:03:28, metric 1 > to 192.168.86.58 via ge-0/0/0.510 192.168.86.52/30 *[BGP/170] 00:03:14, localpref 100, from 10.200.86.7 AS path: I > to 192.168.86.10 via ge-0/0/0.60, label-switched-path blair-to-lagavulin 192.168.86.56/30 *[Direct/0] 01:35:38 > via ge-0/0/0.510 192.168.86.57/32 *[Local/0] 01:35:38 Local via ge-0/0/0.510 224.0.0.5/32 *[OSPF/10] 01:35:41, metric 1 MultiRecv
blair> show route table beer.inet.0 hidden beer.inet.0: 8 destinations, 10 routes (8 active, 0 holddown, 2 hidden) 172.17.0.1/32 [OSPF] 00:00:44, metric 2 > via shamlink.0 192.168.86.52/30 [OSPF] 00:00:44, metric 2 > via shamlink.0
- Если у клиента с двух сторон разные area:
т.к. соседство по OSPF должно быть внутри одной area, то shamlink не поднимется.
По факту LSA3 и LSA5 - одинаковые по структуре - маршрут, но имеют разный приоритет при выборе активного пути.
То есть в случае, когда у клиента разные area - предпринимать ничего не нужно, итак все заработает.
Domain ID
OSPF Domain ID используется, когда передаются маршруты между одинаковыми или разными доменами через MPLS сеть. Domain ID передается как extended community внутри MP-BGP вместе с OSPF route-type и OSPF router ID community.
Фича позволяет передавать на удаленный конец LSA1, LSA2, LSA3 как LSA3.
Также передаются LSA5, LSA7 как LSA5.
Stub и totally-stubby не поддерживают такую фичу.
- Если у клиента:
- Одинаковые Domain ID.
- Есть другой протокол, из которого сеть пришла в OSPF как external.
- Внутри сети клиента по OSPF этот маршрут будет распространятся как LSA5.
- Между PE маршрут передается по iBGP, к удаленному PE приходит как LSA3.
Как исправить:
Вводится правило трансляции типов LSA:
- Если исходно маршрут пришел как LSA1, LSA2, LSA3 - его превращаем в LSA3.
- Если маршрут пришел как LSA5 - превращаем его в LSA5.
Как удаленный PE узнает что было с другой стороны?
BGP использует следующие extended community:
- OSPF route type - тип изначального LSA.
- OSPF Domain ID - обычно закодирован как 4 byte IP address
- OSPF router-id - требуется только при использовании sham-link
Генерируется автоматически. Когда iBGP передает OSPF маршрут, роутер смотрит как исходно пришел маршрут, создает для него соответствующее community, куда записывает тип LSA.
Удаленный PE смотрит тип, применяет правило трансляции.
РЕ генерирует LSA3, когда route type - internal и передает Domain ID community в соответствии в тем, какой сконфигурирован в RI.
Если Domain ID не задан с обоих концов в VRF, то это тоже является совпадением по Domain ID.
PE при передаче CE LSA также помечает из route tag. Пример: tag 3489662039. Рассчитывается автоматически, но можно и задать вручную.
CE1> show route protocol ospf inet.0: 14 destinations, 14 routes (14 active, 0 holddown, 0 hidden) 1.1.1.1/32 *[OSPF/150] 18:38:53, metric 0, tag 3489662039 > to 192.168.86.53 via ge-0/0/0.500 2.2.2.2/32 *[OSPF/150] 18:36:15, metric 0, tag 3489662039 > to 192.168.86.53 via ge-0/0/0.500
Configuration
[edit policy-options policy-statement export-vpn-beer term 1 then] community add vpn-beer { ... } + community add domain-beer; [edit policy-options policy-statement import-vpn-beer] + from community domain-beer; [edit policy-options] + community domain-beer members domain-id:1.1.1.1:0; [edit routing-instances beer] + routing-options { + router-id 10.200.86.7; + } [edit routing-instances beer protocols ospf] + domain-id 1.1.1.1;
- Если у клиента разные домены:
Правило трансляции действует, когда домен одинаковый. При передаче пакета генерируется еще одно специальное community, которое говорит, на удаленном PE: все пришедшие маршруты - LSA5.
Domain-ID одинаковые:
blair> show ospf database instance beer OSPF database, Area 0.0.0.0 Type ID Adv Rtr Seq Age Opt Cksum Len Router 172.17.0.2 172.17.0.2 0x80000035 103 0x22 0x4176 60 Router *192.168.86.57 192.168.86.57 0x80000004 102 0x22 0x2a53 48 Summary *172.17.0.1 192.168.86.57 0x80000003 102 0xa2 0xac55 28
При изменении Domain-ID с одной стороны - несовпадение doamin-id => маршруты прилетают как external (LSA5)
blair> show ospf database instance beer OSPF database, Area 0.0.0.0 Type ID Adv Rtr Seq Age Opt Cksum Len Router 172.17.0.2 172.17.0.2 0x80000038 23 0x22 0x3b79 60 Router *192.168.86.57 192.168.86.57 0x80000007 22 0x22 0x2456 48 OSPF AS SCOPE link state database Type ID Adv Rtr Seq Age Opt Cksum Len Extern *172.17.0.1 192.168.86.57 0x80000001 10 0xa2 0x4984 36
- Если у клиента по краям нашего L3VPN - area1, которая в свою очередь подключается к area0 на сети клиента:
LSA3 дойдет до CE2 (area1), но ABR не отправит LSA3 в area0, т.к. это backbone area (splithorizing). Поднимаем virtual-link.
При использовании IS-IS все проще: редистрибьюция из BGP в ISIS. В любом случае в ISIS получим внешний маршрут.
Exchanging routes between VRF tables
Если нам требуется передать маршруты из одного VRF в другой, в рамках одного маршрутизатора, можно осуществить такое двумя способами:
- включение auto-export: задаем в [routing-options] в нужных VRF. При этом если внутри разных VRF указаны одинаковые vrf-target или vrf-import/export, то маршруты будут скопированы между VRF.
blair# run show route table oak.inet.0
oak.inet.0: 3 destinations, 3 routes (3 active, 0 holddown, 0 hidden) 13.13.13.13/32 *[Static/5] 00:00:09 Discard 192.168.86.64/30 *[Direct/0] 00:00:07 > via ge-0/0/0.600 192.168.86.65/32 *[Local/0] 00:00:07 Local via ge-0/0/0.600
После включения:
blair# run show route table oak.inet.0 oak.inet.0: 6 destinations, 6 routes (6 active, 0 holddown, 0 hidden) 13.13.13.13/32 *[Static/5] 00:01:57 Discard 15.15.15.15/32 *[Static/5] 00:00:08 Discard 192.168.86.64/30 *[Direct/0] 00:01:55 > via ge-0/0/0.600 192.168.86.65/32 *[Local/0] 00:01:55 Local via ge-0/0/0.600 192.168.86.68/30 *[Direct/0] 00:00:08 > via ge-0/0/0.610 192.168.86.69/32 *[Local/0] 00:00:08 Local via ge-0/0/0.610
- использование rib-groups
blair# top show | compare [edit routing-options] + rib-groups { + oak-to-spruce { + import-rib [ oak.inet.0 spruce.inet.0 ]; + } + spruce-to-oak { + import-rib [ spruce.inet.0 oak.inet.0 ]; + } + } [edit routing-instances oak routing-options] + interface-routes { + rib-group inet oak-to-spruce; + } [edit routing-instances spruce routing-options] + interface-routes { + rib-group inet spruce-to-oak; + }
С помощью policy можно контролировать какими-маршрутами обмениваться.