summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEric Dumazet <edumazet@google.com>2019-02-28 15:17:28 -0800
committerDavid S. Miller <davem@davemloft.net>2019-03-01 23:08:30 -0800
commit677f136c6b88ac09a5b1c84dc4473e5901cf218b (patch)
treeee7160784b8e3eca7187baa41bc586debd9c7143
parent6bdef102dae9d24d8eafc9ddfd2bf94a67be3bdc (diff)
downloadlinux-677f136c6b88ac09a5b1c84dc4473e5901cf218b.tar.bz2
net: support 64bit rates for getsockopt(SO_MAX_PACING_RATE)
For legacy applications using 32bit variable, SO_MAX_PACING_RATE has to cap the returned value to 0xFFFFFFFF, meaning that rates above 34.35 Gbit are capped. This patch allows applications to read socket pacing rate at full resolution, if they provide a 64bit variable to store it, and the kernel is 64bit. Signed-off-by: Eric Dumazet <edumazet@google.com> Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--net/core/sock.c10
1 files changed, 8 insertions, 2 deletions
diff --git a/net/core/sock.c b/net/core/sock.c
index 23aa02ffd6b8..782343bb925b 100644
--- a/net/core/sock.c
+++ b/net/core/sock.c
@@ -1219,6 +1219,7 @@ int sock_getsockopt(struct socket *sock, int level, int optname,
union {
int val;
u64 val64;
+ unsigned long ulval;
struct linger ling;
struct old_timeval32 tm32;
struct __kernel_old_timeval tm;
@@ -1464,8 +1465,13 @@ int sock_getsockopt(struct socket *sock, int level, int optname,
#endif
case SO_MAX_PACING_RATE:
- /* 32bit version */
- v.val = min_t(unsigned long, sk->sk_max_pacing_rate, ~0U);
+ if (sizeof(v.ulval) != sizeof(v.val) && len >= sizeof(v.ulval)) {
+ lv = sizeof(v.ulval);
+ v.ulval = sk->sk_max_pacing_rate;
+ } else {
+ /* 32bit version */
+ v.val = min_t(unsigned long, sk->sk_max_pacing_rate, ~0U);
+ }
break;
case SO_INCOMING_CPU: