tc u32 - как сопоставить протоколы L2 в последних ядрах?

12

У меня есть хороший формирователь с хэшированной фильтрацией, построенный на Linux-мосте. Короче говоря, br0соединения externalи internalфизические интерфейсы, маркированные пакеты VLAN соединяются «прозрачно» (я имею в виду, интерфейсы VLAN отсутствуют).

Теперь разные ядра делают это по-разному. Я могу ошибаться с точными диапазонами версий ядра, пожалуйста, прости меня. Благодарю.

2.6.26

Итак, в Debian, 2.6.26 и выше (я думаю, до 2.6.32) --- это работает:

tc filter add dev internal protocol 802.1q parent 1:0 prio 100 \
    u32 ht 1:64 match ip dst 192.168.1.100 flowid 1:200

Здесь «kernel» сопоставляет два байта в поле «protocol» с 0x8100, но считает начало пакета ip «нулевой позицией» (извините за мой английский, если я немного неясен).

2.6.32

Опять же, в Debian (я не собирал ванильное ядро), 2.6.32-5 --- это работает:

tc filter add dev internal protocol 802.1q parent 1:0 prio 100 \
    u32 ht 1:64 match ip dst 192.168.1.100 at 20 flowid 1:200

Здесь «ядро» совпадает с протоколом, но считает смещение от начала заголовка этого протокола - мне нужно добавить 4 байта к смещению (20, а не 16 для адреса dst). Это нормально, кажется более логичным, как для меня.

3.2.11, последняя стабильная версия

Это работает --- как если бы вообще не было тега 802.1q:

tc filter add dev internal protocol ip parent 1:0 prio 100 \
    u32 ht 1:64 match ip dst 192.168.1.100 flowid 1:200

Проблема в том, что я пока не смог найти способ сопоставить тег 802.1q.

Соответствующий тег 802.1q в прошлом

Я мог бы сделать это раньше следующим образом:

tc filter add dev internal protocol 802.1q parent 1:0 prio 100 \
    u32 match u16 0x0ed8 0x0fff at -4 flowid 1:300

Сейчас я не в состоянии соответствовать 802.1q тег at 0, at -2, at -4, at -6или , как это. Основной вопрос , который у меня есть ноль хитов рассчитывать --- этот фильтр не проверяется на всех, «неправильный протокол», другими словами.

Пожалуйста, кто-нибудь, помогите мне :-)

Благодарность!

броуновский
источник

Ответы:

4

Тег VLAN убран из skb в последних ядрах. Попробуйте что-то вроде этого, чтобы выполнить мета-соответствие в skb:

tc filter add dev internal protocol all parent 1:0 prio 100 basic match 'meta(vlan mask 0xfff eq 0x0ed8)' flowid 1:300
Thusitha
источник
Попытка добавить корневой фильтр для protocol allдает мне RTNETLINK answers: Invalid argument(ядро 3.3.4 здесь). Я проверю это с более новыми ядрами. Спасибо.
броунов
У меня это работало с ядром Debian Wheezy 3.2.0. Я добавил еще один ответ с полной информацией.
Ник Крейг-Вуд
3

Я должен был сделать именно это. Я обнаружил, что ответ, предложенный @Thusitha, был правильным способом сделать это для новых ядер.

Протестировано с ядром Debian wheezy 3.2.0-4 и iproute (откуда берется команда tc) версии 20120521-3 + b3

Вот полный сценарий, tc filterстроки которого в точности совпадают с указанными @Thusitha

