0

in r8169 driver from realtek it does

    rx_buf = page_address(tp->Rx_databuff[entry]);
    dma_sync_single_for_cpu(d, addr, pkt_size, DMA_FROM_DEVICE);
    prefetch(rx_buf);
    skb_copy_to_linear_data(skb, rx_buf, pkt_size);<----//Do I get packet at this????
    skb->tail += pkt_size;
    skb->len = pkt_size;
    dma_sync_single_for_device(d, addr, pkt_size, DMA_FROM_DEVICE);
    //csum...
    skb->protocol = eth_type_trans(skb, dev);
    napi_gro_receive(&tp->napi, skb);

this is inside rtl_rx function called from poll of driver. I like to know in above code how can I extract the entire packet from skb at which line afterwards.

I assume at this line

             skb_copy_to_linear_data(skb, rx_buf, pkt_size);

I should have a packet, but like to know the correct way I can create a kmalloc obect like

         void   *packet=   kmalloc(....sizeof(struct ethhdr)+sizeof(struct iphdr)+sizeof(tcphdr))

and read ethernet ip and tcp headers from void *packet

How to achieve it

Or should I simple do skb_netword_header, skb_tcp_header, etc... to extract the headers and payload from skb after it get populated in above lines,

or can I simply cast as

              rx_buf = page_address(tp->Rx_databuff[entry]);
              struct ether_header ethhdr_of_packet=(struct eher_header *) rx_buf;

Should it work?

user786
  • 3,902
  • 4
  • 40
  • 72

1 Answers1

1

The highlighted line (the one with skb_copy_to_linear_data()) indeed copies entire packet data from the buffer in the driver-internal Rx ring (rx_buf) to the data buffer of the skb.

static inline void skb_copy_to_linear_data(struct sk_buff *skb,
                       const void *from,
                       const unsigned int len)
{
    memcpy(skb->data, from, len);
}

Casting the rx_buf pointer to Ethernet header should be OK, too. However, the purpose of accessing the packet header like this is rather vague in the question of yours. Are you trying to just print ("dump") the packet or do you intend to copy the packet data to a completely different buffer to be consumed elsewhere?

user10304260
  • 1,079
  • 7
  • 7
  • `do you intend to copy the packet data to a completely different buffer to be consumed elsewhere?` I like to keep it in my own data structure that will contain packets and it will be global in driver c file and will read it using char device or block device read function of char or block device. I like to know if I create a struct object which is global and similar to my own created circular ring type something struct and just populating it in poll and reading from userspace application after opening char or block device then will it work – user786 Feb 06 '21 at 12:38
  • do u mean this function `int pci_mmap_page_range(struct pci_dev *pdev, int bar,struct vm_area_struct *vma,enum pci_mmap_state mmap_state, int write_combine);` or `io_remap_page_range` wiil do work what exactly I will be reading. Can I get packets and ethernet frames in `vma` in this function call returned. is that what u are saying? what `simple_mmap` function in the driver will look like can u add that in the answer please. – user786 Feb 06 '21 at 13:40
  • I mean I will call the mmap function in probably probe function and once I done with mapping with mmap function call in probe containing pci_mmap_range call. does this will give me green light to read packets and probably write packets too like ethernet frames – user786 Feb 06 '21 at 13:45
  • Can u please tell me if I like to implement mapping using mmap implementation in a driver then can I call `pci_mmap_resource_range` or `pci_mmap_page_range` where exactly these two function are used, can I call them in probe function and what are they used for? – user786 Feb 06 '21 at 13:57
  • Or in side file mmap function – user786 Feb 06 '21 at 14:09
  • Like this https://stackoverflow.com/questions/20120812/how-should-i-read-intel-pci-uncore-performance-counters-on-linux-as-non-root – user786 Feb 06 '21 at 14:12