Message ID | 1354918363.9124.29.camel@jlt4.sipsolutions.net |
---|---|
State | RFC, archived |
Delegated to: | David Miller |
Headers | show |
Oh I should say ... IP is like black magic to me ;-) > - if (!pskb_may_pull(skb, sizeof(struct iphdr))) > + if (!skb_copy_bits(skb, 0, &iph, sizeof(iph))) > return skb; > > - iph = ip_hdr(skb); > - if (iph->ihl < 5 || iph->version != 4) > + if (iph.ihl < 5 || iph.version != 4) > return skb; > - if (!pskb_may_pull(skb, iph->ihl*4)) > - return skb; > - iph = ip_hdr(skb); > - len = ntohs(iph->tot_len); > - if (skb->len < len || len < (iph->ihl * 4)) > + > + len = ntohs(iph.tot_len); > + if (skb->len < len || len < (iph.ihl * 4)) > return skb; > > - if (ip_is_fragment(ip_hdr(skb))) { > + if (ip_is_fragment(&iph)) { > skb = skb_share_check(skb, GFP_ATOMIC); > if (skb) { > + if (!pskb_may_pull(skb, iph.ihl*4)) > + return skb; I moved this here but I have no idea what it does. Asking if we can pull this here seems a bit pointless, and in the previous place it seemed similarly pointless since we only use the static part of the IP header and don't look at any options... So to me it seems this pskb_may_pull() could just be removed, and that most likely means I'm messing with code I don't understand :-) johannes -- To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
On Fri, 2012-12-07 at 23:23 +0100, Johannes Berg wrote: > Oh I should say ... IP is like black magic to me ;-) > > > - if (!pskb_may_pull(skb, sizeof(struct iphdr))) > > + if (!skb_copy_bits(skb, 0, &iph, sizeof(iph))) > > return skb; > > > > - iph = ip_hdr(skb); > > - if (iph->ihl < 5 || iph->version != 4) > > + if (iph.ihl < 5 || iph.version != 4) > > return skb; > > - if (!pskb_may_pull(skb, iph->ihl*4)) > > - return skb; > > - iph = ip_hdr(skb); > > - len = ntohs(iph->tot_len); > > - if (skb->len < len || len < (iph->ihl * 4)) > > + > > + len = ntohs(iph.tot_len); > > + if (skb->len < len || len < (iph.ihl * 4)) > > return skb; > > > > - if (ip_is_fragment(ip_hdr(skb))) { > > + if (ip_is_fragment(&iph)) { > > skb = skb_share_check(skb, GFP_ATOMIC); > > if (skb) { > > + if (!pskb_may_pull(skb, iph.ihl*4)) > > + return skb; > > I moved this here but I have no idea what it does. Well, ok, looking further it does seem kinda obvious -- ip_defrag() assumes the IP header is (fully?) present in the skb header, so that's what this does. Eric (Leblond), could you test this patch? johannes -- To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
diff --git a/net/ipv4/ip_fragment.c b/net/ipv4/ip_fragment.c index 448e685..8d5cc75 100644 --- a/net/ipv4/ip_fragment.c +++ b/net/ipv4/ip_fragment.c @@ -707,28 +707,27 @@ EXPORT_SYMBOL(ip_defrag); struct sk_buff *ip_check_defrag(struct sk_buff *skb, u32 user) { - const struct iphdr *iph; + struct iphdr iph; u32 len; if (skb->protocol != htons(ETH_P_IP)) return skb; - if (!pskb_may_pull(skb, sizeof(struct iphdr))) + if (!skb_copy_bits(skb, 0, &iph, sizeof(iph))) return skb; - iph = ip_hdr(skb); - if (iph->ihl < 5 || iph->version != 4) + if (iph.ihl < 5 || iph.version != 4) return skb; - if (!pskb_may_pull(skb, iph->ihl*4)) - return skb; - iph = ip_hdr(skb); - len = ntohs(iph->tot_len); - if (skb->len < len || len < (iph->ihl * 4)) + + len = ntohs(iph.tot_len); + if (skb->len < len || len < (iph.ihl * 4)) return skb; - if (ip_is_fragment(ip_hdr(skb))) { + if (ip_is_fragment(&iph)) { skb = skb_share_check(skb, GFP_ATOMIC); if (skb) { + if (!pskb_may_pull(skb, iph.ihl*4)) + return skb; if (pskb_trim_rcsum(skb, len)) return skb; memset(IPCB(skb), 0, sizeof(struct inet_skb_parm));