kernel packet gen/parsing bugfixes and cleanup
[cor_2_6_31.git] / net / cor / kpacket_gen.c
blob2ca6d647cf2340e96f814d947928a7f032c83f6e
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 sent over the network - internal meaning only */
26 #define MSGTYPE_ACK 1
27 #define MSGTYPE_CONNECT 2
28 #define MSGTYPE_CONNECT_SUCCESS 3
29 #define MSGTYPE_RESET_CONN 5
30 #define MSGTYPE_CONNDATA 6
33 * lh must be first
35 struct control_msg_out{
36 struct list_head lh;
37 struct neighbor *nb;
39 __u32 length;
41 __u8 type;
42 union{
43 struct{
44 __u32 conn_id;
45 __u32 seqno;
46 }ack;
48 struct{
49 __u32 conn_id;
50 }connect;
52 struct{
53 __u32 rcvd_conn_id;
54 __u32 gen_conn_id;
55 }connect_success;
57 struct{
58 __u32 conn_id;
59 }reset;
61 struct{
62 __u32 conn_id;
63 }reset_bw;
65 struct conn_data{
66 __u32 conn_id;
67 __u32 seqno;
68 char *data_orig;
69 char *data;
70 __u32 datalen;
71 }conn_data;
72 }msg;
75 struct control_msg_out *alloc_control_msg(void)
77 return kmalloc(sizeof(struct control_msg_out), GFP_KERNEL);
80 void free_control_msg(struct control_msg_out *cm)
82 kfree(cm);
85 static int add_ack(struct sk_buff *skb, struct control_msg_out *cm,
86 int spaceleft)
88 char *dst;
90 if (spaceleft < 9)
91 return 0;
93 dst = skb_put(skb, 9);
94 BUG_ON(0 == dst);
96 dst[0] = KP_ACK;
97 put_u32(dst + 1, cm->msg.ack.conn_id, 1);
98 put_u32(dst + 5, cm->msg.ack.seqno, 1);
100 return 9;
103 static int add_connect(struct sk_buff *skb, struct control_msg_out *cm,
104 int spaceleft)
106 char *dst;
108 if (spaceleft < 5)
109 return 0;
111 dst = skb_put(skb, 5);
112 BUG_ON(0 == dst);
114 dst[0] = KP_CONNECT;
115 put_u32(dst + 1, cm->msg.connect.conn_id, 1);
117 return 5;
120 static int add_connect_success(struct sk_buff *skb, struct control_msg_out *cm,
121 int spaceleft)
123 char *dst;
125 if (spaceleft < 9)
126 return 0;
128 dst = skb_put(skb, 9);
129 BUG_ON(0 == dst);
131 dst[0] = KP_CONNECT_SUCCESS;
132 put_u32(dst + 1, cm->msg.connect_success.rcvd_conn_id, 1);
133 put_u32(dst + 5, cm->msg.connect_success.rcvd_conn_id, 1);
135 return 9;
138 static int add_reset_conn(struct sk_buff *skb, struct control_msg_out *cm,
139 int spaceleft)
141 char *dst;
143 if (spaceleft < 5)
144 return 0;
146 dst = skb_put(skb, 5);
147 BUG_ON(0 == dst);
149 dst[0] = KP_RESET_CONN;
150 put_u32(dst + 1, cm->msg.reset.conn_id, 1);
152 return 5;
155 static int add_conndata(struct sk_buff *skb, struct control_msg_out *cm,
156 int spaceleft)
158 char *dst;
160 int totallen = cm->msg.conn_data.datalen + 5;
161 int putlen = min(totallen, spaceleft);
163 if (spaceleft < 25 && totallen > 25)
164 return 0;
166 dst = skb_put(skb, putlen);
167 BUG_ON(0 == dst);
169 dst[0] = KP_RESET_CONN;
170 put_u32(dst + 1, cm->msg.conn_data.conn_id, 1);
171 put_u32(dst + 5, cm->msg.conn_data.seqno, 1);
173 memcpy(dst + 9, cm->msg.conn_data.data, putlen - 9);
174 cm->msg.conn_data.datalen -= (putlen - 9);
176 if (cm->msg.conn_data.datalen == 0) {
177 kfree(cm->msg.conn_data.data_orig);
178 free_control_msg(cm);
179 } else {
180 send_conndata(cm, cm->nb, cm->msg.conn_data.conn_id,
181 cm->msg.conn_data.seqno,
182 cm->msg.conn_data.data_orig,
183 cm->msg.conn_data.data,
184 cm->msg.conn_data.datalen);
187 return putlen;
191 static int add_message(struct sk_buff *skb, struct control_msg_out *cm,
192 int spaceleft)
194 int free = 1;
195 int rc;
196 switch (cm->type) {
197 case MSGTYPE_ACK:
198 rc = add_ack(skb, cm, spaceleft);
199 break;
200 case MSGTYPE_CONNECT:
201 rc = add_connect(skb, cm, spaceleft);
202 break;
203 case MSGTYPE_CONNECT_SUCCESS:
204 rc = add_connect_success(skb, cm, spaceleft);
205 break;
206 case MSGTYPE_RESET_CONN:
207 rc = add_reset_conn(skb, cm, spaceleft);
208 break;
209 case MSGTYPE_CONNDATA:
210 free = 0;
211 rc = add_conndata(skb, cm, spaceleft);
212 break;
213 default:
214 BUG();
216 if (free)
217 free_control_msg(cm);
218 return rc;
222 static void padding(struct sk_buff *skb, int length)
224 char *dst = skb_put(skb, length);
225 BUG_ON(0 == dst);
226 memset(dst, KP_PADDING, length);
229 static void _send_messages(struct neighbor *nb, struct sk_buff *skb,
230 int spaceleft)
232 int length = 0;
234 printk(KERN_ERR "send_msgs11");
236 while (!list_empty((struct list_head *) &(nb->control_msgs_out))) {
237 int rc;
239 struct control_msg_out *cm = (struct control_msg_out *)
240 nb->control_msgs_out.next;
241 list_del((struct list_head *) cm);
243 rc = add_message(skb, cm, spaceleft - length);
244 if (0 == rc)
245 goto send_packet;
246 length += cm->length;
249 send_packet:
250 printk(KERN_ERR "send_msgs12");
251 nb->length -= length;
253 padding(skb, spaceleft - length);
254 send_packet(skb, nb);
257 static void send_messages(struct neighbor *nb, int allmsgs)
259 int targetmss = mss(nb);
261 BUG_ON(list_empty(&(nb->control_msgs_out)) && (nb->length != 0));
262 BUG_ON((list_empty(&(nb->control_msgs_out)) == 0) && (nb->length == 0));
264 while (likely(list_empty(&(nb->control_msgs_out)) == 0) &&
265 (nb->length >= targetmss || allmsgs)) {
266 struct sk_buff *skb;
267 int size = targetmss;
268 if (size > nb->length)
269 size = nb->length;
270 skb = create_packet_kernel(nb, size, GFP_KERNEL);
271 if (skb == 0) {
272 printk(KERN_ERR "cor: send_messages: cannot allocate "
273 "skb (out of memory?)");
274 break;
276 _send_messages(nb, skb, size);
279 BUG_ON(nb->length < 0);
282 static void controlmsg_timerfunc(struct work_struct *work)
284 struct neighbor *nb = container_of(to_delayed_work(work),
285 struct neighbor, cmsg_timer);
286 __u64 jiffies = get_jiffies_64();
288 mutex_lock(&(nb->cmsg_lock));
290 if (nb->timeout > jiffies) {
291 INIT_DELAYED_WORK(&(nb->cmsg_timer), controlmsg_timerfunc);
292 schedule_delayed_work(&(nb->cmsg_timer), nb->timeout - jiffies);
293 goto out;
296 send_messages(nb, 1);
297 schedule_controlmsg_timerfunc(nb);
299 out:
300 mutex_unlock(&(nb->cmsg_lock));
303 void schedule_controlmsg_timerfunc(struct neighbor *nb)
305 int target_delay_ms = 1000;
306 int target_delay_jiffies = msecs_to_jiffies(target_delay_ms);
307 __u64 jiffies = get_jiffies_64();
308 long long delay;
310 nb->timeout += target_delay_jiffies;
312 delay = nb->timeout - jiffies;
313 if (delay < 0) {
314 delay = 0;
315 nb->timeout = jiffies;
318 INIT_DELAYED_WORK(&(nb->cmsg_timer), controlmsg_timerfunc);
319 schedule_delayed_work(&(nb->cmsg_timer), delay);
322 static void add_control_msg(struct control_msg_out *msg, struct neighbor *nb)
324 BUG_ON(msg == 0);
326 printk(KERN_ERR "add_msg %d", msg->type);
328 mutex_lock(&(nb->cmsg_lock));
330 printk(KERN_ERR "add1");
332 msg->nb = nb;
333 nb->length += msg->length;
334 list_add_tail((struct list_head *) msg,
335 (struct list_head *) &(nb->control_msgs_out));
337 if (unlikely(nb->length >= mss(nb)))
338 send_messages(nb, 0);
340 mutex_unlock(&(nb->cmsg_lock));
343 void send_reset_conn(struct control_msg_out *cm, struct neighbor *nb,
344 __u32 conn_id)
346 cm->type = MSGTYPE_RESET_CONN;
347 cm->msg.reset.conn_id = conn_id;
348 cm->length = 5;
349 add_control_msg(cm, nb);
352 void send_ack(struct control_msg_out *cm, struct neighbor *nb, __u32 conn_id,
353 __u32 seqno)
355 cm->type = MSGTYPE_ACK;
356 cm->msg.ack.conn_id = conn_id;
357 cm->msg.ack.seqno = seqno;
358 cm->length = 9;
359 add_control_msg(cm, nb);
362 void send_connect_success(struct control_msg_out *cm, struct neighbor *nb,
363 __u32 rcvd_conn_id, __u32 gen_conn_id)
365 cm->type = MSGTYPE_CONNECT_SUCCESS;
366 cm->msg.connect_success.rcvd_conn_id = rcvd_conn_id;
367 cm->msg.connect_success.gen_conn_id = gen_conn_id;
368 cm->length = 9;
369 add_control_msg(cm, nb);
372 void send_connect_nb(struct control_msg_out *cm, struct neighbor *nb,
373 __u32 conn_id)
375 cm->type = MSGTYPE_CONNECT;
376 cm->msg.connect.conn_id = conn_id;
377 cm->length = 5;
378 add_control_msg(cm, nb);
381 void send_conndata(struct control_msg_out *cm, struct neighbor *nb,
382 __u32 conn_id, __u32 seqno, char *data_orig, char *data,
383 __u32 datalen)
385 printk(KERN_ERR "send_conndata");
386 cm->type = MSGTYPE_CONNDATA;
387 cm->msg.conn_data.conn_id = conn_id;
388 cm->msg.conn_data.seqno = seqno;
389 cm->msg.conn_data.data_orig = data_orig;
390 cm->msg.conn_data.data = data;
391 cm->msg.conn_data.datalen = datalen;
392 cm->length = 9 + datalen;
393 add_control_msg(cm, nb);