How to understand the function of pskb_may_pull()?
Alberto Leiva
ydahhrk at gmail.com
Wed Jan 7 10:35:22 EST 2015
I think in theory whatever random driver for whatever random hardware
might create this situation. It's not illegal. Anyone can create a
driver outside of the kernel tree, after all. In practice, of course,
this is not the case, because anyone can tell it creates a significant
amount of overhead when the inevitable pskb_may_pull() come into play,
but you don't know what constrictive environments a driver out there
might be operating on.
As I understand it, paging skbs is a technique meant to ease the work
of drivers.
A driver might choose to page "too much" data.
The kernel is prepared for this situation ('Be conservative in what
you do, be liberal in what you accept from others' -
http://en.wikipedia.org/wiki/Robustness_principle).
That's all there is to it, I think.
PS: From your sorta definition, you seem to be assuming
pskb_may_pull() is only used to ensure the IP header is not paged. I
understand this might not be the case, but just to make things clear:
pskb_may_pull() can be used to copy *any* amount of bytes from the
paged part to the head room of the packet (it's not tied to the IP
header's length). For example, you could use it to also guarantee a
TCP header by doing this:
if (!pskb_may_pull(skb, sizeof(struct iphdr) + sizeof(struct tcphdr)))
goto inhdr_error;
On Wed, Jan 7, 2015 at 2:28 AM, lx <lxlenovostar at gmail.com> wrote:
> hi all:
> The job of pskb_may_pull is to make sure that the area pointed to by
> skb->data contains a block of
> data at least as big as the IP header, since each IP packet (fragments
> included) must include a complete IP
> header.When we receive a packet , the kernel will call the pkb_may_pull(),
> it looks like the following in line 395:
>
> 373 /*
> 374 * Main IP Receive routine.
> 375 */
> 376 int ip_rcv(struct sk_buff *skb, struct net_device *dev, struct
> packet_type *pt, struct net_device *orig_dev)
> 377 {
> 378 const struct iphdr *iph;
> 379 u32 len;
> 380
> 381 /* When the interface is in promisc. mode, drop all the crap
> 382 * that it receives, do not try to analyse it.
> 383 */
> 384 if (skb->pkt_type == PACKET_OTHERHOST)
> 385 goto drop;
> 386
> 387
> 388 IP_UPD_PO_STATS_BH(dev_net(dev), IPSTATS_MIB_IN, skb->len);
> 389
> 390 if ((skb = skb_share_check(skb, GFP_ATOMIC)) == NULL) {
> 391 IP_INC_STATS_BH(dev_net(dev), IPSTATS_MIB_INDISCARDS);
> 392 goto out;
> 393 }
> 394
> 395 if (!pskb_may_pull(skb, sizeof(struct iphdr)))
> 396 goto inhdr_error;
> 397
> 398 iph = ip_hdr(skb);
> 399
>
> And the definition of pkb_may_pull() looks like the following:
>
> 1708 static inline int pskb_may_pull(struct sk_buff *skb, unsigned int len)
> 1709 {
> 1710 if (likely(len <= skb_headlen(skb)))
> 1711 return 1;
> 1712 if (unlikely(len > skb->len))
> 1713 return 0;
> 1714 return __pskb_pull_tail(skb, len - skb_headlen(skb)) != NULL;
> 1715 }
>
> I just want to know which situation make the skb->data contains a block of
> data less than the IP header?
> I think this packet can't send by kernel at all.
> Thank you.
>
> _______________________________________________
> Kernelnewbies mailing list
> Kernelnewbies at kernelnewbies.org
> http://lists.kernelnewbies.org/mailman/listinfo/kernelnewbies
>
More information about the Kernelnewbies
mailing list