Commit 725ba8ee authored by Arnaldo Carvalho de Melo's avatar Arnaldo Carvalho de Melo Committed by David S. Miller

[DCCP]: Introduce the DCCP Kernel hacking menu

Only available if CONFIG_DEBUG_KERNEL is enabled in the "Kernel
Hacking" Menu.
Signed-off-by: default avatarArnaldo Carvalho de Melo <acme@mandriva.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 531669a0
...@@ -26,4 +26,25 @@ config INET_DCCP_DIAG ...@@ -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
...@@ -2078,6 +2078,15 @@ module_init(ccid3_module_init); ...@@ -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) {
......
...@@ -11,14 +11,13 @@ ...@@ -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 CONFIG_IP_DCCP_DEBUG
#ifdef 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); ...@@ -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);
......
...@@ -58,7 +58,7 @@ static u32 dccp_decode_value_var(const unsigned char *bf, const u8 len) ...@@ -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, ...@@ -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); ...@@ -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, ...@@ -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) ...@@ -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) ...@@ -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 @@ int dccp_ackpkts_add(struct dccp_ackpkts *ap, u64 ackno, u8 state) ...@@ -680,7 +680,7 @@ int dccp_ackpkts_add(struct dccp_ackpkts *ap, u64 ackno, u8 state)
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, ...@@ -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, ...@@ -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 ?
......
...@@ -503,12 +503,16 @@ static int __init dccp_ctl_sock_init(void) ...@@ -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 = ...@@ -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. */ free_percpu(dccp_statistics[0]);
sock_release(dccp_ctl_socket); free_percpu(dccp_statistics[1]);
free_pages((unsigned long)dccp_hashinfo.bhash,
proto_unregister(&dccp_v4_prot); 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);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment