Hi Dave,
Is it possible to mix the likes of skb_clone(), pskb_pull() and pskb_trim()? I've tried to do this and I seem to end up with skb refcounting errors amongst other things. As it happens, the UDP packet was fragmented, and so the skbuff I've got is non-linear. The problem I've got to deal with is that RxRPC permits you to glue packets together into one UDP datagram (a jumbogram). If the UDP datagram wasn't fragmented, you'd end up with a single packet looking like this: +---------------+ | IP header | +---------------+ | UDP header | +---------------+ | RxRPC header | <--- has the RXRPC_JUMBO_PACKET flag set +---------------+ : : : Data : : : +---------------+ | Jumbo header | <--- has the RXRPC_JUMBO_PACKET flag set +---------------+ : : : Data : : : +---------------+ | Jumbo header | <--- has the RXRPC_JUMBO_PACKET flag set +---------------+ : : : Data : : : +---------------+ | Jumbo header | +---------------+ : : : Data : : : +---------------+ This is equivalent to four lots of this: +---------------+ | IP header | +---------------+ | UDP header | +---------------+ | RxRPC header | +---------------+ : : : Data : : : +---------------+ With the sequence number and serial number advanced by 1 in each successive packet and the flags and checksums set appropriately for each. Theoretically, it is permissible for an intervening agency (such as a router) to split a jumbo packet back into its constituent data packets and send them on. If that doesn't happen, then the intended receiver has to reconstitute them. For reference, the RxRPC header looks like this: struct rxrpc_header { __be32 epoch; __be32 cid; __be32 callNumber; __be32 seq; __be32 serial; u8 type; u8 flags; u8 userStatus; u8 securityIndex; __be16 _rsvd; // security checksum __be16 serviceId; }; And the jumbo header looks like this: struct rxrpc_jumbo_header { u8 flags; u8 pad; __be16 _rsvd; // security checksum }; The RxRPC headers are reconstituted by fixing the sequence and serial numbers as previously mentioned, and then replacing the flags and checksum fields in the RxRPC header with the replacements included in the Jumbo header for each packet. So, I have a function that looks like this: void rxrpc_process_jumbo_packet(struct rxrpc_call *call, struct sk_buff *jumbo) { struct rxrpc_jumbo_header jhdr; struct rxrpc_skb_priv *sp; struct sk_buff *part; kenter(",{%u}", jumbo->data_len); sp = rxrpc_skb(jumbo); do { sp->hdr.flags &= ~RXRPC_JUMBO_PACKET; /* make a clone to represent the first subpacket in * what's left of the jumbo packet */ part = skb_clone(jumbo, GFP_ATOMIC); if (!part) { /* simply ditch the tail in the event of * ENOMEM */ pskb_trim(jumbo, RXRPC_JUMBO_DATALEN); break; } pskb_trim(part, RXRPC_JUMBO_DATALEN); if (!pskb_pull(jumbo, RXRPC_JUMBO_DATALEN)) goto protocol_error; if (skb_copy_bits(jumbo, 0, &jhdr, sizeof(jhdr)) < 0) goto protocol_error; if (!pskb_pull(jumbo, sizeof(jhdr))) BUG(); sp->hdr.seq = htonl(ntohl(sp->hdr.seq) + 1); sp->hdr.serial = htonl(ntohl(sp->hdr.serial) + 1); sp->hdr.flags = jhdr.flags; sp->hdr._rsvd = jhdr._rsvd; kproto("Rx DATA Jumbo %%%u", ntohl(sp->hdr.serial) - 1); rxrpc_fast_process_packet(call, part); part = NULL; } while (sp->hdr.flags & RXRPC_JUMBO_PACKET); rxrpc_fast_process_packet(call, jumbo); kleave(""); return; protocol_error: ... } This function is called with the UDP and RxRPC headers already pskb_pull()'d from the packet. The rxrpc_skb_priv struct is stored in jumbo->cb and contains a copy of the RxRPC header placed there by the caller. The packet itself has been skb_orphan()'d. I was wondering if I should use skb_split() instead of skb_clone()'ing the packet and adjusting with pskb_pull() and pskb_trim(), but it's not obvious what the base for the length argument to skb_split() is. Also, from reading the comments in and around these functions, it's not clear that using one of them won't cause a clone to wind up in a bad state. I'm seeing odd effects that seem to indicate that I may not be disassembling the jumbogram correctly and that I've got refcounting errors: [0swappe] ==> rxrpc_process_jumbo_packet(,{1384}) [0swappe] ### Rx DATA Jumbo %32 [0swappe] Rx serial %32 [DATA] [0swappe] Rx DATA %32 { #32 } [0swappe] Rx serial %33 [DATA] [0swappe] ACK Requested on %33 [0swappe] Rx DATA %33 { #33 } [0swappe] <== rxrpc_process_jumbo_packet() bad--> [0swappe] Rx serial %1802201963 [UHAWHEAVAUATSH] ... Slab corruption: start=ffff81003bed5618, len=216 Redzone: 0x5a2cf071/0x5a2cf071. Last user: [<ffffffff803c4bfd>](kfree_skbmem+0x7a/0x7f) 0b0: 6b 6b 6b 6b 6a 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b Single bit error detected. Probably bad RAM. Run memtest86+ or a similar memory test tool. Prev obj: start=ffff81003bed5528, len=216 Redzone: 0x5a2cf071/0x5a2cf071. Last user: [<ffffffff803c4bfd>](kfree_skbmem+0x7a/0x7f) 000: 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 010: 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b Next obj: start=ffff81003bed5708, len=216 Redzone: 0x5a2cf071/0x5a2cf071. Last user: [<ffffffff803c4bfd>](kfree_skbmem+0x7a/0x7f) 000: 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 010: 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b David - To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html