nf_conntrack_netlink.c 38 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617
  1. /* Connection tracking via netlink socket. Allows for user space
  2. * protocol helpers and general trouble making from userspace.
  3. *
  4. * (C) 2001 by Jay Schulist <jschlst@samba.org>
  5. * (C) 2002-2006 by Harald Welte <laforge@gnumonks.org>
  6. * (C) 2003 by Patrick Mchardy <kaber@trash.net>
  7. * (C) 2005-2006 by Pablo Neira Ayuso <pablo@eurodev.net>
  8. *
  9. * I've reworked this stuff to use attributes instead of conntrack
  10. * structures. 5.44 am. I need more tea. --pablo 05/07/11.
  11. *
  12. * Initial connection tracking via netlink development funded and
  13. * generally made possible by Network Robots, Inc. (www.networkrobots.com)
  14. *
  15. * Further development of this code funded by Astaro AG (http://www.astaro.com)
  16. *
  17. * This software may be used and distributed according to the terms
  18. * of the GNU General Public License, incorporated herein by reference.
  19. *
  20. * Derived from ip_conntrack_netlink.c: Port by Pablo Neira Ayuso (05/11/14)
  21. */
  22. #include <linux/init.h>
  23. #include <linux/module.h>
  24. #include <linux/kernel.h>
  25. #include <linux/types.h>
  26. #include <linux/timer.h>
  27. #include <linux/skbuff.h>
  28. #include <linux/errno.h>
  29. #include <linux/netlink.h>
  30. #include <linux/spinlock.h>
  31. #include <linux/interrupt.h>
  32. #include <linux/notifier.h>
  33. #include <linux/netfilter.h>
  34. #include <net/netfilter/nf_conntrack.h>
  35. #include <net/netfilter/nf_conntrack_core.h>
  36. #include <net/netfilter/nf_conntrack_expect.h>
  37. #include <net/netfilter/nf_conntrack_helper.h>
  38. #include <net/netfilter/nf_conntrack_l3proto.h>
  39. #include <net/netfilter/nf_conntrack_l4proto.h>
  40. #include <net/netfilter/nf_conntrack_tuple.h>
  41. #ifdef CONFIG_NF_NAT_NEEDED
  42. #include <net/netfilter/nf_nat_core.h>
  43. #include <net/netfilter/nf_nat_protocol.h>
  44. #endif
  45. #include <linux/netfilter/nfnetlink.h>
  46. #include <linux/netfilter/nfnetlink_conntrack.h>
  47. MODULE_LICENSE("GPL");
  48. static char __initdata version[] = "0.93";
  49. static inline int
  50. ctnetlink_dump_tuples_proto(struct sk_buff *skb,
  51. const struct nf_conntrack_tuple *tuple,
  52. struct nf_conntrack_l4proto *l4proto)
  53. {
  54. int ret = 0;
  55. struct nfattr *nest_parms = NFA_NEST(skb, CTA_TUPLE_PROTO);
  56. NFA_PUT(skb, CTA_PROTO_NUM, sizeof(u_int8_t), &tuple->dst.protonum);
  57. if (likely(l4proto->tuple_to_nfattr))
  58. ret = l4proto->tuple_to_nfattr(skb, tuple);
  59. NFA_NEST_END(skb, nest_parms);
  60. return ret;
  61. nfattr_failure:
  62. return -1;
  63. }
  64. static inline int
  65. ctnetlink_dump_tuples_ip(struct sk_buff *skb,
  66. const struct nf_conntrack_tuple *tuple,
  67. struct nf_conntrack_l3proto *l3proto)
  68. {
  69. int ret = 0;
  70. struct nfattr *nest_parms = NFA_NEST(skb, CTA_TUPLE_IP);
  71. if (likely(l3proto->tuple_to_nfattr))
  72. ret = l3proto->tuple_to_nfattr(skb, tuple);
  73. NFA_NEST_END(skb, nest_parms);
  74. return ret;
  75. nfattr_failure:
  76. return -1;
  77. }
  78. static inline int
  79. ctnetlink_dump_tuples(struct sk_buff *skb,
  80. const struct nf_conntrack_tuple *tuple)
  81. {
  82. int ret;
  83. struct nf_conntrack_l3proto *l3proto;
  84. struct nf_conntrack_l4proto *l4proto;
  85. l3proto = nf_ct_l3proto_find_get(tuple->src.l3num);
  86. ret = ctnetlink_dump_tuples_ip(skb, tuple, l3proto);
  87. nf_ct_l3proto_put(l3proto);
  88. if (unlikely(ret < 0))
  89. return ret;
  90. l4proto = nf_ct_l4proto_find_get(tuple->src.l3num, tuple->dst.protonum);
  91. ret = ctnetlink_dump_tuples_proto(skb, tuple, l4proto);
  92. nf_ct_l4proto_put(l4proto);
  93. return ret;
  94. }
  95. static inline int
  96. ctnetlink_dump_status(struct sk_buff *skb, const struct nf_conn *ct)
  97. {
  98. __be32 status = htonl((u_int32_t) ct->status);
  99. NFA_PUT(skb, CTA_STATUS, sizeof(status), &status);
  100. return 0;
  101. nfattr_failure:
  102. return -1;
  103. }
  104. static inline int
  105. ctnetlink_dump_timeout(struct sk_buff *skb, const struct nf_conn *ct)
  106. {
  107. long timeout_l = ct->timeout.expires - jiffies;
  108. __be32 timeout;
  109. if (timeout_l < 0)
  110. timeout = 0;
  111. else
  112. timeout = htonl(timeout_l / HZ);
  113. NFA_PUT(skb, CTA_TIMEOUT, sizeof(timeout), &timeout);
  114. return 0;
  115. nfattr_failure:
  116. return -1;
  117. }
  118. static inline int
  119. ctnetlink_dump_protoinfo(struct sk_buff *skb, const struct nf_conn *ct)
  120. {
  121. struct nf_conntrack_l4proto *l4proto = nf_ct_l4proto_find_get(ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.src.l3num, ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.dst.protonum);
  122. struct nfattr *nest_proto;
  123. int ret;
  124. if (!l4proto->to_nfattr) {
  125. nf_ct_l4proto_put(l4proto);
  126. return 0;
  127. }
  128. nest_proto = NFA_NEST(skb, CTA_PROTOINFO);
  129. ret = l4proto->to_nfattr(skb, nest_proto, ct);
  130. nf_ct_l4proto_put(l4proto);
  131. NFA_NEST_END(skb, nest_proto);
  132. return ret;
  133. nfattr_failure:
  134. nf_ct_l4proto_put(l4proto);
  135. return -1;
  136. }
  137. static inline int
  138. ctnetlink_dump_helpinfo(struct sk_buff *skb, const struct nf_conn *ct)
  139. {
  140. struct nfattr *nest_helper;
  141. const struct nf_conn_help *help = nfct_help(ct);
  142. if (!help || !help->helper)
  143. return 0;
  144. nest_helper = NFA_NEST(skb, CTA_HELP);
  145. NFA_PUT(skb, CTA_HELP_NAME, strlen(help->helper->name), help->helper->name);
  146. if (help->helper->to_nfattr)
  147. help->helper->to_nfattr(skb, ct);
  148. NFA_NEST_END(skb, nest_helper);
  149. return 0;
  150. nfattr_failure:
  151. return -1;
  152. }
  153. #ifdef CONFIG_NF_CT_ACCT
  154. static inline int
  155. ctnetlink_dump_counters(struct sk_buff *skb, const struct nf_conn *ct,
  156. enum ip_conntrack_dir dir)
  157. {
  158. enum ctattr_type type = dir ? CTA_COUNTERS_REPLY: CTA_COUNTERS_ORIG;
  159. struct nfattr *nest_count = NFA_NEST(skb, type);
  160. __be32 tmp;
  161. tmp = htonl(ct->counters[dir].packets);
  162. NFA_PUT(skb, CTA_COUNTERS32_PACKETS, sizeof(u_int32_t), &tmp);
  163. tmp = htonl(ct->counters[dir].bytes);
  164. NFA_PUT(skb, CTA_COUNTERS32_BYTES, sizeof(u_int32_t), &tmp);
  165. NFA_NEST_END(skb, nest_count);
  166. return 0;
  167. nfattr_failure:
  168. return -1;
  169. }
  170. #else
  171. #define ctnetlink_dump_counters(a, b, c) (0)
  172. #endif
  173. #ifdef CONFIG_NF_CONNTRACK_MARK
  174. static inline int
  175. ctnetlink_dump_mark(struct sk_buff *skb, const struct nf_conn *ct)
  176. {
  177. __be32 mark = htonl(ct->mark);
  178. NFA_PUT(skb, CTA_MARK, sizeof(u_int32_t), &mark);
  179. return 0;
  180. nfattr_failure:
  181. return -1;
  182. }
  183. #else
  184. #define ctnetlink_dump_mark(a, b) (0)
  185. #endif
  186. static inline int
  187. ctnetlink_dump_id(struct sk_buff *skb, const struct nf_conn *ct)
  188. {
  189. __be32 id = htonl(ct->id);
  190. NFA_PUT(skb, CTA_ID, sizeof(u_int32_t), &id);
  191. return 0;
  192. nfattr_failure:
  193. return -1;
  194. }
  195. static inline int
  196. ctnetlink_dump_use(struct sk_buff *skb, const struct nf_conn *ct)
  197. {
  198. __be32 use = htonl(atomic_read(&ct->ct_general.use));
  199. NFA_PUT(skb, CTA_USE, sizeof(u_int32_t), &use);
  200. return 0;
  201. nfattr_failure:
  202. return -1;
  203. }
  204. #define tuple(ct, dir) (&(ct)->tuplehash[dir].tuple)
  205. static int
  206. ctnetlink_fill_info(struct sk_buff *skb, u32 pid, u32 seq,
  207. int event, int nowait,
  208. const struct nf_conn *ct)
  209. {
  210. struct nlmsghdr *nlh;
  211. struct nfgenmsg *nfmsg;
  212. struct nfattr *nest_parms;
  213. unsigned char *b;
  214. b = skb->tail;
  215. event |= NFNL_SUBSYS_CTNETLINK << 8;
  216. nlh = NLMSG_PUT(skb, pid, seq, event, sizeof(struct nfgenmsg));
  217. nfmsg = NLMSG_DATA(nlh);
  218. nlh->nlmsg_flags = (nowait && pid) ? NLM_F_MULTI : 0;
  219. nfmsg->nfgen_family =
  220. ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.src.l3num;
  221. nfmsg->version = NFNETLINK_V0;
  222. nfmsg->res_id = 0;
  223. nest_parms = NFA_NEST(skb, CTA_TUPLE_ORIG);
  224. if (ctnetlink_dump_tuples(skb, tuple(ct, IP_CT_DIR_ORIGINAL)) < 0)
  225. goto nfattr_failure;
  226. NFA_NEST_END(skb, nest_parms);
  227. nest_parms = NFA_NEST(skb, CTA_TUPLE_REPLY);
  228. if (ctnetlink_dump_tuples(skb, tuple(ct, IP_CT_DIR_REPLY)) < 0)
  229. goto nfattr_failure;
  230. NFA_NEST_END(skb, nest_parms);
  231. if (ctnetlink_dump_status(skb, ct) < 0 ||
  232. ctnetlink_dump_timeout(skb, ct) < 0 ||
  233. ctnetlink_dump_counters(skb, ct, IP_CT_DIR_ORIGINAL) < 0 ||
  234. ctnetlink_dump_counters(skb, ct, IP_CT_DIR_REPLY) < 0 ||
  235. ctnetlink_dump_protoinfo(skb, ct) < 0 ||
  236. ctnetlink_dump_helpinfo(skb, ct) < 0 ||
  237. ctnetlink_dump_mark(skb, ct) < 0 ||
  238. ctnetlink_dump_id(skb, ct) < 0 ||
  239. ctnetlink_dump_use(skb, ct) < 0)
  240. goto nfattr_failure;
  241. nlh->nlmsg_len = skb->tail - b;
  242. return skb->len;
  243. nlmsg_failure:
  244. nfattr_failure:
  245. skb_trim(skb, b - skb->data);
  246. return -1;
  247. }
  248. #ifdef CONFIG_NF_CONNTRACK_EVENTS
  249. static int ctnetlink_conntrack_event(struct notifier_block *this,
  250. unsigned long events, void *ptr)
  251. {
  252. struct nlmsghdr *nlh;
  253. struct nfgenmsg *nfmsg;
  254. struct nfattr *nest_parms;
  255. struct nf_conn *ct = (struct nf_conn *)ptr;
  256. struct sk_buff *skb;
  257. unsigned int type;
  258. unsigned char *b;
  259. unsigned int flags = 0, group;
  260. /* ignore our fake conntrack entry */
  261. if (ct == &nf_conntrack_untracked)
  262. return NOTIFY_DONE;
  263. if (events & IPCT_DESTROY) {
  264. type = IPCTNL_MSG_CT_DELETE;
  265. group = NFNLGRP_CONNTRACK_DESTROY;
  266. } else if (events & (IPCT_NEW | IPCT_RELATED)) {
  267. type = IPCTNL_MSG_CT_NEW;
  268. flags = NLM_F_CREATE|NLM_F_EXCL;
  269. group = NFNLGRP_CONNTRACK_NEW;
  270. } else if (events & (IPCT_STATUS | IPCT_PROTOINFO)) {
  271. type = IPCTNL_MSG_CT_NEW;
  272. group = NFNLGRP_CONNTRACK_UPDATE;
  273. } else
  274. return NOTIFY_DONE;
  275. if (!nfnetlink_has_listeners(group))
  276. return NOTIFY_DONE;
  277. skb = alloc_skb(NLMSG_GOODSIZE, GFP_ATOMIC);
  278. if (!skb)
  279. return NOTIFY_DONE;
  280. b = skb->tail;
  281. type |= NFNL_SUBSYS_CTNETLINK << 8;
  282. nlh = NLMSG_PUT(skb, 0, 0, type, sizeof(struct nfgenmsg));
  283. nfmsg = NLMSG_DATA(nlh);
  284. nlh->nlmsg_flags = flags;
  285. nfmsg->nfgen_family = ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.src.l3num;
  286. nfmsg->version = NFNETLINK_V0;
  287. nfmsg->res_id = 0;
  288. nest_parms = NFA_NEST(skb, CTA_TUPLE_ORIG);
  289. if (ctnetlink_dump_tuples(skb, tuple(ct, IP_CT_DIR_ORIGINAL)) < 0)
  290. goto nfattr_failure;
  291. NFA_NEST_END(skb, nest_parms);
  292. nest_parms = NFA_NEST(skb, CTA_TUPLE_REPLY);
  293. if (ctnetlink_dump_tuples(skb, tuple(ct, IP_CT_DIR_REPLY)) < 0)
  294. goto nfattr_failure;
  295. NFA_NEST_END(skb, nest_parms);
  296. if (events & IPCT_DESTROY) {
  297. if (ctnetlink_dump_counters(skb, ct, IP_CT_DIR_ORIGINAL) < 0 ||
  298. ctnetlink_dump_counters(skb, ct, IP_CT_DIR_REPLY) < 0)
  299. goto nfattr_failure;
  300. } else {
  301. if (ctnetlink_dump_status(skb, ct) < 0)
  302. goto nfattr_failure;
  303. if (ctnetlink_dump_timeout(skb, ct) < 0)
  304. goto nfattr_failure;
  305. if (events & IPCT_PROTOINFO
  306. && ctnetlink_dump_protoinfo(skb, ct) < 0)
  307. goto nfattr_failure;
  308. if ((events & IPCT_HELPER || nfct_help(ct))
  309. && ctnetlink_dump_helpinfo(skb, ct) < 0)
  310. goto nfattr_failure;
  311. #ifdef CONFIG_NF_CONNTRACK_MARK
  312. if ((events & IPCT_MARK || ct->mark)
  313. && ctnetlink_dump_mark(skb, ct) < 0)
  314. goto nfattr_failure;
  315. #endif
  316. if (events & IPCT_COUNTER_FILLING &&
  317. (ctnetlink_dump_counters(skb, ct, IP_CT_DIR_ORIGINAL) < 0 ||
  318. ctnetlink_dump_counters(skb, ct, IP_CT_DIR_REPLY) < 0))
  319. goto nfattr_failure;
  320. }
  321. nlh->nlmsg_len = skb->tail - b;
  322. nfnetlink_send(skb, 0, group, 0);
  323. return NOTIFY_DONE;
  324. nlmsg_failure:
  325. nfattr_failure:
  326. kfree_skb(skb);
  327. return NOTIFY_DONE;
  328. }
  329. #endif /* CONFIG_NF_CONNTRACK_EVENTS */
  330. static int ctnetlink_done(struct netlink_callback *cb)
  331. {
  332. if (cb->args[1])
  333. nf_ct_put((struct nf_conn *)cb->args[1]);
  334. return 0;
  335. }
  336. #define L3PROTO(ct) ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.src.l3num
  337. static int
  338. ctnetlink_dump_table(struct sk_buff *skb, struct netlink_callback *cb)
  339. {
  340. struct nf_conn *ct, *last;
  341. struct nf_conntrack_tuple_hash *h;
  342. struct list_head *i;
  343. struct nfgenmsg *nfmsg = NLMSG_DATA(cb->nlh);
  344. u_int8_t l3proto = nfmsg->nfgen_family;
  345. read_lock_bh(&nf_conntrack_lock);
  346. last = (struct nf_conn *)cb->args[1];
  347. for (; cb->args[0] < nf_conntrack_htable_size; cb->args[0]++) {
  348. restart:
  349. list_for_each_prev(i, &nf_conntrack_hash[cb->args[0]]) {
  350. h = (struct nf_conntrack_tuple_hash *) i;
  351. if (NF_CT_DIRECTION(h) != IP_CT_DIR_ORIGINAL)
  352. continue;
  353. ct = nf_ct_tuplehash_to_ctrack(h);
  354. /* Dump entries of a given L3 protocol number.
  355. * If it is not specified, ie. l3proto == 0,
  356. * then dump everything. */
  357. if (l3proto && L3PROTO(ct) != l3proto)
  358. continue;
  359. if (cb->args[1]) {
  360. if (ct != last)
  361. continue;
  362. cb->args[1] = 0;
  363. }
  364. if (ctnetlink_fill_info(skb, NETLINK_CB(cb->skb).pid,
  365. cb->nlh->nlmsg_seq,
  366. IPCTNL_MSG_CT_NEW,
  367. 1, ct) < 0) {
  368. nf_conntrack_get(&ct->ct_general);
  369. cb->args[1] = (unsigned long)ct;
  370. goto out;
  371. }
  372. #ifdef CONFIG_NF_CT_ACCT
  373. if (NFNL_MSG_TYPE(cb->nlh->nlmsg_type) ==
  374. IPCTNL_MSG_CT_GET_CTRZERO)
  375. memset(&ct->counters, 0, sizeof(ct->counters));
  376. #endif
  377. }
  378. if (cb->args[1]) {
  379. cb->args[1] = 0;
  380. goto restart;
  381. }
  382. }
  383. out:
  384. read_unlock_bh(&nf_conntrack_lock);
  385. if (last)
  386. nf_ct_put(last);
  387. return skb->len;
  388. }
  389. static inline int
  390. ctnetlink_parse_tuple_ip(struct nfattr *attr, struct nf_conntrack_tuple *tuple)
  391. {
  392. struct nfattr *tb[CTA_IP_MAX];
  393. struct nf_conntrack_l3proto *l3proto;
  394. int ret = 0;
  395. nfattr_parse_nested(tb, CTA_IP_MAX, attr);
  396. l3proto = nf_ct_l3proto_find_get(tuple->src.l3num);
  397. if (likely(l3proto->nfattr_to_tuple))
  398. ret = l3proto->nfattr_to_tuple(tb, tuple);
  399. nf_ct_l3proto_put(l3proto);
  400. return ret;
  401. }
  402. static const size_t cta_min_proto[CTA_PROTO_MAX] = {
  403. [CTA_PROTO_NUM-1] = sizeof(u_int8_t),
  404. };
  405. static inline int
  406. ctnetlink_parse_tuple_proto(struct nfattr *attr,
  407. struct nf_conntrack_tuple *tuple)
  408. {
  409. struct nfattr *tb[CTA_PROTO_MAX];
  410. struct nf_conntrack_l4proto *l4proto;
  411. int ret = 0;
  412. nfattr_parse_nested(tb, CTA_PROTO_MAX, attr);
  413. if (nfattr_bad_size(tb, CTA_PROTO_MAX, cta_min_proto))
  414. return -EINVAL;
  415. if (!tb[CTA_PROTO_NUM-1])
  416. return -EINVAL;
  417. tuple->dst.protonum = *(u_int8_t *)NFA_DATA(tb[CTA_PROTO_NUM-1]);
  418. l4proto = nf_ct_l4proto_find_get(tuple->src.l3num, tuple->dst.protonum);
  419. if (likely(l4proto->nfattr_to_tuple))
  420. ret = l4proto->nfattr_to_tuple(tb, tuple);
  421. nf_ct_l4proto_put(l4proto);
  422. return ret;
  423. }
  424. static inline int
  425. ctnetlink_parse_tuple(struct nfattr *cda[], struct nf_conntrack_tuple *tuple,
  426. enum ctattr_tuple type, u_int8_t l3num)
  427. {
  428. struct nfattr *tb[CTA_TUPLE_MAX];
  429. int err;
  430. memset(tuple, 0, sizeof(*tuple));
  431. nfattr_parse_nested(tb, CTA_TUPLE_MAX, cda[type-1]);
  432. if (!tb[CTA_TUPLE_IP-1])
  433. return -EINVAL;
  434. tuple->src.l3num = l3num;
  435. err = ctnetlink_parse_tuple_ip(tb[CTA_TUPLE_IP-1], tuple);
  436. if (err < 0)
  437. return err;
  438. if (!tb[CTA_TUPLE_PROTO-1])
  439. return -EINVAL;
  440. err = ctnetlink_parse_tuple_proto(tb[CTA_TUPLE_PROTO-1], tuple);
  441. if (err < 0)
  442. return err;
  443. /* orig and expect tuples get DIR_ORIGINAL */
  444. if (type == CTA_TUPLE_REPLY)
  445. tuple->dst.dir = IP_CT_DIR_REPLY;
  446. else
  447. tuple->dst.dir = IP_CT_DIR_ORIGINAL;
  448. return 0;
  449. }
  450. #ifdef CONFIG_NF_NAT_NEEDED
  451. static const size_t cta_min_protonat[CTA_PROTONAT_MAX] = {
  452. [CTA_PROTONAT_PORT_MIN-1] = sizeof(u_int16_t),
  453. [CTA_PROTONAT_PORT_MAX-1] = sizeof(u_int16_t),
  454. };
  455. static int nfnetlink_parse_nat_proto(struct nfattr *attr,
  456. const struct nf_conn *ct,
  457. struct nf_nat_range *range)
  458. {
  459. struct nfattr *tb[CTA_PROTONAT_MAX];
  460. struct nf_nat_protocol *npt;
  461. nfattr_parse_nested(tb, CTA_PROTONAT_MAX, attr);
  462. if (nfattr_bad_size(tb, CTA_PROTONAT_MAX, cta_min_protonat))
  463. return -EINVAL;
  464. npt = nf_nat_proto_find_get(ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.dst.protonum);
  465. if (!npt->nfattr_to_range) {
  466. nf_nat_proto_put(npt);
  467. return 0;
  468. }
  469. /* nfattr_to_range returns 1 if it parsed, 0 if not, neg. on error */
  470. if (npt->nfattr_to_range(tb, range) > 0)
  471. range->flags |= IP_NAT_RANGE_PROTO_SPECIFIED;
  472. nf_nat_proto_put(npt);
  473. return 0;
  474. }
  475. static const size_t cta_min_nat[CTA_NAT_MAX] = {
  476. [CTA_NAT_MINIP-1] = sizeof(u_int32_t),
  477. [CTA_NAT_MAXIP-1] = sizeof(u_int32_t),
  478. };
  479. static inline int
  480. nfnetlink_parse_nat(struct nfattr *nat,
  481. const struct nf_conn *ct, struct nf_nat_range *range)
  482. {
  483. struct nfattr *tb[CTA_NAT_MAX];
  484. int err;
  485. memset(range, 0, sizeof(*range));
  486. nfattr_parse_nested(tb, CTA_NAT_MAX, nat);
  487. if (nfattr_bad_size(tb, CTA_NAT_MAX, cta_min_nat))
  488. return -EINVAL;
  489. if (tb[CTA_NAT_MINIP-1])
  490. range->min_ip = *(__be32 *)NFA_DATA(tb[CTA_NAT_MINIP-1]);
  491. if (!tb[CTA_NAT_MAXIP-1])
  492. range->max_ip = range->min_ip;
  493. else
  494. range->max_ip = *(__be32 *)NFA_DATA(tb[CTA_NAT_MAXIP-1]);
  495. if (range->min_ip)
  496. range->flags |= IP_NAT_RANGE_MAP_IPS;
  497. if (!tb[CTA_NAT_PROTO-1])
  498. return 0;
  499. err = nfnetlink_parse_nat_proto(tb[CTA_NAT_PROTO-1], ct, range);
  500. if (err < 0)
  501. return err;
  502. return 0;
  503. }
  504. #endif
  505. static inline int
  506. ctnetlink_parse_help(struct nfattr *attr, char **helper_name)
  507. {
  508. struct nfattr *tb[CTA_HELP_MAX];
  509. nfattr_parse_nested(tb, CTA_HELP_MAX, attr);
  510. if (!tb[CTA_HELP_NAME-1])
  511. return -EINVAL;
  512. *helper_name = NFA_DATA(tb[CTA_HELP_NAME-1]);
  513. return 0;
  514. }
  515. static const size_t cta_min[CTA_MAX] = {
  516. [CTA_STATUS-1] = sizeof(u_int32_t),
  517. [CTA_TIMEOUT-1] = sizeof(u_int32_t),
  518. [CTA_MARK-1] = sizeof(u_int32_t),
  519. [CTA_USE-1] = sizeof(u_int32_t),
  520. [CTA_ID-1] = sizeof(u_int32_t)
  521. };
  522. static int
  523. ctnetlink_del_conntrack(struct sock *ctnl, struct sk_buff *skb,
  524. struct nlmsghdr *nlh, struct nfattr *cda[], int *errp)
  525. {
  526. struct nf_conntrack_tuple_hash *h;
  527. struct nf_conntrack_tuple tuple;
  528. struct nf_conn *ct;
  529. struct nfgenmsg *nfmsg = NLMSG_DATA(nlh);
  530. u_int8_t u3 = nfmsg->nfgen_family;
  531. int err = 0;
  532. if (nfattr_bad_size(cda, CTA_MAX, cta_min))
  533. return -EINVAL;
  534. if (cda[CTA_TUPLE_ORIG-1])
  535. err = ctnetlink_parse_tuple(cda, &tuple, CTA_TUPLE_ORIG, u3);
  536. else if (cda[CTA_TUPLE_REPLY-1])
  537. err = ctnetlink_parse_tuple(cda, &tuple, CTA_TUPLE_REPLY, u3);
  538. else {
  539. /* Flush the whole table */
  540. nf_conntrack_flush();
  541. return 0;
  542. }
  543. if (err < 0)
  544. return err;
  545. h = nf_conntrack_find_get(&tuple, NULL);
  546. if (!h)
  547. return -ENOENT;
  548. ct = nf_ct_tuplehash_to_ctrack(h);
  549. if (cda[CTA_ID-1]) {
  550. u_int32_t id = ntohl(*(__be32 *)NFA_DATA(cda[CTA_ID-1]));
  551. if (ct->id != id) {
  552. nf_ct_put(ct);
  553. return -ENOENT;
  554. }
  555. }
  556. if (del_timer(&ct->timeout))
  557. ct->timeout.function((unsigned long)ct);
  558. nf_ct_put(ct);
  559. return 0;
  560. }
  561. static int
  562. ctnetlink_get_conntrack(struct sock *ctnl, struct sk_buff *skb,
  563. struct nlmsghdr *nlh, struct nfattr *cda[], int *errp)
  564. {
  565. struct nf_conntrack_tuple_hash *h;
  566. struct nf_conntrack_tuple tuple;
  567. struct nf_conn *ct;
  568. struct sk_buff *skb2 = NULL;
  569. struct nfgenmsg *nfmsg = NLMSG_DATA(nlh);
  570. u_int8_t u3 = nfmsg->nfgen_family;
  571. int err = 0;
  572. if (nlh->nlmsg_flags & NLM_F_DUMP) {
  573. u32 rlen;
  574. #ifndef CONFIG_NF_CT_ACCT
  575. if (NFNL_MSG_TYPE(nlh->nlmsg_type) == IPCTNL_MSG_CT_GET_CTRZERO)
  576. return -ENOTSUPP;
  577. #endif
  578. if ((*errp = netlink_dump_start(ctnl, skb, nlh,
  579. ctnetlink_dump_table,
  580. ctnetlink_done)) != 0)
  581. return -EINVAL;
  582. rlen = NLMSG_ALIGN(nlh->nlmsg_len);
  583. if (rlen > skb->len)
  584. rlen = skb->len;
  585. skb_pull(skb, rlen);
  586. return 0;
  587. }
  588. if (nfattr_bad_size(cda, CTA_MAX, cta_min))
  589. return -EINVAL;
  590. if (cda[CTA_TUPLE_ORIG-1])
  591. err = ctnetlink_parse_tuple(cda, &tuple, CTA_TUPLE_ORIG, u3);
  592. else if (cda[CTA_TUPLE_REPLY-1])
  593. err = ctnetlink_parse_tuple(cda, &tuple, CTA_TUPLE_REPLY, u3);
  594. else
  595. return -EINVAL;
  596. if (err < 0)
  597. return err;
  598. h = nf_conntrack_find_get(&tuple, NULL);
  599. if (!h)
  600. return -ENOENT;
  601. ct = nf_ct_tuplehash_to_ctrack(h);
  602. err = -ENOMEM;
  603. skb2 = alloc_skb(NLMSG_GOODSIZE, GFP_KERNEL);
  604. if (!skb2) {
  605. nf_ct_put(ct);
  606. return -ENOMEM;
  607. }
  608. err = ctnetlink_fill_info(skb2, NETLINK_CB(skb).pid, nlh->nlmsg_seq,
  609. IPCTNL_MSG_CT_NEW, 1, ct);
  610. nf_ct_put(ct);
  611. if (err <= 0)
  612. goto free;
  613. err = netlink_unicast(ctnl, skb2, NETLINK_CB(skb).pid, MSG_DONTWAIT);
  614. if (err < 0)
  615. goto out;
  616. return 0;
  617. free:
  618. kfree_skb(skb2);
  619. out:
  620. return err;
  621. }
  622. static inline int
  623. ctnetlink_change_status(struct nf_conn *ct, struct nfattr *cda[])
  624. {
  625. unsigned long d;
  626. unsigned int status = ntohl(*(__be32 *)NFA_DATA(cda[CTA_STATUS-1]));
  627. d = ct->status ^ status;
  628. if (d & (IPS_EXPECTED|IPS_CONFIRMED|IPS_DYING))
  629. /* unchangeable */
  630. return -EINVAL;
  631. if (d & IPS_SEEN_REPLY && !(status & IPS_SEEN_REPLY))
  632. /* SEEN_REPLY bit can only be set */
  633. return -EINVAL;
  634. if (d & IPS_ASSURED && !(status & IPS_ASSURED))
  635. /* ASSURED bit can only be set */
  636. return -EINVAL;
  637. if (cda[CTA_NAT_SRC-1] || cda[CTA_NAT_DST-1]) {
  638. #ifndef CONFIG_NF_NAT_NEEDED
  639. return -EINVAL;
  640. #else
  641. struct nf_nat_range range;
  642. if (cda[CTA_NAT_DST-1]) {
  643. if (nfnetlink_parse_nat(cda[CTA_NAT_DST-1], ct,
  644. &range) < 0)
  645. return -EINVAL;
  646. if (nf_nat_initialized(ct,
  647. HOOK2MANIP(NF_IP_PRE_ROUTING)))
  648. return -EEXIST;
  649. nf_nat_setup_info(ct, &range, NF_IP_PRE_ROUTING);
  650. }
  651. if (cda[CTA_NAT_SRC-1]) {
  652. if (nfnetlink_parse_nat(cda[CTA_NAT_SRC-1], ct,
  653. &range) < 0)
  654. return -EINVAL;
  655. if (nf_nat_initialized(ct,
  656. HOOK2MANIP(NF_IP_POST_ROUTING)))
  657. return -EEXIST;
  658. nf_nat_setup_info(ct, &range, NF_IP_POST_ROUTING);
  659. }
  660. #endif
  661. }
  662. /* Be careful here, modifying NAT bits can screw up things,
  663. * so don't let users modify them directly if they don't pass
  664. * nf_nat_range. */
  665. ct->status |= status & ~(IPS_NAT_DONE_MASK | IPS_NAT_MASK);
  666. return 0;
  667. }
  668. static inline int
  669. ctnetlink_change_helper(struct nf_conn *ct, struct nfattr *cda[])
  670. {
  671. struct nf_conntrack_helper *helper;
  672. struct nf_conn_help *help = nfct_help(ct);
  673. char *helpname;
  674. int err;
  675. if (!help) {
  676. /* FIXME: we need to reallocate and rehash */
  677. return -EBUSY;
  678. }
  679. /* don't change helper of sibling connections */
  680. if (ct->master)
  681. return -EINVAL;
  682. err = ctnetlink_parse_help(cda[CTA_HELP-1], &helpname);
  683. if (err < 0)
  684. return err;
  685. helper = __nf_conntrack_helper_find_byname(helpname);
  686. if (!helper) {
  687. if (!strcmp(helpname, ""))
  688. helper = NULL;
  689. else
  690. return -EINVAL;
  691. }
  692. if (help->helper) {
  693. if (!helper) {
  694. /* we had a helper before ... */
  695. nf_ct_remove_expectations(ct);
  696. help->helper = NULL;
  697. } else {
  698. /* need to zero data of old helper */
  699. memset(&help->help, 0, sizeof(help->help));
  700. }
  701. }
  702. help->helper = helper;
  703. return 0;
  704. }
  705. static inline int
  706. ctnetlink_change_timeout(struct nf_conn *ct, struct nfattr *cda[])
  707. {
  708. u_int32_t timeout = ntohl(*(__be32 *)NFA_DATA(cda[CTA_TIMEOUT-1]));
  709. if (!del_timer(&ct->timeout))
  710. return -ETIME;
  711. ct->timeout.expires = jiffies + timeout * HZ;
  712. add_timer(&ct->timeout);
  713. return 0;
  714. }
  715. static inline int
  716. ctnetlink_change_protoinfo(struct nf_conn *ct, struct nfattr *cda[])
  717. {
  718. struct nfattr *tb[CTA_PROTOINFO_MAX], *attr = cda[CTA_PROTOINFO-1];
  719. struct nf_conntrack_l4proto *l4proto;
  720. u_int16_t npt = ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.dst.protonum;
  721. u_int16_t l3num = ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.src.l3num;
  722. int err = 0;
  723. nfattr_parse_nested(tb, CTA_PROTOINFO_MAX, attr);
  724. l4proto = nf_ct_l4proto_find_get(l3num, npt);
  725. if (l4proto->from_nfattr)
  726. err = l4proto->from_nfattr(tb, ct);
  727. nf_ct_l4proto_put(l4proto);
  728. return err;
  729. }
  730. static int
  731. ctnetlink_change_conntrack(struct nf_conn *ct, struct nfattr *cda[])
  732. {
  733. int err;
  734. if (cda[CTA_HELP-1]) {
  735. err = ctnetlink_change_helper(ct, cda);
  736. if (err < 0)
  737. return err;
  738. }
  739. if (cda[CTA_TIMEOUT-1]) {
  740. err = ctnetlink_change_timeout(ct, cda);
  741. if (err < 0)
  742. return err;
  743. }
  744. if (cda[CTA_STATUS-1]) {
  745. err = ctnetlink_change_status(ct, cda);
  746. if (err < 0)
  747. return err;
  748. }
  749. if (cda[CTA_PROTOINFO-1]) {
  750. err = ctnetlink_change_protoinfo(ct, cda);
  751. if (err < 0)
  752. return err;
  753. }
  754. #if defined(CONFIG_NF_CONNTRACK_MARK)
  755. if (cda[CTA_MARK-1])
  756. ct->mark = ntohl(*(__be32 *)NFA_DATA(cda[CTA_MARK-1]));
  757. #endif
  758. return 0;
  759. }
  760. static int
  761. ctnetlink_create_conntrack(struct nfattr *cda[],
  762. struct nf_conntrack_tuple *otuple,
  763. struct nf_conntrack_tuple *rtuple)
  764. {
  765. struct nf_conn *ct;
  766. int err = -EINVAL;
  767. struct nf_conn_help *help;
  768. ct = nf_conntrack_alloc(otuple, rtuple);
  769. if (ct == NULL || IS_ERR(ct))
  770. return -ENOMEM;
  771. if (!cda[CTA_TIMEOUT-1])
  772. goto err;
  773. ct->timeout.expires = ntohl(*(__be32 *)NFA_DATA(cda[CTA_TIMEOUT-1]));
  774. ct->timeout.expires = jiffies + ct->timeout.expires * HZ;
  775. ct->status |= IPS_CONFIRMED;
  776. if (cda[CTA_STATUS-1]) {
  777. err = ctnetlink_change_status(ct, cda);
  778. if (err < 0)
  779. goto err;
  780. }
  781. if (cda[CTA_PROTOINFO-1]) {
  782. err = ctnetlink_change_protoinfo(ct, cda);
  783. if (err < 0)
  784. goto err;
  785. }
  786. #if defined(CONFIG_NF_CONNTRACK_MARK)
  787. if (cda[CTA_MARK-1])
  788. ct->mark = ntohl(*(__be32 *)NFA_DATA(cda[CTA_MARK-1]));
  789. #endif
  790. help = nfct_help(ct);
  791. if (help)
  792. help->helper = nf_ct_helper_find_get(rtuple);
  793. add_timer(&ct->timeout);
  794. nf_conntrack_hash_insert(ct);
  795. if (help && help->helper)
  796. nf_ct_helper_put(help->helper);
  797. return 0;
  798. err:
  799. nf_conntrack_free(ct);
  800. return err;
  801. }
  802. static int
  803. ctnetlink_new_conntrack(struct sock *ctnl, struct sk_buff *skb,
  804. struct nlmsghdr *nlh, struct nfattr *cda[], int *errp)
  805. {
  806. struct nf_conntrack_tuple otuple, rtuple;
  807. struct nf_conntrack_tuple_hash *h = NULL;
  808. struct nfgenmsg *nfmsg = NLMSG_DATA(nlh);
  809. u_int8_t u3 = nfmsg->nfgen_family;
  810. int err = 0;
  811. if (nfattr_bad_size(cda, CTA_MAX, cta_min))
  812. return -EINVAL;
  813. if (cda[CTA_TUPLE_ORIG-1]) {
  814. err = ctnetlink_parse_tuple(cda, &otuple, CTA_TUPLE_ORIG, u3);
  815. if (err < 0)
  816. return err;
  817. }
  818. if (cda[CTA_TUPLE_REPLY-1]) {
  819. err = ctnetlink_parse_tuple(cda, &rtuple, CTA_TUPLE_REPLY, u3);
  820. if (err < 0)
  821. return err;
  822. }
  823. write_lock_bh(&nf_conntrack_lock);
  824. if (cda[CTA_TUPLE_ORIG-1])
  825. h = __nf_conntrack_find(&otuple, NULL);
  826. else if (cda[CTA_TUPLE_REPLY-1])
  827. h = __nf_conntrack_find(&rtuple, NULL);
  828. if (h == NULL) {
  829. write_unlock_bh(&nf_conntrack_lock);
  830. err = -ENOENT;
  831. if (nlh->nlmsg_flags & NLM_F_CREATE)
  832. err = ctnetlink_create_conntrack(cda, &otuple, &rtuple);
  833. return err;
  834. }
  835. /* implicit 'else' */
  836. /* we only allow nat config for new conntracks */
  837. if (cda[CTA_NAT_SRC-1] || cda[CTA_NAT_DST-1]) {
  838. err = -EINVAL;
  839. goto out_unlock;
  840. }
  841. /* We manipulate the conntrack inside the global conntrack table lock,
  842. * so there's no need to increase the refcount */
  843. err = -EEXIST;
  844. if (!(nlh->nlmsg_flags & NLM_F_EXCL))
  845. err = ctnetlink_change_conntrack(nf_ct_tuplehash_to_ctrack(h), cda);
  846. out_unlock:
  847. write_unlock_bh(&nf_conntrack_lock);
  848. return err;
  849. }
  850. /***********************************************************************
  851. * EXPECT
  852. ***********************************************************************/
  853. static inline int
  854. ctnetlink_exp_dump_tuple(struct sk_buff *skb,
  855. const struct nf_conntrack_tuple *tuple,
  856. enum ctattr_expect type)
  857. {
  858. struct nfattr *nest_parms = NFA_NEST(skb, type);
  859. if (ctnetlink_dump_tuples(skb, tuple) < 0)
  860. goto nfattr_failure;
  861. NFA_NEST_END(skb, nest_parms);
  862. return 0;
  863. nfattr_failure:
  864. return -1;
  865. }
  866. static inline int
  867. ctnetlink_exp_dump_mask(struct sk_buff *skb,
  868. const struct nf_conntrack_tuple *tuple,
  869. const struct nf_conntrack_tuple *mask)
  870. {
  871. int ret;
  872. struct nf_conntrack_l3proto *l3proto;
  873. struct nf_conntrack_l4proto *l4proto;
  874. struct nfattr *nest_parms = NFA_NEST(skb, CTA_EXPECT_MASK);
  875. l3proto = nf_ct_l3proto_find_get(tuple->src.l3num);
  876. ret = ctnetlink_dump_tuples_ip(skb, mask, l3proto);
  877. nf_ct_l3proto_put(l3proto);
  878. if (unlikely(ret < 0))
  879. goto nfattr_failure;
  880. l4proto = nf_ct_l4proto_find_get(tuple->src.l3num, tuple->dst.protonum);
  881. ret = ctnetlink_dump_tuples_proto(skb, mask, l4proto);
  882. nf_ct_l4proto_put(l4proto);
  883. if (unlikely(ret < 0))
  884. goto nfattr_failure;
  885. NFA_NEST_END(skb, nest_parms);
  886. return 0;
  887. nfattr_failure:
  888. return -1;
  889. }
  890. static inline int
  891. ctnetlink_exp_dump_expect(struct sk_buff *skb,
  892. const struct nf_conntrack_expect *exp)
  893. {
  894. struct nf_conn *master = exp->master;
  895. __be32 timeout = htonl((exp->timeout.expires - jiffies) / HZ);
  896. __be32 id = htonl(exp->id);
  897. if (ctnetlink_exp_dump_tuple(skb, &exp->tuple, CTA_EXPECT_TUPLE) < 0)
  898. goto nfattr_failure;
  899. if (ctnetlink_exp_dump_mask(skb, &exp->tuple, &exp->mask) < 0)
  900. goto nfattr_failure;
  901. if (ctnetlink_exp_dump_tuple(skb,
  902. &master->tuplehash[IP_CT_DIR_ORIGINAL].tuple,
  903. CTA_EXPECT_MASTER) < 0)
  904. goto nfattr_failure;
  905. NFA_PUT(skb, CTA_EXPECT_TIMEOUT, sizeof(timeout), &timeout);
  906. NFA_PUT(skb, CTA_EXPECT_ID, sizeof(u_int32_t), &id);
  907. return 0;
  908. nfattr_failure:
  909. return -1;
  910. }
  911. static int
  912. ctnetlink_exp_fill_info(struct sk_buff *skb, u32 pid, u32 seq,
  913. int event,
  914. int nowait,
  915. const struct nf_conntrack_expect *exp)
  916. {
  917. struct nlmsghdr *nlh;
  918. struct nfgenmsg *nfmsg;
  919. unsigned char *b;
  920. b = skb->tail;
  921. event |= NFNL_SUBSYS_CTNETLINK_EXP << 8;
  922. nlh = NLMSG_PUT(skb, pid, seq, event, sizeof(struct nfgenmsg));
  923. nfmsg = NLMSG_DATA(nlh);
  924. nlh->nlmsg_flags = (nowait && pid) ? NLM_F_MULTI : 0;
  925. nfmsg->nfgen_family = exp->tuple.src.l3num;
  926. nfmsg->version = NFNETLINK_V0;
  927. nfmsg->res_id = 0;
  928. if (ctnetlink_exp_dump_expect(skb, exp) < 0)
  929. goto nfattr_failure;
  930. nlh->nlmsg_len = skb->tail - b;
  931. return skb->len;
  932. nlmsg_failure:
  933. nfattr_failure:
  934. skb_trim(skb, b - skb->data);
  935. return -1;
  936. }
  937. #ifdef CONFIG_NF_CONNTRACK_EVENTS
  938. static int ctnetlink_expect_event(struct notifier_block *this,
  939. unsigned long events, void *ptr)
  940. {
  941. struct nlmsghdr *nlh;
  942. struct nfgenmsg *nfmsg;
  943. struct nf_conntrack_expect *exp = (struct nf_conntrack_expect *)ptr;
  944. struct sk_buff *skb;
  945. unsigned int type;
  946. unsigned char *b;
  947. int flags = 0;
  948. if (events & IPEXP_NEW) {
  949. type = IPCTNL_MSG_EXP_NEW;
  950. flags = NLM_F_CREATE|NLM_F_EXCL;
  951. } else
  952. return NOTIFY_DONE;
  953. if (!nfnetlink_has_listeners(NFNLGRP_CONNTRACK_EXP_NEW))
  954. return NOTIFY_DONE;
  955. skb = alloc_skb(NLMSG_GOODSIZE, GFP_ATOMIC);
  956. if (!skb)
  957. return NOTIFY_DONE;
  958. b = skb->tail;
  959. type |= NFNL_SUBSYS_CTNETLINK_EXP << 8;
  960. nlh = NLMSG_PUT(skb, 0, 0, type, sizeof(struct nfgenmsg));
  961. nfmsg = NLMSG_DATA(nlh);
  962. nlh->nlmsg_flags = flags;
  963. nfmsg->nfgen_family = exp->tuple.src.l3num;
  964. nfmsg->version = NFNETLINK_V0;
  965. nfmsg->res_id = 0;
  966. if (ctnetlink_exp_dump_expect(skb, exp) < 0)
  967. goto nfattr_failure;
  968. nlh->nlmsg_len = skb->tail - b;
  969. nfnetlink_send(skb, 0, NFNLGRP_CONNTRACK_EXP_NEW, 0);
  970. return NOTIFY_DONE;
  971. nlmsg_failure:
  972. nfattr_failure:
  973. kfree_skb(skb);
  974. return NOTIFY_DONE;
  975. }
  976. #endif
  977. static int
  978. ctnetlink_exp_dump_table(struct sk_buff *skb, struct netlink_callback *cb)
  979. {
  980. struct nf_conntrack_expect *exp = NULL;
  981. struct list_head *i;
  982. u_int32_t *id = (u_int32_t *) &cb->args[0];
  983. struct nfgenmsg *nfmsg = NLMSG_DATA(cb->nlh);
  984. u_int8_t l3proto = nfmsg->nfgen_family;
  985. read_lock_bh(&nf_conntrack_lock);
  986. list_for_each_prev(i, &nf_conntrack_expect_list) {
  987. exp = (struct nf_conntrack_expect *) i;
  988. if (l3proto && exp->tuple.src.l3num != l3proto)
  989. continue;
  990. if (exp->id <= *id)
  991. continue;
  992. if (ctnetlink_exp_fill_info(skb, NETLINK_CB(cb->skb).pid,
  993. cb->nlh->nlmsg_seq,
  994. IPCTNL_MSG_EXP_NEW,
  995. 1, exp) < 0)
  996. goto out;
  997. *id = exp->id;
  998. }
  999. out:
  1000. read_unlock_bh(&nf_conntrack_lock);
  1001. return skb->len;
  1002. }
  1003. static const size_t cta_min_exp[CTA_EXPECT_MAX] = {
  1004. [CTA_EXPECT_TIMEOUT-1] = sizeof(u_int32_t),
  1005. [CTA_EXPECT_ID-1] = sizeof(u_int32_t)
  1006. };
  1007. static int
  1008. ctnetlink_get_expect(struct sock *ctnl, struct sk_buff *skb,
  1009. struct nlmsghdr *nlh, struct nfattr *cda[], int *errp)
  1010. {
  1011. struct nf_conntrack_tuple tuple;
  1012. struct nf_conntrack_expect *exp;
  1013. struct sk_buff *skb2;
  1014. struct nfgenmsg *nfmsg = NLMSG_DATA(nlh);
  1015. u_int8_t u3 = nfmsg->nfgen_family;
  1016. int err = 0;
  1017. if (nfattr_bad_size(cda, CTA_EXPECT_MAX, cta_min_exp))
  1018. return -EINVAL;
  1019. if (nlh->nlmsg_flags & NLM_F_DUMP) {
  1020. u32 rlen;
  1021. if ((*errp = netlink_dump_start(ctnl, skb, nlh,
  1022. ctnetlink_exp_dump_table,
  1023. ctnetlink_done)) != 0)
  1024. return -EINVAL;
  1025. rlen = NLMSG_ALIGN(nlh->nlmsg_len);
  1026. if (rlen > skb->len)
  1027. rlen = skb->len;
  1028. skb_pull(skb, rlen);
  1029. return 0;
  1030. }
  1031. if (cda[CTA_EXPECT_MASTER-1])
  1032. err = ctnetlink_parse_tuple(cda, &tuple, CTA_EXPECT_MASTER, u3);
  1033. else
  1034. return -EINVAL;
  1035. if (err < 0)
  1036. return err;
  1037. exp = nf_conntrack_expect_find_get(&tuple);
  1038. if (!exp)
  1039. return -ENOENT;
  1040. if (cda[CTA_EXPECT_ID-1]) {
  1041. __be32 id = *(__be32 *)NFA_DATA(cda[CTA_EXPECT_ID-1]);
  1042. if (exp->id != ntohl(id)) {
  1043. nf_conntrack_expect_put(exp);
  1044. return -ENOENT;
  1045. }
  1046. }
  1047. err = -ENOMEM;
  1048. skb2 = alloc_skb(NLMSG_GOODSIZE, GFP_KERNEL);
  1049. if (!skb2)
  1050. goto out;
  1051. err = ctnetlink_exp_fill_info(skb2, NETLINK_CB(skb).pid,
  1052. nlh->nlmsg_seq, IPCTNL_MSG_EXP_NEW,
  1053. 1, exp);
  1054. if (err <= 0)
  1055. goto free;
  1056. nf_conntrack_expect_put(exp);
  1057. return netlink_unicast(ctnl, skb2, NETLINK_CB(skb).pid, MSG_DONTWAIT);
  1058. free:
  1059. kfree_skb(skb2);
  1060. out:
  1061. nf_conntrack_expect_put(exp);
  1062. return err;
  1063. }
  1064. static int
  1065. ctnetlink_del_expect(struct sock *ctnl, struct sk_buff *skb,
  1066. struct nlmsghdr *nlh, struct nfattr *cda[], int *errp)
  1067. {
  1068. struct nf_conntrack_expect *exp, *tmp;
  1069. struct nf_conntrack_tuple tuple;
  1070. struct nf_conntrack_helper *h;
  1071. struct nfgenmsg *nfmsg = NLMSG_DATA(nlh);
  1072. u_int8_t u3 = nfmsg->nfgen_family;
  1073. int err;
  1074. if (nfattr_bad_size(cda, CTA_EXPECT_MAX, cta_min_exp))
  1075. return -EINVAL;
  1076. if (cda[CTA_EXPECT_TUPLE-1]) {
  1077. /* delete a single expect by tuple */
  1078. err = ctnetlink_parse_tuple(cda, &tuple, CTA_EXPECT_TUPLE, u3);
  1079. if (err < 0)
  1080. return err;
  1081. /* bump usage count to 2 */
  1082. exp = nf_conntrack_expect_find_get(&tuple);
  1083. if (!exp)
  1084. return -ENOENT;
  1085. if (cda[CTA_EXPECT_ID-1]) {
  1086. __be32 id = *(__be32 *)NFA_DATA(cda[CTA_EXPECT_ID-1]);
  1087. if (exp->id != ntohl(id)) {
  1088. nf_conntrack_expect_put(exp);
  1089. return -ENOENT;
  1090. }
  1091. }
  1092. /* after list removal, usage count == 1 */
  1093. nf_conntrack_unexpect_related(exp);
  1094. /* have to put what we 'get' above.
  1095. * after this line usage count == 0 */
  1096. nf_conntrack_expect_put(exp);
  1097. } else if (cda[CTA_EXPECT_HELP_NAME-1]) {
  1098. char *name = NFA_DATA(cda[CTA_EXPECT_HELP_NAME-1]);
  1099. /* delete all expectations for this helper */
  1100. write_lock_bh(&nf_conntrack_lock);
  1101. h = __nf_conntrack_helper_find_byname(name);
  1102. if (!h) {
  1103. write_unlock_bh(&nf_conntrack_lock);
  1104. return -EINVAL;
  1105. }
  1106. list_for_each_entry_safe(exp, tmp, &nf_conntrack_expect_list,
  1107. list) {
  1108. struct nf_conn_help *m_help = nfct_help(exp->master);
  1109. if (m_help->helper == h
  1110. && del_timer(&exp->timeout)) {
  1111. nf_ct_unlink_expect(exp);
  1112. nf_conntrack_expect_put(exp);
  1113. }
  1114. }
  1115. write_unlock_bh(&nf_conntrack_lock);
  1116. } else {
  1117. /* This basically means we have to flush everything*/
  1118. write_lock_bh(&nf_conntrack_lock);
  1119. list_for_each_entry_safe(exp, tmp, &nf_conntrack_expect_list,
  1120. list) {
  1121. if (del_timer(&exp->timeout)) {
  1122. nf_ct_unlink_expect(exp);
  1123. nf_conntrack_expect_put(exp);
  1124. }
  1125. }
  1126. write_unlock_bh(&nf_conntrack_lock);
  1127. }
  1128. return 0;
  1129. }
  1130. static int
  1131. ctnetlink_change_expect(struct nf_conntrack_expect *x, struct nfattr *cda[])
  1132. {
  1133. return -EOPNOTSUPP;
  1134. }
  1135. static int
  1136. ctnetlink_create_expect(struct nfattr *cda[], u_int8_t u3)
  1137. {
  1138. struct nf_conntrack_tuple tuple, mask, master_tuple;
  1139. struct nf_conntrack_tuple_hash *h = NULL;
  1140. struct nf_conntrack_expect *exp;
  1141. struct nf_conn *ct;
  1142. struct nf_conn_help *help;
  1143. int err = 0;
  1144. /* caller guarantees that those three CTA_EXPECT_* exist */
  1145. err = ctnetlink_parse_tuple(cda, &tuple, CTA_EXPECT_TUPLE, u3);
  1146. if (err < 0)
  1147. return err;
  1148. err = ctnetlink_parse_tuple(cda, &mask, CTA_EXPECT_MASK, u3);
  1149. if (err < 0)
  1150. return err;
  1151. err = ctnetlink_parse_tuple(cda, &master_tuple, CTA_EXPECT_MASTER, u3);
  1152. if (err < 0)
  1153. return err;
  1154. /* Look for master conntrack of this expectation */
  1155. h = nf_conntrack_find_get(&master_tuple, NULL);
  1156. if (!h)
  1157. return -ENOENT;
  1158. ct = nf_ct_tuplehash_to_ctrack(h);
  1159. help = nfct_help(ct);
  1160. if (!help || !help->helper) {
  1161. /* such conntrack hasn't got any helper, abort */
  1162. err = -EINVAL;
  1163. goto out;
  1164. }
  1165. exp = nf_conntrack_expect_alloc(ct);
  1166. if (!exp) {
  1167. err = -ENOMEM;
  1168. goto out;
  1169. }
  1170. exp->expectfn = NULL;
  1171. exp->flags = 0;
  1172. exp->master = ct;
  1173. exp->helper = NULL;
  1174. memcpy(&exp->tuple, &tuple, sizeof(struct nf_conntrack_tuple));
  1175. memcpy(&exp->mask, &mask, sizeof(struct nf_conntrack_tuple));
  1176. err = nf_conntrack_expect_related(exp);
  1177. nf_conntrack_expect_put(exp);
  1178. out:
  1179. nf_ct_put(nf_ct_tuplehash_to_ctrack(h));
  1180. return err;
  1181. }
  1182. static int
  1183. ctnetlink_new_expect(struct sock *ctnl, struct sk_buff *skb,
  1184. struct nlmsghdr *nlh, struct nfattr *cda[], int *errp)
  1185. {
  1186. struct nf_conntrack_tuple tuple;
  1187. struct nf_conntrack_expect *exp;
  1188. struct nfgenmsg *nfmsg = NLMSG_DATA(nlh);
  1189. u_int8_t u3 = nfmsg->nfgen_family;
  1190. int err = 0;
  1191. if (nfattr_bad_size(cda, CTA_EXPECT_MAX, cta_min_exp))
  1192. return -EINVAL;
  1193. if (!cda[CTA_EXPECT_TUPLE-1]
  1194. || !cda[CTA_EXPECT_MASK-1]
  1195. || !cda[CTA_EXPECT_MASTER-1])
  1196. return -EINVAL;
  1197. err = ctnetlink_parse_tuple(cda, &tuple, CTA_EXPECT_TUPLE, u3);
  1198. if (err < 0)
  1199. return err;
  1200. write_lock_bh(&nf_conntrack_lock);
  1201. exp = __nf_conntrack_expect_find(&tuple);
  1202. if (!exp) {
  1203. write_unlock_bh(&nf_conntrack_lock);
  1204. err = -ENOENT;
  1205. if (nlh->nlmsg_flags & NLM_F_CREATE)
  1206. err = ctnetlink_create_expect(cda, u3);
  1207. return err;
  1208. }
  1209. err = -EEXIST;
  1210. if (!(nlh->nlmsg_flags & NLM_F_EXCL))
  1211. err = ctnetlink_change_expect(exp, cda);
  1212. write_unlock_bh(&nf_conntrack_lock);
  1213. return err;
  1214. }
  1215. #ifdef CONFIG_NF_CONNTRACK_EVENTS
  1216. static struct notifier_block ctnl_notifier = {
  1217. .notifier_call = ctnetlink_conntrack_event,
  1218. };
  1219. static struct notifier_block ctnl_notifier_exp = {
  1220. .notifier_call = ctnetlink_expect_event,
  1221. };
  1222. #endif
  1223. static struct nfnl_callback ctnl_cb[IPCTNL_MSG_MAX] = {
  1224. [IPCTNL_MSG_CT_NEW] = { .call = ctnetlink_new_conntrack,
  1225. .attr_count = CTA_MAX, },
  1226. [IPCTNL_MSG_CT_GET] = { .call = ctnetlink_get_conntrack,
  1227. .attr_count = CTA_MAX, },
  1228. [IPCTNL_MSG_CT_DELETE] = { .call = ctnetlink_del_conntrack,
  1229. .attr_count = CTA_MAX, },
  1230. [IPCTNL_MSG_CT_GET_CTRZERO] = { .call = ctnetlink_get_conntrack,
  1231. .attr_count = CTA_MAX, },
  1232. };
  1233. static struct nfnl_callback ctnl_exp_cb[IPCTNL_MSG_EXP_MAX] = {
  1234. [IPCTNL_MSG_EXP_GET] = { .call = ctnetlink_get_expect,
  1235. .attr_count = CTA_EXPECT_MAX, },
  1236. [IPCTNL_MSG_EXP_NEW] = { .call = ctnetlink_new_expect,
  1237. .attr_count = CTA_EXPECT_MAX, },
  1238. [IPCTNL_MSG_EXP_DELETE] = { .call = ctnetlink_del_expect,
  1239. .attr_count = CTA_EXPECT_MAX, },
  1240. };
  1241. static struct nfnetlink_subsystem ctnl_subsys = {
  1242. .name = "conntrack",
  1243. .subsys_id = NFNL_SUBSYS_CTNETLINK,
  1244. .cb_count = IPCTNL_MSG_MAX,
  1245. .cb = ctnl_cb,
  1246. };
  1247. static struct nfnetlink_subsystem ctnl_exp_subsys = {
  1248. .name = "conntrack_expect",
  1249. .subsys_id = NFNL_SUBSYS_CTNETLINK_EXP,
  1250. .cb_count = IPCTNL_MSG_EXP_MAX,
  1251. .cb = ctnl_exp_cb,
  1252. };
  1253. MODULE_ALIAS("ip_conntrack_netlink");
  1254. MODULE_ALIAS_NFNL_SUBSYS(NFNL_SUBSYS_CTNETLINK);
  1255. MODULE_ALIAS_NFNL_SUBSYS(NFNL_SUBSYS_CTNETLINK_EXP);
  1256. static int __init ctnetlink_init(void)
  1257. {
  1258. int ret;
  1259. printk("ctnetlink v%s: registering with nfnetlink.\n", version);
  1260. ret = nfnetlink_subsys_register(&ctnl_subsys);
  1261. if (ret < 0) {
  1262. printk("ctnetlink_init: cannot register with nfnetlink.\n");
  1263. goto err_out;
  1264. }
  1265. ret = nfnetlink_subsys_register(&ctnl_exp_subsys);
  1266. if (ret < 0) {
  1267. printk("ctnetlink_init: cannot register exp with nfnetlink.\n");
  1268. goto err_unreg_subsys;
  1269. }
  1270. #ifdef CONFIG_NF_CONNTRACK_EVENTS
  1271. ret = nf_conntrack_register_notifier(&ctnl_notifier);
  1272. if (ret < 0) {
  1273. printk("ctnetlink_init: cannot register notifier.\n");
  1274. goto err_unreg_exp_subsys;
  1275. }
  1276. ret = nf_conntrack_expect_register_notifier(&ctnl_notifier_exp);
  1277. if (ret < 0) {
  1278. printk("ctnetlink_init: cannot expect register notifier.\n");
  1279. goto err_unreg_notifier;
  1280. }
  1281. #endif
  1282. return 0;
  1283. #ifdef CONFIG_NF_CONNTRACK_EVENTS
  1284. err_unreg_notifier:
  1285. nf_conntrack_unregister_notifier(&ctnl_notifier);
  1286. err_unreg_exp_subsys:
  1287. nfnetlink_subsys_unregister(&ctnl_exp_subsys);
  1288. #endif
  1289. err_unreg_subsys:
  1290. nfnetlink_subsys_unregister(&ctnl_subsys);
  1291. err_out:
  1292. return ret;
  1293. }
  1294. static void __exit ctnetlink_exit(void)
  1295. {
  1296. printk("ctnetlink: unregistering from nfnetlink.\n");
  1297. #ifdef CONFIG_NF_CONNTRACK_EVENTS
  1298. nf_conntrack_expect_unregister_notifier(&ctnl_notifier_exp);
  1299. nf_conntrack_unregister_notifier(&ctnl_notifier);
  1300. #endif
  1301. nfnetlink_subsys_unregister(&ctnl_exp_subsys);
  1302. nfnetlink_subsys_unregister(&ctnl_subsys);
  1303. return;
  1304. }
  1305. module_init(ctnetlink_init);
  1306. module_exit(ctnetlink_exit);