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 used, avoid compiler warning
26 * static __u64 pull_u64(struct sk_buff *skb, int convbo)
28 char *ptr = cor_pull_skb(skb, 8);
34 ((char *)&ret)[0] = ptr[0];
35 ((char *)&ret)[1] = ptr[1];
36 ((char *)&ret)[2] = ptr[2];
37 ((char *)&ret)[3] = ptr[3];
38 ((char *)&ret)[4] = ptr[4];
39 ((char *)&ret)[5] = ptr[5];
40 ((char *)&ret)[6] = ptr[6];
41 ((char *)&ret)[7] = ptr[7];
44 return be64_to_cpu(ret);
48 static __u32
pull_u32(struct sk_buff
*skb
, int convbo
)
50 char *ptr
= cor_pull_skb(skb
, 4);
56 ((char *)&ret
)[0] = ptr
[0];
57 ((char *)&ret
)[1] = ptr
[1];
58 ((char *)&ret
)[2] = ptr
[2];
59 ((char *)&ret
)[3] = ptr
[3];
62 return be32_to_cpu(ret
);
66 static __u16
pull_u16(struct sk_buff
*skb
, int convbo
)
68 char *ptr
= cor_pull_skb(skb
, 2);
74 ((char *)&ret
)[0] = ptr
[0];
75 ((char *)&ret
)[1] = ptr
[1];
78 return be16_to_cpu(ret
);
82 static __u8
pull_u8(struct sk_buff
*skb
)
84 char *ptr
= cor_pull_skb(skb
, 1);
89 static void discard_ack_conn(struct neighbor
*nb
, struct sk_buff
*skb
)
91 pull_u32(skb
, 1); /* seqno */
92 pull_u8(skb
); /* window */
96 static void parse_ack_conn(struct neighbor
*nb
, struct sk_buff
*skb
,
97 __u32 kpacket_seqno
, struct conn
*rconn
)
99 __u32 seqno
= pull_u32(skb
, 1);
100 __u8 window
= pull_u8(skb
);
102 conn_ack_rcvd(kpacket_seqno
, rconn
->reversedir
, seqno
, window
, 0, 0);
105 static void discard_ack_conn_ooo(struct neighbor
*nb
, struct sk_buff
*skb
)
107 pull_u32(skb
, 1); /* seqno */
108 pull_u8(skb
); /* seqno */
109 pull_u32(skb
, 1); /* seqno */
110 pull_u32(skb
, 1); /* seqno */
113 static void parse_ack_conn_ooo(struct neighbor
*nb
, struct sk_buff
*skb
,
114 __u32 kpacket_seqno
, struct conn
*rconn
)
116 __u32 seqno
= pull_u32(skb
, 1);
117 __u8 window
= pull_u8(skb
);
118 __u32 seqno_ooo
= pull_u32(skb
, 1);
119 __u32 length
= pull_u32(skb
, 1);
121 conn_ack_rcvd(kpacket_seqno
, rconn
->reversedir
, seqno
, window
,
125 static void discard_conn_success(struct neighbor
*nb
, struct sk_buff
*skb
)
127 __u32 conn_id
= pull_u32(skb
, 1);
128 struct control_msg_out
*cm
= alloc_control_msg();
130 send_reset_conn(cm
, nb
, conn_id
);
133 static void parse_conn_success(struct neighbor
*nb
, struct sk_buff
*skb
,
134 __u32 seqno
, struct conn
*rconn
)
136 struct conn
*sconn
= rconn
->reversedir
;
138 __u32 conn_id
= pull_u32(skb
, 1);
142 if (unlikely(unlikely(sconn
->targettype
!= TARGET_OUT
) ||
143 unlikely(sconn
->target
.out
.nb
!= nb
) ||
144 unlikely(sconn
->target
.out
.conn_id
!= 0))) {
145 struct control_msg_out
*cm
= alloc_control_msg();
147 send_reset_conn(cm
, nb
, conn_id
);
151 mutex_lock(&(sconn
->rcv_lock
));
152 sconn
->target
.out
.conn_id
= conn_id
;
154 mutex_unlock(&(sconn
->rcv_lock
));
157 static void parse_reset(struct neighbor
*nb
, struct sk_buff
*skb
, __u32 seqno
,
160 atomic_cmpxchg(&(rconn
->reversedir
->isreset
), 0, 1);
164 static void conn_cmd(struct neighbor
*nb
, struct sk_buff
*skb
, __u32 seqno
,
165 __u8 code
, void (*parsefunc
)(struct neighbor
*nb
,
166 struct sk_buff
*skb
, __u32 seqno
, struct conn
*rconn
),
167 void (*readdiscardfunc
)(struct neighbor
*nb
,
168 struct sk_buff
*skb
))
170 __u32 conn_id
= pull_u32(skb
, 1);
171 struct conn
*rconn
= get_conn(conn_id
);
173 if (unlikely(rconn
== 0))
176 BUG_ON(SOURCE_IN
!= rconn
->sourcetype
);
177 BUG_ON(0 == rconn
->reversedir
);
179 if (unlikely(rconn
->source
.in
.nb
!= nb
))
182 parsefunc(nb
, skb
, seqno
, rconn
);
185 #warning send connid_unknown
186 if (readdiscardfunc
!= 0)
187 readdiscardfunc(nb
, skb
);
189 if (likely(rconn
!= 0))
190 kref_put(&(rconn
->ref
), free_conn
);
193 static void parse_conndata(struct neighbor
*nb
, struct sk_buff
*skb
)
195 __u32 conn_id
= pull_u32(skb
, 1);
196 __u32 seqno
= pull_u32(skb
, 1);
197 __u16 datalength
= pull_u16(skb
, 1);
198 char *data
= cor_pull_skb(skb
, datalength
);
202 conn_rcv_buildskb(data
, datalength
, conn_id
, seqno
);
205 static void parse_connect(struct neighbor
*nb
, struct sk_buff
*skb
)
208 __u32 conn_id
= pull_u32(skb
, 1);
209 struct control_msg_out
*cm
= alloc_control_msg();
211 if (unlikely(cm
== 0))
214 rconn
= alloc_conn(GFP_KERNEL
);
216 if (unlikely(rconn
== 0))
219 if (unlikely(conn_init_out(rconn
->reversedir
, nb
)))
222 rconn
->reversedir
->target
.out
.conn_id
= conn_id
;
224 send_connect_success(cm
, nb
, rconn
->reversedir
->target
.out
.conn_id
,
225 rconn
->source
.in
.conn_id
);
229 send_reset_conn(cm
, nb
, conn_id
);
233 #warning todo set window on connect/connect_success
234 static void kernel_packet2(struct neighbor
*nb
, struct sk_buff
*skb
,
237 struct control_msg_out
*cm
= alloc_control_msg();
240 if (unlikely(cm
== 0))
244 struct control_msg_out
*cm_tmp
;
253 __u8
*codeptr
= cor_pull_skb(skb
, 1);
265 cookie
= pull_u32(skb
, 0);
266 cm_tmp
= alloc_control_msg();
267 if (likely(cm
!= 0)) {
268 send_pong(cm_tmp
, nb
, cookie
);
272 cookie
= pull_u32(skb
, 0);
273 respdelay
= pull_u32(skb
, 1);
274 ping_resp(nb
, cookie
, respdelay
);
278 seqno2
= pull_u32(skb
, 1);
279 kern_ack_rcvd(nb
, seqno2
);
282 conn_cmd(nb
, skb
, seqno1
, code
, parse_ack_conn
,
286 case KP_ACK_CONN_OOO
:
287 conn_cmd(nb
, skb
, seqno1
, code
, parse_ack_conn_ooo
,
288 discard_ack_conn_ooo
);
292 parse_connect(nb
, skb
);
295 case KP_CONNECT_SUCCESS
:
296 conn_cmd(nb
, skb
, seqno1
, code
, parse_conn_success
,
297 discard_conn_success
);
301 parse_conndata(nb
, skb
);
305 conn_cmd(nb
, skb
, seqno1
, code
, parse_reset
, 0);
308 case KP_CONNID_UNKNOWN
:
309 conn_id
= pull_u32(skb
, 1);
319 send_ack(cm
, nb
, seqno1
);
321 free_control_msg(cm
);
324 void kernel_packet(struct neighbor
*nb
, struct sk_buff
*skb
, __u32 seqno
)
326 struct sk_buff
*skb2
= skb_clone(skb
, __GFP_DMA
| GFP_KERNEL
);
329 __u8
*codeptr
= cor_pull_skb(skb2
, 1);
343 if (cor_pull_skb(skb2
, 4) == 0)
347 if (cor_pull_skb(skb2
, 8) == 0)
351 if (cor_pull_skb(skb2
, 4) == 0)
355 if (cor_pull_skb(skb2
, 9) == 0)
358 case KP_ACK_CONN_OOO
:
359 if (cor_pull_skb(skb2
, 17) == 0)
363 if (cor_pull_skb(skb2
, 4) == 0)
366 case KP_CONNECT_SUCCESS
:
367 if (cor_pull_skb(skb2
, 8) == 0)
371 if (cor_pull_skb(skb2
, 8) == 0)
373 lengthptr
= cor_pull_skb(skb2
, 2);
376 length
= ntohs(*((__u16
*)lengthptr
));
377 if (cor_pull_skb(skb2
, length
) == 0)
381 case KP_CONNID_UNKNOWN
:
382 if (cor_pull_skb(skb2
, 4) == 0)
390 kernel_packet2(nb
, skb
, seqno
);