QinQ — Часть_2, про Juniper

Posted: 2016-04-15 in IT, Networks
Метки:

Всем привет. Сегодня я расскажу об особенностях настройки Q-in-Q на джунипере, а конкретно — на Juniper EX-4200. Ну и про замеченные багофичи тоже не забуду упомянуть.

Почти 4 года назад я уже писал про настройку QinQ на циске, длинках и линуксах, и эта статья до сих пор активно читается.

Косяки и грабли в начале игрищ
Джунипер, при всех своих плюсах, тоже не без косяков.
Первое — очень рекомендуется таки обновлять прошивки, как минимум — не сидеть на совсем уж старье. Ситуацию с падающим процессом rpd, когда оный коредампится, роняя весь роутинг к херам на пару минут — наблюдал воочию. Но не будем о грустном. Обновление прошивки проблему решило, двигаем дальше.

Из забавного — при сборке стенда обнаружил, что медные SFP-модули прекрасно работали на гигабите, но упорно не хотели делать тоже самое на 100М. Симптомы — линк апнут, но траффик не ходит соовсем, mac-адресов нет, в дампе траффика тишина.

Я попробовал задать скорость и режимы порта ручками:

{master:0}[edit interfaces ge-0/0/21]
Amin@TestJ4200# show 
description "test notebook";
mtu 1600;
ether-options {
    link-mode full-duplex;
    speed {
        100m;
    }
    mdi-mode mdix;
}

Но никакие игрища с ether-options на интерфейсе не помогли — ни mdi, ни speed, ни link-mode. Вот на гигабите линк поднимается без проблем — а на 100/10 — фуй. Что занятно — тот же самый модуль также не работает на 100M в длинке DES-3200/10, зато прекрасно работает в 3750-й циске. Грабли могут обнаружиться в самом неожиданном месте.
Не исключаю, что может помочь правильная прошивка модуля. Только не надо думать, что 10/100М линк вам не понадобится — системы климат-контроля, стоечные ребутилки, ИБП и прочее управляемое железо с mgmt-портами работать ни гигабите совершенно не обязано, а ставить в стойки левое дополнительное железо — не наш путь =)
Но поскольку отказываться от мониторинга никак нельзя, я добавил в стенд ещё пару железок — длинк-3200-10 и катаклизм-3750.

QinQ — Tunnel
В прошлой статье я упоминал про важность параметра ether-type в QinQ. Тут это тоже есть. Увы, но на EX4200 оный ether-type задается для всей коробки целиком:

{master:0}[edit]
Amin@TestJ4200#
set ethernet-switching-options dot1q-tunneling ether-type ?
Possible completions:
  0x8100               Dot1q ether-type value 0x8100
  0x88a8               Dot1q ether-type value 0x88a8
  0x9100               Dot1q ether-type value 0x9100

И по-умолчанию (при пустом конфиге) он стоит 0x8100, то есть как и для одиночных влан-вульгарис.
Логика работы тут такая. Если на циске/длинке режим QnQ — это опция ПОРТА, то на джуне 4200 это опция ВЛАНа.
Сперва мы должны сказать, что влан должен быть QinQ-типа (dot1q-tunneling):

{master:0}[edit]
Amin@TestJ4200# show vlans 
Amin3778 {
    vlan-id 3778;
    l3-interface vlan.3778;
    dot1q-tunneling;
}

В нашем случае внешний тег — 3778.
После этого dot1q-tunnel порт делается так:

Amin@TestJ4200# show interfaces ge-0/0/23   
description 3778-vlan_QinQ-port;
mtu 1600;
unit 0 {
    family ethernet-switching {
        port-mode access;
        vlan {
            members Amin3778;
        }
    }
}

Да, порт конфигурится как аццесс, но наличие опции dot1q-tunneling в настройке влана Amin3778 говорит железке, что режим порта, где будет такой «типа access» — QinQ.
А вот если port-mode поставить в trunk — то теги сниматься уже не будут. Ещё из важного — джуну пофиг, сколько тегов 802.1q наверчено. Я интереса ради сделал соседний порт транком:

Amin@TestJ4200# show interfaces ge-0/0/22  
description test-big-8021q-mixed-trunk;
mtu 1600;
unit 0 {
    family ethernet-switching {
        port-mode trunk;
        vlan {
            members [ Amin3777 Amin3778 ];
        }
    }
}

