Перейти к содержанию
    

виртуальный сетевой драйвер HSR/PRP

Добрый день всем!

Делаю сейчас железку на MPC8321 266MHz DDR2, linux 3.7.6, частью которой является реализация RedBox'а. Есть 3 сетевых интерфейса ETH0, ETH1, ETH2. Простыми словами, нужно грабить все пакеты из одного, немного их модифицировать, и посылать в 2 других, и наоборот. Сейчас сделал все, используя libpcap в userspace. Все работает, но скорость 30 МБит/c. Все максимально оптимизировал, но больше получить так и не смог (железка еще занимается синхронизацией IEEE1588v2, по одному интерфейсу еще реализован RSTP). Как вижу единственный путь - перенести все сетевые дела в kernel, дабы избежать лишнего копирования из kernel в userspace и обратно. С сетевыми драйверами знаком немного (прочитал пару книжек, но ни разу не писал еще ничего реального), с символьным знаком хорошо, было пару проектов, включая этот.

Плиз, посоветуйте оптимальный путь, может есть что нибудь, что можно взять за основу (самый лучший вариант). Как мне видеться, нужен механизм, чтобы спрятать реальные физические интерфейсы от системы, создать виртуальные, на которые будет перенаправлен их вывод с небольшой модификацией пакетов ес-но.

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

В принципе сейчас нашел драйвер для DSA (Distributed Switch Architecture).

Создает виртуальное/ые устройство/а по количеству портов на свитче и вставляет/убирает DSA тэг в пакетах.

Создает виртуальное устройство с помощью alloc_netdev()

Добавляет протокол сетевого уровня с помощью dev_add_pack()

Как я понял, такое решение не скроет физическое устройство, а будет перехватывать только DSA пакеты.

Мне же нужно перехватывать ВСЕ пакеты от физического интерфейса и спрятать само устройство от системы. Есть ли такой метод?

 

 

 

 

Опять таки оно работает с помощью 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:

Драйвер дописал, все работает, всем спасибо.

Изменено пользователем Славка

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...