2 * Connection oriented routing
3 * Copyright (C) 2007-2008 Michael Blizek
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public License
7 * as published by the Free Software Foundation; either version 2
8 * of the License, or (at your option) any later version.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
21 #include <asm/byteorder.h>
25 /* not sent over the network - internal meaning only */
26 #define MSGTYPE_PONG 1
28 #define MSGTYPE_CONNECT 3
29 #define MSGTYPE_CONNECT_SUCCESS 4
30 #define MSGTYPE_RESET_CONN 5
31 #define MSGTYPE_CONNDATA 6
36 struct control_msg_out
{
46 unsigned long time_enqueued
; /* jiffies */
81 struct control_msg_out
*alloc_control_msg(void)
83 struct control_msg_out
*cm
= kmalloc(sizeof(struct control_msg_out
), GFP_KERNEL
);
84 if (unlikely(cm
== 0))
86 cm
->lh
.next
= LIST_POISON1
;
87 cm
->lh
.prev
= LIST_POISON2
;
91 void free_control_msg(struct control_msg_out
*cm
)
96 static int add_ack(struct sk_buff
*skb
, struct control_msg_out
*cm
,
104 dst
= skb_put(skb
, 9);
108 put_u32(dst
+ 1, cm
->msg
.ack
.conn_id
, 1);
109 put_u32(dst
+ 5, cm
->msg
.ack
.seqno
, 1);
114 static int add_ping(struct sk_buff
*skb
, __u32 cookie
,
122 dst
= skb_put(skb
, 5);
126 put_u32(dst
+ 1, cookie
, 0);
131 static int add_pong(struct sk_buff
*skb
, struct control_msg_out
*cm
,
139 dst
= skb_put(skb
, 9);
143 put_u32(dst
+ 1, cm
->msg
.pong
.cookie
, 0);
144 put_u32(dst
+ 5, 1000 * jiffies_to_msecs(jiffies
-
145 cm
->msg
.pong
.time_enqueued
), 1);
150 static int add_connect(struct sk_buff
*skb
, struct control_msg_out
*cm
,
158 dst
= skb_put(skb
, 5);
162 put_u32(dst
+ 1, cm
->msg
.connect
.conn_id
, 1);
167 static int add_connect_success(struct sk_buff
*skb
, struct control_msg_out
*cm
,
175 dst
= skb_put(skb
, 9);
178 dst
[0] = KP_CONNECT_SUCCESS
;
179 put_u32(dst
+ 1, cm
->msg
.connect_success
.rcvd_conn_id
, 1);
180 put_u32(dst
+ 5, cm
->msg
.connect_success
.gen_conn_id
, 1);
185 static int add_reset_conn(struct sk_buff
*skb
, struct control_msg_out
*cm
,
193 dst
= skb_put(skb
, 5);
196 dst
[0] = KP_RESET_CONN
;
197 put_u32(dst
+ 1, cm
->msg
.reset
.conn_id
, 1);
202 static int add_conndata(struct sk_buff
*skb
, struct control_msg_out
*cm
,
207 int totallen
= cm
->msg
.conn_data
.datalen
+ 11;
208 int putlen
= min(totallen
, spaceleft
);
209 int dataputlen
= putlen
- 11;
211 if (dataputlen
< 1 || (spaceleft
< 25 && spaceleft
< totallen
))
214 dst
= skb_put(skb
, putlen
);
217 dst
[0] = KP_CONN_DATA
;
218 put_u32(dst
+ 1, cm
->msg
.conn_data
.conn_id
, 1);
219 put_u32(dst
+ 5, cm
->msg
.conn_data
.seqno
, 1);
220 put_u16(dst
+ 9, dataputlen
, 1);
222 memcpy(dst
+ 11, cm
->msg
.conn_data
.data
, dataputlen
);
224 cm
->msg
.conn_data
.datalen
-= dataputlen
;
225 cm
->msg
.conn_data
.data
+= dataputlen
;
227 if (cm
->msg
.conn_data
.datalen
== 0) {
228 kfree(cm
->msg
.conn_data
.data_orig
);
229 free_control_msg(cm
);
231 send_conndata(cm
, cm
->nb
, cm
->msg
.conn_data
.conn_id
,
232 cm
->msg
.conn_data
.seqno
,
233 cm
->msg
.conn_data
.data_orig
,
234 cm
->msg
.conn_data
.data
,
235 cm
->msg
.conn_data
.datalen
);
242 static int add_message(struct sk_buff
*skb
, struct control_msg_out
*cm
,
249 rc
= add_ack(skb
, cm
, spaceleft
);
252 rc
= add_pong(skb
, cm
, spaceleft
);
254 case MSGTYPE_CONNECT
:
255 rc
= add_connect(skb
, cm
, spaceleft
);
257 case MSGTYPE_CONNECT_SUCCESS
:
258 rc
= add_connect_success(skb
, cm
, spaceleft
);
260 case MSGTYPE_RESET_CONN
:
261 rc
= add_reset_conn(skb
, cm
, spaceleft
);
263 case MSGTYPE_CONNDATA
:
265 rc
= add_conndata(skb
, cm
, spaceleft
);
271 free_control_msg(cm
);
276 static void padding(struct sk_buff
*skb
, int length
)
278 char *dst
= skb_put(skb
, length
);
280 memset(dst
, KP_PADDING
, length
);
283 static void _send_messages(struct neighbor
*nb
, struct sk_buff
*skb
,
289 mutex_lock(&(nb
->cmsg_lock
));
290 while (!list_empty(&(nb
->control_msgs_out
))) {
293 struct control_msg_out
*cm
= container_of(
294 nb
->control_msgs_out
.next
,
295 struct control_msg_out
, lh
);
298 nb
->length
-= cm
->length
;
299 if (cm
->type
!= MSGTYPE_ACK
|| cm
->msg
.ack
.conn_id
!= 0)
301 mutex_unlock(&(nb
->cmsg_lock
));
302 rc
= add_message(skb
, cm
, spaceleft
- length
);
303 mutex_lock(&(nb
->cmsg_lock
));
306 list_add(&(cm
->lh
), &(nb
->control_msgs_out
));
307 nb
->length
+= cm
->length
;
319 mutex_unlock(&(nb
->cmsg_lock
));
321 padding(skb
, spaceleft
- length
);
322 send_packet(skb
, nb
, retransmit
);
325 static void send_messages(struct neighbor
*nb
, int allmsgs
)
327 int targetmss
= mss(nb
);
330 int pingdelay1
= 1000;
331 int pingdelay2
= 400;
333 mutex_lock(&(nb
->cmsg_lock
));
335 BUG_ON(list_empty(&(nb
->control_msgs_out
)) && (nb
->length
!= 0));
336 BUG_ON((list_empty(&(nb
->control_msgs_out
)) == 0) && (nb
->length
== 0));
338 ping
= time_before_eq(nb
->last_ping_time
+ msecs_to_jiffies(pingdelay1
),
341 while ((list_empty(&(nb
->control_msgs_out
)) == 0 &&
342 (nb
->length
>= targetmss
|| allmsgs
)) ||
345 int size
= targetmss
;
348 if (nb
->noping_cnt
> 3)
350 if (time_before_eq(nb
->last_ping_time
+
351 msecs_to_jiffies(pingdelay2
), jiffies
))
355 length
= nb
->length
+ (ping
!= 0 ? 5 : 0);
358 mutex_unlock(&(nb
->cmsg_lock
));
359 skb
= create_packet_kernel(nb
, size
, GFP_KERNEL
);
361 printk(KERN_ERR
"cor: send_messages: cannot allocate "
362 "skb (out of memory?)");
367 __u32 pingcookie
= add_ping_req(nb
);
368 int rc
= add_ping(skb
, pingcookie
, size
);
372 nb
->last_ping_time
= jiffies
;
376 _send_messages(nb
, skb
, size
);
380 printk(KERN_ERR
"kpacket_gen add_ping error");
384 mutex_lock(&(nb
->cmsg_lock
));
386 mutex_unlock(&(nb
->cmsg_lock
));
389 BUG_ON(nb
->length
< 0);
392 static void controlmsg_timerfunc(struct work_struct
*work
)
394 struct neighbor
*nb
= container_of(to_delayed_work(work
),
395 struct neighbor
, cmsg_timer
);
396 __u64 jiffies
= get_jiffies_64();
398 mutex_lock(&(nb
->cmsg_lock
));
400 if (nb
->timeout
> jiffies
) {
401 INIT_DELAYED_WORK(&(nb
->cmsg_timer
), controlmsg_timerfunc
);
402 schedule_delayed_work(&(nb
->cmsg_timer
), nb
->timeout
- jiffies
);
403 mutex_unlock(&(nb
->cmsg_lock
));
407 mutex_unlock(&(nb
->cmsg_lock
));
409 send_messages(nb
, 1);
410 schedule_controlmsg_timerfunc(nb
);
413 void schedule_controlmsg_timerfunc(struct neighbor
*nb
)
415 int target_delay_ms
= 100;
416 int target_delay_jiffies
= msecs_to_jiffies(target_delay_ms
);
417 __u64 jiffies
= get_jiffies_64();
420 mutex_lock(&(nb
->cmsg_lock
));
421 nb
->timeout
+= target_delay_jiffies
;
423 delay
= nb
->timeout
- jiffies
;
426 nb
->timeout
= jiffies
;
429 INIT_DELAYED_WORK(&(nb
->cmsg_timer
), controlmsg_timerfunc
);
430 schedule_delayed_work(&(nb
->cmsg_timer
), delay
);
431 mutex_unlock(&(nb
->cmsg_lock
));
434 static void add_control_msg(struct control_msg_out
*msg
, struct neighbor
*nb
)
438 mutex_lock(&(nb
->cmsg_lock
));
441 nb
->length
+= msg
->length
;
442 list_add_tail(&(msg
->lh
), &(nb
->control_msgs_out
));
444 if (unlikely(nb
->length
>= mss(nb
)))
445 send_messages(nb
, 0);
447 mutex_unlock(&(nb
->cmsg_lock
));
450 void send_pong(struct control_msg_out
*cm
, struct neighbor
*nb
, __u32 cookie
)
452 BUG_ON(cm
->lh
.next
!= LIST_POISON1
|| cm
->lh
.prev
!= LIST_POISON2
);
453 cm
->type
= MSGTYPE_PONG
;
454 cm
->msg
.pong
.cookie
= cookie
;
455 cm
->msg
.pong
.time_enqueued
= jiffies
;
457 add_control_msg(cm
, nb
);
460 void send_reset_conn(struct control_msg_out
*cm
, struct neighbor
*nb
,
463 BUG_ON(cm
->lh
.next
!= LIST_POISON1
|| cm
->lh
.prev
!= LIST_POISON2
);
464 cm
->type
= MSGTYPE_RESET_CONN
;
465 cm
->msg
.reset
.conn_id
= conn_id
;
467 add_control_msg(cm
, nb
);
470 void send_ack(struct control_msg_out
*cm
, struct neighbor
*nb
, __u32 conn_id
,
473 BUG_ON(cm
->lh
.next
!= LIST_POISON1
|| cm
->lh
.prev
!= LIST_POISON2
);
474 cm
->type
= MSGTYPE_ACK
;
475 cm
->msg
.ack
.conn_id
= conn_id
;
476 cm
->msg
.ack
.seqno
= seqno
;
478 add_control_msg(cm
, nb
);
481 void send_connect_success(struct control_msg_out
*cm
, struct neighbor
*nb
,
482 __u32 rcvd_conn_id
, __u32 gen_conn_id
)
484 BUG_ON(cm
->lh
.next
!= LIST_POISON1
|| cm
->lh
.prev
!= LIST_POISON2
);
485 cm
->type
= MSGTYPE_CONNECT_SUCCESS
;
486 cm
->msg
.connect_success
.rcvd_conn_id
= rcvd_conn_id
;
487 cm
->msg
.connect_success
.gen_conn_id
= gen_conn_id
;
489 add_control_msg(cm
, nb
);
492 void send_connect_nb(struct control_msg_out
*cm
, struct neighbor
*nb
,
495 BUG_ON(cm
->lh
.next
!= LIST_POISON1
|| cm
->lh
.prev
!= LIST_POISON2
);
496 cm
->type
= MSGTYPE_CONNECT
;
497 cm
->msg
.connect
.conn_id
= conn_id
;
499 add_control_msg(cm
, nb
);
502 void send_conndata(struct control_msg_out
*cm
, struct neighbor
*nb
,
503 __u32 conn_id
, __u32 seqno
, char *data_orig
, char *data
,
506 BUG_ON(cm
->lh
.next
!= LIST_POISON1
|| cm
->lh
.prev
!= LIST_POISON2
);
507 cm
->type
= MSGTYPE_CONNDATA
;
508 cm
->msg
.conn_data
.conn_id
= conn_id
;
509 cm
->msg
.conn_data
.seqno
= seqno
;
510 cm
->msg
.conn_data
.data_orig
= data_orig
;
511 cm
->msg
.conn_data
.data
= data
;
512 cm
->msg
.conn_data
.datalen
= datalen
;
513 cm
->length
= 9 + datalen
;
514 add_control_msg(cm
, nb
);