kernel packet ack gen bugfix, empty retransmit queue on conn reset
[cor_2_6_31.git] / net / cor / kpacket_parse.c
blobcddf8ec4c46339d4c371183c0719c8f7b1b7ffce
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 used, avoid compiler warning
26 * static __u64 pull_u64(struct sk_buff *skb, int convbo)
28 char *ptr = cor_pull_skb(skb, 8);
30 __u64 ret = 0;
32 BUG_ON(0 == ptr);
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];
43 if (convbo)
44 return be64_to_cpu(ret);
45 return ret;
46 } */
48 static __u32 pull_u32(struct sk_buff *skb, int convbo)
50 char *ptr = cor_pull_skb(skb, 4);
52 __u32 ret = 0;
54 BUG_ON(0 == ptr);
56 ((char *)&ret)[0] = ptr[0];
57 ((char *)&ret)[1] = ptr[1];
58 ((char *)&ret)[2] = ptr[2];
59 ((char *)&ret)[3] = ptr[3];
61 if (convbo)
62 return be32_to_cpu(ret);
63 return ret;
66 static __u16 pull_u16(struct sk_buff *skb, int convbo)
68 char *ptr = cor_pull_skb(skb, 2);
70 __u16 ret = 0;
72 BUG_ON(0 == ptr);
74 ((char *)&ret)[0] = ptr[0];
75 ((char *)&ret)[1] = ptr[1];
77 if (convbo)
78 return be16_to_cpu(ret);
79 return ret;
82 static __u8 pull_u8(struct sk_buff *skb)
84 char *ptr = cor_pull_skb(skb, 1);
85 BUG_ON(0 == ptr);
86 return *ptr;
89 static void discard_ack_conn(struct neighbor *nb, struct sk_buff *skb)
91 pull_u32(skb, 1); /* seqno */
92 pull_u8(skb); /* window */
95 #warning todo
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,
122 seqno_ooo, length);
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();
129 if (likely(cm != 0))
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);
140 BUG_ON(sconn == 0);
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();
146 if (likely(cm != 0))
147 send_reset_conn(cm, nb, conn_id);
148 return;
151 mutex_lock(&(sconn->rcv_lock));
152 sconn->target.out.conn_id = conn_id;
153 flush_out(sconn);
154 mutex_unlock(&(sconn->rcv_lock));
157 static void parse_reset(struct neighbor *nb, struct sk_buff *skb, __u32 seqno,
158 struct conn *rconn)
160 atomic_cmpxchg(&(rconn->reversedir->isreset), 0, 1);
161 reset_conn(rconn);
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))
174 goto err;
176 BUG_ON(SOURCE_IN != rconn->sourcetype);
177 BUG_ON(0 == rconn->reversedir);
179 if (unlikely(rconn->source.in.nb != nb))
180 goto err;
182 parsefunc(nb, skb, seqno, rconn);
183 if (0) {
184 err:
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);
200 BUG_ON(data == 0);
202 conn_rcv_buildskb(data, datalength, conn_id, seqno);
205 static void parse_connect(struct neighbor *nb, struct sk_buff *skb)
207 struct conn *rconn;
208 __u32 conn_id = pull_u32(skb, 1);
209 struct control_msg_out *cm = alloc_control_msg();
211 if (unlikely(cm == 0))
212 return;
214 rconn = alloc_conn(GFP_KERNEL);
216 if (unlikely(rconn == 0))
217 goto err;
219 if (unlikely(conn_init_out(rconn->reversedir, nb)))
220 goto err;
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);
227 if (0) {
228 err:
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,
235 __u32 seqno1)
237 struct control_msg_out *cm = alloc_control_msg();
238 int ack = 0;
240 if (unlikely(cm == 0))
241 return;
243 while (1) {
244 struct control_msg_out *cm_tmp;
246 __u32 seqno2;
248 __u32 conn_id;
250 __u32 cookie;
251 __u32 respdelay;
253 __u8 *codeptr = cor_pull_skb(skb, 1);
254 __u8 code;
256 if (codeptr == 0)
257 break;
259 code = *codeptr;
261 switch (code) {
262 case KP_PADDING:
263 break;
264 case KP_PING:
265 cookie = pull_u32(skb, 0);
266 cm_tmp = alloc_control_msg();
267 if (likely(cm != 0)) {
268 send_pong(cm_tmp, nb, cookie);
270 break;
271 case KP_PONG:
272 cookie = pull_u32(skb, 0);
273 respdelay = pull_u32(skb, 1);
274 ping_resp(nb, cookie, respdelay);
275 ack = 1;
276 break;
277 case KP_ACK:
278 seqno2 = pull_u32(skb, 1);
279 kern_ack_rcvd(nb, seqno2);
280 break;
281 case KP_ACK_CONN:
282 conn_cmd(nb, skb, seqno1, code, parse_ack_conn,
283 discard_ack_conn);
284 ack = 1;
285 break;
286 case KP_ACK_CONN_OOO:
287 conn_cmd(nb, skb, seqno1, code, parse_ack_conn_ooo,
288 discard_ack_conn_ooo);
289 ack = 1;
290 break;
291 case KP_CONNECT:
292 parse_connect(nb, skb);
293 ack = 1;
294 break;
295 case KP_CONNECT_SUCCESS:
296 conn_cmd(nb, skb, seqno1, code, parse_conn_success,
297 discard_conn_success);
298 ack = 1;
299 break;
300 case KP_CONN_DATA:
301 parse_conndata(nb, skb);
302 ack = 1;
303 break;
304 case KP_RESET_CONN:
305 conn_cmd(nb, skb, seqno1, code, parse_reset, 0);
306 ack = 1;
307 break;
308 case KP_CONNID_UNKNOWN:
309 conn_id = pull_u32(skb, 1);
310 #warning todo
311 ack = 1;
312 break;
313 default:
314 BUG();
318 if (ack)
319 send_ack(cm, nb, seqno1);
320 else
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);
328 while (1) {
329 __u8 *codeptr = cor_pull_skb(skb2, 1);
330 __u8 code;
332 char *lengthptr;
333 __u32 length;
335 if (codeptr == 0)
336 break;
337 code = *codeptr;
339 switch (code) {
340 case KP_PADDING:
341 break;
342 case KP_PING:
343 if (cor_pull_skb(skb2, 4) == 0)
344 goto discard;
345 break;
346 case KP_PONG:
347 if (cor_pull_skb(skb2, 8) == 0)
348 goto discard;
349 break;
350 case KP_ACK:
351 if (cor_pull_skb(skb2, 4) == 0)
352 goto discard;
353 break;
354 case KP_ACK_CONN:
355 if (cor_pull_skb(skb2, 9) == 0)
356 goto discard;
357 break;
358 case KP_ACK_CONN_OOO:
359 if (cor_pull_skb(skb2, 17) == 0)
360 goto discard;
361 break;
362 case KP_CONNECT:
363 if (cor_pull_skb(skb2, 4) == 0)
364 goto discard;
365 break;
366 case KP_CONNECT_SUCCESS:
367 if (cor_pull_skb(skb2, 8) == 0)
368 goto discard;
369 break;
370 case KP_CONN_DATA:
371 if (cor_pull_skb(skb2, 8) == 0)
372 goto discard;
373 lengthptr = cor_pull_skb(skb2, 2);
374 if (lengthptr == 0)
375 goto discard;
376 length = ntohs(*((__u16 *)lengthptr));
377 if (cor_pull_skb(skb2, length) == 0)
378 goto discard;
379 break;
380 case KP_RESET_CONN:
381 case KP_CONNID_UNKNOWN:
382 if (cor_pull_skb(skb2, 4) == 0)
383 goto discard;
384 break;
385 default:
386 goto discard;
389 kfree_skb(skb2);
390 kernel_packet2(nb, skb, seqno);
391 kfree_skb(skb);
392 return;
393 discard:
394 kfree_skb(skb2);
395 kfree_skb(skb);