36
36
#include "server.h"
37
37
#include "core.h"
38
38
#include "socket.h"
39
+ #include "addr.h"
40
+ #include "msg.h"
39
41
#include <net/sock.h>
40
42
#include <linux/module.h>
41
43
@@ -105,13 +107,11 @@ static void tipc_conn_kref_release(struct kref *kref)
105
107
kernel_bind (sock , (struct sockaddr * )saddr , sizeof (* saddr ));
106
108
sock_release (sock );
107
109
con -> sock = NULL ;
108
-
109
- spin_lock_bh (& s -> idr_lock );
110
- idr_remove (& s -> conn_idr , con -> conid );
111
- s -> idr_in_use -- ;
112
- spin_unlock_bh (& s -> idr_lock );
113
110
}
114
-
111
+ spin_lock_bh (& s -> idr_lock );
112
+ idr_remove (& s -> conn_idr , con -> conid );
113
+ s -> idr_in_use -- ;
114
+ spin_unlock_bh (& s -> idr_lock );
115
115
tipc_clean_outqueues (con );
116
116
kfree (con );
117
117
}
@@ -197,7 +197,8 @@ static void tipc_close_conn(struct tipc_conn *con)
197
197
struct tipc_server * s = con -> server ;
198
198
199
199
if (test_and_clear_bit (CF_CONNECTED , & con -> flags )) {
200
- tipc_unregister_callbacks (con );
200
+ if (con -> sock )
201
+ tipc_unregister_callbacks (con );
201
202
202
203
if (con -> conid )
203
204
s -> tipc_conn_release (con -> conid , con -> usr_data );
@@ -207,8 +208,8 @@ static void tipc_close_conn(struct tipc_conn *con)
207
208
* are harmless for us here as we have already deleted this
208
209
* connection from server connection list.
209
210
*/
210
- kernel_sock_shutdown (con -> sock , SHUT_RDWR );
211
-
211
+ if (con -> sock )
212
+ kernel_sock_shutdown ( con -> sock , SHUT_RDWR );
212
213
conn_put (con );
213
214
}
214
215
}
@@ -487,38 +488,104 @@ void tipc_conn_terminate(struct tipc_server *s, int conid)
487
488
}
488
489
}
489
490
491
+ bool tipc_topsrv_kern_subscr (struct net * net , u32 port , u32 type ,
492
+ u32 lower , u32 upper , int * conid )
493
+ {
494
+ struct tipc_subscriber * scbr ;
495
+ struct tipc_subscr sub ;
496
+ struct tipc_server * s ;
497
+ struct tipc_conn * con ;
498
+
499
+ sub .seq .type = type ;
500
+ sub .seq .lower = lower ;
501
+ sub .seq .upper = upper ;
502
+ sub .timeout = TIPC_WAIT_FOREVER ;
503
+ sub .filter = TIPC_SUB_PORTS ;
504
+ * (u32 * )& sub .usr_handle = port ;
505
+
506
+ con = tipc_alloc_conn (tipc_topsrv (net ));
507
+ if (!con )
508
+ return false;
509
+
510
+ * conid = con -> conid ;
511
+ s = con -> server ;
512
+ scbr = s -> tipc_conn_new (* conid );
513
+ if (!scbr ) {
514
+ tipc_close_conn (con );
515
+ return false;
516
+ }
517
+
518
+ con -> usr_data = scbr ;
519
+ con -> sock = NULL ;
520
+ s -> tipc_conn_recvmsg (net , * conid , NULL , scbr , & sub , sizeof (sub ));
521
+ return true;
522
+ }
523
+
524
+ void tipc_topsrv_kern_unsubscr (struct net * net , int conid )
525
+ {
526
+ struct tipc_conn * con ;
527
+
528
+ con = tipc_conn_lookup (tipc_topsrv (net ), conid );
529
+ if (!con )
530
+ return ;
531
+ tipc_close_conn (con );
532
+ conn_put (con );
533
+ }
534
+
535
+ static void tipc_send_kern_top_evt (struct net * net , struct tipc_event * evt )
536
+ {
537
+ u32 port = * (u32 * )& evt -> s .usr_handle ;
538
+ u32 self = tipc_own_addr (net );
539
+ struct sk_buff_head evtq ;
540
+ struct sk_buff * skb ;
541
+
542
+ skb = tipc_msg_create (TOP_SRV , 0 , INT_H_SIZE , sizeof (* evt ),
543
+ self , self , port , port , 0 );
544
+ if (!skb )
545
+ return ;
546
+ msg_set_dest_droppable (buf_msg (skb ), true);
547
+ memcpy (msg_data (buf_msg (skb )), evt , sizeof (* evt ));
548
+ skb_queue_head_init (& evtq );
549
+ __skb_queue_tail (& evtq , skb );
550
+ tipc_sk_rcv (net , & evtq );
551
+ }
552
+
490
553
static void tipc_send_to_sock (struct tipc_conn * con )
491
554
{
492
- int count = 0 ;
493
555
struct tipc_server * s = con -> server ;
494
556
struct outqueue_entry * e ;
557
+ struct tipc_event * evt ;
495
558
struct msghdr msg ;
559
+ int count = 0 ;
496
560
int ret ;
497
561
498
562
spin_lock_bh (& con -> outqueue_lock );
499
563
while (test_bit (CF_CONNECTED , & con -> flags )) {
500
- e = list_entry (con -> outqueue .next , struct outqueue_entry ,
501
- list );
564
+ e = list_entry (con -> outqueue .next , struct outqueue_entry , list );
502
565
if ((struct list_head * ) e == & con -> outqueue )
503
566
break ;
504
- spin_unlock_bh (& con -> outqueue_lock );
505
567
506
- memset (& msg , 0 , sizeof (msg ));
507
- msg .msg_flags = MSG_DONTWAIT ;
568
+ spin_unlock_bh (& con -> outqueue_lock );
508
569
509
- if (s -> type == SOCK_DGRAM || s -> type == SOCK_RDM ) {
510
- msg .msg_name = & e -> dest ;
511
- msg .msg_namelen = sizeof (struct sockaddr_tipc );
512
- }
513
- ret = kernel_sendmsg (con -> sock , & msg , & e -> iov , 1 ,
514
- e -> iov .iov_len );
515
- if (ret == - EWOULDBLOCK || ret == 0 ) {
516
- cond_resched ();
517
- goto out ;
518
- } else if (ret < 0 ) {
519
- goto send_err ;
570
+ if (con -> sock ) {
571
+ memset (& msg , 0 , sizeof (msg ));
572
+ msg .msg_flags = MSG_DONTWAIT ;
573
+ if (s -> type == SOCK_DGRAM || s -> type == SOCK_RDM ) {
574
+ msg .msg_name = & e -> dest ;
575
+ msg .msg_namelen = sizeof (struct sockaddr_tipc );
576
+ }
577
+ ret = kernel_sendmsg (con -> sock , & msg , & e -> iov , 1 ,
578
+ e -> iov .iov_len );
579
+ if (ret == - EWOULDBLOCK || ret == 0 ) {
580
+ cond_resched ();
581
+ goto out ;
582
+ } else if (ret < 0 ) {
583
+ goto send_err ;
584
+ }
585
+ } else {
586
+ evt = e -> iov .iov_base ;
587
+ tipc_send_kern_top_evt (s -> net , evt );
520
588
}
521
-
522
589
/* Don't starve users filling buffers */
523
590
if (++ count >= MAX_SEND_MSG_COUNT ) {
524
591
cond_resched ();
0 commit comments