nfnetlink_cttimeout.c 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585
  1. /*
  2. * (C) 2012 by Pablo Neira Ayuso <pablo@netfilter.org>
  3. * (C) 2012 by Vyatta Inc. <http://www.vyatta.com>
  4. *
  5. * This program is free software; you can redistribute it and/or modify
  6. * it under the terms of the GNU General Public License version 2 as
  7. * published by the Free Software Foundation (or any later at your option).
  8. */
  9. #include <linux/init.h>
  10. #include <linux/module.h>
  11. #include <linux/kernel.h>
  12. #include <linux/rculist.h>
  13. #include <linux/rculist_nulls.h>
  14. #include <linux/types.h>
  15. #include <linux/timer.h>
  16. #include <linux/security.h>
  17. #include <linux/skbuff.h>
  18. #include <linux/errno.h>
  19. #include <linux/netlink.h>
  20. #include <linux/spinlock.h>
  21. #include <linux/interrupt.h>
  22. #include <linux/slab.h>
  23. #include <linux/netfilter.h>
  24. #include <net/netlink.h>
  25. #include <net/sock.h>
  26. #include <net/netfilter/nf_conntrack.h>
  27. #include <net/netfilter/nf_conntrack_core.h>
  28. #include <net/netfilter/nf_conntrack_l3proto.h>
  29. #include <net/netfilter/nf_conntrack_l4proto.h>
  30. #include <net/netfilter/nf_conntrack_tuple.h>
  31. #include <net/netfilter/nf_conntrack_timeout.h>
  32. #include <linux/netfilter/nfnetlink.h>
  33. #include <linux/netfilter/nfnetlink_cttimeout.h>
  34. MODULE_LICENSE("GPL");
  35. MODULE_AUTHOR("Pablo Neira Ayuso <pablo@netfilter.org>");
  36. MODULE_DESCRIPTION("cttimeout: Extended Netfilter Connection Tracking timeout tuning");
  37. static LIST_HEAD(cttimeout_list);
  38. static const struct nla_policy cttimeout_nla_policy[CTA_TIMEOUT_MAX+1] = {
  39. [CTA_TIMEOUT_NAME] = { .type = NLA_NUL_STRING,
  40. .len = CTNL_TIMEOUT_NAME_MAX - 1},
  41. [CTA_TIMEOUT_L3PROTO] = { .type = NLA_U16 },
  42. [CTA_TIMEOUT_L4PROTO] = { .type = NLA_U8 },
  43. [CTA_TIMEOUT_DATA] = { .type = NLA_NESTED },
  44. };
  45. static int
  46. ctnl_timeout_parse_policy(void *timeouts, struct nf_conntrack_l4proto *l4proto,
  47. struct net *net, const struct nlattr *attr)
  48. {
  49. int ret = 0;
  50. if (likely(l4proto->ctnl_timeout.nlattr_to_obj)) {
  51. struct nlattr *tb[l4proto->ctnl_timeout.nlattr_max+1];
  52. ret = nla_parse_nested(tb, l4proto->ctnl_timeout.nlattr_max,
  53. attr, l4proto->ctnl_timeout.nla_policy);
  54. if (ret < 0)
  55. return ret;
  56. ret = l4proto->ctnl_timeout.nlattr_to_obj(tb, net, timeouts);
  57. }
  58. return ret;
  59. }
  60. static int
  61. cttimeout_new_timeout(struct sock *ctnl, struct sk_buff *skb,
  62. const struct nlmsghdr *nlh,
  63. const struct nlattr * const cda[])
  64. {
  65. __u16 l3num;
  66. __u8 l4num;
  67. struct nf_conntrack_l4proto *l4proto;
  68. struct ctnl_timeout *timeout, *matching = NULL;
  69. struct net *net = sock_net(skb->sk);
  70. char *name;
  71. int ret;
  72. if (!cda[CTA_TIMEOUT_NAME] ||
  73. !cda[CTA_TIMEOUT_L3PROTO] ||
  74. !cda[CTA_TIMEOUT_L4PROTO] ||
  75. !cda[CTA_TIMEOUT_DATA])
  76. return -EINVAL;
  77. name = nla_data(cda[CTA_TIMEOUT_NAME]);
  78. l3num = ntohs(nla_get_be16(cda[CTA_TIMEOUT_L3PROTO]));
  79. l4num = nla_get_u8(cda[CTA_TIMEOUT_L4PROTO]);
  80. list_for_each_entry(timeout, &cttimeout_list, head) {
  81. if (strncmp(timeout->name, name, CTNL_TIMEOUT_NAME_MAX) != 0)
  82. continue;
  83. if (nlh->nlmsg_flags & NLM_F_EXCL)
  84. return -EEXIST;
  85. matching = timeout;
  86. break;
  87. }
  88. l4proto = nf_ct_l4proto_find_get(l3num, l4num);
  89. /* This protocol is not supportted, skip. */
  90. if (l4proto->l4proto != l4num) {
  91. ret = -EOPNOTSUPP;
  92. goto err_proto_put;
  93. }
  94. if (matching) {
  95. if (nlh->nlmsg_flags & NLM_F_REPLACE) {
  96. /* You cannot replace one timeout policy by another of
  97. * different kind, sorry.
  98. */
  99. if (matching->l3num != l3num ||
  100. matching->l4proto->l4proto != l4num) {
  101. ret = -EINVAL;
  102. goto err_proto_put;
  103. }
  104. ret = ctnl_timeout_parse_policy(&matching->data,
  105. l4proto, net,
  106. cda[CTA_TIMEOUT_DATA]);
  107. return ret;
  108. }
  109. ret = -EBUSY;
  110. goto err_proto_put;
  111. }
  112. timeout = kzalloc(sizeof(struct ctnl_timeout) +
  113. l4proto->ctnl_timeout.obj_size, GFP_KERNEL);
  114. if (timeout == NULL) {
  115. ret = -ENOMEM;
  116. goto err_proto_put;
  117. }
  118. ret = ctnl_timeout_parse_policy(&timeout->data, l4proto, net,
  119. cda[CTA_TIMEOUT_DATA]);
  120. if (ret < 0)
  121. goto err;
  122. strcpy(timeout->name, nla_data(cda[CTA_TIMEOUT_NAME]));
  123. timeout->l3num = l3num;
  124. timeout->l4proto = l4proto;
  125. atomic_set(&timeout->refcnt, 1);
  126. list_add_tail_rcu(&timeout->head, &cttimeout_list);
  127. return 0;
  128. err:
  129. kfree(timeout);
  130. err_proto_put:
  131. nf_ct_l4proto_put(l4proto);
  132. return ret;
  133. }
  134. static int
  135. ctnl_timeout_fill_info(struct sk_buff *skb, u32 portid, u32 seq, u32 type,
  136. int event, struct ctnl_timeout *timeout)
  137. {
  138. struct nlmsghdr *nlh;
  139. struct nfgenmsg *nfmsg;
  140. unsigned int flags = portid ? NLM_F_MULTI : 0;
  141. struct nf_conntrack_l4proto *l4proto = timeout->l4proto;
  142. event |= NFNL_SUBSYS_CTNETLINK_TIMEOUT << 8;
  143. nlh = nlmsg_put(skb, portid, seq, event, sizeof(*nfmsg), flags);
  144. if (nlh == NULL)
  145. goto nlmsg_failure;
  146. nfmsg = nlmsg_data(nlh);
  147. nfmsg->nfgen_family = AF_UNSPEC;
  148. nfmsg->version = NFNETLINK_V0;
  149. nfmsg->res_id = 0;
  150. if (nla_put_string(skb, CTA_TIMEOUT_NAME, timeout->name) ||
  151. nla_put_be16(skb, CTA_TIMEOUT_L3PROTO, htons(timeout->l3num)) ||
  152. nla_put_u8(skb, CTA_TIMEOUT_L4PROTO, timeout->l4proto->l4proto) ||
  153. nla_put_be32(skb, CTA_TIMEOUT_USE,
  154. htonl(atomic_read(&timeout->refcnt))))
  155. goto nla_put_failure;
  156. if (likely(l4proto->ctnl_timeout.obj_to_nlattr)) {
  157. struct nlattr *nest_parms;
  158. int ret;
  159. nest_parms = nla_nest_start(skb,
  160. CTA_TIMEOUT_DATA | NLA_F_NESTED);
  161. if (!nest_parms)
  162. goto nla_put_failure;
  163. ret = l4proto->ctnl_timeout.obj_to_nlattr(skb, &timeout->data);
  164. if (ret < 0)
  165. goto nla_put_failure;
  166. nla_nest_end(skb, nest_parms);
  167. }
  168. nlmsg_end(skb, nlh);
  169. return skb->len;
  170. nlmsg_failure:
  171. nla_put_failure:
  172. nlmsg_cancel(skb, nlh);
  173. return -1;
  174. }
  175. static int
  176. ctnl_timeout_dump(struct sk_buff *skb, struct netlink_callback *cb)
  177. {
  178. struct ctnl_timeout *cur, *last;
  179. if (cb->args[2])
  180. return 0;
  181. last = (struct ctnl_timeout *)cb->args[1];
  182. if (cb->args[1])
  183. cb->args[1] = 0;
  184. rcu_read_lock();
  185. list_for_each_entry_rcu(cur, &cttimeout_list, head) {
  186. if (last) {
  187. if (cur != last)
  188. continue;
  189. last = NULL;
  190. }
  191. if (ctnl_timeout_fill_info(skb, NETLINK_CB(cb->skb).portid,
  192. cb->nlh->nlmsg_seq,
  193. NFNL_MSG_TYPE(cb->nlh->nlmsg_type),
  194. IPCTNL_MSG_TIMEOUT_NEW, cur) < 0) {
  195. cb->args[1] = (unsigned long)cur;
  196. break;
  197. }
  198. }
  199. if (!cb->args[1])
  200. cb->args[2] = 1;
  201. rcu_read_unlock();
  202. return skb->len;
  203. }
  204. static int
  205. cttimeout_get_timeout(struct sock *ctnl, struct sk_buff *skb,
  206. const struct nlmsghdr *nlh,
  207. const struct nlattr * const cda[])
  208. {
  209. int ret = -ENOENT;
  210. char *name;
  211. struct ctnl_timeout *cur;
  212. if (nlh->nlmsg_flags & NLM_F_DUMP) {
  213. struct netlink_dump_control c = {
  214. .dump = ctnl_timeout_dump,
  215. };
  216. return netlink_dump_start(ctnl, skb, nlh, &c);
  217. }
  218. if (!cda[CTA_TIMEOUT_NAME])
  219. return -EINVAL;
  220. name = nla_data(cda[CTA_TIMEOUT_NAME]);
  221. list_for_each_entry(cur, &cttimeout_list, head) {
  222. struct sk_buff *skb2;
  223. if (strncmp(cur->name, name, CTNL_TIMEOUT_NAME_MAX) != 0)
  224. continue;
  225. skb2 = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
  226. if (skb2 == NULL) {
  227. ret = -ENOMEM;
  228. break;
  229. }
  230. ret = ctnl_timeout_fill_info(skb2, NETLINK_CB(skb).portid,
  231. nlh->nlmsg_seq,
  232. NFNL_MSG_TYPE(nlh->nlmsg_type),
  233. IPCTNL_MSG_TIMEOUT_NEW, cur);
  234. if (ret <= 0) {
  235. kfree_skb(skb2);
  236. break;
  237. }
  238. ret = netlink_unicast(ctnl, skb2, NETLINK_CB(skb).portid,
  239. MSG_DONTWAIT);
  240. if (ret > 0)
  241. ret = 0;
  242. /* this avoids a loop in nfnetlink. */
  243. return ret == -EAGAIN ? -ENOBUFS : ret;
  244. }
  245. return ret;
  246. }
  247. /* try to delete object, fail if it is still in use. */
  248. static int ctnl_timeout_try_del(struct ctnl_timeout *timeout)
  249. {
  250. int ret = 0;
  251. /* we want to avoid races with nf_ct_timeout_find_get. */
  252. if (atomic_dec_and_test(&timeout->refcnt)) {
  253. /* We are protected by nfnl mutex. */
  254. list_del_rcu(&timeout->head);
  255. nf_ct_l4proto_put(timeout->l4proto);
  256. kfree_rcu(timeout, rcu_head);
  257. } else {
  258. /* still in use, restore reference counter. */
  259. atomic_inc(&timeout->refcnt);
  260. ret = -EBUSY;
  261. }
  262. return ret;
  263. }
  264. static int
  265. cttimeout_del_timeout(struct sock *ctnl, struct sk_buff *skb,
  266. const struct nlmsghdr *nlh,
  267. const struct nlattr * const cda[])
  268. {
  269. char *name;
  270. struct ctnl_timeout *cur;
  271. int ret = -ENOENT;
  272. if (!cda[CTA_TIMEOUT_NAME]) {
  273. list_for_each_entry(cur, &cttimeout_list, head)
  274. ctnl_timeout_try_del(cur);
  275. return 0;
  276. }
  277. name = nla_data(cda[CTA_TIMEOUT_NAME]);
  278. list_for_each_entry(cur, &cttimeout_list, head) {
  279. if (strncmp(cur->name, name, CTNL_TIMEOUT_NAME_MAX) != 0)
  280. continue;
  281. ret = ctnl_timeout_try_del(cur);
  282. if (ret < 0)
  283. return ret;
  284. break;
  285. }
  286. return ret;
  287. }
  288. static int
  289. cttimeout_default_set(struct sock *ctnl, struct sk_buff *skb,
  290. const struct nlmsghdr *nlh,
  291. const struct nlattr * const cda[])
  292. {
  293. __u16 l3num;
  294. __u8 l4num;
  295. struct nf_conntrack_l4proto *l4proto;
  296. struct net *net = sock_net(skb->sk);
  297. unsigned int *timeouts;
  298. int ret;
  299. if (!cda[CTA_TIMEOUT_L3PROTO] ||
  300. !cda[CTA_TIMEOUT_L4PROTO] ||
  301. !cda[CTA_TIMEOUT_DATA])
  302. return -EINVAL;
  303. l3num = ntohs(nla_get_be16(cda[CTA_TIMEOUT_L3PROTO]));
  304. l4num = nla_get_u8(cda[CTA_TIMEOUT_L4PROTO]);
  305. l4proto = nf_ct_l4proto_find_get(l3num, l4num);
  306. /* This protocol is not supported, skip. */
  307. if (l4proto->l4proto != l4num) {
  308. ret = -EOPNOTSUPP;
  309. goto err;
  310. }
  311. timeouts = l4proto->get_timeouts(net);
  312. ret = ctnl_timeout_parse_policy(timeouts, l4proto, net,
  313. cda[CTA_TIMEOUT_DATA]);
  314. if (ret < 0)
  315. goto err;
  316. nf_ct_l4proto_put(l4proto);
  317. return 0;
  318. err:
  319. nf_ct_l4proto_put(l4proto);
  320. return ret;
  321. }
  322. static int
  323. cttimeout_default_fill_info(struct net *net, struct sk_buff *skb, u32 portid,
  324. u32 seq, u32 type, int event,
  325. struct nf_conntrack_l4proto *l4proto)
  326. {
  327. struct nlmsghdr *nlh;
  328. struct nfgenmsg *nfmsg;
  329. unsigned int flags = portid ? NLM_F_MULTI : 0;
  330. event |= NFNL_SUBSYS_CTNETLINK_TIMEOUT << 8;
  331. nlh = nlmsg_put(skb, portid, seq, event, sizeof(*nfmsg), flags);
  332. if (nlh == NULL)
  333. goto nlmsg_failure;
  334. nfmsg = nlmsg_data(nlh);
  335. nfmsg->nfgen_family = AF_UNSPEC;
  336. nfmsg->version = NFNETLINK_V0;
  337. nfmsg->res_id = 0;
  338. if (nla_put_be16(skb, CTA_TIMEOUT_L3PROTO, htons(l4proto->l3proto)) ||
  339. nla_put_u8(skb, CTA_TIMEOUT_L4PROTO, l4proto->l4proto))
  340. goto nla_put_failure;
  341. if (likely(l4proto->ctnl_timeout.obj_to_nlattr)) {
  342. struct nlattr *nest_parms;
  343. unsigned int *timeouts = l4proto->get_timeouts(net);
  344. int ret;
  345. nest_parms = nla_nest_start(skb,
  346. CTA_TIMEOUT_DATA | NLA_F_NESTED);
  347. if (!nest_parms)
  348. goto nla_put_failure;
  349. ret = l4proto->ctnl_timeout.obj_to_nlattr(skb, timeouts);
  350. if (ret < 0)
  351. goto nla_put_failure;
  352. nla_nest_end(skb, nest_parms);
  353. }
  354. nlmsg_end(skb, nlh);
  355. return skb->len;
  356. nlmsg_failure:
  357. nla_put_failure:
  358. nlmsg_cancel(skb, nlh);
  359. return -1;
  360. }
  361. static int cttimeout_default_get(struct sock *ctnl, struct sk_buff *skb,
  362. const struct nlmsghdr *nlh,
  363. const struct nlattr * const cda[])
  364. {
  365. __u16 l3num;
  366. __u8 l4num;
  367. struct nf_conntrack_l4proto *l4proto;
  368. struct net *net = sock_net(skb->sk);
  369. struct sk_buff *skb2;
  370. int ret, err;
  371. if (!cda[CTA_TIMEOUT_L3PROTO] || !cda[CTA_TIMEOUT_L4PROTO])
  372. return -EINVAL;
  373. l3num = ntohs(nla_get_be16(cda[CTA_TIMEOUT_L3PROTO]));
  374. l4num = nla_get_u8(cda[CTA_TIMEOUT_L4PROTO]);
  375. l4proto = nf_ct_l4proto_find_get(l3num, l4num);
  376. /* This protocol is not supported, skip. */
  377. if (l4proto->l4proto != l4num) {
  378. err = -EOPNOTSUPP;
  379. goto err;
  380. }
  381. skb2 = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
  382. if (skb2 == NULL) {
  383. err = -ENOMEM;
  384. goto err;
  385. }
  386. ret = cttimeout_default_fill_info(net, skb2, NETLINK_CB(skb).portid,
  387. nlh->nlmsg_seq,
  388. NFNL_MSG_TYPE(nlh->nlmsg_type),
  389. IPCTNL_MSG_TIMEOUT_DEFAULT_SET,
  390. l4proto);
  391. if (ret <= 0) {
  392. kfree_skb(skb2);
  393. err = -ENOMEM;
  394. goto err;
  395. }
  396. ret = netlink_unicast(ctnl, skb2, NETLINK_CB(skb).portid, MSG_DONTWAIT);
  397. if (ret > 0)
  398. ret = 0;
  399. /* this avoids a loop in nfnetlink. */
  400. return ret == -EAGAIN ? -ENOBUFS : ret;
  401. err:
  402. nf_ct_l4proto_put(l4proto);
  403. return err;
  404. }
  405. #ifdef CONFIG_NF_CONNTRACK_TIMEOUT
  406. static struct ctnl_timeout *ctnl_timeout_find_get(const char *name)
  407. {
  408. struct ctnl_timeout *timeout, *matching = NULL;
  409. rcu_read_lock();
  410. list_for_each_entry_rcu(timeout, &cttimeout_list, head) {
  411. if (strncmp(timeout->name, name, CTNL_TIMEOUT_NAME_MAX) != 0)
  412. continue;
  413. if (!try_module_get(THIS_MODULE))
  414. goto err;
  415. if (!atomic_inc_not_zero(&timeout->refcnt)) {
  416. module_put(THIS_MODULE);
  417. goto err;
  418. }
  419. matching = timeout;
  420. break;
  421. }
  422. err:
  423. rcu_read_unlock();
  424. return matching;
  425. }
  426. static void ctnl_timeout_put(struct ctnl_timeout *timeout)
  427. {
  428. atomic_dec(&timeout->refcnt);
  429. module_put(THIS_MODULE);
  430. }
  431. #endif /* CONFIG_NF_CONNTRACK_TIMEOUT */
  432. static const struct nfnl_callback cttimeout_cb[IPCTNL_MSG_TIMEOUT_MAX] = {
  433. [IPCTNL_MSG_TIMEOUT_NEW] = { .call = cttimeout_new_timeout,
  434. .attr_count = CTA_TIMEOUT_MAX,
  435. .policy = cttimeout_nla_policy },
  436. [IPCTNL_MSG_TIMEOUT_GET] = { .call = cttimeout_get_timeout,
  437. .attr_count = CTA_TIMEOUT_MAX,
  438. .policy = cttimeout_nla_policy },
  439. [IPCTNL_MSG_TIMEOUT_DELETE] = { .call = cttimeout_del_timeout,
  440. .attr_count = CTA_TIMEOUT_MAX,
  441. .policy = cttimeout_nla_policy },
  442. [IPCTNL_MSG_TIMEOUT_DEFAULT_SET]= { .call = cttimeout_default_set,
  443. .attr_count = CTA_TIMEOUT_MAX,
  444. .policy = cttimeout_nla_policy },
  445. [IPCTNL_MSG_TIMEOUT_DEFAULT_GET]= { .call = cttimeout_default_get,
  446. .attr_count = CTA_TIMEOUT_MAX,
  447. .policy = cttimeout_nla_policy },
  448. };
  449. static const struct nfnetlink_subsystem cttimeout_subsys = {
  450. .name = "conntrack_timeout",
  451. .subsys_id = NFNL_SUBSYS_CTNETLINK_TIMEOUT,
  452. .cb_count = IPCTNL_MSG_TIMEOUT_MAX,
  453. .cb = cttimeout_cb,
  454. };
  455. MODULE_ALIAS_NFNL_SUBSYS(NFNL_SUBSYS_CTNETLINK_TIMEOUT);
  456. static int __init cttimeout_init(void)
  457. {
  458. int ret;
  459. ret = nfnetlink_subsys_register(&cttimeout_subsys);
  460. if (ret < 0) {
  461. pr_err("cttimeout_init: cannot register cttimeout with "
  462. "nfnetlink.\n");
  463. goto err_out;
  464. }
  465. #ifdef CONFIG_NF_CONNTRACK_TIMEOUT
  466. RCU_INIT_POINTER(nf_ct_timeout_find_get_hook, ctnl_timeout_find_get);
  467. RCU_INIT_POINTER(nf_ct_timeout_put_hook, ctnl_timeout_put);
  468. #endif /* CONFIG_NF_CONNTRACK_TIMEOUT */
  469. return 0;
  470. err_out:
  471. return ret;
  472. }
  473. static void __exit cttimeout_exit(void)
  474. {
  475. struct ctnl_timeout *cur, *tmp;
  476. pr_info("cttimeout: unregistering from nfnetlink.\n");
  477. nfnetlink_subsys_unregister(&cttimeout_subsys);
  478. list_for_each_entry_safe(cur, tmp, &cttimeout_list, head) {
  479. list_del_rcu(&cur->head);
  480. /* We are sure that our objects have no clients at this point,
  481. * it's safe to release them all without checking refcnt.
  482. */
  483. nf_ct_l4proto_put(cur->l4proto);
  484. kfree_rcu(cur, rcu_head);
  485. }
  486. #ifdef CONFIG_NF_CONNTRACK_TIMEOUT
  487. RCU_INIT_POINTER(nf_ct_timeout_find_get_hook, NULL);
  488. RCU_INIT_POINTER(nf_ct_timeout_put_hook, NULL);
  489. #endif /* CONFIG_NF_CONNTRACK_TIMEOUT */
  490. }
  491. module_init(cttimeout_init);
  492. module_exit(cttimeout_exit);