Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
bug2833
cloud-kernel
提交
508862e4
cloud-kernel
项目概览
bug2833
/
cloud-kernel
与 Fork 源项目一致
Fork自
openanolis / cloud-kernel
通知
1
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
cloud-kernel
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
提交
508862e4
编写于
11月 11, 2005
作者:
L
Linus Torvalds
浏览文件
操作
浏览文件
下载
差异文件
Merge master.kernel.org:/pub/scm/linux/kernel/git/davem/net-2.6
上级
9cf93d7b
049b3ff5
变更
13
显示空白变更内容
内联
并排
Showing
13 changed file
with
109 addition
and
76 deletion
+109
-76
include/linux/sysctl.h
include/linux/sysctl.h
+1
-0
include/net/sctp/command.h
include/net/sctp/command.h
+4
-3
include/net/sctp/structs.h
include/net/sctp/structs.h
+16
-3
net/ipv6/af_inet6.c
net/ipv6/af_inet6.c
+6
-2
net/sctp/associola.c
net/sctp/associola.c
+29
-4
net/sctp/endpointola.c
net/sctp/endpointola.c
+3
-23
net/sctp/input.c
net/sctp/input.c
+0
-20
net/sctp/protocol.c
net/sctp/protocol.c
+6
-0
net/sctp/sm_sideeffect.c
net/sctp/sm_sideeffect.c
+3
-3
net/sctp/sm_statefuns.c
net/sctp/sm_statefuns.c
+22
-0
net/sctp/socket.c
net/sctp/socket.c
+4
-1
net/sctp/sysctl.c
net/sctp/sysctl.c
+8
-0
net/sctp/ulpevent.c
net/sctp/ulpevent.c
+7
-17
未找到文件。
include/linux/sysctl.h
浏览文件 @
508862e4
...
...
@@ -715,6 +715,7 @@ enum {
NET_SCTP_PRSCTP_ENABLE
=
14
,
NET_SCTP_SNDBUF_POLICY
=
15
,
NET_SCTP_SACK_TIMEOUT
=
16
,
NET_SCTP_RCVBUF_POLICY
=
17
,
};
/* /proc/sys/net/bridge */
...
...
include/net/sctp/command.h
浏览文件 @
508862e4
...
...
@@ -120,6 +120,7 @@ typedef union {
int
error
;
sctp_state_t
state
;
sctp_event_timeout_t
to
;
unsigned
long
zero
;
void
*
ptr
;
struct
sctp_chunk
*
chunk
;
struct
sctp_association
*
asoc
;
...
...
@@ -148,17 +149,17 @@ static inline sctp_arg_t SCTP_NULL(void)
}
static
inline
sctp_arg_t
SCTP_NOFORCE
(
void
)
{
sctp_arg_t
retval
;
retval
.
i32
=
0
;
return
retval
;
sctp_arg_t
retval
=
{.
zero
=
0UL
}
;
retval
.
i32
=
0
;
return
retval
;
}
static
inline
sctp_arg_t
SCTP_FORCE
(
void
)
{
sctp_arg_t
retval
;
retval
.
i32
=
1
;
return
retval
;
sctp_arg_t
retval
=
{.
zero
=
0UL
}
;
retval
.
i32
=
1
;
return
retval
;
}
#define SCTP_ARG_CONSTRUCTOR(name, type, elt) \
static inline sctp_arg_t \
SCTP_## name (type arg) \
{ sctp_arg_t retval; retval.elt = arg; return retval; }
{ sctp_arg_t retval
= {.zero = 0UL}
; retval.elt = arg; return retval; }
SCTP_ARG_CONSTRUCTOR
(
I32
,
__s32
,
i32
)
SCTP_ARG_CONSTRUCTOR
(
U32
,
__u32
,
u32
)
...
...
include/net/sctp/structs.h
浏览文件 @
508862e4
...
...
@@ -161,6 +161,13 @@ extern struct sctp_globals {
*/
int
sndbuf_policy
;
/*
* Policy for preforming sctp/socket accounting
* 0 - do socket level accounting, all assocs share sk_rcvbuf
* 1 - do sctp accounting, each asoc may use sk_rcvbuf bytes
*/
int
rcvbuf_policy
;
/* Delayed SACK timeout 200ms default*/
int
sack_timeout
;
...
...
@@ -218,6 +225,7 @@ extern struct sctp_globals {
#define sctp_cookie_preserve_enable (sctp_globals.cookie_preserve_enable)
#define sctp_max_retrans_association (sctp_globals.max_retrans_association)
#define sctp_sndbuf_policy (sctp_globals.sndbuf_policy)
#define sctp_rcvbuf_policy (sctp_globals.rcvbuf_policy)
#define sctp_max_retrans_path (sctp_globals.max_retrans_path)
#define sctp_max_retrans_init (sctp_globals.max_retrans_init)
#define sctp_sack_timeout (sctp_globals.sack_timeout)
...
...
@@ -1222,11 +1230,11 @@ struct sctp_endpoint {
int
last_key
;
int
key_changed_at
;
/* Default timeouts. */
int
timeouts
[
SCTP_NUM_TIMEOUT_TYPES
];
/* sendbuf acct. policy. */
__u32
sndbuf_policy
;
/* rcvbuf acct. policy. */
__u32
rcvbuf_policy
;
};
/* Recover the outter endpoint structure. */
...
...
@@ -1553,6 +1561,11 @@ struct sctp_association {
*/
int
sndbuf_used
;
/* This is the amount of memory that this association has allocated
* in the receive path at any given time.
*/
atomic_t
rmem_alloc
;
/* This is the wait queue head for send requests waiting on
* the association sndbuf space.
*/
...
...
net/ipv6/af_inet6.c
浏览文件 @
508862e4
...
...
@@ -699,12 +699,14 @@ static int __init inet6_init(void)
/* Register the family here so that the init calls below will
* be able to create sockets. (?? is this dangerous ??)
*/
(
void
)
sock_register
(
&
inet6_family_ops
);
err
=
sock_register
(
&
inet6_family_ops
);
if
(
err
)
goto
out_unregister_raw_proto
;
/* Initialise ipv6 mibs */
err
=
init_ipv6_mibs
();
if
(
err
)
goto
out_unregister_
raw_proto
;
goto
out_unregister_
sock
;
/*
* ipngwg API draft makes clear that the correct semantics
...
...
@@ -796,6 +798,8 @@ static int __init inet6_init(void)
ipv6_sysctl_unregister
();
#endif
cleanup_ipv6_mibs
();
out_unregister_sock:
sock_unregister
(
PF_INET6
);
out_unregister_raw_proto:
proto_unregister
(
&
rawv6_prot
);
out_unregister_udp_proto:
...
...
net/sctp/associola.c
浏览文件 @
508862e4
...
...
@@ -128,9 +128,29 @@ static struct sctp_association *sctp_association_init(struct sctp_association *a
*/
asoc
->
max_burst
=
sctp_max_burst
;
/* Copy things from the endpoint. */
/* initialize association timers */
asoc
->
timeouts
[
SCTP_EVENT_TIMEOUT_NONE
]
=
0
;
asoc
->
timeouts
[
SCTP_EVENT_TIMEOUT_T1_COOKIE
]
=
asoc
->
rto_initial
;
asoc
->
timeouts
[
SCTP_EVENT_TIMEOUT_T1_INIT
]
=
asoc
->
rto_initial
;
asoc
->
timeouts
[
SCTP_EVENT_TIMEOUT_T2_SHUTDOWN
]
=
asoc
->
rto_initial
;
asoc
->
timeouts
[
SCTP_EVENT_TIMEOUT_T3_RTX
]
=
0
;
asoc
->
timeouts
[
SCTP_EVENT_TIMEOUT_T4_RTO
]
=
0
;
/* sctpimpguide Section 2.12.2
* If the 'T5-shutdown-guard' timer is used, it SHOULD be set to the
* recommended value of 5 times 'RTO.Max'.
*/
asoc
->
timeouts
[
SCTP_EVENT_TIMEOUT_T5_SHUTDOWN_GUARD
]
=
5
*
asoc
->
rto_max
;
asoc
->
timeouts
[
SCTP_EVENT_TIMEOUT_HEARTBEAT
]
=
0
;
asoc
->
timeouts
[
SCTP_EVENT_TIMEOUT_SACK
]
=
SCTP_DEFAULT_TIMEOUT_SACK
;
asoc
->
timeouts
[
SCTP_EVENT_TIMEOUT_AUTOCLOSE
]
=
sp
->
autoclose
*
HZ
;
/* Initilizes the timers */
for
(
i
=
SCTP_EVENT_TIMEOUT_NONE
;
i
<
SCTP_NUM_TIMEOUT_TYPES
;
++
i
)
{
asoc
->
timeouts
[
i
]
=
ep
->
timeouts
[
i
];
init_timer
(
&
asoc
->
timers
[
i
]);
asoc
->
timers
[
i
].
function
=
sctp_timer_events
[
i
];
asoc
->
timers
[
i
].
data
=
(
unsigned
long
)
asoc
;
...
...
@@ -157,10 +177,10 @@ static struct sctp_association *sctp_association_init(struct sctp_association *a
* RFC 6 - A SCTP receiver MUST be able to receive a minimum of
* 1500 bytes in one SCTP packet.
*/
if
(
sk
->
sk_rcvbuf
<
SCTP_DEFAULT_MINWINDOW
)
if
(
(
sk
->
sk_rcvbuf
/
2
)
<
SCTP_DEFAULT_MINWINDOW
)
asoc
->
rwnd
=
SCTP_DEFAULT_MINWINDOW
;
else
asoc
->
rwnd
=
sk
->
sk_rcvbuf
;
asoc
->
rwnd
=
sk
->
sk_rcvbuf
/
2
;
asoc
->
a_rwnd
=
asoc
->
rwnd
;
...
...
@@ -172,6 +192,9 @@ static struct sctp_association *sctp_association_init(struct sctp_association *a
/* Set the sndbuf size for transmit. */
asoc
->
sndbuf_used
=
0
;
/* Initialize the receive memory counter */
atomic_set
(
&
asoc
->
rmem_alloc
,
0
);
init_waitqueue_head
(
&
asoc
->
wait
);
asoc
->
c
.
my_vtag
=
sctp_generate_tag
(
ep
);
...
...
@@ -380,6 +403,8 @@ static void sctp_association_destroy(struct sctp_association *asoc)
spin_unlock_bh
(
&
sctp_assocs_id_lock
);
}
BUG_TRAP
(
!
atomic_read
(
&
asoc
->
rmem_alloc
));
if
(
asoc
->
base
.
malloced
)
{
kfree
(
asoc
);
SCTP_DBG_OBJCNT_DEC
(
assoc
);
...
...
net/sctp/endpointola.c
浏览文件 @
508862e4
...
...
@@ -70,7 +70,6 @@ static struct sctp_endpoint *sctp_endpoint_init(struct sctp_endpoint *ep,
struct
sock
*
sk
,
gfp_t
gfp
)
{
struct
sctp_sock
*
sp
=
sctp_sk
(
sk
);
memset
(
ep
,
0
,
sizeof
(
struct
sctp_endpoint
));
/* Initialize the base structure. */
...
...
@@ -100,33 +99,14 @@ static struct sctp_endpoint *sctp_endpoint_init(struct sctp_endpoint *ep,
/* Create the lists of associations. */
INIT_LIST_HEAD
(
&
ep
->
asocs
);
/* Set up the base timeout information. */
ep
->
timeouts
[
SCTP_EVENT_TIMEOUT_NONE
]
=
0
;
ep
->
timeouts
[
SCTP_EVENT_TIMEOUT_T1_COOKIE
]
=
msecs_to_jiffies
(
sp
->
rtoinfo
.
srto_initial
);
ep
->
timeouts
[
SCTP_EVENT_TIMEOUT_T1_INIT
]
=
msecs_to_jiffies
(
sp
->
rtoinfo
.
srto_initial
);
ep
->
timeouts
[
SCTP_EVENT_TIMEOUT_T2_SHUTDOWN
]
=
msecs_to_jiffies
(
sp
->
rtoinfo
.
srto_initial
);
ep
->
timeouts
[
SCTP_EVENT_TIMEOUT_T3_RTX
]
=
0
;
ep
->
timeouts
[
SCTP_EVENT_TIMEOUT_T4_RTO
]
=
0
;
/* sctpimpguide-05 Section 2.12.2
* If the 'T5-shutdown-guard' timer is used, it SHOULD be set to the
* recommended value of 5 times 'RTO.Max'.
*/
ep
->
timeouts
[
SCTP_EVENT_TIMEOUT_T5_SHUTDOWN_GUARD
]
=
5
*
msecs_to_jiffies
(
sp
->
rtoinfo
.
srto_max
);
ep
->
timeouts
[
SCTP_EVENT_TIMEOUT_HEARTBEAT
]
=
0
;
ep
->
timeouts
[
SCTP_EVENT_TIMEOUT_SACK
]
=
sctp_sack_timeout
;
ep
->
timeouts
[
SCTP_EVENT_TIMEOUT_AUTOCLOSE
]
=
sp
->
autoclose
*
HZ
;
/* Use SCTP specific send buffer space queues. */
ep
->
sndbuf_policy
=
sctp_sndbuf_policy
;
sk
->
sk_write_space
=
sctp_write_space
;
sock_set_flag
(
sk
,
SOCK_USE_WRITE_QUEUE
);
/* Get the receive buffer policy for this endpoint */
ep
->
rcvbuf_policy
=
sctp_rcvbuf_policy
;
/* Initialize the secret key used with cookie. */
get_random_bytes
(
&
ep
->
secret_key
[
0
],
SCTP_SECRET_SIZE
);
ep
->
last_key
=
ep
->
current_key
=
0
;
...
...
net/sctp/input.c
浏览文件 @
508862e4
...
...
@@ -100,21 +100,6 @@ static inline int sctp_rcv_checksum(struct sk_buff *skb)
return
0
;
}
/* The free routine for skbuffs that sctp receives */
static
void
sctp_rfree
(
struct
sk_buff
*
skb
)
{
atomic_sub
(
sizeof
(
struct
sctp_chunk
),
&
skb
->
sk
->
sk_rmem_alloc
);
sock_rfree
(
skb
);
}
/* The ownership wrapper routine to do receive buffer accounting */
static
void
sctp_rcv_set_owner_r
(
struct
sk_buff
*
skb
,
struct
sock
*
sk
)
{
skb_set_owner_r
(
skb
,
sk
);
skb
->
destructor
=
sctp_rfree
;
atomic_add
(
sizeof
(
struct
sctp_chunk
),
&
sk
->
sk_rmem_alloc
);
}
struct
sctp_input_cb
{
union
{
struct
inet_skb_parm
h4
;
...
...
@@ -217,9 +202,6 @@ int sctp_rcv(struct sk_buff *skb)
rcvr
=
&
ep
->
base
;
}
if
(
atomic_read
(
&
sk
->
sk_rmem_alloc
)
>=
sk
->
sk_rcvbuf
)
goto
discard_release
;
/*
* RFC 2960, 8.4 - Handle "Out of the blue" Packets.
* An SCTP packet is called an "out of the blue" (OOTB)
...
...
@@ -256,8 +238,6 @@ int sctp_rcv(struct sk_buff *skb)
}
SCTP_INPUT_CB
(
skb
)
->
chunk
=
chunk
;
sctp_rcv_set_owner_r
(
skb
,
sk
);
/* Remember what endpoint is to handle this packet. */
chunk
->
rcvr
=
rcvr
;
...
...
net/sctp/protocol.c
浏览文件 @
508862e4
...
...
@@ -530,6 +530,9 @@ static void sctp_v4_get_saddr(struct sctp_association *asoc,
{
struct
rtable
*
rt
=
(
struct
rtable
*
)
dst
;
if
(
!
asoc
)
return
;
if
(
rt
)
{
saddr
->
v4
.
sin_family
=
AF_INET
;
saddr
->
v4
.
sin_port
=
asoc
->
base
.
bind_addr
.
port
;
...
...
@@ -1047,6 +1050,9 @@ SCTP_STATIC __init int sctp_init(void)
/* Sendbuffer growth - do per-socket accounting */
sctp_sndbuf_policy
=
0
;
/* Rcvbuffer growth - do per-socket accounting */
sctp_rcvbuf_policy
=
0
;
/* HB.interval - 30 seconds */
sctp_hb_interval
=
SCTP_DEFAULT_TIMEOUT_HEARTBEAT
;
...
...
net/sctp/sm_sideeffect.c
浏览文件 @
508862e4
...
...
@@ -385,7 +385,7 @@ sctp_timer_event_t *sctp_timer_events[SCTP_NUM_TIMEOUT_TYPES] = {
NULL
,
sctp_generate_t4_rto_event
,
sctp_generate_t5_shutdown_guard_event
,
sctp_generate_heartbeat_event
,
NULL
,
sctp_generate_sack_event
,
sctp_generate_autoclose_event
,
};
...
...
@@ -689,9 +689,9 @@ static void sctp_cmd_new_state(sctp_cmd_seq_t *cmds,
* increased due to timer expirations.
*/
asoc
->
timeouts
[
SCTP_EVENT_TIMEOUT_T1_INIT
]
=
asoc
->
ep
->
timeouts
[
SCTP_EVENT_TIMEOUT_T1_INIT
]
;
asoc
->
rto_initial
;
asoc
->
timeouts
[
SCTP_EVENT_TIMEOUT_T1_COOKIE
]
=
asoc
->
ep
->
timeouts
[
SCTP_EVENT_TIMEOUT_T1_COOKIE
]
;
asoc
->
rto_initial
;
}
if
(
sctp_state
(
asoc
,
ESTABLISHED
)
||
...
...
net/sctp/sm_statefuns.c
浏览文件 @
508862e4
...
...
@@ -5160,6 +5160,8 @@ static int sctp_eat_data(const struct sctp_association *asoc,
sctp_verb_t
deliver
;
int
tmp
;
__u32
tsn
;
int
account_value
;
struct
sock
*
sk
=
asoc
->
base
.
sk
;
data_hdr
=
chunk
->
subh
.
data_hdr
=
(
sctp_datahdr_t
*
)
chunk
->
skb
->
data
;
skb_pull
(
chunk
->
skb
,
sizeof
(
sctp_datahdr_t
));
...
...
@@ -5169,6 +5171,26 @@ static int sctp_eat_data(const struct sctp_association *asoc,
/* ASSERT: Now skb->data is really the user data. */
/*
* if we are established, and we have used up our receive
* buffer memory, drop the frame
*/
if
(
asoc
->
state
==
SCTP_STATE_ESTABLISHED
)
{
/*
* If the receive buffer policy is 1, then each
* association can allocate up to sk_rcvbuf bytes
* otherwise, all the associations in aggregate
* may allocate up to sk_rcvbuf bytes
*/
if
(
asoc
->
ep
->
rcvbuf_policy
)
account_value
=
atomic_read
(
&
asoc
->
rmem_alloc
);
else
account_value
=
atomic_read
(
&
sk
->
sk_rmem_alloc
);
if
(
account_value
>
sk
->
sk_rcvbuf
)
return
SCTP_IERROR_IGNORE_TSN
;
}
/* Process ECN based congestion.
*
* Since the chunk structure is reused for all chunks within
...
...
net/sctp/socket.c
浏览文件 @
508862e4
...
...
@@ -1932,7 +1932,6 @@ static int sctp_setsockopt_autoclose(struct sock *sk, char __user *optval,
if
(
copy_from_user
(
&
sp
->
autoclose
,
optval
,
optlen
))
return
-
EFAULT
;
sp
->
ep
->
timeouts
[
SCTP_EVENT_TIMEOUT_AUTOCLOSE
]
=
sp
->
autoclose
*
HZ
;
return
0
;
}
...
...
@@ -5115,8 +5114,10 @@ static void sctp_sock_migrate(struct sock *oldsk, struct sock *newsk,
sctp_skb_for_each
(
skb
,
&
oldsk
->
sk_receive_queue
,
tmp
)
{
event
=
sctp_skb2event
(
skb
);
if
(
event
->
asoc
==
assoc
)
{
sock_rfree
(
skb
);
__skb_unlink
(
skb
,
&
oldsk
->
sk_receive_queue
);
__skb_queue_tail
(
&
newsk
->
sk_receive_queue
,
skb
);
skb_set_owner_r
(
skb
,
newsk
);
}
}
...
...
@@ -5144,8 +5145,10 @@ static void sctp_sock_migrate(struct sock *oldsk, struct sock *newsk,
sctp_skb_for_each
(
skb
,
&
oldsp
->
pd_lobby
,
tmp
)
{
event
=
sctp_skb2event
(
skb
);
if
(
event
->
asoc
==
assoc
)
{
sock_rfree
(
skb
);
__skb_unlink
(
skb
,
&
oldsp
->
pd_lobby
);
__skb_queue_tail
(
queue
,
skb
);
skb_set_owner_r
(
skb
,
newsk
);
}
}
...
...
net/sctp/sysctl.c
浏览文件 @
508862e4
...
...
@@ -120,6 +120,14 @@ static ctl_table sctp_table[] = {
.
mode
=
0644
,
.
proc_handler
=
&
proc_dointvec
},
{
.
ctl_name
=
NET_SCTP_RCVBUF_POLICY
,
.
procname
=
"rcvbuf_policy"
,
.
data
=
&
sctp_rcvbuf_policy
,
.
maxlen
=
sizeof
(
int
),
.
mode
=
0644
,
.
proc_handler
=
&
proc_dointvec
},
{
.
ctl_name
=
NET_SCTP_PATH_MAX_RETRANS
,
.
procname
=
"path_max_retrans"
,
...
...
net/sctp/ulpevent.c
浏览文件 @
508862e4
...
...
@@ -52,19 +52,6 @@ static void sctp_ulpevent_receive_data(struct sctp_ulpevent *event,
struct
sctp_association
*
asoc
);
static
void
sctp_ulpevent_release_data
(
struct
sctp_ulpevent
*
event
);
/* Stub skb destructor. */
static
void
sctp_stub_rfree
(
struct
sk_buff
*
skb
)
{
/* WARNING: This function is just a warning not to use the
* skb destructor. If the skb is shared, we may get the destructor
* callback on some processor that does not own the sock_lock. This
* was occuring with PACKET socket applications that were monitoring
* our skbs. We can't take the sock_lock, because we can't risk
* recursing if we do really own the sock lock. Instead, do all
* of our rwnd manipulation while we own the sock_lock outright.
*/
}
/* Initialize an ULP event from an given skb. */
SCTP_STATIC
void
sctp_ulpevent_init
(
struct
sctp_ulpevent
*
event
,
int
msg_flags
)
{
...
...
@@ -111,15 +98,19 @@ static inline void sctp_ulpevent_set_owner(struct sctp_ulpevent *event,
*/
sctp_association_hold
((
struct
sctp_association
*
)
asoc
);
skb
=
sctp_event2skb
(
event
);
skb
->
sk
=
asoc
->
base
.
sk
;
event
->
asoc
=
(
struct
sctp_association
*
)
asoc
;
skb
->
destructor
=
sctp_stub_rfree
;
atomic_add
(
skb
->
truesize
,
&
event
->
asoc
->
rmem_alloc
);
skb_set_owner_r
(
skb
,
asoc
->
base
.
sk
);
}
/* A simple destructor to give up the reference to the association. */
static
inline
void
sctp_ulpevent_release_owner
(
struct
sctp_ulpevent
*
event
)
{
sctp_association_put
(
event
->
asoc
);
struct
sctp_association
*
asoc
=
event
->
asoc
;
struct
sk_buff
*
skb
=
sctp_event2skb
(
event
);
atomic_sub
(
skb
->
truesize
,
&
asoc
->
rmem_alloc
);
sctp_association_put
(
asoc
);
}
/* Create and initialize an SCTP_ASSOC_CHANGE event.
...
...
@@ -922,7 +913,6 @@ static void sctp_ulpevent_release_data(struct sctp_ulpevent *event)
/* Free a ulpevent that has an owner. It includes releasing the reference
* to the owner, updating the rwnd in case of a DATA event and freeing the
* skb.
* See comments in sctp_stub_rfree().
*/
void
sctp_ulpevent_free
(
struct
sctp_ulpevent
*
event
)
{
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录