arm64: rockchip_defconfig: enable drm display drivers
[firefly-linux-kernel-4.4.55.git] / net / core / sock_diag.c
index 0c1d58d43f67c46c7a11081d0ecdd30cb5878529..3963c3872c69b806afe6788ec1a4e588adc9cb6e 100644 (file)
@@ -214,7 +214,7 @@ void sock_diag_unregister(const struct sock_diag_handler *hnld)
 }
 EXPORT_SYMBOL_GPL(sock_diag_unregister);
 
-static int __sock_diag_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh)
+static int __sock_diag_cmd(struct sk_buff *skb, struct nlmsghdr *nlh)
 {
        int err;
        struct sock_diag_req *req = nlmsg_data(nlh);
@@ -234,8 +234,12 @@ static int __sock_diag_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh)
        hndl = sock_diag_handlers[req->sdiag_family];
        if (hndl == NULL)
                err = -ENOENT;
-       else
+       else if (nlh->nlmsg_type == SOCK_DIAG_BY_FAMILY)
                err = hndl->dump(skb, nlh);
+       else if (nlh->nlmsg_type == SOCK_DESTROY_BACKPORT && hndl->destroy)
+               err = hndl->destroy(skb, nlh);
+       else
+               err = -EOPNOTSUPP;
        mutex_unlock(&sock_diag_table_mutex);
 
        return err;
@@ -261,7 +265,8 @@ static int sock_diag_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh)
 
                return ret;
        case SOCK_DIAG_BY_FAMILY:
-               return __sock_diag_rcv_msg(skb, nlh);
+       case SOCK_DESTROY_BACKPORT:
+               return __sock_diag_cmd(skb, nlh);
        default:
                return -EINVAL;
        }
@@ -295,6 +300,18 @@ static int sock_diag_bind(struct net *net, int group)
        return 0;
 }
 
+int sock_diag_destroy(struct sock *sk, int err)
+{
+       if (!ns_capable(sock_net(sk)->user_ns, CAP_NET_ADMIN))
+               return -EPERM;
+
+       if (!sk->sk_prot->diag_destroy)
+               return -EOPNOTSUPP;
+
+       return sk->sk_prot->diag_destroy(sk, err);
+}
+EXPORT_SYMBOL_GPL(sock_diag_destroy);
+
 static int __net_init diag_net_init(struct net *net)
 {
        struct netlink_kernel_cfg cfg = {