conn rcv_lock converted to spinlock, struct cor_sock created, kernel_packet skb_clone...
[cor_2_6_31.git] / net / cor / kpacket_gen.c
blob4b2199a4e1b89d1ede844723a791d1d8cda88844
1 /**
2 * Connection oriented routing
3 * Copyright (C) 2007-2011 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
18 * 02110-1301, USA.
21 #include <asm/byteorder.h>
23 #include "cor.h"
25 /* not sent over the network - internal meaning only */
26 #define MSGTYPE_PONG 1
27 #define MSGTYPE_ACK 2
28 #define MSGTYPE_ACK_CONN 3
29 #define MSGTYPE_CONNECT 4
30 #define MSGTYPE_CONNECT_SUCCESS 5
31 #define MSGTYPE_RESET_CONN 6
32 #define MSGTYPE_CONNDATA 7
33 #define MSGTYPE_CONNID_UNKNOWN 8
34 #define MSGTYPE_SET_MAX_CMSG_DELAY 9
36 #define MSGTYPE_PONG_TIMEENQUEUED 1
37 #define MSGTYPE_PONG_RESPDELAY 2
39 struct control_msg_out{
40 struct list_head lh; /* either neighbor or control_retrans_packet */
41 struct neighbor *nb;
43 struct kref ref;
45 unsigned long timeout;
47 __u32 length;
49 __u8 type;
50 union{
51 struct{
53 __u32 cookie;
54 __u8 type;
56 union {
57 ktime_t time_enqueued;
58 __u32 respdelay;
59 } delaycomp;
60 }pong;
62 struct{
63 __u32 seqno;
64 }ack;
66 struct{
67 struct conn *src_in;
68 struct list_head conn_acks;
69 __u32 conn_id;
70 __u32 seqno;
71 __u32 seqno_ooo;
72 __u32 length;
74 __u16 decaytime;
75 __u8 decaytime_seqno;
77 __u8 flags;
79 __u32 ack_seqno;
80 }ack_conn;
82 struct{
83 __u32 conn_id;
84 __u32 init_seqno;
85 struct conn *src_in;
86 }connect;
88 struct{
89 __u32 rcvd_conn_id;
90 __u32 gen_conn_id;
91 __u32 init_seqno;
92 struct conn *src_in;
93 }connect_success;
95 struct{
96 struct htab_entry htab_entry;
97 __u32 conn_id_reset;
98 __u32 conn_id_unknown;
99 }reset_connidunknown;
101 struct{
102 __u32 conn_id;
103 __u32 seqno;
104 char *data_orig;
105 char *data;
106 __u32 datalen;
107 }conn_data;
109 struct{
110 __u32 delay;
111 }set_max_cmsg_delay;
112 }msg;
115 struct control_retrans {
116 struct kref ref;
118 struct neighbor *nb;
119 __u32 seqno;
121 unsigned long timeout;
123 struct list_head msgs;
125 struct htab_entry htab_entry;
126 struct list_head timeout_list;
129 struct unknownconnid_matchparam {
130 struct neighbor *nb;
131 __u32 conn_id;
134 struct retransmit_matchparam {
135 struct neighbor *nb;
136 __u32 seqno;
140 struct kmem_cache *controlmsg_slab;
141 struct kmem_cache *controlretrans_slab;
143 static struct htable retransmits;
145 DEFINE_SPINLOCK(unknown_connids_lock);
146 static struct htable unknown_connids;
148 atomic_t cmcnt = ATOMIC_INIT(0);
151 static void add_control_msg(struct control_msg_out *msg, int retrans);
153 static void try_merge_ackconns(struct conn *src_in_l,
154 struct control_msg_out *cm);
156 static void mergeadd_ackconn(struct conn *src_in_l, struct control_msg_out *cm);
159 static __u32 ucm_to_key(struct unknownconnid_matchparam *ucm)
161 return ((__u32)((long) ucm->nb)) ^ ucm->conn_id;
164 static __u32 rm_to_key(struct retransmit_matchparam *rm)
166 return ((__u32)((long) rm->nb)) ^ rm->seqno;
169 static inline int isurgent(struct control_msg_out *cm)
171 if (unlikely(cm->type == MSGTYPE_PONG || cm->type == MSGTYPE_ACK))
172 return 1;
173 return 0;
176 static struct control_msg_out *__alloc_control_msg(void)
178 struct control_msg_out *cm = kmem_cache_alloc(controlmsg_slab,
179 GFP_ATOMIC);
180 if (unlikely(cm == 0))
181 return 0;
182 memset(cm, 0, sizeof(struct control_msg_out));
183 cm->lh.next = LIST_POISON1;
184 cm->lh.prev = LIST_POISON2;
185 kref_init(&(cm->ref));
186 return cm;
189 static int calc_limit(int limit, int priority)
191 if (priority == ACM_PRIORITY_LOW)
192 return (limit+2)/3;
193 else if (priority == ACM_PRIORITY_MED)
194 return (limit * 2 + 1)/3;
195 else if (priority == ACM_PRIORITY_HIGH)
196 return limit;
197 else
198 BUG();
201 int may_alloc_control_msg(struct neighbor *nb, int priority)
203 long packets1 = atomic_read(&(nb->cmcnt));
204 long packets2 = atomic_read(&(cmcnt));
206 BUG_ON(packets1 < 0);
207 BUG_ON(packets2 < 0);
209 if (packets1 < calc_limit(GUARANTEED_CMSGS_PER_NEIGH, priority))
210 return 1;
212 if (unlikely(unlikely(packets2 >= calc_limit(MAX_CMSGS_PER_NEIGH,
213 priority)) || unlikely(packets1 >= (
214 calc_limit(MAX_CMSGS_PER_NEIGH, priority) *
215 (MAX_CMSGS - packets2) / MAX_CMSGS))))
216 return 0;
217 return 1;
220 static struct control_msg_out *_alloc_control_msg(struct neighbor *nb,
221 int priority, int urgent)
223 struct control_msg_out *cm = 0;
225 BUG_ON(nb == 0);
227 if (urgent == 0) {
228 long packets1 = atomic_inc_return(&(nb->cmcnt));
229 long packets2 = atomic_inc_return(&(cmcnt));
231 BUG_ON(packets1 <= 0);
232 BUG_ON(packets2 <= 0);
234 if (packets1 <= calc_limit(GUARANTEED_CMSGS_PER_NEIGH,
235 priority))
236 goto alloc;
238 if (unlikely(unlikely(packets2 > calc_limit(MAX_CMSGS_PER_NEIGH,
239 priority)) || unlikely(packets1 > (
240 calc_limit(MAX_CMSGS_PER_NEIGH, priority) *
241 (MAX_CMSGS - packets2) / MAX_CMSGS))))
242 goto full;
245 alloc:
246 cm = __alloc_control_msg();
247 if (unlikely(cm == 0))
248 goto full;
249 cm->nb = nb;
251 if (0) {
252 full:
253 if (urgent == 0) {
254 atomic_dec(&(nb->cmcnt));
255 atomic_dec(&(cmcnt));
258 return cm;
261 struct control_msg_out *alloc_control_msg(struct neighbor *nb, int priority)
263 return _alloc_control_msg(nb, priority, 0);
266 static void cmsg_kref_free(struct kref *ref)
268 struct control_msg_out *cm = container_of(ref, struct control_msg_out,
269 ref);
270 kmem_cache_free(controlmsg_slab, cm);
273 void free_control_msg(struct control_msg_out *cm)
275 if (isurgent(cm) == 0) {
276 atomic_dec(&(cm->nb->cmcnt));
277 atomic_dec(&(cmcnt));
280 if (cm->type == MSGTYPE_ACK_CONN) {
281 struct conn *trgt_out = cm->msg.ack_conn.src_in->reversedir;
282 BUG_ON(cm->msg.ack_conn.src_in == 0);
283 spin_lock_bh(&(trgt_out->rcv_lock));
284 BUG_ON(trgt_out->targettype != TARGET_OUT);
285 if ((cm->msg.ack_conn.flags & KP_ACK_CONN_FLAGS_CREDITS) != 0 &&
286 trgt_out->target.out.decaytime_send_allowed !=
287 0) {
288 trgt_out->target.out.decaytime_send_allowed = 1;
289 spin_unlock_bh(&(trgt_out->rcv_lock));
290 refresh_conn_credits(trgt_out, 0, 0);
291 } else {
292 spin_unlock_bh(&(trgt_out->rcv_lock));
295 kref_put(&(cm->msg.ack_conn.src_in->ref), free_conn);
296 cm->msg.ack_conn.src_in = 0;
297 } else if (cm->type == MSGTYPE_CONNECT) {
298 BUG_ON(cm->msg.connect.src_in == 0);
299 kref_put(&(cm->msg.connect.src_in->ref), free_conn);
300 cm->msg.connect.src_in = 0;
301 } else if (cm->type == MSGTYPE_CONNECT_SUCCESS) {
302 BUG_ON(cm->msg.connect_success.src_in == 0);
303 kref_put(&(cm->msg.connect_success.src_in->ref), free_conn);
304 cm->msg.connect_success.src_in = 0;
305 } else if (cm->type == MSGTYPE_RESET_CONN ||
306 cm->type == MSGTYPE_CONNID_UNKNOWN) {
307 struct unknownconnid_matchparam ucm;
309 ucm.nb = cm->nb;
310 ucm.conn_id = cm->msg.reset_connidunknown.conn_id_unknown;
312 htable_delete(&unknown_connids, ucm_to_key(&ucm), &ucm,
313 cmsg_kref_free);
316 kref_put(&(cm->ref), cmsg_kref_free);
319 static void free_control_retrans(struct kref *ref)
321 struct control_retrans *cr = container_of(ref, struct control_retrans,
322 ref);
324 while (list_empty(&(cr->msgs)) == 0) {
325 struct control_msg_out *cm = container_of(cr->msgs.next,
326 struct control_msg_out, lh);
327 list_del(&(cm->lh));
328 free_control_msg(cm);
331 kmem_cache_free(controlretrans_slab, cr);
335 static void set_retrans_timeout(struct control_retrans *cr, struct neighbor *nb)
337 cr->timeout = jiffies + usecs_to_jiffies(100000 +
338 ((__u32) atomic_read(&(nb->latency))) * 2 +
339 ((__u32) atomic_read(&(nb->max_remote_cmsg_delay))));
342 static void remove_connack_oooflag_ifold(struct conn *src_in_l,
343 struct control_msg_out *cm)
345 if (ooolen(cm->msg.ack_conn.flags) != 0 && seqno_before_eq(
346 cm->msg.ack_conn.seqno_ooo +
347 cm->msg.ack_conn.length,
348 src_in_l->source.in.next_seqno)) {
349 cm->msg.ack_conn.length = 0;
350 cm->msg.ack_conn.flags = (cm->msg.ack_conn.flags &
351 (~KP_ACK_CONN_FLAGS_OOO));
355 static int ackconn_prepare_readd(struct conn *cn_l,
356 struct control_msg_out *cm)
358 if (unlikely(unlikely(cn_l->sourcetype != SOURCE_IN) ||
359 unlikely(cn_l->source.in.nb != cm->nb) ||
360 unlikely(cn_l->reversedir->target.out.conn_id !=
361 cm->msg.ack_conn.conn_id) ||
362 unlikely(cn_l->isreset != 0)))
363 return 0;
365 remove_connack_oooflag_ifold(cn_l, cm);
367 if (cm->msg.ack_conn.ack_seqno != cn_l->source.in.ack_seqno)
368 cm->msg.ack_conn.flags = (cm->msg.ack_conn.flags &
369 (~KP_ACK_CONN_FLAGS_SEQNO) &
370 (~KP_ACK_CONN_FLAGS_WINDOW));
372 if (cm->msg.ack_conn.flags == 0)
373 return 0;
375 cm->length = 6 + ack_conn_len(cm->msg.ack_conn.flags);
377 return 1;
380 static void readd_control_retrans(struct control_retrans *cr)
382 while (list_empty(&(cr->msgs)) == 0) {
383 struct control_msg_out *cm = container_of(cr->msgs.next,
384 struct control_msg_out, lh);
385 list_del(&(cm->lh));
386 if (cm->type == MSGTYPE_ACK_CONN) {
387 struct conn *cn_l = cm->msg.ack_conn.src_in;
388 spin_lock_bh(&(cn_l->rcv_lock));
389 if (unlikely(ackconn_prepare_readd(cn_l, cm) == 0)) {
390 free_control_msg(cm);
391 } else {
392 mergeadd_ackconn(cn_l, cm);
395 spin_unlock_bh(&(cn_l->rcv_lock));
396 } else {
397 add_control_msg(cm, 1);
402 void retransmit_taskfunc(unsigned long arg)
404 struct neighbor *nb = (struct neighbor *) arg;
405 unsigned long iflags;
407 int nbstate;
408 int nbput = 0;
410 spin_lock_irqsave(&(nb->state_lock), iflags);
411 nbstate = nb->state;
412 spin_unlock_irqrestore(&(nb->state_lock), iflags);
414 while (1) {
415 struct control_retrans *cr = 0;
416 struct retransmit_matchparam rm;
418 spin_lock_bh(&(nb->retrans_lock));
420 if (list_empty(&(nb->retrans_list))) {
421 nb->retrans_timer_running = 0;
422 nbput = 1;
423 break;
426 cr = container_of(nb->retrans_list.next,
427 struct control_retrans, timeout_list);
429 BUG_ON(cr->nb != nb);
431 rm.seqno = cr->seqno;
432 rm.nb = nb;
434 list_del(&(cr->timeout_list));
436 if (unlikely(nbstate == NEIGHBOR_STATE_KILLED)) {
437 spin_unlock_bh(&(nb->retrans_lock));
439 htable_delete(&retransmits, rm_to_key(&rm), &rm,
440 free_control_retrans);
441 kref_put(&(cr->ref), free_control_retrans);
442 continue;
445 if (time_after(cr->timeout, jiffies)) {
446 list_add(&(cr->timeout_list), &(nb->retrans_list));
447 mod_timer(&(nb->retrans_timer_conn), cr->timeout);
448 break;
451 if (unlikely(htable_delete(&retransmits, rm_to_key(&rm), &rm,
452 free_control_retrans)))
453 BUG();
455 spin_unlock_bh(&(nb->retrans_lock));
457 readd_control_retrans(cr);
459 kref_put(&(cr->ref), free_control_retrans);
462 spin_unlock_bh(&(nb->retrans_lock));
464 if (nbput)
465 kref_put(&(nb->ref), neighbor_free);
468 void retransmit_timerfunc(unsigned long arg)
470 struct neighbor *nb = (struct neighbor *) arg;
471 tasklet_schedule(&(nb->retrans_task));
474 static void schedule_retransmit(struct control_retrans *cr, struct neighbor *nb)
476 struct retransmit_matchparam rm;
477 int first;
479 rm.seqno = cr->seqno;
480 rm.nb = nb;
482 set_retrans_timeout(cr, nb);
484 spin_lock_bh(&(nb->retrans_lock));
485 htable_insert(&retransmits, (char *) cr, rm_to_key(&rm));
486 first = list_empty(&(nb->retrans_list));
487 list_add_tail(&(cr->timeout_list), &(nb->retrans_list));
489 if (first && nb->retrans_timer_running == 0) {
490 mod_timer(&(nb->retrans_timer), cr->timeout);
491 nb->retrans_timer_running = 1;
492 kref_get(&(nb->ref));
495 spin_unlock_bh(&(nb->retrans_lock));
498 void kern_ack_rcvd(struct neighbor *nb, __u32 seqno)
500 struct control_retrans *cr = 0;
501 struct retransmit_matchparam rm;
503 rm.seqno = seqno;
504 rm.nb = nb;
506 spin_lock_bh(&(nb->retrans_lock));
508 cr = (struct control_retrans *) htable_get(&retransmits, rm_to_key(&rm),
509 &rm);
511 if (cr == 0) {
512 printk(KERN_ERR "bogus/duplicate ack received");
513 goto out;
516 if (unlikely(htable_delete(&retransmits, rm_to_key(&rm), &rm,
517 free_control_retrans)))
518 BUG();
520 BUG_ON(cr->nb != nb);
522 list_del(&(cr->timeout_list));
524 out:
525 spin_unlock_bh(&(nb->retrans_lock));
527 if (cr != 0) {
528 kref_put(&(cr->ref), free_control_retrans); /* htable_get */
529 kref_put(&(cr->ref), free_control_retrans); /* list */
533 static void padding(struct sk_buff *skb, int length)
535 char *dst;
536 if (length <= 0)
537 return;
538 dst = skb_put(skb, length);
539 BUG_ON(dst == 0);
540 memset(dst, KP_PADDING, length);
543 static int add_ack(struct sk_buff *skb, struct control_retrans *cr,
544 struct control_msg_out *cm, int spaceleft)
546 char *dst;
548 if (unlikely(spaceleft < 5))
549 return 0;
551 dst = skb_put(skb, 5);
552 BUG_ON(dst == 0);
554 dst[0] = KP_ACK;
555 put_u32(dst + 1, cm->msg.ack.seqno, 1);
557 atomic_dec(&(cm->nb->ucmcnt));
558 free_control_msg(cm);
560 return 5;
563 static int add_ack_conn(struct sk_buff *skb, struct control_retrans *cr,
564 struct control_msg_out *cm, int spaceleft)
566 char *dst;
567 int offset = 0;
569 if (unlikely(spaceleft < cm->length))
570 return 0;
572 dst = skb_put(skb, cm->length);
573 BUG_ON(dst == 0);
575 dst[offset] = KP_ACK_CONN;
576 offset++;
577 put_u32(dst + offset, cm->msg.ack_conn.conn_id, 1);
578 offset += 4;
579 dst[offset] = cm->msg.ack_conn.flags;
580 offset++;
582 if ((cm->msg.ack_conn.flags & KP_ACK_CONN_FLAGS_SEQNO) != 0) {
583 put_u32(dst + offset, cm->msg.ack_conn.seqno, 1);
584 offset += 4;
586 if ((cm->msg.ack_conn.flags & KP_ACK_CONN_FLAGS_WINDOW) != 0) {
587 BUG_ON(cm->msg.ack_conn.src_in == 0);
588 dst[offset] = get_window(cm->msg.ack_conn.src_in,
589 cm->nb, cm->msg.ack_conn.conn_id, 1);
590 offset++;
594 if (ooolen(cm->msg.ack_conn.flags) != 0) {
595 put_u32(dst + offset, cm->msg.ack_conn.seqno_ooo, 1);
596 offset += 4;
597 if (ooolen(cm->msg.ack_conn.flags) == 1) {
598 BUG_ON(cm->msg.ack_conn.length > 255);
599 dst[offset] = cm->msg.ack_conn.length;
600 offset += 1;
601 } else if (ooolen(cm->msg.ack_conn.flags) == 2) {
602 BUG_ON(cm->msg.ack_conn.length <= 255);
603 BUG_ON(cm->msg.ack_conn.length > 65535);
604 put_u16(dst + offset, cm->msg.ack_conn.length, 1);
605 offset += 2;
606 } else if (ooolen(cm->msg.ack_conn.flags) == 4) {
607 BUG_ON(cm->msg.ack_conn.length <= 65535);
608 put_u32(dst + offset, cm->msg.ack_conn.length, 1);
609 offset += 4;
610 } else {
611 BUG();
615 if ((cm->msg.ack_conn.flags & KP_ACK_CONN_FLAGS_CREDITS) != 0) {
616 __u16 value = cm->msg.ack_conn.decaytime + (
617 cm->msg.ack_conn.decaytime_seqno << 10);
619 BUG_ON(cm->msg.ack_conn.decaytime >= 1024);
620 BUG_ON(cm->msg.ack_conn.decaytime_seqno >= 64);
622 put_u16(dst + offset, value, 1);
623 offset += 2;
626 list_add_tail(&(cm->lh), &(cr->msgs));
628 BUG_ON(offset != cm->length);
629 return offset;
632 static int add_ping(struct sk_buff *skb, __u32 cookie,
633 int spaceleft)
635 char *dst;
637 if (unlikely(spaceleft < 5))
638 return 0;
640 dst = skb_put(skb, 5);
641 BUG_ON(dst == 0);
643 dst[0] = KP_PING;
644 put_u32(dst + 1, cookie, 0);
646 return 5;
649 static int add_pong(struct sk_buff *skb, struct control_retrans *cr,
650 struct control_msg_out *cm, int spaceleft)
652 char *dst;
654 if (unlikely(spaceleft < 9))
655 return 0;
657 if (cm->msg.pong.type == MSGTYPE_PONG_TIMEENQUEUED) {
658 __s64 now = ktime_to_ns(ktime_get());
659 __s64 enq = ktime_to_ns(cm->msg.pong.delaycomp.time_enqueued);
660 __s64 respdelay = (now - enq + 500) / 1000;
661 if (unlikely(respdelay >= (1LL << 32)))
662 respdelay = (1LL << 32) - 1;
663 cm->msg.pong.type = MSGTYPE_PONG_RESPDELAY;
664 cm->msg.pong.delaycomp.respdelay = (__u32) respdelay;
667 BUG_ON(cm->msg.pong.type != MSGTYPE_PONG_RESPDELAY);
669 dst = skb_put(skb, 9);
670 BUG_ON(dst == 0);
672 dst[0] = KP_PONG;
673 put_u32(dst + 1, cm->msg.pong.cookie, 0);
674 put_u32(dst + 5, cm->msg.pong.delaycomp.respdelay, 1);
677 atomic_dec(&(cm->nb->ucmcnt));
678 list_add_tail(&(cm->lh), &(cr->msgs));
680 return 9;
683 static __u16 get_credits(struct conn *sconn)
685 __u16 ret;
686 spin_lock_bh(&(sconn->reversedir->rcv_lock));
687 BUG_ON(sconn->reversedir->targettype != TARGET_OUT);
689 BUG_ON(sconn->reversedir->target.out.decaytime_last >= 1024);
690 BUG_ON(sconn->reversedir->target.out.decaytime_seqno >= 64);
691 ret = sconn->reversedir->target.out.decaytime_last + (
692 sconn->reversedir->target.out.decaytime_seqno <<
693 10);
694 spin_unlock_bh(&(sconn->reversedir->rcv_lock));
696 return ret;
699 static int add_connect(struct sk_buff *skb, struct control_retrans *cr,
700 struct control_msg_out *cm, int spaceleft)
702 char *dst;
704 if (unlikely(spaceleft < 12))
705 return 0;
707 dst = skb_put(skb, 12);
708 BUG_ON(dst == 0);
710 dst[0] = KP_CONNECT;
711 put_u32(dst + 1, cm->msg.connect.conn_id, 1);
712 put_u32(dst + 5, cm->msg.connect.init_seqno, 1);
713 BUG_ON(cm->msg.connect.src_in == 0);
714 dst[9] = get_window(cm->msg.connect.src_in, cm->nb, 0, 1);
715 put_u16(dst + 10, get_credits(cm->msg.connect.src_in), 1);
717 list_add_tail(&(cm->lh), &(cr->msgs));
719 return 12;
722 static int add_connect_success(struct sk_buff *skb, struct control_retrans *cr,
723 struct control_msg_out *cm, int spaceleft)
725 char *dst;
727 if (unlikely(spaceleft < 16))
728 return 0;
730 dst = skb_put(skb, 16);
731 BUG_ON(dst == 0);
733 dst[0] = KP_CONNECT_SUCCESS;
734 put_u32(dst + 1, cm->msg.connect_success.rcvd_conn_id, 1);
735 put_u32(dst + 5, cm->msg.connect_success.gen_conn_id, 1);
736 put_u32(dst + 9, cm->msg.connect_success.init_seqno, 1);
737 BUG_ON(cm->msg.connect_success.src_in == 0);
738 dst[13] = get_window(cm->msg.connect_success.src_in, cm->nb,
739 cm->msg.connect_success.rcvd_conn_id, 1);
740 put_u16(dst + 14, get_credits(cm->msg.connect_success.src_in), 1);
742 list_add_tail(&(cm->lh), &(cr->msgs));
744 return 16;
747 static int add_reset_conn(struct sk_buff *skb, struct control_retrans *cr,
748 struct control_msg_out *cm, int spaceleft)
750 char *dst;
752 if (unlikely(spaceleft < 5))
753 return 0;
755 dst = skb_put(skb, 5);
756 BUG_ON(dst == 0);
758 dst[0] = KP_RESET_CONN;
759 put_u32(dst + 1, cm->msg.reset_connidunknown.conn_id_reset, 1);
761 list_add_tail(&(cm->lh), &(cr->msgs));
763 return 5;
766 static int add_conndata(struct sk_buff *skb, struct control_retrans *cr,
767 struct control_msg_out *cm, int spaceleft,
768 struct control_msg_out **split_conndata, __u32 *sc_sendlen)
770 char *dst;
772 int totallen = cm->msg.conn_data.datalen + 11;
773 int putlen = min(totallen, spaceleft);
774 int dataputlen = putlen - 11;
776 BUG_ON(split_conndata == 0);
777 BUG_ON(sc_sendlen == 0);
779 if (dataputlen < 1 || (spaceleft < 25 && spaceleft < totallen))
780 return 0;
782 dst = skb_put(skb, putlen);
783 BUG_ON(dst == 0);
785 dst[0] = KP_CONN_DATA;
786 put_u32(dst + 1, cm->msg.conn_data.conn_id, 1);
787 put_u32(dst + 5, cm->msg.conn_data.seqno, 1);
788 put_u16(dst + 9, dataputlen, 1);
790 memcpy(dst + 11, cm->msg.conn_data.data, dataputlen);
792 if (cm->msg.conn_data.datalen == dataputlen) {
793 list_add_tail(&(cm->lh), &(cr->msgs));
794 } else {
795 *split_conndata = cm;
796 *sc_sendlen = dataputlen;
799 return putlen;
802 static int add_connid_unknown(struct sk_buff *skb, struct control_retrans *cr,
803 struct control_msg_out *cm, int spaceleft)
805 char *dst;
807 if (unlikely(spaceleft < 5))
808 return 0;
810 dst = skb_put(skb, 5);
811 BUG_ON(dst == 0);
813 dst[0] = KP_CONNID_UNKNOWN;
814 put_u32(dst + 1, cm->msg.reset_connidunknown.conn_id_unknown, 1);
816 list_add_tail(&(cm->lh), &(cr->msgs));
818 return 5;
821 static int add_set_max_cmsg_dly(struct sk_buff *skb, struct control_retrans *cr,
822 struct control_msg_out *cm, int spaceleft)
824 char *dst;
826 if (unlikely(spaceleft < 5))
827 return 0;
829 dst = skb_put(skb, 5);
830 BUG_ON(dst == 0);
832 dst[0] = KP_SET_MAX_CMSG_DELAY;
833 put_u32(dst + 1, cm->msg.set_max_cmsg_delay.delay, 1);
835 list_add_tail(&(cm->lh), &(cr->msgs));
837 return 5;
840 static int add_message(struct sk_buff *skb, struct control_retrans *cr,
841 struct control_msg_out *cm, int spaceleft,
842 struct control_msg_out **split_conndata, __u32 *sc_sendlen)
844 BUG_ON(split_conndata != 0 && *split_conndata != 0);
845 BUG_ON(sc_sendlen != 0 && *sc_sendlen != 0);
847 switch (cm->type) {
848 case MSGTYPE_ACK:
849 return add_ack(skb, cr, cm, spaceleft);
850 case MSGTYPE_ACK_CONN:
851 return add_ack_conn(skb, cr, cm, spaceleft);
852 case MSGTYPE_PONG:
853 return add_pong(skb, cr, cm, spaceleft);
854 case MSGTYPE_CONNECT:
855 return add_connect(skb, cr, cm, spaceleft);
856 case MSGTYPE_CONNECT_SUCCESS:
857 return add_connect_success(skb, cr, cm, spaceleft);
858 case MSGTYPE_RESET_CONN:
859 return add_reset_conn(skb, cr, cm, spaceleft);
860 case MSGTYPE_CONNDATA:
861 return add_conndata(skb, cr, cm, spaceleft, split_conndata,
862 sc_sendlen);
863 case MSGTYPE_CONNID_UNKNOWN:
864 return add_connid_unknown(skb, cr, cm, spaceleft);
865 case MSGTYPE_SET_MAX_CMSG_DELAY:
866 return add_set_max_cmsg_dly(skb, cr, cm, spaceleft);
867 default:
868 BUG();
870 BUG();
871 return 0;
874 static void requeue_message(struct control_msg_out *cm)
876 if (cm->type == MSGTYPE_ACK_CONN) {
877 struct conn *cn_l = cm->msg.ack_conn.src_in;
879 spin_lock_bh(&(cn_l->rcv_lock));
880 if (unlikely(ackconn_prepare_readd(cn_l, cm) == 0)) {
881 free_control_msg(cm);
882 } else {
883 spin_lock_bh(&(cm->nb->cmsg_lock));
885 list_add(&(cm->lh), &(cm->nb->control_msgs_out));
886 cm->nb->cmlength += cm->length;
888 list_add(&(cm->msg.ack_conn.conn_acks),
889 &(cn_l->source.in.acks_pending));
890 try_merge_ackconns(cn_l, cm);
892 spin_unlock_bh(&(cm->nb->cmsg_lock));
894 spin_unlock_bh(&(cn_l->rcv_lock));
895 return;
898 if (isurgent(cm)) {
899 list_add(&(cm->lh), &(cm->nb->ucontrol_msgs_out));
900 cm->nb->ucmlength += cm->length;
901 } else {
902 list_add(&(cm->lh), &(cm->nb->control_msgs_out));
903 cm->nb->cmlength += cm->length;
907 static struct control_msg_out *dequeue_message(struct neighbor *nb,
908 int urgentonly)
910 struct control_msg_out *cm;
912 if (list_empty(&(nb->ucontrol_msgs_out)) == 0) {
913 cm = container_of(nb->ucontrol_msgs_out.next,
914 struct control_msg_out, lh);
915 nb->ucmlength -= cm->length;
916 } else if (urgentonly) {
917 return 0;
918 } else {
919 if (list_empty(&(nb->control_msgs_out)))
920 return 0;
922 cm = container_of(nb->control_msgs_out.next,
923 struct control_msg_out, lh);
924 nb->cmlength -= cm->length;
927 BUG_ON(cm->nb != nb);
929 list_del(&(cm->lh));
930 if (cm->type == MSGTYPE_ACK_CONN)
931 list_del(&(cm->msg.ack_conn.conn_acks));
933 return cm;
936 static __u32 __send_messages(struct neighbor *nb, struct sk_buff *skb,
937 struct control_retrans *cr, int spaceleft, int urgentonly,
938 struct control_msg_out **split_conndata, __u32 *sc_sendlen)
940 __u32 length = 0;
941 while (1) {
942 int rc;
943 struct control_msg_out *cm;
945 spin_lock_bh(&(nb->cmsg_lock));
946 cm = dequeue_message(nb, urgentonly);
947 spin_unlock_bh(&(nb->cmsg_lock));
949 if (cm == 0)
950 break;
952 rc = add_message(skb, cr, cm, spaceleft - length,
953 split_conndata, sc_sendlen);
954 if (rc == 0) {
955 requeue_message(cm);
956 break;
959 length += rc;
962 return length;
965 static __u32 __send_messages_smcd(struct neighbor *nb, struct sk_buff *skb,
966 struct control_retrans *cr, int spaceleft)
968 struct control_msg_out *cm;
969 int rc;
971 cm = alloc_control_msg(nb, ACM_PRIORITY_LOW);
973 if (unlikely(cm == 0))
974 return 0;
976 cm->type = MSGTYPE_SET_MAX_CMSG_DELAY;
977 cm->msg.set_max_cmsg_delay.delay = CMSG_INTERVAL_MS * 10;
978 cm->length = 5;
980 rc = add_message(skb, cr, cm, spaceleft, 0, 0);
982 nb->max_cmsg_delay_sent = 1;
984 return rc;
987 static int _send_messages(struct neighbor *nb, struct sk_buff *skb, int ping,
988 struct control_retrans *cr, int spaceleft, int urgentonly)
990 int rc;
991 __u32 length = 0;
992 __u32 pinglen = 0;
993 __u32 pingcookie = 0;
994 unsigned long last_ping_time;
995 struct control_msg_out *split_conndata = 0;
996 __u32 sc_sendlen = 0;
998 spin_lock_bh(&(nb->cmsg_lock));
1000 if (ping != 0) {
1001 int rc;
1002 pingcookie = add_ping_req(nb, &last_ping_time);
1003 rc = add_ping(skb, pingcookie, spaceleft - length);
1004 BUG_ON(rc == 0);
1005 pinglen = rc;
1006 length += rc;
1009 if (likely(urgentonly == 0) && unlikely(nb->max_cmsg_delay_sent == 0))
1010 length += __send_messages_smcd(nb, skb, cr, spaceleft - length);
1012 spin_unlock_bh(&(nb->cmsg_lock));
1014 length += __send_messages(nb, skb, cr, spaceleft - length, urgentonly,
1015 &split_conndata, &sc_sendlen);
1017 BUG_ON(length > spaceleft);
1019 if (likely(ping != 2) && unlikely(length == pinglen)) {
1020 unadd_ping_req(nb, pingcookie, last_ping_time);
1021 kfree_skb(skb);
1023 BUG_ON(list_empty(&(cr->msgs)) == 0);
1024 kref_put(&(cr->ref), free_control_retrans);
1026 atomic_sub(1, &(nb->kpacket_seqno));
1027 return 0;
1030 padding(skb, spaceleft - length);
1032 rc = dev_queue_xmit(skb);
1034 if (rc != 0) {
1035 unadd_ping_req(nb, pingcookie, last_ping_time);
1037 while (list_empty(&(cr->msgs)) == 0) {
1038 struct control_msg_out *cm = container_of(cr->msgs.prev,
1039 struct control_msg_out, lh);
1040 list_del(&(cm->lh));
1041 add_control_msg(cm, 1);
1044 if (split_conndata != 0) {
1045 add_control_msg(split_conndata, 1);
1048 kref_put(&(cr->ref), free_control_retrans);
1049 } else {
1050 struct list_head *curr = cr->msgs.next;
1052 while(curr != &(cr->msgs)) {
1053 struct control_msg_out *cm = container_of(curr,
1054 struct control_msg_out, lh);
1056 curr = curr->next;
1058 if (cm->type == MSGTYPE_CONNDATA) {
1059 list_del(&(cm->lh));
1060 kfree(cm->msg.conn_data.data_orig);
1061 free_control_msg(cm);
1065 if (split_conndata != 0) {
1066 BUG_ON(sc_sendlen == 0);
1067 BUG_ON(sc_sendlen >=
1068 split_conndata->msg.conn_data.datalen);
1070 split_conndata->msg.conn_data.data += sc_sendlen;
1071 split_conndata->msg.conn_data.datalen -= sc_sendlen;
1073 send_conndata(split_conndata,
1074 split_conndata->msg.conn_data.conn_id,
1075 split_conndata->msg.conn_data.seqno,
1076 split_conndata->msg.conn_data.data_orig,
1077 split_conndata->msg.conn_data.data,
1078 split_conndata->msg.conn_data.datalen);
1082 if (list_empty(&(cr->msgs)))
1083 kref_put(&(cr->ref), free_control_retrans);
1084 else
1085 schedule_retransmit(cr, nb);
1088 return rc;
1091 static __u32 get_total_messages_length(struct neighbor *nb, int ping,
1092 int urgentonly)
1094 __u32 length = nb->ucmlength;
1096 if (likely(urgentonly == 0)) {
1097 length += nb->cmlength;
1099 if (unlikely(nb->max_cmsg_delay_sent == 0))
1100 length += 5;
1102 if (ping == 2 || (length > 0 && ping != 0))
1103 length += 5;
1105 return length;
1108 static int reset_timeouted_conn_needed(struct neighbor *nb,
1109 struct conn *src_in_l)
1111 if (unlikely(unlikely(src_in_l->sourcetype != SOURCE_IN) ||
1112 unlikely(src_in_l->source.in.nb != nb) ||
1113 unlikely(src_in_l->isreset != 0)))
1114 return 0;
1115 else if (likely(time_after(src_in_l->source.in.jiffies_last_act +
1116 CONN_ACTIVITY_UPDATEINTERVAL_SEC * HZ +
1117 CONN_INACTIVITY_TIMEOUT_SEC * HZ, jiffies)))
1118 return 0;
1120 return 1;
1123 static int reset_timeouted_conn(struct neighbor *nb, struct conn *src_in)
1125 int resetted = 0;
1127 if (src_in->is_client) {
1128 spin_lock_bh(&(src_in->rcv_lock));
1129 spin_lock_bh(&(src_in->reversedir->rcv_lock));
1130 } else {
1131 spin_lock_bh(&(src_in->reversedir->rcv_lock));
1132 spin_lock_bh(&(src_in->rcv_lock));
1135 resetted = reset_timeouted_conn_needed(nb, src_in);
1136 if (unlikely(resetted == 0))
1137 goto unlock;
1139 resetted = (send_reset_conn(nb, src_in->reversedir->target.out.conn_id,
1140 src_in->source.in.conn_id, 1) == 0);
1141 if (unlikely(resetted == 0))
1142 goto unlock;
1145 BUG_ON(src_in->reversedir->isreset != 0);
1146 src_in->reversedir->isreset = 1;
1148 unlock:
1149 if (src_in->is_client) {
1150 spin_unlock_bh(&(src_in->rcv_lock));
1151 spin_unlock_bh(&(src_in->reversedir->rcv_lock));
1152 } else {
1153 spin_unlock_bh(&(src_in->reversedir->rcv_lock));
1154 spin_unlock_bh(&(src_in->rcv_lock));
1157 if (resetted)
1158 reset_conn(src_in);
1160 return resetted;
1163 static void reset_timeouted_conns(struct neighbor *nb)
1165 int i;
1166 for (i=0;i<10000;i++) {
1167 unsigned long iflags;
1168 struct conn *src_in;
1170 int resetted = 1;
1172 spin_lock_irqsave(&(nb->conn_list_lock), iflags);
1174 if (list_empty(&(nb->rcv_conn_list))) {
1175 spin_unlock_irqrestore(&(nb->conn_list_lock), iflags);
1176 break;
1179 src_in = container_of(nb->rcv_conn_list.next, struct conn,
1180 source.in.nb_list);
1181 kref_get(&(src_in->ref));
1183 spin_unlock_irqrestore(&(nb->conn_list_lock), iflags);
1186 spin_lock_bh(&(src_in->rcv_lock));
1187 resetted = reset_timeouted_conn_needed(nb, src_in);
1188 spin_unlock_bh(&(src_in->rcv_lock));
1189 if (likely(resetted == 0))
1190 goto put;
1192 resetted = reset_timeouted_conn(nb, src_in);
1194 put:
1195 kref_put(&(src_in->ref), free_conn);
1197 if (likely(resetted == 0))
1198 break;
1202 int send_messages(struct neighbor *nb, int resume)
1204 int i;
1205 int rc = 0;
1206 int ping;
1207 int targetmss = mss(nb);
1209 int nbstate = get_neigh_state(nb);
1210 int urgentonly = (nbstate != NEIGHBOR_STATE_ACTIVE);
1212 if (likely(urgentonly == 0))
1213 reset_timeouted_conns(nb);
1215 spin_lock_bh(&(nb->send_cmsg_lock));
1216 spin_lock_bh(&(nb->cmsg_lock));
1218 ping = time_to_send_ping(nb);
1220 for (i=0;1;i++) {
1221 __u32 length;
1223 __u32 seqno;
1224 struct sk_buff *skb;
1225 struct control_retrans *cr;
1227 BUG_ON(list_empty(&(nb->control_msgs_out)) &&
1228 (nb->cmlength != 0));
1229 BUG_ON((list_empty(&(nb->control_msgs_out)) == 0) &&
1230 (nb->cmlength == 0));
1231 BUG_ON(list_empty(&(nb->ucontrol_msgs_out)) &&
1232 (nb->ucmlength != 0));
1233 BUG_ON((list_empty(&(nb->ucontrol_msgs_out)) == 0) &&
1234 (nb->ucmlength == 0));
1235 BUG_ON(nb->cmlength < 0);
1236 BUG_ON(nb->ucmlength < 0);
1238 length = get_total_messages_length(nb, ping, urgentonly);
1240 if (length == 0)
1241 break;
1243 if (length < targetmss && i > 0)
1244 break;
1246 seqno = atomic_add_return(1, &(nb->kpacket_seqno));
1248 if (length > targetmss)
1249 length = targetmss;
1251 spin_unlock_bh(&(nb->cmsg_lock));
1252 skb = create_packet(nb, length, GFP_ATOMIC, 0, seqno);
1253 if (unlikely(skb == 0)) {
1254 printk(KERN_ERR "cor: send_messages: cannot allocate "
1255 "skb (out of memory?)");
1256 goto oom;
1259 cr = kmem_cache_alloc(controlretrans_slab, GFP_ATOMIC);
1260 if (unlikely(cr == 0)) {
1261 kfree_skb(skb);
1262 printk(KERN_ERR "cor: send_messages: cannot allocate "
1263 "control_retrans (out of memory?)");
1264 goto oom;
1266 memset(cr, 0, sizeof(struct control_retrans));
1267 kref_init(&(cr->ref));
1268 cr->nb = nb;
1269 cr->seqno = seqno;
1270 INIT_LIST_HEAD(&(cr->msgs));
1272 rc = _send_messages(nb, skb, ping, cr, length, urgentonly);
1273 ping = 0;
1275 spin_lock_bh(&(nb->cmsg_lock));
1277 if (rc != 0)
1278 break;
1281 if (0) {
1282 oom:
1283 spin_lock_bh(&(nb->cmsg_lock));
1286 if (rc != 0) {
1287 if (resume == 0)
1288 qos_enqueue(nb->queue, &(nb->rb_kp),
1289 QOS_CALLER_KPACKET);
1290 } else {
1291 atomic_set(&(nb->cmsg_task_scheduled), 0);
1292 schedule_controlmsg_timer(nb);
1295 spin_unlock_bh(&(nb->cmsg_lock));
1296 spin_unlock_bh(&(nb->send_cmsg_lock));
1298 if (resume == 0)
1299 kref_put(&(nb->ref), neighbor_free);
1301 return rc;
1304 void controlmsg_taskfunc(unsigned long nb)
1306 send_messages((struct neighbor *)nb, 0);
1309 static void schedule_cmsg_task(struct neighbor *nb)
1311 if (atomic_cmpxchg(&(nb->cmsg_task_scheduled), 0, 1) == 0) {
1312 kref_get(&(nb->ref));
1313 atomic_cmpxchg(&(nb->cmsg_timer_running), 1, 2);
1314 tasklet_schedule(&(nb->cmsg_task));
1318 void controlmsg_timerfunc(unsigned long arg)
1320 struct neighbor *nb = (struct neighbor *) arg;
1322 int oldval = atomic_xchg(&(nb->cmsg_timer_running), 0);
1324 BUG_ON(oldval == 0);
1326 if (likely(oldval == 1))
1327 schedule_cmsg_task(nb);
1328 kref_put(&(nb->ref), neighbor_free);
1331 static unsigned long get_cmsg_timeout(struct neighbor *nb, int nbstate)
1333 unsigned long timeout = get_next_ping_time(nb);
1335 if (likely(nbstate == NEIGHBOR_STATE_ACTIVE) &&
1336 list_empty(&(nb->control_msgs_out)) == 0) {
1337 struct control_msg_out *first = container_of(
1338 nb->control_msgs_out.next,
1339 struct control_msg_out, lh);
1340 if (time_before(first->timeout, jiffies +
1341 usecs_to_jiffies(nb->cmsg_interval)))
1342 timeout = jiffies;
1343 else if (time_before(first->timeout, timeout))
1344 timeout = first->timeout;
1347 if (list_empty(&(nb->ucontrol_msgs_out)) == 0) {
1348 struct control_msg_out *first = container_of(
1349 nb->ucontrol_msgs_out.next,
1350 struct control_msg_out, lh);
1351 if (time_before(first->timeout, jiffies +
1352 usecs_to_jiffies(nb->cmsg_interval)))
1353 timeout = jiffies;
1354 else if (time_before(first->timeout, timeout))
1355 timeout = first->timeout;
1358 return timeout;
1361 static int cmsg_full_packet(struct neighbor *nb, int nbstate)
1363 int ping = time_to_send_ping(nb);
1364 int urgentonly = (nbstate != NEIGHBOR_STATE_ACTIVE);
1365 __u32 len = get_total_messages_length(nb, ping, urgentonly);
1367 if (len == 0)
1368 return 0;
1369 if (len < mss(nb))
1370 return 0;
1372 return 1;
1375 void schedule_controlmsg_timer(struct neighbor *nb)
1377 unsigned long timeout;
1378 int state = get_neigh_state(nb);
1380 if (unlikely(state == NEIGHBOR_STATE_KILLED)) {
1381 atomic_cmpxchg(&(nb->cmsg_timer_running), 1, 2);
1382 return;
1385 if (unlikely(atomic_read(&(nb->cmsg_task_scheduled)) == 1))
1386 return;
1388 if (cmsg_full_packet(nb, state))
1389 goto now;
1391 timeout = get_cmsg_timeout(nb, state);
1393 if (time_before_eq(timeout, jiffies)) {
1394 now:
1395 schedule_cmsg_task(nb);
1396 } else {
1397 if (atomic_xchg(&(nb->cmsg_timer_running), 1) == 0)
1398 kref_get(&(nb->ref));
1399 mod_timer(&(nb->cmsg_timer), timeout);
1403 static void free_oldest_ucm(struct neighbor *nb)
1405 struct control_msg_out *cm = container_of(nb->ucontrol_msgs_out.next,
1406 struct control_msg_out, lh);
1408 BUG_ON(list_empty(&(nb->ucontrol_msgs_out)));
1409 BUG_ON(isurgent(cm) == 0);
1411 list_del(&(cm->lh));
1412 nb->ucmlength -= cm->length;
1413 atomic_dec(&(nb->ucmcnt));
1414 free_control_msg(cm);
1417 static void add_control_msg(struct control_msg_out *cm, int retrans)
1419 int nbstate;
1420 __u64 newinterval;
1421 unsigned long jiffies_tmp;
1423 BUG_ON(cm->nb == 0);
1425 nbstate = get_neigh_state(cm->nb);
1427 BUG_ON(cm == 0);
1428 BUG_ON(cm->lh.next != LIST_POISON1 || cm->lh.prev != LIST_POISON2);
1430 cm->timeout = jiffies + msecs_to_jiffies(CMSG_INTERVAL_MS);
1432 spin_lock_bh(&(cm->nb->cmsg_lock));
1434 if (isurgent(cm)) {
1435 long msgs;
1437 msgs = atomic_inc_return(&(cm->nb->ucmcnt));
1438 BUG_ON(msgs <= 0);
1440 if (unlikely(retrans)) {
1441 if (msgs > MAX_URGENT_CMSGS_PER_NEIGH_RETRANSALLOW ||
1442 msgs > MAX_URGENT_CMSGS_PER_NEIGH) {
1443 atomic_dec(&(cm->nb->ucmcnt));
1444 free_control_msg(cm);
1445 goto out;
1448 cm->nb->ucmlength += cm->length;
1449 list_add(&(cm->lh), &(cm->nb->ucontrol_msgs_out));
1450 } else {
1451 if (msgs > MAX_URGENT_CMSGS_PER_NEIGH) {
1452 free_oldest_ucm(cm->nb);
1455 cm->nb->ucmlength += cm->length;
1456 list_add_tail(&(cm->lh), &(cm->nb->ucontrol_msgs_out));
1458 } else {
1459 cm->nb->cmlength += cm->length;
1460 list_add_tail(&(cm->lh), &(cm->nb->control_msgs_out));
1463 jiffies_tmp = jiffies;
1464 newinterval = (((__u64) cm->nb->cmsg_interval) * 255 +
1465 jiffies_to_usecs(jiffies_tmp -
1466 cm->nb->jiffies_last_cmsg)) / 256;
1467 cm->nb->jiffies_last_cmsg = jiffies_tmp;
1468 if (unlikely(newinterval > (1LL << 32) - 1))
1469 cm->nb->cmsg_interval = (__u32) ((1LL << 32) - 1);
1470 else
1471 cm->nb->cmsg_interval = newinterval;
1473 schedule_controlmsg_timer(cm->nb);
1475 out:
1476 spin_unlock_bh(&(cm->nb->cmsg_lock));
1480 void send_pong(struct neighbor *nb, __u32 cookie)
1482 struct control_msg_out *cm = _alloc_control_msg(nb, 0, 1);
1484 if (unlikely(cm == 0))
1485 return;
1487 cm->nb = nb;
1488 cm->type = MSGTYPE_PONG;
1489 cm->msg.pong.cookie = cookie;
1490 cm->msg.pong.type = MSGTYPE_PONG_TIMEENQUEUED;
1491 cm->msg.pong.delaycomp.time_enqueued = ktime_get();
1492 cm->length = 9;
1493 add_control_msg(cm, 0);
1496 int send_reset_conn(struct neighbor *nb, __u32 conn_id_reset,
1497 __u32 conn_id_unknown, int lowprio)
1499 unsigned long iflags;
1500 int killed;
1501 struct control_msg_out *cm;
1502 struct unknownconnid_matchparam ucm;
1504 spin_lock_irqsave(&(nb->state_lock), iflags);
1505 killed = (nb->state == NEIGHBOR_STATE_KILLED);
1506 spin_unlock_irqrestore(&(nb->state_lock), iflags);
1508 if (unlikely(killed))
1509 return 0;
1511 cm = alloc_control_msg(nb, lowprio ?
1512 ACM_PRIORITY_LOW : ACM_PRIORITY_HIGH);
1514 if (unlikely(cm == 0))
1515 return 1;
1517 cm->type = MSGTYPE_RESET_CONN;
1518 cm->msg.reset_connidunknown.conn_id_reset = conn_id_reset;
1519 cm->msg.reset_connidunknown.conn_id_unknown = conn_id_unknown;
1520 cm->length = 5;
1522 if (conn_id_unknown != 0) {
1523 ucm.nb = nb;
1524 ucm.conn_id = conn_id_unknown;
1526 spin_lock_irqsave(&unknown_connids_lock, iflags);
1527 BUG_ON(htable_get(&unknown_connids, ucm_to_key(&ucm), &ucm) !=
1529 htable_insert(&unknown_connids, (char *) cm, ucm_to_key(&ucm));
1530 spin_unlock_irqrestore(&unknown_connids_lock, iflags);
1533 add_control_msg(cm, 0);
1535 return 0;
1538 void send_ack(struct neighbor *nb, __u32 seqno)
1540 struct control_msg_out *cm = _alloc_control_msg(nb, 0, 1);
1542 if (unlikely(cm == 0))
1543 return;
1545 cm->nb = nb;
1546 cm->type = MSGTYPE_ACK;
1547 cm->msg.ack.seqno = seqno;
1548 cm->length = 5;
1549 add_control_msg(cm, 0);
1552 static void set_ooolen_flags(struct control_msg_out *cm)
1554 cm->msg.ack_conn.flags = (cm->msg.ack_conn.flags &
1555 (~KP_ACK_CONN_FLAGS_OOO));
1556 cm->msg.ack_conn.flags = (cm->msg.ack_conn.flags |
1557 ooolen_to_flags(cm->msg.ack_conn.length));
1560 /* cmsg_lock must be held */
1561 static void remove_pending_ackconn(struct control_msg_out *cm)
1563 cm->nb->cmlength -= cm->length;
1564 list_del(&(cm->lh));
1566 list_del(&(cm->msg.ack_conn.conn_acks));
1567 kref_put(&(cm->msg.ack_conn.src_in->ref), free_conn);
1568 cm->msg.ack_conn.src_in = 0;
1570 cm->type = 0;
1571 free_control_msg(cm);
1574 /* cmsg_lock must be held */
1575 static void recalc_scheduled_ackconn_size(struct control_msg_out *cm)
1577 cm->nb->cmlength -= cm->length;
1578 cm->length = 6 + ack_conn_len(cm->msg.ack_conn.flags);
1579 cm->nb->cmlength += cm->length;
1582 /* cmsg_lock must be held */
1583 static int _try_merge_ackconn(struct conn *src_in_l,
1584 struct control_msg_out *fromcm, struct control_msg_out *tocm,
1585 int from_newack)
1587 if (ooolen(fromcm->msg.ack_conn.flags) != 0 &&
1588 ooolen(tocm->msg.ack_conn.flags) != 0) {
1589 __u32 tocmseqno = tocm->msg.ack_conn.seqno_ooo;
1590 __u32 tocmlength = tocm->msg.ack_conn.length;
1591 __u32 fromcmseqno = fromcm->msg.ack_conn.seqno_ooo;
1592 __u32 fromcmlength = fromcm->msg.ack_conn.length;
1594 if (tocmseqno == fromcmseqno) {
1595 if (fromcmlength > tocmlength)
1596 tocm->msg.ack_conn.length = fromcmlength;
1597 } else if (seqno_after(fromcmseqno, tocmseqno) &&
1598 seqno_before_eq(fromcmseqno, tocmseqno +
1599 tocmlength)) {
1600 tocm->msg.ack_conn.length = fromcmseqno + fromcmlength -
1601 tocmseqno;
1602 } else if (seqno_before(fromcmseqno, tocmseqno) &&
1603 seqno_after_eq(fromcmseqno, tocmseqno)) {
1604 tocm->msg.ack_conn.seqno_ooo = fromcmseqno;
1605 tocm->msg.ack_conn.length = tocmseqno + tocmlength -
1606 fromcmseqno;
1607 } else {
1608 return 1;
1610 set_ooolen_flags(tocm);
1613 if ((fromcm->msg.ack_conn.flags &
1614 KP_ACK_CONN_FLAGS_SEQNO) != 0) {
1615 if ((tocm->msg.ack_conn.flags & KP_ACK_CONN_FLAGS_SEQNO) == 0)
1616 goto setseqno;
1618 BUG_ON(fromcm->msg.ack_conn.ack_seqno ==
1619 tocm->msg.ack_conn.ack_seqno);
1620 if ((tocm->msg.ack_conn.ack_seqno -
1621 fromcm->msg.ack_conn.ack_seqno) < (1 << 31)) {
1622 BUG_ON(seqno_after(fromcm->msg.ack_conn.seqno,
1623 tocm->msg.ack_conn.seqno));
1624 goto skipseqno;
1627 BUG_ON(seqno_before(fromcm->msg.ack_conn.seqno,
1628 tocm->msg.ack_conn.seqno));
1630 setseqno:
1631 tocm->msg.ack_conn.flags = (tocm->msg.ack_conn.flags |
1632 KP_ACK_CONN_FLAGS_SEQNO);
1633 tocm->msg.ack_conn.seqno = fromcm->msg.ack_conn.seqno;
1634 tocm->msg.ack_conn.ack_seqno = fromcm->msg.ack_conn.ack_seqno;
1636 skipseqno:
1637 if ((fromcm->msg.ack_conn.flags &
1638 KP_ACK_CONN_FLAGS_WINDOW) != 0)
1639 tocm->msg.ack_conn.flags = (tocm->msg.ack_conn.flags |
1640 KP_ACK_CONN_FLAGS_WINDOW);
1644 if (ooolen(fromcm->msg.ack_conn.flags) != 0) {
1645 tocm->msg.ack_conn.seqno_ooo = fromcm->msg.ack_conn.seqno_ooo;
1646 tocm->msg.ack_conn.length = fromcm->msg.ack_conn.length;
1647 set_ooolen_flags(tocm);
1650 if ((fromcm->msg.ack_conn.flags & KP_ACK_CONN_FLAGS_CREDITS) != 0) {
1651 BUG_ON((tocm->msg.ack_conn.flags &
1652 KP_ACK_CONN_FLAGS_CREDITS) != 0);
1653 tocm->msg.ack_conn.decaytime_seqno =
1654 fromcm->msg.ack_conn.decaytime_seqno;
1655 tocm->msg.ack_conn.decaytime =
1656 fromcm->msg.ack_conn.decaytime;
1659 recalc_scheduled_ackconn_size(tocm);
1660 if (from_newack)
1661 kref_put(&(fromcm->msg.ack_conn.src_in->ref), free_conn);
1662 else
1663 remove_pending_ackconn(fromcm);
1665 return 0;
1668 /* cmsg_lock must be held */
1669 static void try_merge_ackconns(struct conn *src_in_l,
1670 struct control_msg_out *cm)
1672 struct list_head *currlh = cm->msg.ack_conn.conn_acks.next;
1674 while (currlh != &(src_in_l->source.in.acks_pending)) {
1675 struct control_msg_out *currcm = container_of(currlh,
1676 struct control_msg_out,
1677 msg.ack_conn.conn_acks);
1678 currlh = currlh->next;
1679 remove_connack_oooflag_ifold(src_in_l, currcm);
1680 _try_merge_ackconn(src_in_l, currcm, cm, 0);
1684 static void mergeadd_ackconn(struct conn *src_in_l, struct control_msg_out *cm)
1686 struct list_head *currlh;
1688 BUG_ON(src_in_l->sourcetype != SOURCE_IN);
1690 spin_lock_bh(&(cm->nb->cmsg_lock));
1692 currlh = src_in_l->source.in.acks_pending.next;
1694 while (currlh != &(src_in_l->source.in.acks_pending)) {
1695 struct control_msg_out *currcm = container_of(currlh,
1696 struct control_msg_out,
1697 msg.ack_conn.conn_acks);
1699 BUG_ON(currcm->nb != cm->nb);
1700 BUG_ON(currcm->type != MSGTYPE_ACK_CONN);
1701 BUG_ON(cm->msg.ack_conn.src_in != src_in_l);
1702 BUG_ON(currcm->msg.ack_conn.conn_id !=
1703 cm->msg.ack_conn.conn_id);
1705 if (_try_merge_ackconn(src_in_l, cm, currcm, 1) == 0) {
1706 try_merge_ackconns(src_in_l, currcm);
1707 schedule_controlmsg_timer(currcm->nb);
1708 spin_unlock_bh(&(currcm->nb->cmsg_lock));
1709 return;
1712 currlh = currlh->next;
1715 list_add_tail(&(cm->msg.ack_conn.conn_acks),
1716 &(src_in_l->source.in.acks_pending));
1718 spin_unlock_bh(&(cm->nb->cmsg_lock));
1720 add_control_msg(cm, 0);
1723 static int try_update_ackconn_seqno(struct conn *src_in_l)
1725 int rc = 1;
1727 spin_lock_bh(&(src_in_l->source.in.nb->cmsg_lock));
1729 if (list_empty(&(src_in_l->source.in.acks_pending)) == 0) {
1730 struct control_msg_out *cm = container_of(
1731 src_in_l->source.in.acks_pending.next,
1732 struct control_msg_out,
1733 msg.ack_conn.conn_acks);
1734 BUG_ON(cm->nb != src_in_l->source.in.nb);
1735 BUG_ON(cm->type != MSGTYPE_ACK_CONN);
1736 BUG_ON(cm->msg.ack_conn.src_in != src_in_l);
1737 BUG_ON(cm->msg.ack_conn.conn_id !=
1738 src_in_l->reversedir->target.out.conn_id);
1740 cm->msg.ack_conn.flags = (cm->msg.ack_conn.flags |
1741 KP_ACK_CONN_FLAGS_SEQNO |
1742 KP_ACK_CONN_FLAGS_WINDOW);
1743 cm->msg.ack_conn.seqno = src_in_l->source.in.next_seqno;
1745 src_in_l->source.in.ack_seqno++;
1746 cm->msg.ack_conn.ack_seqno = src_in_l->source.in.ack_seqno;
1748 remove_connack_oooflag_ifold(src_in_l, cm);
1749 recalc_scheduled_ackconn_size(cm);
1751 try_merge_ackconns(src_in_l, cm);
1753 rc = 0;
1756 spin_unlock_bh(&(src_in_l->source.in.nb->cmsg_lock));
1758 return rc;
1761 void send_ack_conn_ifneeded(struct conn *src_in_l)
1763 struct control_msg_out *cm;
1765 BUG_ON(src_in_l->sourcetype != SOURCE_IN);
1767 if (src_in_l->source.in.inorder_ack_needed == 0 &&
1768 ((src_in_l->source.in.window_seqnolimit -
1769 src_in_l->source.in.next_seqno)/2) <
1770 (src_in_l->source.in.window_seqnolimit_remote -
1771 src_in_l->source.in.next_seqno))
1772 return;
1774 if (try_update_ackconn_seqno(src_in_l) == 0)
1775 goto out;
1777 cm = alloc_control_msg(src_in_l->source.in.nb, ACM_PRIORITY_LOW);
1778 if (cm == 0)
1779 return;
1781 cm->type = MSGTYPE_ACK_CONN;
1782 cm->msg.ack_conn.flags = KP_ACK_CONN_FLAGS_SEQNO |
1783 KP_ACK_CONN_FLAGS_WINDOW;
1784 kref_get(&(src_in_l->ref));
1785 cm->msg.ack_conn.src_in = src_in_l;
1786 cm->msg.ack_conn.conn_id = src_in_l->reversedir->target.out.conn_id;
1787 cm->msg.ack_conn.seqno = src_in_l->source.in.next_seqno;
1788 src_in_l->source.in.ack_seqno++;
1789 cm->msg.ack_conn.ack_seqno = src_in_l->source.in.ack_seqno;
1790 cm->length = 6 + ack_conn_len(cm->msg.ack_conn.flags);
1792 mergeadd_ackconn(src_in_l, cm);
1794 out:
1795 src_in_l->source.in.inorder_ack_needed = 0;
1796 src_in_l->source.in.window_seqnolimit_remote =
1797 src_in_l->source.in.window_seqnolimit;
1800 void send_ack_conn_ooo(struct control_msg_out *cm, struct conn *src_in_l,
1801 __u32 conn_id, __u32 seqno_ooo, __u32 length)
1803 cm->type = MSGTYPE_ACK_CONN;
1804 kref_get(&(src_in_l->ref));
1805 BUG_ON(src_in_l->sourcetype != SOURCE_IN);
1806 cm->msg.ack_conn.flags = 0;
1807 cm->msg.ack_conn.src_in = src_in_l;
1808 cm->msg.ack_conn.conn_id = conn_id;
1809 cm->msg.ack_conn.seqno_ooo = seqno_ooo;
1810 cm->msg.ack_conn.length = length;
1811 set_ooolen_flags(cm);
1812 cm->length = 6 + ack_conn_len(cm->msg.ack_conn.flags);
1814 mergeadd_ackconn(src_in_l, cm);
1817 static int try_add_decaytime(struct conn *trgt_out_l, __u16 decaytime)
1819 int rc = 1;
1820 struct conn *src_in = trgt_out_l->reversedir;
1822 spin_lock_bh(&(trgt_out_l->target.out.nb->cmsg_lock));
1824 if (list_empty(&(src_in->source.in.acks_pending)) == 0) {
1825 struct control_msg_out *cm = container_of(
1826 src_in->source.in.acks_pending.next,
1827 struct control_msg_out,
1828 msg.ack_conn.conn_acks);
1829 BUG_ON(cm->nb != trgt_out_l->target.out.nb);
1830 BUG_ON(cm->type != MSGTYPE_ACK_CONN);
1831 BUG_ON(cm->msg.ack_conn.src_in != trgt_out_l->reversedir);
1832 BUG_ON(cm->msg.ack_conn.conn_id !=
1833 trgt_out_l->target.out.conn_id);
1835 BUG_ON((cm->msg.ack_conn.flags & KP_ACK_CONN_FLAGS_CREDITS) !=
1837 cm->msg.ack_conn.flags = (cm->msg.ack_conn.flags |
1838 KP_ACK_CONN_FLAGS_CREDITS);
1839 cm->msg.ack_conn.decaytime_seqno =
1840 trgt_out_l->target.out.decaytime_seqno;
1841 cm->msg.ack_conn.decaytime = decaytime;
1842 recalc_scheduled_ackconn_size(cm);
1844 rc = 0;
1847 spin_unlock_bh(&(trgt_out_l->target.out.nb->cmsg_lock));
1849 return rc;
1852 void send_decaytime(struct conn *trgt_out_l, int force, __u16 decaytime)
1854 struct control_msg_out *cm;
1856 if (try_add_decaytime(trgt_out_l, decaytime) == 0)
1857 goto out;
1859 if (force == 0)
1860 return;
1862 cm = alloc_control_msg(trgt_out_l->target.out.nb, ACM_PRIORITY_LOW);
1864 if (cm == 0)
1865 return;
1867 cm->type = MSGTYPE_ACK_CONN;
1868 cm->msg.ack_conn.flags = KP_ACK_CONN_FLAGS_CREDITS;
1869 kref_get(&(trgt_out_l->reversedir->ref));
1870 BUG_ON(trgt_out_l->targettype != TARGET_OUT);
1871 cm->msg.ack_conn.src_in = trgt_out_l->reversedir;
1872 cm->msg.ack_conn.conn_id = trgt_out_l->target.out.conn_id;
1873 cm->msg.ack_conn.decaytime_seqno =
1874 trgt_out_l->target.out.decaytime_seqno;
1875 cm->msg.ack_conn.decaytime = decaytime;
1877 cm->length = 6 + ack_conn_len(cm->msg.ack_conn.flags);
1878 mergeadd_ackconn(trgt_out_l, cm);
1880 out:
1881 trgt_out_l->target.out.decaytime_last = decaytime;
1882 trgt_out_l->target.out.decaytime_seqno =
1883 (trgt_out_l->target.out.decaytime_seqno + 1) % 64;
1884 trgt_out_l->target.out.decaytime_send_allowed = 0;
1887 void free_ack_conns(struct conn *src_in_l)
1889 int changed = 0;
1890 spin_lock_bh(&(src_in_l->source.in.nb->cmsg_lock));
1891 while (list_empty(&(src_in_l->source.in.acks_pending)) == 0) {
1892 struct list_head *currlh =
1893 src_in_l->source.in.acks_pending.next;
1894 struct control_msg_out *currcm = container_of(currlh,
1895 struct control_msg_out,
1896 msg.ack_conn.conn_acks);
1898 remove_pending_ackconn(currcm);
1899 changed = 1;
1901 if (changed)
1902 schedule_controlmsg_timer(src_in_l->source.in.nb);
1903 spin_unlock_bh(&(src_in_l->source.in.nb->cmsg_lock));
1906 void send_connect_success(struct control_msg_out *cm, __u32 rcvd_conn_id,
1907 __u32 gen_conn_id, __u32 init_seqno, struct conn *src_in)
1909 cm->type = MSGTYPE_CONNECT_SUCCESS;
1910 cm->msg.connect_success.rcvd_conn_id = rcvd_conn_id;
1911 cm->msg.connect_success.gen_conn_id = gen_conn_id;
1912 cm->msg.connect_success.init_seqno = init_seqno;
1913 kref_get(&(src_in->ref));
1914 cm->msg.connect_success.src_in = src_in;
1915 cm->length = 16;
1916 add_control_msg(cm, 0);
1919 void send_connect_nb(struct control_msg_out *cm, __u32 conn_id,
1920 __u32 init_seqno, struct conn *src_in)
1922 cm->type = MSGTYPE_CONNECT;
1923 cm->msg.connect.conn_id = conn_id;
1924 cm->msg.connect.init_seqno = init_seqno;
1925 kref_get(&(src_in->ref));
1926 BUG_ON(src_in->sourcetype != SOURCE_IN);
1927 cm->msg.connect.src_in = src_in;
1928 cm->length = 12;
1929 add_control_msg(cm, 0);
1932 #warning todo ref to buf instead
1933 void send_conndata(struct control_msg_out *cm, __u32 conn_id, __u32 seqno,
1934 char *data_orig, char *data, __u32 datalen)
1936 cm->type = MSGTYPE_CONNDATA;
1937 cm->msg.conn_data.conn_id = conn_id;
1938 cm->msg.conn_data.seqno = seqno;
1939 cm->msg.conn_data.data_orig = data_orig;
1940 cm->msg.conn_data.data = data;
1941 cm->msg.conn_data.datalen = datalen;
1942 cm->length = 11 + datalen;
1943 add_control_msg(cm, 0);
1946 void send_connid_unknown(struct neighbor *nb, __u32 conn_id)
1948 unsigned long iflags;
1949 char *ret;
1950 struct unknownconnid_matchparam ucm;
1952 struct control_msg_out *cm = alloc_control_msg(nb, ACM_PRIORITY_HIGH);
1954 if (unlikely(cm == 0))
1955 return;
1957 cm->type = MSGTYPE_CONNID_UNKNOWN;
1958 cm->msg.reset_connidunknown.conn_id_unknown = conn_id;
1959 cm->length = 5;
1961 ucm.nb = nb;
1962 ucm.conn_id = conn_id;
1964 spin_lock_irqsave(&unknown_connids_lock, iflags);
1965 ret = htable_get(&unknown_connids, ucm_to_key(&ucm), &ucm);
1966 if (ret == 0)
1967 htable_insert(&unknown_connids, (char *) cm, ucm_to_key(&ucm));
1968 spin_unlock_irqrestore(&unknown_connids_lock, iflags);
1970 if (ret != 0) {
1971 struct control_msg_out *cm2 = (struct control_msg_out *) ret;
1973 BUG_ON(cm2->type != MSGTYPE_RESET_CONN &&
1974 cm2->type != MSGTYPE_CONNID_UNKNOWN);
1976 kref_put(&(cm2->ref), cmsg_kref_free);
1978 cm->type = 0;
1979 free_control_msg(cm);
1980 } else {
1981 add_control_msg(cm, 0);
1986 static int matches_connretrans(void *htentry, void *searcheditem)
1988 struct control_retrans *cr = (struct control_retrans *) htentry;
1989 struct retransmit_matchparam *rm = (struct retransmit_matchparam *)
1990 searcheditem;
1992 return rm->nb == cr->nb && rm->seqno == cr->seqno;
1995 static int matches_unknownconnid(void *htentry, void *searcheditem)
1997 struct control_msg_out *cm = (struct control_msg_out *) htentry;
1999 struct unknownconnid_matchparam *ucm =
2000 (struct unknownconnid_matchparam *)searcheditem;
2002 BUG_ON(cm->type != MSGTYPE_RESET_CONN &&
2003 cm->type != MSGTYPE_CONNID_UNKNOWN);
2005 return ucm->nb == cm->nb && ucm->conn_id ==
2006 cm->msg.reset_connidunknown.conn_id_unknown;
2009 void __init cor_kgen_init(void)
2011 controlmsg_slab = kmem_cache_create("cor_controlmsg",
2012 sizeof(struct control_msg_out), 8, 0, 0);
2013 controlretrans_slab = kmem_cache_create("cor_controlretransmsg",
2014 sizeof(struct control_retrans), 8, 0, 0);
2015 htable_init(&retransmits, matches_connretrans,
2016 offsetof(struct control_retrans, htab_entry),
2017 offsetof(struct control_retrans, ref));
2018 htable_init(&unknown_connids, matches_unknownconnid,
2019 offsetof(struct control_msg_out,
2020 msg.reset_connidunknown.htab_entry),
2021 offsetof(struct control_msg_out, ref));
2024 MODULE_LICENSE("GPL");