浏览代码

[DCCP]: Introduce the DCCP Kernel hacking menu

Only available if CONFIG_DEBUG_KERNEL is enabled in the "Kernel
Hacking" Menu.

Signed-off-by: Arnaldo Carvalho de Melo <acme@mandriva.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Arnaldo Carvalho de Melo 20 年之前
父节点
当前提交
725ba8eee3
共有 5 个文件被更改,包括 56 次插入21 次删除
  1. 21 0
      net/dccp/Kconfig
  2. 9 0
      net/dccp/ccids/ccid3.c
  3. 3 4
      net/dccp/dccp.h
  4. 9 9
      net/dccp/options.c
  5. 14 8
      net/dccp/proto.c

+ 21 - 0
net/dccp/Kconfig

@@ -26,4 +26,25 @@ config INET_DCCP_DIAG
 
 
 source "net/dccp/ccids/Kconfig"
 source "net/dccp/ccids/Kconfig"
 
 
+menu "DCCP Kernel Hacking"
+	depends on IP_DCCP=m && DEBUG_KERNEL=y
+
+config IP_DCCP_DEBUG
+	bool "DCCP debug messages"
+	---help---
+	  Only use this if you're hacking DCCP.
+
+	  Just say N.
+
+config IP_DCCP_UNLOAD_HACK
+	depends on IP_DCCP_CCID3=m
+	bool "DCCP control sock unload hack"
+	---help---
+	  Enable this to be able to unload the dccp module when the it
+	  has only one refcount held, the control sock one. Just execute
+	  "rmmod dccp_ccid3 dccp"
+
+	  Just say N.
+endmenu
+
 endmenu
 endmenu

+ 9 - 0
net/dccp/ccids/ccid3.c

