1787a51a0878f7bee3a9a83040077301e1556b69aWei Yongjun/* 2787a51a0878f7bee3a9a83040077301e1556b69aWei Yongjun * sctp_probe - Observe the SCTP flow with kprobes. 3787a51a0878f7bee3a9a83040077301e1556b69aWei Yongjun * 4787a51a0878f7bee3a9a83040077301e1556b69aWei Yongjun * The idea for this came from Werner Almesberger's umlsim 5787a51a0878f7bee3a9a83040077301e1556b69aWei Yongjun * Copyright (C) 2004, Stephen Hemminger <shemminger@osdl.org> 6787a51a0878f7bee3a9a83040077301e1556b69aWei Yongjun * 7787a51a0878f7bee3a9a83040077301e1556b69aWei Yongjun * Modified for SCTP from Stephen Hemminger's code 8787a51a0878f7bee3a9a83040077301e1556b69aWei Yongjun * Copyright (C) 2010, Wei Yongjun <yjwei@cn.fujitsu.com> 9787a51a0878f7bee3a9a83040077301e1556b69aWei Yongjun * 10787a51a0878f7bee3a9a83040077301e1556b69aWei Yongjun * This program is free software; you can redistribute it and/or modify 11787a51a0878f7bee3a9a83040077301e1556b69aWei Yongjun * it under the terms of the GNU General Public License as published by 12787a51a0878f7bee3a9a83040077301e1556b69aWei Yongjun * the Free Software Foundation; either version 2 of the License, or 13787a51a0878f7bee3a9a83040077301e1556b69aWei Yongjun * (at your option) any later version. 14787a51a0878f7bee3a9a83040077301e1556b69aWei Yongjun * 15787a51a0878f7bee3a9a83040077301e1556b69aWei Yongjun * This program is distributed in the hope that it will be useful, 16787a51a0878f7bee3a9a83040077301e1556b69aWei Yongjun * but WITHOUT ANY WARRANTY; without even the implied warranty of 17787a51a0878f7bee3a9a83040077301e1556b69aWei Yongjun * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18787a51a0878f7bee3a9a83040077301e1556b69aWei Yongjun * GNU General Public License for more details. 19787a51a0878f7bee3a9a83040077301e1556b69aWei Yongjun * 20787a51a0878f7bee3a9a83040077301e1556b69aWei Yongjun * You should have received a copy of the GNU General Public License 21787a51a0878f7bee3a9a83040077301e1556b69aWei Yongjun * along with this program; if not, write to the Free Software 22787a51a0878f7bee3a9a83040077301e1556b69aWei Yongjun * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 23787a51a0878f7bee3a9a83040077301e1556b69aWei Yongjun */ 24787a51a0878f7bee3a9a83040077301e1556b69aWei Yongjun 25145ce502e44b57c074c72cfdc855557e19026999Joe Perches#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt 26145ce502e44b57c074c72cfdc855557e19026999Joe Perches 27787a51a0878f7bee3a9a83040077301e1556b69aWei Yongjun#include <linux/kernel.h> 28787a51a0878f7bee3a9a83040077301e1556b69aWei Yongjun#include <linux/kprobes.h> 29787a51a0878f7bee3a9a83040077301e1556b69aWei Yongjun#include <linux/socket.h> 30787a51a0878f7bee3a9a83040077301e1556b69aWei Yongjun#include <linux/sctp.h> 31787a51a0878f7bee3a9a83040077301e1556b69aWei Yongjun#include <linux/proc_fs.h> 32f5460618405eec8c3300947a499011528a115acdDavid S. Miller#include <linux/vmalloc.h> 33787a51a0878f7bee3a9a83040077301e1556b69aWei Yongjun#include <linux/module.h> 34787a51a0878f7bee3a9a83040077301e1556b69aWei Yongjun#include <linux/kfifo.h> 35787a51a0878f7bee3a9a83040077301e1556b69aWei Yongjun#include <linux/time.h> 36787a51a0878f7bee3a9a83040077301e1556b69aWei Yongjun#include <net/net_namespace.h> 37787a51a0878f7bee3a9a83040077301e1556b69aWei Yongjun 38787a51a0878f7bee3a9a83040077301e1556b69aWei Yongjun#include <net/sctp/sctp.h> 39787a51a0878f7bee3a9a83040077301e1556b69aWei Yongjun#include <net/sctp/sm.h> 40787a51a0878f7bee3a9a83040077301e1556b69aWei Yongjun 419bd7d20c45157c175bfd45449e904a404506f99cwangweidongMODULE_SOFTDEP("pre: sctp"); 42787a51a0878f7bee3a9a83040077301e1556b69aWei YongjunMODULE_AUTHOR("Wei Yongjun <yjwei@cn.fujitsu.com>"); 43787a51a0878f7bee3a9a83040077301e1556b69aWei YongjunMODULE_DESCRIPTION("SCTP snooper"); 44787a51a0878f7bee3a9a83040077301e1556b69aWei YongjunMODULE_LICENSE("GPL"); 45787a51a0878f7bee3a9a83040077301e1556b69aWei Yongjun 46787a51a0878f7bee3a9a83040077301e1556b69aWei Yongjunstatic int port __read_mostly = 0; 47787a51a0878f7bee3a9a83040077301e1556b69aWei YongjunMODULE_PARM_DESC(port, "Port to match (0=all)"); 48787a51a0878f7bee3a9a83040077301e1556b69aWei Yongjunmodule_param(port, int, 0); 49787a51a0878f7bee3a9a83040077301e1556b69aWei Yongjun 50b1b72076b90d631637497b35e36bc64254df199dDaniel Borkmannstatic unsigned int fwmark __read_mostly = 0; 51b1b72076b90d631637497b35e36bc64254df199dDaniel BorkmannMODULE_PARM_DESC(fwmark, "skb mark to match (0=no mark)"); 52b1b72076b90d631637497b35e36bc64254df199dDaniel Borkmannmodule_param(fwmark, uint, 0); 53b1b72076b90d631637497b35e36bc64254df199dDaniel Borkmann 54787a51a0878f7bee3a9a83040077301e1556b69aWei Yongjunstatic int bufsize __read_mostly = 64 * 1024; 55787a51a0878f7bee3a9a83040077301e1556b69aWei YongjunMODULE_PARM_DESC(bufsize, "Log buffer size (default 64k)"); 56787a51a0878f7bee3a9a83040077301e1556b69aWei Yongjunmodule_param(bufsize, int, 0); 57787a51a0878f7bee3a9a83040077301e1556b69aWei Yongjun 58787a51a0878f7bee3a9a83040077301e1556b69aWei Yongjunstatic int full __read_mostly = 1; 59787a51a0878f7bee3a9a83040077301e1556b69aWei YongjunMODULE_PARM_DESC(full, "Full log (1=every ack packet received, 0=only cwnd changes)"); 60787a51a0878f7bee3a9a83040077301e1556b69aWei Yongjunmodule_param(full, int, 0); 61787a51a0878f7bee3a9a83040077301e1556b69aWei Yongjun 62787a51a0878f7bee3a9a83040077301e1556b69aWei Yongjunstatic const char procname[] = "sctpprobe"; 63787a51a0878f7bee3a9a83040077301e1556b69aWei Yongjun 64787a51a0878f7bee3a9a83040077301e1556b69aWei Yongjunstatic struct { 65787a51a0878f7bee3a9a83040077301e1556b69aWei Yongjun struct kfifo fifo; 66787a51a0878f7bee3a9a83040077301e1556b69aWei Yongjun spinlock_t lock; 67787a51a0878f7bee3a9a83040077301e1556b69aWei Yongjun wait_queue_head_t wait; 68787a51a0878f7bee3a9a83040077301e1556b69aWei Yongjun struct timespec tstart; 69787a51a0878f7bee3a9a83040077301e1556b69aWei Yongjun} sctpw; 70787a51a0878f7bee3a9a83040077301e1556b69aWei Yongjun 71be3e45810bb1ee0bdfa93f6b9532d8c451e50f48Daniel Borkmannstatic __printf(1, 2) void printl(const char *fmt, ...) 72787a51a0878f7bee3a9a83040077301e1556b69aWei Yongjun{ 73787a51a0878f7bee3a9a83040077301e1556b69aWei Yongjun va_list args; 74787a51a0878f7bee3a9a83040077301e1556b69aWei Yongjun int len; 75787a51a0878f7bee3a9a83040077301e1556b69aWei Yongjun char tbuf[256]; 76787a51a0878f7bee3a9a83040077301e1556b69aWei Yongjun 77787a51a0878f7bee3a9a83040077301e1556b69aWei Yongjun va_start(args, fmt); 78787a51a0878f7bee3a9a83040077301e1556b69aWei Yongjun len = vscnprintf(tbuf, sizeof(tbuf), fmt, args); 79787a51a0878f7bee3a9a83040077301e1556b69aWei Yongjun va_end(args); 80787a51a0878f7bee3a9a83040077301e1556b69aWei Yongjun 81787a51a0878f7bee3a9a83040077301e1556b69aWei Yongjun kfifo_in_locked(&sctpw.fifo, tbuf, len, &sctpw.lock); 82787a51a0878f7bee3a9a83040077301e1556b69aWei Yongjun wake_up(&sctpw.wait); 83787a51a0878f7bee3a9a83040077301e1556b69aWei Yongjun} 84787a51a0878f7bee3a9a83040077301e1556b69aWei Yongjun 85787a51a0878f7bee3a9a83040077301e1556b69aWei Yongjunstatic int sctpprobe_open(struct inode *inode, struct file *file) 86787a51a0878f7bee3a9a83040077301e1556b69aWei Yongjun{ 87787a51a0878f7bee3a9a83040077301e1556b69aWei Yongjun kfifo_reset(&sctpw.fifo); 88787a51a0878f7bee3a9a83040077301e1556b69aWei Yongjun getnstimeofday(&sctpw.tstart); 89787a51a0878f7bee3a9a83040077301e1556b69aWei Yongjun 90787a51a0878f7bee3a9a83040077301e1556b69aWei Yongjun return 0; 91787a51a0878f7bee3a9a83040077301e1556b69aWei Yongjun} 92787a51a0878f7bee3a9a83040077301e1556b69aWei Yongjun 93787a51a0878f7bee3a9a83040077301e1556b69aWei Yongjunstatic ssize_t sctpprobe_read(struct file *file, char __user *buf, 94787a51a0878f7bee3a9a83040077301e1556b69aWei Yongjun size_t len, loff_t *ppos) 95787a51a0878f7bee3a9a83040077301e1556b69aWei Yongjun{ 96787a51a0878f7bee3a9a83040077301e1556b69aWei Yongjun int error = 0, cnt = 0; 97787a51a0878f7bee3a9a83040077301e1556b69aWei Yongjun unsigned char *tbuf; 98787a51a0878f7bee3a9a83040077301e1556b69aWei Yongjun 99787a51a0878f7bee3a9a83040077301e1556b69aWei Yongjun if (!buf) 100787a51a0878f7bee3a9a83040077301e1556b69aWei Yongjun return -EINVAL; 101787a51a0878f7bee3a9a83040077301e1556b69aWei Yongjun 102787a51a0878f7bee3a9a83040077301e1556b69aWei Yongjun if (len == 0) 103787a51a0878f7bee3a9a83040077301e1556b69aWei Yongjun return 0; 104787a51a0878f7bee3a9a83040077301e1556b69aWei Yongjun 105787a51a0878f7bee3a9a83040077301e1556b69aWei Yongjun tbuf = vmalloc(len); 106787a51a0878f7bee3a9a83040077301e1556b69aWei Yongjun if (!tbuf) 107787a51a0878f7bee3a9a83040077301e1556b69aWei Yongjun return -ENOMEM; 108787a51a0878f7bee3a9a83040077301e1556b69aWei Yongjun 109787a51a0878f7bee3a9a83040077301e1556b69aWei Yongjun error = wait_event_interruptible(sctpw.wait, 110787a51a0878f7bee3a9a83040077301e1556b69aWei Yongjun kfifo_len(&sctpw.fifo) != 0); 111787a51a0878f7bee3a9a83040077301e1556b69aWei Yongjun if (error) 112787a51a0878f7bee3a9a83040077301e1556b69aWei Yongjun goto out_free; 113787a51a0878f7bee3a9a83040077301e1556b69aWei Yongjun 114787a51a0878f7bee3a9a83040077301e1556b69aWei Yongjun cnt = kfifo_out_locked(&sctpw.fifo, tbuf, len, &sctpw.lock); 115787a51a0878f7bee3a9a83040077301e1556b69aWei Yongjun error = copy_to_user(buf, tbuf, cnt) ? -EFAULT : 0; 116787a51a0878f7bee3a9a83040077301e1556b69aWei Yongjun 117787a51a0878f7bee3a9a83040077301e1556b69aWei Yongjunout_free: 118787a51a0878f7bee3a9a83040077301e1556b69aWei Yongjun vfree(tbuf); 119787a51a0878f7bee3a9a83040077301e1556b69aWei Yongjun 120787a51a0878f7bee3a9a83040077301e1556b69aWei Yongjun return error ? error : cnt; 121787a51a0878f7bee3a9a83040077301e1556b69aWei Yongjun} 122787a51a0878f7bee3a9a83040077301e1556b69aWei Yongjun 123787a51a0878f7bee3a9a83040077301e1556b69aWei Yongjunstatic const struct file_operations sctpprobe_fops = { 124787a51a0878f7bee3a9a83040077301e1556b69aWei Yongjun .owner = THIS_MODULE, 125787a51a0878f7bee3a9a83040077301e1556b69aWei Yongjun .open = sctpprobe_open, 126787a51a0878f7bee3a9a83040077301e1556b69aWei Yongjun .read = sctpprobe_read, 1276038f373a3dc1f1c26496e60b6c40b164716f07eArnd Bergmann .llseek = noop_llseek, 128787a51a0878f7bee3a9a83040077301e1556b69aWei Yongjun}; 129787a51a0878f7bee3a9a83040077301e1556b69aWei Yongjun 1301e558174637689a53a24b4c94f6f1aed38361b3eDaniel Borkmannstatic sctp_disposition_t jsctp_sf_eat_sack(struct net *net, 1311e558174637689a53a24b4c94f6f1aed38361b3eDaniel Borkmann const struct sctp_endpoint *ep, 1321e558174637689a53a24b4c94f6f1aed38361b3eDaniel Borkmann const struct sctp_association *asoc, 1331e558174637689a53a24b4c94f6f1aed38361b3eDaniel Borkmann const sctp_subtype_t type, 1341e558174637689a53a24b4c94f6f1aed38361b3eDaniel Borkmann void *arg, 1351e558174637689a53a24b4c94f6f1aed38361b3eDaniel Borkmann sctp_cmd_seq_t *commands) 136787a51a0878f7bee3a9a83040077301e1556b69aWei Yongjun{ 137b1b72076b90d631637497b35e36bc64254df199dDaniel Borkmann struct sctp_chunk *chunk = arg; 138b1b72076b90d631637497b35e36bc64254df199dDaniel Borkmann struct sk_buff *skb = chunk->skb; 139787a51a0878f7bee3a9a83040077301e1556b69aWei Yongjun struct sctp_transport *sp; 140787a51a0878f7bee3a9a83040077301e1556b69aWei Yongjun static __u32 lcwnd = 0; 141787a51a0878f7bee3a9a83040077301e1556b69aWei Yongjun struct timespec now; 142787a51a0878f7bee3a9a83040077301e1556b69aWei Yongjun 143787a51a0878f7bee3a9a83040077301e1556b69aWei Yongjun sp = asoc->peer.primary_path; 144787a51a0878f7bee3a9a83040077301e1556b69aWei Yongjun 145b1b72076b90d631637497b35e36bc64254df199dDaniel Borkmann if (((port == 0 && fwmark == 0) || 146b1b72076b90d631637497b35e36bc64254df199dDaniel Borkmann asoc->peer.port == port || 147b1b72076b90d631637497b35e36bc64254df199dDaniel Borkmann ep->base.bind_addr.port == port || 148b1b72076b90d631637497b35e36bc64254df199dDaniel Borkmann (fwmark > 0 && skb->mark == fwmark)) && 149b1b72076b90d631637497b35e36bc64254df199dDaniel Borkmann (full || sp->cwnd != lcwnd)) { 150787a51a0878f7bee3a9a83040077301e1556b69aWei Yongjun lcwnd = sp->cwnd; 151787a51a0878f7bee3a9a83040077301e1556b69aWei Yongjun 152787a51a0878f7bee3a9a83040077301e1556b69aWei Yongjun getnstimeofday(&now); 153787a51a0878f7bee3a9a83040077301e1556b69aWei Yongjun now = timespec_sub(now, sctpw.tstart); 154787a51a0878f7bee3a9a83040077301e1556b69aWei Yongjun 155787a51a0878f7bee3a9a83040077301e1556b69aWei Yongjun printl("%lu.%06lu ", (unsigned long) now.tv_sec, 156787a51a0878f7bee3a9a83040077301e1556b69aWei Yongjun (unsigned long) now.tv_nsec / NSEC_PER_USEC); 157787a51a0878f7bee3a9a83040077301e1556b69aWei Yongjun 158787a51a0878f7bee3a9a83040077301e1556b69aWei Yongjun printl("%p %5d %5d %5d %8d %5d ", asoc, 159787a51a0878f7bee3a9a83040077301e1556b69aWei Yongjun ep->base.bind_addr.port, asoc->peer.port, 160787a51a0878f7bee3a9a83040077301e1556b69aWei Yongjun asoc->pathmtu, asoc->peer.rwnd, asoc->unack_data); 161787a51a0878f7bee3a9a83040077301e1556b69aWei Yongjun 162787a51a0878f7bee3a9a83040077301e1556b69aWei Yongjun list_for_each_entry(sp, &asoc->peer.transport_addr_list, 163787a51a0878f7bee3a9a83040077301e1556b69aWei Yongjun transports) { 164787a51a0878f7bee3a9a83040077301e1556b69aWei Yongjun if (sp == asoc->peer.primary_path) 165787a51a0878f7bee3a9a83040077301e1556b69aWei Yongjun printl("*"); 166787a51a0878f7bee3a9a83040077301e1556b69aWei Yongjun 16705f147ef7c5289e9aba488b3e71a4259be5a1420Daniel Borkmann printl("%pISc %2u %8u %8u %8u %8u %8u ", 16805f147ef7c5289e9aba488b3e71a4259be5a1420Daniel Borkmann &sp->ipaddr, sp->state, sp->cwnd, sp->ssthresh, 169787a51a0878f7bee3a9a83040077301e1556b69aWei Yongjun sp->flight_size, sp->partial_bytes_acked, 170787a51a0878f7bee3a9a83040077301e1556b69aWei Yongjun sp->pathmtu); 171787a51a0878f7bee3a9a83040077301e1556b69aWei Yongjun } 172787a51a0878f7bee3a9a83040077301e1556b69aWei Yongjun printl("\n"); 173787a51a0878f7bee3a9a83040077301e1556b69aWei Yongjun } 174787a51a0878f7bee3a9a83040077301e1556b69aWei Yongjun 175787a51a0878f7bee3a9a83040077301e1556b69aWei Yongjun jprobe_return(); 176787a51a0878f7bee3a9a83040077301e1556b69aWei Yongjun return 0; 177787a51a0878f7bee3a9a83040077301e1556b69aWei Yongjun} 178787a51a0878f7bee3a9a83040077301e1556b69aWei Yongjun 179787a51a0878f7bee3a9a83040077301e1556b69aWei Yongjunstatic struct jprobe sctp_recv_probe = { 180787a51a0878f7bee3a9a83040077301e1556b69aWei Yongjun .kp = { 181787a51a0878f7bee3a9a83040077301e1556b69aWei Yongjun .symbol_name = "sctp_sf_eat_sack_6_2", 182787a51a0878f7bee3a9a83040077301e1556b69aWei Yongjun }, 183787a51a0878f7bee3a9a83040077301e1556b69aWei Yongjun .entry = jsctp_sf_eat_sack, 184787a51a0878f7bee3a9a83040077301e1556b69aWei Yongjun}; 185787a51a0878f7bee3a9a83040077301e1556b69aWei Yongjun 1869bd7d20c45157c175bfd45449e904a404506f99cwangweidongstatic __init int sctp_setup_jprobe(void) 1879bd7d20c45157c175bfd45449e904a404506f99cwangweidong{ 1889bd7d20c45157c175bfd45449e904a404506f99cwangweidong int ret = register_jprobe(&sctp_recv_probe); 1899bd7d20c45157c175bfd45449e904a404506f99cwangweidong 1909bd7d20c45157c175bfd45449e904a404506f99cwangweidong if (ret) { 1919bd7d20c45157c175bfd45449e904a404506f99cwangweidong if (request_module("sctp")) 1929bd7d20c45157c175bfd45449e904a404506f99cwangweidong goto out; 1939bd7d20c45157c175bfd45449e904a404506f99cwangweidong ret = register_jprobe(&sctp_recv_probe); 1949bd7d20c45157c175bfd45449e904a404506f99cwangweidong } 1959bd7d20c45157c175bfd45449e904a404506f99cwangweidong 1969bd7d20c45157c175bfd45449e904a404506f99cwangweidongout: 1979bd7d20c45157c175bfd45449e904a404506f99cwangweidong return ret; 1989bd7d20c45157c175bfd45449e904a404506f99cwangweidong} 1999bd7d20c45157c175bfd45449e904a404506f99cwangweidong 200787a51a0878f7bee3a9a83040077301e1556b69aWei Yongjunstatic __init int sctpprobe_init(void) 201787a51a0878f7bee3a9a83040077301e1556b69aWei Yongjun{ 202787a51a0878f7bee3a9a83040077301e1556b69aWei Yongjun int ret = -ENOMEM; 203787a51a0878f7bee3a9a83040077301e1556b69aWei Yongjun 204222229974824a4f30b417531cdc9b5b869d6a6b7Daniel Borkmann /* Warning: if the function signature of sctp_sf_eat_sack_6_2, 205222229974824a4f30b417531cdc9b5b869d6a6b7Daniel Borkmann * has been changed, you also have to change the signature of 206222229974824a4f30b417531cdc9b5b869d6a6b7Daniel Borkmann * jsctp_sf_eat_sack, otherwise you end up right here! 207222229974824a4f30b417531cdc9b5b869d6a6b7Daniel Borkmann */ 208222229974824a4f30b417531cdc9b5b869d6a6b7Daniel Borkmann BUILD_BUG_ON(__same_type(sctp_sf_eat_sack_6_2, 209222229974824a4f30b417531cdc9b5b869d6a6b7Daniel Borkmann jsctp_sf_eat_sack) == 0); 210222229974824a4f30b417531cdc9b5b869d6a6b7Daniel Borkmann 211787a51a0878f7bee3a9a83040077301e1556b69aWei Yongjun init_waitqueue_head(&sctpw.wait); 212787a51a0878f7bee3a9a83040077301e1556b69aWei Yongjun spin_lock_init(&sctpw.lock); 213787a51a0878f7bee3a9a83040077301e1556b69aWei Yongjun if (kfifo_alloc(&sctpw.fifo, bufsize, GFP_KERNEL)) 214787a51a0878f7bee3a9a83040077301e1556b69aWei Yongjun return ret; 215787a51a0878f7bee3a9a83040077301e1556b69aWei Yongjun 216d4beaa66add8aebf83ab16d2fde4e4de8dac36dfGao feng if (!proc_create(procname, S_IRUSR, init_net.proc_net, 217d4beaa66add8aebf83ab16d2fde4e4de8dac36dfGao feng &sctpprobe_fops)) 218787a51a0878f7bee3a9a83040077301e1556b69aWei Yongjun goto free_kfifo; 219787a51a0878f7bee3a9a83040077301e1556b69aWei Yongjun 2209bd7d20c45157c175bfd45449e904a404506f99cwangweidong ret = sctp_setup_jprobe(); 221787a51a0878f7bee3a9a83040077301e1556b69aWei Yongjun if (ret) 222787a51a0878f7bee3a9a83040077301e1556b69aWei Yongjun goto remove_proc; 223787a51a0878f7bee3a9a83040077301e1556b69aWei Yongjun 224b1b72076b90d631637497b35e36bc64254df199dDaniel Borkmann pr_info("probe registered (port=%d/fwmark=%u) bufsize=%u\n", 225b1b72076b90d631637497b35e36bc64254df199dDaniel Borkmann port, fwmark, bufsize); 226787a51a0878f7bee3a9a83040077301e1556b69aWei Yongjun return 0; 227787a51a0878f7bee3a9a83040077301e1556b69aWei Yongjun 228787a51a0878f7bee3a9a83040077301e1556b69aWei Yongjunremove_proc: 229ece31ffd539e8e2b586b1ca5f50bc4f4591e3893Gao feng remove_proc_entry(procname, init_net.proc_net); 230787a51a0878f7bee3a9a83040077301e1556b69aWei Yongjunfree_kfifo: 231787a51a0878f7bee3a9a83040077301e1556b69aWei Yongjun kfifo_free(&sctpw.fifo); 232787a51a0878f7bee3a9a83040077301e1556b69aWei Yongjun return ret; 233787a51a0878f7bee3a9a83040077301e1556b69aWei Yongjun} 234787a51a0878f7bee3a9a83040077301e1556b69aWei Yongjun 235787a51a0878f7bee3a9a83040077301e1556b69aWei Yongjunstatic __exit void sctpprobe_exit(void) 236787a51a0878f7bee3a9a83040077301e1556b69aWei Yongjun{ 237787a51a0878f7bee3a9a83040077301e1556b69aWei Yongjun kfifo_free(&sctpw.fifo); 238ece31ffd539e8e2b586b1ca5f50bc4f4591e3893Gao feng remove_proc_entry(procname, init_net.proc_net); 239787a51a0878f7bee3a9a83040077301e1556b69aWei Yongjun unregister_jprobe(&sctp_recv_probe); 240787a51a0878f7bee3a9a83040077301e1556b69aWei Yongjun} 241787a51a0878f7bee3a9a83040077301e1556b69aWei Yongjun 242787a51a0878f7bee3a9a83040077301e1556b69aWei Yongjunmodule_init(sctpprobe_init); 243787a51a0878f7bee3a9a83040077301e1556b69aWei Yongjunmodule_exit(sctpprobe_exit); 244