From patchwork Sun Oct 21 04:43:36 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Xin Long X-Patchwork-Id: 987278 X-Patchwork-Delegate: davem@davemloft.net Return-Path: X-Original-To: patchwork-incoming-netdev@ozlabs.org Delivered-To: patchwork-incoming-netdev@ozlabs.org Authentication-Results: ozlabs.org; spf=none (mailfrom) smtp.mailfrom=vger.kernel.org (client-ip=209.132.180.67; helo=vger.kernel.org; envelope-from=netdev-owner@vger.kernel.org; receiver=) Authentication-Results: ozlabs.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.b="qq9XZ/ej"; dkim-atps=neutral Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 42d6WF27PSz9sCw for ; Sun, 21 Oct 2018 15:44:25 +1100 (AEDT) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727033AbeJUM4x (ORCPT ); Sun, 21 Oct 2018 08:56:53 -0400 Received: from mail-pg1-f193.google.com ([209.85.215.193]:44214 "EHLO mail-pg1-f193.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726895AbeJUM4w (ORCPT ); Sun, 21 Oct 2018 08:56:52 -0400 Received: by mail-pg1-f193.google.com with SMTP id w3-v6so1947738pgs.11; Sat, 20 Oct 2018 21:43:55 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references :in-reply-to:references; bh=9nMhiZINR3Ds0Ro8mkrv64FcvpImyasios76qMS/ztg=; b=qq9XZ/ejJQQ+PvQKdcuSE/JgurHj4WoElB9tEFmHLwpmzDnDmdTA/iweQovbUtYAwO M/lRK6vyhK7yKFnR1vhRFHsa2kEvNkpC01aX3GXnGgSWWoshz8qNKUgml8psLiEzLOay WaUrpJkx/U3wgbOjN6JT4DvH6ODOGkWPGh7z+Bj9WxWI2gV7QDOnYy/Ldu/R0Hc7tc4X 7d5t1O+J7Px/MMc8CCOgh8jEByH67X8AridJpG6km8p68CIEaHuuEjVdmieJRmyiL+Pz PsMTF2MzFl3yqp+s+ww2MJMSj4EPca13pzNKI+mNLbJ67UVw32stgdlLgA+8H+LBztcm 2j+w== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:in-reply-to:references; bh=9nMhiZINR3Ds0Ro8mkrv64FcvpImyasios76qMS/ztg=; b=ATCCJUALIVopZ8UCCxAdjcD08nlShBWmUz8QHCJ5l/CoDpo+irw/4jfW0/mKGonoEb 8i0r+7s8c8pOVHIJ65I0FVcRtfbt9EzSwPxGA4lu0xl/wSQ0Fp5l5fcBWBPnedVJR59a Ci6Fh8OMi3L5neTf5UF2BKDkSu9z39bNB+ddqE+V/kHqegf/qLb6/RG/prHPSfV1gG3g hoHDDhm6wv5YS+Wu47uff3rCapVbVSSNkNwQmEhJ7G+K2Hp1xDCiEgrt3XepNJ9b95de n7qW/E9G8qtKqdt2RbxgZwJ6/u/7KzkjnsBXxGeJJ00x+ZEaYfxGJ/3cdb0jNGq/jmL/ cTkQ== X-Gm-Message-State: ABuFfohEGzKrTybhCRnMFc5x/0mrwHZO1mNtjyRk3mKMwb09fN57cIhg 729a1DKoOtKwnTHd/d8/lhljQYJz X-Google-Smtp-Source: ACcGV62XdzwlKXKTkidJkKTVRt+g4OwYuw8pS9h9eIVcsYGW7gUmpvR4bEnaW+NrjFXeZSNDJqDB8A== X-Received: by 2002:a62:8910:: with SMTP id v16-v6mr40642484pfd.106.1540097034763; Sat, 20 Oct 2018 21:43:54 -0700 (PDT) Received: from localhost ([209.132.188.80]) by smtp.gmail.com with ESMTPSA id 28-v6sm5826538pgm.27.2018.10.20.21.43.53 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Sat, 20 Oct 2018 21:43:54 -0700 (PDT) From: Xin Long To: network dev , linux-sctp@vger.kernel.org Cc: Marcelo Ricardo Leitner , Neil Horman , davem@davemloft.net Subject: [PATCH net-next 1/3] sctp: do reuseport_select_sock in __sctp_rcv_lookup_endpoint Date: Sun, 21 Oct 2018 12:43:36 +0800 Message-Id: <08b533092a01a8f7cf2eb4c459fe3570a8df702b.1540095102.git.lucien.xin@gmail.com> X-Mailer: git-send-email 2.1.0 In-Reply-To: References: In-Reply-To: References: Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org This is a part of sk_reuseport support for sctp, and it selects a sock by the hashkey of lport, paddr and dport by default. It will work until sk_reuseport support is added in sctp_get_port_local() in the next patch. Signed-off-by: Xin Long --- net/sctp/input.c | 69 +++++++++++++++++++++++++++++++++----------------------- 1 file changed, 41 insertions(+), 28 deletions(-) diff --git a/net/sctp/input.c b/net/sctp/input.c index 5c36a99..60ede89 100644 --- a/net/sctp/input.c +++ b/net/sctp/input.c @@ -57,6 +57,7 @@ #include #include #include +#include /* Forward declarations for internal helpers. */ static int sctp_rcv_ootb(struct sk_buff *); @@ -65,8 +66,10 @@ static struct sctp_association *__sctp_rcv_lookup(struct net *net, const union sctp_addr *paddr, const union sctp_addr *laddr, struct sctp_transport **transportp); -static struct sctp_endpoint *__sctp_rcv_lookup_endpoint(struct net *net, - const union sctp_addr *laddr); +static struct sctp_endpoint *__sctp_rcv_lookup_endpoint( + struct net *net, struct sk_buff *skb, + const union sctp_addr *laddr, + const union sctp_addr *daddr); static struct sctp_association *__sctp_lookup_association( struct net *net, const union sctp_addr *local, @@ -171,7 +174,7 @@ int sctp_rcv(struct sk_buff *skb) asoc = __sctp_rcv_lookup(net, skb, &src, &dest, &transport); if (!asoc) - ep = __sctp_rcv_lookup_endpoint(net, &dest); + ep = __sctp_rcv_lookup_endpoint(net, skb, &dest, &src); /* Retrieve the common input handling substructure. */ rcvr = asoc ? &asoc->base : &ep->base; @@ -770,16 +773,35 @@ void sctp_unhash_endpoint(struct sctp_endpoint *ep) local_bh_enable(); } +static inline __u32 sctp_hashfn(const struct net *net, __be16 lport, + const union sctp_addr *paddr, __u32 seed) +{ + __u32 addr; + + if (paddr->sa.sa_family == AF_INET6) + addr = jhash(&paddr->v6.sin6_addr, 16, seed); + else + addr = (__force __u32)paddr->v4.sin_addr.s_addr; + + return jhash_3words(addr, ((__force __u32)paddr->v4.sin_port) << 16 | + (__force __u32)lport, net_hash_mix(net), seed); +} + /* Look up an endpoint. */ -static struct sctp_endpoint *__sctp_rcv_lookup_endpoint(struct net *net, - const union sctp_addr *laddr) +static struct sctp_endpoint *__sctp_rcv_lookup_endpoint( + struct net *net, struct sk_buff *skb, + const union sctp_addr *laddr, + const union sctp_addr *paddr) { struct sctp_hashbucket *head; struct sctp_ep_common *epb; struct sctp_endpoint *ep; + struct sock *sk; + __be32 lport; int hash; - hash = sctp_ep_hashfn(net, ntohs(laddr->v4.sin_port)); + lport = laddr->v4.sin_port; + hash = sctp_ep_hashfn(net, ntohs(lport)); head = &sctp_ep_hashtable[hash]; read_lock(&head->lock); sctp_for_each_hentry(epb, &head->chain) { @@ -791,6 +813,15 @@ static struct sctp_endpoint *__sctp_rcv_lookup_endpoint(struct net *net, ep = sctp_sk(net->sctp.ctl_sock)->ep; hit: + sk = ep->base.sk; + if (sk->sk_reuseport) { + __u32 phash = sctp_hashfn(net, lport, paddr, 0); + + sk = reuseport_select_sock(sk, phash, skb, + sizeof(struct sctphdr)); + if (sk) + ep = sctp_sk(sk)->ep; + } sctp_endpoint_hold(ep); read_unlock(&head->lock); return ep; @@ -829,35 +860,17 @@ static inline int sctp_hash_cmp(struct rhashtable_compare_arg *arg, static inline __u32 sctp_hash_obj(const void *data, u32 len, u32 seed) { const struct sctp_transport *t = data; - const union sctp_addr *paddr = &t->ipaddr; - const struct net *net = sock_net(t->asoc->base.sk); - __be16 lport = htons(t->asoc->base.bind_addr.port); - __u32 addr; - - if (paddr->sa.sa_family == AF_INET6) - addr = jhash(&paddr->v6.sin6_addr, 16, seed); - else - addr = (__force __u32)paddr->v4.sin_addr.s_addr; - return jhash_3words(addr, ((__force __u32)paddr->v4.sin_port) << 16 | - (__force __u32)lport, net_hash_mix(net), seed); + return sctp_hashfn(sock_net(t->asoc->base.sk), + htons(t->asoc->base.bind_addr.port), + &t->ipaddr, seed); } static inline __u32 sctp_hash_key(const void *data, u32 len, u32 seed) { const struct sctp_hash_cmp_arg *x = data; - const union sctp_addr *paddr = x->paddr; - const struct net *net = x->net; - __be16 lport = x->lport; - __u32 addr; - - if (paddr->sa.sa_family == AF_INET6) - addr = jhash(&paddr->v6.sin6_addr, 16, seed); - else - addr = (__force __u32)paddr->v4.sin_addr.s_addr; - return jhash_3words(addr, ((__force __u32)paddr->v4.sin_port) << 16 | - (__force __u32)lport, net_hash_mix(net), seed); + return sctp_hashfn(x->net, x->lport, x->paddr, seed); } static const struct rhashtable_params sctp_hash_params = { From patchwork Sun Oct 21 04:43:37 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Xin Long X-Patchwork-Id: 987279 X-Patchwork-Delegate: davem@davemloft.net Return-Path: X-Original-To: patchwork-incoming-netdev@ozlabs.org Delivered-To: patchwork-incoming-netdev@ozlabs.org Authentication-Results: ozlabs.org; spf=none (mailfrom) smtp.mailfrom=vger.kernel.org (client-ip=209.132.180.67; helo=vger.kernel.org; envelope-from=netdev-owner@vger.kernel.org; receiver=) Authentication-Results: ozlabs.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.b="BzfK+0vP"; dkim-atps=neutral Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 42d6WG0Ldrz9sC2 for ; Sun, 21 Oct 2018 15:44:26 +1100 (AEDT) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727110AbeJUM5B (ORCPT ); Sun, 21 Oct 2018 08:57:01 -0400 Received: from mail-pg1-f193.google.com ([209.85.215.193]:43173 "EHLO mail-pg1-f193.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726895AbeJUM5B (ORCPT ); Sun, 21 Oct 2018 08:57:01 -0400 Received: by mail-pg1-f193.google.com with SMTP id d8-v6so6277563pgv.10; Sat, 20 Oct 2018 21:44:03 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references :in-reply-to:references; bh=i8d6X4SaHhCUEaay4qBxHbfZFPM3/NL34FOrINCJnRQ=; b=BzfK+0vPewdjXO9oS7S+lBnnHBsKj8zYOr/kzYC00i+zLkwtXElD0/iusSuxX04nIH b3T2Sk1CXhm9G7fPIqJgANZAFqWclvZJD6BRBkdLx9YfEA+vFxmdJJdC3Wc30EjgbZos lvfWwzs1Js7v7+aaelNI1ZpmMbujhgcuhDLKtOYgu5ZWmRwFkBV1+pRLa3wj9Wi94f4M Ez7/ZyYQ4Mo6wUpCpv6t8Mh8Y9v2i30oTnvWUYIF9kJiS3aNaMpQC2ZOO9vsfyLtOC1Z 4O+vVU9cfhkPPUuZlxkoYT3ozRCB4k3tTGwWdbJfgG/72ktVG1c6+YMsYV9h/h27LmjR lFXQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:in-reply-to:references; bh=i8d6X4SaHhCUEaay4qBxHbfZFPM3/NL34FOrINCJnRQ=; b=Mqpunh8L8RQ/v3cMGXRcO4RbPnZh885xmdP59totswfn7QnwGoIhd5QfUL5fYn4aU4 6DwSbLuzgUw89beSh6YlOE5J73K6YFocC1JXQINh2xzNFIMWT+itXMJWGZQ0/eYNrV0A jV/xpBhw5pFjS7E6s6dmER2CC0OdJLkpO1oHiJCcX/WONgSdc/8ATZN6OFkYSAhJh4jA dSMAe2oWj8y22dXQyAZfI/vwmX0hOtaJ6FwzqXf7DzuOY1loEJuAiWjWJ80edB3GsRxR h03D5t0QTYz8X3NZeJ3NYsRkffkX5QH2p4K086liNND9p+zuS+vGTcEL15gAc4HpMoP5 NYuA== X-Gm-Message-State: ABuFfojxKFl/XapX9XQz7ODxBp9uncoTMxEc1maZAdi8iqXfFsLHMSuD Khvf0Vl4UTVbcAloU8e/6quM9HX/ X-Google-Smtp-Source: ACcGV62d+lApdlh+vxFB7Tc6CMs7aOGUAy2NYCdkchdk66MBmb/80vv6mRrqnqar2D2Kce1rCvTFyw== X-Received: by 2002:a63:a09:: with SMTP id 9-v6mr38238613pgk.318.1540097042693; Sat, 20 Oct 2018 21:44:02 -0700 (PDT) Received: from localhost ([209.132.188.80]) by smtp.gmail.com with ESMTPSA id j188-v6sm37844990pfg.132.2018.10.20.21.44.01 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Sat, 20 Oct 2018 21:44:02 -0700 (PDT) From: Xin Long To: network dev , linux-sctp@vger.kernel.org Cc: Marcelo Ricardo Leitner , Neil Horman , davem@davemloft.net Subject: [PATCH net-next 2/3] sctp: add sock_reuseport for the sock in __sctp_hash_endpoint Date: Sun, 21 Oct 2018 12:43:37 +0800 Message-Id: <661578e3134c79c575d934b3267b327773fd34f7.1540095102.git.lucien.xin@gmail.com> X-Mailer: git-send-email 2.1.0 In-Reply-To: <08b533092a01a8f7cf2eb4c459fe3570a8df702b.1540095102.git.lucien.xin@gmail.com> References: <08b533092a01a8f7cf2eb4c459fe3570a8df702b.1540095102.git.lucien.xin@gmail.com> In-Reply-To: References: Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org This is a part of sk_reuseport support for sctp. It defines a helper sctp_bind_addrs_check() to check if the bind_addrs in two socks are matched. It will add sock_reuseport if they are completely matched, and return err if they are partly matched, and alloc sock_reuseport if all socks are not matched at all. It will work until sk_reuseport support is added in sctp_get_port_local() in the next patch. Signed-off-by: Xin Long --- include/net/sctp/sctp.h | 2 +- include/net/sctp/structs.h | 2 ++ net/core/sock_reuseport.c | 1 + net/sctp/bind_addr.c | 28 ++++++++++++++++++++++ net/sctp/input.c | 60 +++++++++++++++++++++++++++++++++++++++------- net/sctp/socket.c | 3 +-- 6 files changed, 85 insertions(+), 11 deletions(-) diff --git a/include/net/sctp/sctp.h b/include/net/sctp/sctp.h index 8c2caa3..b8cd58d 100644 --- a/include/net/sctp/sctp.h +++ b/include/net/sctp/sctp.h @@ -152,7 +152,7 @@ int sctp_primitive_RECONF(struct net *net, struct sctp_association *asoc, */ int sctp_rcv(struct sk_buff *skb); void sctp_v4_err(struct sk_buff *skb, u32 info); -void sctp_hash_endpoint(struct sctp_endpoint *); +int sctp_hash_endpoint(struct sctp_endpoint *ep); void sctp_unhash_endpoint(struct sctp_endpoint *); struct sock *sctp_err_lookup(struct net *net, int family, struct sk_buff *, struct sctphdr *, struct sctp_association **, diff --git a/include/net/sctp/structs.h b/include/net/sctp/structs.h index a11f937..15d017f 100644 --- a/include/net/sctp/structs.h +++ b/include/net/sctp/structs.h @@ -1190,6 +1190,8 @@ int sctp_bind_addr_conflict(struct sctp_bind_addr *, const union sctp_addr *, struct sctp_sock *, struct sctp_sock *); int sctp_bind_addr_state(const struct sctp_bind_addr *bp, const union sctp_addr *addr); +int sctp_bind_addrs_check(struct sctp_sock *sp, + struct sctp_sock *sp2, int cnt2); union sctp_addr *sctp_find_unmatch_addr(struct sctp_bind_addr *bp, const union sctp_addr *addrs, int addrcnt, diff --git a/net/core/sock_reuseport.c b/net/core/sock_reuseport.c index ba5cba5..d8fe3e5 100644 --- a/net/core/sock_reuseport.c +++ b/net/core/sock_reuseport.c @@ -187,6 +187,7 @@ int reuseport_add_sock(struct sock *sk, struct sock *sk2, bool bind_inany) call_rcu(&old_reuse->rcu, reuseport_free_rcu); return 0; } +EXPORT_SYMBOL(reuseport_add_sock); void reuseport_detach_sock(struct sock *sk) { diff --git a/net/sctp/bind_addr.c b/net/sctp/bind_addr.c index 7df3704..78d0d93 100644 --- a/net/sctp/bind_addr.c +++ b/net/sctp/bind_addr.c @@ -337,6 +337,34 @@ int sctp_bind_addr_match(struct sctp_bind_addr *bp, return match; } +int sctp_bind_addrs_check(struct sctp_sock *sp, + struct sctp_sock *sp2, int cnt2) +{ + struct sctp_bind_addr *bp2 = &sp2->ep->base.bind_addr; + struct sctp_bind_addr *bp = &sp->ep->base.bind_addr; + struct sctp_sockaddr_entry *laddr, *laddr2; + bool exist = false; + int cnt = 0; + + rcu_read_lock(); + list_for_each_entry_rcu(laddr, &bp->address_list, list) { + list_for_each_entry_rcu(laddr2, &bp2->address_list, list) { + if (sp->pf->af->cmp_addr(&laddr->a, &laddr2->a) && + laddr->valid == laddr2->valid) { + exist = true; + goto next; + } + } + cnt = 0; + break; +next: + cnt++; + } + rcu_read_unlock(); + + return (cnt == cnt2) ? 0 : (exist ? -EEXIST : 1); +} + /* Does the address 'addr' conflict with any addresses in * the bp. */ diff --git a/net/sctp/input.c b/net/sctp/input.c index 60ede89..6bfeb10 100644 --- a/net/sctp/input.c +++ b/net/sctp/input.c @@ -723,43 +723,87 @@ static int sctp_rcv_ootb(struct sk_buff *skb) } /* Insert endpoint into the hash table. */ -static void __sctp_hash_endpoint(struct sctp_endpoint *ep) +static int __sctp_hash_endpoint(struct sctp_endpoint *ep) { - struct net *net = sock_net(ep->base.sk); - struct sctp_ep_common *epb; + struct sock *sk = ep->base.sk; + struct net *net = sock_net(sk); struct sctp_hashbucket *head; + struct sctp_ep_common *epb; epb = &ep->base; - epb->hashent = sctp_ep_hashfn(net, epb->bind_addr.port); head = &sctp_ep_hashtable[epb->hashent]; + if (sk->sk_reuseport) { + bool any = sctp_is_ep_boundall(sk); + struct sctp_ep_common *epb2; + struct list_head *list; + int cnt = 0, err = 1; + + list_for_each(list, &ep->base.bind_addr.address_list) + cnt++; + + sctp_for_each_hentry(epb2, &head->chain) { + struct sock *sk2 = epb2->sk; + + if (!net_eq(sock_net(sk2), net) || sk2 == sk || + !uid_eq(sock_i_uid(sk2), sock_i_uid(sk)) || + !sk2->sk_reuseport) + continue; + + err = sctp_bind_addrs_check(sctp_sk(sk2), + sctp_sk(sk), cnt); + if (!err) { + err = reuseport_add_sock(sk, sk2, any); + if (err) + return err; + break; + } else if (err < 0) { + return err; + } + } + + if (err) { + err = reuseport_alloc(sk, any); + if (err) + return err; + } + } + write_lock(&head->lock); hlist_add_head(&epb->node, &head->chain); write_unlock(&head->lock); + return 0; } /* Add an endpoint to the hash. Local BH-safe. */ -void sctp_hash_endpoint(struct sctp_endpoint *ep) +int sctp_hash_endpoint(struct sctp_endpoint *ep) { + int err; + local_bh_disable(); - __sctp_hash_endpoint(ep); + err = __sctp_hash_endpoint(ep); local_bh_enable(); + + return err; } /* Remove endpoint from the hash table. */ static void __sctp_unhash_endpoint(struct sctp_endpoint *ep) { - struct net *net = sock_net(ep->base.sk); + struct sock *sk = ep->base.sk; struct sctp_hashbucket *head; struct sctp_ep_common *epb; epb = &ep->base; - epb->hashent = sctp_ep_hashfn(net, epb->bind_addr.port); + epb->hashent = sctp_ep_hashfn(sock_net(sk), epb->bind_addr.port); head = &sctp_ep_hashtable[epb->hashent]; + if (rcu_access_pointer(sk->sk_reuseport_cb)) + reuseport_detach_sock(sk); + write_lock(&head->lock); hlist_del_init(&epb->node); write_unlock(&head->lock); diff --git a/net/sctp/socket.c b/net/sctp/socket.c index fc0386e..44e7d8c 100644 --- a/net/sctp/socket.c +++ b/net/sctp/socket.c @@ -7850,8 +7850,7 @@ static int sctp_listen_start(struct sock *sk, int backlog) } sk->sk_max_ack_backlog = backlog; - sctp_hash_endpoint(ep); - return 0; + return sctp_hash_endpoint(ep); } /* From patchwork Sun Oct 21 04:43:38 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Xin Long X-Patchwork-Id: 987280 X-Patchwork-Delegate: davem@davemloft.net Return-Path: X-Original-To: patchwork-incoming-netdev@ozlabs.org Delivered-To: patchwork-incoming-netdev@ozlabs.org Authentication-Results: ozlabs.org; spf=none (mailfrom) smtp.mailfrom=vger.kernel.org (client-ip=209.132.180.67; helo=vger.kernel.org; envelope-from=netdev-owner@vger.kernel.org; receiver=) Authentication-Results: ozlabs.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.b="B9bieENt"; dkim-atps=neutral Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 42d6WG593gz9sCw for ; Sun, 21 Oct 2018 15:44:26 +1100 (AEDT) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727129AbeJUM5J (ORCPT ); Sun, 21 Oct 2018 08:57:09 -0400 Received: from mail-pl1-f193.google.com ([209.85.214.193]:32883 "EHLO mail-pl1-f193.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726895AbeJUM5J (ORCPT ); Sun, 21 Oct 2018 08:57:09 -0400 Received: by mail-pl1-f193.google.com with SMTP id x6-v6so728245pln.0; Sat, 20 Oct 2018 21:44:11 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references :in-reply-to:references; bh=xDpo8gogWsXU220D6cDIpGV/0kNdqhcUS+hgkHtYYAM=; b=B9bieENtWxRZnUetC0/ptKgjprBBgPRqpT7T4HNQzFr7tODG9mhVUtfUJqsO02vtqR Sdu2/iORN2gn72Oqv2mF+64t6viGBZs+Y/l08fy0wDPBquFZswRmTNrWMO4j4FdCrChQ 2/XM1oLb0iKiaJGVsUeR68BtLpkZUkXcSX1IwwhQ4NLUvITkMz1BoveQq+vlbOFp+ZdI AQ3ho/hwievyqFZ/NYhki4/jrKDXbX03K81w4jYJKSHSMFUUzfpVWMh9YEtDPkZWK0II ZeHv9dLYG0ZPmvvj/X0xlhsAT9rq8PYoaLIJSAX1k7vu9q9mNoo4Tz59356m70HqrP0a TD6w== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:in-reply-to:references; bh=xDpo8gogWsXU220D6cDIpGV/0kNdqhcUS+hgkHtYYAM=; b=Df88SgnoT18T2iQXp+Bi/TVkk1oxXEjLuL1SVHMERljoiMN4UMMW1AVu9Biz7m14/U OFzHp8qcgDZSwOOQjX59g4CBIWrZqT8UUO/kOQjIKef+QRj4gHiGlosK75qQnFg3svjv JCJbNNyHkpvsm5ITn6ptMvGf3vzbtHPDt1KQje4VU+cKzK8CErJFG/4KZoAVhPAfXzIY VghftCe0m1fdDobLqRe63gKkRIT67tfJYtdgjRwTekEzH9neK707Ujf1ShdbgR54TxTa 6M43veFMBB6Z6EDKapoyb8KONw0075U0qpr0svxi9Qd7Bgfxk4oUeZo7Gwrt7hUkfriZ ZC2g== X-Gm-Message-State: ABuFfohvGLG0+7Lr+laChwo70D8fxV58lJY0xtkhKR4wDndWnNptAvVj 7KGNM5vBt9/BrdJ7/LNH9vl9KJrqB2Q= X-Google-Smtp-Source: ACcGV61hcs3BLMXGhXROz0NjUtcEmsLmBwbXlZ9fHz+VLo2VyU9UhsubdkiBlS0Wm0vkv5VdnmaH3Q== X-Received: by 2002:a17:902:5a89:: with SMTP id r9-v6mr39442175pli.95.1540097050726; Sat, 20 Oct 2018 21:44:10 -0700 (PDT) Received: from localhost ([209.132.188.80]) by smtp.gmail.com with ESMTPSA id t69-v6sm35156759pgd.43.2018.10.20.21.44.09 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Sat, 20 Oct 2018 21:44:10 -0700 (PDT) From: Xin Long To: network dev , linux-sctp@vger.kernel.org Cc: Marcelo Ricardo Leitner , Neil Horman , davem@davemloft.net Subject: [PATCH net-next 3/3] sctp: process sk_reuseport in sctp_get_port_local Date: Sun, 21 Oct 2018 12:43:38 +0800 Message-Id: <8695b919f856029566aa477b966ec61ab5611338.1540095102.git.lucien.xin@gmail.com> X-Mailer: git-send-email 2.1.0 In-Reply-To: <661578e3134c79c575d934b3267b327773fd34f7.1540095102.git.lucien.xin@gmail.com> References: <08b533092a01a8f7cf2eb4c459fe3570a8df702b.1540095102.git.lucien.xin@gmail.com> <661578e3134c79c575d934b3267b327773fd34f7.1540095102.git.lucien.xin@gmail.com> In-Reply-To: References: Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org When socks' sk_reuseport is set, the same port and address are allowed to be bound into these socks who have the same uid. Note that the difference from sk_reuse is that it allows multiple socks to listen on the same port and address. Signed-off-by: Xin Long --- include/net/sctp/structs.h | 4 +++- net/sctp/socket.c | 46 +++++++++++++++++++++++++++++++++------------- 2 files changed, 36 insertions(+), 14 deletions(-) diff --git a/include/net/sctp/structs.h b/include/net/sctp/structs.h index 15d017f..af9d494 100644 --- a/include/net/sctp/structs.h +++ b/include/net/sctp/structs.h @@ -96,7 +96,9 @@ struct sctp_stream; struct sctp_bind_bucket { unsigned short port; - unsigned short fastreuse; + signed char fastreuse; + signed char fastreuseport; + kuid_t fastuid; struct hlist_node node; struct hlist_head owner; struct net *net; diff --git a/net/sctp/socket.c b/net/sctp/socket.c index 44e7d8c..8605705 100644 --- a/net/sctp/socket.c +++ b/net/sctp/socket.c @@ -7642,8 +7642,10 @@ static struct sctp_bind_bucket *sctp_bucket_create( static long sctp_get_port_local(struct sock *sk, union sctp_addr *addr) { - bool reuse = (sk->sk_reuse || sctp_sk(sk)->reuse); + struct sctp_sock *sp = sctp_sk(sk); + bool reuse = (sk->sk_reuse || sp->reuse); struct sctp_bind_hashbucket *head; /* hash list */ + kuid_t uid = sock_i_uid(sk); struct sctp_bind_bucket *pp; unsigned short snum; int ret; @@ -7719,7 +7721,10 @@ static long sctp_get_port_local(struct sock *sk, union sctp_addr *addr) pr_debug("%s: found a possible match\n", __func__); - if (pp->fastreuse && reuse && sk->sk_state != SCTP_SS_LISTENING) + if ((pp->fastreuse && reuse && + sk->sk_state != SCTP_SS_LISTENING) || + (pp->fastreuseport && sk->sk_reuseport && + uid_eq(pp->fastuid, uid))) goto success; /* Run through the list of sockets bound to the port @@ -7733,16 +7738,18 @@ static long sctp_get_port_local(struct sock *sk, union sctp_addr *addr) * in an endpoint. */ sk_for_each_bound(sk2, &pp->owner) { - struct sctp_endpoint *ep2; - ep2 = sctp_sk(sk2)->ep; + struct sctp_sock *sp2 = sctp_sk(sk2); + struct sctp_endpoint *ep2 = sp2->ep; if (sk == sk2 || - (reuse && (sk2->sk_reuse || sctp_sk(sk2)->reuse) && - sk2->sk_state != SCTP_SS_LISTENING)) + (reuse && (sk2->sk_reuse || sp2->reuse) && + sk2->sk_state != SCTP_SS_LISTENING) || + (sk->sk_reuseport && sk2->sk_reuseport && + uid_eq(uid, sock_i_uid(sk2)))) continue; - if (sctp_bind_addr_conflict(&ep2->base.bind_addr, addr, - sctp_sk(sk2), sctp_sk(sk))) { + if (sctp_bind_addr_conflict(&ep2->base.bind_addr, + addr, sp2, sp)) { ret = (long)sk2; goto fail_unlock; } @@ -7765,19 +7772,32 @@ static long sctp_get_port_local(struct sock *sk, union sctp_addr *addr) pp->fastreuse = 1; else pp->fastreuse = 0; - } else if (pp->fastreuse && - (!reuse || sk->sk_state == SCTP_SS_LISTENING)) - pp->fastreuse = 0; + + if (sk->sk_reuseport) { + pp->fastreuseport = 1; + pp->fastuid = uid; + } else { + pp->fastreuseport = 0; + } + } else { + if (pp->fastreuse && + (!reuse || sk->sk_state == SCTP_SS_LISTENING)) + pp->fastreuse = 0; + + if (pp->fastreuseport && + (!sk->sk_reuseport || !uid_eq(pp->fastuid, uid))) + pp->fastreuseport = 0; + } /* We are set, so fill up all the data in the hash table * entry, tie the socket list information with the rest of the * sockets FIXME: Blurry, NPI (ipg). */ success: - if (!sctp_sk(sk)->bind_hash) { + if (!sp->bind_hash) { inet_sk(sk)->inet_num = snum; sk_add_bind_node(sk, &pp->owner); - sctp_sk(sk)->bind_hash = pp; + sp->bind_hash = pp; } ret = 0;