Skip to content

Commit 80b14de

Browse files
Richard Cochrandavem330
authored andcommitted
net: Add a new socket option for a future transmit time.
This patch introduces SO_TXTIME. User space enables this option in order to pass a desired future transmit time in a CMSG when calling sendmsg(2). The argument to this socket option is a 8-bytes long struct provided by the uapi header net_tstamp.h defined as: struct sock_txtime { clockid_t clockid; u32 flags; }; Note that new fields were added to struct sock by filling a 2-bytes hole found in the struct. For that reason, neither the struct size or number of cachelines were altered. Signed-off-by: Richard Cochran <rcochran@linutronix.de> Signed-off-by: Jesus Sanchez-Palencia <jesus.sanchez-palencia@intel.com> Signed-off-by: David S. Miller <davem@davemloft.net>
1 parent c47d8c2 commit 80b14de

File tree

11 files changed

+84
-0
lines changed

11 files changed

+84
-0
lines changed

arch/alpha/include/uapi/asm/socket.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -112,4 +112,7 @@
112112

113113
#define SO_ZEROCOPY 60
114114

115+
#define SO_TXTIME 61
116+
#define SCM_TXTIME SO_TXTIME
117+
115118
#endif /* _UAPI_ASM_SOCKET_H */

arch/ia64/include/uapi/asm/socket.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -114,4 +114,7 @@
114114

115115
#define SO_ZEROCOPY 60
116116

117+
#define SO_TXTIME 61
118+
#define SCM_TXTIME SO_TXTIME
119+
117120
#endif /* _ASM_IA64_SOCKET_H */

arch/mips/include/uapi/asm/socket.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -123,4 +123,7 @@
123123

124124
#define SO_ZEROCOPY 60
125125

126+
#define SO_TXTIME 61
127+
#define SCM_TXTIME SO_TXTIME
128+
126129
#endif /* _UAPI_ASM_SOCKET_H */

arch/parisc/include/uapi/asm/socket.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -104,4 +104,7 @@
104104

105105
#define SO_ZEROCOPY 0x4035
106106

107+
#define SO_TXTIME 0x4036
108+
#define SCM_TXTIME SO_TXTIME
109+
107110
#endif /* _UAPI_ASM_SOCKET_H */

arch/s390/include/uapi/asm/socket.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -111,4 +111,7 @@
111111

112112
#define SO_ZEROCOPY 60
113113

114+
#define SO_TXTIME 61
115+
#define SCM_TXTIME SO_TXTIME
116+
114117
#endif /* _ASM_SOCKET_H */

arch/sparc/include/uapi/asm/socket.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,9 @@
101101

102102
#define SO_ZEROCOPY 0x003e
103103

104+
#define SO_TXTIME 0x003f
105+
#define SCM_TXTIME SO_TXTIME
106+
104107
/* Security levels - as per NRL IPv6 - don't actually do anything */
105108
#define SO_SECURITY_AUTHENTICATION 0x5001
106109
#define SO_SECURITY_ENCRYPTION_TRANSPORT 0x5002

arch/xtensa/include/uapi/asm/socket.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -116,4 +116,7 @@
116116

117117
#define SO_ZEROCOPY 60
118118

119+
#define SO_TXTIME 61
120+
#define SCM_TXTIME SO_TXTIME
121+
119122
#endif /* _XTENSA_SOCKET_H */

