diff options
-rw-r--r-- | net/dccp/Kconfig | 21 | ||||
-rw-r--r-- | net/dccp/ccids/ccid3.c | 9 | ||||
-rw-r--r-- | net/dccp/dccp.h | 7 | ||||
-rw-r--r-- | net/dccp/options.c | 18 | ||||
-rw-r--r-- | net/dccp/proto.c | 22 |
5 files changed, 56 insertions, 21 deletions
diff --git a/net/dccp/Kconfig b/net/dccp/Kconfig index 6760830c490f..3023f702eb87 100644 --- a/net/dccp/Kconfig +++ b/net/dccp/Kconfig | |||
@@ -26,4 +26,25 @@ config INET_DCCP_DIAG | |||
26 | 26 | ||
27 | source "net/dccp/ccids/Kconfig" | 27 | source "net/dccp/ccids/Kconfig" |
28 | 28 | ||
29 | menu "DCCP Kernel Hacking" | ||
30 | depends on IP_DCCP=m && DEBUG_KERNEL=y | ||
31 | |||
32 | config IP_DCCP_DEBUG | ||
33 | bool "DCCP debug messages" | ||
34 | ---help--- | ||
35 | Only use this if you're hacking DCCP. | ||
36 | |||
37 | Just say N. | ||
38 | |||
39 | config IP_DCCP_UNLOAD_HACK | ||
40 | depends on IP_DCCP_CCID3=m | ||
41 | bool "DCCP control sock unload hack" | ||
42 | ---help--- | ||
43 | Enable this to be able to unload the dccp module when the it | ||
44 | has only one refcount held, the control sock one. Just execute | ||
45 | "rmmod dccp_ccid3 dccp" | ||
46 | |||
47 | Just say N. | ||
48 | endmenu | ||
49 | |||
29 | endmenu | 50 | endmenu |
diff --git a/net/dccp/ccids/ccid3.c b/net/dccp/ccids/ccid3.c index edf9740d8d82..09274f32a337 100644 --- a/net/dccp/ccids/ccid3.c +++ b/net/dccp/ccids/ccid3.c | |||
@@ -2078,6 +2078,15 @@ module_init(ccid3_module_init); | |||
2078 | 2078 | ||
2079 | static __exit void ccid3_module_exit(void) | 2079 | static __exit void ccid3_module_exit(void) |
2080 | { | 2080 | { |
2081 | #ifdef CONFIG_IP_DCCP_UNLOAD_HACK | ||
2082 | /* | ||
2083 | * Hack to use while developing, so that we get rid of the control | ||
2084 | * sock, that is what keeps a refcount on dccp.ko -acme | ||
2085 | */ | ||
2086 | extern void dccp_ctl_sock_exit(void); | ||
2087 | |||
2088 | dccp_ctl_sock_exit(); | ||
2089 | #endif | ||
2081 | ccid_unregister(&ccid3); | 2090 | ccid_unregister(&ccid3); |
2082 | 2091 | ||
2083 | if (ccid3_tx_hist != NULL) { | 2092 | if (ccid3_tx_hist != NULL) { |
diff --git a/net/dccp/dccp.h b/net/dccp/dccp.h index 62e735f1807d..270f19439964 100644 --- a/net/dccp/dccp.h +++ b/net/dccp/dccp.h | |||
@@ -11,14 +11,13 @@ | |||
11 | * published by the Free Software Foundation. | 11 | * published by the Free Software Foundation. |
12 | */ | 12 | */ |
13 | 13 | ||
14 | #include <linux/config.h> | ||
14 | #include <linux/dccp.h> | 15 | #include <linux/dccp.h> |
15 | #include <net/snmp.h> | 16 | #include <net/snmp.h> |
16 | #include <net/sock.h> | 17 | #include <net/sock.h> |
17 | #include <net/tcp.h> | 18 | #include <net/tcp.h> |
18 | 19 | ||
19 | #define DCCP_DEBUG | 20 | #ifdef CONFIG_IP_DCCP_DEBUG |
20 | |||
21 | #ifdef DCCP_DEBUG | ||
22 | extern int dccp_debug; | 21 | extern int dccp_debug; |
23 | 22 | ||
24 | #define dccp_pr_debug(format, a...) \ | 23 | #define dccp_pr_debug(format, a...) \ |
@@ -426,7 +425,7 @@ extern int dccp_ackpkts_add(struct dccp_ackpkts *ap, u64 ackno, u8 state); | |||
426 | extern void dccp_ackpkts_check_rcv_ackno(struct dccp_ackpkts *ap, | 425 | extern void dccp_ackpkts_check_rcv_ackno(struct dccp_ackpkts *ap, |
427 | struct sock *sk, u64 ackno); | 426 | struct sock *sk, u64 ackno); |
428 | 427 | ||
429 | #ifdef DCCP_DEBUG | 428 | #ifdef CONFIG_IP_DCCP_DEBUG |
430 | extern void dccp_ackvector_print(const u64 ackno, | 429 | extern void dccp_ackvector_print(const u64 ackno, |
431 | const unsigned char *vector, int len); | 430 | const unsigned char *vector, int len); |
432 | extern void dccp_ackpkts_print(const struct dccp_ackpkts *ap); | 431 | extern void dccp_ackpkts_print(const struct dccp_ackpkts *ap); |
diff --git a/net/dccp/options.c b/net/dccp/options.c index 68d6614edcf1..fc363aaeedaf 100644 --- a/net/dccp/options.c +++ b/net/dccp/options.c | |||
@@ -58,7 +58,7 @@ static u32 dccp_decode_value_var(const unsigned char *bf, const u8 len) | |||
58 | int dccp_parse_options(struct sock *sk, struct sk_buff *skb) | 58 | int dccp_parse_options(struct sock *sk, struct sk_buff *skb) |
59 | { | 59 | { |
60 | struct dccp_sock *dp = dccp_sk(sk); | 60 | struct dccp_sock *dp = dccp_sk(sk); |
61 | #ifdef DCCP_DEBUG | 61 | #ifdef CONFIG_IP_DCCP_DEBUG |
62 | const char *debug_prefix = dp->dccps_role == DCCP_ROLE_CLIENT ? | 62 | const char *debug_prefix = dp->dccps_role == DCCP_ROLE_CLIENT ? |
63 | "CLIENT rx opt: " : "server rx opt: "; | 63 | "CLIENT rx opt: " : "server rx opt: "; |
64 | #endif | 64 | #endif |
@@ -303,7 +303,7 @@ void dccp_insert_option_elapsed_time(struct sock *sk, | |||
303 | struct sk_buff *skb, | 303 | struct sk_buff *skb, |
304 | u32 elapsed_time) | 304 | u32 elapsed_time) |
305 | { | 305 | { |
306 | #ifdef DCCP_DEBUG | 306 | #ifdef CONFIG_IP_DCCP_DEBUG |
307 | struct dccp_sock *dp = dccp_sk(sk); | 307 | struct dccp_sock *dp = dccp_sk(sk); |
308 | const char *debug_prefix = dp->dccps_role == DCCP_ROLE_CLIENT ? | 308 | const char *debug_prefix = dp->dccps_role == DCCP_ROLE_CLIENT ? |
309 | "CLIENT TX opt: " : "server TX opt: "; | 309 | "CLIENT TX opt: " : "server TX opt: "; |
@@ -341,7 +341,7 @@ EXPORT_SYMBOL(dccp_insert_option_elapsed_time); | |||
341 | static void dccp_insert_option_ack_vector(struct sock *sk, struct sk_buff *skb) | 341 | static void dccp_insert_option_ack_vector(struct sock *sk, struct sk_buff *skb) |
342 | { | 342 | { |
343 | struct dccp_sock *dp = dccp_sk(sk); | 343 | struct dccp_sock *dp = dccp_sk(sk); |
344 | #ifdef DCCP_DEBUG | 344 | #ifdef CONFIG_IP_DCCP_DEBUG |
345 | const char *debug_prefix = dp->dccps_role == DCCP_ROLE_CLIENT ? | 345 | const char *debug_prefix = dp->dccps_role == DCCP_ROLE_CLIENT ? |
346 | "CLIENT TX opt: " : "server TX opt: "; | 346 | "CLIENT TX opt: " : "server TX opt: "; |
347 | #endif | 347 | #endif |
@@ -425,7 +425,7 @@ static void dccp_insert_option_timestamp_echo(struct sock *sk, | |||
425 | struct sk_buff *skb) | 425 | struct sk_buff *skb) |
426 | { | 426 | { |
427 | struct dccp_sock *dp = dccp_sk(sk); | 427 | struct dccp_sock *dp = dccp_sk(sk); |
428 | #ifdef DCCP_DEBUG | 428 | #ifdef CONFIG_IP_DCCP_DEBUG |
429 | const char *debug_prefix = dp->dccps_role == DCCP_ROLE_CLIENT ? | 429 | const char *debug_prefix = dp->dccps_role == DCCP_ROLE_CLIENT ? |
430 | "CLIENT TX opt: " : "server TX opt: "; | 430 | "CLIENT TX opt: " : "server TX opt: "; |
431 | #endif | 431 | #endif |
@@ -504,7 +504,7 @@ struct dccp_ackpkts *dccp_ackpkts_alloc(unsigned int len, int priority) | |||
504 | struct dccp_ackpkts *ap = kmalloc(sizeof(*ap) + len, priority); | 504 | struct dccp_ackpkts *ap = kmalloc(sizeof(*ap) + len, priority); |
505 | 505 | ||
506 | if (ap != NULL) { | 506 | if (ap != NULL) { |
507 | #ifdef DCCP_DEBUG | 507 | #ifdef CONFIG_IP_DCCP_DEBUG |
508 | memset(ap->dccpap_buf, 0xFF, len); | 508 | memset(ap->dccpap_buf, 0xFF, len); |
509 | #endif | 509 | #endif |
510 | ap->dccpap_buf_len = len; | 510 | ap->dccpap_buf_len = len; |
@@ -526,7 +526,7 @@ struct dccp_ackpkts *dccp_ackpkts_alloc(unsigned int len, int priority) | |||
526 | void dccp_ackpkts_free(struct dccp_ackpkts *ap) | 526 | void dccp_ackpkts_free(struct dccp_ackpkts *ap) |
527 | { | 527 | { |
528 | if (ap != NULL) { | 528 | if (ap != NULL) { |
529 | #ifdef DCCP_DEBUG | 529 | #ifdef CONFIG_IP_DCCP_DEBUG |
530 | memset(ap, 0xFF, sizeof(*ap) + ap->dccpap_buf_len); | 530 | memset(ap, 0xFF, sizeof(*ap) + ap->dccpap_buf_len); |
531 | #endif | 531 | #endif |
532 | kfree(ap); | 532 | kfree(ap); |
@@ -680,7 +680,7 @@ out_duplicate: | |||
680 | return -EILSEQ; | 680 | return -EILSEQ; |
681 | } | 681 | } |
682 | 682 | ||
683 | #ifdef DCCP_DEBUG | 683 | #ifdef CONFIG_IP_DCCP_DEBUG |
684 | void dccp_ackvector_print(const u64 ackno, const unsigned char *vector, | 684 | void dccp_ackvector_print(const u64 ackno, const unsigned char *vector, |
685 | int len) | 685 | int len) |
686 | { | 686 | { |
@@ -735,7 +735,7 @@ void dccp_ackpkts_check_rcv_ackno(struct dccp_ackpkts *ap, struct sock *sk, | |||
735 | return; | 735 | return; |
736 | 736 | ||
737 | if (ackno == ap->dccpap_ack_seqno) { | 737 | if (ackno == ap->dccpap_ack_seqno) { |
738 | #ifdef DCCP_DEBUG | 738 | #ifdef CONFIG_IP_DCCP_DEBUG |
739 | struct dccp_sock *dp = dccp_sk(sk); | 739 | struct dccp_sock *dp = dccp_sk(sk); |
740 | const char *debug_prefix = dp->dccps_role == DCCP_ROLE_CLIENT ? | 740 | const char *debug_prefix = dp->dccps_role == DCCP_ROLE_CLIENT ? |
741 | "CLIENT rx ack: " : "server rx ack: "; | 741 | "CLIENT rx ack: " : "server rx ack: "; |
@@ -794,7 +794,7 @@ static void dccp_ackpkts_check_rcv_ackvector(struct dccp_ackpkts *ap, | |||
794 | /* dccp_pr_debug_cat("yes\n"); */ | 794 | /* dccp_pr_debug_cat("yes\n"); */ |
795 | 795 | ||
796 | if (state != DCCP_ACKPKTS_STATE_NOT_RECEIVED) { | 796 | if (state != DCCP_ACKPKTS_STATE_NOT_RECEIVED) { |
797 | #ifdef DCCP_DEBUG | 797 | #ifdef CONFIG_IP_DCCP_DEBUG |
798 | struct dccp_sock *dp = dccp_sk(sk); | 798 | struct dccp_sock *dp = dccp_sk(sk); |
799 | const char *debug_prefix = | 799 | const char *debug_prefix = |
800 | dp->dccps_role == DCCP_ROLE_CLIENT ? | 800 | dp->dccps_role == DCCP_ROLE_CLIENT ? |
diff --git a/net/dccp/proto.c b/net/dccp/proto.c index ed0bf58c8ae0..be0669242069 100644 --- a/net/dccp/proto.c +++ b/net/dccp/proto.c | |||
@@ -503,12 +503,16 @@ static int __init dccp_ctl_sock_init(void) | |||
503 | return rc; | 503 | return rc; |
504 | } | 504 | } |
505 | 505 | ||
506 | static void __exit dccp_ctl_sock_exit(void) | 506 | #ifdef CONFIG_IP_DCCP_UNLOAD_HACK |
507 | void dccp_ctl_sock_exit(void) | ||
507 | { | 508 | { |
508 | if (dccp_ctl_socket != NULL) | 509 | if (dccp_ctl_socket != NULL) |
509 | sock_release(dccp_ctl_socket); | 510 | sock_release(dccp_ctl_socket); |
510 | } | 511 | } |
511 | 512 | ||
513 | EXPORT_SYMBOL_GPL(dccp_ctl_sock_exit); | ||
514 | #endif | ||
515 | |||
512 | static int __init init_dccp_v4_mibs(void) | 516 | static int __init init_dccp_v4_mibs(void) |
513 | { | 517 | { |
514 | int rc = -ENOMEM; | 518 | int rc = -ENOMEM; |
@@ -655,19 +659,21 @@ static const char dccp_del_proto_err_msg[] __exitdata = | |||
655 | 659 | ||
656 | static void __exit dccp_fini(void) | 660 | static void __exit dccp_fini(void) |
657 | { | 661 | { |
658 | dccp_ctl_sock_exit(); | ||
659 | |||
660 | inet_unregister_protosw(&dccp_v4_protosw); | 662 | inet_unregister_protosw(&dccp_v4_protosw); |
661 | 663 | ||
662 | if (inet_del_protocol(&dccp_protocol, IPPROTO_DCCP) < 0) | 664 | if (inet_del_protocol(&dccp_protocol, IPPROTO_DCCP) < 0) |
663 | printk(dccp_del_proto_err_msg); | 665 | printk(dccp_del_proto_err_msg); |
664 | 666 | ||
665 | /* Free the control endpoint. */ | 667 | free_percpu(dccp_statistics[0]); |
666 | sock_release(dccp_ctl_socket); | 668 | free_percpu(dccp_statistics[1]); |
667 | 669 | free_pages((unsigned long)dccp_hashinfo.bhash, | |
668 | proto_unregister(&dccp_v4_prot); | 670 | get_order(dccp_hashinfo.bhash_size * |
669 | 671 | sizeof(struct inet_bind_hashbucket))); | |
672 | free_pages((unsigned long)dccp_hashinfo.ehash, | ||
673 | get_order(dccp_hashinfo.ehash_size * | ||
674 | sizeof(struct inet_ehash_bucket))); | ||
670 | kmem_cache_destroy(dccp_hashinfo.bind_bucket_cachep); | 675 | kmem_cache_destroy(dccp_hashinfo.bind_bucket_cachep); |
676 | proto_unregister(&dccp_v4_prot); | ||
671 | } | 677 | } |
672 | 678 | ||
673 | module_init(dccp_init); | 679 | module_init(dccp_init); |