new ack code
[cor_2_6_31.git] / net / cor / kpacket_gen.c
blobf32fbe12ff7b6baa739d49a72879cbb9241e6238
1 /*
2 * Connection oriented routing
3 * Copyright (C) 2007-2010 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_PING_CONN 8
34 #define MSGTYPE_CONNID_UNKNOWN 9
35 #define MSGTYPE_PING_ALL_CONNS 10
36 #define MSGTYPE_SET_MAX_CMSG_DELAY 11
38 struct control_msg_out{
39 struct list_head lh; /* either neighbor or control_retrans_packet */
40 struct neighbor *nb;
42 __u32 length;
44 __u8 type;
45 union{
46 struct{
47 __u32 cookie;
48 unsigned long time_enqueued; /* jiffies */
49 int sent;
50 }pong;
52 struct{
53 __u32 seqno;
54 }ack;
56 struct{
57 struct conn *rconn;
58 __u32 conn_id;
59 __u32 seqno;
60 __u32 seqno_ooo;
61 __u32 length;
63 __u8 flags;
64 }ack_conn;
66 struct{
67 __u32 conn_id;
68 __u32 init_seqno;
69 struct conn *sconn;
70 }connect;
72 struct{
73 __u32 rcvd_conn_id;
74 __u32 gen_conn_id;
75 __u32 init_seqno;
76 struct conn *rconn;
77 }connect_success;
79 struct{
80 __u32 conn_id;
81 }reset;
83 struct{
84 __u32 conn_id;
85 __u32 seqno;
86 char *data_orig;
87 char *data;
88 __u32 datalen;
89 }conn_data;
91 struct{
92 __u32 conn_id;
93 }ping_conn;
95 struct{
96 __u32 conn_id;
97 }connid_unknown;
99 struct{
100 __u32 delay;
101 }set_max_cmsg_delay;
102 }msg;
105 struct control_retrans {
106 struct kref ref;
108 struct neighbor *nb;
109 __u32 seqno;
111 unsigned long timeout;
113 struct list_head msgs;
115 struct htab_entry htab_entry;
116 struct list_head timeout_list;
119 struct kmem_cache *controlmsg_slab;
120 struct kmem_cache *controlretrans_slab;
122 static struct htable retransmits;
124 atomic_t cmcnt = ATOMIC_INIT(0);
126 static void add_control_msg(struct control_msg_out *msg, int retrans);
128 static inline int isurgent(struct control_msg_out *cm)
130 if (unlikely(cm->type == MSGTYPE_PONG || cm->type == MSGTYPE_ACK))
131 return 1;
132 return 0;
135 static struct control_msg_out *__alloc_control_msg(void)
137 struct control_msg_out *cm = kmem_cache_alloc(controlmsg_slab,
138 GFP_KERNEL);
139 if (unlikely(cm == 0))
140 return 0;
141 cm->lh.next = LIST_POISON1;
142 cm->lh.prev = LIST_POISON2;
143 return cm;
146 static int calc_limit(int limit, int priority)
148 if (priority == ACM_PRIORITY_LOW)
149 return (limit+1)/2;
150 else if (priority == ACM_PRIORITY_MED)
151 return (limit*3 + 3)/4;
152 else if (priority == ACM_PRIORITY_HIGH)
153 return limit;
154 else
155 BUG();
158 int may_alloc_control_msg(struct neighbor *nb, int priority)
160 long packets1 = atomic_read(&(nb->cmcnt));
161 long packets2 = atomic_read(&(cmcnt));
163 BUG_ON(packets1 < 0);
164 BUG_ON(packets2 < 0);
166 if (packets1 < calc_limit(GUARANTEED_CMSGS_PER_NEIGH, priority))
167 return 1;
169 if (unlikely(unlikely(packets2 >= calc_limit(MAX_CMSGS_PER_NEIGH,
170 priority)) || unlikely(packets1 >= (
171 calc_limit(MAX_CMSGS_PER_NEIGH, priority) *
172 (MAX_CMSGS - packets2) / MAX_CMSGS))))
173 return 0;
174 return 1;
177 static struct control_msg_out *_alloc_control_msg(struct neighbor *nb,
178 int priority, int urgent)
180 struct control_msg_out *cm = 0;
182 BUG_ON(nb == 0);
184 if (urgent == 0) {
185 long packets1 = atomic_inc_return(&(nb->cmcnt));
186 long packets2 = atomic_inc_return(&(cmcnt));
188 BUG_ON(packets1 <= 0);
189 BUG_ON(packets2 <= 0);
191 if (packets1 <= calc_limit(GUARANTEED_CMSGS_PER_NEIGH,
192 priority))
193 goto alloc;
195 if (unlikely(unlikely(packets2 > calc_limit(MAX_CMSGS_PER_NEIGH,
196 priority)) || unlikely(packets1 > (
197 calc_limit(MAX_CMSGS_PER_NEIGH, priority) *
198 (MAX_CMSGS - packets2) / MAX_CMSGS))))
199 goto full;
202 alloc:
203 cm = __alloc_control_msg();
204 if (unlikely(cm == 0))
205 goto full;
206 cm->nb = nb;
208 if (0) {
209 full:
210 if (urgent == 0) {
211 atomic_dec(&(nb->cmcnt));
212 atomic_dec(&(cmcnt));
215 return cm;
218 struct control_msg_out *alloc_control_msg(struct neighbor *nb, int priority)
220 return _alloc_control_msg(nb, priority, 0);
223 void free_control_msg(struct control_msg_out *cm)
225 if (isurgent(cm) == 0) {
226 atomic_dec(&(cm->nb->cmcnt));
227 atomic_dec(&(cmcnt));
230 if (cm->type == MSGTYPE_ACK_CONN) {
231 BUG_ON(cm->msg.ack_conn.rconn == 0);
232 kref_put(&(cm->msg.ack_conn.rconn->ref), free_conn);
233 cm->msg.ack_conn.rconn = 0;
234 } else if (cm->type == MSGTYPE_CONNECT) {
235 BUG_ON(cm->msg.connect.sconn == 0);
236 kref_put(&(cm->msg.connect.sconn->ref), free_conn);
237 cm->msg.connect.sconn = 0;
238 } else if (cm->type == MSGTYPE_CONNECT_SUCCESS) {
239 BUG_ON(cm->msg.connect_success.rconn == 0);
240 kref_put(&(cm->msg.connect_success.rconn->ref), free_conn);
241 cm->msg.connect_success.rconn = 0;
244 kmem_cache_free(controlmsg_slab, cm);
247 static void free_control_retrans(struct kref *ref)
249 struct control_retrans *cr = container_of(ref, struct control_retrans,
250 ref);
252 while (list_empty(&(cr->msgs)) == 0) {
253 struct control_msg_out *cm = container_of(cr->msgs.next,
254 struct control_msg_out, lh);
255 list_del(&(cm->lh));
256 free_control_msg(cm);
259 kmem_cache_free(controlretrans_slab, cr);
262 struct retransmit_matchparam {
263 struct neighbor *nb;
264 __u32 seqno;
267 static __u32 rm_to_key(struct retransmit_matchparam *rm)
269 return ((__u32)((long) rm->nb)) ^ rm->seqno;
272 static void set_retrans_timeout(struct control_retrans *cr, struct neighbor *nb)
274 cr->timeout = jiffies + usecs_to_jiffies(100000 +
275 ((__u32) atomic_read(&(nb->latency))) * 2 +
276 ((__u32) atomic_read(&(nb->max_remote_cmsg_delay))));
279 void retransmit_timerfunc(struct work_struct *work)
281 unsigned long iflags;
283 struct neighbor *nb = container_of(to_delayed_work(work),
284 struct neighbor, retrans_timer);
286 int nbstate;
287 int nbput = 0;
289 spin_lock_irqsave( &(nb->state_lock), iflags );
290 nbstate = nb->state;
291 spin_unlock_irqrestore( &(nb->state_lock), iflags );
293 while (1) {
294 struct control_retrans *cr = 0;
295 struct retransmit_matchparam rm;
297 spin_lock_irqsave( &(nb->retrans_lock), iflags );
299 if (list_empty(&(nb->retrans_list))) {
300 nb->retrans_timer_running = 0;
301 nbput = 1;
302 break;
305 cr = container_of(nb->retrans_list.next,
306 struct control_retrans, timeout_list);
308 BUG_ON(cr->nb != nb);
310 rm.seqno = cr->seqno;
311 rm.nb = nb;
313 list_del(&(cr->timeout_list));
315 if (unlikely(nbstate == NEIGHBOR_STATE_KILLED)) {
316 spin_unlock_irqrestore( &(nb->retrans_lock), iflags );
318 htable_delete(&retransmits, rm_to_key(&rm), &rm,
319 free_control_retrans);
320 kref_put(&(cr->ref), free_control_retrans);
321 continue;
324 if (time_after(cr->timeout, jiffies)) {
325 list_add(&(cr->timeout_list), &(nb->retrans_list));
326 schedule_delayed_work(&(nb->retrans_timer),
327 cr->timeout - jiffies);
328 break;
331 if (unlikely(htable_delete(&retransmits, rm_to_key(&rm), &rm,
332 free_control_retrans)))
333 BUG();
335 spin_unlock_irqrestore( &(nb->retrans_lock), iflags );
337 while (list_empty(&(cr->msgs)) == 0) {
338 struct control_msg_out *cm = container_of(cr->msgs.next,
339 struct control_msg_out, lh);
340 list_del(&(cm->lh));
341 add_control_msg(cm, 1);
344 kref_put(&(cr->ref), free_control_retrans);
347 spin_unlock_irqrestore( &(nb->retrans_lock), iflags );
349 if (nbput)
350 kref_put(&(nb->ref), neighbor_free);
353 static void schedule_retransmit(struct control_retrans *cr, struct neighbor *nb)
355 unsigned long iflags;
357 struct retransmit_matchparam rm;
358 int first;
360 rm.seqno = cr->seqno;
361 rm.nb = nb;
363 set_retrans_timeout(cr, nb);
365 spin_lock_irqsave( &(nb->retrans_lock), iflags );
366 htable_insert(&retransmits, (char *) cr, rm_to_key(&rm));
367 first = list_empty(&(nb->retrans_list));
368 list_add_tail(&(cr->timeout_list), &(nb->retrans_list));
370 if (first && nb->retrans_timer_running == 0) {
371 schedule_delayed_work(&(nb->retrans_timer),
372 cr->timeout - jiffies);
373 nb->retrans_timer_running = 1;
374 kref_get(&(nb->ref));
377 spin_unlock_irqrestore( &(nb->retrans_lock), iflags );
380 void kern_ack_rcvd(struct neighbor *nb, __u32 seqno)
382 unsigned long iflags;
384 struct control_retrans *cr = 0;
385 struct retransmit_matchparam rm;
387 rm.seqno = seqno;
388 rm.nb = nb;
390 spin_lock_irqsave( &(nb->retrans_lock), iflags );
392 cr = (struct control_retrans *) htable_get(&retransmits, rm_to_key(&rm),
393 &rm);
395 if (cr == 0) {
396 printk(KERN_ERR "bogus/duplicate ack received");
397 goto out;
400 if (unlikely(htable_delete(&retransmits, rm_to_key(&rm), &rm,
401 free_control_retrans)))
402 BUG();
404 BUG_ON(cr->nb != nb);
406 list_del(&(cr->timeout_list));
408 out:
409 spin_unlock_irqrestore( &(nb->retrans_lock), iflags );
411 if (cr != 0) {
412 kref_put(&(cr->ref), free_control_retrans); /* htable_get */
413 kref_put(&(cr->ref), free_control_retrans); /* list */
417 static void padding(struct sk_buff *skb, int length)
419 char *dst;
420 if (length <= 0)
421 return;
422 dst = skb_put(skb, length);
423 BUG_ON(dst == 0);
424 memset(dst, KP_PADDING, length);
427 static int add_ack(struct sk_buff *skb, struct control_retrans *cr,
428 struct control_msg_out *cm, int spaceleft)
430 char *dst;
432 if (unlikely(spaceleft < 5))
433 return 0;
435 dst = skb_put(skb, 5);
436 BUG_ON(dst == 0);
438 dst[0] = KP_ACK;
439 put_u32(dst + 1, cm->msg.ack.seqno, 1);
441 atomic_dec(&(cm->nb->ucmcnt));
442 free_control_msg(cm);
444 return 5;
447 static int add_ack_conn(struct sk_buff *skb, struct control_retrans *cr,
448 struct control_msg_out *cm, int spaceleft)
450 char *dst;
451 int offset = 0;
453 if (unlikely(spaceleft < cm->length))
454 return 0;
456 dst = skb_put(skb, cm->length);
457 BUG_ON(dst == 0);
459 dst[offset] = KP_ACK_CONN;
460 offset++;
461 put_u32(dst + offset, cm->msg.ack_conn.conn_id, 1);
462 offset += 4;
463 dst[offset] = cm->msg.ack_conn.flags;
464 offset++;
466 if ((cm->msg.ack_conn.flags & KP_ACK_CONN_FLAGS_SEQNO) != 0) {
467 put_u32(dst + offset, cm->msg.ack_conn.seqno, 1);
468 offset += 4;
470 if ((cm->msg.ack_conn.flags & KP_ACK_CONN_FLAGS_WINDOW) != 0) {
471 BUG_ON(cm->msg.ack_conn.rconn == 0);
472 dst[offset] = get_window(cm->msg.ack_conn.rconn);
473 offset++;
477 if (ooolen(cm->msg.ack_conn.flags) != 0) {
478 put_u32(dst + offset, cm->msg.ack_conn.seqno_ooo, 1);
479 offset += 4;
480 if (ooolen(cm->msg.ack_conn.flags) == 1) {
481 BUG_ON(cm->msg.ack_conn.length > 255);
482 dst[offset] = cm->msg.ack_conn.length;
483 offset += 1;
484 } else if (ooolen(cm->msg.ack_conn.flags) == 2) {
485 BUG_ON(cm->msg.ack_conn.length <= 255);
486 BUG_ON(cm->msg.ack_conn.length > 65535);
487 put_u16(dst + offset, cm->msg.ack_conn.length, 1);
488 offset += 2;
489 } else if (ooolen(cm->msg.ack_conn.flags) == 4) {
490 BUG_ON(cm->msg.ack_conn.length <= 65535);
491 put_u32(dst + offset, cm->msg.ack_conn.length, 1);
492 offset += 4;
493 } else {
494 BUG();
499 list_add_tail(&(cm->lh), &(cr->msgs));
501 BUG_ON(offset != cm->length);
502 return offset;
505 static int add_ping(struct sk_buff *skb, __u32 cookie,
506 int spaceleft)
508 char *dst;
510 if (unlikely(spaceleft < 5))
511 return 0;
513 dst = skb_put(skb, 5);
514 BUG_ON(dst == 0);
516 dst[0] = KP_PING;
517 put_u32(dst + 1, cookie, 0);
519 return 5;
522 static int add_pong(struct sk_buff *skb, struct control_retrans *cr,
523 struct control_msg_out *cm, int spaceleft)
525 char *dst;
527 if (unlikely(spaceleft < 9))
528 return 0;
530 dst = skb_put(skb, 9);
531 BUG_ON(dst == 0);
533 dst[0] = KP_PONG;
534 put_u32(dst + 1, cm->msg.pong.cookie, 0);
535 put_u32(dst + 5, 1000 * jiffies_to_msecs(jiffies -
536 cm->msg.pong.time_enqueued), 1);
539 atomic_dec(&(cm->nb->ucmcnt));
540 list_add_tail(&(cm->lh), &(cr->msgs));
542 return 9;
545 static int add_connect(struct sk_buff *skb, struct control_retrans *cr,
546 struct control_msg_out *cm, int spaceleft)
548 char *dst;
550 if (unlikely(spaceleft < 10))
551 return 0;
553 dst = skb_put(skb, 10);
554 BUG_ON(dst == 0);
556 dst[0] = KP_CONNECT;
557 put_u32(dst + 1, cm->msg.connect.conn_id, 1);
558 put_u32(dst + 5, cm->msg.connect.init_seqno, 1);
559 BUG_ON(cm->msg.connect.sconn == 0);
560 dst[9] = get_window(cm->msg.connect.sconn);
562 list_add_tail(&(cm->lh), &(cr->msgs));
564 return 10;
567 static int add_connect_success(struct sk_buff *skb, struct control_retrans *cr,
568 struct control_msg_out *cm, int spaceleft)
570 char *dst;
572 if (unlikely(spaceleft < 14))
573 return 0;
575 dst = skb_put(skb, 14);
576 BUG_ON(dst == 0);
578 dst[0] = KP_CONNECT_SUCCESS;
579 put_u32(dst + 1, cm->msg.connect_success.rcvd_conn_id, 1);
580 put_u32(dst + 5, cm->msg.connect_success.gen_conn_id, 1);
581 put_u32(dst + 9, cm->msg.connect_success.init_seqno, 1);
582 BUG_ON(cm->msg.connect_success.rconn == 0);
583 dst[13] = get_window(cm->msg.connect_success.rconn);
585 list_add_tail(&(cm->lh), &(cr->msgs));
587 return 14;
590 static int add_reset_conn(struct sk_buff *skb, struct control_retrans *cr,
591 struct control_msg_out *cm, int spaceleft)
593 char *dst;
595 if (unlikely(spaceleft < 5))
596 return 0;
598 dst = skb_put(skb, 5);
599 BUG_ON(dst == 0);
601 dst[0] = KP_RESET_CONN;
602 put_u32(dst + 1, cm->msg.reset.conn_id, 1);
604 list_add_tail(&(cm->lh), &(cr->msgs));
606 return 5;
609 static int add_conndata(struct sk_buff *skb, struct control_retrans *cr,
610 struct control_msg_out *cm, int spaceleft,
611 struct control_msg_out **split_conndata, __u32 *sc_sendlen)
613 char *dst;
615 int totallen = cm->msg.conn_data.datalen + 11;
616 int putlen = min(totallen, spaceleft);
617 int dataputlen = putlen - 11;
619 BUG_ON(split_conndata == 0);
620 BUG_ON(sc_sendlen == 0);
622 if (dataputlen < 1 || (spaceleft < 25 && spaceleft < totallen))
623 return 0;
625 dst = skb_put(skb, putlen);
626 BUG_ON(dst == 0);
628 dst[0] = KP_CONN_DATA;
629 put_u32(dst + 1, cm->msg.conn_data.conn_id, 1);
630 put_u32(dst + 5, cm->msg.conn_data.seqno, 1);
631 put_u16(dst + 9, dataputlen, 1);
633 memcpy(dst + 11, cm->msg.conn_data.data, dataputlen);
635 if (cm->msg.conn_data.datalen == dataputlen) {
636 list_add_tail(&(cm->lh), &(cr->msgs));
637 } else {
638 *split_conndata = cm;
639 *sc_sendlen = dataputlen;
642 return putlen;
645 static int add_ping_conn(struct sk_buff *skb, struct control_retrans *cr,
646 struct control_msg_out *cm, int spaceleft)
648 char *dst;
650 if (unlikely(spaceleft < 5))
651 return 0;
653 dst = skb_put(skb, 5);
654 BUG_ON(dst == 0);
656 dst[0] = KP_PING_CONN;
657 put_u32(dst + 1, cm->msg.ping_conn.conn_id, 1);
659 list_add_tail(&(cm->lh), &(cr->msgs));
661 return 5;
664 static int add_connid_unknown(struct sk_buff *skb, struct control_retrans *cr,
665 struct control_msg_out *cm, int spaceleft)
667 char *dst;
669 if (unlikely(spaceleft < 5))
670 return 0;
672 dst = skb_put(skb, 5);
673 BUG_ON(dst == 0);
675 dst[0] = KP_CONNID_UNKNOWN;
676 put_u32(dst + 1, cm->msg.connid_unknown.conn_id, 1);
678 list_add_tail(&(cm->lh), &(cr->msgs));
680 return 5;
683 static int add_ping_all_conns(struct sk_buff *skb, struct control_retrans *cr,
684 struct control_msg_out *cm, int spaceleft)
686 char *dst;
688 if (unlikely(spaceleft < 1))
689 return 0;
691 dst = skb_put(skb, 1);
692 BUG_ON(dst == 0);
694 dst[0] = KP_PING_ALL_CONNS;
696 list_add_tail(&(cm->lh), &(cr->msgs));
698 return 1;
701 static int add_set_max_cmsg_dly(struct sk_buff *skb, struct control_retrans *cr,
702 struct control_msg_out *cm, int spaceleft)
704 char *dst;
706 if (unlikely(spaceleft < 5))
707 return 0;
709 dst = skb_put(skb, 5);
710 BUG_ON(dst == 0);
712 dst[0] = KP_SET_MAX_CMSG_DELAY;
713 put_u32(dst + 1, cm->msg.set_max_cmsg_delay.delay, 1);
715 list_add_tail(&(cm->lh), &(cr->msgs));
717 return 5;
720 static int add_message(struct sk_buff *skb, struct control_retrans *cr,
721 struct control_msg_out *cm, int spaceleft,
722 struct control_msg_out **split_conndata, __u32 *sc_sendlen)
724 BUG_ON(split_conndata != 0 && *split_conndata != 0);
725 BUG_ON(sc_sendlen != 0 && *sc_sendlen != 0);
727 switch (cm->type) {
728 case MSGTYPE_ACK:
729 return add_ack(skb, cr, cm, spaceleft);
730 case MSGTYPE_ACK_CONN:
731 return add_ack_conn(skb, cr, cm, spaceleft);
732 case MSGTYPE_PONG:
733 return add_pong(skb, cr, cm, spaceleft);
734 case MSGTYPE_CONNECT:
735 return add_connect(skb, cr, cm, spaceleft);
736 case MSGTYPE_CONNECT_SUCCESS:
737 return add_connect_success(skb, cr, cm, spaceleft);
738 case MSGTYPE_RESET_CONN:
739 return add_reset_conn(skb, cr, cm, spaceleft);
740 case MSGTYPE_CONNDATA:
741 return add_conndata(skb, cr, cm, spaceleft, split_conndata,
742 sc_sendlen);
743 case MSGTYPE_PING_CONN:
744 return add_ping_conn(skb, cr, cm, spaceleft);
745 case MSGTYPE_CONNID_UNKNOWN:
746 return add_connid_unknown(skb, cr, cm, spaceleft);
747 case MSGTYPE_PING_ALL_CONNS:
748 return add_ping_all_conns(skb, cr, cm, spaceleft);
749 case MSGTYPE_SET_MAX_CMSG_DELAY:
750 return add_set_max_cmsg_dly(skb, cr, cm, spaceleft);
751 default:
752 BUG();
754 BUG();
755 return 0;
758 static __u32 recount_ping_conns(struct neighbor *nb)
760 __u32 cnt;
761 struct list_head *curr = nb->next_ping_conn->target.out.nb_list.next;
762 while (curr != &(nb->snd_conn_list)) {
763 cnt++;
764 BUG_ON(cnt > 1000000000);
766 return cnt;
769 static __u32 __send_messages_pc(struct neighbor *nb, struct sk_buff *skb,
770 struct control_retrans *cr, int spaceleft)
772 __u32 length = 0;
773 mutex_lock(&(nb->conn_list_lock));
774 while (nb->next_ping_conn != 0) {
775 struct conn *rconn;
776 struct conn *sconn;
777 struct list_head *next;
778 struct control_msg_out *cm;
779 int rc;
781 rconn = nb->next_ping_conn;
782 sconn = rconn->reversedir;
784 BUG_ON(rconn->targettype != TARGET_OUT);
785 BUG_ON(sconn->sourcetype != SOURCE_IN);
787 if (unlikely(rconn->target.out.conn_id))
788 goto next;
790 if (nb->ping_conns_remaining == 0) {
791 atomic_set(&(sconn->source.in.pong_awaiting), 1);
792 nb->pong_conns_expected++;
793 nb->ping_conns_remaining--;
794 if (unlikely(nb->ping_conns_remaining == 0))
795 nb->ping_conns_remaining =
796 recount_ping_conns(nb);
797 } else {
798 if (likely(atomic_read(&(
799 sconn->source.in.pong_awaiting)) == 0))
800 goto next;
801 nb->ping_conns_remaining--;
802 if (unlikely(nb->ping_conns_retrans_remaining == 0))
803 nb->ping_conns_retrans_remaining =
804 recount_ping_conns(nb);
807 cm = alloc_control_msg(nb, ACM_PRIORITY_LOW);
808 cm->length = 5;
809 cm->type = MSGTYPE_PING_CONN;
810 cm->msg.ping_conn.conn_id = rconn->target.out.conn_id;
811 rc = add_message(skb, cr, cm, spaceleft - length, 0, 0);
812 if (rc == 0)
813 break;
815 length = rc;
816 next:
817 next = rconn->target.out.nb_list.next;
818 nb->next_ping_conn = container_of(next, struct conn,
819 target.out.nb_list);
820 if (next == &(nb->snd_conn_list)) {
821 nb->next_ping_conn = 0;
822 nb->ping_conns_remaining = 0;
825 if (unlikely(length != 0)) {
826 nb->ping_conn_completed = jiffies;
828 mutex_unlock(&(nb->conn_list_lock));
829 return length;
832 static __u32 __send_messages(struct neighbor *nb, struct sk_buff *skb,
833 struct control_retrans *cr, int spaceleft, int urgentonly,
834 struct control_msg_out **split_conndata, __u32 *sc_sendlen)
836 __u32 length = 0;
837 while (!list_empty(&(nb->ucontrol_msgs_out)) || (!urgentonly &&
838 !list_empty(&(nb->control_msgs_out)))) {
839 int rc;
841 int urgent = !list_empty(&(nb->ucontrol_msgs_out));
843 struct control_msg_out *cm;
845 if (urgent)
846 cm = container_of(nb->ucontrol_msgs_out.next,
847 struct control_msg_out, lh);
848 else
849 cm = container_of(nb->control_msgs_out.next,
850 struct control_msg_out, lh);
852 list_del(&(cm->lh));
853 if (urgent)
854 nb->ucmlength -= cm->length;
855 else
856 nb->cmlength -= cm->length;
857 mutex_unlock(&(nb->cmsg_lock));
858 rc = add_message(skb, cr, cm, spaceleft - length,
859 split_conndata, sc_sendlen);
860 mutex_lock(&(nb->cmsg_lock));
862 if (rc == 0) {
863 if (urgent) {
864 list_add(&(cm->lh), &(nb->ucontrol_msgs_out));
865 nb->ucmlength += cm->length;
866 } else {
867 list_add(&(cm->lh), &(nb->control_msgs_out));
868 nb->cmlength += cm->length;
870 break;
873 length += rc;
876 return length;
879 static int msgtype_present(struct neighbor *nb, __u8 type)
881 struct list_head *curr;
883 curr = nb->control_msgs_out.next;
884 while (curr != &(nb->control_msgs_out)) {
885 struct control_msg_out *cm = container_of(curr,
886 struct control_msg_out, lh);
888 if (cm->type == MSGTYPE_PING_ALL_CONNS)
889 return 1;
891 curr = curr->next;
894 return 0;
897 static int ping_all_conns_needed(struct neighbor *nb)
899 if (likely(nb->ping_all_conns == 0))
900 return 0;
902 if (msgtype_present(nb, MSGTYPE_PING_ALL_CONNS))
903 return 0;
905 return 1;
908 static int __send_messages_smcd(struct neighbor *nb, struct sk_buff *skb,
909 struct control_retrans *cr, int spaceleft)
911 struct control_msg_out *cm;
912 int rc;
914 cm = alloc_control_msg(nb, ACM_PRIORITY_MED);
916 if (unlikely(cm == 0))
917 return 0;
919 cm->type = MSGTYPE_SET_MAX_CMSG_DELAY;
920 cm->msg.set_max_cmsg_delay.delay = CMSG_INTERVAL_MS * 10;
921 cm->length = 5;
923 rc = add_message(skb, cr, cm, spaceleft, 0, 0);
925 nb->max_cmsg_delay_sent = 1;
927 return rc;
930 static int __send_messages_pac(struct neighbor *nb, struct sk_buff *skb,
931 struct control_retrans *cr, int spaceleft)
933 struct control_msg_out *cm;
934 int rc;
936 cm = alloc_control_msg(nb, ACM_PRIORITY_MED);
938 if (unlikely(cm == 0))
939 return 0;
941 cm->type = MSGTYPE_PING_ALL_CONNS;
942 cm->length = 1;
944 rc = add_message(skb, cr, cm, spaceleft, 0, 0);
946 nb->ping_all_conns = 0;
947 return rc;
951 static int _send_messages(struct neighbor *nb, struct sk_buff *skb, int ping,
952 struct control_retrans *cr, int spaceleft, int urgentonly)
954 int rc;
955 int length = 0;
956 __u32 pingcookie = 0;
957 struct control_msg_out *split_conndata = 0;
958 __u32 sc_sendlen = 0;
960 mutex_lock(&(nb->cmsg_lock));
962 if (ping != 0) {
963 int rc;
964 pingcookie = add_ping_req(nb);
965 rc = add_ping(skb, pingcookie, spaceleft - length);
966 BUG_ON(rc == 0);
967 length += rc;
970 if (likely(urgentonly == 0) && unlikely(ping_all_conns_needed(nb) != 0))
971 length += __send_messages_pac(nb, skb, cr, spaceleft - length);
973 if (likely(urgentonly == 0) && unlikely(nb->max_cmsg_delay_sent == 0))
974 length += __send_messages_smcd(nb, skb, cr, spaceleft - length);
977 length += __send_messages(nb, skb, cr, spaceleft - length, urgentonly,
978 &split_conndata, &sc_sendlen);
980 if (likely(urgentonly == 0))
981 length += __send_messages_pc(nb, skb, cr, spaceleft - length);
983 mutex_unlock(&(nb->cmsg_lock));
985 if (unlikely(length > spaceleft))
986 printk(KERN_ERR "error cor/kpacket_gen: length > spaceleft!?");
988 padding(skb, spaceleft - length);
990 rc = dev_queue_xmit(skb);
992 if (rc != 0) {
993 unadd_ping_req(nb, pingcookie);
995 while (list_empty(&(cr->msgs)) == 0) {
996 struct control_msg_out *cm = container_of(cr->msgs.prev,
997 struct control_msg_out, lh);
998 list_del(&(cm->lh));
999 add_control_msg(cm, 1);
1002 if (split_conndata != 0) {
1003 add_control_msg(split_conndata, 1);
1006 kref_put(&(cr->ref), free_control_retrans);
1007 } else {
1008 struct list_head *curr = cr->msgs.next;
1010 while(curr != &(cr->msgs)) {
1011 struct control_msg_out *cm = container_of(curr,
1012 struct control_msg_out, lh);
1014 curr = curr->next;
1016 if (cm->type == MSGTYPE_CONNDATA) {
1017 list_del(&(cm->lh));
1018 kfree(cm->msg.conn_data.data_orig);
1019 free_control_msg(cm);
1023 if (split_conndata != 0) {
1024 BUG_ON(sc_sendlen == 0);
1025 BUG_ON(sc_sendlen >=
1026 split_conndata->msg.conn_data.datalen);
1028 split_conndata->msg.conn_data.data += sc_sendlen;
1029 split_conndata->msg.conn_data.datalen -= sc_sendlen;
1031 send_conndata(split_conndata,
1032 split_conndata->msg.conn_data.conn_id,
1033 split_conndata->msg.conn_data.seqno,
1034 split_conndata->msg.conn_data.data_orig,
1035 split_conndata->msg.conn_data.data,
1036 split_conndata->msg.conn_data.datalen);
1040 if (list_empty(&(cr->msgs)))
1041 kref_put(&(cr->ref), free_control_retrans);
1042 else
1043 schedule_retransmit(cr, nb);
1046 return rc;
1049 static __u32 get_total_messages_length(struct neighbor *nb, int ping,
1050 int urgentonly)
1052 __u32 length = nb->ucmlength;
1054 if (likely(urgentonly == 0)) {
1055 length += nb->cmlength + nb->ping_conns_remaining * 5;
1056 if (likely(nb->ping_conns_remaining == 0)) {
1057 if (likely(nb->ping_conns_retrans_remaining == 0) &&
1058 unlikely(nb->pong_conns_expected !=0) &&
1059 time_before(nb->ping_conn_completed,
1060 jiffies + msecs_to_jiffies(
1061 PING_ALL_CONNS_TIMEOUT) +
1062 usecs_to_jiffies(((__u32) atomic_read(&(
1063 nb->latency))) * 2 + ((__u32)
1064 atomic_read(&(nb->max_remote_cmsg_delay)
1065 )))))
1066 nb->ping_conns_retrans_remaining =
1067 nb->pong_conns_expected;
1069 if (unlikely(nb->ping_conns_retrans_remaining >
1070 nb->pong_conns_expected))
1071 nb->ping_conns_retrans_remaining =
1072 nb->pong_conns_expected;
1074 length += nb->ping_conns_retrans_remaining * 5;
1076 if (unlikely(ping_all_conns_needed(nb) != 0))
1077 length += 1;
1078 if (unlikely(nb->max_cmsg_delay_sent == 0))
1079 length += 5;
1081 if (ping == 2 || (length > 0 && ping != 0))
1082 length += 5;
1084 return length;
1087 int send_messages(struct neighbor *nb, int allmsgs, int resume)
1089 int rc = 0;
1090 int ping;
1091 int targetmss = mss(nb);
1093 int nbstate = get_neigh_state(nb);
1094 int urgentonly = (nbstate != NEIGHBOR_STATE_ACTIVE);
1096 mutex_lock(&(nb->cmsg_lock));
1098 if (resume)
1099 allmsgs = nb->kp_allmsgs;
1101 ping = time_to_send_ping(nb);
1103 while (1) {
1104 __u32 length;
1106 __u32 seqno;
1107 struct sk_buff *skb;
1108 struct control_retrans *cr;
1110 BUG_ON(list_empty(&(nb->control_msgs_out)) &&
1111 (nb->cmlength != 0));
1112 BUG_ON((list_empty(&(nb->control_msgs_out)) == 0) &&
1113 (nb->cmlength == 0));
1114 BUG_ON(list_empty(&(nb->ucontrol_msgs_out)) &&
1115 (nb->ucmlength != 0));
1116 BUG_ON((list_empty(&(nb->ucontrol_msgs_out)) == 0) &&
1117 (nb->ucmlength == 0));
1118 BUG_ON(nb->cmlength < 0);
1119 BUG_ON(nb->ucmlength < 0);
1121 length = get_total_messages_length(nb, ping, urgentonly);
1123 if (length == 0)
1124 break;
1126 if (length < targetmss && allmsgs == 0)
1127 break;
1129 seqno = atomic_add_return(1, &(nb->kpacket_seqno));
1131 if (length > targetmss)
1132 length = targetmss;
1134 mutex_unlock(&(nb->cmsg_lock));
1135 skb = create_packet(nb, length, GFP_KERNEL, 0, seqno);
1136 if (unlikely(skb == 0)) {
1137 printk(KERN_ERR "cor: send_messages: cannot allocate "
1138 "skb (out of memory?)");
1139 goto oom;
1142 cr = kmem_cache_alloc(controlretrans_slab, GFP_KERNEL);
1143 if (unlikely(cr == 0)) {
1144 kfree_skb(skb);
1145 printk(KERN_ERR "cor: send_messages: cannot allocate "
1146 "control_retrans (out of memory?)");
1147 goto oom;
1149 memset(cr, 0, sizeof(struct control_retrans));
1150 kref_init(&(cr->ref));
1151 cr->nb = nb;
1152 cr->seqno = seqno;
1153 INIT_LIST_HEAD(&(cr->msgs));
1155 rc = _send_messages(nb, skb, ping, cr, length, urgentonly);
1156 ping = 0;
1158 mutex_lock(&(nb->cmsg_lock));
1160 if (rc != 0)
1161 break;
1164 if (0) {
1165 oom:
1166 mutex_lock(&(nb->cmsg_lock));
1169 if (rc != 0) {
1170 if (resume == 0) {
1171 nb->kp_allmsgs = nb->kp_allmsgs || allmsgs;
1172 qos_enqueue(nb->dev, &(nb->rb_kp), QOS_CALLER_KPACKET);
1174 } else if (allmsgs) {
1175 nb->kp_allmsgs = 0;
1178 mutex_unlock(&(nb->cmsg_lock));
1180 if (allmsgs)
1181 schedule_controlmsg_timerfunc(nb);
1183 return rc;
1186 static void controlmsg_timerfunc(struct work_struct *work)
1188 struct neighbor *nb = container_of(to_delayed_work(work),
1189 struct neighbor, cmsg_timer);
1190 unsigned long jiffies_tmp = jiffies;
1192 mutex_lock(&(nb->cmsg_lock));
1194 if (time_after(nb->timeout, jiffies_tmp)) {
1195 INIT_DELAYED_WORK(&(nb->cmsg_timer), controlmsg_timerfunc);
1196 schedule_delayed_work(&(nb->cmsg_timer), nb->timeout -
1197 jiffies_tmp);
1198 mutex_unlock(&(nb->cmsg_lock));
1199 return;
1202 mutex_unlock(&(nb->cmsg_lock));
1204 send_messages(nb, 1, 0);
1205 kref_put(&(nb->ref), neighbor_free);
1208 void schedule_controlmsg_timerfunc(struct neighbor *nb)
1210 __u64 jiffies = get_jiffies_64();
1211 long long delay;
1213 int state = get_neigh_state(nb);
1215 if (unlikely(state == NEIGHBOR_STATE_KILLED))
1216 return;
1218 mutex_lock(&(nb->cmsg_lock));
1219 nb->timeout += msecs_to_jiffies(CMSG_INTERVAL_MS);
1221 delay = nb->timeout - jiffies;
1222 if (delay < 0) {
1223 delay = 1;
1224 nb->timeout = jiffies;
1227 INIT_DELAYED_WORK(&(nb->cmsg_timer), controlmsg_timerfunc);
1228 schedule_delayed_work(&(nb->cmsg_timer), delay);
1229 mutex_unlock(&(nb->cmsg_lock));
1230 kref_get(&(nb->ref));
1233 static void free_oldest_ucm(struct neighbor *nb)
1235 struct control_msg_out *cm = container_of(nb->ucontrol_msgs_out.next,
1236 struct control_msg_out, lh);
1238 BUG_ON(list_empty(&(nb->ucontrol_msgs_out)));
1239 BUG_ON(isurgent(cm) == 0);
1241 list_del(&(cm->lh));
1242 nb->ucmlength -= cm->length;
1243 atomic_dec(&(nb->ucmcnt));
1244 free_control_msg(cm);
1247 static void add_control_msg(struct control_msg_out *cm, int retrans)
1249 int nbstate;
1251 BUG_ON(cm->nb == 0);
1253 nbstate = get_neigh_state(cm->nb);
1255 BUG_ON(cm == 0);
1256 BUG_ON(cm->lh.next != LIST_POISON1 || cm->lh.prev != LIST_POISON2);
1258 mutex_lock(&(cm->nb->cmsg_lock));
1260 if (isurgent(cm)) {
1261 long msgs;
1263 msgs = atomic_inc_return(&(cm->nb->ucmcnt));
1264 BUG_ON(msgs <= 0);
1266 if (unlikely(retrans)) {
1267 if (msgs > MAX_URGENT_CMSGS_PER_NEIGH_RETRANSALLOW ||
1268 msgs > MAX_URGENT_CMSGS_PER_NEIGH) {
1269 atomic_dec(&(cm->nb->ucmcnt));
1270 free_control_msg(cm);
1271 goto out;
1274 cm->nb->ucmlength += cm->length;
1275 list_add(&(cm->lh), &(cm->nb->ucontrol_msgs_out));
1276 } else {
1277 if (msgs > MAX_URGENT_CMSGS_PER_NEIGH) {
1278 free_oldest_ucm(cm->nb);
1281 cm->nb->ucmlength += cm->length;
1282 list_add_tail(&(cm->lh), &(cm->nb->ucontrol_msgs_out));
1284 } else {
1285 cm->nb->cmlength += cm->length;
1286 list_add_tail(&(cm->lh), &(cm->nb->control_msgs_out));
1289 #warning todo measure inter message interval
1290 if (unlikely((nbstate == NEIGHBOR_STATE_ACTIVE ? cm->nb->cmlength : 0) +
1291 cm->nb->ucmlength >= mss(cm->nb)))
1292 send_messages(cm->nb, 0, 0);
1294 out:
1295 mutex_unlock(&(cm->nb->cmsg_lock));
1298 void send_pong(struct neighbor *nb, __u32 cookie)
1300 struct control_msg_out *cm = _alloc_control_msg(nb, 0, 1);
1302 if (unlikely(cm == 0))
1303 return;
1305 cm->nb = nb;
1306 cm->type = MSGTYPE_PONG;
1307 cm->msg.pong.cookie = cookie;
1308 cm->msg.pong.time_enqueued = jiffies;
1309 cm->length = 9;
1310 add_control_msg(cm, 0);
1313 void send_reset_conn(struct control_msg_out *cm, __u32 conn_id)
1315 cm->type = MSGTYPE_RESET_CONN;
1316 cm->msg.reset.conn_id = conn_id;
1317 cm->length = 5;
1318 add_control_msg(cm, 0);
1321 void send_ack(struct neighbor *nb, __u32 seqno)
1323 struct control_msg_out *cm = _alloc_control_msg(nb, 0, 1);
1325 if (unlikely(cm == 0))
1326 return;
1328 cm->nb = nb;
1329 cm->type = MSGTYPE_ACK;
1330 cm->msg.ack.seqno = seqno;
1331 cm->length = 5;
1332 add_control_msg(cm, 0);
1335 void send_ack_conn(struct control_msg_out *cm, struct conn *rconn,
1336 __u32 conn_id, __u32 seqno)
1338 cm->type = MSGTYPE_ACK_CONN;
1339 kref_get(&(rconn->ref));
1340 BUG_ON(rconn->sourcetype != SOURCE_IN);
1341 cm->msg.ack_conn.flags = KP_ACK_CONN_FLAGS_SEQNO |
1342 KP_ACK_CONN_FLAGS_WINDOW;
1343 cm->msg.ack_conn.rconn = rconn;
1344 cm->msg.ack_conn.conn_id = conn_id;
1345 cm->msg.ack_conn.seqno = seqno;
1346 cm->length = 6 + ack_conn_len(cm->msg.ack_conn.flags);
1347 add_control_msg(cm, 0);
1350 void send_ack_conn_ooo(struct control_msg_out *cm, struct conn *rconn,
1351 __u32 conn_id, __u32 seqno_ooo, __u32 length)
1353 cm->type = MSGTYPE_ACK_CONN;
1354 kref_get(&(rconn->ref));
1355 BUG_ON(rconn->sourcetype != SOURCE_IN);
1356 cm->msg.ack_conn.flags = ooolen_to_flags(length);
1357 cm->msg.ack_conn.rconn = rconn;
1358 cm->msg.ack_conn.conn_id = conn_id;
1359 cm->msg.ack_conn.seqno_ooo = seqno_ooo;
1360 cm->msg.ack_conn.length = length;
1361 cm->length = 6 + ack_conn_len(cm->msg.ack_conn.flags);
1362 add_control_msg(cm, 0);
1365 void send_connect_success(struct control_msg_out *cm, __u32 rcvd_conn_id,
1366 __u32 gen_conn_id, __u32 init_seqno, struct conn *rconn)
1368 cm->type = MSGTYPE_CONNECT_SUCCESS;
1369 cm->msg.connect_success.rcvd_conn_id = rcvd_conn_id;
1370 cm->msg.connect_success.gen_conn_id = gen_conn_id;
1371 cm->msg.connect_success.init_seqno = init_seqno;
1372 kref_get(&(rconn->ref));
1373 BUG_ON(rconn->sourcetype != SOURCE_IN);
1374 cm->msg.connect_success.rconn = rconn;
1375 cm->length = 14;
1376 add_control_msg(cm, 0);
1379 void send_connect_nb(struct control_msg_out *cm, __u32 conn_id,
1380 __u32 init_seqno, struct conn *sconn)
1382 cm->type = MSGTYPE_CONNECT;
1383 cm->msg.connect.conn_id = conn_id;
1384 cm->msg.connect.init_seqno = init_seqno;
1385 kref_get(&(sconn->ref));
1386 BUG_ON(sconn->sourcetype != SOURCE_IN);
1387 cm->msg.connect.sconn = sconn;
1388 cm->length = 10;
1389 add_control_msg(cm, 0);
1392 void send_conndata(struct control_msg_out *cm, __u32 conn_id, __u32 seqno,
1393 char *data_orig, char *data, __u32 datalen)
1395 cm->type = MSGTYPE_CONNDATA;
1396 cm->msg.conn_data.conn_id = conn_id;
1397 cm->msg.conn_data.seqno = seqno;
1398 cm->msg.conn_data.data_orig = data_orig;
1399 cm->msg.conn_data.data = data;
1400 cm->msg.conn_data.datalen = datalen;
1401 cm->length = 11 + datalen;
1402 add_control_msg(cm, 0);
1405 void send_ping_conn(struct control_msg_out *cm, __u32 conn_id)
1407 cm->type = MSGTYPE_PING_CONN;
1408 cm->msg.ping_conn.conn_id = conn_id;
1409 cm->length = 5;
1410 add_control_msg(cm, 0);
1414 void send_connid_unknown(struct control_msg_out *cm, __u32 conn_id)
1416 cm->type = MSGTYPE_CONNID_UNKNOWN;
1417 cm->msg.connid_unknown.conn_id = conn_id;
1418 cm->length = 5;
1419 add_control_msg(cm, 0);
1422 void send_ping_all_conns(struct neighbor *nb)
1424 mutex_lock(&(nb->cmsg_lock));
1425 nb->ping_all_conns = 1;
1426 mutex_unlock(&(nb->cmsg_lock));
1429 /* 8*2**(x/5.5) */
1430 void set_creditrate_out(struct control_msg_out *cm, __u32 conn_id,
1431 __u32 creditrate)
1433 free_control_msg(cm);
1434 #warning todo
1438 static int matches_connretrans(void *htentry, void *searcheditem)
1440 struct control_retrans *cr = (struct control_retrans *) htentry;
1441 struct retransmit_matchparam *rm = (struct retransmit_matchparam *)
1442 searcheditem;
1444 return rm->nb == cr->nb && rm->seqno == cr->seqno;
1447 void __init cor_kgen_init(void)
1449 controlmsg_slab = kmem_cache_create("cor_controlmsg",
1450 sizeof(struct control_msg_out), 8, 0, 0);
1451 controlretrans_slab = kmem_cache_create("cor_controlretransmsg",
1452 sizeof(struct control_retrans), 8, 0, 0);
1453 htable_init(&retransmits, matches_connretrans,
1454 offsetof(struct control_retrans, htab_entry),
1455 offsetof(struct control_retrans, ref));
1458 MODULE_LICENSE("GPL");