Воткнув в 0/0/23 линуксовую тачку с уже собранным QinQ (когда траффик идет с компа уже с двумя тегами), на выходе из 0/0/22 я увидел траффик сразу с тремя vlan-метками:

QnQnQ__Linux-QinQ-in_dot1q_tunnel

Это даже работает =).

Для таких транков, где есть как обычные, так и QinQ-вланы, джуниперу требуется обязательное совпадение ether-type. Например, если поставить 0x88a8 в ether-switching-options — то вытащить QinQ-влан в смеси с обычными в транке уже не получится. При попытке коммита произойдет вот такой облом:

error: Trunk interface can not be memeber of both dot1q-tunneling enabled vlan , and a non dot1q-tunneled vlan when do
error: configuration check-out failed

То есть либо мы ставим ether-type 0x8100 на всю железку, и обрабатываем QinQ-вланы наравне с обычными, либо теряем возможность направить QinQ-траффик в прозвольный транк. Внутренний перфекционист упорно шепчет, что QinQ — это ether-type 0x88a8, но прагматик явно намекает, что с единым ether-type 0x8100 жизнь станет заметно проще.

Selective QinQ
Это такая опция настройки customer-vlans в dot1q-tunneling, позволяющая от клиента принимать только траффик с определенными тегами:

{master:0}[edit vlans]
Amin@TestJ4200# show
Amin3778 {
    vlan-id 3778;
    l3-interface vlan.3778;
    dot1q-tunneling {
        customer-vlans [ native 3779 ];
    }
}

Но! В этом случае фильтруются только клиентские теги для входящего в qinq-порт (ge-0/0/23) траффика. То есть в такой конфигурации порт ge-0/0/23, будет принимать только нетегированный или тегированный 3779-траффик. Траффик с любым другим тегом, кроме 3779, будет отброшен. Можно сделать весело (и бессмысленно/беспощадно 😀 ) — оставить в customer-vlans только native — тогда порт станет работать как обычный access, принимая только нетегированный траффик и добавляя ему одну-единственную метку 3778.

Если же native в customer-vlans не указывать — то нетегированный траффик, по идее, должен отбрасываться. Однако тут я словил облом — нетегированный траффик через QinQ-туннель ходит в любом случае, как через обычный влан — то есть на входе в qnq-порт метка добавляется, на выходе — снимается. Возможно, я не очень понял, что делает опция native для dot1q-tunneling -> customer-vlans (в дампах траффика отличий не увидел), а может, это просто очередной редкий баг, на который никто не натыкался из-за специфичности сценария использования.

Можно задавать прозвольно широкие диапазоны клиентских вланов, которые разрешены для прохождения через qnq-туннель:

customer-vlans [ 3779 150-2550 ];

Набор указывается в квадратных скобках, разделитель диапазонов — пробел, можно указывать сразу непрерывную группу. В этой строчке мы разрешаем для QinQ-влана прохождение только такого входящего в qinq-порт тегированного траффика, внешняя (клиентская!) метка которого на входе либо лежит в диапазоне от 150 до 2550, либо равна 3779. Во внутренние более глубокие метки джуник не лезет.

А вот для исходящего траффика фильтрация с помощью customer-vlans не работает!

Если в наш обычный транк на 22-м порту направить со второго линукс-хоста QinQ-траффик с внешним тегом 3778 и какими-либо внутренними тегами, не прописанными в customer-vlans, то джунипер при форвардинге просто снимет сервисный тег 3778 и отправит пакет в 23-й qnq-порт прямо с теми тегами, что были внутри, невзирая на значения customer-vlans. Фича не очевидная, без дампов траффика догадаться нереально.

LACP, LLDP и прочие полезные L2-извраты поверх QinQ-туннеля
Для настройки прохождения такого траффика через qnq-туннель на джунипере есть такая конфигурялка:

{master:0}[edit vlans Amin3778 dot1q-tunneling]
Amin@TestJ4200# set layer2-protocol-tunneling ?
Possible completions:
  802.1x               Tunnel 802.1X PDUs
  802.3ah              Tunnel 802.3AH (Ethernet Link OAM) PDUs
  all                  Tunnel all layer-2 protocol PDUs
  cdp                  Tunnel CDP PDUs
  e-lmi                Tunnel E-LMI PDUs
  gvrp                 Tunnel GVRP PDUs
  lacp                 Tunnel LACP PDUs
  lldp                 Tunnel LLDP PDUs
  mmrp                 Tunnel MMRP PDUs
  mvrp                 Tunnel MVRP PDUs
  stp                  Tunnel STP PDUs
  udld                 Tunnel UDLD PDUs
  vstp                 Tunnel VSTP PDUs
  vtp                  Tunnel VTP PDUs

