aboutsummaryrefslogtreecommitdiffstats
path: root/include/net/sock.h
diff options
context:
space:
mode:
Diffstat (limited to 'include/net/sock.h')
-rw-r--r--include/net/sock.h55
1 files changed, 54 insertions, 1 deletions
diff --git a/include/net/sock.h b/include/net/sock.h
index 01810a3f19df..c0b938cb4b1a 100644
--- a/include/net/sock.h
+++ b/include/net/sock.h
@@ -52,6 +52,7 @@
52#include <linux/mm.h> 52#include <linux/mm.h>
53#include <linux/security.h> 53#include <linux/security.h>
54#include <linux/slab.h> 54#include <linux/slab.h>
55#include <linux/uaccess.h>
55 56
56#include <linux/filter.h> 57#include <linux/filter.h>
57#include <linux/rculist_nulls.h> 58#include <linux/rculist_nulls.h>
@@ -177,7 +178,6 @@ struct sock_common {
177 * @sk_dst_cache: destination cache 178 * @sk_dst_cache: destination cache
178 * @sk_dst_lock: destination cache lock 179 * @sk_dst_lock: destination cache lock
179 * @sk_policy: flow policy 180 * @sk_policy: flow policy
180 * @sk_rmem_alloc: receive queue bytes committed
181 * @sk_receive_queue: incoming packets 181 * @sk_receive_queue: incoming packets
182 * @sk_wmem_alloc: transmit queue bytes committed 182 * @sk_wmem_alloc: transmit queue bytes committed
183 * @sk_write_queue: Packet sending queue 183 * @sk_write_queue: Packet sending queue
@@ -1389,6 +1389,59 @@ static inline void sk_nocaps_add(struct sock *sk, int flags)
1389 sk->sk_route_caps &= ~flags; 1389 sk->sk_route_caps &= ~flags;
1390} 1390}
1391 1391
1392static inline int skb_do_copy_data_nocache(struct sock *sk, struct sk_buff *skb,
1393 char __user *from, char *to,
1394 int copy, int offset)
1395{
1396 if (skb->ip_summed == CHECKSUM_NONE) {
1397 int err = 0;
1398 __wsum csum = csum_and_copy_from_user(from, to, copy, 0, &err);
1399 if (err)
1400 return err;
1401 skb->csum = csum_block_add(skb->csum, csum, offset);
1402 } else if (sk->sk_route_caps & NETIF_F_NOCACHE_COPY) {
1403 if (!access_ok(VERIFY_READ, from, copy) ||
1404 __copy_from_user_nocache(to, from, copy))
1405 return -EFAULT;
1406 } else if (copy_from_user(to, from, copy))
1407 return -EFAULT;
1408
1409 return 0;
1410}
1411
1412static inline int skb_add_data_nocache(struct sock *sk, struct sk_buff *skb,
1413 char __user *from, int copy)
1414{
1415 int err, offset = skb->len;
1416
1417 err = skb_do_copy_data_nocache(sk, skb, from, skb_put(skb, copy),
1418 copy, offset);
1419 if (err)
1420 __skb_trim(skb, offset);
1421
1422 return err;
1423}
1424
1425static inline int skb_copy_to_page_nocache(struct sock *sk, char __user *from,
1426 struct sk_buff *skb,
1427 struct page *page,
1428 int off, int copy)
1429{
1430 int err;
1431
1432 err = skb_do_copy_data_nocache(sk, skb, from, page_address(page) + off,
1433 copy, skb->len);
1434 if (err)
1435 return err;
1436
1437 skb->len += copy;
1438 skb->data_len += copy;
1439 skb->truesize += copy;
1440 sk->sk_wmem_queued += copy;
1441 sk_mem_charge(sk, copy);
1442 return 0;
1443}
1444
1392static inline int skb_copy_to_page(struct sock *sk, char __user *from, 1445static inline int skb_copy_to_page(struct sock *sk, char __user *from,
1393 struct sk_buff *skb, struct page *page, 1446 struct sk_buff *skb, struct page *page,
1394 int off, int copy) 1447 int off, int copy)