2 * Connection oriented routing
3 * Copyright (C) 2007-2008 Michael Blizek
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public License
7 * as published by the Free Software Foundation; either version 2
8 * of the License, or (at your option) any later version.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
21 #include <linux/mutex.h>
25 DEFINE_MUTEX(cor_bindnodes
);
26 DEFINE_SPINLOCK(conn_free
);
28 DEFINE_MUTEX(connid_gen
);
39 struct kmem_cache
*conn_slab
;
41 struct htable connid_table
;
42 struct htable reverse_connid_table
;
46 struct kmem_cache
*bindnode_slab
;
47 struct kmem_cache
*connlistener_slab
;
49 /* see cor.h/KP_ACK_CONN */
50 static const __u32 window_sizes
[] = {0,
51 64, 68, 73, 77, 82, 88, 93, 99, 106, 113, 120,
52 128, 136, 145, 155, 165, 175, 187, 199, 212, 226, 240,
53 256, 273, 290, 309, 329, 351, 374, 398, 424, 451, 481,
54 512, 545, 581, 619, 659, 702, 747, 796, 848, 903, 961,
55 1024, 1091, 1162, 1237, 1318, 1403, 1495, 1592, 1695, 1805,
57 2048, 2181, 2323, 2474, 2635, 2806, 2989, 3183, 3390, 3611,
59 4096, 4362, 4646, 4948, 5270, 5613, 5978, 6367, 6781, 7222,
61 8192, 8725, 9292, 9897, 10540, 11226, 11956, 12734, 13562,
63 16384, 17450, 18585, 19793, 21081, 22452, 23912, 25467, 27124,
65 32768, 34899, 37169, 39587, 42161, 44904, 47824, 50935, 54248,
67 65536, 69799, 74338, 79173, 84323, 89807, 95648, 101870, 108495,
69 131072, 139597, 148677, 158347, 168646, 179615, 191297, 203739,
70 216991, 231104, 246135,
71 262144, 279194, 297353, 316693, 337291, 359229, 382594, 407478,
72 433981, 462208, 492270,
73 524288, 558388, 594706, 633387, 674583, 718459, 765188, 814957,
74 867962, 924415, 984540,
75 1048576, 1116777, 1189413, 1266774, 1349166, 1436917, 1530376,
76 1629913, 1735924, 1848831, 1969081,
77 2097152, 2233553, 2378826, 2533547, 2698332, 2873834, 3060752,
78 3259826, 3471849, 3697662, 3938162,
79 4194304, 4467106, 4757652, 5067094, 5396664, 5747669, 6121503,
80 6519652, 6943698, 7395323, 7876323,
81 8388608, 8934212, 9515303, 10134189, 10793327, 11495337,
82 12243006, 13039305, 13887396, 14790647,
84 16777216, 17868424, 19030606, 20268378, 21586655, 22990674,
85 24486013, 26078610, 27774791, 29581294,
87 33554432, 35736849, 38061212, 40536755, 43173310, 45981349,
88 48972026, 52157220, 55549582, 59162588,
90 67108864, 71473698, 76122425, 81073510, 86346620, 91962698,
91 97944052, 104314440, 111099165, 118325175,
93 134217728, 142947395, 152244850, 162147020, 172693239,
94 183925396, 195888104, 208628880, 222198329,
96 268435456, 285894791, 304489699, 324294041, 345386479,
97 367850791, 391776208, 417257759, 444396658,
99 536870912, 571789581};
101 __u8
enc_window(__u32 window_bytes
)
104 BUG_ON(window_sizes
[255] != 571789581);
105 for (i
=1;i
<256;i
++) {
106 if (window_sizes
[i
] > window_bytes
)
110 return (__u8
)(i
-1); /* round down */
113 __u32
dec_window(__u8 window
)
115 BUG_ON(window_sizes
[255] != 571789581);
116 return window_sizes
[window
];
119 static inline int hdr_size(void)
121 return ((sizeof(struct cell_hdr
) + sizeof(void *) - 1) / sizeof(void *)
125 static inline int elements_per_cell(int cell_size
)
127 return (cell_size
- hdr_size())/sizeof(void *);
130 static inline struct cell_hdr
*cell_addr(struct htable
*ht
, __u32 id
)
132 int idx
= (id
%ht
->htable_size
) / (elements_per_cell(ht
->cell_size
));
133 return (struct cell_hdr
*) (((char *)ht
->htable
) + ht
->cell_size
* idx
);
136 static inline char **element_addr(struct htable
*ht
, __u32 id
)
138 int idx
= (id
%ht
->htable_size
) % (elements_per_cell(ht
->cell_size
));
140 ( ((char *)cell_addr(ht
, id
)) +
141 hdr_size() + idx
*sizeof(void *) );
145 static inline char **next_element(struct htable
*ht
, char *element
)
147 return (char **)(element
+ ht
->entry_offset
);
150 static inline struct kref
*element_kref(struct htable
*ht
, char *element
)
152 return (struct kref
*)(element
+ ht
->kref_offset
);
156 static inline void unlock_element(struct htable
*ht
, __u32 key
)
158 struct cell_hdr
*hdr
= cell_addr(ht
, key
);
159 spin_unlock( &(hdr
->lock
) );
163 static char **get_element_nounlock(struct htable
*ht
, __u32 key
,
166 struct cell_hdr
*hdr
= cell_addr(ht
, key
);
167 char **element
= element_addr(ht
, key
);
169 BUG_ON(0 == element
);
171 spin_lock( &(hdr
->lock
) );
176 if (searcheditem
!= 0 && ht
->matches(*element
, searcheditem
))
178 element
= next_element(ht
, *element
);
184 char *htable_get(struct htable
*ht
, __u32 key
, void *searcheditem
)
186 unsigned long iflags
;
189 if (unlikely(ht
->htable
== 0))
192 local_irq_save(iflags
);
193 element
= *(get_element_nounlock(ht
, key
, searcheditem
));
194 if (likely(element
!= 0))
195 kref_get(element_kref(ht
, element
));
196 unlock_element(ht
, key
);
197 local_irq_restore(iflags
);
202 int htable_delete(struct htable
*ht
, __u32 key
,
203 void *searcheditem
, void (*free
) (struct kref
*ref
))
205 unsigned long iflags
;
210 if (unlikely(ht
->htable
== 0))
213 local_irq_save(iflags
);
215 element
= get_element_nounlock(ht
, key
, searcheditem
);
216 BUG_ON(0 == element
);
218 if (unlikely(*element
== 0)) {
219 /* key not in table */
224 next
= next_element(ht
, *element
);
225 kref_put(element_kref(ht
, *element
), free
);
229 unlock_element(ht
, key
);
230 local_irq_restore(iflags
);
235 void htable_insert(struct htable
*ht
, char *newelement
, __u32 key
)
237 unsigned long iflags
;
240 if (unlikely(ht
->htable
== 0))
243 BUG_ON(*next_element(ht
, newelement
) != 0);
244 local_irq_save(iflags
);
246 element
= get_element_nounlock(ht
, key
, 0);
248 BUG_ON(element
== 0);
249 BUG_ON(*element
!= 0);
251 *element
= newelement
;
252 kref_get(element_kref(ht
, newelement
));
254 unlock_element(ht
, key
);
255 local_irq_restore(iflags
);
259 void htable_init(struct htable
*ht
, int (*matches
)(void *htentry
,
260 void *searcheditem
), __u32 entry_offset
, __u32 kref_offset
)
267 ht
->htable
= kmalloc(PAGE_SIZE
, GFP_KERNEL
);
268 if (unlikely(ht
->htable
== 0)) {
269 printk(KERN_CRIT
"cor: error allocating htable (out of "
273 memset(ht
->htable
, 0, PAGE_SIZE
);
276 num_cells
= PAGE_SIZE
/ht
->cell_size
;
278 for (j
=0;j
<num_cells
;j
++) {
279 struct cell_hdr
*hdr
= (struct cell_hdr
*)
280 ( ((char *) ht
->htable
) + j
* ht
->cell_size
);
281 spin_lock_init(&(hdr
->lock
));
284 ht
->htable_size
= num_cells
* elements_per_cell(ht
->cell_size
);
285 ht
->num_elements
= 0;
287 ht
->matches
= matches
;
288 ht
->entry_offset
= entry_offset
;
289 ht
->kref_offset
= kref_offset
;
292 struct reverse_connid_matchparam
{
297 static __u32
rcm_to_key(struct reverse_connid_matchparam
*rcm
)
299 return (((__u32
) rcm
->nb
) ^ rcm
->conn_id
);
302 static int matches_reverse_connid(void *htentry
, void *searcheditem
)
304 struct conn
*conn
= (struct conn
*) htentry
;
305 struct reverse_connid_matchparam
*rcm
=
306 (struct reverse_connid_matchparam
*) searcheditem
;
307 BUG_ON(conn
->targettype
!= TARGET_OUT
);
308 return (conn
->target
.out
.nb
== rcm
->nb
) &&
309 (conn
->target
.out
.conn_id
== rcm
->conn_id
);
312 struct conn
*get_conn_reverse(struct neighbor
*nb
, __u32 conn_id
)
314 struct reverse_connid_matchparam rcm
;
316 rcm
.conn_id
= conn_id
;
318 return (struct conn
*) htable_get(&reverse_connid_table
,
319 rcm_to_key(&rcm
), &rcm
);
322 void insert_reverse_connid(struct conn
*rconn
)
324 struct reverse_connid_matchparam rcm
;
326 BUG_ON(rconn
->targettype
!= TARGET_OUT
);
328 rcm
.nb
= rconn
->target
.out
.nb
;
329 rcm
.conn_id
= rconn
->target
.out
.conn_id
;
330 htable_insert(&reverse_connid_table
, (char *) rconn
, rcm_to_key(&rcm
));
333 struct conn
*get_conn(__u32 conn_id
)
335 return (struct conn
*) htable_get(&connid_table
, conn_id
, &conn_id
);
338 static int connid_alloc(struct conn
*sconn
)
343 BUG_ON(sconn
->sourcetype
!= SOURCE_IN
);
345 mutex_lock(&connid_gen
);
350 get_random_bytes((char *) &conn_id
, sizeof(conn_id
));
352 if (unlikely(conn_id
== 0))
355 tmp
= get_conn(conn_id
);
356 if (unlikely(tmp
!= 0)) {
357 kref_put(&(tmp
->ref
), free_conn
);
363 mutex_unlock(&connid_gen
);
368 sconn
->source
.in
.conn_id
= conn_id
;
369 htable_insert(&connid_table
, (char *) sconn
, conn_id
);
370 mutex_unlock(&connid_gen
);
374 void free_conn(struct kref
*ref
)
376 unsigned long iflags
;
377 struct conn
*conn
= container_of(ref
, struct conn
, ref
);
378 struct conn
*reversedir
= 0;
380 BUG_ON(atomic_read(&(conn
->isreset
)) == 0);
382 spin_lock_irqsave(&conn_free
, iflags
);
384 if (conn
->reversedir
!= 0)
385 atomic_set(&(conn
->reversedir
->isreset
), 3);
387 if (atomic_read(&(conn
->isreset
)) != 3)
390 if (conn
->reversedir
!= 0) {
391 conn
->reversedir
->reversedir
= 0;
392 reversedir
= conn
->reversedir
;
393 conn
->reversedir
= 0;
396 if (conn
->sourcetype
== SOURCE_IN
) {
397 kref_put(&(conn
->source
.in
.nb
->ref
), neighbor_free
);
398 conn
->source
.in
.nb
= 0;
401 if (conn
->targettype
== TARGET_OUT
) {
402 kref_put(&(conn
->target
.out
.nb
->ref
), neighbor_free
);
403 conn
->target
.out
.nb
= 0;
406 databuf_free(&(conn
->buf
));
408 kmem_cache_free(conn_slab
, conn
);
410 atomic_dec(&num_conns
);
413 spin_unlock_irqrestore(&conn_free
, iflags
);
416 free_conn(&(reversedir
->ref
));
420 * rconn ==> the connection we received the commend from
421 * ==> init rconn->target.out + rconn->reversedir->source.in
423 * rc == 1 ==> connid allocation failed
425 * NOTE: call to this func *must* be protected by rcv_lock
427 int conn_init_out(struct conn
*rconn
, struct neighbor
*nb
)
430 struct conn
*sconn
= rconn
->reversedir
;
431 __u32 stall_timeout_ms
= rconn
->target
.unconnected
.stall_timeout_ms
;
433 mutex_lock(&(sconn
->rcv_lock
));
435 BUG_ON(rconn
->targettype
!= TARGET_UNCONNECTED
);
437 BUG_ON(sconn
->sourcetype
!= SOURCE_NONE
);
439 memset(&(rconn
->target
.out
), 0, sizeof(rconn
->target
.out
));
440 memset(&(sconn
->source
.in
), 0, sizeof(sconn
->source
.in
));
442 rconn
->targettype
= TARGET_OUT
;
443 sconn
->sourcetype
= SOURCE_IN
;
445 rconn
->target
.out
.nb
= nb
;
446 sconn
->source
.in
.nb
= nb
;
448 /* neighbor pointer */
449 kref_get(&(nb
->ref
));
450 kref_get(&(nb
->ref
));
452 rconn
->target
.out
.stall_timeout_ms
= stall_timeout_ms
;
453 skb_queue_head_init(&(sconn
->source
.in
.reorder_queue
));
454 atomic_set(&(sconn
->source
.in
.pong_awaiting
), 0);
455 atomic_set(&(sconn
->source
.in
.usage_reserve
), 0);
457 if (unlikely(connid_alloc(sconn
))) {
462 INIT_LIST_HEAD(&(rconn
->target
.out
.retrans_list
));
464 reset_seqno(&(rconn
->buf
));
466 mutex_lock(&(nb
->conn_list_lock
));
467 list_add_tail(&(sconn
->source
.in
.nb_list
), &(nb
->rcv_conn_list
));
468 list_add_tail(&(rconn
->target
.out
.nb_list
), &(nb
->snd_conn_list
));
469 nb
->num_send_conns
++;
470 mutex_unlock(&(nb
->conn_list_lock
));
473 kref_get(&(rconn
->ref
));
474 kref_get(&(sconn
->ref
));
477 mutex_unlock(&(sconn
->rcv_lock
));
482 void conn_init_sock_source(struct conn
*conn
)
485 conn
->sourcetype
= SOURCE_SOCK
;
486 memset(&(conn
->source
.sock
), 0, sizeof(conn
->source
.sock
));
487 init_waitqueue_head(&(conn
->source
.sock
.wait
));
490 void conn_init_sock_target(struct conn
*conn
)
493 conn
->targettype
= TARGET_SOCK
;
494 memset(&(conn
->target
.sock
), 0, sizeof(conn
->target
.sock
));
495 init_waitqueue_head(&(conn
->target
.sock
.wait
));
496 reset_seqno(&(conn
->buf
));
499 struct conn
* alloc_conn(gfp_t allocflags
)
501 struct conn
*rconn
= 0;
502 struct conn
*sconn
= 0;
504 rconn
= kmem_cache_alloc(conn_slab
, allocflags
);
505 if (unlikely(rconn
== 0))
508 sconn
= kmem_cache_alloc(conn_slab
, allocflags
);
509 if (unlikely(sconn
== 0))
512 atomic_add(2, &num_conns
);
514 memset(rconn
, 0, sizeof(struct conn
));
515 memset(sconn
, 0, sizeof(struct conn
));
517 rconn
->reversedir
= sconn
;
518 sconn
->reversedir
= rconn
;
520 kref_init(&(rconn
->ref
));
521 kref_init(&(sconn
->ref
));
523 rconn
->sockstate
= SOCKSTATE_CONN
;
524 sconn
->sockstate
= SOCKSTATE_CONN
;
526 rconn
->sourcetype
= SOURCE_NONE
;
527 sconn
->sourcetype
= SOURCE_NONE
;
528 rconn
->targettype
= TARGET_UNCONNECTED
;
529 sconn
->targettype
= TARGET_UNCONNECTED
;
531 mutex_init(&(rconn
->rcv_lock
));
532 mutex_init(&(sconn
->rcv_lock
));
534 rconn
->target
.unconnected
.stall_timeout_ms
=
535 CONN_STALL_DEFAULT_TIMEOUT_MS
;
536 sconn
->target
.unconnected
.stall_timeout_ms
=
537 CONN_STALL_DEFAULT_TIMEOUT_MS
;
539 databuf_init(&(rconn
->buf
));
540 databuf_init(&(sconn
->buf
));
542 rconn
->jiffies_credit_update
= jiffies
;
543 rconn
->jiffies_credit_update
= rconn
->jiffies_credit_update
;
548 kmem_cache_free(conn_slab
, rconn
);
553 static struct connlistener
*get_connlistener(__be64 port
)
555 struct list_head
*curr
= openports
.next
;
557 while (curr
!= &openports
) {
558 struct bindnode
*currnode
= ((struct bindnode
*)
559 (((char *)curr
) - offsetof(struct bindnode
, lh
)));
560 if (currnode
->port
== port
) {
561 BUG_ON(currnode
->owner
== 0);
562 return currnode
->owner
;
571 void close_port(struct connlistener
*listener
)
573 mutex_lock(&cor_bindnodes
);
575 if (listener
->bn
!= 0) {
576 list_del(&(listener
->bn
->lh
));
577 kmem_cache_free(bindnode_slab
, listener
->bn
);
581 while (list_empty(&(listener
->conn_queue
)) == 0) {
582 struct conn
*rconn
= container_of(listener
->conn_queue
.next
,
583 struct conn
, source
.sock
.cl_list
);
584 list_del(&(rconn
->source
.sock
.cl_list
));
585 atomic_cmpxchg(&(rconn
->reversedir
->isreset
), 0, 1);
587 kref_put(&(rconn
->ref
), free_conn
);
590 kmem_cache_free(connlistener_slab
, listener
);
592 mutex_unlock(&cor_bindnodes
);
595 struct connlistener
*open_port(__be64 port
)
598 struct bindnode
*bn
= 0;
599 struct connlistener
*listener
= 0;
601 mutex_lock(&cor_bindnodes
);
602 if (get_connlistener(port
) != 0)
606 bn
= kmem_cache_alloc(bindnode_slab
, GFP_KERNEL
);
607 listener
= kmem_cache_alloc(connlistener_slab
, GFP_KERNEL
);
609 memset(bn
, 0, sizeof(struct bindnode
));
610 memset(listener
, 0, sizeof(struct connlistener
));
612 bn
->owner
= listener
;
615 /* kref is not actually used */
616 listener
->sockstate
= SOCKSTATE_LISTENER
;
618 mutex_init(&(listener
->lock
));
619 INIT_LIST_HEAD(&(listener
->conn_queue
));
620 init_waitqueue_head(&(listener
->wait
));
622 list_add_tail((struct list_head
*) &(bn
->lh
), &openports
);
625 mutex_unlock(&cor_bindnodes
);
632 * rc == 2 port not open
633 * rc == 3 listener queue full
635 int connect_port(struct conn
*rconn
, __be64 port
)
638 struct connlistener
*listener
;
641 mutex_lock(&cor_bindnodes
);
643 listener
= get_connlistener(port
);
649 mutex_lock(&(listener
->lock
));
651 if (unlikely(listener
->queue_len
>= listener
->queue_maxlen
)) {
652 if (listener
->queue_maxlen
<= 0)
660 kref_get(&(rconn
->reversedir
->ref
));
662 mutex_lock(&(rconn
->rcv_lock
));
663 mutex_lock(&(rconn
->reversedir
->rcv_lock
));
664 conn_init_sock_target(rconn
);
665 conn_init_sock_source(rconn
->reversedir
);
666 mutex_unlock(&(rconn
->reversedir
->rcv_lock
));
667 mutex_unlock(&(rconn
->rcv_lock
));
669 list_add_tail(&(rconn
->reversedir
->source
.sock
.cl_list
),
670 &(listener
->conn_queue
));
671 listener
->queue_len
++;
672 wake_up_interruptible(&(listener
->wait
));
675 mutex_unlock(&(listener
->lock
));
678 mutex_unlock(&cor_bindnodes
);
684 * rc == 2 addrtype not found
685 * rc == 3 addr not found
686 * rc == 4 ==> connid allocation failed
687 * rc == 5 ==> control msg alloc failed
689 int connect_neigh(struct conn
*rconn
,
690 __u16 addrtypelen
, __u8
*addrtype
,
691 __u16 addrlen
, __u8
*addr
)
694 struct control_msg_out
*cm
;
695 struct neighbor
*nb
= find_neigh(addrtypelen
, addrtype
, addrlen
, addr
);
698 if (unlikely(conn_init_out(rconn
, nb
))) {
703 cm
= alloc_control_msg(nb
, ACM_PRIORITY_HIGH
);
704 if (unlikely(cm
== 0)) {
709 send_connect_nb(cm
, rconn
->reversedir
->source
.in
.conn_id
,
710 get_window(rconn
->reversedir
));
713 kref_put(&(nb
->ref
), neighbor_free
);
718 static int _reset_conn(struct conn
*conn
)
721 * aktive conns have an additional ref to make sure that they are not
722 * freed when only one direction is referenced by the connid hashtable
725 int isreset
= atomic_cmpxchg(&(conn
->isreset
), 0, 2);
727 isreset
= atomic_cmpxchg(&(conn
->isreset
), 1, 2);
729 if (isreset
== 2 || isreset
== 3)
732 /* lock sourcetype/targettype */
733 mutex_lock(&(conn
->rcv_lock
));
735 if (conn
->sourcetype
== SOURCE_IN
) {
736 mutex_lock(&(conn
->source
.in
.nb
->conn_list_lock
));
737 list_del(&(conn
->source
.in
.nb_list
));
738 mutex_unlock(&(conn
->source
.in
.nb
->conn_list_lock
));
740 #warning todo reset bufferlimits/space
744 if (conn
->source
.in
.conn_id
!= 0) {
745 if (htable_delete(&connid_table
,
746 conn
->source
.in
.conn_id
,
747 &(conn
->source
.in
.conn_id
), free_conn
)){
748 printk(KERN_ERR
"error in _reset_conn: "
749 "htable_delete src_in failed");
751 conn
->source
.in
.conn_id
= 0;
753 } else if (conn
->sourcetype
== SOURCE_SOCK
) {
754 wake_up_interruptible(&(conn
->source
.sock
.wait
));
757 if (conn
->targettype
== TARGET_OUT
) {
758 mutex_lock(&(conn
->target
.out
.nb
->conn_list_lock
));
759 list_del(&(conn
->target
.out
.nb_list
));
760 conn
->target
.out
.nb
->num_send_conns
--;
761 BUG_ON(conn
->target
.out
.nb
->num_send_conns
< 0);
762 mutex_unlock(&(conn
->target
.out
.nb
->conn_list_lock
));
766 if (conn
->target
.out
.conn_id
!= 0) {
767 struct reverse_connid_matchparam rcm
;
768 rcm
.nb
= conn
->target
.out
.nb
;
769 rcm
.conn_id
= conn
->target
.out
.conn_id
;
770 if (htable_delete(&reverse_connid_table
,
773 printk(KERN_ERR
"error in _reset_conn: "
774 "htable_delete target_out "
779 if (isreset
== 0 && conn
->target
.out
.conn_id
!= 0) {
780 struct control_msg_out
*cm
= alloc_control_msg(
781 conn
->target
.out
.nb
, ACM_PRIORITY_HIGH
);
782 if (unlikely(cm
== 0))
783 send_ping_all_conns(conn
->target
.out
.nb
);
785 send_reset_conn(cm
, conn
->target
.out
.conn_id
);
788 conn
->target
.out
.conn_id
= 0;
790 cancel_retrans(conn
);
791 } else if (conn
->targettype
== TARGET_SOCK
) {
792 wake_up_interruptible(&(conn
->target
.sock
.wait
));
795 databuf_free(&(conn
->buf
));
797 mutex_unlock(&(conn
->rcv_lock
));
802 /* warning: do not hold the rcv_lock while calling this! */
803 void reset_conn(struct conn
*conn
)
805 int put1
= _reset_conn(conn
);
806 int put2
= _reset_conn(conn
->reversedir
);
808 /*free_conn may not be called, before both _reset_conn have finished */
810 kref_put(&(conn
->ref
), free_conn
);
815 kref_put(&(conn
->reversedir
->ref
), free_conn
);
820 static int matches_connid_in(void *htentry
, void *searcheditem
)
822 struct conn
*conn
= (struct conn
*) htentry
;
823 __u32 conn_id
= *((__u32
*) searcheditem
);
824 BUG_ON(conn
->sourcetype
!= SOURCE_IN
);
825 return (conn
->source
.in
.conn_id
== conn_id
);
828 static int __init
cor_common_init(void)
834 printk(KERN_ERR
"sizeof conn: %d", sizeof(c
));
835 printk(KERN_ERR
" conn.source: %d", sizeof(c
.source
));
836 printk(KERN_ERR
" conn.target: %d", sizeof(c
.target
));
837 printk(KERN_ERR
" conn.target.out: %d", sizeof(c
.target
.out
));
838 printk(KERN_ERR
" conn.buf: %d", sizeof(c
.buf
));
840 printk(KERN_ERR
" mutex: %d", sizeof(struct mutex
));
841 printk(KERN_ERR
" spinlock: %d", sizeof(spinlock_t
));
842 printk(KERN_ERR
" kref: %d", sizeof(struct kref
));
844 conn_slab
= kmem_cache_create("cor_conn", sizeof(struct conn
), 8, 0, 0);
845 htable_init(&connid_table
, matches_connid_in
,
846 offsetof(struct conn
, source
.in
.htab_entry
),
847 offsetof(struct conn
, ref
));
849 htable_init(&reverse_connid_table
, matches_reverse_connid
,
850 offsetof(struct conn
, source
.in
.htab_entry
),
851 offsetof(struct conn
, ref
));
853 bindnode_slab
= kmem_cache_create("cor_bindnode",
854 sizeof(struct bindnode
), 8, 0, 0);
855 connlistener_slab
= kmem_cache_create("cor_connlistener",
856 sizeof(struct connlistener
), 8, 0, 0);
865 if (unlikely(rc
!= 0))
868 rc
= cor_neighbor_init();
869 if (unlikely(rc
!= 0))
873 if (unlikely(rc
!= 0))
879 module_init(cor_common_init
);
880 MODULE_LICENSE("GPL");