diff options
Diffstat (limited to 'net/sctp/probe.c')
| -rw-r--r-- | net/sctp/probe.c | 72 | 
1 files changed, 49 insertions, 23 deletions
diff --git a/net/sctp/probe.c b/net/sctp/probe.c index bc6cd75cc1d..5e68b94ee64 100644 --- a/net/sctp/probe.c +++ b/net/sctp/probe.c @@ -38,6 +38,7 @@  #include <net/sctp/sctp.h>  #include <net/sctp/sm.h> +MODULE_SOFTDEP("pre: sctp");  MODULE_AUTHOR("Wei Yongjun <yjwei@cn.fujitsu.com>");  MODULE_DESCRIPTION("SCTP snooper");  MODULE_LICENSE("GPL"); @@ -46,6 +47,10 @@ static int port __read_mostly = 0;  MODULE_PARM_DESC(port, "Port to match (0=all)");  module_param(port, int, 0); +static unsigned int fwmark __read_mostly = 0; +MODULE_PARM_DESC(fwmark, "skb mark to match (0=no mark)"); +module_param(fwmark, uint, 0); +  static int bufsize __read_mostly = 64 * 1024;  MODULE_PARM_DESC(bufsize, "Log buffer size (default 64k)");  module_param(bufsize, int, 0); @@ -63,7 +68,7 @@ static struct {  	struct timespec	  tstart;  } sctpw; -static void printl(const char *fmt, ...) +static __printf(1, 2) void printl(const char *fmt, ...)  {  	va_list args;  	int len; @@ -122,21 +127,26 @@ static const struct file_operations sctpprobe_fops = {  	.llseek = noop_llseek,  }; -sctp_disposition_t jsctp_sf_eat_sack(const struct sctp_endpoint *ep, -				     const struct sctp_association *asoc, -				     const sctp_subtype_t type, -				     void *arg, -				     sctp_cmd_seq_t *commands) +static sctp_disposition_t jsctp_sf_eat_sack(struct net *net, +					    const struct sctp_endpoint *ep, +					    const struct sctp_association *asoc, +					    const sctp_subtype_t type, +					    void *arg, +					    sctp_cmd_seq_t *commands)  { +	struct sctp_chunk *chunk = arg; +	struct sk_buff *skb = chunk->skb;  	struct sctp_transport *sp;  	static __u32 lcwnd = 0;  	struct timespec now;  	sp = asoc->peer.primary_path; -	if ((full || sp->cwnd != lcwnd) && -	    (!port || asoc->peer.port == port || -	     ep->base.bind_addr.port == port)) { +	if (((port == 0 && fwmark == 0) || +	     asoc->peer.port == port || +	     ep->base.bind_addr.port == port || +	     (fwmark > 0 && skb->mark == fwmark)) && +	    (full || sp->cwnd != lcwnd)) {  		lcwnd = sp->cwnd;  		getnstimeofday(&now); @@ -154,13 +164,8 @@ sctp_disposition_t jsctp_sf_eat_sack(const struct sctp_endpoint *ep,  			if (sp == asoc->peer.primary_path)  				printl("*"); -			if (sp->ipaddr.sa.sa_family == AF_INET) -				printl("%pI4 ", &sp->ipaddr.v4.sin_addr); -			else -				printl("%pI6 ", &sp->ipaddr.v6.sin6_addr); - -			printl("%2u %8u %8u %8u %8u %8u ", -			       sp->state, sp->cwnd, sp->ssthresh, +			printl("%pISc %2u %8u %8u %8u %8u %8u ", +			       &sp->ipaddr, sp->state, sp->cwnd, sp->ssthresh,  			       sp->flight_size, sp->partial_bytes_acked,  			       sp->pathmtu);  		} @@ -178,29 +183,50 @@ static struct jprobe sctp_recv_probe = {  	.entry	= jsctp_sf_eat_sack,  }; +static __init int sctp_setup_jprobe(void) +{ +	int ret = register_jprobe(&sctp_recv_probe); + +	if (ret) { +		if (request_module("sctp")) +			goto out; +		ret = register_jprobe(&sctp_recv_probe); +	} + +out: +	return ret; +} +  static __init int sctpprobe_init(void)  {  	int ret = -ENOMEM; +	/* Warning: if the function signature of sctp_sf_eat_sack_6_2, +	 * has been changed, you also have to change the signature of +	 * jsctp_sf_eat_sack, otherwise you end up right here! +	 */ +	BUILD_BUG_ON(__same_type(sctp_sf_eat_sack_6_2, +				 jsctp_sf_eat_sack) == 0); +  	init_waitqueue_head(&sctpw.wait);  	spin_lock_init(&sctpw.lock);  	if (kfifo_alloc(&sctpw.fifo, bufsize, GFP_KERNEL))  		return ret; -	if (!proc_net_fops_create(&init_net, procname, S_IRUSR, -				  &sctpprobe_fops)) +	if (!proc_create(procname, S_IRUSR, init_net.proc_net, +			 &sctpprobe_fops))  		goto free_kfifo; -	ret = register_jprobe(&sctp_recv_probe); +	ret = sctp_setup_jprobe();  	if (ret)  		goto remove_proc; -	pr_info("probe registered (port=%d)\n", port); - +	pr_info("probe registered (port=%d/fwmark=%u) bufsize=%u\n", +		port, fwmark, bufsize);  	return 0;  remove_proc: -	proc_net_remove(&init_net, procname); +	remove_proc_entry(procname, init_net.proc_net);  free_kfifo:  	kfifo_free(&sctpw.fifo);  	return ret; @@ -209,7 +235,7 @@ free_kfifo:  static __exit void sctpprobe_exit(void)  {  	kfifo_free(&sctpw.fifo); -	proc_net_remove(&init_net, procname); +	remove_proc_entry(procname, init_net.proc_net);  	unregister_jprobe(&sctp_recv_probe);  }  | 
