LINUX.ORG.RU

[embedded] перехват и обработка пакета в ядре

 


0

1

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

есть код драйвера ethernet свитча, который необходимо сопровождать (комментариев и документации нет, ниже русские комментарии мои). Там есть следующий фрагмент в bottom-half обработчика прерываний, который мне не до конца понятен:

struct sk_buff *skb;

/* pktbuf это указатель на собственную структуру, описывающую
 хранимый в буферной памяти свитча пришедший фрейм */
struct pkt_buffer *pktbuf;

/* здесь берем пакет посредством DMA */
pktbuf = dmaGetPacket(...);

while (pktbuf) {
  pkt_type = classifyPacket(pktbuf);

  skb = dev_alloc_skb(pkt_len + 2);
  skb_reserve(skb, 2);  /* align IP in 16 byte */
  memcpy(skb_put(skb, pkt_len), pktbuf->eth[2], pkt_len);

  /* т.е. теперь skb содержит принятый фрейм:
     ethernet заголовок + поле тип пакета + payload */

  switch (pkt_type) {
    case (DHCP):  pktProcess_dhcp(skb, ...); break;
    case (IGMP):  pktProcess_igmp(skb, ...); break;
    /* pktProcess_*() определяют на какие порты форвардить фреймы и вообще что с ними делать */
    ...
    default:
         skb->protocol = eth_type_trans(skb, netdev);
         netif_rx(SKB);
         netdev->last_rx = jiffies;
  }
  ...

  pktbuf = dmaGetNext(...);
}

Все выглядит стройно, кроме того, что в ряде некоторых случаев, в зависимости от типа пакета, создается копия skb и уже эта копия передается в pktProcess_*(). Непонятно — с какой целью это делается, ведь выше по стеку, как я понимаю, отловленные пакеты не уходят (кроме тех, что попадают в ветку default).

★★

Последнее исправление: cruz7 (всего исправлений: 1)

>Все выглядит стройно, кроме того, что в ряде некоторых случаев, в зависимости от типа пакета, создается копия skb и уже эта копия передается в pktProcess_*().

Что-то я не заметил этого в приведенном вами коде. Или вы что-то опустили?

Dead ★★★★
()
Ответ на: комментарий от Dead

Что-то я не заметил этого в приведенном вами коде. Или вы что-то опустили?

Я опустил, там выглядит примерно так:

case (SOME_PACKET):
   skb2 = dev_alloc_skb(pkt_len + 2);
   if (skb2) {
      skb2->dev = netdev;
      skb_reserve(skb2, 2);
      memcpy(skb_put(skb2, pkt_len), &pktbuf->eth[2], pkt_len);
   }
   pktProcess_dhcp(skb2, ...); break;
cruz7 ★★
() автор топика

Копия создается скорее всего для последующей модификации

vasily_pupkin ★★★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.