diff options
| author | David S. Miller <davem@nuts.davemloft.net> | 2004-06-20 02:38:03 -0700 |
|---|---|---|
| committer | David S. Miller <davem@nuts.davemloft.net> | 2004-06-20 02:38:03 -0700 |
| commit | 40fe493622602e8ba438f227f30cd982a0e14979 (patch) | |
| tree | 70c9b22dfc2277e5758284a7dc8b2bb48a5aacfa /include | |
| parent | 85bed77bb232e5ee7ce6dccaf7c85ec656ebf9c9 (diff) | |
| parent | 86adf644850fbbc3da6448e8e1a0e39fe755e8e9 (diff) | |
Merge bk://kernel.bkbits.net/acme/net-2.6-1.1768
into nuts.davemloft.net:/disk1/BK/acme-2.6
Diffstat (limited to 'include')
| -rw-r--r-- | include/linux/errqueue.h | 4 | ||||
| -rw-r--r-- | include/linux/skbuff.h | 36 | ||||
| -rw-r--r-- | include/net/checksum.h | 70 | ||||
| -rw-r--r-- | include/net/ip.h | 2 | ||||
| -rw-r--r-- | include/net/ip6_checksum.h | 94 | ||||
| -rw-r--r-- | include/net/sock.h | 24 | ||||
| -rw-r--r-- | include/net/tcp.h | 1 |
7 files changed, 161 insertions, 70 deletions
diff --git a/include/linux/errqueue.h b/include/linux/errqueue.h index 0d87e62ec9e7..174582fedb8b 100644 --- a/include/linux/errqueue.h +++ b/include/linux/errqueue.h @@ -22,6 +22,10 @@ struct sock_extended_err #ifdef __KERNEL__ #include <linux/config.h> +#include <net/ip.h> +#if defined(CONFIG_IPV6) || defined (CONFIG_IPV6_MODULE) +#include <linux/ipv6.h> +#endif #define SKB_EXT_ERR(skb) ((struct sock_exterr_skb *) ((skb)->cb)) diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h index c0af91ff4b1e..1b33d607f276 100644 --- a/include/linux/skbuff.h +++ b/include/linux/skbuff.h @@ -27,6 +27,7 @@ #include <linux/highmem.h> #include <linux/poll.h> #include <linux/net.h> +#include <net/checksum.h> #define HAVE_ALLOC_SKB /* For the drivers to know */ #define HAVE_ALIGNABLE_SKB /* Ditto 8) */ @@ -995,6 +996,39 @@ static inline struct sk_buff *skb_padto(struct sk_buff *skb, unsigned int len) return skb_pad(skb, len-size); } +static inline int skb_add_data(struct sk_buff *skb, + char __user *from, int copy) +{ + const int off = skb->len; + + if (skb->ip_summed == CHECKSUM_NONE) { + int err = 0; + unsigned int csum = csum_and_copy_from_user(from, + skb_put(skb, copy), + copy, 0, &err); + if (!err) { + skb->csum = csum_block_add(skb->csum, csum, off); + return 0; + } + } else if (!copy_from_user(skb_put(skb, copy), from, copy)) + return 0; + + __skb_trim(skb, off); + return -EFAULT; +} + +static inline int skb_can_coalesce(struct sk_buff *skb, int i, + struct page *page, int off) +{ + if (i) { + struct skb_frag_struct *frag = &skb_shinfo(skb)->frags[i - 1]; + + return page == frag->page && + off == frag->page_offset + frag->size; + } + return 0; +} + /** * skb_linearize - convert paged skb to linear one * @skb: buffer to linarize @@ -1058,6 +1092,8 @@ extern unsigned int skb_copy_and_csum_bits(const struct sk_buff *skb, int offset, u8 *to, int len, unsigned int csum); extern void skb_copy_and_csum_dev(const struct sk_buff *skb, u8 *to); +extern void skb_split(struct sk_buff *skb, + struct sk_buff *skb1, const u32 len); extern void skb_init(void); extern void skb_add_mtu(int mtu); diff --git a/include/net/checksum.h b/include/net/checksum.h index cd3c52a594e4..43f40235114e 100644 --- a/include/net/checksum.h +++ b/include/net/checksum.h @@ -16,83 +16,15 @@ * 2 of the License, or (at your option) any later version. */ -/* - * Fixes: - * - * Ralf Baechle : generic ipv6 checksum - * <ralf@waldorf-gmbh.de> - */ - #ifndef _CHECKSUM_H #define _CHECKSUM_H +#include <linux/errno.h> #include <asm/types.h> #include <asm/byteorder.h> -#include <net/ip.h> -#include <linux/in6.h> #include <asm/uaccess.h> #include <asm/checksum.h> -#ifndef _HAVE_ARCH_IPV6_CSUM - -static __inline__ unsigned short int csum_ipv6_magic(struct in6_addr *saddr, - struct in6_addr *daddr, - __u16 len, - unsigned short proto, - unsigned int csum) -{ - - int carry; - __u32 ulen; - __u32 uproto; - - csum += saddr->s6_addr32[0]; - carry = (csum < saddr->s6_addr32[0]); - csum += carry; - - csum += saddr->s6_addr32[1]; - carry = (csum < saddr->s6_addr32[1]); - csum += carry; - - csum += saddr->s6_addr32[2]; - carry = (csum < saddr->s6_addr32[2]); - csum += carry; - - csum += saddr->s6_addr32[3]; - carry = (csum < saddr->s6_addr32[3]); - csum += carry; - - csum += daddr->s6_addr32[0]; - carry = (csum < daddr->s6_addr32[0]); - csum += carry; - - csum += daddr->s6_addr32[1]; - carry = (csum < daddr->s6_addr32[1]); - csum += carry; - - csum += daddr->s6_addr32[2]; - carry = (csum < daddr->s6_addr32[2]); - csum += carry; - - csum += daddr->s6_addr32[3]; - carry = (csum < daddr->s6_addr32[3]); - csum += carry; - - ulen = htonl((__u32) len); - csum += ulen; - carry = (csum < ulen); - csum += carry; - - uproto = htonl(proto); - csum += uproto; - carry = (csum < uproto); - csum += carry; - - return csum_fold(csum); -} - -#endif - #ifndef _HAVE_ARCH_COPY_AND_CSUM_FROM_USER static inline unsigned int csum_and_copy_from_user (const char __user *src, char *dst, diff --git a/include/net/ip.h b/include/net/ip.h index 5a683ccd4cb0..d36a3b230819 100644 --- a/include/net/ip.h +++ b/include/net/ip.h @@ -37,7 +37,7 @@ #include <net/snmp.h> #endif -#include <net/sock.h> /* struct sock */ +struct sock; struct inet_skb_parm { diff --git a/include/net/ip6_checksum.h b/include/net/ip6_checksum.h new file mode 100644 index 000000000000..3dfc885bdf25 --- /dev/null +++ b/include/net/ip6_checksum.h @@ -0,0 +1,94 @@ +/* + * INET An implementation of the TCP/IP protocol suite for the LINUX + * operating system. INET is implemented using the BSD Socket + * interface as the means of communication with the user level. + * + * Checksumming functions for IPv6 + * + * Authors: Jorge Cwik, <jorge@laser.satlink.net> + * Arnt Gulbrandsen, <agulbra@nvg.unit.no> + * Borrows very liberally from tcp.c and ip.c, see those + * files for more names. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version + * 2 of the License, or (at your option) any later version. + */ + +/* + * Fixes: + * + * Ralf Baechle : generic ipv6 checksum + * <ralf@waldorf-gmbh.de> + */ + +#ifndef _CHECKSUM_IPV6_H +#define _CHECKSUM_IPV6_H + +#include <asm/types.h> +#include <asm/byteorder.h> +#include <net/ip.h> +#include <asm/checksum.h> +#include <linux/in6.h> + +#ifndef _HAVE_ARCH_IPV6_CSUM + +static __inline__ unsigned short int csum_ipv6_magic(struct in6_addr *saddr, + struct in6_addr *daddr, + __u16 len, + unsigned short proto, + unsigned int csum) +{ + + int carry; + __u32 ulen; + __u32 uproto; + + csum += saddr->s6_addr32[0]; + carry = (csum < saddr->s6_addr32[0]); + csum += carry; + + csum += saddr->s6_addr32[1]; + carry = (csum < saddr->s6_addr32[1]); + csum += carry; + + csum += saddr->s6_addr32[2]; + carry = (csum < saddr->s6_addr32[2]); + csum += carry; + + csum += saddr->s6_addr32[3]; + carry = (csum < saddr->s6_addr32[3]); + csum += carry; + + csum += daddr->s6_addr32[0]; + carry = (csum < daddr->s6_addr32[0]); + csum += carry; + + csum += daddr->s6_addr32[1]; + carry = (csum < daddr->s6_addr32[1]); + csum += carry; + + csum += daddr->s6_addr32[2]; + carry = (csum < daddr->s6_addr32[2]); + csum += carry; + + csum += daddr->s6_addr32[3]; + carry = (csum < daddr->s6_addr32[3]); + csum += carry; + + ulen = htonl((__u32) len); + csum += ulen; + carry = (csum < ulen); + csum += carry; + + uproto = htonl(proto); + csum += uproto; + carry = (csum < uproto); + csum += carry; + + return csum_fold(csum); +} + +#endif +#endif diff --git a/include/net/sock.h b/include/net/sock.h index 38b90c8ab25f..5624b084742f 100644 --- a/include/net/sock.h +++ b/include/net/sock.h @@ -53,6 +53,7 @@ #include <asm/atomic.h> #include <net/dst.h> +#include <net/checksum.h> /* * This structure really needs to be cleaned up. @@ -923,6 +924,29 @@ static inline void sk_charge_skb(struct sock *sk, struct sk_buff *skb) sk->sk_forward_alloc -= skb->truesize; } +static inline int skb_copy_to_page(struct sock *sk, char __user *from, + struct sk_buff *skb, struct page *page, + int off, int copy) +{ + if (skb->ip_summed == CHECKSUM_NONE) { + int err = 0; + unsigned int csum = csum_and_copy_from_user(from, + page_address(page) + off, + copy, 0, &err); + if (err) + return err; + skb->csum = csum_block_add(skb->csum, csum, skb->len); + } else if (copy_from_user(page_address(page) + off, from, copy)) + return -EFAULT; + + skb->len += copy; + skb->data_len += copy; + skb->truesize += copy; + sk->sk_wmem_queued += copy; + sk->sk_forward_alloc -= copy; + return 0; +} + /* * Queue a received datagram if it will fit. Stream and sequenced * protocols can't normally use this as they need to fit buffers in diff --git a/include/net/tcp.h b/include/net/tcp.h index 52f27edef69e..3a323cd1e79f 100644 --- a/include/net/tcp.h +++ b/include/net/tcp.h @@ -33,6 +33,7 @@ #include <net/checksum.h> #include <net/sock.h> #include <net/snmp.h> +#include <net/ip.h> #if defined(CONFIG_IPV6) || defined (CONFIG_IPV6_MODULE) #include <linux/ipv6.h> #endif |
