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
21 #include <asm/byteorder.h>
25 /*static __u64 pull_u64(struct sk_buff *skb, int convbo)
27 char *ptr = cor_pull_skb(skb, 8);
33 ((char *)&ret)[0] = ptr[0];
34 ((char *)&ret)[1] = ptr[1];
35 ((char *)&ret)[2] = ptr[2];
36 ((char *)&ret)[3] = ptr[3];
37 ((char *)&ret)[4] = ptr[4];
38 ((char *)&ret)[5] = ptr[5];
39 ((char *)&ret)[6] = ptr[6];
40 ((char *)&ret)[7] = ptr[7];
43 return be64_to_cpu(ret);
47 static __u32
pull_u32(struct sk_buff
*skb
, int convbo
)
49 char *ptr
= cor_pull_skb(skb
, 4);
55 ((char *)&ret
)[0] = ptr
[0];
56 ((char *)&ret
)[1] = ptr
[1];
57 ((char *)&ret
)[2] = ptr
[2];
58 ((char *)&ret
)[3] = ptr
[3];
61 return be32_to_cpu(ret
);
65 static __u16
pull_u16(struct sk_buff
*skb
, int convbo
)
67 char *ptr
= cor_pull_skb(skb
, 2);
73 ((char *)&ret
)[0] = ptr
[0];
74 ((char *)&ret
)[1] = ptr
[1];
77 return be16_to_cpu(ret
);
81 static __u8
pull_u8(struct sk_buff
*skb
)
83 char *ptr
= cor_pull_skb(skb
, 1);
88 static void parse_ack_conn(struct neighbor
*nb
, struct sk_buff
*skb
)
90 __u32 conn_id
= pull_u32(skb
, 1);
91 __u8 flags
= pull_u8(skb
);
93 struct conn
*src_in
= get_conn(conn_id
);
95 if ((flags
& KP_ACK_CONN_FLAGS_SEQNO
) != 0) {
96 __u32 seqno
= pull_u32(skb
, 1);
100 if ((flags
& KP_ACK_CONN_FLAGS_WINDOW
) != 0) {
102 window
= pull_u8(skb
);
105 if (likely(src_in
!= 0))
106 conn_ack_rcvd(nb
, conn_id
, src_in
->reversedir
, seqno
,
110 if (ooolen(flags
) != 0) {
111 __u32 seqno_ooo
= pull_u32(skb
, 1);
114 if (ooolen(flags
) == 1) {
115 ooo_len
= pull_u8(skb
);
116 } else if (ooolen(flags
) == 2) {
117 ooo_len
= pull_u16(skb
, 1);
118 } else if (ooolen(flags
) == 4) {
119 ooo_len
= pull_u32(skb
, 1);
124 if (likely(src_in
!= 0))
125 conn_ack_ooo_rcvd(nb
, conn_id
, src_in
->reversedir
,
129 if (flags
& KP_ACK_CONN_FLAGS_CREDITS
) {
130 __u16 value
= pull_u16(skb
, 1);
132 __u8 seqno
= value
>> 10;
133 __u16 decaytime
= value
& 1023;
136 BUG_ON(decaytime
>= 1024);
138 if (likely(src_in
!= 0))
139 set_conn_in_decaytime(nb
, conn_id
, src_in
, seqno
,
143 if (unlikely(src_in
== 0)) {
144 send_connid_unknown(nb
, conn_id
);
148 mutex_lock(&(src_in
->rcv_lock
));
150 if (unlikely(is_conn_in(src_in
, nb
, conn_id
) == 0)) {
151 send_connid_unknown(nb
, conn_id
);
153 set_last_act(src_in
);
156 mutex_unlock(&(src_in
->rcv_lock
));
158 kref_put(&(src_in
->ref
), free_conn
);
161 static void parse_connect(struct neighbor
*nb
, struct sk_buff
*skb
)
164 __u32 conn_id
= pull_u32(skb
, 1);
165 __u32 init_seqno
= pull_u32(skb
, 1);
166 __u8 window
= pull_u8(skb
);
167 __u16 credits
= pull_u16(skb
, 1);
168 __u8 credits_seqno
= credits
>> 10;
169 __u16 decaytime
= credits
& 1023;
170 struct control_msg_out
*cm
= alloc_control_msg(nb
, ACM_PRIORITY_MED
);
174 if (unlikely(cm
== 0))
177 #warning todo use credits for conn alloclimit
178 src_in
= alloc_conn(GFP_KERNEL
);
180 if (unlikely(src_in
== 0))
183 src_in
->is_client
= 1;
185 mutex_lock(&(src_in
->rcv_lock
));
186 mutex_lock(&(src_in
->reversedir
->rcv_lock
));
187 if (unlikely(conn_init_out(src_in
->reversedir
, nb
))) {
188 mutex_unlock(&(src_in
->reversedir
->rcv_lock
));
189 mutex_unlock(&(src_in
->rcv_lock
));
190 kref_put(&(src_in
->reversedir
->ref
), free_conn
);
191 kref_put(&(src_in
->ref
), free_conn
);
195 gen_conn_id
= src_in
->source
.in
.conn_id
;
196 gen_seqno
= src_in
->source
.in
.next_seqno
;
198 src_in
->reversedir
->target
.out
.conn_id
= conn_id
;
200 src_in
->reversedir
->target
.out
.seqno_nextsend
= init_seqno
;
201 src_in
->reversedir
->target
.out
.seqno_acked
= init_seqno
;
202 reset_seqno(src_in
->reversedir
, init_seqno
);
204 src_in
->reversedir
->target
.out
.seqno_windowlimit
=
205 src_in
->reversedir
->target
.out
.seqno_nextsend
+
206 dec_log_64_11(window
);
207 insert_reverse_connid(src_in
->reversedir
);
208 mutex_unlock(&(src_in
->reversedir
->rcv_lock
));
209 mutex_unlock(&(src_in
->rcv_lock
));
211 BUG_ON(credits_seqno
>= 64);
212 BUG_ON(decaytime
>= 1024);
213 set_conn_in_decaytime(nb
, gen_conn_id
, src_in
, credits_seqno
,
216 send_connect_success(cm
, conn_id
, gen_conn_id
, gen_seqno
, src_in
);
221 free_control_msg(cm
);
223 send_reset_conn(nb
, conn_id
, 0, 0);
227 static void parse_conn_success(struct neighbor
*nb
, struct sk_buff
*skb
)
229 __u32 conn_id1
= pull_u32(skb
, 1);
230 __u32 conn_id2
= pull_u32(skb
, 1);
231 __u32 init_seqno
= pull_u32(skb
, 1);
232 __u8 window
= pull_u8(skb
);
233 __u16 credits
= pull_u16(skb
, 1);
235 __u8 credits_seqno
= credits
>> 10;
236 __u16 decaytime
= credits
& 1023;
240 struct conn
*src_in
= get_conn(conn_id1
);
242 if (unlikely(src_in
== 0))
245 if (unlikely(src_in
->is_client
!= 0))
249 mutex_lock(&(src_in
->reversedir
->rcv_lock
));
250 mutex_lock(&(src_in
->rcv_lock
));
252 if (unlikely(is_conn_in(src_in
, nb
, conn_id1
) == 0))
255 if (unlikely(unlikely(src_in
->reversedir
->targettype
!= TARGET_OUT
) ||
256 unlikely(src_in
->reversedir
->target
.out
.nb
!= nb
) ||
257 unlikely(src_in
->reversedir
->target
.out
.conn_id
!= 0 &&
258 src_in
->reversedir
->target
.out
.conn_id
!= conn_id2
)))
261 if (unlikely(src_in
->reversedir
->isreset
!= 0))
264 set_last_act(src_in
);
266 if (likely(src_in
->reversedir
->target
.out
.conn_id
== 0)) {
267 src_in
->reversedir
->target
.out
.conn_id
= conn_id2
;
268 src_in
->reversedir
->target
.out
.seqno_nextsend
= init_seqno
;
269 src_in
->reversedir
->target
.out
.seqno_acked
= init_seqno
;
270 src_in
->reversedir
->target
.out
.decaytime_send_allowed
= 1;
271 reset_seqno(src_in
->reversedir
, init_seqno
);
273 src_in
->reversedir
->target
.out
.seqno_windowlimit
=
274 src_in
->reversedir
->target
.out
.seqno_nextsend
+
275 dec_log_64_11(window
);
277 insert_reverse_connid(src_in
->reversedir
);
282 mutex_unlock(&(src_in
->reversedir
->rcv_lock
));
283 mutex_unlock(&(src_in
->rcv_lock
));
285 BUG_ON(credits_seqno
>= 64);
286 BUG_ON(decaytime
>= 1024);
288 set_conn_in_decaytime(nb
, conn_id1
, src_in
, credits_seqno
,
291 flush_buf(src_in
->reversedir
);
295 mutex_unlock(&(src_in
->reversedir
->rcv_lock
));
296 mutex_unlock(&(src_in
->rcv_lock
));
298 send_reset_conn(nb
, conn_id2
, conn_id1
, 0);
301 if (likely(src_in
!= 0))
302 kref_put(&(src_in
->ref
), free_conn
);
305 static void parse_conndata(struct neighbor
*nb
, struct sk_buff
*skb
)
307 __u32 conn_id
= pull_u32(skb
, 1);
308 __u32 seqno
= pull_u32(skb
, 1);
309 __u16 datalength
= pull_u16(skb
, 1);
310 char *data
= cor_pull_skb(skb
, datalength
);
314 conn_rcv_buildskb(nb
, data
, datalength
, conn_id
, seqno
);
317 static void parse_reset(struct neighbor
*nb
, struct sk_buff
*skb
)
319 __u32 conn_id
= pull_u32(skb
, 1);
323 struct conn
*src_in
= get_conn(conn_id
);
327 if (src_in
->is_client
) {
328 mutex_lock(&(src_in
->rcv_lock
));
329 mutex_lock(&(src_in
->reversedir
->rcv_lock
));
331 mutex_lock(&(src_in
->reversedir
->rcv_lock
));
332 mutex_lock(&(src_in
->rcv_lock
));
335 send
= unlikely(is_conn_in(src_in
, nb
, conn_id
));
336 if (send
&& src_in
->reversedir
->isreset
== 0)
337 src_in
->reversedir
->isreset
= 1;
339 if (src_in
->is_client
) {
340 mutex_unlock(&(src_in
->rcv_lock
));
341 mutex_unlock(&(src_in
->reversedir
->rcv_lock
));
343 mutex_unlock(&(src_in
->reversedir
->rcv_lock
));
344 mutex_unlock(&(src_in
->rcv_lock
));
350 kref_put(&(src_in
->ref
), free_conn
);
353 static void parse_connid_unknown(struct neighbor
*nb
, struct sk_buff
*skb
)
355 __u32 conn_id
= pull_u32(skb
, 1);
356 struct conn
*trgt_out
= get_conn_reverse(nb
, conn_id
);
360 mutex_lock(&(trgt_out
->rcv_lock
));
362 if (unlikely(trgt_out
->targettype
!= TARGET_OUT
))
364 if (unlikely((trgt_out
->target
.out
.nb
!= nb
)))
366 if (unlikely((trgt_out
->target
.out
.conn_id
!= conn_id
)))
369 if (trgt_out
->isreset
== 0)
370 trgt_out
->isreset
= 1;
372 mutex_unlock(&(trgt_out
->rcv_lock
));
374 reset_conn(trgt_out
);
378 mutex_unlock(&(trgt_out
->rcv_lock
));
380 kref_put(&(trgt_out
->ref
), free_conn
);
383 static void kernel_packet2(struct neighbor
*nb
, struct sk_buff
*skb
,
396 __u8
*codeptr
= cor_pull_skb(skb
, 1);
408 cookie
= pull_u32(skb
, 0);
409 send_pong(nb
, cookie
);
412 cookie
= pull_u32(skb
, 0);
413 respdelay
= pull_u32(skb
, 1);
414 ping_resp(nb
, cookie
, respdelay
);
418 seqno2
= pull_u32(skb
, 1);
419 kern_ack_rcvd(nb
, seqno2
);
422 parse_ack_conn(nb
, skb
);
426 parse_connect(nb
, skb
);
429 case KP_CONNECT_SUCCESS
:
430 parse_conn_success(nb
, skb
);
434 parse_conndata(nb
, skb
);
437 parse_reset(nb
, skb
);
440 case KP_CONNID_UNKNOWN
:
441 parse_connid_unknown(nb
, skb
);
444 case KP_SET_MAX_CMSG_DELAY
:
445 max_cmsg_dly
= pull_u32(skb
, 1);
446 if (((__u64
) max_cmsg_dly
) * 1000 > ((__u64
)
447 (max_cmsg_dly
* 1000)))
448 max_cmsg_dly
= 400000000;
451 atomic_set(&(nb
->max_remote_cmsg_delay
), max_cmsg_dly
);
460 send_ack(nb
, seqno1
);
463 void kernel_packet(struct neighbor
*nb
, struct sk_buff
*skb
, __u32 seqno
)
465 struct sk_buff
*skb2
= skb_clone(skb
, __GFP_DMA
| GFP_KERNEL
);
468 __u8
*codeptr
= cor_pull_skb(skb2
, 1);
483 if (cor_pull_skb(skb2
, 4) == 0)
487 if (cor_pull_skb(skb2
, 8) == 0)
491 if (cor_pull_skb(skb2
, 4) == 0)
495 if (cor_pull_skb(skb2
, 4) == 0)
497 flags
= cor_pull_skb(skb2
, 1);
500 if (cor_pull_skb(skb2
, ack_conn_len(*flags
)) == 0)
504 if (cor_pull_skb(skb2
, 11) == 0)
507 case KP_CONNECT_SUCCESS
:
508 if (cor_pull_skb(skb2
, 15) == 0)
512 if (cor_pull_skb(skb2
, 8) == 0)
514 lengthptr
= cor_pull_skb(skb2
, 2);
517 length
= ntohs(*((__u16
*)lengthptr
));
518 if (cor_pull_skb(skb2
, length
) == 0)
522 case KP_CONNID_UNKNOWN
:
523 if (cor_pull_skb(skb2
, 4) == 0)
526 case KP_SET_MAX_CMSG_DELAY
:
527 if (cor_pull_skb(skb2
, 4) == 0)
535 kernel_packet2(nb
, skb
, seqno
);
543 MODULE_LICENSE("GPL");