Jump to content

    
Sign in to follow this  
Maverick_

packet parsing ipv4/ipv6 на hdl (low latency)

Recommended Posts

Может есть у кого то литература/статьи как лучше это на vhdl/verilog сделать

Может есть наработки которыми можете поделиться или где то видели/находили

целевая FPGA arria10

PS я только начал смотреть в этом направлении - читаю что предлагает гугл :)

Share this post


Link to post
Share on other sites

Приветствую!

48 minutes ago, Maverick_ said:

Может есть у кого то литература/статьи как лучше это на vhdl/verilog сделать

А что  тут  сложного то?  (акромя  проблем со сном из необходимости читать на ночь жуткие RFC :wacko2:  ).
Основной по сложности будет вопрос "... а что же надо поддерживать из зверинца стандартов и в каком объеме".:mega_shok:
А дальше  чисто технические трудности - какая целевая частота/разрядность шины.
Как разбивать FSM парсинга по уровням - как в теории, в соответствии с уровнями стека,
или  делать все проще объединяя несколько уровней в одной FSM.  Что делать при возможных ошибках, ... 

 

Ну и естественно  чем и как проверять все то что вы напишете на соответствие "ночным кошмарам" :scratch_one-s_head: 

Увы о таком в книжках обычно не пишут, так как обычно зависит это от особенностей вашего дизайна.   

 

Удачи!  Rob. 

 

P.S.  Для автоматизации такой рутины, packet processing, есть спец. язык P4. По нему много работ можно найти и я даже на github когда-то видел генераторы V/VHDL кода  из него. 
У Xilinx  был SDNet который тоже делал  подобное.  Но  Low Latency такими генераторами не получить :cray:

Share this post


Link to post
Share on other sites

Если сетку никогда не парсили, наверное стоит пробежаться по википедии, там красивые статьи по струткурам пакета. Начиная от самого верхней структуры ethernet фрейма до ip4, ip6, tcp, udp. Потом можно свою сеть посниффить, записать dump (с помощью wireshark) и посмотреть как пакеты ходят в сетке и из чего состоят. Появится уже представления об ethernet фреймах. IP уровень в них не такой сложный.


Ну а потом уже выяснять нюансы в rfc и на бою может

Проверку парсера в симуляторе я делал просто: поназаписывал дампы с разных сетей, потом подгружал их в симулятор и гонял тесты.

Edited by new123

Share this post


Link to post
Share on other sites
2 hours ago, new123 said:

Если сетку никогда не парсили, наверное стоит пробежаться по википедии, там красивые статьи по струткурам пакета. Начиная от самого верхней структуры ethernet фрейма до ip4, ip6, tcp, udp. Потом можно свою сеть посниффить, записать dump (с помощью wireshark) и посмотреть как пакеты ходят в сетке и из чего состоят. Появится уже представления об ethernet фреймах. IP уровень в них не такой сложный.


Ну а потом уже выяснять нюансы в rfc и на бою может

Проверку парсера в симуляторе я делал просто: поназаписывал дампы с разных сетей, потом подгружал их в симулятор и гонял тесты.

С этого я и начал :)

Совет как симулить принят

Спасибо

3 hours ago, RobFPGA said:

Приветствую!

...

P.S.  Для автоматизации такой рутины, packet processing, есть спец. язык P4. По нему много работ можно найти и я даже на github когда-то видел генераторы V/VHDL кода  из него. 
У Xilinx  был SDNet который тоже делал  подобное.  Но  Low Latency такими генераторами не получить :cray:

можете дать ссылку на язык P4?

уже нашел   https://github.com/p4lang/

 

Share this post


Link to post
Share on other sites

Мой опыт:

Курили  RFC, Wiki, КиТ, Electronix

1. Взяли корку с OpenCores Ethernet, допилили под себя (чистый Verilog)

2. Сделали разбор ip4 (чистый Verilog)

3. Сделали разбор UDP (чистый Verilog)

4. Реализовали ARP ответы, таблицу (чистый Verilog)

5. Подняли буфер на несколько (не помню на столько точно) пакетов, по приоритетам, арбитраж (чистый Verilog)

Конечная цель железки ретрансляция пакетов UDP с подменой MAC, IP согласно заложенной конфигурации. Сама конфигурация прилетала в конфигурационном UDP пакете.

Spartan-6

Если актуально, пишите в личку. 

Могу скинуть все или часть исходников, если не найдется противопоказаний.

Share this post


Link to post
Share on other sites
On 4/29/2021 at 5:18 PM, new123 said:


