Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: виртуальный сетевой драйвер HSR/PRP
Форум разработчиков электроники ELECTRONIX.ru > Cистемный уровень проектирования > Операционные системы > Linux
Славка
Добрый день всем!
Делаю сейчас железку на MPC8321 266MHz DDR2, linux 3.7.6, частью которой является реализация RedBox'а. Есть 3 сетевых интерфейса ETH0, ETH1, ETH2. Простыми словами, нужно грабить все пакеты из одного, немного их модифицировать, и посылать в 2 других, и наоборот. Сейчас сделал все, используя libpcap в userspace. Все работает, но скорость 30 МБит/c. Все максимально оптимизировал, но больше получить так и не смог (железка еще занимается синхронизацией IEEE1588v2, по одному интерфейсу еще реализован RSTP). Как вижу единственный путь - перенести все сетевые дела в kernel, дабы избежать лишнего копирования из kernel в userspace и обратно. С сетевыми драйверами знаком немного (прочитал пару книжек, но ни разу не писал еще ничего реального), с символьным знаком хорошо, было пару проектов, включая этот.
Плиз, посоветуйте оптимальный путь, может есть что нибудь, что можно взять за основу (самый лучший вариант). Как мне видеться, нужен механизм, чтобы спрятать реальные физические интерфейсы от системы, создать виртуальные, на которые будет перенаправлен их вывод с небольшой модификацией пакетов ес-но.
Idle
Не оно? http://lwn.net/Articles/488836/
Славка
В принципе сейчас нашел драйвер для DSA (Distributed Switch Architecture).
Создает виртуальное/ые устройство/а по количеству портов на свитче и вставляет/убирает DSA тэг в пакетах.
Создает виртуальное устройство с помощью alloc_netdev()
Добавляет протокол сетевого уровня с помощью dev_add_pack()
Как я понял, такое решение не скроет физическое устройство, а будет перехватывать только DSA пакеты.
Мне же нужно перехватывать ВСЕ пакеты от физического интерфейса и спрятать само устройство от системы. Есть ли такой метод?



Цитата(Idle @ Apr 9 2013, 12:05) *


Опять таки оно работает с помощью dev_add_pack() и не прячет физические устройства на сколько я понял.
Если пакет без определенного тэга, то он пойдет дальше в систему через физическое устройство. Мне же нужно, как я говорил, спрятать физический интерфейс от системы и подменить его виртуальным.



Нашел ETH_P_ALL фильтр для dev_add_pack как вариант. Будет перехватывать все пакеты.
Нашел так же метод netdev_rx_handler_register(). Что лучше использовать, пока в замешательстве.
Вопрос, как спрятать физическое устройство в системе отсаеться открытым. А нужно ли его прятать?
Славка
Сделал виртуальный интерфейс по примеру из http://www.ibm.com/developerworks/ru/libra...l_33/index.html

добавил только dev_set_promiscuity(front_dev, 1);

вопрос в следующем. Почему, если у физического и виртуального интерфейса одинаковые mac, ping проходит, а если разные, то нет? Хотя wiresharkом вижу, что пакеты от виртуального интерфейса посылаются, компьютер на них отвечает, пакет заходит в handle_frame(), в буфере skb подменяется устройство, но линух этот пакет не видит.

В drivers/net/bonding/ и net/bridge/ после alloc_netdev вызывается dev_net_set(). Зачем это делается? Может в этом причина? Тогда где взять аргумент net?


Славка
Решил задачку с netdev_rx_handler_register()

Код
static rx_handler_result_t _front_phys_handler(struct sk_buff **pskb) {
    struct sk_buff *skb = *pskb;

    skb = skb_share_check(skb, GFP_ATOMIC );
    if (!skb)
        return RX_HANDLER_CONSUMED;

    skb->dev = redbox_dev.virt_front;

    skb->pkt_type = PACKET_HOST;

    if(netif_rx(skb) == NET_RX_SUCCESS) {
        redbox_dev.virt_front->stats.rx_packets++;
        redbox_dev.virt_front->stats.rx_bytes += skb->len;
    }

    return RX_HANDLER_CONSUMED;
}


Теперь пакеты гуляют спокойно от виртуального адаптера через физический при разных мак адрессах. В общем то могу уже переносить код. Спрятать физический интерфейс от системы не получиться, как я понял. Но он и не мешает, все пакеты перехватываются новым handler'ом.
Славка
Может подскажите как послать skb сразу в 2 интерфейса? Сейчас ситуация следующая, пакет приходящий из xmit функции виртуального сетевого устройства посылаю с помощью dev_queue_xmit по следующему алгоритму.
Код
skb2 = skb_clone(skb, GFP_ATOMIC)
skb->dev = eth1
skb2->dev = eth2
dev_queue_xmit(skb)
dev_queue_xmit(skb2)


ping на удаленный хост проходит с 30-70% потерями. И вообще твориться что то непредсказуемое. Когда же посылаю только в 1 интерфейс ping проходит 100%. В чем может быть проблема?
Славка
Нужно было отключить learning на свитче, чтоб одинаковые пакеты выходили с интерфейса. У меня два ETH подключены к свитчу и разруливаются на внешние порты через port based vlan. Так что все я правильно делал с skb буферами. Перерыл тонну литературы, узнал очень много нового по сетевым драйверам, а проблема изначально было в другом biggrin.gif
Драйвер дописал, все работает, всем спасибо.
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.