@@ -2078,6 +2078,15 @@ module_init(ccid3_module_init);
 
 
 static __exit void ccid3_module_exit(void)
 static __exit void ccid3_module_exit(void)
 {
 {
+#ifdef CONFIG_IP_DCCP_UNLOAD_HACK
+	/*
+	 * Hack to use while developing, so that we get rid of the control
+	 * sock, that is what keeps a refcount on dccp.ko -acme
+	 */
+	extern void dccp_ctl_sock_exit(void);
+
+	dccp_ctl_sock_exit();
+#endif
 	ccid_unregister(&ccid3);
 	ccid_unregister(&ccid3);
 
 
 	if (ccid3_tx_hist != NULL) {
 	if (ccid3_tx_hist != NULL) {

+ 3 - 4
net/dccp/dccp.h

@@ -11,14 +11,13 @@
  *	published by the Free Software Foundation.
  *	published by the Free Software Foundation.
  */
  */
 
 
+#include <linux/config.h>
 #include <linux/dccp.h>
 #include <linux/dccp.h>
 #include <net/snmp.h>
 #include <net/snmp.h>
 #include <net/sock.h>
 #include <net/sock.h>
 #include <net/tcp.h>
 #include <net/tcp.h>
 
 
-#define DCCP_DEBUG
-
-#ifdef DCCP_DEBUG
+#ifdef CONFIG_IP_DCCP_DEBUG
 extern int dccp_debug;
 extern int dccp_debug;
 
 
 #define dccp_pr_debug(format, a...) \
 #define dccp_pr_debug(format, a...) \
@@ -426,7 +425,7 @@ extern int dccp_ackpkts_add(struct dccp_ackpkts *ap, u64 ackno, u8 state);
 extern void dccp_ackpkts_check_rcv_ackno(struct dccp_ackpkts *ap,
 extern void dccp_ackpkts_check_rcv_ackno(struct dccp_ackpkts *ap,
 					 struct sock *sk, u64 ackno);
 					 struct sock *sk, u64 ackno);
 
 
-#ifdef DCCP_DEBUG
+#ifdef CONFIG_IP_DCCP_DEBUG
 extern void dccp_ackvector_print(const u64 ackno,
 extern void dccp_ackvector_print(const u64 ackno,
 				 const unsigned char *vector, int len);
 				 const unsigned char *vector, int len);
 extern void dccp_ackpkts_print(const struct dccp_ackpkts *ap);
 extern void dccp_ackpkts_print(const struct dccp_ackpkts *ap);

+ 9 - 9
net/dccp/options.c

@@ -58,7 +58,7 @@ static u32 dccp_decode_value_var(const unsigned char *bf, const u8 len)
 int dccp_parse_options(struct sock *sk, struct sk_buff *skb)
 int dccp_parse_options(struct sock *sk, struct sk_buff *skb)
 {
 {
 	struct dccp_sock *dp = dccp_sk(sk);
 	struct dccp_sock *dp = dccp_sk(sk);
-#ifdef DCCP_DEBUG
+#ifdef CONFIG_IP_DCCP_DEBUG
 	const char *debug_prefix = dp->dccps_role == DCCP_ROLE_CLIENT ?
 	const char *debug_prefix = dp->dccps_role == DCCP_ROLE_CLIENT ?
 					"CLIENT rx opt: " : "server rx opt: ";
 					"CLIENT rx opt: " : "server rx opt: ";
 #endif
 #endif
@@ -303,7 +303,7 @@ void dccp_insert_option_elapsed_time(struct sock *sk,
 				     struct sk_buff *skb,
 				     struct sk_buff *skb,
 				     u32 elapsed_time)
 				     u32 elapsed_time)
 {
 {
-#ifdef DCCP_DEBUG
+#ifdef CONFIG_IP_DCCP_DEBUG
 	struct dccp_sock *dp = dccp_sk(sk);
 	struct dccp_sock *dp = dccp_sk(sk);
 	const char *debug_prefix = dp->dccps_role == DCCP_ROLE_CLIENT ?
 	const char *debug_prefix = dp->dccps_role == DCCP_ROLE_CLIENT ?
 					"CLIENT TX opt: " : "server TX opt: ";
 					"CLIENT TX opt: " : "server TX opt: ";
@@ -341,7 +341,7 @@ EXPORT_SYMBOL(dccp_insert_option_elapsed_time);
 static void dccp_insert_option_ack_vector(struct sock *sk, struct sk_buff *skb)
 static void dccp_insert_option_ack_vector(struct sock *sk, struct sk_buff *skb)
 {
 {
 	struct dccp_sock *dp = dccp_sk(sk);
 	struct dccp_sock *dp = dccp_sk(sk);
-#ifdef DCCP_DEBUG
+#ifdef CONFIG_IP_DCCP_DEBUG
 	const char *debug_prefix = dp->dccps_role == DCCP_ROLE_CLIENT ?
 	const char *debug_prefix = dp->dccps_role == DCCP_ROLE_CLIENT ?
 					"CLIENT TX opt: " : "server TX opt: ";
 					"CLIENT TX opt: " : "server TX opt: ";
 #endif
 #endif
@@ -425,7 +425,7 @@ static void dccp_insert_option_timestamp_echo(struct sock *sk,
 					      struct sk_buff *skb)
 					      struct sk_buff *skb)
 {
 {
 	struct dccp_sock *dp = dccp_sk(sk);
 	struct dccp_sock *dp = dccp_sk(sk);
-#ifdef DCCP_DEBUG
+#ifdef CONFIG_IP_DCCP_DEBUG
 	const char *debug_prefix = dp->dccps_role == DCCP_ROLE_CLIENT ?
 	const char *debug_prefix = dp->dccps_role == DCCP_ROLE_CLIENT ?
 					"CLIENT TX opt: " : "server TX opt: ";
 					"CLIENT TX opt: " : "server TX opt: ";
 #endif
 #endif
@@ -504,7 +504,7 @@ struct dccp_ackpkts *dccp_ackpkts_alloc(unsigned int len, int priority)
 	struct dccp_ackpkts *ap = kmalloc(sizeof(*ap) + len, priority);
 	struct dccp_ackpkts *ap = kmalloc(sizeof(*ap) + len, priority);
 
 
 	if (ap != NULL) {
 	if (ap != NULL) {
-#ifdef DCCP_DEBUG
+#ifdef CONFIG_IP_DCCP_DEBUG
 		memset(ap->dccpap_buf, 0xFF, len);
 		memset(ap->dccpap_buf, 0xFF, len);
 #endif
 #endif
 		ap->dccpap_buf_len   = len;
 		ap->dccpap_buf_len   = len;
@@ -526,7 +526,7 @@ struct dccp_ackpkts *dccp_ackpkts_alloc(unsigned int len, int priority)
 void dccp_ackpkts_free(struct dccp_ackpkts *ap)
 void dccp_ackpkts_free(struct dccp_ackpkts *ap)
 {
 {
 	if (ap != NULL) {
 	if (ap != NULL) {
-#ifdef DCCP_DEBUG
+#ifdef CONFIG_IP_DCCP_DEBUG
 		memset(ap, 0xFF, sizeof(*ap) + ap->dccpap_buf_len);
 		memset(ap, 0xFF, sizeof(*ap) + ap->dccpap_buf_len);
 #endif
 #endif
 		kfree(ap);
 		kfree(ap);
@@ -680,7 +680,7 @@ out_duplicate:
 	return -EILSEQ;
 	return -EILSEQ;
 }
 }
 
 
-#ifdef DCCP_DEBUG
+#ifdef CONFIG_IP_DCCP_DEBUG
 void dccp_ackvector_print(const u64 ackno, const unsigned char *vector,
 void dccp_ackvector_print(const u64 ackno, const unsigned char *vector,
 			  int len)
 			  int len)
 {
 {
@@ -735,7 +735,7 @@ void dccp_ackpkts_check_rcv_ackno(struct dccp_ackpkts *ap, struct sock *sk,
 		return;
 		return;
 
 
 	if (ackno == ap->dccpap_ack_seqno) {
 	if (ackno == ap->dccpap_ack_seqno) {
-#ifdef DCCP_DEBUG
+#ifdef CONFIG_IP_DCCP_DEBUG
 		struct dccp_sock *dp = dccp_sk(sk);
 		struct dccp_sock *dp = dccp_sk(sk);
 		const char *debug_prefix = dp->dccps_role == DCCP_ROLE_CLIENT ?
 		const char *debug_prefix = dp->dccps_role == DCCP_ROLE_CLIENT ?
 					"CLIENT rx ack: " : "server rx ack: ";
 					"CLIENT rx ack: " : "server rx ack: ";
@@ -794,7 +794,7 @@ static void dccp_ackpkts_check_rcv_ackvector(struct dccp_ackpkts *ap,
 			/* dccp_pr_debug_cat("yes\n"); */
 			/* dccp_pr_debug_cat("yes\n"); */
 
 
 			if (state != DCCP_ACKPKTS_STATE_NOT_RECEIVED) {
 			if (state != DCCP_ACKPKTS_STATE_NOT_RECEIVED) {
-#ifdef DCCP_DEBUG
+#ifdef CONFIG_IP_DCCP_DEBUG
 				struct dccp_sock *dp = dccp_sk(sk);
 				struct dccp_sock *dp = dccp_sk(sk);
 				const char *debug_prefix =
 				const char *debug_prefix =
 					dp->dccps_role == DCCP_ROLE_CLIENT ?
 					dp->dccps_role == DCCP_ROLE_CLIENT ?

+ 14 - 8
net/dccp/proto.c

@@ -503,12 +503,16 @@ static int __init dccp_ctl_sock_init(void)
 	return rc;
 	return rc;
 }
 }
 
 
-static void __exit dccp_ctl_sock_exit(void)
+#ifdef CONFIG_IP_DCCP_UNLOAD_HACK
+void dccp_ctl_sock_exit(void)
 {
 {
 	if (dccp_ctl_socket != NULL)
 	if (dccp_ctl_socket != NULL)
 		sock_release(dccp_ctl_socket);
 		sock_release(dccp_ctl_socket);
 }
 }
 
 
+EXPORT_SYMBOL_GPL(dccp_ctl_sock_exit);
+#endif
+
 static int __init init_dccp_v4_mibs(void)
 static int __init init_dccp_v4_mibs(void)
 {
 {
 	int rc = -ENOMEM;
 	int rc = -ENOMEM;
@@ -655,19 +659,21 @@ static const char dccp_del_proto_err_msg[] __exitdata =
 
 
 static void __exit dccp_fini(void)
 static void __exit dccp_fini(void)
 {
 {
-	dccp_ctl_sock_exit();
-
 	inet_unregister_protosw(&dccp_v4_protosw);
 	inet_unregister_protosw(&dccp_v4_protosw);
 
 
 	if (inet_del_protocol(&dccp_protocol, IPPROTO_DCCP) < 0)
 	if (inet_del_protocol(&dccp_protocol, IPPROTO_DCCP) < 0)
 		printk(dccp_del_proto_err_msg);
 		printk(dccp_del_proto_err_msg);
 
 
-	/* Free the control endpoint.  */
-	sock_release(dccp_ctl_socket);
-
-	proto_unregister(&dccp_v4_prot);
-
+	free_percpu(dccp_statistics[0]);
+	free_percpu(dccp_statistics[1]);
+	free_pages((unsigned long)dccp_hashinfo.bhash,
+		   get_order(dccp_hashinfo.bhash_size *
+			     sizeof(struct inet_bind_hashbucket)));
+	free_pages((unsigned long)dccp_hashinfo.ehash,
+		   get_order(dccp_hashinfo.ehash_size *
+			     sizeof(struct inet_ehash_bucket)));
 	kmem_cache_destroy(dccp_hashinfo.bind_bucket_cachep);
 	kmem_cache_destroy(dccp_hashinfo.bind_bucket_cachep);
+	proto_unregister(&dccp_v4_prot);
 }
 }
 
 
 module_init(dccp_init);
 module_init(dccp_init);