Merge tag 'sched-urgent-2021-07-11' of git://git.kernel.org/pub/scm/linux/kernel...
[platform/kernel/linux-rpi.git] / net / core / sock.c
index 5ec90f9..ba1c0f7 100644 (file)
@@ -331,6 +331,22 @@ int __sk_backlog_rcv(struct sock *sk, struct sk_buff *skb)
 }
 EXPORT_SYMBOL(__sk_backlog_rcv);
 
+void sk_error_report(struct sock *sk)
+{
+       sk->sk_error_report(sk);
+
+       switch (sk->sk_family) {
+       case AF_INET:
+               fallthrough;
+       case AF_INET6:
+               trace_inet_sk_error_report(sk);
+               break;
+       default:
+               break;
+       }
+}
+EXPORT_SYMBOL(sk_error_report);
+
 static int sock_get_timeout(long timeo, void *optval, bool old_timeval)
 {
        struct __kernel_sock_timeval tv;
@@ -776,6 +792,58 @@ void sock_enable_timestamps(struct sock *sk)
 }
 EXPORT_SYMBOL(sock_enable_timestamps);
 
+void sock_set_timestamp(struct sock *sk, int optname, bool valbool)
+{
+       switch (optname) {
+       case SO_TIMESTAMP_OLD:
+               __sock_set_timestamps(sk, valbool, false, false);
+               break;
+       case SO_TIMESTAMP_NEW:
+               __sock_set_timestamps(sk, valbool, true, false);
+               break;
+       case SO_TIMESTAMPNS_OLD:
+               __sock_set_timestamps(sk, valbool, false, true);
+               break;
+       case SO_TIMESTAMPNS_NEW:
+               __sock_set_timestamps(sk, valbool, true, true);
+               break;
+       }
+}
+
+int sock_set_timestamping(struct sock *sk, int optname, int val)
+{
+       if (val & ~SOF_TIMESTAMPING_MASK)
+               return -EINVAL;
+
+       if (val & SOF_TIMESTAMPING_OPT_ID &&
+           !(sk->sk_tsflags & SOF_TIMESTAMPING_OPT_ID)) {
+               if (sk->sk_protocol == IPPROTO_TCP &&
+                   sk->sk_type == SOCK_STREAM) {
+                       if ((1 << sk->sk_state) &
+                           (TCPF_CLOSE | TCPF_LISTEN))
+                               return -EINVAL;
+                       sk->sk_tskey = tcp_sk(sk)->snd_una;
+               } else {
+                       sk->sk_tskey = 0;
+               }
+       }
+
+       if (val & SOF_TIMESTAMPING_OPT_STATS &&
+           !(val & SOF_TIMESTAMPING_OPT_TSONLY))
+               return -EINVAL;
+
+       sk->sk_tsflags = val;
+       sock_valbool_flag(sk, SOCK_TSTAMP_NEW, optname == SO_TIMESTAMPING_NEW);
+
+       if (val & SOF_TIMESTAMPING_RX_SOFTWARE)
+               sock_enable_timestamp(sk,
+                                     SOCK_TIMESTAMPING_RX_SOFTWARE);
+       else
+               sock_disable_timestamp(sk,
+                                      (1UL << SOCK_TIMESTAMPING_RX_SOFTWARE));
+       return 0;
+}
+
 void sock_set_keepalive(struct sock *sk)
 {
        lock_sock(sk);
@@ -815,10 +883,18 @@ void sock_set_rcvbuf(struct sock *sk, int val)
 }
 EXPORT_SYMBOL(sock_set_rcvbuf);
 
+static void __sock_set_mark(struct sock *sk, u32 val)
+{
+       if (val != sk->sk_mark) {
+               sk->sk_mark = val;
+               sk_dst_reset(sk);
+       }
+}
+
 void sock_set_mark(struct sock *sk, u32 val)
 {
        lock_sock(sk);
-       sk->sk_mark = val;
+       __sock_set_mark(sk, val);
        release_sock(sk);
 }
 EXPORT_SYMBOL(sock_set_mark);
@@ -989,54 +1065,15 @@ set_sndbuf:
                break;
 
        case SO_TIMESTAMP_OLD:
