summaryrefslogtreecommitdiff
path: root/include
diff options
context:
space:
mode:
authorDavid S. Miller <davem@nuts.davemloft.net>2004-06-20 02:38:03 -0700
committerDavid S. Miller <davem@nuts.davemloft.net>2004-06-20 02:38:03 -0700
commit40fe493622602e8ba438f227f30cd982a0e14979 (patch)
tree70c9b22dfc2277e5758284a7dc8b2bb48a5aacfa /include
parent85bed77bb232e5ee7ce6dccaf7c85ec656ebf9c9 (diff)
parent86adf644850fbbc3da6448e8e1a0e39fe755e8e9 (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.h4
-rw-r--r--include/linux/skbuff.h36
-rw-r--r--include/net/checksum.h70
-rw-r--r--include/net/ip.h2
-rw-r--r--include/net/ip6_checksum.h94
-rw-r--r--include/net/sock.h24
-rw-r--r--include/net/tcp.h1
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