diff options
author | Rusty Russell <rusty@rustcorp.com.au> | 2008-02-04 23:49:54 -0500 |
---|---|---|
committer | Rusty Russell <rusty@rustcorp.com.au> | 2008-02-04 23:49:56 +1100 |
commit | f35d9d8aae08940b7fdd1bb8110619da2ece6b28 (patch) | |
tree | 562d8d7a6583d0a0750ec8d996026b73e8315421 /net/core/skbuff.c | |
parent | 9135f1901ee6449dfe338adf6e40e9c2025b8150 (diff) | |
download | lwn-f35d9d8aae08940b7fdd1bb8110619da2ece6b28.tar.gz lwn-f35d9d8aae08940b7fdd1bb8110619da2ece6b28.zip |
virtio: Implement skb_partial_csum_set, for setting partial csums on untrusted packets.
Use it in virtio_net (replacing buggy version there), it's also going
to be used by TAP for partial csum support.
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
Acked-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/core/skbuff.c')
-rw-r--r-- | net/core/skbuff.c | 29 |
1 files changed, 29 insertions, 0 deletions
diff --git a/net/core/skbuff.c b/net/core/skbuff.c index 98420f9c4b6d..4e354221ec23 100644 --- a/net/core/skbuff.c +++ b/net/core/skbuff.c @@ -2461,6 +2461,34 @@ int skb_cow_data(struct sk_buff *skb, int tailbits, struct sk_buff **trailer) return elt; } +/** + * skb_partial_csum_set - set up and verify partial csum values for packet + * @skb: the skb to set + * @start: the number of bytes after skb->data to start checksumming. + * @off: the offset from start to place the checksum. + * + * For untrusted partially-checksummed packets, we need to make sure the values + * for skb->csum_start and skb->csum_offset are valid so we don't oops. + * + * This function checks and sets those values and skb->ip_summed: if this + * returns false you should drop the packet. + */ +bool skb_partial_csum_set(struct sk_buff *skb, u16 start, u16 off) +{ + if (unlikely(start > skb->len - 2) || + unlikely((int)start + off > skb->len - 2)) { + if (net_ratelimit()) + printk(KERN_WARNING + "bad partial csum: csum=%u/%u len=%u\n", + start, off, skb->len); + return false; + } + skb->ip_summed = CHECKSUM_PARTIAL; + skb->csum_start = skb_headroom(skb) + start; + skb->csum_offset = off; + return true; +} + EXPORT_SYMBOL(___pskb_trim); EXPORT_SYMBOL(__kfree_skb); EXPORT_SYMBOL(kfree_skb); @@ -2497,3 +2525,4 @@ EXPORT_SYMBOL(skb_append_datato_frags); EXPORT_SYMBOL_GPL(skb_to_sgvec); EXPORT_SYMBOL_GPL(skb_cow_data); +EXPORT_SYMBOL_GPL(skb_partial_csum_set); |