Как клонировать пакет и изменить поля заголовка Ethernet, IP и UDP в DPDK?
Я пытаюсь клонировать пакет и изменить различные поля заголовка уровня 2/3/4 в клонированных пакетах.
Основываясь на примерах, приведенных в репозитории DPDK и через Интернет, rte_pktmbuf_prepend() использовалась почти во всех примерах. После добавления необходимого заголовка эти новые добавленные заголовки изменяются, чтобы отразить более новое значение различных полей. Насколько я понимаю, rte_pktmbuf_clone () будет клонировать все сегменты, и почему мы не можем изменить поля заголовка в клонированных пакетах, и почему мы должны добавлять заголовки после клонирования пакета?
Более того, в ipv4_multicast(пример приложения DPDK) заголовки сначала удаляются с помощью rte_pktmbuf_adj(), а затем к пакету добавляются новые заголовки. Так, в некоторых примерах заголовки сначала удаляются, а затем добавляются новые заголовки, а в некоторых других примерах добавляются новые заголовки. Зачем нам это делать?
Благодарю.
Ссылки по теме:
http://dpdk.org/ml/archives/dev/2014-March/001589.html
http://dpdk.org/ml/archives/dev/2014-March/001583.html
http://dpdk.readthedocs.io/en/v17.08/sample_app_ug/ipv4_multicast.html
1 ответ
В DPDK (как и во многих других библиотеках) идея mbufs заключается в разделении данных (т. Е. Кадра Ethernet с IP-пакетом внутри) и метаданных (т. Е. Количества буферов в цепочке, указателя на следующий буфер, флагов, общей длины и т. Д.).
rte_pktmbuf_clone()
для данного mbuf выделяет другие метаданные. Эти метаданные присоединяются к исходным данным mbuf, т.е. исходные и клонированные mbuf совместно используют одни и те же данные после клонирования, но имеют два отдельных метаданных. Это описано более подробно в Руководстве программиста.
Теперь отвечаю на ваш вопрос.
почему мы не можем изменить поля заголовка в клонированных пакетах и почему нам нужно добавить заголовки после клонирования пакета?
Фактически, мы МОЖЕМ изменить заголовки пакетов в клонированных пакетах, но поскольку (после клонирования) два mbuf совместно используют одни и те же данные буфера, изменение данных одного mbuf изменит данные в другом, так как данные mbuf совместно используются.
Цель некоторых примеров - отправить один и тот же mbuf в N пунктов назначения одновременно. Простейшим решением будет:
- Выделите N новых mbufs.
- Сделайте N копий оригинальных данных.
- Измените заголовки пакетов N раз для N получателей.
- Отправьте эти mbufs на N различных интерфейсов.
К сожалению, создание N копий данных только для изменения нескольких байтов в начале не является наиболее эффективным решением. Поэтому вместо этого мы клонируем пакеты, то есть:
- Выделите N новых метаданных mbufs (т.е. намного меньше, чем ранее).
- Прикрепите N mbufs к исходным данным (т.е. не копируйте данные).
Теперь, поскольку все N mbuf совместно используют одни и те же данные, мы не можем изменить заголовки пакетов для N различных адресатов. Итак, вместо этого мы выделяем другой mbuf только для заголовков пакетов, то есть:
- Выделите N mbufs для заголовков пакетов.
- Заполните заголовки пакетов N раз для N пунктов назначения.
- Добавьте N заголовков к N клонированным mbuf.
- Отправьте эти mbufs на N различных интерфейсов.
Таким образом, процесс является более сложным, чем ранее, но потенциально может показать лучшую производительность, потому что мы никогда не копируем пакетные данные, которые могут быть до ~65K в некоторых случаях.
Так, в некоторых примерах заголовки сначала удаляются, а затем добавляются новые заголовки, а в некоторых других примерах добавляются новые заголовки. Зачем нам это делать?
Это зависит от того, нужно ли просто изменить заголовки пакетов и отправить их, или нам нужно сделать N копий с N различными заголовками пакетов, как описано выше. В целом, DPDK очень ориентирован на производительность, поэтому мы можем принять как должное, что все эти осложнения есть причина...