new retransmit
[cor_2_6_31.git] / net / cor / kpacket_gen.c
blob80b0fb46dbbde41306430ba92055f5f610e23b63
1 /*
2 * Connection oriented routing
3 * Copyright (C) 2007-2008 Michael Blizek
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public License
7 * as published by the Free Software Foundation; either version 2
8 * of the License, or (at your option) any later version.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
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_CONNECT 3
29 #define MSGTYPE_CONNECT_SUCCESS 4
30 #define MSGTYPE_RESET_CONN 5
31 #define MSGTYPE_CONNDATA 6
34 * lh must be first
36 struct control_msg_out{
37 struct list_head lh;
38 struct neighbor *nb;
40 __u32 length;
42 __u8 type;
43 union{
44 struct{
45 __u32 cookie;
46 unsigned long time_enqueued; /* jiffies */
47 }pong;
49 struct{
50 __u32 conn_id;
51 __u32 seqno;
52 }ack;
54 struct{
55 __u32 conn_id;
56 }connect;
58 struct{
59 __u32 rcvd_conn_id;
60 __u32 gen_conn_id;
61 }connect_success;
63 struct{
64 __u32 conn_id;
65 }reset;
67 struct{
68 __u32 conn_id;
69 }reset_bw;
71 struct conn_data{
72 __u32 conn_id;
73 __u32 seqno;
74 char *data_orig;
75 char *data;
76 __u32 datalen;
77 }conn_data;
78 }msg;
81 struct control_msg_out *alloc_control_msg(void)
83 struct control_msg_out *cm = kmalloc(sizeof(struct control_msg_out),
84 GFP_KERNEL);
85 if (unlikely(cm == 0))
86 return 0;
87 cm->lh.next = LIST_POISON1;
88 cm->lh.prev = LIST_POISON2;
89 return cm;
92 void free_control_msg(struct control_msg_out *cm)
94 kfree(cm);
97 static void cor_xmit(struct sk_buff *skb, int atomic, int clone)
99 struct sk_buff *skb2;
101 BUG_ON(skb == 0);
103 if (clone) {
104 skb2 = skb_clone(skb, __GFP_DMA | (atomic ? GFP_ATOMIC :
105 GFP_KERNEL));
107 if (skb2 == 0) {
108 printk(KERN_WARNING "cor_xmit: cannot clone skb, "
109 "allocation failure?");
110 return;
112 } else {
113 skb2 = skb;
116 dev_queue_xmit(skb2);
119 static int add_ack(struct sk_buff *skb, struct control_msg_out *cm,
120 int spaceleft)
122 char *dst;
124 if (spaceleft < 9)
125 return 0;
127 dst = skb_put(skb, 9);
128 BUG_ON(0 == dst);
130 dst[0] = KP_ACK;
131 put_u32(dst + 1, cm->msg.ack.conn_id, 1);
132 put_u32(dst + 5, cm->msg.ack.seqno, 1);
134 return 9;
137 static int add_ping(struct sk_buff *skb, __u32 cookie,
138 int spaceleft)
140 char *dst;
142 if (spaceleft < 5)
143 return 0;
145 dst = skb_put(skb, 5);
146 BUG_ON(0 == dst);
148 dst[0] = KP_PING;
149 put_u32(dst + 1, cookie, 0);
151 return 5;
154 static int add_pong(struct sk_buff *skb, struct control_msg_out *cm,
155 int spaceleft)
157 char *dst;
159 if (spaceleft < 9)
160 return 0;
162 dst = skb_put(skb, 9);
163 BUG_ON(0 == dst);
165 dst[0] = KP_PONG;
166 put_u32(dst + 1, cm->msg.pong.cookie, 0);
167 put_u32(dst + 5, 1000 * jiffies_to_msecs(jiffies -
168 cm->msg.pong.time_enqueued), 1);
170 return 9;
173 static int add_connect(struct sk_buff *skb, struct control_msg_out *cm,
174 int spaceleft)
176 char *dst;
178 if (spaceleft < 5)
179 return 0;
181 dst = skb_put(skb, 5);
182 BUG_ON(0 == dst);
184 dst[0] = KP_CONNECT;
185 put_u32(dst + 1, cm->msg.connect.conn_id, 1);
187 return 5;
190 static int add_connect_success(struct sk_buff *skb, struct control_msg_out *cm,
191 int spaceleft)
193 char *dst;
195 if (spaceleft < 9)
196 return 0;
198 dst = skb_put(skb, 9);
199 BUG_ON(0 == dst);
201 dst[0] = KP_CONNECT_SUCCESS;
202 put_u32(dst + 1, cm->msg.connect_success.rcvd_conn_id, 1);
203 put_u32(dst + 5, cm->msg.connect_success.gen_conn_id, 1);
205 return 9;
208 static int add_reset_conn(struct sk_buff *skb, struct control_msg_out *cm,
209 int spaceleft)
211 char *dst;
213 if (spaceleft < 5)
214 return 0;
216 dst = skb_put(skb, 5);
217 BUG_ON(0 == dst);
219 dst[0] = KP_RESET_CONN;
220 put_u32(dst + 1, cm->msg.reset.conn_id, 1);
222 return 5;
225 static int add_conndata(struct sk_buff *skb, struct control_msg_out *cm,
226 int spaceleft)
228 char *dst;
230 int totallen = cm->msg.conn_data.datalen + 11;
231 int putlen = min(totallen, spaceleft);
232 int dataputlen = putlen - 11;
234 if (dataputlen < 1 || (spaceleft < 25 && spaceleft < totallen))
235 return 0;
237 dst = skb_put(skb, putlen);
238 BUG_ON(0 == dst);
240 dst[0] = KP_CONN_DATA;
241 put_u32(dst + 1, cm->msg.conn_data.conn_id, 1);
242 put_u32(dst + 5, cm->msg.conn_data.seqno, 1);
243 put_u16(dst + 9, dataputlen, 1);
245 memcpy(dst + 11, cm->msg.conn_data.data, dataputlen);
247 cm->msg.conn_data.datalen -= dataputlen;
248 cm->msg.conn_data.data += dataputlen;
250 if (cm->msg.conn_data.datalen == 0) {
251 kfree(cm->msg.conn_data.data_orig);
252 free_control_msg(cm);
253 } else {
254 send_conndata(cm, cm->nb, cm->msg.conn_data.conn_id,
255 cm->msg.conn_data.seqno,
256 cm->msg.conn_data.data_orig,
257 cm->msg.conn_data.data,
258 cm->msg.conn_data.datalen);
261 return putlen;
265 static int add_message(struct sk_buff *skb, struct control_msg_out *cm,
266 int spaceleft)
268 int free = 1;
269 int rc;
270 switch (cm->type) {
271 case MSGTYPE_ACK:
272 rc = add_ack(skb, cm, spaceleft);
273 break;
274 case MSGTYPE_PONG:
275 rc = add_pong(skb, cm, spaceleft);
276 break;
277 case MSGTYPE_CONNECT:
278 rc = add_connect(skb, cm, spaceleft);
279 break;
280 case MSGTYPE_CONNECT_SUCCESS:
281 rc = add_connect_success(skb, cm, spaceleft);
282 break;
283 case MSGTYPE_RESET_CONN:
284 rc = add_reset_conn(skb, cm, spaceleft);
285 break;
286 case MSGTYPE_CONNDATA:
287 free = 0;
288 rc = add_conndata(skb, cm, spaceleft);
289 break;
290 default:
291 BUG();
293 if (free && rc != 0)
294 free_control_msg(cm);
295 return rc;
299 static void padding(struct sk_buff *skb, int length)
301 char *dst = skb_put(skb, length);
302 BUG_ON(0 == dst);
303 memset(dst, KP_PADDING, length);
306 static struct htable retransmits;
308 static void free_skb(struct kref *ref)
310 struct skb_procstate *ps = container_of(ref, struct skb_procstate,
311 funcstate.retransmit_queue.ref);
313 struct sk_buff *skb = skb_from_pstate(ps);
314 kref_put(&(ps->funcstate.retransmit_queue.nb->ref), neighbor_free);
315 kfree_skb(skb);
318 struct retransmit_matchparam {
319 struct neighbor *nb;
320 __u32 seqno;
324 static __u32 rm_to_key(struct retransmit_matchparam *rm)
326 return ((__u32) rm->nb) ^ rm->seqno;
329 static void set_retrans_timeout(struct sk_buff *skb, struct neighbor *nb)
331 struct skb_procstate *ps = skb_pstate(skb);
332 ps->funcstate.retransmit_queue.timeout = jiffies + msecs_to_jiffies(
333 300 + ((__u32)atomic_read(&(nb->latency)))/1000);
336 void retransmit_timerfunc(unsigned long arg)
338 unsigned long iflags;
340 struct neighbor *nb = (struct neighbor *) arg;
341 struct sk_buff *skb = 0;
342 unsigned long timeout;
344 int nbstate;
345 int nbput = 0;
347 spin_lock_irqsave( &(nb->state_lock), iflags );
348 nbstate = nb->state;
349 spin_unlock_irqrestore( &(nb->state_lock), iflags );
351 while (1) {
352 spin_lock_irqsave( &(nb->retrans_lock), iflags );
353 skb = __skb_dequeue(&(nb->retrans_list));
355 if (0 == skb)
356 goto out;
358 if (nbstate == NEIGHBOR_STATE_KILLED) {
359 struct skb_procstate *ps = skb_pstate(skb);
360 struct retransmit_matchparam rm;
361 spin_unlock_irqrestore( &(nb->retrans_lock), iflags );
363 rm.seqno = ps->funcstate.retransmit_queue.seqno;
364 rm.nb = ps->funcstate.retransmit_queue.nb;
366 htable_delete(&retransmits, rm_to_key(&rm), &rm,
367 free_skb);
368 kref_put(&(ps->funcstate.retransmit_queue.ref),
369 free_skb);
370 continue;
373 timeout = skb_pstate(skb)->funcstate.retransmit_queue.timeout;
375 if (time_after(timeout, jiffies)) {
376 __skb_queue_head(&(nb->retrans_list), skb);
377 goto modtimer;
380 set_retrans_timeout(skb, nb);
382 __skb_queue_tail(&(nb->retrans_list), skb);
384 spin_unlock_irqrestore( &(nb->retrans_lock), iflags );
385 cor_xmit(skb, 1, 1);
388 modtimer:
389 mod_timer(&(nb->retrans_timer), timeout);
391 if (0) {
392 out:
393 nb->retrans_timer_running = 0;
394 nbput = 1;
397 spin_unlock_irqrestore( &(nb->retrans_lock), iflags );
399 if (nbput)
400 kref_put(&(nb->ref), neighbor_free);
403 static void schedule_retransmit(struct sk_buff *skb, struct neighbor *nb)
405 unsigned long iflags;
407 struct skb_procstate *ps = skb_pstate(skb);
408 struct retransmit_matchparam rm;
409 int first;
411 rm.seqno = ps->funcstate.retransmit_queue.seqno;
412 rm.nb = nb;
414 set_retrans_timeout(skb, nb);
415 kref_init(&(ps->funcstate.retransmit_queue.ref));
416 htable_insert(&retransmits, (char *) skb, rm_to_key(&rm));
417 spin_lock_irqsave( &(nb->retrans_lock), iflags );
418 first = unlikely(skb_queue_empty(&(nb->retrans_list)));
419 __skb_queue_tail(&(nb->retrans_list), skb);
421 if (unlikely(unlikely(first) &&
422 unlikely(nb->retrans_timer_running == 0))) {
423 mod_timer(&(nb->retrans_timer),
424 ps->funcstate.retransmit_queue.timeout);
425 nb->retrans_timer_running = 1;
426 kref_get(&(nb->ref));
429 spin_unlock_irqrestore( &(nb->retrans_lock), iflags );
431 kref_get(&(ps->funcstate.retransmit_queue.ref));
434 void kern_ack_rcvd(struct neighbor *nb, __u32 seqno)
436 unsigned long iflags;
438 struct sk_buff *skb = 0;
439 struct skb_procstate *ps;
440 struct retransmit_matchparam rm;
442 rm.seqno = seqno;
443 rm.nb = nb;
445 skb = (struct sk_buff *) htable_get(&retransmits, rm_to_key(&rm), &rm);
447 if (0 == skb) {
448 printk(KERN_ERR "bogus/duplicate ack received");
449 return;
452 ps = skb_pstate(skb);
454 if (htable_delete(&retransmits, rm_to_key(&rm), &rm, free_skb)) {
455 /* somebody else has already deleted it in the meantime */
456 return;
459 BUG_ON(ps->funcstate.retransmit_queue.nb != nb);
461 spin_lock_irqsave( &(nb->retrans_lock), iflags );
463 skb->next->prev = skb->prev;
464 skb->prev->next = skb->next;
466 spin_unlock_irqrestore( &(nb->retrans_lock), iflags );
468 kref_put(&(ps->funcstate.retransmit_queue.ref), free_skb);
472 static void _send_messages(struct neighbor *nb, struct sk_buff *skb,
473 int spaceleft, int pongsonly)
475 int length = 0;
476 int retransmit = 0;
478 mutex_lock(&(nb->cmsg_lock));
479 while (!list_empty(&(nb->ucontrol_msgs_out)) || (!pongsonly &&
480 !list_empty(&(nb->control_msgs_out)))) {
481 int rc;
483 int urgent = !list_empty(&(nb->ucontrol_msgs_out));
485 struct control_msg_out *cm;
486 int retrans = 0;
488 if (urgent)
489 cm = container_of(nb->ucontrol_msgs_out.next,
490 struct control_msg_out, lh);
491 else
492 cm = container_of(nb->control_msgs_out.next,
493 struct control_msg_out, lh);
495 list_del(&(cm->lh));
496 if (urgent)
497 nb->ucmlength -= cm->length;
498 else
499 nb->cmlength -= cm->length;
500 if (cm->type != MSGTYPE_ACK || cm->msg.ack.conn_id != 0)
501 retrans = 1;
502 mutex_unlock(&(nb->cmsg_lock));
503 rc = add_message(skb, cm, spaceleft - length);
504 mutex_lock(&(nb->cmsg_lock));
506 if (rc == 0) {
507 if (urgent) {
508 list_add(&(cm->lh), &(nb->ucontrol_msgs_out));
509 nb->ucmlength += cm->length;
510 } else {
511 list_add(&(cm->lh), &(nb->control_msgs_out));
512 nb->cmlength += cm->length;
514 break;
517 length += rc;
519 if (retrans)
520 retransmit = 1;
523 mutex_unlock(&(nb->cmsg_lock));
525 padding(skb, spaceleft - length);
526 if (retransmit)
527 schedule_retransmit(skb, nb);
529 cor_xmit(skb, 0, retransmit);
532 static void send_messages(struct neighbor *nb, int allmsgs)
534 int targetmss = mss(nb);
535 int pingok;
536 int ping = 0;
538 int pingdelay1 = 1000;
539 int pingdelay2 = 400;
541 int nbstate = get_neigh_state(nb);
543 mutex_lock(&(nb->cmsg_lock));
545 BUG_ON(list_empty(&(nb->control_msgs_out)) && (nb->cmlength != 0));
546 BUG_ON((list_empty(&(nb->control_msgs_out)) == 0) &&
547 (nb->cmlength == 0));
548 BUG_ON(list_empty(&(nb->ucontrol_msgs_out)) && (nb->ucmlength != 0));
549 BUG_ON((list_empty(&(nb->ucontrol_msgs_out)) == 0) &&
550 (nb->ucmlength == 0));
552 pingok = time_to_send_ping(nb);
554 if (pingok)
555 ping = time_after_eq(jiffies, nb->last_ping_time +
556 msecs_to_jiffies(pingdelay1));
558 while ((((nbstate == NEIGHBOR_STATE_ACTIVE &&
559 !list_empty(&(nb->control_msgs_out))) ||
560 !list_empty(&(nb->ucontrol_msgs_out))
561 ) && ( (nbstate == NEIGHBOR_STATE_ACTIVE ?
562 nb->cmlength : 0) + nb->ucmlength >= targetmss ||
563 allmsgs)) || (pingok && ping)) {
564 struct sk_buff *skb;
565 int size = targetmss;
566 __u32 length;
568 if (pingok && nb->noping_cnt > 3)
569 ping = 1;
570 if (pingok && time_before_eq(nb->last_ping_time +
571 msecs_to_jiffies(pingdelay2), jiffies))
572 ping = 1;
573 nb->noping_cnt++;
575 length = nb->ucmlength + (ping != 0 ? 5 : 0) + (likely(
576 nbstate == NEIGHBOR_STATE_ACTIVE) ?
577 nb->cmlength : 0);
578 if (size > length)
579 size = length;
580 mutex_unlock(&(nb->cmsg_lock));
581 skb = create_packet_kernel(nb, size, GFP_KERNEL);
582 if (skb == 0) {
583 printk(KERN_ERR "cor: send_messages: cannot allocate "
584 "skb (out of memory?)");
585 goto out;
588 if (ping) {
589 __u32 pingcookie = add_ping_req(nb);
590 int rc = add_ping(skb, pingcookie, size);
591 if (rc == 0)
592 goto err;
593 nb->noping_cnt = 0;
594 nb->last_ping_time = jiffies;
595 size -= rc;
596 ping = 0;
598 _send_messages(nb, skb, size, nbstate != NEIGHBOR_STATE_ACTIVE);
600 if (0) {
601 err:
602 printk(KERN_ERR "kpacket_gen add_ping error");
603 kfree_skb(skb);
606 mutex_lock(&(nb->cmsg_lock));
608 mutex_unlock(&(nb->cmsg_lock));
610 out:
611 BUG_ON(nb->cmlength < 0);
614 static void controlmsg_timerfunc(struct work_struct *work)
616 struct neighbor *nb = container_of(to_delayed_work(work),
617 struct neighbor, cmsg_timer);
618 __u64 jiffies = get_jiffies_64();
620 mutex_lock(&(nb->cmsg_lock));
622 if (nb->timeout > jiffies) {
623 INIT_DELAYED_WORK(&(nb->cmsg_timer), controlmsg_timerfunc);
624 schedule_delayed_work(&(nb->cmsg_timer), nb->timeout - jiffies);
625 mutex_unlock(&(nb->cmsg_lock));
626 return;
629 mutex_unlock(&(nb->cmsg_lock));
631 send_messages(nb, 1);
632 schedule_controlmsg_timerfunc(nb);
633 kref_put(&(nb->ref), neighbor_free);
636 void schedule_controlmsg_timerfunc(struct neighbor *nb)
638 int target_delay_ms = 100;
639 int target_delay_jiffies = msecs_to_jiffies(target_delay_ms);
640 __u64 jiffies = get_jiffies_64();
641 long long delay;
643 int state = get_neigh_state(nb);
645 if (state == NEIGHBOR_STATE_KILLED)
646 return;
648 mutex_lock(&(nb->cmsg_lock));
649 nb->timeout += target_delay_jiffies;
651 delay = nb->timeout - jiffies;
652 if (delay < 0) {
653 delay = 0;
654 nb->timeout = jiffies;
657 INIT_DELAYED_WORK(&(nb->cmsg_timer), controlmsg_timerfunc);
658 schedule_delayed_work(&(nb->cmsg_timer), delay);
659 mutex_unlock(&(nb->cmsg_lock));
660 kref_get(&(nb->ref));
663 static void add_control_msg(struct control_msg_out *msg, struct neighbor *nb)
665 int nbstate = get_neigh_state(nb);
667 BUG_ON(msg == 0);
668 BUG_ON(msg->lh.next != LIST_POISON1 || msg->lh.prev != LIST_POISON2);
670 mutex_lock(&(nb->cmsg_lock));
672 msg->nb = nb;
673 if (unlikely(msg->type == MSGTYPE_PONG || (msg->type == MSGTYPE_ACK &&
674 unlikely(msg->msg.ack.conn_id == 0)))) {
675 nb->ucmlength += msg->length;
676 list_add_tail(&(msg->lh), &(nb->ucontrol_msgs_out));
677 } else {
678 nb->cmlength += msg->length;
679 list_add_tail(&(msg->lh), &(nb->control_msgs_out));
682 if (unlikely((nbstate == NEIGHBOR_STATE_ACTIVE ? nb->cmlength : 0) +
683 nb->ucmlength >= mss(nb)))
684 send_messages(nb, 0);
686 mutex_unlock(&(nb->cmsg_lock));
689 void send_pong(struct control_msg_out *cm, struct neighbor *nb, __u32 cookie)
691 cm->type = MSGTYPE_PONG;
692 cm->msg.pong.cookie = cookie;
693 cm->msg.pong.time_enqueued = jiffies;
694 cm->length = 9;
695 add_control_msg(cm, nb);
698 void send_reset_conn(struct control_msg_out *cm, struct neighbor *nb,
699 __u32 conn_id)
701 cm->type = MSGTYPE_RESET_CONN;
702 cm->msg.reset.conn_id = conn_id;
703 cm->length = 5;
704 add_control_msg(cm, nb);
707 void send_ack(struct control_msg_out *cm, struct neighbor *nb, __u32 conn_id,
708 __u32 seqno)
710 cm->type = MSGTYPE_ACK;
711 cm->msg.ack.conn_id = conn_id;
712 cm->msg.ack.seqno = seqno;
713 cm->length = 9;
714 add_control_msg(cm, nb);
717 void send_connect_success(struct control_msg_out *cm, struct neighbor *nb,
718 __u32 rcvd_conn_id, __u32 gen_conn_id)
720 cm->type = MSGTYPE_CONNECT_SUCCESS;
721 cm->msg.connect_success.rcvd_conn_id = rcvd_conn_id;
722 cm->msg.connect_success.gen_conn_id = gen_conn_id;
723 cm->length = 9;
724 add_control_msg(cm, nb);
727 void send_connect_nb(struct control_msg_out *cm, struct neighbor *nb,
728 __u32 conn_id)
730 cm->type = MSGTYPE_CONNECT;
731 cm->msg.connect.conn_id = conn_id;
732 cm->length = 5;
733 add_control_msg(cm, nb);
736 void send_conndata(struct control_msg_out *cm, struct neighbor *nb,
737 __u32 conn_id, __u32 seqno, char *data_orig, char *data,
738 __u32 datalen)
740 cm->type = MSGTYPE_CONNDATA;
741 cm->msg.conn_data.conn_id = conn_id;
742 cm->msg.conn_data.seqno = seqno;
743 cm->msg.conn_data.data_orig = data_orig;
744 cm->msg.conn_data.data = data;
745 cm->msg.conn_data.datalen = datalen;
746 cm->length = 11 + datalen;
747 add_control_msg(cm, nb);
750 static int matches_skb_connid_seqno(void *htentry, void *searcheditem)
752 struct sk_buff *skb = (struct sk_buff *) htentry;
753 struct skb_procstate *ps = skb_pstate(skb);
754 struct retransmit_matchparam *rm = (struct retransmit_matchparam *)
755 searcheditem;
757 return rm->seqno == ps->funcstate.retransmit_queue.seqno &&
758 rm->nb == ps->funcstate.retransmit_queue.nb;
761 static inline __u32 retransmit_entryoffset(void)
763 return offsetof(struct sk_buff, cb) + offsetof(struct skb_procstate,
764 funcstate.retransmit_queue.htab_entry);
767 static inline __u32 retransmit_refoffset(void)
769 return offsetof(struct sk_buff, cb) + offsetof(struct skb_procstate,
770 funcstate.retransmit_queue.ref);
773 void __init cor_kgen_init(void)
775 htable_init(&retransmits, matches_skb_connid_seqno,
776 retransmit_entryoffset(), retransmit_refoffset());