ip_conntrack_netlink.c 37 KB

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