Проверку парсера в симуляторе я делал просто: поназаписывал дампы с разных сетей, потом подгружал их в симулятор и гонял тесты.

Приветствую. А дампы вы чем писали? Плисиной или wireshark'ом. Если последнее, то поделитесь, каквы pcap  симулятору скармливали.

Share this post


Link to post
Share on other sites

Приветствую

15 minutes ago, DuHast said:

Приветствую. А дампы вы чем писали? Плисиной или wireshark'ом. Если последнее, то поделитесь, каквы pcap  симулятору скармливали.

На  github  есть несколько очень полезных  библиотек для работы Ethernet с пакетами  - например sv_pkt_lib.  В ней также есть пример как читать/писать pcap через С/С++ DPI. 
Но при желании можно сделать чтение/запись pcap и на чистом V/SV,  будет даже  проще  чем через  DPI. 

 

Удачи! Rob.

Share this post


Link to post
Share on other sites
2 hours ago, DuHast said:

А дампы вы чем писали? Плисиной или wireshark'ом

wireshark'ом я писал только точечно, если что то конкретно надо выделить. И прям из него экспортировал хекс, особо не утруждался.
Массово дамп я писал в c++ из разных сетей (чтобы записать разновидный трафик ip4/ip6/vlan/tcp/udp...), заставляя весь трафик прогонять через свою утилиту. Записывал в хекс все и подгружал в симуляторе. С pcap я особо не заморачивался, сделал все предельно просто. Возможно что то есть специализированное, о чем пишет Rob.

 

У меня все как то просто было, примерно вот так в цикле
 

	reg 	[31:0] 	tx_packet_size;
	reg 	[255:0] tx_packet [29:0];
	
	dump_file = $fopen("dumps/example.bin","rb");
	
	$fread (tx_packet_size, dump_file);
	$fread (tx_packet, dump_file);

	....

 

Edited by new123

Share this post


Link to post
Share on other sites

Приветствую!

Если грубо то работа  с pcap  это  простой парсинг файла 

Есть   две структуры заголовков - начального  и пакетного  

  //
  typedef struct packed {
    u32_t magic        ;
    u16_t version_major;
    u16_t version_minor;
    u32_t thiszone     ;
    u32_t sigfigs      ;
    u32_t snaplen      ;
    u32_t linktype     ;
  } st_PCAP_HDR_t;

  //
  typedef struct packed {
    u32_t tv_sec  ;
    u32_t tv_usec ;
    u32_t caplen  ;
    u32_t len     ;
  } st_PKT_HDR_t;

открываем файл, сначала читаем  начальный заголовок,  а потом в цикле заголовок пакета и само тело пакета (если есть). 

st_PCAP_HDR_t  pcap_hdr;

bit [0: $bits(pcap_hdr)-1] pcap_tmp;
...
fin_h = $fopen(fname,"rb");
...
res = $fread(pcap_tmp, fin_h);

pcap_hdr.magic         = n2h32(pcap_tmp[0   +: 32]);  // byte swap  
pcap_hdr.version_major = n2h16(pcap_tmp[32  +: 16]);
pcap_hdr.version_minor = n2h16(pcap_tmp[48  +: 16]);
pcap_hdr.thiszone      = n2h32(pcap_tmp[64  +: 32]);
pcap_hdr.sigfigs       = n2h32(pcap_tmp[96  +: 32]);
pcap_hdr.snaplen       = n2h32(pcap_tmp[128 +: 32]);
pcap_hdr.linktype      = n2h32(pcap_tmp[160 +: 32]);

//...

st_PKT_HDR_t               pkt_hdr;
bit [0: $bits(pkt_hdr)-1]  pkt_tmp;
u8_t pkt_data[];

while (!$feof(fin_h)) begin
  res = $fread(pkt_tmp, fin_h);

  pkt_hdr.tv_sec = n2h32(pkt_tmp[0  +: 32]);
  pkt_hdr.tv_usec= n2h32(pkt_tmp[32 +: 32]);
  pkt_hdr.caplen = n2h32(pkt_tmp[64 +: 32]);
  pkt_hdr.len    = n2h32(pkt_tmp[96 +: 32]);
    
  if (pkt_hdr.caplen>0) begin
    res = fread_n_byte(fin_h, pkt_hdr.caplen, pkt_data); // read N bytes from file
    // process pkt_data ...
  end
end 
//...
$fclose(fin_h);

Похоже делаем и для записи из сима  в pcap, но естественно  сами пишем в структуры нужные данные.      

Удачи! Rob.

Share this post


Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Sign in to follow this