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 /* not used, avoid compiler warning
67 static __u16 pull_u16(struct sk_buff *skb, int convbo)
69 char *ptr = cor_pull_skb(skb, 2);
75 ((char *)&ret)[0] = ptr[0];
76 ((char *)&ret)[1] = ptr[1];
79 return be16_to_cpu(ret);
83 static __u8
pull_u8(struct sk_buff
*skb
)
85 char *ptr
= cor_pull_skb(skb
, 1);
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
;
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();
109 send_reset_conn(cm
, nb
, conn_id
);
113 rconn
->target
.out
.conn_id
= pull_u32(skb
, 1);
115 drain_ooo_queue(sconn
);
118 static void parse_conn_failed(struct neighbor
*nb
, struct sk_buff
*skb
,
119 __u8 code
, struct conn
*rconn
)
125 static void parse_reset(struct neighbor
*nb
, struct sk_buff
*skb
,
126 __u8 code
, struct conn
*rconn
)
132 static void conn_cmd(struct neighbor
*nb
, struct sk_buff
*skb
, __u8 code
,
133 void (*parsefunc
)(struct neighbor
*nb
, struct sk_buff
*skb
,
134 __u8 code
, struct conn
*rconn
))
136 __u32 conn_id
= pull_u32(skb
, 1);
137 struct conn
*rconn
= get_conn(conn_id
);
139 if (unlikely(rconn
== 0))
142 BUG_ON(SOURCE_IN
!= rconn
->sourcetype
);
143 BUG_ON(0 == rconn
->reversedir
);
145 if (unlikely(rconn
->source
.in
.nb
!= nb
))
148 parsefunc(nb
, skb
, code
, rconn
);
152 #warning todo reset backwards
158 static void parse_conndata(struct neighbor
*nb
, struct sk_buff
*skb
)
160 __u32 conn_id
= pull_u32(skb
, 1);
161 __u32 seqno
= pull_u32(skb
, 1);
162 __u32 datalength
= pull_u32(skb
, 1);
163 char *data
= cor_pull_skb(skb
, datalength
);
167 conn_rcv_buildskb(data
, datalength
, conn_id
, seqno
);
170 static void parse_connect(struct neighbor
*nb
, struct sk_buff
*skb
)
173 __u32 conn_id
= pull_u32(skb
, 1);
174 struct control_msg_out
*cm
= alloc_control_msg();
176 if (unlikely(cm
== 0))
179 rconn
= alloc_conn(GFP_KERNEL
);
181 if (unlikely(rconn
== 0))
184 if (conn_init_out(rconn
->reversedir
, nb
)) {
187 rconn
->target
.out
.conn_id
= conn_id
;
189 send_connect_success(cm
, rconn
);
191 send_connect_failed_temp(cm
, nb
, conn_id
);
195 static void kernel_packet2(struct neighbor
*nb
, struct sk_buff
*skb
,
198 struct control_msg_out
*cm
= alloc_control_msg();
201 if (unlikely(cm
== 0))
208 __u8 code
= pull_u8(skb
);
214 conn_id
= pull_u32(skb
, 0);
215 seqno
= pull_u32(skb
, 0);
216 ack_received(nb
, conn_id
, seqno
, 0);
219 conn_id
= pull_u32(skb
, 0);
220 seqno
= pull_u32(skb
, 0);
221 ack_received(nb
, conn_id
, seqno
, 1);
224 conn_cmd(nb
, skb
, code
, parse_speed
);
227 parse_connect(nb
, skb
);
229 case KP_CONNECT_SUCCESS
:
230 conn_cmd(nb
, skb
, code
, parse_conn_success
);
232 case KP_CONNECT_FAILED_TEMP
:
233 case KP_CONNECT_FAILED_PERM
:
234 conn_cmd(nb
, skb
, code
, parse_conn_failed
);
237 parse_conndata(nb
, skb
);
240 #warning todo is next packet?
241 #warning todo move to next packet
242 packet_id = pull_u32(skb);
243 struc packet_id *pid = search_packet_id(packet_id);
244 if (code == KP_FLUSH_CONN_BUF)
245 #warning todo offset, timeout
246 flush(pid->conn, 0, 10);
247 else if (code == KP_CONN_DATA) {
249 //skb_trim(skb, len);
250 } else if (code == KP_CONN_EOF)
251 #warning todo timeout
253 else if (code == KP_CONN_RESET_FW)
259 conn_cmd(nb
, skb
, code
, parse_reset
);
267 send_ack(cm
, nb
, 0, seqno
);
269 free_control_msg(cm
);
272 void kernel_packet(struct neighbor
*nb
, struct sk_buff
*skb
, __u32 seqno
)
274 struct sk_buff
*skb2
= skb_clone(skb
, __GFP_DMA
| GFP_KERNEL
);
277 __u8
*codeptr
= cor_pull_skb(skb2
, 1);
291 if (cor_pull_skb(skb2
, 4) == 0)
296 if (cor_pull_skb(skb2
, 5) == 0)
299 case KP_CONNECT_SUCCESS
:
300 if (cor_pull_skb(skb2
, 4) == 0)
303 case KP_CONNECT_FAILED_TEMP
:
304 case KP_CONNECT_FAILED_PERM
:
305 if (cor_pull_skb(skb2
, 4) == 0)
309 if (cor_pull_skb(skb2
, 4) == 0)
311 lengthptr
= cor_pull_skb(skb2
, 4);
314 length
= ntohl(*((__u32
*)lengthptr
));
315 if (cor_pull_skb(skb
, length
) == 0)
319 if (cor_pull_skb(skb2
, 4) == 0)
327 kernel_packet2(nb
, skb
, seqno
);