kernel packet sending bugfixes
[cor_2_6_31.git] / net / cor / kpacket_parse.c
blob85f49943dfd41b8c2fda395ad1026842128ec2bd
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 /* not used, avoid compiler warning
67 static __u16 pull_u16(struct sk_buff *skb, int convbo)
69 char *ptr = cor_pull_skb(skb, 2);
71 __u16 ret = 0;
73 BUG_ON(0 == ptr);
75 ((char *)&ret)[0] = ptr[0];
76 ((char *)&ret)[1] = ptr[1];
78 if (convbo)
79 return be16_to_cpu(ret);
80 return ret;
81 } */
83 static __u8 pull_u8(struct sk_buff *skb)
85 char *ptr = cor_pull_skb(skb, 1);
86 BUG_ON(0 == ptr);
87 return *ptr;
90 #warning todo
91 static void parse_speed(struct neighbor *nb, struct sk_buff *skb,
92 __u8 code, struct conn *rconn)
96 static void parse_conn_success(struct neighbor *nb, struct sk_buff *skb,
97 __u8 code, struct conn *rconn)
99 struct conn *sconn = rconn->reversedir;
101 BUG_ON(sconn == 0);
103 if (unlikely(unlikely(TARGET_OUT != sconn->targettype) ||
104 unlikely(nb != sconn->target.out.nb) ||
105 unlikely(rconn->target.out.conn_id != 0))) {
106 int conn_id = pull_u32(skb, 1);
107 struct control_msg_out *cm = alloc_control_msg();
108 if (likely(cm != 0))
109 send_reset_conn(cm, nb, conn_id);
110 return;
113 mutex_lock(&(sconn->rcv_lock));
114 sconn->target.out.conn_id = pull_u32(skb, 1);
115 flush_out(sconn);
116 mutex_unlock(&(sconn->rcv_lock));
119 static void parse_conn_failed(struct neighbor *nb, struct sk_buff *skb,
120 __u8 code, struct conn *rconn)
122 rconn->isreset = 1;
123 reset_conn(rconn);
126 static void parse_reset(struct neighbor *nb, struct sk_buff *skb,
127 __u8 code, struct conn *rconn)
129 rconn->isreset = 1;
130 reset_conn(rconn);
133 static void conn_cmd(struct neighbor *nb, struct sk_buff *skb, __u8 code,
134 void (*parsefunc)(struct neighbor *nb, struct sk_buff *skb,
135 __u8 code, struct conn *rconn))
137 __u32 conn_id = pull_u32(skb, 1);
138 struct conn *rconn = get_conn(conn_id);
140 if (unlikely(rconn == 0))
141 goto reset;
143 BUG_ON(SOURCE_IN != rconn->sourcetype);
144 BUG_ON(0 == rconn->reversedir);
146 if (unlikely(rconn->source.in.nb != nb))
147 goto reset;
149 parsefunc(nb, skb, code, rconn);
151 if (0) {
152 reset:
153 #warning todo reset backwards
154 return;
159 static void parse_conndata(struct neighbor *nb, struct sk_buff *skb)
161 __u32 conn_id = pull_u32(skb, 1);
162 __u32 seqno = pull_u32(skb, 1);
163 __u32 datalength = pull_u32(skb, 1);
164 char *data = cor_pull_skb(skb, datalength);
166 BUG_ON(data == 0);
168 conn_rcv_buildskb(data, datalength, conn_id, seqno);
171 static void parse_connect(struct neighbor *nb, struct sk_buff *skb)
173 struct conn *rconn;
174 __u32 conn_id = pull_u32(skb, 1);
175 struct control_msg_out *cm = alloc_control_msg();
177 if (unlikely(cm == 0))
178 return;
180 rconn = alloc_conn(GFP_KERNEL);
182 if (unlikely(rconn == 0))
183 goto err;
185 if (conn_init_out(rconn->reversedir, nb)) {
186 goto err;
188 rconn->target.out.conn_id = conn_id;
190 send_connect_success(cm, rconn);
191 err:
192 send_connect_failed_temp(cm, nb, conn_id);
193 return;
196 static void kernel_packet2(struct neighbor *nb, struct sk_buff *skb,
197 __u32 seqno)
199 struct control_msg_out *cm = alloc_control_msg();
200 int ack = 0;
202 if (unlikely(cm == 0))
203 return;
205 while (1) {
206 __u32 conn_id;
207 __u32 seqno;
209 __u8 code = pull_u8(skb);
211 switch (code) {
212 case KP_PADDING:
213 break;
214 case KP_ACK:
215 conn_id = pull_u32(skb, 0);
216 seqno = pull_u32(skb, 0);
217 ack_received(nb, conn_id, seqno, 0);
218 break;
219 case KP_NACK:
220 conn_id = pull_u32(skb, 0);
221 seqno = pull_u32(skb, 0);
222 ack_received(nb, conn_id, seqno, 1);
223 break;
224 case KP_SPEED:
225 conn_cmd(nb, skb, code, parse_speed);
226 break;
227 case KP_CONNECT:
228 parse_connect(nb, skb);
229 break;
230 case KP_CONNECT_SUCCESS:
231 conn_cmd(nb, skb, code, parse_conn_success);
232 break;
233 case KP_CONNECT_FAILED_TEMP:
234 case KP_CONNECT_FAILED_PERM:
235 conn_cmd(nb, skb, code, parse_conn_failed);
236 break;
237 case KP_CONN_DATA:
238 parse_conndata(nb, skb);
239 break;
241 #warning todo is next packet?
242 #warning todo move to next packet
243 packet_id = pull_u32(skb);
244 struc packet_id *pid = search_packet_id(packet_id);
245 if (code == KP_FLUSH_CONN_BUF)
246 #warning todo offset, timeout
247 flush(pid->conn, 0, 10);
248 else if (code == KP_CONN_DATA) {
249 #warning todo
250 //skb_trim(skb, len);
251 } else if (code == KP_CONN_EOF)
252 #warning todo timeout
253 eof(pid->conn, 10);
254 else if (code == KP_CONN_RESET_FW)
255 reset(pid->conn)
256 else
257 BUG();
258 break;*/
259 case KP_RESET_CONN:
260 conn_cmd(nb, skb, code, parse_reset);
261 break;
262 default:
263 BUG();
267 if (ack)
268 send_ack(cm, nb, 0, seqno);
269 else
270 free_control_msg(cm);
273 void kernel_packet(struct neighbor *nb, struct sk_buff *skb, __u32 seqno)
275 struct sk_buff *skb2 = skb_clone(skb, __GFP_DMA | GFP_KERNEL);
277 while (1) {
278 __u8 *codeptr = cor_pull_skb(skb2, 1);
279 __u8 code;
281 char *lengthptr;
282 __u32 length;
284 if (codeptr == 0)
285 goto discard;
286 code = *codeptr;
287 switch (code) {
288 case KP_PADDING:
289 break;
290 case KP_ACK:
291 case KP_NACK:
292 if (cor_pull_skb(skb2, 4) == 0)
293 goto discard;
294 break;
295 case KP_SPEED:
296 case KP_CONNECT:
297 if (cor_pull_skb(skb2, 5) == 0)
298 goto discard;
299 break;
300 case KP_CONNECT_SUCCESS:
301 if (cor_pull_skb(skb2, 4) == 0)
302 goto discard;
303 break;
304 case KP_CONNECT_FAILED_TEMP:
305 case KP_CONNECT_FAILED_PERM:
306 if (cor_pull_skb(skb2, 4) == 0)
307 goto discard;
308 break;
309 case KP_CONN_DATA:
310 if (cor_pull_skb(skb2, 4) == 0)
311 goto discard;
312 lengthptr = cor_pull_skb(skb2, 4);
313 if (lengthptr == 0)
314 goto discard;
315 length = ntohl(*((__u32 *)lengthptr));
316 if (cor_pull_skb(skb, length) == 0)
317 goto discard;
318 break;
319 case KP_RESET_CONN:
320 if (cor_pull_skb(skb2, 4) == 0)
321 goto discard;
322 break;
323 default:
324 goto discard;
327 kfree_skb(skb2);
328 kernel_packet2(nb, skb, seqno);
329 kfree_skb(skb);
330 return;
331 discard:
332 kfree_skb(skb2);
333 kfree_skb(skb);