aboutsummaryrefslogtreecommitdiffstats
path: root/net/socket.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2012-10-02 16:38:27 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2012-10-02 16:38:27 -0400
commitaecdc33e111b2c447b622e287c6003726daa1426 (patch)
tree3e7657eae4b785e1a1fb5dfb225dbae0b2f0cfc6 /net/socket.c
parenta20acf99f75e49271381d65db097c9763060a1e8 (diff)
parenta3a6cab5ea10cca64d036851fe0d932448f2fe4f (diff)
Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-next
Pull networking changes from David Miller: 1) GRE now works over ipv6, from Dmitry Kozlov. 2) Make SCTP more network namespace aware, from Eric Biederman. 3) TEAM driver now works with non-ethernet devices, from Jiri Pirko. 4) Make openvswitch network namespace aware, from Pravin B Shelar. 5) IPV6 NAT implementation, from Patrick McHardy. 6) Server side support for TCP Fast Open, from Jerry Chu and others. 7) Packet BPF filter supports MOD and XOR, from Eric Dumazet and Daniel Borkmann. 8) Increate the loopback default MTU to 64K, from Eric Dumazet. 9) Use a per-task rather than per-socket page fragment allocator for outgoing networking traffic. This benefits processes that have very many mostly idle sockets, which is quite common. From Eric Dumazet. 10) Use up to 32K for page fragment allocations, with fallbacks to smaller sizes when higher order page allocations fail. Benefits are a) less segments for driver to process b) less calls to page allocator c) less waste of space. From Eric Dumazet. 11) Allow GRO to be used on GRE tunnels, from Eric Dumazet. 12) VXLAN device driver, one way to handle VLAN issues such as the limitation of 4096 VLAN IDs yet still have some level of isolation. From Stephen Hemminger. 13) As usual there is a large boatload of driver changes, with the scale perhaps tilted towards the wireless side this time around. Fix up various fairly trivial conflicts, mostly caused by the user namespace changes. * git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-next: (1012 commits) hyperv: Add buffer for extended info after the RNDIS response message. hyperv: Report actual status in receive completion packet hyperv: Remove extra allocated space for recv_pkt_list elements hyperv: Fix page buffer handling in rndis_filter_send_request() hyperv: Fix the missing return value in rndis_filter_set_packet_filter() hyperv: Fix the max_xfer_size in RNDIS initialization vxlan: put UDP socket in correct namespace vxlan: Depend on CONFIG_INET sfc: Fix the reported priorities of different filter types sfc: Remove EFX_FILTER_FLAG_RX_OVERRIDE_IP sfc: Fix loopback self-test with separate_tx_channels=1 sfc: Fix MCDI structure field lookup sfc: Add parentheses around use of bitfield macro arguments sfc: Fix null function pointer in efx_sriov_channel_type vxlan: virtual extensible lan igmp: export symbol ip_mc_leave_group netlink: add attributes to fdb interface tg3: unconditionally select HWMON support when tg3 is enabled. Revert "net: ti cpsw ethernet: allow reading phy interface mode from DT" gre: fix sparse warning ...
Diffstat (limited to 'net/socket.c')
-rw-r--r--net/socket.c89
1 files changed, 78 insertions, 11 deletions
diff --git a/net/socket.c b/net/socket.c
index edc3c4af9085..80dc7e84b046 100644
--- a/net/socket.c
+++ b/net/socket.c
@@ -88,6 +88,7 @@
88#include <linux/nsproxy.h> 88#include <linux/nsproxy.h>
89#include <linux/magic.h> 89#include <linux/magic.h>
90#include <linux/slab.h> 90#include <linux/slab.h>
91#include <linux/xattr.h>
91 92
92#include <asm/uaccess.h> 93#include <asm/uaccess.h>
93#include <asm/unistd.h> 94#include <asm/unistd.h>
@@ -346,7 +347,8 @@ static struct file_system_type sock_fs_type = {
346 * but we take care of internal coherence yet. 347 * but we take care of internal coherence yet.
347 */ 348 */
348 349
349static int sock_alloc_file(struct socket *sock, struct file **f, int flags) 350static int sock_alloc_file(struct socket *sock, struct file **f, int flags,
351 const char *dname)
350{ 352{
351 struct qstr name = { .name = "" }; 353 struct qstr name = { .name = "" };
352 struct path path; 354 struct path path;
@@ -357,6 +359,13 @@ static int sock_alloc_file(struct socket *sock, struct file **f, int flags)
357 if (unlikely(fd < 0)) 359 if (unlikely(fd < 0))
358 return fd; 360 return fd;
359 361
362 if (dname) {
363 name.name = dname;
364 name.len = strlen(name.name);
365 } else if (sock->sk) {
366 name.name = sock->sk->sk_prot_creator->name;
367 name.len = strlen(name.name);
368 }
360 path.dentry = d_alloc_pseudo(sock_mnt->mnt_sb, &name); 369 path.dentry = d_alloc_pseudo(sock_mnt->mnt_sb, &name);
361 if (unlikely(!path.dentry)) { 370 if (unlikely(!path.dentry)) {
362 put_unused_fd(fd); 371 put_unused_fd(fd);
@@ -389,7 +398,7 @@ static int sock_alloc_file(struct socket *sock, struct file **f, int flags)
389int sock_map_fd(struct socket *sock, int flags) 398int sock_map_fd(struct socket *sock, int flags)
390{ 399{
391 struct file *newfile; 400 struct file *newfile;
392 int fd = sock_alloc_file(sock, &newfile, flags); 401 int fd = sock_alloc_file(sock, &newfile, flags, NULL);
393 402
394 if (likely(fd >= 0)) 403 if (likely(fd >= 0))
395 fd_install(fd, newfile); 404 fd_install(fd, newfile);
@@ -455,6 +464,68 @@ static struct socket *sockfd_lookup_light(int fd, int *err, int *fput_needed)
455 return NULL; 464 return NULL;
456} 465}
457 466
467#define XATTR_SOCKPROTONAME_SUFFIX "sockprotoname"
468#define XATTR_NAME_SOCKPROTONAME (XATTR_SYSTEM_PREFIX XATTR_SOCKPROTONAME_SUFFIX)
469#define XATTR_NAME_SOCKPROTONAME_LEN (sizeof(XATTR_NAME_SOCKPROTONAME)-1)
470static ssize_t sockfs_getxattr(struct dentry *dentry,
471 const char *name, void *value, size_t size)
472{
473 const char *proto_name;
474 size_t proto_size;
475 int error;
476
477 error = -ENODATA;
478 if (!strncmp(name, XATTR_NAME_SOCKPROTONAME, XATTR_NAME_SOCKPROTONAME_LEN)) {
479 proto_name = dentry->d_name.name;
480 proto_size = strlen(proto_name);
481
482 if (value) {
483 error = -ERANGE;
484 if (proto_size + 1 > size)
485 goto out;
486
487 strncpy(value, proto_name, proto_size + 1);
488 }
489 error = proto_size + 1;
490 }
491
492out:
493 return error;
494}
495
496static ssize_t sockfs_listxattr(struct dentry *dentry, char *buffer,
497 size_t size)
498{
499 ssize_t len;
500 ssize_t used = 0;
501
502 len = security_inode_listsecurity(dentry->d_inode, buffer, size);
503 if (len < 0)
504 return len;
505 used += len;
506 if (buffer) {
507 if (size < used)
508 return -ERANGE;
509 buffer += len;
510 }
511
512 len = (XATTR_NAME_SOCKPROTONAME_LEN + 1);
513 used += len;
514 if (buffer) {
515 if (size < used)
516 return -ERANGE;
517 memcpy(buffer, XATTR_NAME_SOCKPROTONAME, len);
518 buffer += len;
519 }
520
521 return used;
522}
523
524static const struct inode_operations sockfs_inode_ops = {
525 .getxattr = sockfs_getxattr,
526 .listxattr = sockfs_listxattr,
527};
528
458/** 529/**
459 * sock_alloc - allocate a socket 530 * sock_alloc - allocate a socket
460 * 531 *
@@ -479,6 +550,7 @@ static struct socket *sock_alloc(void)
479 inode->i_mode = S_IFSOCK | S_IRWXUGO; 550 inode->i_mode = S_IFSOCK | S_IRWXUGO;
480 inode->i_uid = current_fsuid(); 551 inode->i_uid = current_fsuid();
481 inode->i_gid = current_fsgid(); 552 inode->i_gid = current_fsgid();
553 inode->i_op = &sockfs_inode_ops;
482 554
483 this_cpu_add(sockets_in_use, 1); 555 this_cpu_add(sockets_in_use, 1);
484 return sock; 556 return sock;
@@ -1394,13 +1466,13 @@ SYSCALL_DEFINE4(socketpair, int, family, int, type, int, protocol,
1394 if (err < 0) 1466 if (err < 0)
1395 goto out_release_both; 1467 goto out_release_both;
1396 1468
1397 fd1 = sock_alloc_file(sock1, &newfile1, flags); 1469 fd1 = sock_alloc_file(sock1, &newfile1, flags, NULL);
1398 if (unlikely(fd1 < 0)) { 1470 if (unlikely(fd1 < 0)) {
1399 err = fd1; 1471 err = fd1;
1400 goto out_release_both; 1472 goto out_release_both;
1401 } 1473 }
1402 1474
1403 fd2 = sock_alloc_file(sock2, &newfile2, flags); 1475 fd2 = sock_alloc_file(sock2, &newfile2, flags, NULL);
1404 if (unlikely(fd2 < 0)) { 1476 if (unlikely(fd2 < 0)) {
1405 err = fd2; 1477 err = fd2;
1406 fput(newfile1); 1478 fput(newfile1);
@@ -1536,7 +1608,8 @@ SYSCALL_DEFINE4(accept4, int, fd, struct sockaddr __user *, upeer_sockaddr,
1536 */ 1608 */
1537 __module_get(newsock->ops->owner); 1609 __module_get(newsock->ops->owner);
1538 1610
1539 newfd = sock_alloc_file(newsock, &newfile, flags); 1611 newfd = sock_alloc_file(newsock, &newfile, flags,
1612 sock->sk->sk_prot_creator->name);
1540 if (unlikely(newfd < 0)) { 1613 if (unlikely(newfd < 0)) {
1541 err = newfd; 1614 err = newfd;
1542 sock_release(newsock); 1615 sock_release(newsock);
@@ -2528,12 +2601,6 @@ static int __init sock_init(void)
2528 goto out; 2601 goto out;
2529 2602
2530 /* 2603 /*
2531 * Initialize sock SLAB cache.
2532 */
2533
2534 sk_init();
2535
2536 /*
2537 * Initialize skbuff SLAB cache 2604 * Initialize skbuff SLAB cache
2538 */ 2605 */
2539 skb_init(); 2606 skb_init();