Признаюсь, пять протоколов из этого списка мне незнакомы ну вот совсем, а остальные как-то через qnq пробрасывать не приходилось. Но раз я это увидел в процессе написания этой небольшой статьи, попробуем проверить работу и этой секции. В качестве генератора такого типа траффика у меня стоит циска 3750.
Сперва попробуем включить их все и настроим их на циске. Первое — не забывайте, что в циско-сетях протокол VTP может быть зело опасен.
Джунипер пропускает такой траффик через QinQ-порт, навешивая на него провайдерскую влан-метку:

l2protocols-in-qnq-tunnel

То есть даже при отсутствии опции layer2-protocol-tunneling траффик L2-протоколов всё равно проходить будет.

В конфиге же можно настроить защитные интервалы:

{master:0}[edit vlans Amin3778]
Amin@TestJ4200# show 
vlan-id 3778;
l3-interface vlan.3778;
dot1q-tunneling {
    layer2-protocol-tunneling {
        all {
            drop-threshold 5;
            shutdown-threshold 30;
        }
        stp {
            drop-threshold 1;
            shutdown-threshold 10;
        }
    }
}

Больше ничего интересного тут нет.

L3-интерфейс в QinQ-влане
Опция l3-interface vlan.3778; во всех примерах выше. Конфиг интерфейса обычен:

{master:0}[edit]
Amin@TestJ4200# show interfaces vlan unit 3778 
description l3-vlan-if-3778;
family inet {
    address 192.168.178.118/24;
}

Работает также, как и IP-интерфейсы в обычных вланах. Создать L3-интерфейс для вложенных клиентских вланов, приходящих в qnq-порт, не удалось, во всяком случае без использования дополнительных петель, перетагирования и прочих нестандартных методов.

VLAN-Remap/Translation
Это фича для более гибкого и сложного управленяи влан-тегами. К сожалению, на EX-4200 ремаппинг поддерживается только на qinq-портах (напоминаю, что это которые port-mode = access + dot1q-tunneling влан) и с рядом ограничений.
Ограничение значительное — применять такой трикс можно только на qinq-портах. Настраивается в конфиге влана, указывая в нем правила обработки для интерфейсов:

