bpf: sk_msg, zap ingress queue on psock down
[linux-2.6-block.git] / net / core / sock.c
index 080a880a1761b8e0efafaddf0ddac5bb87c64f88..f00902c532cc777335eaad8989e472ef71089ecd 100644 (file)
@@ -567,6 +567,8 @@ static int sock_setbindtodevice(struct sock *sk, char __user *optval,
 
        lock_sock(sk);
        sk->sk_bound_dev_if = index;
+       if (sk->sk_prot->rehash)
+               sk->sk_prot->rehash(sk);
        sk_dst_reset(sk);
        release_sock(sk);
 
@@ -698,6 +700,7 @@ int sock_setsockopt(struct socket *sock, int level, int optname,
                break;
        case SO_DONTROUTE:
                sock_valbool_flag(sk, SOCK_LOCALROUTE, valbool);
+               sk_dst_reset(sk);
                break;
        case SO_BROADCAST:
                sock_valbool_flag(sk, SOCK_BROADCAST, valbool);
@@ -950,10 +953,12 @@ set_rcvbuf:
                        clear_bit(SOCK_PASSSEC, &sock->flags);
                break;
        case SO_MARK:
-               if (!ns_capable(sock_net(sk)->user_ns, CAP_NET_ADMIN))
+               if (!ns_capable(sock_net(sk)->user_ns, CAP_NET_ADMIN)) {
                        ret = -EPERM;
-               else
+               } else if (val != sk->sk_mark) {
                        sk->sk_mark = val;
+                       sk_dst_reset(sk);
+               }
                break;
 
        case SO_RXQ_OVFL:
@@ -1014,7 +1019,10 @@ set_rcvbuf:
 
        case SO_ZEROCOPY:
                if (sk->sk_family == PF_INET || sk->sk_family == PF_INET6) {
-                       if (sk->sk_protocol != IPPROTO_TCP)
+                       if (!((sk->sk_type == SOCK_STREAM &&
+                              sk->sk_protocol == IPPROTO_TCP) ||
+                             (sk->sk_type == SOCK_DGRAM &&
+                              sk->sk_protocol == IPPROTO_UDP)))
                                ret = -ENOTSUPP;
                } else if (sk->sk_family != PF_RDS) {
                        ret = -ENOTSUPP;