These changes make associations namespace aware, including
association ID lists and their associated locks.

Signed-off-by: Jan Ariyasu <jan.ariy...@hp.com>
---
 include/net/sctp/sctp.h    |    3 ---
 include/net/sctp/structs.h |    3 ++-
 net/sctp/associola.c       |   37 ++++++++++++++++++++++++-------------
 net/sctp/input.c           |   25 +++++++++++++++----------
 net/sctp/sm_sideeffect.c   |    9 ++++-----
 5 files changed, 45 insertions(+), 32 deletions(-)

diff --git a/include/net/sctp/sctp.h b/include/net/sctp/sctp.h
index 8488d5e..363a786 100644
--- a/include/net/sctp/sctp.h
+++ b/include/net/sctp/sctp.h
@@ -601,9 +601,6 @@ extern struct proto sctp_prot;
 extern struct proto sctpv6_prot;
 void sctp_put_port(struct sock *sk);
 
-extern struct idr sctp_assocs_id;
-extern spinlock_t sctp_assocs_id_lock;
-
 /* Static inline functions. */
 
 /* Convert from an IP version number to an Address Family symbol.  */
diff --git a/include/net/sctp/structs.h b/include/net/sctp/structs.h
index 2034d53..72d473b 100644
--- a/include/net/sctp/structs.h
+++ b/include/net/sctp/structs.h
@@ -2153,7 +2153,8 @@ struct sctp_transport *sctp_assoc_is_match(struct 
sctp_association *,
                                           const union sctp_addr *,
                                           const union sctp_addr *);
 void sctp_assoc_migrate(struct sctp_association *, struct sock *);
