aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--net/dccp/Kconfig21
-rw-r--r--net/dccp/ccids/ccid3.c9
-rw-r--r--net/dccp/dccp.h7
-rw-r--r--net/dccp/options.c18
-rw-r--r--net/dccp/proto.c22
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
27source "net/dccp/ccids/Kconfig" 27source "net/dccp/ccids/Kconfig"
28 28
29menu "DCCP Kernel Hacking"
30 depends on IP_DCCP=m && DEBUG_KERNEL=y
31
32config 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
39config 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.
48endmenu
49
29endmenu 50endmenu
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
2079static __exit void ccid3_module_exit(void) 2079static __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
22extern int dccp_debug; 21extern 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);
426extern void dccp_ackpkts_check_rcv_ackno(struct dccp_ackpkts *ap, 425extern 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
430extern void dccp_ackvector_print(const u64 ackno, 429extern void dccp_ackvector_print(const u64 ackno,
431 const unsigned char *vector, int len); 430 const unsigned char *vector, int len);
432extern void dccp_ackpkts_print(const struct dccp_ackpkts *ap); 431extern 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)
58int dccp_parse_options(struct sock *sk, struct sk_buff *skb) 58int 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);
341static void dccp_insert_option_ack_vector(struct sock *sk, struct sk_buff *skb) 341static 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)
526void dccp_ackpkts_free(struct dccp_ackpkts *ap) 526void 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
684void dccp_ackvector_print(const u64 ackno, const unsigned char *vector, 684void 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
506static void __exit dccp_ctl_sock_exit(void) 506#ifdef CONFIG_IP_DCCP_UNLOAD_HACK
507void 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
513EXPORT_SYMBOL_GPL(dccp_ctl_sock_exit);
514#endif
515
512static int __init init_dccp_v4_mibs(void) 516static 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
656static void __exit dccp_fini(void) 660static 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
673module_init(dccp_init); 679module_init(dccp_init);