#include <linux/proc_fs.h>
#include <linux/seq_file.h>
#include <linux/mutex.h>
-#include <linux/thread_info.h>
#include <linux/wanrouter.h>
#include <linux/if_bridge.h>
#include <linux/if_frad.h>
sock = SOCKET_I(inode);
inode->i_mode = S_IFSOCK | S_IRWXUGO;
- inode->i_uid = current->fsuid;
- inode->i_gid = current->fsgid;
+ inode->i_uid = current_fsuid();
+ inode->i_gid = current_fsgid();
get_cpu_var(sockets_in_use)++;
put_cpu_var(sockets_in_use);
sock->file = NULL;
}
+int sock_tx_timestamp(struct msghdr *msg, struct sock *sk,
+ union skb_shared_tx *shtx)
+{
+ shtx->flags = 0;
+ if (sock_flag(sk, SOCK_TIMESTAMPING_TX_HARDWARE))
+ shtx->hardware = 1;
+ if (sock_flag(sk, SOCK_TIMESTAMPING_TX_SOFTWARE))
+ shtx->software = 1;
+ return 0;
+}
+EXPORT_SYMBOL(sock_tx_timestamp);
+
static inline int __sock_sendmsg(struct kiocb *iocb, struct socket *sock,
struct msghdr *msg, size_t size)
{
return result;
}
+static int ktime2ts(ktime_t kt, struct timespec *ts)
+{
+ if (kt.tv64) {
+ *ts = ktime_to_timespec(kt);
+ return 1;
+ } else {
+ return 0;
+ }
+}
+
/*
* called from sock_recv_timestamp() if sock_flag(sk, SOCK_RCVTSTAMP)
*/
void __sock_recv_timestamp(struct msghdr *msg, struct sock *sk,
struct sk_buff *skb)
{
- ktime_t kt = skb->tstamp;
-
- if (!sock_flag(sk, SOCK_RCVTSTAMPNS)) {
- struct timeval tv;
- /* Race occurred between timestamp enabling and packet
- receiving. Fill in the current time for now. */
- if (kt.tv64 == 0)
- kt = ktime_get_real();
- skb->tstamp = kt;
- tv = ktime_to_timeval(kt);
- put_cmsg(msg, SOL_SOCKET, SCM_TIMESTAMP, sizeof(tv), &tv);
- } else {
- struct timespec ts;
- /* Race occurred between timestamp enabling and packet
- receiving. Fill in the current time for now. */
- if (kt.tv64 == 0)
- kt = ktime_get_real();
- skb->tstamp = kt;
- ts = ktime_to_timespec(kt);
- put_cmsg(msg, SOL_SOCKET, SCM_TIMESTAMPNS, sizeof(ts), &ts);
+ int need_software_tstamp = sock_flag(sk, SOCK_RCVTSTAMP);
+ struct timespec ts[3];
+ int empty = 1;
+ struct skb_shared_hwtstamps *shhwtstamps =
+ skb_hwtstamps(skb);
+
+ /* Race occurred between timestamp enabling and packet
+ receiving. Fill in the current time for now. */
+ if (need_software_tstamp && skb->tstamp.tv64 == 0)
+ __net_timestamp(skb);
+
+ if (need_software_tstamp) {
+ if (!sock_flag(sk, SOCK_RCVTSTAMPNS)) {
+ struct timeval tv;
+ skb_get_timestamp(skb, &tv);
+ put_cmsg(msg, SOL_SOCKET, SCM_TIMESTAMP,
+ sizeof(tv), &tv);
+ } else {
+ struct timespec ts;
+ skb_get_timestampns(skb, &ts);
+ put_cmsg(msg, SOL_SOCKET, SCM_TIMESTAMPNS,
+ sizeof(ts), &ts);
+ }
}
+
+
+ memset(ts, 0, sizeof(ts));
+ if (skb->tstamp.tv64 &&
+ sock_flag(sk, SOCK_TIMESTAMPING_SOFTWARE)) {
+ skb_get_timestampns(skb, ts + 0);
+ empty = 0;
+ }
+ if (shhwtstamps) {
+ if (sock_flag(sk, SOCK_TIMESTAMPING_SYS_HARDWARE) &&
+ ktime2ts(shhwtstamps->syststamp, ts + 1))
+ empty = 0;
+ if (sock_flag(sk, SOCK_TIMESTAMPING_RAW_HARDWARE) &&
+ ktime2ts(shhwtstamps->hwtstamp, ts + 2))
+ empty = 0;
+ }
+ if (!empty)
+ put_cmsg(msg, SOL_SOCKET,
+ SCM_TIMESTAMPING, sizeof(ts), &ts);
}
EXPORT_SYMBOL_GPL(__sock_recv_timestamp);
return __sock_create(&init_net, family, type, protocol, res, 1);
}
-asmlinkage long sys_socket(int family, int type, int protocol)
+SYSCALL_DEFINE3(socket, int, family, int, type, int, protocol)
{
int retval;
struct socket *sock;
* Create a pair of connected sockets.
*/
-asmlinkage long sys_socketpair(int family, int type, int protocol,
- int __user *usockvec)
+SYSCALL_DEFINE4(socketpair, int, family, int, type, int, protocol,
+ int __user *, usockvec)
{
struct socket *sock1, *sock2;
int fd1, fd2, err;
goto out_fd1;
}
- err = audit_fd_pair(fd1, fd2);
- if (err < 0) {
- fput(newfile1);
- fput(newfile2);
- goto out_fd;
- }
-
+ audit_fd_pair(fd1, fd2);
fd_install(fd1, newfile1);
fd_install(fd2, newfile2);
/* fd1 and fd2 may be already another descriptors.
out_fd1:
put_filp(newfile2);
sock_release(sock2);
-out_fd:
put_unused_fd(fd1);
put_unused_fd(fd2);
goto out;
* the protocol layer (having also checked the address is ok).
*/
-asmlinkage long sys_bind(int fd, struct sockaddr __user *umyaddr, int addrlen)
+SYSCALL_DEFINE3(bind, int, fd, struct sockaddr __user *, umyaddr, int, addrlen)
{
struct socket *sock;
struct sockaddr_storage address;
* ready for listening.
*/
-asmlinkage long sys_listen(int fd, int backlog)
+SYSCALL_DEFINE2(listen, int, fd, int, backlog)
{
struct socket *sock;
int err, fput_needed;
* clean when we restucture accept also.
*/
-asmlinkage long sys_accept4(int fd, struct sockaddr __user *upeer_sockaddr,
- int __user *upeer_addrlen, int flags)
+SYSCALL_DEFINE4(accept4, int, fd, struct sockaddr __user *, upeer_sockaddr,
+ int __user *, upeer_addrlen, int, flags)
{
struct socket *sock, *newsock;
struct file *newfile;
goto out_put;
}
-asmlinkage long sys_accept(int fd, struct sockaddr __user *upeer_sockaddr,
- int __user *upeer_addrlen)
+SYSCALL_DEFINE3(accept, int, fd, struct sockaddr __user *, upeer_sockaddr,
+ int __user *, upeer_addrlen)
{
return sys_accept4(fd, upeer_sockaddr, upeer_addrlen, 0);
}
* include the -EINPROGRESS status for such sockets.
*/
-asmlinkage long sys_connect(int fd, struct sockaddr __user *uservaddr,
- int addrlen)
+SYSCALL_DEFINE3(connect, int, fd, struct sockaddr __user *, uservaddr,
+ int, addrlen)
{
struct socket *sock;
struct sockaddr_storage address;
* name to user space.
*/
-asmlinkage long sys_getsockname(int fd, struct sockaddr __user *usockaddr,
- int __user *usockaddr_len)
+SYSCALL_DEFINE3(getsockname, int, fd, struct sockaddr __user *, usockaddr,
+ int __user *, usockaddr_len)
{
struct socket *sock;
struct sockaddr_storage address;
* name to user space.
*/
-asmlinkage long sys_getpeername(int fd, struct sockaddr __user *usockaddr,
- int __user *usockaddr_len)
+SYSCALL_DEFINE3(getpeername, int, fd, struct sockaddr __user *, usockaddr,
+ int __user *, usockaddr_len)
{
struct socket *sock;
struct sockaddr_storage address;
* the protocol.
*/
-asmlinkage long sys_sendto(int fd, void __user *buff, size_t len,
- unsigned flags, struct sockaddr __user *addr,
- int addr_len)
+SYSCALL_DEFINE6(sendto, int, fd, void __user *, buff, size_t, len,
+ unsigned, flags, struct sockaddr __user *, addr,
+ int, addr_len)
{
struct socket *sock;
struct sockaddr_storage address;
* Send a datagram down a socket.
*/
-asmlinkage long sys_send(int fd, void __user *buff, size_t len, unsigned flags)
+SYSCALL_DEFINE4(send, int, fd, void __user *, buff, size_t, len,
+ unsigned, flags)
{
return sys_sendto(fd, buff, len, flags, NULL, 0);
}
* sender address from kernel to user space.
*/
-asmlinkage long sys_recvfrom(int fd, void __user *ubuf, size_t size,
- unsigned flags, struct sockaddr __user *addr,
- int __user *addr_len)
+SYSCALL_DEFINE6(recvfrom, int, fd, void __user *, ubuf, size_t, size,
+ unsigned, flags, struct sockaddr __user *, addr,
+ int __user *, addr_len)
{
struct socket *sock;
struct iovec iov;
* to pass the user mode parameter for the protocols to sort out.
*/
-asmlinkage long sys_setsockopt(int fd, int level, int optname,
- char __user *optval, int optlen)
+SYSCALL_DEFINE5(setsockopt, int, fd, int, level, int, optname,
+ char __user *, optval, int, optlen)
{
int err, fput_needed;
struct socket *sock;
* to pass a user mode parameter for the protocols to sort out.
*/
-asmlinkage long sys_getsockopt(int fd, int level, int optname,
- char __user *optval, int __user *optlen)
+SYSCALL_DEFINE5(getsockopt, int, fd, int, level, int, optname,
+ char __user *, optval, int __user *, optlen)
{
int err, fput_needed;
struct socket *sock;
* Shutdown a socket.
*/
-asmlinkage long sys_shutdown(int fd, int how)
+SYSCALL_DEFINE2(shutdown, int, fd, int, how)
{
int err, fput_needed;
struct socket *sock;
* BSD sendmsg interface
*/
-asmlinkage long sys_sendmsg(int fd, struct msghdr __user *msg, unsigned flags)
+SYSCALL_DEFINE3(sendmsg, int, fd, struct msghdr __user *, msg, unsigned, flags)
{
struct compat_msghdr __user *msg_compat =
(struct compat_msghdr __user *)msg;
* BSD recvmsg interface
*/
-asmlinkage long sys_recvmsg(int fd, struct msghdr __user *msg,
- unsigned int flags)
+SYSCALL_DEFINE3(recvmsg, int, fd, struct msghdr __user *, msg,
+ unsigned int, flags)
{
struct compat_msghdr __user *msg_compat =
(struct compat_msghdr __user *)msg;
* it is set by the callees.
*/
-asmlinkage long sys_socketcall(int call, unsigned long __user *args)
+SYSCALL_DEFINE2(socketcall, int, call, unsigned long __user *, args)
{
unsigned long a[6];
unsigned long a0, a1;
if (copy_from_user(a, args, nargs[call]))
return -EFAULT;
- err = audit_socketcall(nargs[call] / sizeof(unsigned long), a);
- if (err)
- return err;
+ audit_socketcall(nargs[call] / sizeof(unsigned long), a);
a0 = a[0];
a1 = a[1];