matches_skb_connid_seqno bugfix on kernel packets, ref counter is_active is now gone...
[cor_2_6_31.git] / net / cor / kpacket_gen.c
blob803b29f147a006b12ac649bfa4dc893f09ca4322
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 4
30 #define MSGTYPE_CONNDATA 5
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 while (!list_empty((struct list_head *) &(nb->control_msgs_out))) {
235 int rc;
237 struct control_msg_out *cm = (struct control_msg_out *)
238 nb->control_msgs_out.next;
239 list_del((struct list_head *) cm);
241 rc = add_message(skb, cm, spaceleft - length);
242 if (0 == rc)
243 goto send_packet;
244 length += cm->length;
247 send_packet:
248 nb->length -= length;
250 padding(skb, spaceleft - length);
251 send_packet(skb, nb);
254 static void send_messages(struct neighbor *nb, int allmsgs)
256 int targetmss = mss(nb);
258 BUG_ON(list_empty(&(nb->control_msgs_out)) && (nb->length != 0));
259 BUG_ON((list_empty(&(nb->control_msgs_out)) == 0) && (nb->length == 0));
261 while (likely(list_empty(&(nb->control_msgs_out)) == 0) &&
262 (nb->length >= targetmss || allmsgs)) {
263 struct sk_buff *skb;
264 int size = targetmss;
265 if (size > nb->length)
266 size = nb->length;
267 skb = create_packet_kernel(nb, size, GFP_KERNEL);
268 if (skb == 0) {
269 printk(KERN_ERR "cor: send_messages: cannot allocate "
270 "skb (out of memory?)");
271 break;
273 _send_messages(nb, skb, size);
276 BUG_ON(nb->length < 0);
279 static void controlmsg_timerfunc(struct work_struct *work)
281 struct neighbor *nb = container_of(to_delayed_work(work),
282 struct neighbor, cmsg_timer);
283 __u64 jiffies = get_jiffies_64();
285 mutex_lock(&(nb->cmsg_lock));
287 if (nb->timeout > jiffies) {
288 INIT_DELAYED_WORK(&(nb->cmsg_timer), controlmsg_timerfunc);
289 schedule_delayed_work(&(nb->cmsg_timer), nb->timeout - jiffies);
290 goto out;
293 send_messages(nb, 1);
294 schedule_controlmsg_timerfunc(nb);
296 out:
297 mutex_unlock(&(nb->cmsg_lock));
300 void schedule_controlmsg_timerfunc(struct neighbor *nb)
302 int target_delay_ms = 1000;
303 int target_delay_jiffies = msecs_to_jiffies(target_delay_ms);
304 __u64 jiffies = get_jiffies_64();
305 long long delay;
307 nb->timeout += target_delay_jiffies;
309 delay = nb->timeout - jiffies;
310 if (delay < 0) {
311 delay = 0;
312 nb->timeout = jiffies;
315 INIT_DELAYED_WORK(&(nb->cmsg_timer), controlmsg_timerfunc);
316 schedule_delayed_work(&(nb->cmsg_timer), delay);
319 static void add_control_msg(struct control_msg_out *msg, struct neighbor *nb)
321 BUG_ON(msg == 0);
323 printk(KERN_ERR "add_msg %d", msg->type);
325 mutex_lock(&(nb->cmsg_lock));
327 msg->nb = nb;
328 nb->length += msg->length;
329 list_add_tail((struct list_head *) msg,
330 (struct list_head *) &(nb->control_msgs_out));
332 if (unlikely(nb->length >= mss(nb)))
333 send_messages(nb, 0);
335 mutex_unlock(&(nb->cmsg_lock));
338 void send_reset_conn(struct control_msg_out *cm, struct neighbor *nb,
339 __u32 conn_id)
341 cm->type = MSGTYPE_RESET_CONN;
342 cm->msg.reset.conn_id = conn_id;
343 cm->length = 5;
344 add_control_msg(cm, nb);
347 void send_ack(struct control_msg_out *cm, struct neighbor *nb, __u32 conn_id,
348 __u32 seqno)
350 cm->type = MSGTYPE_ACK;
351 cm->msg.ack.conn_id = conn_id;
352 cm->msg.ack.seqno = seqno;
353 cm->length = 9;
354 add_control_msg(cm, nb);
357 void send_connect_success(struct control_msg_out *cm, struct neighbor *nb,
358 __u32 rcvd_conn_id, __u32 gen_conn_id)
360 cm->type = MSGTYPE_CONNECT_SUCCESS;
361 cm->msg.connect_success.rcvd_conn_id = rcvd_conn_id;
362 cm->msg.connect_success.gen_conn_id = gen_conn_id;
363 cm->length = 9;
364 add_control_msg(cm, nb);
367 void send_connect_nb(struct control_msg_out *cm, struct neighbor *nb,
368 __u32 conn_id)
370 cm->type = MSGTYPE_CONNECT;
371 cm->msg.connect.conn_id = conn_id;
372 cm->length = 5;
373 add_control_msg(cm, nb);
376 void send_conndata(struct control_msg_out *cm, struct neighbor *nb,
377 __u32 conn_id, __u32 seqno, char *data_orig, char *data,
378 __u32 datalen)
380 printk(KERN_ERR "send_conndata");
381 cm->type = MSGTYPE_CONNDATA;
382 cm->msg.conn_data.conn_id = conn_id;
383 cm->msg.conn_data.seqno = seqno;
384 cm->msg.conn_data.data_orig = data_orig;
385 cm->msg.conn_data.data = data;
386 cm->msg.conn_data.datalen = datalen;
387 cm->length = 9 + datalen;
388 add_control_msg(cm, nb);