include/net/sock.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -319,6 +319,9 @@ struct sock_common {
319319
* @sk_destruct: called at sock freeing time, i.e. when all refcnt == 0
320320
* @sk_reuseport_cb: reuseport group container
321321
* @sk_rcu: used during RCU grace period
322+
* @sk_clockid: clockid used by time-based scheduling (SO_TXTIME)
323+
* @sk_txtime_deadline_mode: set deadline mode for SO_TXTIME
324+
* @sk_txtime_unused: unused txtime flags
322325
*/
323326
struct sock {
324327
/*
@@ -475,6 +478,11 @@ struct sock {
475478
u8 sk_shutdown;
476479
u32 sk_tskey;
477480
atomic_t sk_zckey;
481+
482+
u8 sk_clockid;
483+
u8 sk_txtime_deadline_mode : 1,
484+
sk_txtime_unused : 7;
485+
478486
struct socket *sk_socket;
479487
void *sk_user_data;
480488
#ifdef CONFIG_SECURITY
@@ -790,6 +798,7 @@ enum sock_flags {
790798
SOCK_FILTER_LOCKED, /* Filter cannot be changed anymore */
791799
SOCK_SELECT_ERR_QUEUE, /* Wake select on error queue */
792800
SOCK_RCU_FREE, /* wait rcu grace period in sk_destruct() */
801+
SOCK_TXTIME,
793802
};
794803

795804
#define SK_FLAGS_TIMESTAMP ((1UL << SOCK_TIMESTAMP) | (1UL << SOCK_TIMESTAMPING_RX_SOFTWARE))
@@ -1585,6 +1594,7 @@ void sock_kzfree_s(struct sock *sk, void *mem, int size);
15851594
void sk_send_sigurg(struct sock *sk);
15861595

15871596
struct sockcm_cookie {
1597+
u64 transmit_time;
15881598
u32 mark;
15891599
u16 tsflags;
15901600
};

include/uapi/asm-generic/socket.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -107,4 +107,7 @@
107107

108108
#define SO_ZEROCOPY 60
109109

110+
#define SO_TXTIME 61
111+
#define SCM_TXTIME SO_TXTIME
112+
110113
#endif /* __ASM_GENERIC_SOCKET_H */

include/uapi/linux/net_tstamp.h

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -141,4 +141,19 @@ struct scm_ts_pktinfo {
141141
__u32 reserved[2];
142142
};
143143

144+
/*
145+
* SO_TXTIME gets a struct sock_txtime with flags being an integer bit
146+
* field comprised of these values.
147+
*/
148+
enum txtime_flags {
149+
SOF_TXTIME_DEADLINE_MODE = (1 << 0),
150+
151+
SOF_TXTIME_FLAGS_MASK = (SOF_TXTIME_DEADLINE_MODE)
152+
};
153+
154+
struct sock_txtime {
155+
clockid_t clockid; /* reference clockid */
156+
u32 flags; /* flags defined by enum txtime_flags */
157+
};
158+
144159
#endif /* _NET_TIMESTAMPING_H */

net/core/sock.c

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,7 @@
9191

9292
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
9393

94+
#include <asm/unaligned.h>
9495
#include <linux/capability.h>
9596
#include <linux/errno.h>
9697
#include <linux/errqueue.h>
@@ -697,6 +698,7 @@ EXPORT_SYMBOL(sk_mc_loop);
697698
int sock_setsockopt(struct socket *sock, int level, int optname,
698699
char __user *optval, unsigned int optlen)
699700
{
701+
struct sock_txtime sk_txtime;
700702
struct sock *sk = sock->sk;
701703
int val;
702704
int valbool;
@@ -1070,6 +1072,24 @@ int sock_setsockopt(struct socket *sock, int level, int optname,
10701072
}
10711073
break;
10721074

1075+
case SO_TXTIME:
1076+
if (!ns_capable(sock_net(sk)->user_ns, CAP_NET_ADMIN)) {
1077+
ret = -EPERM;
1078+
} else if (optlen != sizeof(struct sock_txtime)) {
1079+
ret = -EINVAL;
1080+
} else if (copy_from_user(&sk_txtime, optval,
1081+
sizeof(struct sock_txtime))) {
1082+
ret = -EFAULT;
1083+
} else if (sk_txtime.flags & ~SOF_TXTIME_FLAGS_MASK) {
1084+
ret = -EINVAL;
1085+
} else {
1086+
sock_valbool_flag(sk, SOCK_TXTIME, true);
1087+
sk->sk_clockid = sk_txtime.clockid;
1088+
sk->sk_txtime_deadline_mode =
1089+
!!(sk_txtime.flags & SOF_TXTIME_DEADLINE_MODE);
1090+
}
1091+
break;
1092+
10731093
default:
10741094
ret = -ENOPROTOOPT;
10751095
break;
@@ -1115,6 +1135,7 @@ int sock_getsockopt(struct socket *sock, int level, int optname,
11151135
u64 val64;
11161136
struct linger ling;
11171137
struct timeval tm;
1138+
struct sock_txtime txtime;
11181139
} v;
11191140

11201141
int lv = sizeof(int);
@@ -1403,6 +1424,13 @@ int sock_getsockopt(struct socket *sock, int level, int optname,
14031424
v.val = sock_flag(sk, SOCK_ZEROCOPY);
14041425
break;
14051426

1427+
case SO_TXTIME:
1428+
lv = sizeof(v.txtime);
1429+
v.txtime.clockid = sk->sk_clockid;
1430+
v.txtime.flags |= sk->sk_txtime_deadline_mode ?
1431+
SOF_TXTIME_DEADLINE_MODE : 0;
1432+
break;
1433+
14061434
default:
14071435
/* We implement the SO_SNDLOWAT etc to not be settable
14081436
* (1003.1g 7).
@@ -2137,6 +2165,13 @@ int __sock_cmsg_send(struct sock *sk, struct msghdr *msg, struct cmsghdr *cmsg,
21372165
sockc->tsflags &= ~SOF_TIMESTAMPING_TX_RECORD_MASK;
21382166
sockc->tsflags |= tsflags;
21392167
break;
2168+
case SCM_TXTIME:
2169+
if (!sock_flag(sk, SOCK_TXTIME))
2170+
return -EINVAL;
2171+
if (cmsg->cmsg_len != CMSG_LEN(sizeof(u64)))
2172+
return -EINVAL;
2173+
sockc->transmit_time = get_unaligned((u64 *)CMSG_DATA(cmsg));
2174+
break;
21402175
/* SCM_RIGHTS and SCM_CREDENTIALS are semantically in SOL_UNIX. */
21412176
case SCM_RIGHTS:
21422177
case SCM_CREDENTIALS:

0 commit comments

Comments
 (0)