-               __sock_set_timestamps(sk, valbool, false, false);
-               break;
        case SO_TIMESTAMP_NEW:
-               __sock_set_timestamps(sk, valbool, true, false);
-               break;
        case SO_TIMESTAMPNS_OLD:
-               __sock_set_timestamps(sk, valbool, false, true);
-               break;
        case SO_TIMESTAMPNS_NEW:
-               __sock_set_timestamps(sk, valbool, true, true);
+               sock_set_timestamp(sk, valbool, optname);
                break;
+
        case SO_TIMESTAMPING_NEW:
        case SO_TIMESTAMPING_OLD:
-               if (val & ~SOF_TIMESTAMPING_MASK) {
-                       ret = -EINVAL;
-                       break;
-               }
-
-               if (val & SOF_TIMESTAMPING_OPT_ID &&
-                   !(sk->sk_tsflags & SOF_TIMESTAMPING_OPT_ID)) {
-                       if (sk->sk_protocol == IPPROTO_TCP &&
-                           sk->sk_type == SOCK_STREAM) {
-                               if ((1 << sk->sk_state) &
-                                   (TCPF_CLOSE | TCPF_LISTEN)) {
-                                       ret = -EINVAL;
-                                       break;
-                               }
-                               sk->sk_tskey = tcp_sk(sk)->snd_una;
-                       } else {
-                               sk->sk_tskey = 0;
-                       }
-               }
-
-               if (val & SOF_TIMESTAMPING_OPT_STATS &&
-                   !(val & SOF_TIMESTAMPING_OPT_TSONLY)) {
-                       ret = -EINVAL;
-                       break;
-               }
-
-               sk->sk_tsflags = val;
-               sock_valbool_flag(sk, SOCK_TSTAMP_NEW, optname == SO_TIMESTAMPING_NEW);
-
-               if (val & SOF_TIMESTAMPING_RX_SOFTWARE)
-                       sock_enable_timestamp(sk,
-                                             SOCK_TIMESTAMPING_RX_SOFTWARE);
-               else
-                       sock_disable_timestamp(sk,
-                                              (1UL << SOCK_TIMESTAMPING_RX_SOFTWARE));
+               ret = sock_set_timestamping(sk, optname, val);
                break;
 
        case SO_RCVLOWAT:
@@ -1126,10 +1163,10 @@ set_sndbuf:
        case SO_MARK:
                if (!ns_capable(sock_net(sk)->user_ns, CAP_NET_ADMIN)) {
                        ret = -EPERM;
-               } else if (val != sk->sk_mark) {
-                       sk->sk_mark = val;
-                       sk_dst_reset(sk);
+                       break;
                }
+
+               __sock_set_mark(sk, val);
                break;
 
        case SO_RXQ_OVFL:
@@ -1614,6 +1651,13 @@ int sock_getsockopt(struct socket *sock, int level, int optname,
                v.val = sk->sk_bound_dev_if;
                break;
 
+       case SO_NETNS_COOKIE:
+               lv = sizeof(u64);
+               if (len != lv)
+                       return -EINVAL;
+               v.val64 = sock_net(sk)->net_cookie;
+               break;
+
        default:
                /* We implement the SO_SNDLOWAT etc to not be settable
                 * (1003.1g 7).
@@ -2132,10 +2176,10 @@ void skb_orphan_partial(struct sk_buff *skb)
        if (skb_is_tcp_pure_ack(skb))
                return;
 
-       if (can_skb_orphan_partial(skb))
-               skb_set_owner_sk_safe(skb, skb->sk);
-       else
-               skb_orphan(skb);
+       if (can_skb_orphan_partial(skb) && skb_set_owner_sk_safe(skb, skb->sk))
+               return;
+
+       skb_orphan(skb);
 }
 EXPORT_SYMBOL(skb_orphan_partial);
 
@@ -3531,7 +3575,7 @@ int proto_register(struct proto *prot, int alloc_slab)
        return ret;
 
 out_free_timewait_sock_slab:
-       if (alloc_slab && prot->twsk_prot)
+       if (alloc_slab)
                tw_prot_cleanup(prot->twsk_prot);
 out_free_request_sock_slab:
        if (alloc_slab) {