{master:0}[edit vlans Amin3778]
Amin@TestJ4200# show                                 
vlan-id 3778;
interface {
    ge-0/0/22.0 {
        mapping {
            17 {
                push;  
            }
        }
    }

Но поскольку порт ge-0/0/22 unit 0 — обычный транк, то коммит обломится:

Amin@TestJ4200# commit
[edit vlans Amin3778 interface ge-0/0/22.0 mapping 17]
'push'
Mapping operation "push" cannot be defined for trunk interface
error: configuration check-out failed

Однако применяя ручные правила маппинга, надо убрать влан 3778 ин конфига интерфейса, иначе получим такую ошибку:

error: Interface can not have membership to vlan from both "mapping" and "interfaces" statement
error: configuration check-out failed

Просто приводим конфиг к такому виду:

{master:0}[edit interfaces ge-0/0/23]
Amin@TestJ4200# show 
description 3778-vlan_QinQ-port;
mtu 1600;
unit 0 {
    family ethernet-switching {
        port-mode access;
    }
}

А правила обработки тегов пишем в [ edit vlans Amin3778 interface ge-0/0/23.0 ].
Это не очень хорошо, что принадлежность вланов портам оказывается в двух разных секциях конфига, но иногда и такое случается.

Тут тоже появляется возможность фильтрации клиентских вланов.

Например при таком конфиге:

{master:0}[edit vlans Amin3778]
Amin@TestJ4200# show 
vlan-id 3778;
interface {
    ge-0/0/23.0 {
        mapping {
            17 {
                push;
            }
            29 {
                push;
            }
        }
    }
}
l3-interface vlan.3778;
dot1q-tunneling

qinq-порт будет пропускать только клиентские вланы 17,29 и L2-протоколы, тогда как любые другие теги и нетегированный траффик будет дропаться. Это отличается от опции customer-vlans, будьте внимательны, хотя поведение и очень похоже.
Для пропуска нетегированного траффика прописываем опцию

{master:0}[edit vlans Amin3778]
Amin@TestJ4200# set interface ge-0/0/23.0 mapping native push

Инструкция push говорит устройству, что надо принять траффик с ge-0/0/23.0, если тег 17, 29 или какой там указан одним уровнем выше, обработать его как обычно для qnq добавлением сервисного влан-тага и отправить дальше по транкам как обычно. И если есть хоть одна инструкция push — то все остальные вланы, не перечисленные в маппинге, при такой настройке пропускаться не будут. Не исключаю, что в разных версиях такие тонкости могут работать немного по=разному, так что дампы траффика в помощь.

Есть у маппинга и второй интересный режим — swap. Инструкция swap может быть только одна на интерфейс, и не может применять совместно с интсрукцией push. В этом режиме самый верхний клиентский тег _замещается_ сервисным тегом джунипера, никакие другие вланы при этом не проходят. Я сгенерировал с помощью линукс-хоста дважды тегированный траффик, в котором влан 117 был обернут верхним тегом 17 (ну и ещё пачка других вланов тоже имела место, чтобы видеть в дампе, как работает фильтрация), и соединил эту машину с ge-0/0/23 портом. Без swap это дало бы траффик сразу с тремя vlan-метками.
Однако вот такая конструкцию:

{master:0}[edit vlans Amin3778 interface ge-0/0/23.0 mapping]
Amin@TestJ4200# show  
17 {
    swap;
}

будет пропускать только траффик, у которого внешний тег на выходе с линукс-хоста был равен 17, при этом метка 3778 (секция [edit vlans Amin3778] -> vlan-id 3778; у нас никуда не делась) будет ставиться ВМЕСТО верхнего тега 17, а не ставиться поверх него. В итоге у нас в обычном транке появится траффик, в котором 117-й сильно внутри-клиентский влан будет обернут сразу сервисным тегом 3778, тогда как тег внешний тег 17, пришеший от клиента, будет потерян.

Понятно, почему их нельзя несколько — swap сразу с двух разных вланов приведёт к риску смешению траффика внутри-клиентских вланов, если скажем от клиента прилетят двойные теги вида s17-c8 и s29-c1. При обычном режиме (push) траффик станет трижды тегированным (QinQinQ), тогда как при швапе траффик 1-го влана из s-17-го и 1-го влана из s-29-го смешаются, что могло бы привести бы к очень странным и трудно диагностируемым глюкам =)

Также можно сделать так:

{master:0}[edit vlans Amin3778 interface ge-0/0/23.0 mapping]
Amin@TestJ4200# show  
17 {
    swap;
}
native {
    push;
}

В этом случае от qinq-порта будут приниматься L2-протоколы, нетегированный траффик (превратиться в одиночно тегированный с тегом из edit vlans Amin3778 vlan-id 3778; ) и траффик с внешним тегом 17, для которого метка 17 заменится на метку 3778.
Важно помнить, что настройки маппинга специфичны для qinq-интерфейса. В данном примере влан Amin3778 настроен на специфичную обработку тегов только на интерфейсе 0/0/23. Если этот влан прописать на обычные транки (ge-0/0/22) во vlan -> memebers , никаких проблем не будет — qinq-траффик, как и одиночно тегированный, будет проходить через транк, как обычно, без всякой фильтрации по номерам внутренних клиентских вланов / ремаппинга.

А вот смешивать swap и push нельзя, как и нельзя указывать заведдомо бессмысленный native swap (сложно заменить то, чего не существует).

Вот такой вот тёплый ламповый свитчинг. На этом я завершаю повествование. Если будет время и желание — выложу ещё что-нибуь подобное.

Ну и чтиво но ночь:

https://packetcorner.wordpress.com/2012/12/01/qinq/
QinQ 3750
http://forums.juniper.net/t5/Ethernet-Switching/QinQ-VLAN-transport-Issue-over-Etherchannel/td-p/222647
http://nag.ru/user/notes/27230/kontseptsiya-uzla-svyazi.html
https://www.ideal-spb.ru/blog/qinq-na-juniper-ex/
http://www.juniper.net/documentation/en_US/junos13.2/topics/reference/configuration-statement/mapping-bridging-ex-series.html

P.S. У JunOS есть три варианта (редакции) — domestics, export и fips. Иногда поисковики адски жгут, и поиск нужной версии прошивки может завести немного не туда: https://yandex.ru/search/?text=domestics%20ex3300&lr=240

Реклама
- комментарии