@@ -4288,6 +4288,131 @@ int sctp_get_sctp_info(struct sock *sk, struct sctp_association *asoc,
42884288}
42894289EXPORT_SYMBOL_GPL (sctp_get_sctp_info );
42904290
4291+ /* use callback to avoid exporting the core structure */
4292+ int sctp_transport_walk_start (struct rhashtable_iter * iter )
4293+ {
4294+ int err ;
4295+
4296+ err = rhashtable_walk_init (& sctp_transport_hashtable , iter ,
4297+ GFP_KERNEL );
4298+ if (err )
4299+ return err ;
4300+
4301+ err = rhashtable_walk_start (iter );
4302+
4303+ return err == - EAGAIN ? 0 : err ;
4304+ }
4305+
4306+ void sctp_transport_walk_stop (struct rhashtable_iter * iter )
4307+ {
4308+ rhashtable_walk_stop (iter );
4309+ rhashtable_walk_exit (iter );
4310+ }
4311+
4312+ struct sctp_transport * sctp_transport_get_next (struct net * net ,
4313+ struct rhashtable_iter * iter )
4314+ {
4315+ struct sctp_transport * t ;
4316+
4317+ t = rhashtable_walk_next (iter );
4318+ for (; t ; t = rhashtable_walk_next (iter )) {
4319+ if (IS_ERR (t )) {
4320+ if (PTR_ERR (t ) == - EAGAIN )
4321+ continue ;
4322+ break ;
4323+ }
4324+
4325+ if (net_eq (sock_net (t -> asoc -> base .sk ), net ) &&
4326+ t -> asoc -> peer .primary_path == t )
4327+ break ;
4328+ }
4329+
4330+ return t ;
4331+ }
4332+
4333+ struct sctp_transport * sctp_transport_get_idx (struct net * net ,
4334+ struct rhashtable_iter * iter ,
4335+ int pos )
4336+ {
4337+ void * obj = SEQ_START_TOKEN ;
4338+
4339+ while (pos && (obj = sctp_transport_get_next (net , iter )) &&
4340+ !IS_ERR (obj ))
4341+ pos -- ;
4342+
4343+ return obj ;
4344+ }
4345+
4346+ int sctp_for_each_endpoint (int (* cb )(struct sctp_endpoint * , void * ),
4347+ void * p ) {
4348+ int err = 0 ;
4349+ int hash = 0 ;
4350+ struct sctp_ep_common * epb ;
4351+ struct sctp_hashbucket * head ;
4352+
4353+ for (head = sctp_ep_hashtable ; hash < sctp_ep_hashsize ;
4354+ hash ++ , head ++ ) {
4355+ read_lock (& head -> lock );
4356+ sctp_for_each_hentry (epb , & head -> chain ) {
4357+ err = cb (sctp_ep (epb ), p );
4358+ if (err )
4359+ break ;
4360+ }
4361+ read_unlock (& head -> lock );
4362+ }
4363+
4364+ return err ;
4365+ }
4366+ EXPORT_SYMBOL_GPL (sctp_for_each_endpoint );
4367+
4368+ int sctp_transport_lookup_process (int (* cb )(struct sctp_transport * , void * ),
4369+ struct net * net ,
4370+ const union sctp_addr * laddr ,
4371+ const union sctp_addr * paddr , void * p )
4372+ {
4373+ struct sctp_transport * transport ;
4374+ int err = 0 ;
4375+
4376+ rcu_read_lock ();
4377+ transport = sctp_addrs_lookup_transport (net , laddr , paddr );
4378+ if (!transport || !sctp_transport_hold (transport ))
4379+ goto out ;
4380+ err = cb (transport , p );
4381+ sctp_transport_put (transport );
4382+
4383+ out :
4384+ rcu_read_unlock ();
4385+ return err ;
4386+ }
4387+ EXPORT_SYMBOL_GPL (sctp_transport_lookup_process );
4388+
4389+ int sctp_for_each_transport (int (* cb )(struct sctp_transport * , void * ),
4390+ struct net * net , int pos , void * p ) {
4391+ struct rhashtable_iter hti ;
4392+ int err = 0 ;
4393+ void * obj ;
4394+
4395+ if (sctp_transport_walk_start (& hti ))
4396+ goto out ;
4397+
4398+ sctp_transport_get_idx (net , & hti , pos );
4399+ obj = sctp_transport_get_next (net , & hti );
4400+ for (; obj && !IS_ERR (obj ); obj = sctp_transport_get_next (net , & hti )) {
4401+ struct sctp_transport * transport = obj ;
4402+
4403+ if (!sctp_transport_hold (transport ))
4404+ continue ;
4405+ err = cb (transport , p );
4406+ sctp_transport_put (transport );
4407+ if (err )
4408+ break ;
4409+ }
4410+ out :
4411+ sctp_transport_walk_stop (& hti );
4412+ return err ;
4413+ }
4414+ EXPORT_SYMBOL_GPL (sctp_for_each_transport );
4415+
42914416/* 7.2.1 Association Status (SCTP_STATUS)
42924417
42934418 * Applications can retrieve current status information about an
0 commit comments