-void sctp_assoc_update(struct sctp_association *old,
+void sctp_assoc_update(struct net *net,
+                      struct sctp_association *old,
                       struct sctp_association *new);
 
 __u32 sctp_association_get_next_tsn(struct sctp_association *);
diff --git a/net/sctp/associola.c b/net/sctp/associola.c
index 1bd956b..5b4be66 100644
--- a/net/sctp/associola.c
+++ b/net/sctp/associola.c
@@ -86,6 +86,8 @@ static struct sctp_association *sctp_association_init(struct 
sctp_association *a
        int i;
        sctp_paramhdr_t *p;
        int err;
+       struct sctp_net_params *net_params =
+                       sctp_get_params(sock_net(sk));
 
        /* Retrieve the SCTP per socket area.  */
        sp = sctp_sk((struct sock *)sk);
@@ -124,7 +126,7 @@ static struct sctp_association 
*sctp_association_init(struct sctp_association *a
         * socket values.
         */
        asoc->max_retrans = sp->assocparams.sasoc_asocmaxrxt;
-       asoc->pf_retrans  = sctp_pf_retrans;
+       asoc->pf_retrans  = net_params->pf_retrans;
 
        asoc->rto_initial = msecs_to_jiffies(sp->rtoinfo.srto_initial);
        asoc->rto_max = msecs_to_jiffies(sp->rtoinfo.srto_max);
@@ -175,7 +177,8 @@ static struct sctp_association 
*sctp_association_init(struct sctp_association *a
        asoc->timeouts[SCTP_EVENT_TIMEOUT_HEARTBEAT] = 0;
        asoc->timeouts[SCTP_EVENT_TIMEOUT_SACK] = asoc->sackdelay;
        asoc->timeouts[SCTP_EVENT_TIMEOUT_AUTOCLOSE] =
-               min_t(unsigned long, sp->autoclose, sctp_max_autoclose) * HZ;
+               min_t(unsigned long, sp->autoclose,
+                       net_params->max_autoclose) * HZ;
 
        /* Initializes the timers */
        for (i = SCTP_EVENT_TIMEOUT_NONE; i < SCTP_NUM_TIMEOUT_TYPES; ++i)
@@ -281,7 +284,7 @@ static struct sctp_association 
*sctp_association_init(struct sctp_association *a
         * and will revert old behavior.
         */
        asoc->peer.asconf_capable = 0;
-       if (sctp_addip_noauth)
+       if (net_params->addip_noauth_enable)
                asoc->peer.asconf_capable = 1;
        asoc->asconf_addr_del_pending = NULL;
        asoc->src_out_of_asoc_ok = 0;
@@ -468,15 +471,18 @@ void sctp_association_free(struct sctp_association *asoc)
 /* Cleanup and free up an association. */
 static void sctp_association_destroy(struct sctp_association *asoc)
 {
+       struct sctp_ns_globals *ns_globals =
+               sctp_get_ns_globals(sock_net(asoc->base.sk));
+
        SCTP_ASSERT(asoc->base.dead, "Assoc is not dead", return);
 
        sctp_endpoint_put(asoc->ep);
        sock_put(asoc->base.sk);
 
        if (asoc->assoc_id != 0) {
-               spin_lock_bh(&sctp_assocs_id_lock);
-               idr_remove(&sctp_assocs_id, asoc->assoc_id);
-               spin_unlock_bh(&sctp_assocs_id_lock);
+               spin_lock_bh(&ns_globals->assocs_id_lock);
+               idr_remove(&ns_globals->assocs_id, asoc->assoc_id);
+               spin_unlock_bh(&ns_globals->assocs_id_lock);
        }
 
        WARN_ON(atomic_read(&asoc->rmem_alloc));
@@ -1204,7 +1210,8 @@ void sctp_assoc_migrate(struct sctp_association *assoc, 
struct sock *newsk)
 }
 
 /* Update an association (possibly from unexpected COOKIE-ECHO processing).  */
-void sctp_assoc_update(struct sctp_association *asoc,
+void sctp_assoc_update(struct net *net,
+                      struct sctp_association *asoc,
                       struct sctp_association *new)
 {
        struct sctp_transport *trans;
@@ -1416,6 +1423,8 @@ void sctp_assoc_sync_pmtu(struct sock *sk, struct 
sctp_association *asoc)
 /* Should we send a SACK to update our peer? */
 static inline int sctp_peer_needs_update(struct sctp_association *asoc)
 {
+       struct sctp_net_params *net_params =
+               sctp_get_params(sock_net(asoc->base.sk));
        switch (asoc->state) {
        case SCTP_STATE_ESTABLISHED:
        case SCTP_STATE_SHUTDOWN_PENDING:
@@ -1423,8 +1432,8 @@ static inline int sctp_peer_needs_update(struct 
sctp_association *asoc)
        case SCTP_STATE_SHUTDOWN_SENT:
                if ((asoc->rwnd > asoc->a_rwnd) &&
                    ((asoc->rwnd - asoc->a_rwnd) >= max_t(__u32,
-                          (asoc->base.sk->sk_rcvbuf >> sctp_rwnd_upd_shift),
-                          asoc->pathmtu)))
+                       (asoc->base.sk->sk_rcvbuf >>
+                         net_params->rwnd_update_shift), asoc->pathmtu)))
                        return 1;
                break;
        default:
@@ -1582,23 +1591,25 @@ int sctp_assoc_set_id(struct sctp_association *asoc, 
gfp_t gfp)
 {
        int assoc_id;
        int error = 0;
+       struct sctp_ns_globals *ns_globals =
+               sctp_get_ns_globals(sock_net(asoc->base.sk));
 
        /* If the id is already assigned, keep it. */
        if (asoc->assoc_id)
                return error;
 retry:
-       if (unlikely(!idr_pre_get(&sctp_assocs_id, gfp)))
+       if (unlikely(!idr_pre_get(&ns_globals->assocs_id, gfp)))
                return -ENOMEM;
 
-       spin_lock_bh(&sctp_assocs_id_lock);
-       error = idr_get_new_above(&sctp_assocs_id, (void *)asoc,
+       spin_lock_bh(&ns_globals->assocs_id_lock);
+       error = idr_get_new_above(&ns_globals->assocs_id, (void *)asoc,
                                    idr_low, &assoc_id);
        if (!error) {
                idr_low = assoc_id + 1;
                if (idr_low == INT_MAX)
                        idr_low = 1;
        }
-       spin_unlock_bh(&sctp_assocs_id_lock);
+       spin_unlock_bh(&ns_globals->assocs_id_lock);
        if (error == -EAGAIN)
                goto retry;
        else if (error)
diff --git a/net/sctp/input.c b/net/sctp/input.c
index 1b92da2..9b53b95 100644
--- a/net/sctp/input.c
+++ b/net/sctp/input.c
@@ -70,7 +70,8 @@ static struct sctp_association *__sctp_rcv_lookup(struct 
sk_buff *skb,
                                      const union sctp_addr *laddr,
                                      const union sctp_addr *paddr,
                                      struct sctp_transport **transportp);
-static struct sctp_endpoint *__sctp_rcv_lookup_endpoint(const union sctp_addr 
*laddr);
+static struct sctp_endpoint *__sctp_rcv_lookup_endpoint(struct net *net,
+                                       const union sctp_addr *laddr);
 static struct sctp_association *__sctp_lookup_association(
                                        const union sctp_addr *local,
                                        const union sctp_addr *peer,
@@ -129,6 +130,7 @@ int sctp_rcv(struct sk_buff *skb)
        union sctp_addr dest;
        int family;
        struct sctp_af *af;
+       struct net *net = dev_net(skb->dev);
 
        if (skb->pkt_type!=PACKET_HOST)
                goto discard_it;
@@ -181,7 +183,7 @@ int sctp_rcv(struct sk_buff *skb)
        asoc = __sctp_rcv_lookup(skb, &src, &dest, &transport);
 
        if (!asoc)
-               ep = __sctp_rcv_lookup_endpoint(&dest);
+               ep = __sctp_rcv_lookup_endpoint(net, &dest);
 
        /* Retrieve the common input handling substructure. */
        rcvr = asoc ? &asoc->base : &ep->base;
@@ -200,7 +202,7 @@ int sctp_rcv(struct sk_buff *skb)
                        sctp_endpoint_put(ep);
                        ep = NULL;
                }
-               sk = *(sctp_get_ctl_sock(&init_net));
+               sk = *(sctp_get_ctl_sock(net));
                ep = sctp_sk(sk)->ep;
                sctp_endpoint_hold(ep);
                rcvr = &ep->base;
@@ -539,7 +541,7 @@ struct sock *sctp_err_lookup(int family, struct sk_buff 
*skb,
         * servers this needs to be solved differently.
         */
        if (sock_owned_by_user(sk))
-               NET_INC_STATS_BH(&init_net, LINUX_MIB_LOCKDROPPEDICMPS);
+               NET_INC_STATS_BH(sock_net(sk), LINUX_MIB_LOCKDROPPEDICMPS);
 
        *app = asoc;
        *tpp = transport;
@@ -588,7 +590,7 @@ void sctp_v4_err(struct sk_buff *skb, __u32 info)
        int err;
 
        if (skb->len < ihlen + 8) {
-               ICMP_INC_STATS_BH(&init_net, ICMP_MIB_INERRORS);
+               ICMP_INC_STATS_BH(dev_net(skb->dev), ICMP_MIB_INERRORS);
                return;
        }
 
@@ -602,7 +604,7 @@ void sctp_v4_err(struct sk_buff *skb, __u32 info)
        skb->network_header = saveip;
        skb->transport_header = savesctp;
        if (!sk) {
-               ICMP_INC_STATS_BH(&init_net, ICMP_MIB_INERRORS);
+               ICMP_INC_STATS_BH(dev_net(skb->dev), ICMP_MIB_INERRORS);
                return;
        }
        /* Warning:  The sock lock is held.  Remember to call
@@ -770,7 +772,8 @@ void sctp_unhash_endpoint(struct sctp_endpoint *ep)
 }
 
 /* Look up an endpoint. */
-static struct sctp_endpoint *__sctp_rcv_lookup_endpoint(const union sctp_addr 
*laddr)
+static struct sctp_endpoint *__sctp_rcv_lookup_endpoint(struct net *net,
+                                       const union sctp_addr *laddr)
 {
        struct sctp_hashbucket *head;
        struct sctp_ep_common *epb;
@@ -787,7 +790,7 @@ static struct sctp_endpoint 
*__sctp_rcv_lookup_endpoint(const union sctp_addr *l
                        goto hit;
        }
 
-       ep = sctp_sk(*(sctp_get_ctl_sock(&init_net)))->ep;
+       ep = sctp_sk(*(sctp_get_ctl_sock(net)))->ep;
 
 hit:
        sctp_endpoint_hold(ep);
@@ -1042,6 +1045,8 @@ static struct sctp_association 
*__sctp_rcv_walk_lookup(struct sk_buff *skb,
        int have_auth = 0;
        unsigned int chunk_num = 1;
        __u8 *ch_end;
+       struct sctp_net_params *net_params =
+                       sctp_get_params(dev_net(skb->dev));
 
        /* Walk through the chunks looking for AUTH or ASCONF chunks
         * to help us find the association.
@@ -1074,8 +1079,8 @@ static struct sctp_association 
*__sctp_rcv_walk_lookup(struct sk_buff *skb,
                            break;
 
                    case SCTP_CID_ASCONF:
-                           if (have_auth || sctp_addip_noauth)
-                                   asoc = __sctp_rcv_asconf_lookup(ch, laddr,
+                           if (have_auth || net_params->addip_noauth_enable)
+                               asoc = __sctp_rcv_asconf_lookup(ch, laddr,
                                                        sctp_hdr(skb)->source,
                                                        transportp);
                    default:
diff --git a/net/sctp/sm_sideeffect.c b/net/sctp/sm_sideeffect.c
index 2c895fd..35cbbe5 100644
--- a/net/sctp/sm_sideeffect.c
+++ b/net/sctp/sm_sideeffect.c
@@ -1058,8 +1058,8 @@ static void sctp_cmd_send_asconf(struct sctp_association 
*asoc)
 
                /* Hold the chunk until an ASCONF_ACK is received. */
                sctp_chunk_hold(asconf);
-               if (sctp_primitive_ASCONF(sock_net(asoc->base.sk), asoc,
-                                         asconf))
+               if (sctp_primitive_ASCONF(sock_net(asoc->base.sk),
+                                         asoc, asconf))
                        sctp_chunk_free(asconf);
                else
                        asoc->addip_last_asconf = asconf;
@@ -1277,7 +1277,7 @@ static int sctp_cmd_interpreter(sctp_event_t event_type,
                        break;
 
                case SCTP_CMD_UPDATE_ASSOC:
-                      sctp_assoc_update(asoc, cmd->obj.ptr);
+                      sctp_assoc_update(net, asoc, cmd->obj.ptr);
                       break;
 
                case SCTP_CMD_PURGE_OUTQUEUE:
@@ -1354,8 +1354,7 @@ static int sctp_cmd_interpreter(sctp_event_t event_type,
                         * layer which will bail.
                         */
                        error = sctp_cmd_process_init(net, commands, asoc,
-                                                     chunk, cmd->obj.ptr,
-                                                     gfp);
+                                                     chunk, cmd->obj.ptr, gfp);
                        break;
 
                case SCTP_CMD_GEN_COOKIE_ECHO:
-- 
1.7.9.5

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

Reply via email to