Packet Reception
Receiving data from the network is trickier than transmitting it
because an sk_buff must be allocated and handed off
to the upper layers from within an interrupt handler. The usual way
to receive a packet is through an interrupt, unless the interface is a
purely software one like snull or the
loopback interface. Although it is possible to write polling drivers,
and a few exist in the official kernel, interrupt-driven operation is
much better, both in terms of data throughput and computational
demands. Because most network interfaces are interrupt driven, we
won’t talk about the polling implementation, which just exploits
kernel timers.
The implementation of snull separates the “hardware” details from the device-independent housekeeping. The function snull_rx is thus called after the hardware has received the packet and it is already in the computer’s memory. snull_rx receives a pointer to the data and the length of the packet; its sole responsibility is to send the packet and some additional information to the upper layers of networking code. This code is independent of the way the data pointer and length are obtained.
void snull_rx(struct net_device *dev, int len, unsigned char *buf) { struct sk_buff *skb; struct snull_priv *priv = (struct snull_priv *) dev->priv; /* * The packet has been retrieved from the transmission * medium. Build an skb around it, so upper layers can handle it */ skb = dev_alloc_skb(len+2); if (!skb) { printk("snull rx: low on mem - packet ...