Как клонировать пакет и изменить поля заголовка 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 пунктов назначения одновременно. Простейшим решением будет:

  1. Выделите N новых mbufs.
  2. Сделайте N копий оригинальных данных.
  3. Измените заголовки пакетов N раз для N получателей.
  4. Отправьте эти mbufs на N различных интерфейсов.

К сожалению, создание N копий данных только для изменения нескольких байтов в начале не является наиболее эффективным решением. Поэтому вместо этого мы клонируем пакеты, то есть:

  1. Выделите N новых метаданных mbufs (т.е. намного меньше, чем ранее).
  2. Прикрепите N mbufs к исходным данным (т.е. не копируйте данные).

Теперь, поскольку все N mbuf совместно используют одни и те же данные, мы не можем изменить заголовки пакетов для N различных адресатов. Итак, вместо этого мы выделяем другой mbuf только для заголовков пакетов, то есть:

  1. Выделите N mbufs для заголовков пакетов.
  2. Заполните заголовки пакетов N раз для N пунктов назначения.
  3. Добавьте N заголовков к N клонированным mbuf.
  4. Отправьте эти mbufs на N различных интерфейсов.

Таким образом, процесс является более сложным, чем ранее, но потенциально может показать лучшую производительность, потому что мы никогда не копируем пакетные данные, которые могут быть до ~65K в некоторых случаях.

Так, в некоторых примерах заголовки сначала удаляются, а затем добавляются новые заголовки, а в некоторых других примерах добавляются новые заголовки. Зачем нам это делать?

Это зависит от того, нужно ли просто изменить заголовки пакетов и отправить их, или нам нужно сделать N копий с N различными заголовками пакетов, как описано выше. В целом, DPDK очень ориентирован на производительность, поэтому мы можем принять как должное, что все эти осложнения есть причина...

Другие вопросы по тегам