function qos() {
    if="$1"
    vlan1="$2"
    vlan2="$3"

    # delete previous
    tc qdisc del dev $if root >/dev/null 2>&1
    tc qdisc del dev $if ingress >/dev/null 2>&1

    # Root HTB for $if
    tc qdisc add dev $if root handle 1: htb r2q 1 default 1

    # Root class to borrow from
    tc class add dev $if parent 1: classid 1:1 htb quantum 1000000 rate 500mbit ceil 500mbit burst 64k prio 2
    tc qdisc add dev $if parent 1:1 handle 101 sfq perturb 10

    # class for vlan1
    tc class add dev $if parent 1:1 classid 1:106 htb quantum 1000000 rate 1.00mbit ceil 1.00mbit burst 6k
    tc qdisc add dev $if parent 1:106 handle 107 sfq perturb 10
    tc filter add dev $if protocol all parent 1: prio 100 basic match "meta(vlan mask 0xfff eq ${vlan1})" flowid 1:106

    # class for vlan2
    tc class add dev $if parent 1:1 classid 1:108 htb quantum 1000000 rate 1.00mbit ceil 10.00mbit burst 6k
    tc qdisc add dev $if parent 1:108 handle 108 sfq perturb 10
    tc filter add dev $if protocol all parent 1: prio 100 basic match "meta(vlan mask 0xfff eq ${vlan2})" flowid 1:108

}

qos eth1 1234 1235
qos eth2 2345 2346
Ник Крейг-Вуд
источник
Странно, protocol allвыдал ошибку в ванильном ядре. Я должен проверить это больше. Спасибо.
броуновский
1

Я бы порекомендовал использовать wireshark для захвата того, что происходит через интерфейс, как видимое в пользовательском пространстве, и использовать его для написания фильтра. Мне интересно, может быть, интерфейс по какой-то причине удаляет теги VLAN (несмотря на то, что он настроен для прозрачного моста). Возможно, это добавление дополнительных тегов или что-то?

Сокол Момот
источник
Нет, это, безусловно, не удаление тега VLAN - все работает (трафик переключается через транки на аппаратных коммутаторах), кроме фильтров в формирователе. Я посмотрю поближе, однако. Я посмотрел на возможность разгрузки тегов VLAN, но эти драйверы не способны выполнять разгрузку VID.
броунов
tcpdumpпоказывает идентификаторы VLAN на всех интерфейсах bridgeи его портах.
броуновский
Теперь мой симпатичный шейпер работает под ядром linux 3.3.4, все отлично работает, кроме фильтрации тегов 8021q (я могу жить без него). Проблема остается нерешенной. Все равно спасибо.
броуновский
1

Вы можете пометить пакеты vlan ebtables .

# mark packets according to the vlan id
ebtables -i br0 -A PREROUTING -p 802_1Q --vlan-id 1 -j mark --mark-set 1
ebtables -i br0 -A PREROUTING -p 802_1Q --vlan-id 5 -j mark --mark-set 2

Тогда примените формирование, основанное на маркировке. ebtables и iptables имеют одинаковую маркировку.

Сам еще не сделал этого. Так что это скорее догадка.

rhasti
источник
Я сомневаюсь, что это будет работать гладко на 10Gb ссылке ... Я хотел бы избежать любых * таблиц. В любом случае, спасибо за предложение.
броунов
@brownian вы думаете, что такая же фильтрация в iproute2 будет более высокой производительностью? Это то же самое ядро, тот же путь кода, те же алгоритмы. До тех пор, пока вы случайно не сделаете что-то вроде включения отслеживания соединения, вы не увидите никакой разницы. * таблицы могут влиять на производительность, потому что это может делать много сложных вещей. Но это не значит, что так и будет .
Tylerl
@tylerl Поскольку мне действительно приходится фильтровать с помощью iproute2 (сотни клиентов в одном vlan, куча фильтров хэшей) - любая другая дополнительная проверка для каждого пакета будет влиять на производительность, я верю.
броунов
0

Попробуйте отключить reorder_hdrопцию на интерфейсе vlan. Если опция переупорядочивания заголовка включена, то теги из фреймов удаляются. Проверьте это по команде ip -d link list dev vlan_iface.

Злой, недобрый человек
источник
1
Не могли бы вы уточнить, когда он удаляется, а когда вставляется обратно? Я имею в виду, тегированный фрейм входит в linux bridge и затем покидает его из другого интерфейса - когда / где происходят эти манипуляции с тегами, и когда / где tcвызываются фильтры? У вас есть ссылка на карту или что-то подобное? Благодарность!
броуновский
Пожалуйста, еще одна мысль: какой интерфейс vlan вы имеете в виду? У этого моста нет одного интерфейса vlan (в первом абзаце я написал «я имею в виду, что интерфейсов VLAN нет»).
броунов