2 * Connection oriented routing
3 * Copyright (C) 2007-2011 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
23 struct work_struct cpacket_resume_work
;
24 static int cpacket_resume_running
;
25 DEFINE_SPINLOCK(cpacket_bufferlimits_lock
);
26 static __u64 cpacket_bufferusage
;
27 static int cpacket_kmallocfailed
;
28 LIST_HEAD(cpacket_bufferwaiting
);
30 static int reserve_cpacket_buffer(struct conn
*trtg_unconn_l
, int fromresume
)
35 __u32 paramlen
= trtg_unconn_l
->target
.unconnected
.paramlen
;
38 if (trtg_unconn_l
->target
.unconnected
.cmd
== CD_LIST_NEIGH
)
39 resplen
= LISTNEIGH_RESP_MAXSIZE
+ 128;
41 if (trtg_unconn_l
->target
.unconnected
.in_buffer_wait_list
&&
45 if (trtg_unconn_l
->data_buf
.cpacket_buffer
+ paramlen
+ resplen
>
46 BUFFERLIMIT_CONNDATA_PERCONN
)
49 spin_lock_irqsave(&cpacket_bufferlimits_lock
, iflags
);
51 if (list_empty(&cpacket_bufferwaiting
) == 0 || paramlen
+ resplen
+
52 cpacket_bufferusage
> BUFFERLIMIT_CONNDATA_GLOBAL
) {
53 /* out of bufferspace */
54 if (trtg_unconn_l
->target
.unconnected
.in_buffer_wait_list
== 0){
55 trtg_unconn_l
->target
.unconnected
.in_buffer_wait_list
=1;
56 list_add_tail(&(trtg_unconn_l
->target
.unconnected
.buffer_wait_list
),
57 &cpacket_bufferwaiting
);
58 kref_get(&(trtg_unconn_l
->ref
));
60 if (cpacket_resume_running
== 0) {
61 schedule_work(&cpacket_resume_work
);
62 cpacket_resume_running
= 1;
65 spin_unlock_irqrestore(&cpacket_bufferlimits_lock
,
70 cpacket_bufferusage
+= paramlen
+ resplen
;
72 if (trtg_unconn_l
->target
.unconnected
.in_buffer_wait_list
) {
73 trtg_unconn_l
->target
.unconnected
.in_buffer_wait_list
= 0;
74 list_del(&(trtg_unconn_l
->target
.unconnected
.buffer_wait_list
));
78 spin_unlock_irqrestore(&cpacket_bufferlimits_lock
, iflags
);
80 trtg_unconn_l
->target
.unconnected
.cmdparams
= kmalloc(paramlen
,
82 if (unlikely(trtg_unconn_l
->target
.unconnected
.cmdparams
== 0)) {
83 spin_lock_irqsave(&cpacket_bufferlimits_lock
, iflags
);
84 cpacket_kmallocfailed
= 1;
85 trtg_unconn_l
->target
.unconnected
.in_buffer_wait_list
= 1;
86 list_add(&(trtg_unconn_l
->target
.unconnected
.buffer_wait_list
),
87 &cpacket_bufferwaiting
);
88 if (cpacket_resume_running
== 0) {
89 schedule_work(&cpacket_resume_work
);
90 cpacket_resume_running
= 1;
93 kref_get(&(trtg_unconn_l
->ref
));
94 cpacket_bufferusage
-= paramlen
+ resplen
;
95 spin_unlock_irqrestore(&cpacket_bufferlimits_lock
, iflags
);
99 spin_lock_bh(&(trtg_unconn_l
->reversedir
->rcv_lock
));
100 trtg_unconn_l
->reversedir
->data_buf
.cpacket_buffer
+= resplen
;
101 spin_unlock_bh(&(trtg_unconn_l
->reversedir
->rcv_lock
));
104 kref_put(&(trtg_unconn_l
->ref
), free_conn
);
109 static void cpacket_buffer_resume(struct work_struct
*work
)
111 unsigned long iflags
;
114 spin_lock_irqsave(&cpacket_bufferlimits_lock
, iflags
);
116 cpacket_kmallocfailed
= 0;
118 for (i
=0;i
<100;i
++) {
119 struct conn
*trtg_unconn
;
122 if (list_empty(&cpacket_bufferwaiting
))
125 if (cpacket_kmallocfailed
)
128 trtg_unconn
= container_of(cpacket_bufferwaiting
.next
,
130 target
.unconnected
.buffer_wait_list
);
132 kref_get(&(trtg_unconn
->ref
));
134 spin_unlock_irqrestore(&cpacket_bufferlimits_lock
, iflags
);
136 spin_lock_bh(&(trtg_unconn
->rcv_lock
));
138 if (unlikely(trtg_unconn
->targettype
!= TARGET_UNCONNECTED
)) {
143 spin_lock_irqsave(&cpacket_bufferlimits_lock
, iflags
);
145 if (unlikely(trtg_unconn
->target
.unconnected
.in_buffer_wait_list
148 } else if (unlikely(trtg_unconn
->isreset
!= 0)) {
149 trtg_unconn
->target
.unconnected
.in_buffer_wait_list
= 0;
150 list_del(&(trtg_unconn
->target
.unconnected
.buffer_wait_list
));
151 kref_put(&(trtg_unconn
->ref
), free_conn
);
155 spin_unlock_irqrestore(&cpacket_bufferlimits_lock
, iflags
);
158 spin_unlock_bh(&(trtg_unconn
->rcv_lock
));
161 parse(trtg_unconn
, 1);
163 kref_put(&(trtg_unconn
->ref
), free_conn
);
164 spin_lock_irqsave(&cpacket_bufferlimits_lock
, iflags
);
167 schedule_work(&cpacket_resume_work
);
171 cpacket_resume_running
= 0;
174 spin_unlock_irqrestore(&cpacket_bufferlimits_lock
, iflags
);
177 void free_cpacket_buffer(__s32 amount
)
179 unsigned long iflags
;
180 spin_lock_irqsave(&cpacket_bufferlimits_lock
, iflags
);
181 BUG_ON(amount
> 0 && amount
> cpacket_bufferusage
);
182 cpacket_bufferusage
-= amount
;
184 if (amount
> 0 && list_empty(&cpacket_bufferwaiting
) == 0 &&
185 cpacket_resume_running
== 0) {
186 schedule_work(&cpacket_resume_work
);
187 cpacket_resume_running
= 1;
189 spin_unlock_irqrestore(&cpacket_bufferlimits_lock
, iflags
);
192 void connreset_cpacket_buffer(struct conn
*trtg_unconn_l
)
194 if (trtg_unconn_l
->target
.unconnected
.in_buffer_wait_list
) {
195 unsigned long iflags
;
196 spin_lock_irqsave(&cpacket_bufferlimits_lock
, iflags
);
197 trtg_unconn_l
->target
.unconnected
.in_buffer_wait_list
= 0;
198 list_del(&(trtg_unconn_l
->target
.unconnected
.buffer_wait_list
));
199 spin_unlock_irqrestore(&cpacket_bufferlimits_lock
, iflags
);
200 kref_put(&(trtg_unconn_l
->ref
), free_conn
);
203 if (trtg_unconn_l
->target
.unconnected
.cmdparams
!= 0) {
204 BUG_ON(trtg_unconn_l
->target
.unconnected
.paramlen
<= 0);
205 kfree(trtg_unconn_l
->target
.unconnected
.cmdparams
);
206 trtg_unconn_l
->target
.unconnected
.cmdparams
= 0;
207 free_cpacket_buffer(trtg_unconn_l
->target
.unconnected
.paramlen
);
211 int encode_len(char *buf
, int buflen
, __u32 len
)
222 buf
[0] = (__u8
) ((len
- 128) /256 + 128);
223 buf
[1] = (__u8
) ((len
- 128) & 255);
227 if (len
< 1073741951) {
228 __u32 len_be
= cpu_to_be32(len
- 16511);
229 char *len_p
= (char *) &len_be
;
231 buf
[0] = len_p
[0] + 192;
241 int decode_len(char *buf
, int buflen
, __u32
*len
)
246 if ((__u8
) buf
[0] <= 127) {
247 *len
= (__u8
) buf
[0];
254 if ((__u8
) buf
[0] <= 191) {
255 *len
= 128 + ((__u32
) ((__u8
) buf
[0]) - 128) * 256 +
263 ((char *) len
)[0] = buf
[0] - 192;
264 ((char *) len
)[1] = buf
[1];
265 ((char *) len
)[2] = buf
[2];
266 ((char *) len
)[3] = buf
[3];
268 *len
= be32_to_cpu(*len
) + 16511;
272 static void send_resp_ok(struct conn
*trtg_unconn_l
)
274 __u8 respcode
= CDR_EXECOK
;
276 spin_lock_bh(&(trtg_unconn_l
->reversedir
->rcv_lock
));
277 receive_cpacketresp(trtg_unconn_l
->reversedir
, (char *) &respcode
, 1);
278 spin_unlock_bh(&(trtg_unconn_l
->reversedir
->rcv_lock
));
281 static char *get_error_reason_text(__u16 reasoncode
)
283 if (reasoncode
== CDR_EXECFAILED_UNKNOWN_COMMAND
)
284 return "Unknown command";
285 else if (reasoncode
== CDR_EXECFAILED_PERMISSION_DENIED
)
286 return "Permission denied";
287 else if (reasoncode
== CDR_EXECFAILED_TEMPORARILY_OUT_OF_RESSOURCES
)
288 return "Temporarily out of ressources";
289 else if (reasoncode
== CDR_EXECFAILED_CMD_TOO_SHORT
)
290 return "The length of the command is too short for all params";
291 else if (reasoncode
== CDR_EXECFAILED_CMD_TOO_LONG
)
292 return "command param is too long";
293 else if (reasoncode
== CDR_EXECFAILED_TARGETADDRTYPE_UNKNOWN
)
294 return "targettype unknown";
295 else if (reasoncode
== CDR_EXECFAILED_TARGETADDR_DOESNTEXIST
)
296 return "targetaddr does not exist";
297 else if (reasoncode
== CDR_EXECFAILED_TARGETADDR_PORTCLOSED
)
298 return "Port is on open";
299 else if (reasoncode
== CDR_EXECFAILED_LISTENERQUEUE_FULL
)
300 return "Listener queue full";
305 static void send_resp_failed(struct conn
*trtg_unconn_l
, __u16 reasoncode
)
313 hdr
[0] = CDR_EXECFAILED
;
315 reasoncode
= cpu_to_be16(reasoncode
);
316 hdr
[1] = ((char *) &reasoncode
)[0];
317 hdr
[2] = ((char *) &reasoncode
)[1];
319 reasontext
= get_error_reason_text(reasoncode
);
321 reasonlen
= strnlen(reasontext
, 1024);
322 reasonlen_len
= encode_len(hdr
+ 3, 4, reasonlen
);
323 BUG_ON(reasonlen_len
<= 0);
325 spin_lock_bh(&(trtg_unconn_l
->reversedir
->rcv_lock
));
326 receive_cpacketresp(trtg_unconn_l
->reversedir
, hdr
, 3 + reasonlen_len
);
327 receive_cpacketresp(trtg_unconn_l
->reversedir
, reasontext
, reasonlen
);
328 spin_unlock_bh(&(trtg_unconn_l
->reversedir
->rcv_lock
));
331 static void send_resp_bin(struct conn
*trtg_unconn_l
, char *buf
, __u32 len
)
336 hdr
[0] = CDR_BINDATA
;
337 len_len
= encode_len(hdr
+ 1, 4, len
);
339 BUG_ON(len_len
<= 0);
341 spin_lock_bh(&(trtg_unconn_l
->reversedir
->rcv_lock
));
342 receive_cpacketresp(trtg_unconn_l
->reversedir
, hdr
, len_len
+ 1);
343 receive_cpacketresp(trtg_unconn_l
->reversedir
, buf
, len
);
344 spin_unlock_bh(&(trtg_unconn_l
->reversedir
->rcv_lock
));
347 static void parse_set_tos(struct conn
*trtg_unconn_l
)
349 if (unlikely(trtg_unconn_l
->target
.unconnected
.paramlen
< 2)) {
350 send_resp_failed(trtg_unconn_l
, CDR_EXECFAILED_CMD_TOO_SHORT
);
355 (trtg_unconn_l
->target
.unconnected
.cmdparams
[0]) & 3;
356 trtg_unconn_l
->reversedir
->tos
=
357 (trtg_unconn_l
->target
.unconnected
.cmdparams
[1]) & 3;
360 static void parse_list_neigh(struct conn
*trtg_unconn_l
)
371 BUG_ON(read
> trtg_unconn_l
->target
.unconnected
.paramlen
);
372 rc
= decode_len(trtg_unconn_l
->target
.unconnected
.cmdparams
+ read
,
373 trtg_unconn_l
->target
.unconnected
.paramlen
- read
,
376 if (unlikely(rc
<= 0)) {
377 send_resp_failed(trtg_unconn_l
, CDR_EXECFAILED_CMD_TOO_SHORT
);
383 BUG_ON(read
> trtg_unconn_l
->target
.unconnected
.paramlen
);
384 rc
= decode_len(trtg_unconn_l
->target
.unconnected
.cmdparams
+ read
,
385 trtg_unconn_l
->target
.unconnected
.paramlen
- read
,
388 if (unlikely(rc
<= 0)) {
389 send_resp_failed(trtg_unconn_l
, CDR_EXECFAILED_CMD_TOO_SHORT
);
395 buf
= kmalloc(LISTNEIGH_RESP_MAXSIZE
, GFP_ATOMIC
);
397 if (unlikely(buf
== 0)) {
398 send_resp_failed(trtg_unconn_l
,
399 CDR_EXECFAILED_TEMPORARILY_OUT_OF_RESSOURCES
);
403 send_resp_ok(trtg_unconn_l
);
405 len
= generate_neigh_list(buf
, 2048, limit
, offset
);
406 send_resp_bin(trtg_unconn_l
, buf
, len
);
409 static void parse_connect_port(struct conn
*trtg_unconn_l
)
414 if (unlikely(trtg_unconn_l
->target
.unconnected
.paramlen
< 8)) {
415 send_resp_failed(trtg_unconn_l
, CDR_EXECFAILED_CMD_TOO_SHORT
);
419 memcpy((char *) &addr
, trtg_unconn_l
->target
.unconnected
.cmdparams
, 8);
421 rc
= connect_port(trtg_unconn_l
, addr
);
424 send_resp_ok(trtg_unconn_l
);
425 } else if (rc
== 2) {
426 send_resp_failed(trtg_unconn_l
,
427 CDR_EXECFAILED_TARGETADDR_DOESNTEXIST
);
428 } else if (rc
== 3) {
429 send_resp_failed(trtg_unconn_l
,
430 CDR_EXECFAILED_LISTENERQUEUE_FULL
);
436 static void parse_connect_nb(struct conn
*trtg_unconn_l
)
446 BUG_ON(read
> trtg_unconn_l
->target
.unconnected
.paramlen
);
447 rc
= decode_len(trtg_unconn_l
->target
.unconnected
.cmdparams
+ read
,
448 trtg_unconn_l
->target
.unconnected
.paramlen
- read
,
451 if (unlikely(rc
<= 0)) {
452 send_resp_failed(trtg_unconn_l
, CDR_EXECFAILED_CMD_TOO_SHORT
);
458 BUG_ON(read
> trtg_unconn_l
->target
.unconnected
.paramlen
);
459 rc
= decode_len(trtg_unconn_l
->target
.unconnected
.cmdparams
+ read
,
460 trtg_unconn_l
->target
.unconnected
.paramlen
- read
,
463 if (unlikely(rc
<= 0)) {
464 send_resp_failed(trtg_unconn_l
, CDR_EXECFAILED_CMD_TOO_SHORT
);
470 if (unlikely(addrtypelen
> 65535 || addrtypelen
> 65535)) {
471 send_resp_failed(trtg_unconn_l
,
472 CDR_EXECFAILED_TARGETADDR_DOESNTEXIST
);
476 if (unlikely((read
+ addrtypelen
+ addrlen
) >
477 trtg_unconn_l
->target
.unconnected
.paramlen
)) {
478 send_resp_failed(trtg_unconn_l
, CDR_EXECFAILED_CMD_TOO_SHORT
);
482 addrtype
= trtg_unconn_l
->target
.unconnected
.cmdparams
+ read
;
483 addr
= addrtype
+ addrtypelen
;
485 rc
= connect_neigh(trtg_unconn_l
, (__u16
) addrtypelen
, addrtype
,
486 (__u16
) addrlen
, addr
);
489 #warning todo send ok when receiving conn_success and failed when receiving reset
490 send_resp_ok(trtg_unconn_l
);
491 } else if (rc
== 2) {
492 send_resp_failed(trtg_unconn_l
,
493 CDR_EXECFAILED_TARGETADDRTYPE_UNKNOWN
);
494 } else if (rc
== 3) {
495 send_resp_failed(trtg_unconn_l
,
496 CDR_EXECFAILED_TARGETADDR_DOESNTEXIST
);
497 } else if (rc
== 4) {
498 send_resp_failed(trtg_unconn_l
,
499 CDR_EXECFAILED_TEMPORARILY_OUT_OF_RESSOURCES
);
505 static void parse_cmd(struct conn
*trtg_unconn_l
)
507 __u16 code
= trtg_unconn_l
->target
.unconnected
.cmd
;
509 BUG_ON(trtg_unconn_l
->target
.unconnected
.cmdparams
== 0);
511 if (code
== CD_CONNECT_NB
) {
512 parse_connect_nb(trtg_unconn_l
);
513 } else if (code
== CD_CONNECT_PORT
) {
514 parse_connect_port(trtg_unconn_l
);
515 } else if (code
== CD_LIST_NEIGH
) {
516 parse_list_neigh(trtg_unconn_l
);
517 } else if (code
== CD_SET_TOS
) {
518 parse_set_tos(trtg_unconn_l
);
520 send_resp_failed(trtg_unconn_l
, CDR_EXECFAILED_UNKNOWN_COMMAND
);
524 static void read_cmd(struct conn
*trtg_unconn_l
)
528 pull
= min(trtg_unconn_l
->target
.unconnected
.paramlen
-
529 trtg_unconn_l
->target
.unconnected
.cmdread
,
530 trtg_unconn_l
->data_buf
.read_remaining
);
533 BUG_ON(trtg_unconn_l
->target
.unconnected
.cmdparams
== 0);
538 databuf_pull(trtg_unconn_l
,
539 trtg_unconn_l
->target
.unconnected
.cmdparams
+
540 trtg_unconn_l
->target
.unconnected
.cmdread
, pull
);
541 databuf_ackread(trtg_unconn_l
);
543 trtg_unconn_l
->target
.unconnected
.cmdread
+= pull
;
546 static void read_discard(struct conn
*trtg_unconn_l
)
548 BUG_ON(trtg_unconn_l
->target
.unconnected
.paramlen_read
== 0);
550 while (trtg_unconn_l
->target
.unconnected
.paramlen
<
551 trtg_unconn_l
->target
.unconnected
.cmdread
&&
552 trtg_unconn_l
->data_buf
.read_remaining
> 0) {
554 databuf_pull(trtg_unconn_l
, buf
, 1);
555 databuf_ackread(trtg_unconn_l
);
557 trtg_unconn_l
->target
.unconnected
.cmdread
++;
561 static void read_hdr(struct conn
*trtg_unconn_l
)
563 BUG_ON(trtg_unconn_l
->target
.unconnected
.cmdparams
!= 0);
565 while (trtg_unconn_l
->target
.unconnected
.paramlen_read
== 0 &&
566 trtg_unconn_l
->data_buf
.read_remaining
> 0) {
569 BUG_ON(trtg_unconn_l
->target
.unconnected
.cmdread
>= 6);
571 if (trtg_unconn_l
->target
.unconnected
.cmdread
< 2) {
573 databuf_pull(trtg_unconn_l
, buf
, 1);
574 trtg_unconn_l
->target
.unconnected
.cmd
<<= 8;
575 trtg_unconn_l
->target
.unconnected
.cmd
+= buf
[0];
576 trtg_unconn_l
->target
.unconnected
.cmdread
+= 1;
580 databuf_pull(trtg_unconn_l
,
581 trtg_unconn_l
->target
.unconnected
.paramlen_buf
+
582 trtg_unconn_l
->target
.unconnected
.cmdread
- 2,
584 trtg_unconn_l
->target
.unconnected
.cmdread
+= 1;
586 rc
= decode_len(trtg_unconn_l
->target
.unconnected
.paramlen_buf
,
587 trtg_unconn_l
->target
.unconnected
.cmdread
- 2,
588 &(trtg_unconn_l
->target
.unconnected
.paramlen
));
591 trtg_unconn_l
->target
.unconnected
.paramlen_read
= 1;
592 trtg_unconn_l
->target
.unconnected
.cmdread
= 0;
598 void parse(struct conn
*trtg_unconn
, int fromresume
)
601 spin_lock_bh(&(trtg_unconn
->rcv_lock
));
603 if (unlikely(trtg_unconn
->isreset
!= 0))
606 if (unlikely(trtg_unconn
->targettype
!= TARGET_UNCONNECTED
))
609 BUG_ON(trtg_unconn
->data_buf
.cpacket_buffer
!= 0);
611 if (trtg_unconn
->target
.unconnected
.paramlen_read
== 0) {
612 read_hdr(trtg_unconn
);
613 if (trtg_unconn
->target
.unconnected
.paramlen_read
== 0)
616 if (trtg_unconn
->target
.unconnected
.paramlen
>
618 send_resp_failed(trtg_unconn
,
619 CDR_EXECFAILED_CMD_TOO_LONG
);
623 if (trtg_unconn
->target
.unconnected
.paramlen
> MAX_CONN_CMD_LEN
) {
624 read_discard(trtg_unconn
);
628 if (trtg_unconn
->target
.unconnected
.cmdparams
== 0) {
629 if (reserve_cpacket_buffer(trtg_unconn
, fromresume
))
633 if (trtg_unconn
->target
.unconnected
.paramlen
>
634 trtg_unconn
->target
.unconnected
.cmdread
) {
635 read_cmd(trtg_unconn
);
638 if (trtg_unconn
->target
.unconnected
.paramlen
==
639 trtg_unconn
->target
.unconnected
.cmdread
) {
640 char *cmd
= trtg_unconn
->target
.unconnected
.cmdparams
;
641 __s32 cpacket_buffer
;
642 __u32 paramlen
= trtg_unconn
->target
.unconnected
.paramlen
;
645 BUG_ON(trtg_unconn
->is_client
== 0);
646 spin_lock_bh(&(trtg_unconn
->reversedir
->rcv_lock
));
647 cpacket_buffer
= trtg_unconn
->reversedir
->data_buf
.cpacket_buffer
;
648 spin_unlock_bh(&(trtg_unconn
->reversedir
->rcv_lock
));
649 parse_cmd(trtg_unconn
);
651 spin_lock_bh(&(trtg_unconn
->reversedir
->rcv_lock
));
652 trtg_unconn
->reversedir
->data_buf
.cpacket_buffer
=
653 trtg_unconn
->reversedir
->data_buf
.totalsize
+
654 trtg_unconn
->reversedir
->data_buf
.overhead
;
655 cpacket_buffer
-= trtg_unconn
->reversedir
->data_buf
.cpacket_buffer
;
656 spin_unlock_bh(&(trtg_unconn
->reversedir
->rcv_lock
));
657 free_cpacket_buffer(paramlen
+ cpacket_buffer
);
659 if (trtg_unconn
->targettype
!= TARGET_UNCONNECTED
) {
662 trtg_unconn
->target
.unconnected
.cmdparams
= 0;
663 trtg_unconn
->target
.unconnected
.cmdread
= 0;
664 trtg_unconn
->target
.unconnected
.paramlen_read
= 0;
665 trtg_unconn
->target
.unconnected
.cmd
= 0;
666 trtg_unconn
->target
.unconnected
.paramlen
= 0;
669 spin_unlock_bh(&(trtg_unconn
->rcv_lock
));
671 flush_buf(trtg_unconn
);
672 flush_buf(trtg_unconn
->reversedir
);
679 spin_unlock_bh(&(trtg_unconn
->rcv_lock
));
682 int __init
cor_cpacket_init(void)
684 INIT_WORK(&cpacket_resume_work
, cpacket_buffer_resume
);
685 cpacket_resume_running
= 0;
686 cpacket_bufferusage
= 0;
687 cpacket_kmallocfailed
= 0;
691 MODULE_LICENSE("GPL");