ack merging, unforced decaytime sending, in order receive during ack oom, resuming...
[cor_2_6_31.git] / net / cor / kpacket_gen.c
blob1e1d95d0bad8a0ba3d4a7438d4d039477aa995fc
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;
78 }ack_conn;
80 struct{
81 __u32 conn_id;
82 __u32 init_seqno;
83 struct conn *sconn;
84 }connect;
86 struct{
87 __u32 rcvd_conn_id;
88 __u32 gen_conn_id;
89 __u32 init_seqno;
90 struct conn *rconn;
91 }connect_success;
93 struct{
94 struct htab_entry htab_entry;
95 __u32 conn_id_reset;
96 __u32 conn_id_unknown;
97 }reset_connidunknown;
99 struct{
100 __u32 conn_id;
101 __u32 seqno;
102 char *data_orig;
103 char *data;
104 __u32 datalen;
105 }conn_data;
107 struct{
108 __u32 delay;
109 }set_max_cmsg_delay;
110 }msg;
113 struct control_retrans {
114 struct kref ref;
116 struct neighbor *nb;
117 __u32 seqno;
119 unsigned long timeout;
121 struct list_head msgs;
123 struct htab_entry htab_entry;
124 struct list_head timeout_list;
127 struct unknownconnid_matchparam {
128 struct neighbor *nb;
129 __u32 conn_id;
132 struct retransmit_matchparam {
133 struct neighbor *nb;
134 __u32 seqno;
138 struct kmem_cache *controlmsg_slab;
139 struct kmem_cache *controlretrans_slab;
141 static struct htable retransmits;
143 DEFINE_SPINLOCK(unknown_connids_lock);
144 static struct htable unknown_connids;
146 atomic_t cmcnt = ATOMIC_INIT(0);
149 static void add_control_msg(struct control_msg_out *msg, int retrans);
151 static void try_merge_ackconns(struct conn *src_in_l,
152 struct control_msg_out *cm);
154 static void mergeadd_ackconn(struct conn *src_in_l, struct control_msg_out *cm);
157 static __u32 ucm_to_key(struct unknownconnid_matchparam *ucm)
159 return ((__u32)((long) ucm->nb)) ^ ucm->conn_id;
162 static __u32 rm_to_key(struct retransmit_matchparam *rm)
164 return ((__u32)((long) rm->nb)) ^ rm->seqno;
167 static inline int isurgent(struct control_msg_out *cm)
169 if (unlikely(cm->type == MSGTYPE_PONG || cm->type == MSGTYPE_ACK))
170 return 1;
171 return 0;
174 static inline int ackconn_connvalid(struct conn *cn_l,
175 struct control_msg_out *cm)
177 if (unlikely(unlikely(cn_l->sourcetype != SOURCE_IN)) ||
178 unlikely((cn_l->source.in.nb != cm->nb)) ||
179 unlikely((cn_l->reversedir->target.out.conn_id !=
180 cm->msg.ack_conn.conn_id) ||
181 unlikely(atomic_read(&(cn_l->isreset)) != 0)))
182 return 0;
183 return 1;
186 static struct control_msg_out *__alloc_control_msg(void)
188 struct control_msg_out *cm = kmem_cache_alloc(controlmsg_slab,
189 GFP_KERNEL);
190 if (unlikely(cm == 0))
191 return 0;
192 memset(cm, 0, sizeof(struct control_msg_out));
193 cm->lh.next = LIST_POISON1;
194 cm->lh.prev = LIST_POISON2;
195 kref_init(&(cm->ref));
196 return cm;
199 static int calc_limit(int limit, int priority)
201 if (priority == ACM_PRIORITY_LOW)
202 return (limit+2)/3;
203 else if (priority == ACM_PRIORITY_MED)
204 return (limit * 2 + 1)/3;
205 else if (priority == ACM_PRIORITY_HIGH)
206 return limit;
207 else
208 BUG();
211 int may_alloc_control_msg(struct neighbor *nb, int priority)
213 long packets1 = atomic_read(&(nb->cmcnt));
214 long packets2 = atomic_read(&(cmcnt));
216 BUG_ON(packets1 < 0);
217 BUG_ON(packets2 < 0);
219 if (packets1 < calc_limit(GUARANTEED_CMSGS_PER_NEIGH, priority))
220 return 1;
222 if (unlikely(unlikely(packets2 >= calc_limit(MAX_CMSGS_PER_NEIGH,
223 priority)) || unlikely(packets1 >= (
224 calc_limit(MAX_CMSGS_PER_NEIGH, priority) *
225 (MAX_CMSGS - packets2) / MAX_CMSGS))))
226 return 0;
227 return 1;
230 static struct control_msg_out *_alloc_control_msg(struct neighbor *nb,
231 int priority, int urgent)
233 struct control_msg_out *cm = 0;
235 BUG_ON(nb == 0);
237 if (urgent == 0) {
238 long packets1 = atomic_inc_return(&(nb->cmcnt));
239 long packets2 = atomic_inc_return(&(cmcnt));
241 BUG_ON(packets1 <= 0);
242 BUG_ON(packets2 <= 0);
244 if (packets1 <= calc_limit(GUARANTEED_CMSGS_PER_NEIGH,
245 priority))
246 goto alloc;
248 if (unlikely(unlikely(packets2 > calc_limit(MAX_CMSGS_PER_NEIGH,
249 priority)) || unlikely(packets1 > (
250 calc_limit(MAX_CMSGS_PER_NEIGH, priority) *
251 (MAX_CMSGS - packets2) / MAX_CMSGS))))
252 goto full;
255 alloc:
256 cm = __alloc_control_msg();
257 if (unlikely(cm == 0))
258 goto full;
259 cm->nb = nb;
261 if (0) {
262 full:
263 if (urgent == 0) {
264 atomic_dec(&(nb->cmcnt));
265 atomic_dec(&(cmcnt));
268 return cm;
271 struct control_msg_out *alloc_control_msg(struct neighbor *nb, int priority)
273 return _alloc_control_msg(nb, priority, 0);
276 static void cmsg_kref_free(struct kref *ref)
278 struct control_msg_out *cm = container_of(ref, struct control_msg_out,
279 ref);
280 kmem_cache_free(controlmsg_slab, cm);
283 void free_control_msg(struct control_msg_out *cm)
285 if (isurgent(cm) == 0) {
286 atomic_dec(&(cm->nb->cmcnt));
287 atomic_dec(&(cmcnt));
290 if (cm->type == MSGTYPE_ACK_CONN) {
291 struct conn *trgt_out = cm->msg.ack_conn.src_in->reversedir;
292 BUG_ON(cm->msg.ack_conn.src_in == 0);
293 mutex_lock(&(trgt_out->rcv_lock));
294 BUG_ON(trgt_out->targettype != TARGET_OUT);
295 if ((cm->msg.ack_conn.flags & KP_ACK_CONN_FLAGS_CREDITS) != 0 &&
296 trgt_out->target.out.decaytime_send_allowed !=
297 0) {
298 trgt_out->target.out.decaytime_send_allowed = 0;
299 mutex_unlock(&(trgt_out->rcv_lock));
300 refresh_conn_credits(trgt_out, 0, 0);
301 } else {
302 mutex_unlock(&(trgt_out->rcv_lock));
305 kref_put(&(cm->msg.ack_conn.src_in->ref), free_conn);
306 cm->msg.ack_conn.src_in = 0;
307 } else if (cm->type == MSGTYPE_CONNECT) {
308 BUG_ON(cm->msg.connect.sconn == 0);
309 kref_put(&(cm->msg.connect.sconn->ref), free_conn);
310 cm->msg.connect.sconn = 0;
311 } else if (cm->type == MSGTYPE_CONNECT_SUCCESS) {
312 BUG_ON(cm->msg.connect_success.rconn == 0);
313 kref_put(&(cm->msg.connect_success.rconn->ref), free_conn);
314 cm->msg.connect_success.rconn = 0;
315 } else if (cm->type == MSGTYPE_RESET_CONN ||
316 cm->type == MSGTYPE_CONNID_UNKNOWN) {
317 struct unknownconnid_matchparam ucm;
319 ucm.nb = cm->nb;
320 ucm.conn_id = cm->msg.reset_connidunknown.conn_id_unknown;
322 htable_delete(&unknown_connids, ucm_to_key(&ucm), &ucm,
323 cmsg_kref_free);
326 kref_put(&(cm->ref), cmsg_kref_free);
329 static void free_control_retrans(struct kref *ref)
331 struct control_retrans *cr = container_of(ref, struct control_retrans,
332 ref);
334 while (list_empty(&(cr->msgs)) == 0) {
335 struct control_msg_out *cm = container_of(cr->msgs.next,
336 struct control_msg_out, lh);
337 list_del(&(cm->lh));
338 free_control_msg(cm);
341 kmem_cache_free(controlretrans_slab, cr);
345 static void set_retrans_timeout(struct control_retrans *cr, struct neighbor *nb)
347 cr->timeout = jiffies + usecs_to_jiffies(100000 +
348 ((__u32) atomic_read(&(nb->latency))) * 2 +
349 ((__u32) atomic_read(&(nb->max_remote_cmsg_delay))));
352 static void readd_control_retrans(struct control_retrans *cr)
354 while (list_empty(&(cr->msgs)) == 0) {
355 struct control_msg_out *cm = container_of(cr->msgs.next,
356 struct control_msg_out, lh);
357 list_del(&(cm->lh));
358 if (cm->type == MSGTYPE_ACK_CONN) {
359 struct conn *cn_l = cm->msg.ack_conn.src_in;
360 mutex_lock(&(cn_l->rcv_lock));
361 if (unlikely(ackconn_connvalid(cn_l, cm) == 0)) {
362 free_control_msg(cm);
363 } else {
364 mergeadd_ackconn(cn_l, cm);
367 mutex_unlock(&(cn_l->rcv_lock));
368 } else {
369 add_control_msg(cm, 1);
374 void retransmit_timerfunc(struct work_struct *work)
376 unsigned long iflags;
378 struct neighbor *nb = container_of(to_delayed_work(work),
379 struct neighbor, retrans_timer);
381 int nbstate;
382 int nbput = 0;
384 spin_lock_irqsave(&(nb->state_lock), iflags);
385 nbstate = nb->state;
386 spin_unlock_irqrestore(&(nb->state_lock), iflags);
388 while (1) {
389 struct control_retrans *cr = 0;
390 struct retransmit_matchparam rm;
392 spin_lock_irqsave(&(nb->retrans_lock), iflags);
394 if (list_empty(&(nb->retrans_list))) {
395 nb->retrans_timer_running = 0;
396 nbput = 1;
397 break;
400 cr = container_of(nb->retrans_list.next,
401 struct control_retrans, timeout_list);
403 BUG_ON(cr->nb != nb);
405 rm.seqno = cr->seqno;
406 rm.nb = nb;
408 list_del(&(cr->timeout_list));
410 if (unlikely(nbstate == NEIGHBOR_STATE_KILLED)) {
411 spin_unlock_irqrestore(&(nb->retrans_lock), iflags);
413 htable_delete(&retransmits, rm_to_key(&rm), &rm,
414 free_control_retrans);
415 kref_put(&(cr->ref), free_control_retrans);
416 continue;
419 if (time_after(cr->timeout, jiffies)) {
420 list_add(&(cr->timeout_list), &(nb->retrans_list));
421 schedule_delayed_work(&(nb->retrans_timer),
422 cr->timeout - jiffies);
423 break;
426 if (unlikely(htable_delete(&retransmits, rm_to_key(&rm), &rm,
427 free_control_retrans)))
428 BUG();
430 spin_unlock_irqrestore(&(nb->retrans_lock), iflags);
432 readd_control_retrans(cr);
434 kref_put(&(cr->ref), free_control_retrans);
437 spin_unlock_irqrestore(&(nb->retrans_lock), iflags);
439 if (nbput)
440 kref_put(&(nb->ref), neighbor_free);
443 static void schedule_retransmit(struct control_retrans *cr, struct neighbor *nb)
445 unsigned long iflags;
447 struct retransmit_matchparam rm;
448 int first;
450 rm.seqno = cr->seqno;
451 rm.nb = nb;
453 set_retrans_timeout(cr, nb);
455 spin_lock_irqsave(&(nb->retrans_lock), iflags);
456 htable_insert(&retransmits, (char *) cr, rm_to_key(&rm));
457 first = list_empty(&(nb->retrans_list));
458 list_add_tail(&(cr->timeout_list), &(nb->retrans_list));
460 if (first && nb->retrans_timer_running == 0) {
461 schedule_delayed_work(&(nb->retrans_timer),
462 cr->timeout - jiffies);
463 nb->retrans_timer_running = 1;
464 kref_get(&(nb->ref));
467 spin_unlock_irqrestore(&(nb->retrans_lock), iflags);
470 void kern_ack_rcvd(struct neighbor *nb, __u32 seqno)
472 unsigned long iflags;
474 struct control_retrans *cr = 0;
475 struct retransmit_matchparam rm;
477 rm.seqno = seqno;
478 rm.nb = nb;
480 spin_lock_irqsave(&(nb->retrans_lock), iflags);
482 cr = (struct control_retrans *) htable_get(&retransmits, rm_to_key(&rm),
483 &rm);
485 if (cr == 0) {
486 printk(KERN_ERR "bogus/duplicate ack received");
487 goto out;
490 if (unlikely(htable_delete(&retransmits, rm_to_key(&rm), &rm,
491 free_control_retrans)))
492 BUG();
494 BUG_ON(cr->nb != nb);
496 list_del(&(cr->timeout_list));
498 out:
499 spin_unlock_irqrestore(&(nb->retrans_lock), iflags);
501 if (cr != 0) {
502 kref_put(&(cr->ref), free_control_retrans); /* htable_get */
503 kref_put(&(cr->ref), free_control_retrans); /* list */
507 static void padding(struct sk_buff *skb, int length)
509 char *dst;
510 if (length <= 0)
511 return;
512 dst = skb_put(skb, length);
513 BUG_ON(dst == 0);
514 memset(dst, KP_PADDING, length);
517 static int add_ack(struct sk_buff *skb, struct control_retrans *cr,
518 struct control_msg_out *cm, int spaceleft)
520 char *dst;
522 if (unlikely(spaceleft < 5))
523 return 0;
525 dst = skb_put(skb, 5);
526 BUG_ON(dst == 0);
528 dst[0] = KP_ACK;
529 put_u32(dst + 1, cm->msg.ack.seqno, 1);
531 atomic_dec(&(cm->nb->ucmcnt));
532 free_control_msg(cm);
534 return 5;
537 static int add_ack_conn(struct sk_buff *skb, struct control_retrans *cr,
538 struct control_msg_out *cm, int spaceleft)
540 char *dst;
541 int offset = 0;
543 if (unlikely(spaceleft < cm->length))
544 return 0;
546 dst = skb_put(skb, cm->length);
547 BUG_ON(dst == 0);
549 dst[offset] = KP_ACK_CONN;
550 offset++;
551 put_u32(dst + offset, cm->msg.ack_conn.conn_id, 1);
552 offset += 4;
553 dst[offset] = cm->msg.ack_conn.flags;
554 offset++;
556 if ((cm->msg.ack_conn.flags & KP_ACK_CONN_FLAGS_SEQNO) != 0) {
557 put_u32(dst + offset, cm->msg.ack_conn.seqno, 1);
558 offset += 4;
560 if ((cm->msg.ack_conn.flags & KP_ACK_CONN_FLAGS_WINDOW) != 0) {
561 BUG_ON(cm->msg.ack_conn.src_in == 0);
562 dst[offset] = get_window(cm->msg.ack_conn.src_in,
563 cm->nb, cm->msg.ack_conn.conn_id, 1);
564 offset++;
568 if (ooolen(cm->msg.ack_conn.flags) != 0) {
569 put_u32(dst + offset, cm->msg.ack_conn.seqno_ooo, 1);
570 offset += 4;
571 if (ooolen(cm->msg.ack_conn.flags) == 1) {
572 BUG_ON(cm->msg.ack_conn.length > 255);
573 dst[offset] = cm->msg.ack_conn.length;
574 offset += 1;
575 } else if (ooolen(cm->msg.ack_conn.flags) == 2) {
576 BUG_ON(cm->msg.ack_conn.length <= 255);
577 BUG_ON(cm->msg.ack_conn.length > 65535);
578 put_u16(dst + offset, cm->msg.ack_conn.length, 1);
579 offset += 2;
580 } else if (ooolen(cm->msg.ack_conn.flags) == 4) {
581 BUG_ON(cm->msg.ack_conn.length <= 65535);
582 put_u32(dst + offset, cm->msg.ack_conn.length, 1);
583 offset += 4;
584 } else {
585 BUG();
589 if ((cm->msg.ack_conn.flags & KP_ACK_CONN_FLAGS_CREDITS) != 0) {
590 __u16 value = cm->msg.ack_conn.decaytime + (
591 cm->msg.ack_conn.decaytime_seqno << 10);
593 BUG_ON(cm->msg.ack_conn.decaytime >= 1024);
594 BUG_ON(cm->msg.ack_conn.decaytime_seqno >= 64);
596 put_u16(dst + offset, value, 1);
597 offset += 2;
600 list_add_tail(&(cm->lh), &(cr->msgs));
602 BUG_ON(offset != cm->length);
603 return offset;
606 static int add_ping(struct sk_buff *skb, __u32 cookie,
607 int spaceleft)
609 char *dst;
611 if (unlikely(spaceleft < 5))
612 return 0;
614 dst = skb_put(skb, 5);
615 BUG_ON(dst == 0);
617 dst[0] = KP_PING;
618 put_u32(dst + 1, cookie, 0);
620 return 5;
623 static int add_pong(struct sk_buff *skb, struct control_retrans *cr,
624 struct control_msg_out *cm, int spaceleft)
626 char *dst;
628 if (unlikely(spaceleft < 9))
629 return 0;
631 if (cm->msg.pong.type == MSGTYPE_PONG_TIMEENQUEUED) {
632 __s64 now = ktime_to_ns(ktime_get());
633 __s64 enq = ktime_to_ns(cm->msg.pong.delaycomp.time_enqueued);
634 __s64 respdelay = (now - enq + 500) / 1000;
635 if (unlikely(respdelay >= (1LL << 32)))
636 respdelay = (1LL << 32) - 1;
637 cm->msg.pong.type = MSGTYPE_PONG_RESPDELAY;
638 cm->msg.pong.delaycomp.respdelay = (__u32) respdelay;
641 BUG_ON(cm->msg.pong.type != MSGTYPE_PONG_RESPDELAY);
643 dst = skb_put(skb, 9);
644 BUG_ON(dst == 0);
646 dst[0] = KP_PONG;
647 put_u32(dst + 1, cm->msg.pong.cookie, 0);
648 put_u32(dst + 5, cm->msg.pong.delaycomp.respdelay, 1);
651 atomic_dec(&(cm->nb->ucmcnt));
652 list_add_tail(&(cm->lh), &(cr->msgs));
654 return 9;
657 static __u16 get_credits(struct conn *sconn)
659 __u16 ret;
660 mutex_lock(&(sconn->reversedir->rcv_lock));
661 BUG_ON(sconn->reversedir->targettype != TARGET_OUT);
663 BUG_ON(sconn->reversedir->target.out.decaytime_last >= 1024);
664 BUG_ON(sconn->reversedir->target.out.decaytime_seqno >= 64);
665 ret = sconn->reversedir->target.out.decaytime_last + (
666 sconn->reversedir->target.out.decaytime_seqno <<
667 10);
668 mutex_unlock(&(sconn->reversedir->rcv_lock));
670 return ret;
673 static int add_connect(struct sk_buff *skb, struct control_retrans *cr,
674 struct control_msg_out *cm, int spaceleft)
676 char *dst;
678 if (unlikely(spaceleft < 12))
679 return 0;
681 dst = skb_put(skb, 12);
682 BUG_ON(dst == 0);
684 dst[0] = KP_CONNECT;
685 put_u32(dst + 1, cm->msg.connect.conn_id, 1);
686 put_u32(dst + 5, cm->msg.connect.init_seqno, 1);
687 BUG_ON(cm->msg.connect.sconn == 0);
688 dst[9] = get_window(cm->msg.connect.sconn, cm->nb, 0, 1);
689 put_u16(dst + 10, get_credits(cm->msg.connect.sconn), 1);
691 list_add_tail(&(cm->lh), &(cr->msgs));
693 return 12;
696 static int add_connect_success(struct sk_buff *skb, struct control_retrans *cr,
697 struct control_msg_out *cm, int spaceleft)
699 char *dst;
701 if (unlikely(spaceleft < 16))
702 return 0;
704 dst = skb_put(skb, 16);
705 BUG_ON(dst == 0);
707 dst[0] = KP_CONNECT_SUCCESS;
708 put_u32(dst + 1, cm->msg.connect_success.rcvd_conn_id, 1);
709 put_u32(dst + 5, cm->msg.connect_success.gen_conn_id, 1);
710 put_u32(dst + 9, cm->msg.connect_success.init_seqno, 1);
711 BUG_ON(cm->msg.connect_success.rconn == 0);
712 dst[13] = get_window(cm->msg.connect_success.rconn, cm->nb,
713 cm->msg.connect_success.rcvd_conn_id, 1);
714 put_u16(dst + 14, get_credits(cm->msg.connect_success.rconn), 1);
716 list_add_tail(&(cm->lh), &(cr->msgs));
718 return 16;
721 static int add_reset_conn(struct sk_buff *skb, struct control_retrans *cr,
722 struct control_msg_out *cm, int spaceleft)
724 char *dst;
726 if (unlikely(spaceleft < 5))
727 return 0;
729 dst = skb_put(skb, 5);
730 BUG_ON(dst == 0);
732 dst[0] = KP_RESET_CONN;
733 put_u32(dst + 1, cm->msg.reset_connidunknown.conn_id_reset, 1);
735 list_add_tail(&(cm->lh), &(cr->msgs));
737 return 5;
740 static int add_conndata(struct sk_buff *skb, struct control_retrans *cr,
741 struct control_msg_out *cm, int spaceleft,
742 struct control_msg_out **split_conndata, __u32 *sc_sendlen)
744 char *dst;
746 int totallen = cm->msg.conn_data.datalen + 11;
747 int putlen = min(totallen, spaceleft);
748 int dataputlen = putlen - 11;
750 BUG_ON(split_conndata == 0);
751 BUG_ON(sc_sendlen == 0);
753 if (dataputlen < 1 || (spaceleft < 25 && spaceleft < totallen))
754 return 0;
756 dst = skb_put(skb, putlen);
757 BUG_ON(dst == 0);
759 dst[0] = KP_CONN_DATA;
760 put_u32(dst + 1, cm->msg.conn_data.conn_id, 1);
761 put_u32(dst + 5, cm->msg.conn_data.seqno, 1);
762 put_u16(dst + 9, dataputlen, 1);
764 memcpy(dst + 11, cm->msg.conn_data.data, dataputlen);
766 if (cm->msg.conn_data.datalen == dataputlen) {
767 list_add_tail(&(cm->lh), &(cr->msgs));
768 } else {
769 *split_conndata = cm;
770 *sc_sendlen = dataputlen;
773 return putlen;
776 static int add_connid_unknown(struct sk_buff *skb, struct control_retrans *cr,
777 struct control_msg_out *cm, int spaceleft)
779 char *dst;
781 if (unlikely(spaceleft < 5))
782 return 0;
784 dst = skb_put(skb, 5);
785 BUG_ON(dst == 0);
787 dst[0] = KP_CONNID_UNKNOWN;
788 put_u32(dst + 1, cm->msg.reset_connidunknown.conn_id_unknown, 1);
790 list_add_tail(&(cm->lh), &(cr->msgs));
792 return 5;
795 static int add_set_max_cmsg_dly(struct sk_buff *skb, struct control_retrans *cr,
796 struct control_msg_out *cm, int spaceleft)
798 char *dst;
800 if (unlikely(spaceleft < 5))
801 return 0;
803 dst = skb_put(skb, 5);
804 BUG_ON(dst == 0);
806 dst[0] = KP_SET_MAX_CMSG_DELAY;
807 put_u32(dst + 1, cm->msg.set_max_cmsg_delay.delay, 1);
809 list_add_tail(&(cm->lh), &(cr->msgs));
811 return 5;
814 static int add_message(struct sk_buff *skb, struct control_retrans *cr,
815 struct control_msg_out *cm, int spaceleft,
816 struct control_msg_out **split_conndata, __u32 *sc_sendlen)
818 BUG_ON(split_conndata != 0 && *split_conndata != 0);
819 BUG_ON(sc_sendlen != 0 && *sc_sendlen != 0);
821 switch (cm->type) {
822 case MSGTYPE_ACK:
823 return add_ack(skb, cr, cm, spaceleft);
824 case MSGTYPE_ACK_CONN:
825 return add_ack_conn(skb, cr, cm, spaceleft);
826 case MSGTYPE_PONG:
827 return add_pong(skb, cr, cm, spaceleft);
828 case MSGTYPE_CONNECT:
829 return add_connect(skb, cr, cm, spaceleft);
830 case MSGTYPE_CONNECT_SUCCESS:
831 return add_connect_success(skb, cr, cm, spaceleft);
832 case MSGTYPE_RESET_CONN:
833 return add_reset_conn(skb, cr, cm, spaceleft);
834 case MSGTYPE_CONNDATA:
835 return add_conndata(skb, cr, cm, spaceleft, split_conndata,
836 sc_sendlen);
837 case MSGTYPE_CONNID_UNKNOWN:
838 return add_connid_unknown(skb, cr, cm, spaceleft);
839 case MSGTYPE_SET_MAX_CMSG_DELAY:
840 return add_set_max_cmsg_dly(skb, cr, cm, spaceleft);
841 default:
842 BUG();
844 BUG();
845 return 0;
848 static void requeue_message(struct control_msg_out *cm)
850 if (cm->type == MSGTYPE_ACK_CONN) {
851 struct conn *cn_l = cm->msg.ack_conn.src_in;
853 mutex_lock(&(cn_l->rcv_lock));
854 if (unlikely(ackconn_connvalid(cn_l, cm) == 0)) {
855 free_control_msg(cm);
856 } else {
857 mutex_lock(&(cm->nb->cmsg_lock));
859 list_add(&(cm->lh), &(cm->nb->control_msgs_out));
860 cm->nb->cmlength += cm->length;
862 list_add(&(cm->msg.ack_conn.conn_acks),
863 &(cn_l->source.in.acks_pending));
864 try_merge_ackconns(cn_l, cm);
866 mutex_unlock(&(cm->nb->cmsg_lock));
868 mutex_unlock(&(cn_l->rcv_lock));
869 return;
872 if (isurgent(cm)) {
873 list_add(&(cm->lh), &(cm->nb->ucontrol_msgs_out));
874 cm->nb->ucmlength += cm->length;
875 } else {
876 list_add(&(cm->lh), &(cm->nb->control_msgs_out));
877 cm->nb->cmlength += cm->length;
881 static struct control_msg_out *dequeue_message(struct neighbor *nb,
882 int urgentonly)
884 struct control_msg_out *cm;
886 if (list_empty(&(nb->ucontrol_msgs_out)) == 0) {
887 cm = container_of(nb->ucontrol_msgs_out.next,
888 struct control_msg_out, lh);
889 nb->ucmlength -= cm->length;
890 } else if (urgentonly) {
891 return 0;
892 } else {
893 if (list_empty(&(nb->control_msgs_out)))
894 return 0;
896 cm = container_of(nb->control_msgs_out.next,
897 struct control_msg_out, lh);
898 nb->cmlength -= cm->length;
901 BUG_ON(cm->nb != nb);
903 list_del(&(cm->lh));
904 if (cm->type == MSGTYPE_ACK_CONN)
905 list_del(&(cm->msg.ack_conn.conn_acks));
907 return cm;
910 static __u32 __send_messages(struct neighbor *nb, struct sk_buff *skb,
911 struct control_retrans *cr, int spaceleft, int urgentonly,
912 struct control_msg_out **split_conndata, __u32 *sc_sendlen)
914 __u32 length = 0;
915 while (1) {
916 int rc;
917 struct control_msg_out *cm;
919 mutex_lock(&(nb->cmsg_lock));
920 cm = dequeue_message(nb, urgentonly);
921 mutex_unlock(&(nb->cmsg_lock));
923 if (cm == 0)
924 break;
926 rc = add_message(skb, cr, cm, spaceleft - length,
927 split_conndata, sc_sendlen);
928 if (rc == 0) {
929 requeue_message(cm);
930 break;
933 length += rc;
936 return length;
939 static __u32 __send_messages_smcd(struct neighbor *nb, struct sk_buff *skb,
940 struct control_retrans *cr, int spaceleft)
942 struct control_msg_out *cm;
943 int rc;
945 cm = alloc_control_msg(nb, ACM_PRIORITY_LOW);
947 if (unlikely(cm == 0))
948 return 0;
950 cm->type = MSGTYPE_SET_MAX_CMSG_DELAY;
951 cm->msg.set_max_cmsg_delay.delay = CMSG_INTERVAL_MS * 10;
952 cm->length = 5;
954 rc = add_message(skb, cr, cm, spaceleft, 0, 0);
956 nb->max_cmsg_delay_sent = 1;
958 return rc;
961 static int _send_messages(struct neighbor *nb, struct sk_buff *skb, int ping,
962 struct control_retrans *cr, int spaceleft, int urgentonly)
964 int rc;
965 __u32 length = 0;
966 __u32 pinglen = 0;
967 __u32 pingcookie = 0;
968 unsigned long last_ping_time;
969 struct control_msg_out *split_conndata = 0;
970 __u32 sc_sendlen = 0;
972 mutex_lock(&(nb->cmsg_lock));
974 if (ping != 0) {
975 int rc;
976 pingcookie = add_ping_req(nb, &last_ping_time);
977 rc = add_ping(skb, pingcookie, spaceleft - length);
978 BUG_ON(rc == 0);
979 pinglen = rc;
980 length += rc;
983 if (likely(urgentonly == 0) && unlikely(nb->max_cmsg_delay_sent == 0))
984 length += __send_messages_smcd(nb, skb, cr, spaceleft - length);
986 mutex_unlock(&(nb->cmsg_lock));
988 length += __send_messages(nb, skb, cr, spaceleft - length, urgentonly,
989 &split_conndata, &sc_sendlen);
991 BUG_ON(length > spaceleft);
993 if (likely(ping != 2) && unlikely(length == pinglen)) {
994 unadd_ping_req(nb, pingcookie, last_ping_time);
995 kfree_skb(skb);
997 BUG_ON(list_empty(&(cr->msgs)) == 0);
998 kref_put(&(cr->ref), free_control_retrans);
1000 atomic_sub(1, &(nb->kpacket_seqno));
1001 return 0;
1004 padding(skb, spaceleft - length);
1006 rc = dev_queue_xmit(skb);
1008 if (rc != 0) {
1009 unadd_ping_req(nb, pingcookie, last_ping_time);
1011 while (list_empty(&(cr->msgs)) == 0) {
1012 struct control_msg_out *cm = container_of(cr->msgs.prev,
1013 struct control_msg_out, lh);
1014 list_del(&(cm->lh));
1015 add_control_msg(cm, 1);
1018 if (split_conndata != 0) {
1019 add_control_msg(split_conndata, 1);
1022 kref_put(&(cr->ref), free_control_retrans);
1023 } else {
1024 struct list_head *curr = cr->msgs.next;
1026 while(curr != &(cr->msgs)) {
1027 struct control_msg_out *cm = container_of(curr,
1028 struct control_msg_out, lh);
1030 curr = curr->next;
1032 if (cm->type == MSGTYPE_CONNDATA) {
1033 list_del(&(cm->lh));
1034 kfree(cm->msg.conn_data.data_orig);
1035 free_control_msg(cm);
1039 if (split_conndata != 0) {
1040 BUG_ON(sc_sendlen == 0);
1041 BUG_ON(sc_sendlen >=
1042 split_conndata->msg.conn_data.datalen);
1044 split_conndata->msg.conn_data.data += sc_sendlen;
1045 split_conndata->msg.conn_data.datalen -= sc_sendlen;
1047 send_conndata(split_conndata,
1048 split_conndata->msg.conn_data.conn_id,
1049 split_conndata->msg.conn_data.seqno,
1050 split_conndata->msg.conn_data.data_orig,
1051 split_conndata->msg.conn_data.data,
1052 split_conndata->msg.conn_data.datalen);
1056 if (list_empty(&(cr->msgs)))
1057 kref_put(&(cr->ref), free_control_retrans);
1058 else
1059 schedule_retransmit(cr, nb);
1062 return rc;
1065 static __u32 get_total_messages_length(struct neighbor *nb, int ping,
1066 int urgentonly)
1068 __u32 length = nb->ucmlength;
1070 if (likely(urgentonly == 0)) {
1071 length += nb->cmlength;
1073 if (unlikely(nb->max_cmsg_delay_sent == 0))
1074 length += 5;
1076 if (ping == 2 || (length > 0 && ping != 0))
1077 length += 5;
1079 return length;
1082 static int reset_timeouted_conn_needed(struct neighbor *nb, struct conn *src_in)
1084 if (unlikely(unlikely(src_in->sourcetype != SOURCE_IN) ||
1085 unlikely(src_in->source.in.nb != nb) ||
1086 unlikely(atomic_read(&(src_in->isreset)) != 0)))
1087 return 0;
1088 else if (likely(time_after(src_in->source.in.jiffies_last_act +
1089 CONN_ACTIVITY_UPDATEINTERVAL_SEC * HZ +
1090 CONN_INACTIVITY_TIMEOUT_SEC * HZ, jiffies)))
1091 return 0;
1093 return 1;
1096 static void reset_timeouted_conns(struct neighbor *nb)
1098 int i;
1099 for (i=0;i<10000;i++) {
1100 unsigned long iflags;
1101 struct conn *src_in;
1103 int resetrc = 1;
1104 int rc = 0;
1106 spin_lock_irqsave(&(nb->conn_list_lock), iflags);
1108 if (list_empty(&(nb->rcv_conn_list))) {
1109 spin_unlock_irqrestore(&(nb->conn_list_lock), iflags);
1110 break;
1113 src_in = container_of(nb->rcv_conn_list.next, struct conn,
1114 source.in.nb_list);
1115 kref_get(&(src_in->ref));
1117 spin_unlock_irqrestore(&(nb->conn_list_lock), iflags);
1120 mutex_lock(&(src_in->rcv_lock));
1122 resetrc = reset_timeouted_conn_needed(nb, src_in);
1123 if (likely(resetrc == 0))
1124 goto put;
1126 rc = send_reset_conn(nb, src_in->reversedir->target.out.conn_id,
1127 src_in->source.in.conn_id, 1);
1128 if (unlikely(rc != 0))
1129 goto put;
1131 atomic_cmpxchg(&(src_in->reversedir->isreset), 0, 1);
1132 mutex_unlock(&(src_in->rcv_lock));
1133 reset_conn(src_in);
1135 if (0) {
1136 put:
1137 mutex_unlock(&(src_in->rcv_lock));
1139 kref_put(&(src_in->ref), free_conn);
1141 if (likely(resetrc == 0) || rc != 0)
1142 break;
1146 int send_messages(struct neighbor *nb, int resume)
1148 int i;
1149 int rc = 0;
1150 int ping;
1151 int targetmss = mss(nb);
1153 int nbstate = get_neigh_state(nb);
1154 int urgentonly = (nbstate != NEIGHBOR_STATE_ACTIVE);
1156 if (likely(urgentonly == 0))
1157 reset_timeouted_conns(nb);
1159 mutex_lock(&(nb->send_cmsg_lock));
1160 mutex_lock(&(nb->cmsg_lock));
1162 ping = time_to_send_ping(nb);
1164 for (i=0;1;i++) {
1165 __u32 length;
1167 __u32 seqno;
1168 struct sk_buff *skb;
1169 struct control_retrans *cr;
1171 BUG_ON(list_empty(&(nb->control_msgs_out)) &&
1172 (nb->cmlength != 0));
1173 BUG_ON((list_empty(&(nb->control_msgs_out)) == 0) &&
1174 (nb->cmlength == 0));
1175 BUG_ON(list_empty(&(nb->ucontrol_msgs_out)) &&
1176 (nb->ucmlength != 0));
1177 BUG_ON((list_empty(&(nb->ucontrol_msgs_out)) == 0) &&
1178 (nb->ucmlength == 0));
1179 BUG_ON(nb->cmlength < 0);
1180 BUG_ON(nb->ucmlength < 0);
1182 length = get_total_messages_length(nb, ping, urgentonly);
1184 if (length == 0)
1185 break;
1187 if (length < targetmss && i > 0)
1188 break;
1190 seqno = atomic_add_return(1, &(nb->kpacket_seqno));
1192 if (length > targetmss)
1193 length = targetmss;
1195 mutex_unlock(&(nb->cmsg_lock));
1196 skb = create_packet(nb, length, GFP_KERNEL, 0, seqno);
1197 if (unlikely(skb == 0)) {
1198 printk(KERN_ERR "cor: send_messages: cannot allocate "
1199 "skb (out of memory?)");
1200 goto oom;
1203 cr = kmem_cache_alloc(controlretrans_slab, GFP_KERNEL);
1204 if (unlikely(cr == 0)) {
1205 kfree_skb(skb);
1206 printk(KERN_ERR "cor: send_messages: cannot allocate "
1207 "control_retrans (out of memory?)");
1208 goto oom;
1210 memset(cr, 0, sizeof(struct control_retrans));
1211 kref_init(&(cr->ref));
1212 cr->nb = nb;
1213 cr->seqno = seqno;
1214 INIT_LIST_HEAD(&(cr->msgs));
1216 rc = _send_messages(nb, skb, ping, cr, length, urgentonly);
1217 ping = 0;
1219 mutex_lock(&(nb->cmsg_lock));
1221 if (rc != 0)
1222 break;
1225 if (0) {
1226 oom:
1227 mutex_lock(&(nb->cmsg_lock));
1230 if (rc != 0) {
1231 if (resume == 0)
1232 qos_enqueue(nb->dev, &(nb->rb_kp), QOS_CALLER_KPACKET);
1233 } else {
1234 atomic_set(&(nb->cmsg_work_scheduled), 0);
1235 schedule_controlmsg_timer(nb);
1238 mutex_unlock(&(nb->cmsg_lock));
1239 mutex_unlock(&(nb->send_cmsg_lock));
1241 if (rc == 0)
1242 kref_put(&(nb->ref), neighbor_free);
1244 return rc;
1247 void controlmsg_workfunc(struct work_struct *work)
1249 struct neighbor *nb = container_of(work, struct neighbor, cmsg_work);
1250 send_messages(nb, 0);
1253 static void schedule_cmsg_work(struct neighbor *nb)
1255 if (atomic_cmpxchg(&(nb->cmsg_work_scheduled), 0, 1) == 0) {
1256 kref_get(&(nb->ref));
1257 atomic_cmpxchg(&(nb->cmsg_timer_running), 1, 2);
1258 schedule_work(&(nb->cmsg_work));
1262 void controlmsg_timerfunc(unsigned long arg)
1264 struct neighbor *nb = (struct neighbor *) arg;
1266 int oldval = atomic_xchg(&(nb->cmsg_timer_running), 0);
1268 BUG_ON(oldval == 0);
1270 if (likely(oldval == 1))
1271 schedule_cmsg_work(nb);
1272 kref_put(&(nb->ref), neighbor_free);
1275 static unsigned long get_cmsg_timeout(struct neighbor *nb, int nbstate)
1277 unsigned long timeout = get_next_ping_time(nb);
1279 if (likely(nbstate == NEIGHBOR_STATE_ACTIVE) &&
1280 list_empty(&(nb->control_msgs_out)) == 0) {
1281 struct control_msg_out *first = container_of(
1282 nb->control_msgs_out.next,
1283 struct control_msg_out, lh);
1284 if (time_before(first->timeout, jiffies +
1285 usecs_to_jiffies(nb->cmsg_interval)))
1286 timeout = jiffies;
1287 else if (time_before(first->timeout, timeout))
1288 timeout = first->timeout;
1291 if (list_empty(&(nb->ucontrol_msgs_out)) == 0) {
1292 struct control_msg_out *first = container_of(
1293 nb->ucontrol_msgs_out.next,
1294 struct control_msg_out, lh);
1295 if (time_before(first->timeout, jiffies +
1296 usecs_to_jiffies(nb->cmsg_interval)))
1297 timeout = jiffies;
1298 else if (time_before(first->timeout, timeout))
1299 timeout = first->timeout;
1302 return timeout;
1305 static int cmsg_full_packet(struct neighbor *nb, int nbstate)
1307 int ping = time_to_send_ping(nb);
1308 int urgentonly = (nbstate != NEIGHBOR_STATE_ACTIVE);
1309 __u32 len = get_total_messages_length(nb, ping, urgentonly);
1311 if (len == 0)
1312 return 0;
1313 if (len < mss(nb))
1314 return 0;
1316 return 1;
1319 void schedule_controlmsg_timer(struct neighbor *nb)
1321 unsigned long timeout;
1322 int state = get_neigh_state(nb);
1324 if (unlikely(state == NEIGHBOR_STATE_KILLED)) {
1325 atomic_cmpxchg(&(nb->cmsg_timer_running), 1, 2);
1326 return;
1329 if (unlikely(atomic_read(&(nb->cmsg_work_scheduled)) == 1))
1330 return;
1332 if (cmsg_full_packet(nb, state))
1333 goto now;
1335 timeout = get_cmsg_timeout(nb, state);
1337 if (time_before_eq(timeout, jiffies)) {
1338 now:
1339 schedule_cmsg_work(nb);
1340 } else {
1341 if (atomic_xchg(&(nb->cmsg_timer_running), 1) == 0)
1342 kref_get(&(nb->ref));
1343 mod_timer(&(nb->cmsg_timer), timeout);
1347 static void free_oldest_ucm(struct neighbor *nb)
1349 struct control_msg_out *cm = container_of(nb->ucontrol_msgs_out.next,
1350 struct control_msg_out, lh);
1352 BUG_ON(list_empty(&(nb->ucontrol_msgs_out)));
1353 BUG_ON(isurgent(cm) == 0);
1355 list_del(&(cm->lh));
1356 nb->ucmlength -= cm->length;
1357 atomic_dec(&(nb->ucmcnt));
1358 free_control_msg(cm);
1361 static void add_control_msg(struct control_msg_out *cm, int retrans)
1363 int nbstate;
1364 __u64 newinterval;
1365 unsigned long jiffies_tmp;
1367 BUG_ON(cm->nb == 0);
1369 nbstate = get_neigh_state(cm->nb);
1371 BUG_ON(cm == 0);
1372 BUG_ON(cm->lh.next != LIST_POISON1 || cm->lh.prev != LIST_POISON2);
1374 cm->timeout = jiffies + msecs_to_jiffies(CMSG_INTERVAL_MS);
1376 mutex_lock(&(cm->nb->cmsg_lock));
1378 if (isurgent(cm)) {
1379 long msgs;
1381 msgs = atomic_inc_return(&(cm->nb->ucmcnt));
1382 BUG_ON(msgs <= 0);
1384 if (unlikely(retrans)) {
1385 if (msgs > MAX_URGENT_CMSGS_PER_NEIGH_RETRANSALLOW ||
1386 msgs > MAX_URGENT_CMSGS_PER_NEIGH) {
1387 atomic_dec(&(cm->nb->ucmcnt));
1388 free_control_msg(cm);
1389 goto out;
1392 cm->nb->ucmlength += cm->length;
1393 list_add(&(cm->lh), &(cm->nb->ucontrol_msgs_out));
1394 } else {
1395 if (msgs > MAX_URGENT_CMSGS_PER_NEIGH) {
1396 free_oldest_ucm(cm->nb);
1399 cm->nb->ucmlength += cm->length;
1400 list_add_tail(&(cm->lh), &(cm->nb->ucontrol_msgs_out));
1402 } else {
1403 cm->nb->cmlength += cm->length;
1404 list_add_tail(&(cm->lh), &(cm->nb->control_msgs_out));
1407 jiffies_tmp = jiffies;
1408 newinterval = (((__u64) cm->nb->cmsg_interval) * 255 +
1409 jiffies_to_usecs(jiffies_tmp -
1410 cm->nb->jiffies_last_cmsg)) / 256;
1411 cm->nb->jiffies_last_cmsg = jiffies_tmp;
1412 if (unlikely(newinterval > (1LL << 32) - 1))
1413 cm->nb->cmsg_interval = (__u32) ((1LL << 32) - 1);
1414 else
1415 cm->nb->cmsg_interval = newinterval;
1417 schedule_controlmsg_timer(cm->nb);
1419 out:
1420 mutex_unlock(&(cm->nb->cmsg_lock));
1423 void send_pong(struct neighbor *nb, __u32 cookie)
1425 struct control_msg_out *cm = _alloc_control_msg(nb, 0, 1);
1427 if (unlikely(cm == 0))
1428 return;
1430 cm->nb = nb;
1431 cm->type = MSGTYPE_PONG;
1432 cm->msg.pong.cookie = cookie;
1433 cm->msg.pong.type = MSGTYPE_PONG_TIMEENQUEUED;
1434 cm->msg.pong.delaycomp.time_enqueued = ktime_get();
1435 cm->length = 9;
1436 add_control_msg(cm, 0);
1439 #warning todo reuse/free acks
1440 int send_reset_conn(struct neighbor *nb, __u32 conn_id_reset,
1441 __u32 conn_id_unknown, int lowprio)
1443 unsigned long iflags;
1444 int killed;
1445 struct control_msg_out *cm;
1446 struct unknownconnid_matchparam ucm;
1448 spin_lock_irqsave(&(nb->state_lock), iflags);
1449 killed = (nb->state == NEIGHBOR_STATE_KILLED);
1450 spin_unlock_irqrestore(&(nb->state_lock), iflags);
1452 if (unlikely(killed))
1453 return 0;
1455 cm = alloc_control_msg(nb, lowprio ?
1456 ACM_PRIORITY_LOW : ACM_PRIORITY_HIGH);
1458 if (unlikely(cm == 0))
1459 return 1;
1461 cm->type = MSGTYPE_RESET_CONN;
1462 cm->msg.reset_connidunknown.conn_id_reset = conn_id_reset;
1463 cm->msg.reset_connidunknown.conn_id_unknown = conn_id_unknown;
1464 cm->length = 5;
1466 if (conn_id_unknown != 0) {
1467 ucm.nb = nb;
1468 ucm.conn_id = conn_id_unknown;
1470 spin_lock_irqsave(&unknown_connids_lock, iflags);
1471 BUG_ON(htable_get(&unknown_connids, ucm_to_key(&ucm), &ucm) !=
1473 htable_insert(&unknown_connids, (char *) cm, ucm_to_key(&ucm));
1474 spin_unlock_irqrestore(&unknown_connids_lock, iflags);
1477 add_control_msg(cm, 0);
1479 return 0;
1482 void send_ack(struct neighbor *nb, __u32 seqno)
1484 struct control_msg_out *cm = _alloc_control_msg(nb, 0, 1);
1486 if (unlikely(cm == 0))
1487 return;
1489 cm->nb = nb;
1490 cm->type = MSGTYPE_ACK;
1491 cm->msg.ack.seqno = seqno;
1492 cm->length = 5;
1493 add_control_msg(cm, 0);
1496 static void set_ooolen_flags(struct control_msg_out *cm)
1498 cm->msg.ack_conn.flags = (cm->msg.ack_conn.flags &
1499 (~KP_ACK_CONN_FLAGS_OOO));
1500 cm->msg.ack_conn.flags = (cm->msg.ack_conn.flags |
1501 ooolen_to_flags(cm->msg.ack_conn.length));
1504 static void remove_pending_ackconn(struct control_msg_out *cm)
1506 cm->nb->cmlength -= cm->length;
1507 list_del(&(cm->lh));
1509 list_del(&(cm->msg.ack_conn.conn_acks));
1510 kref_put(&(cm->msg.ack_conn.src_in->ref), free_conn);
1511 cm->msg.ack_conn.src_in = 0;
1513 cm->type = 0;
1514 free_control_msg(cm);
1517 /* cmsg_lock must be held */
1518 static void recalc_scheduled_ackconn_size(struct control_msg_out *cm)
1520 cm->nb->cmlength -= cm->length;
1521 cm->length = 6 + ack_conn_len(cm->msg.ack_conn.flags);
1522 cm->nb->cmlength += cm->length;
1525 /* cmsg_lock must be held */
1526 static int _try_merge_ackconn(struct conn *src_in_l,
1527 struct control_msg_out *fromcm, struct control_msg_out *tocm,
1528 int from_newack)
1530 if (ooolen(fromcm->msg.ack_conn.flags) != 0 &&
1531 ooolen(tocm->msg.ack_conn.flags) != 0) {
1532 __u32 tocmseqno = tocm->msg.ack_conn.seqno_ooo;
1533 __u32 tocmlength = tocm->msg.ack_conn.length;
1534 __u32 fromcmseqno = fromcm->msg.ack_conn.seqno_ooo;
1535 __u32 fromcmlength = fromcm->msg.ack_conn.length;
1537 if (tocmseqno == fromcmseqno) {
1538 if (fromcmlength > tocmlength)
1539 tocm->msg.ack_conn.length = fromcmlength;
1540 } else if (seqno_after(fromcmseqno, tocmseqno) &&
1541 seqno_before_eq(fromcmseqno, tocmseqno +
1542 tocmlength)) {
1543 tocm->msg.ack_conn.length = fromcmseqno + fromcmlength -
1544 tocmseqno;
1545 } else if (seqno_before(fromcmseqno, tocmseqno) &&
1546 seqno_after_eq(fromcmseqno, tocmseqno)) {
1547 tocm->msg.ack_conn.seqno_ooo = fromcmseqno;
1548 tocm->msg.ack_conn.length = tocmseqno + tocmlength -
1549 fromcmseqno;
1550 } else {
1551 return 1;
1553 set_ooolen_flags(tocm);
1556 if ((fromcm->msg.ack_conn.flags &
1557 KP_ACK_CONN_FLAGS_SEQNO) != 0) {
1558 if ((tocm->msg.ack_conn.flags &
1559 KP_ACK_CONN_FLAGS_SEQNO) == 0 ||
1560 seqno_after(fromcm->msg.ack_conn.seqno,
1561 tocm->msg.ack_conn.seqno))
1562 tocm->msg.ack_conn.seqno = fromcm->msg.ack_conn.seqno;
1564 if ((fromcm->msg.ack_conn.flags &
1565 KP_ACK_CONN_FLAGS_WINDOW) != 0)
1566 tocm->msg.ack_conn.flags = (tocm->msg.ack_conn.flags |
1567 KP_ACK_CONN_FLAGS_WINDOW);
1570 if (ooolen(fromcm->msg.ack_conn.flags) != 0) {
1571 tocm->msg.ack_conn.seqno_ooo = fromcm->msg.ack_conn.seqno_ooo;
1572 tocm->msg.ack_conn.length = fromcm->msg.ack_conn.length;
1573 set_ooolen_flags(tocm);
1576 if ((fromcm->msg.ack_conn.flags & KP_ACK_CONN_FLAGS_CREDITS) != 0) {
1577 BUG_ON((tocm->msg.ack_conn.flags &
1578 KP_ACK_CONN_FLAGS_CREDITS) != 0);
1579 tocm->msg.ack_conn.decaytime_seqno =
1580 fromcm->msg.ack_conn.decaytime_seqno;
1581 tocm->msg.ack_conn.decaytime =
1582 fromcm->msg.ack_conn.decaytime;
1585 recalc_scheduled_ackconn_size(tocm);
1586 if (from_newack == 0)
1587 remove_pending_ackconn(fromcm);
1589 return 0;
1592 /* cmsg_lock must be held */
1593 static void try_merge_ackconns(struct conn *src_in_l,
1594 struct control_msg_out *cm)
1596 struct list_head *currlh = cm->msg.ack_conn.conn_acks.next;
1598 while (currlh != &(src_in_l->source.in.acks_pending)) {
1599 struct control_msg_out *currcm = container_of(currlh,
1600 struct control_msg_out,
1601 msg.ack_conn.conn_acks);
1602 printk(KERN_ERR "try_merge_ackconns iterate");
1603 currlh = currlh->next;
1604 _try_merge_ackconn(src_in_l, currcm, cm, 0);
1608 static void mergeadd_ackconn(struct conn *src_in_l, struct control_msg_out *cm)
1610 struct list_head *currlh;
1612 BUG_ON(src_in_l->sourcetype != SOURCE_IN);
1614 mutex_lock(&(cm->nb->cmsg_lock));
1616 currlh = src_in_l->source.in.acks_pending.next;
1618 #warning todo search limit
1619 while (currlh != &(src_in_l->source.in.acks_pending)) {
1620 struct control_msg_out *currcm = container_of(currlh,
1621 struct control_msg_out,
1622 msg.ack_conn.conn_acks);
1624 BUG_ON(currcm->nb != cm->nb);
1625 BUG_ON(currcm->type != MSGTYPE_ACK_CONN);
1626 BUG_ON(cm->msg.ack_conn.src_in != src_in_l);
1627 BUG_ON(currcm->msg.ack_conn.conn_id !=
1628 cm->msg.ack_conn.conn_id);
1630 if (_try_merge_ackconn(src_in_l, cm, currcm, 1) == 0) {
1631 try_merge_ackconns(src_in_l, currcm);
1632 schedule_controlmsg_timer(currcm->nb);
1633 mutex_unlock(&(currcm->nb->cmsg_lock));
1634 return;
1637 currlh = currlh->next;
1640 list_add_tail(&(cm->msg.ack_conn.conn_acks),
1641 &(src_in_l->source.in.acks_pending));
1643 mutex_unlock(&(cm->nb->cmsg_lock));
1645 add_control_msg(cm, 0);
1648 static int try_update_ackconn_seqno(struct conn *src_in_l)
1650 int rc = 1;
1652 mutex_lock(&(src_in_l->source.in.nb->cmsg_lock));
1654 if (list_empty(&(src_in_l->source.in.acks_pending)) == 0) {
1655 struct control_msg_out *cm = container_of(
1656 src_in_l->source.in.acks_pending.next,
1657 struct control_msg_out,
1658 msg.ack_conn.conn_acks);
1659 BUG_ON(cm->nb != src_in_l->source.in.nb);
1660 BUG_ON(cm->type != MSGTYPE_ACK_CONN);
1661 BUG_ON(cm->msg.ack_conn.src_in != src_in_l);
1662 BUG_ON(cm->msg.ack_conn.conn_id !=
1663 src_in_l->reversedir->target.out.conn_id);
1665 cm->msg.ack_conn.flags = (cm->msg.ack_conn.flags |
1666 KP_ACK_CONN_FLAGS_SEQNO |
1667 KP_ACK_CONN_FLAGS_WINDOW);
1668 cm->msg.ack_conn.seqno = src_in_l->source.in.next_seqno;
1669 recalc_scheduled_ackconn_size(cm);
1671 try_merge_ackconns(src_in_l, cm);
1673 rc = 0;
1676 mutex_unlock(&(src_in_l->source.in.nb->cmsg_lock));
1678 return rc;
1681 void send_ack_conn_ifneeded(struct conn *src_in_l)
1683 struct control_msg_out *cm;
1685 BUG_ON(src_in_l->sourcetype != SOURCE_IN);
1687 if (src_in_l->source.in.inorder_ack_needed == 0 &&
1688 ((src_in_l->source.in.window_seqnolimit -
1689 src_in_l->source.in.next_seqno)/2) <
1690 (src_in_l->source.in.window_seqnolimit_remote -
1691 src_in_l->source.in.next_seqno))
1692 return;
1694 if (try_update_ackconn_seqno(src_in_l) == 0)
1695 goto out;
1697 cm = alloc_control_msg(src_in_l->source.in.nb, ACM_PRIORITY_LOW);
1698 if (cm == 0)
1699 return;
1701 cm->type = MSGTYPE_ACK_CONN;
1702 cm->msg.ack_conn.flags = KP_ACK_CONN_FLAGS_SEQNO |
1703 KP_ACK_CONN_FLAGS_WINDOW;
1704 kref_get(&(src_in_l->ref));
1705 cm->msg.ack_conn.src_in = src_in_l;
1706 cm->msg.ack_conn.conn_id = src_in_l->reversedir->target.out.conn_id;
1707 cm->msg.ack_conn.seqno = src_in_l->source.in.next_seqno;
1708 cm->length = 6 + ack_conn_len(cm->msg.ack_conn.flags);
1710 mergeadd_ackconn(src_in_l, cm);
1712 out:
1713 src_in_l->source.in.inorder_ack_needed = 0;
1714 src_in_l->source.in.window_seqnolimit_remote =
1715 src_in_l->source.in.window_seqnolimit;
1718 void send_ack_conn_ooo(struct control_msg_out *cm, struct conn *src_in_l,
1719 __u32 conn_id, __u32 seqno_ooo, __u32 length)
1721 cm->type = MSGTYPE_ACK_CONN;
1722 kref_get(&(src_in_l->ref));
1723 BUG_ON(src_in_l->sourcetype != SOURCE_IN);
1724 cm->msg.ack_conn.flags = 0;
1725 cm->msg.ack_conn.src_in = src_in_l;
1726 cm->msg.ack_conn.conn_id = conn_id;
1727 cm->msg.ack_conn.seqno_ooo = seqno_ooo;
1728 cm->msg.ack_conn.length = length;
1729 set_ooolen_flags(cm);
1730 cm->length = 6 + ack_conn_len(cm->msg.ack_conn.flags);
1732 mergeadd_ackconn(src_in_l, cm);
1735 static int try_add_decaytime(struct conn *trgt_out_l, __u16 decaytime)
1737 int rc = 1;
1738 struct conn *src_in = trgt_out_l->reversedir;
1740 mutex_lock(&(trgt_out_l->target.out.nb->cmsg_lock));
1742 if (list_empty(&(src_in->source.in.acks_pending)) == 0) {
1743 struct control_msg_out *cm = container_of(
1744 src_in->source.in.acks_pending.next,
1745 struct control_msg_out,
1746 msg.ack_conn.conn_acks);
1747 BUG_ON(cm->nb != trgt_out_l->target.out.nb);
1748 BUG_ON(cm->type != MSGTYPE_ACK_CONN);
1749 BUG_ON(cm->msg.ack_conn.src_in != trgt_out_l->reversedir);
1750 BUG_ON(cm->msg.ack_conn.conn_id !=
1751 trgt_out_l->target.out.conn_id);
1753 BUG_ON((cm->msg.ack_conn.flags & KP_ACK_CONN_FLAGS_CREDITS) !=
1755 cm->msg.ack_conn.flags = (cm->msg.ack_conn.flags |
1756 KP_ACK_CONN_FLAGS_CREDITS);
1757 cm->msg.ack_conn.decaytime_seqno =
1758 trgt_out_l->target.out.decaytime_seqno;
1759 cm->msg.ack_conn.decaytime = decaytime;
1760 recalc_scheduled_ackconn_size(cm);
1762 rc = 0;
1765 mutex_unlock(&(trgt_out_l->target.out.nb->cmsg_lock));
1767 return rc;
1770 void send_decaytime(struct conn *trgt_out_l, int force, __u16 decaytime)
1772 struct control_msg_out *cm;
1774 if (try_add_decaytime(trgt_out_l, decaytime) == 0)
1775 goto out;
1777 if (force == 0)
1778 return;
1780 cm = alloc_control_msg(trgt_out_l->target.out.nb, ACM_PRIORITY_LOW);
1782 if (cm == 0)
1783 return;
1785 cm->type = MSGTYPE_ACK_CONN;
1786 kref_get(&(trgt_out_l->ref));
1787 BUG_ON(trgt_out_l->targettype != TARGET_OUT);
1788 cm->msg.ack_conn.flags = KP_ACK_CONN_FLAGS_CREDITS;
1789 cm->msg.ack_conn.src_in = trgt_out_l->reversedir;
1790 cm->msg.ack_conn.conn_id = trgt_out_l->target.out.conn_id;
1791 cm->msg.ack_conn.decaytime_seqno =
1792 trgt_out_l->target.out.decaytime_seqno;
1793 cm->msg.ack_conn.decaytime = decaytime;
1795 cm->length = 6 + ack_conn_len(cm->msg.ack_conn.flags);
1796 mergeadd_ackconn(trgt_out_l, cm);
1798 out:
1799 trgt_out_l->target.out.decaytime_last = decaytime;
1800 trgt_out_l->target.out.decaytime_seqno =
1801 (trgt_out_l->target.out.decaytime_seqno + 1) % 64;
1802 trgt_out_l->target.out.decaytime_send_allowed = 0;
1805 void send_connect_success(struct control_msg_out *cm, __u32 rcvd_conn_id,
1806 __u32 gen_conn_id, __u32 init_seqno, struct conn *rconn)
1808 cm->type = MSGTYPE_CONNECT_SUCCESS;
1809 cm->msg.connect_success.rcvd_conn_id = rcvd_conn_id;
1810 cm->msg.connect_success.gen_conn_id = gen_conn_id;
1811 cm->msg.connect_success.init_seqno = init_seqno;
1812 kref_get(&(rconn->ref));
1813 cm->msg.connect_success.rconn = rconn;
1814 cm->length = 16;
1815 add_control_msg(cm, 0);
1818 void send_connect_nb(struct control_msg_out *cm, __u32 conn_id,
1819 __u32 init_seqno, struct conn *sconn)
1821 cm->type = MSGTYPE_CONNECT;
1822 cm->msg.connect.conn_id = conn_id;
1823 cm->msg.connect.init_seqno = init_seqno;
1824 kref_get(&(sconn->ref));
1825 BUG_ON(sconn->sourcetype != SOURCE_IN);
1826 cm->msg.connect.sconn = sconn;
1827 cm->length = 12;
1828 add_control_msg(cm, 0);
1831 #warning todo ref to buf instead
1832 void send_conndata(struct control_msg_out *cm, __u32 conn_id, __u32 seqno,
1833 char *data_orig, char *data, __u32 datalen)
1835 cm->type = MSGTYPE_CONNDATA;
1836 cm->msg.conn_data.conn_id = conn_id;
1837 cm->msg.conn_data.seqno = seqno;
1838 cm->msg.conn_data.data_orig = data_orig;
1839 cm->msg.conn_data.data = data;
1840 cm->msg.conn_data.datalen = datalen;
1841 cm->length = 11 + datalen;
1842 add_control_msg(cm, 0);
1845 void send_connid_unknown(struct neighbor *nb, __u32 conn_id)
1847 unsigned long iflags;
1848 char *ret;
1849 struct unknownconnid_matchparam ucm;
1851 struct control_msg_out *cm = alloc_control_msg(nb, ACM_PRIORITY_HIGH);
1853 if (unlikely(cm == 0))
1854 return;
1856 cm->type = MSGTYPE_CONNID_UNKNOWN;
1857 cm->msg.reset_connidunknown.conn_id_unknown = conn_id;
1858 cm->length = 5;
1860 ucm.nb = nb;
1861 ucm.conn_id = conn_id;
1863 spin_lock_irqsave(&unknown_connids_lock, iflags);
1864 ret = htable_get(&unknown_connids, ucm_to_key(&ucm), &ucm);
1865 if (ret == 0)
1866 htable_insert(&unknown_connids, (char *) cm, ucm_to_key(&ucm));
1867 spin_unlock_irqrestore(&unknown_connids_lock, iflags);
1869 if (ret != 0) {
1870 struct control_msg_out *cm2 = (struct control_msg_out *) ret;
1872 BUG_ON(cm2->type != MSGTYPE_RESET_CONN &&
1873 cm2->type != MSGTYPE_CONNID_UNKNOWN);
1875 kref_put(&(cm2->ref), cmsg_kref_free);
1877 free_control_msg(cm);
1878 } else {
1879 add_control_msg(cm, 0);
1884 static int matches_connretrans(void *htentry, void *searcheditem)
1886 struct control_retrans *cr = (struct control_retrans *) htentry;
1887 struct retransmit_matchparam *rm = (struct retransmit_matchparam *)
1888 searcheditem;
1890 return rm->nb == cr->nb && rm->seqno == cr->seqno;
1893 static int matches_unknownconnid(void *htentry, void *searcheditem)
1895 struct control_msg_out *cm = (struct control_msg_out *) htentry;
1897 struct unknownconnid_matchparam *ucm =
1898 (struct unknownconnid_matchparam *)searcheditem;
1900 BUG_ON(cm->type != MSGTYPE_RESET_CONN &&
1901 cm->type != MSGTYPE_CONNID_UNKNOWN);
1903 return ucm->nb == cm->nb && ucm->conn_id ==
1904 cm->msg.reset_connidunknown.conn_id_unknown;
1907 void __init cor_kgen_init(void)
1909 controlmsg_slab = kmem_cache_create("cor_controlmsg",
1910 sizeof(struct control_msg_out), 8, 0, 0);
1911 controlretrans_slab = kmem_cache_create("cor_controlretransmsg",
1912 sizeof(struct control_retrans), 8, 0, 0);
1913 htable_init(&retransmits, matches_connretrans,
1914 offsetof(struct control_retrans, htab_entry),
1915 offsetof(struct control_retrans, ref));
1916 htable_init(&unknown_connids, matches_unknownconnid,
1917 offsetof(struct control_msg_out,
1918 msg.reset_connidunknown.htab_entry),
1919 offsetof(struct control_msg_out, ref));
1922 MODULE_LICENSE("GPL");