nf_nat_proto.c 27 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065
  1. // SPDX-License-Identifier: GPL-2.0-only
  2. /* (C) 1999-2001 Paul `Rusty' Russell
  3. * (C) 2002-2006 Netfilter Core Team <coreteam@netfilter.org>
  4. */
  5. #include <linux/types.h>
  6. #include <linux/export.h>
  7. #include <linux/init.h>
  8. #include <linux/udp.h>
  9. #include <linux/tcp.h>
  10. #include <linux/icmp.h>
  11. #include <linux/icmpv6.h>
  12. #include <linux/dccp.h>
  13. #include <linux/sctp.h>
  14. #include <net/sctp/checksum.h>
  15. #include <linux/netfilter.h>
  16. #include <net/netfilter/nf_nat.h>
  17. #include <linux/ipv6.h>
  18. #include <linux/netfilter_ipv6.h>
  19. #include <net/checksum.h>
  20. #include <net/ip6_checksum.h>
  21. #include <net/ip6_route.h>
  22. #include <net/xfrm.h>
  23. #include <net/ipv6.h>
  24. #include <net/netfilter/nf_conntrack_core.h>
  25. #include <net/netfilter/nf_conntrack.h>
  26. #include <linux/netfilter/nfnetlink_conntrack.h>
  27. static void nf_csum_update(struct sk_buff *skb,
  28. unsigned int iphdroff, __sum16 *check,
  29. const struct nf_conntrack_tuple *t,
  30. enum nf_nat_manip_type maniptype);
  31. static void
  32. __udp_manip_pkt(struct sk_buff *skb,
  33. unsigned int iphdroff, struct udphdr *hdr,
  34. const struct nf_conntrack_tuple *tuple,
  35. enum nf_nat_manip_type maniptype, bool do_csum)
  36. {
  37. __be16 *portptr, newport;
  38. if (maniptype == NF_NAT_MANIP_SRC) {
  39. /* Get rid of src port */
  40. newport = tuple->src.u.udp.port;
  41. portptr = &hdr->source;
  42. } else {
  43. /* Get rid of dst port */
  44. newport = tuple->dst.u.udp.port;
  45. portptr = &hdr->dest;
  46. }
  47. if (do_csum) {
  48. nf_csum_update(skb, iphdroff, &hdr->check, tuple, maniptype);
  49. inet_proto_csum_replace2(&hdr->check, skb, *portptr, newport,
  50. false);
  51. if (!hdr->check)
  52. hdr->check = CSUM_MANGLED_0;
  53. }
  54. *portptr = newport;
  55. }
  56. static bool udp_manip_pkt(struct sk_buff *skb,
  57. unsigned int iphdroff, unsigned int hdroff,
  58. const struct nf_conntrack_tuple *tuple,
  59. enum nf_nat_manip_type maniptype)
  60. {
  61. struct udphdr *hdr;
  62. if (skb_ensure_writable(skb, hdroff + sizeof(*hdr)))
  63. return false;
  64. hdr = (struct udphdr *)(skb->data + hdroff);
  65. __udp_manip_pkt(skb, iphdroff, hdr, tuple, maniptype, !!hdr->check);
  66. return true;
  67. }
  68. static bool udplite_manip_pkt(struct sk_buff *skb,
  69. unsigned int iphdroff, unsigned int hdroff,
  70. const struct nf_conntrack_tuple *tuple,
  71. enum nf_nat_manip_type maniptype)
  72. {
  73. #ifdef CONFIG_NF_CT_PROTO_UDPLITE
  74. struct udphdr *hdr;
  75. if (skb_ensure_writable(skb, hdroff + sizeof(*hdr)))
  76. return false;
  77. hdr = (struct udphdr *)(skb->data + hdroff);
  78. __udp_manip_pkt(skb, iphdroff, hdr, tuple, maniptype, true);
  79. #endif
  80. return true;
  81. }
  82. static bool
  83. sctp_manip_pkt(struct sk_buff *skb,
  84. unsigned int iphdroff, unsigned int hdroff,
  85. const struct nf_conntrack_tuple *tuple,
  86. enum nf_nat_manip_type maniptype)
  87. {
  88. #ifdef CONFIG_NF_CT_PROTO_SCTP
  89. struct sctphdr *hdr;
  90. int hdrsize = 8;
  91. /* This could be an inner header returned in imcp packet; in such
  92. * cases we cannot update the checksum field since it is outside
  93. * of the 8 bytes of transport layer headers we are guaranteed.
  94. */
  95. if (skb->len >= hdroff + sizeof(*hdr))
  96. hdrsize = sizeof(*hdr);
  97. if (skb_ensure_writable(skb, hdroff + hdrsize))
  98. return false;
  99. hdr = (struct sctphdr *)(skb->data + hdroff);
  100. if (maniptype == NF_NAT_MANIP_SRC) {
  101. /* Get rid of src port */
  102. hdr->source = tuple->src.u.sctp.port;
  103. } else {
  104. /* Get rid of dst port */
  105. hdr->dest = tuple->dst.u.sctp.port;
  106. }
  107. if (hdrsize < sizeof(*hdr))
  108. return true;
  109. if (skb->ip_summed != CHECKSUM_PARTIAL) {
  110. hdr->checksum = sctp_compute_cksum(skb, hdroff);
  111. skb->ip_summed = CHECKSUM_NONE;
  112. }
  113. #endif
  114. return true;
  115. }
  116. static bool
  117. tcp_manip_pkt(struct sk_buff *skb,
  118. unsigned int iphdroff, unsigned int hdroff,
  119. const struct nf_conntrack_tuple *tuple,
  120. enum nf_nat_manip_type maniptype)
  121. {
  122. struct tcphdr *hdr;
  123. __be16 *portptr, newport, oldport;
  124. int hdrsize = 8; /* TCP connection tracking guarantees this much */
  125. /* this could be a inner header returned in icmp packet; in such
  126. cases we cannot update the checksum field since it is outside of
  127. the 8 bytes of transport layer headers we are guaranteed */
  128. if (skb->len >= hdroff + sizeof(struct tcphdr))
  129. hdrsize = sizeof(struct tcphdr);
  130. if (skb_ensure_writable(skb, hdroff + hdrsize))
  131. return false;
  132. hdr = (struct tcphdr *)(skb->data + hdroff);
  133. if (maniptype == NF_NAT_MANIP_SRC) {
  134. /* Get rid of src port */
  135. newport = tuple->src.u.tcp.port;
  136. portptr = &hdr->source;
  137. } else {
  138. /* Get rid of dst port */
  139. newport = tuple->dst.u.tcp.port;
  140. portptr = &hdr->dest;
  141. }
  142. oldport = *portptr;
  143. *portptr = newport;
  144. if (hdrsize < sizeof(*hdr))
  145. return true;
  146. nf_csum_update(skb, iphdroff, &hdr->check, tuple, maniptype);
  147. inet_proto_csum_replace2(&hdr->check, skb, oldport, newport, false);
  148. return true;
  149. }
  150. static bool
  151. dccp_manip_pkt(struct sk_buff *skb,
  152. unsigned int iphdroff, unsigned int hdroff,
  153. const struct nf_conntrack_tuple *tuple,
  154. enum nf_nat_manip_type maniptype)
  155. {
  156. #ifdef CONFIG_NF_CT_PROTO_DCCP
  157. struct dccp_hdr *hdr;
  158. __be16 *portptr, oldport, newport;
  159. int hdrsize = 8; /* DCCP connection tracking guarantees this much */
  160. if (skb->len >= hdroff + sizeof(struct dccp_hdr))
  161. hdrsize = sizeof(struct dccp_hdr);
  162. if (skb_ensure_writable(skb, hdroff + hdrsize))
  163. return false;
  164. hdr = (struct dccp_hdr *)(skb->data + hdroff);
  165. if (maniptype == NF_NAT_MANIP_SRC) {
  166. newport = tuple->src.u.dccp.port;
  167. portptr = &hdr->dccph_sport;
  168. } else {
  169. newport = tuple->dst.u.dccp.port;
  170. portptr = &hdr->dccph_dport;
  171. }
  172. oldport = *portptr;
  173. *portptr = newport;
  174. if (hdrsize < sizeof(*hdr))
  175. return true;
  176. nf_csum_update(skb, iphdroff, &hdr->dccph_checksum, tuple, maniptype);
  177. inet_proto_csum_replace2(&hdr->dccph_checksum, skb, oldport, newport,
  178. false);
  179. #endif
  180. return true;
  181. }
  182. static bool
  183. icmp_manip_pkt(struct sk_buff *skb,
  184. unsigned int iphdroff, unsigned int hdroff,
  185. const struct nf_conntrack_tuple *tuple,
  186. enum nf_nat_manip_type maniptype)
  187. {
  188. struct icmphdr *hdr;
  189. if (skb_ensure_writable(skb, hdroff + sizeof(*hdr)))
  190. return false;
  191. hdr = (struct icmphdr *)(skb->data + hdroff);
  192. switch (hdr->type) {
  193. case ICMP_ECHO:
  194. case ICMP_ECHOREPLY:
  195. case ICMP_TIMESTAMP:
  196. case ICMP_TIMESTAMPREPLY:
  197. case ICMP_INFO_REQUEST:
  198. case ICMP_INFO_REPLY:
  199. case ICMP_ADDRESS:
  200. case ICMP_ADDRESSREPLY:
  201. break;
  202. default:
  203. return true;
  204. }
  205. inet_proto_csum_replace2(&hdr->checksum, skb,
  206. hdr->un.echo.id, tuple->src.u.icmp.id, false);
  207. hdr->un.echo.id = tuple->src.u.icmp.id;
  208. return true;
  209. }
  210. static bool
  211. icmpv6_manip_pkt(struct sk_buff *skb,
  212. unsigned int iphdroff, unsigned int hdroff,
  213. const struct nf_conntrack_tuple *tuple,
  214. enum nf_nat_manip_type maniptype)
  215. {
  216. struct icmp6hdr *hdr;
  217. if (skb_ensure_writable(skb, hdroff + sizeof(*hdr)))
  218. return false;
  219. hdr = (struct icmp6hdr *)(skb->data + hdroff);
  220. nf_csum_update(skb, iphdroff, &hdr->icmp6_cksum, tuple, maniptype);
  221. if (hdr->icmp6_type == ICMPV6_ECHO_REQUEST ||
  222. hdr->icmp6_type == ICMPV6_ECHO_REPLY) {
  223. inet_proto_csum_replace2(&hdr->icmp6_cksum, skb,
  224. hdr->icmp6_identifier,
  225. tuple->src.u.icmp.id, false);
  226. hdr->icmp6_identifier = tuple->src.u.icmp.id;
  227. }
  228. return true;
  229. }
  230. /* manipulate a GRE packet according to maniptype */
  231. static bool
  232. gre_manip_pkt(struct sk_buff *skb,
  233. unsigned int iphdroff, unsigned int hdroff,
  234. const struct nf_conntrack_tuple *tuple,
  235. enum nf_nat_manip_type maniptype)
  236. {
  237. #if IS_ENABLED(CONFIG_NF_CT_PROTO_GRE)
  238. const struct gre_base_hdr *greh;
  239. struct pptp_gre_header *pgreh;
  240. /* pgreh includes two optional 32bit fields which are not required
  241. * to be there. That's where the magic '8' comes from */
  242. if (skb_ensure_writable(skb, hdroff + sizeof(*pgreh) - 8))
  243. return false;
  244. greh = (void *)skb->data + hdroff;
  245. pgreh = (struct pptp_gre_header *)greh;
  246. /* we only have destination manip of a packet, since 'source key'
  247. * is not present in the packet itself */
  248. if (maniptype != NF_NAT_MANIP_DST)
  249. return true;
  250. switch (greh->flags & GRE_VERSION) {
  251. case GRE_VERSION_0:
  252. /* We do not currently NAT any GREv0 packets.
  253. * Try to behave like "nf_nat_proto_unknown" */
  254. break;
  255. case GRE_VERSION_1:
  256. pr_debug("call_id -> 0x%04x\n", ntohs(tuple->dst.u.gre.key));
  257. pgreh->call_id = tuple->dst.u.gre.key;
  258. break;
  259. default:
  260. pr_debug("can't nat unknown GRE version\n");
  261. return false;
  262. }
  263. #endif
  264. return true;
  265. }
  266. static bool l4proto_manip_pkt(struct sk_buff *skb,
  267. unsigned int iphdroff, unsigned int hdroff,
  268. const struct nf_conntrack_tuple *tuple,
  269. enum nf_nat_manip_type maniptype)
  270. {
  271. switch (tuple->dst.protonum) {
  272. case IPPROTO_TCP:
  273. return tcp_manip_pkt(skb, iphdroff, hdroff,
  274. tuple, maniptype);
  275. case IPPROTO_UDP:
  276. return udp_manip_pkt(skb, iphdroff, hdroff,
  277. tuple, maniptype);
  278. case IPPROTO_UDPLITE:
  279. return udplite_manip_pkt(skb, iphdroff, hdroff,
  280. tuple, maniptype);
  281. case IPPROTO_SCTP:
  282. return sctp_manip_pkt(skb, iphdroff, hdroff,
  283. tuple, maniptype);
  284. case IPPROTO_ICMP:
  285. return icmp_manip_pkt(skb, iphdroff, hdroff,
  286. tuple, maniptype);
  287. case IPPROTO_ICMPV6:
  288. return icmpv6_manip_pkt(skb, iphdroff, hdroff,
  289. tuple, maniptype);
  290. case IPPROTO_DCCP:
  291. return dccp_manip_pkt(skb, iphdroff, hdroff,
  292. tuple, maniptype);
  293. case IPPROTO_GRE:
  294. return gre_manip_pkt(skb, iphdroff, hdroff,
  295. tuple, maniptype);
  296. }
  297. /* If we don't know protocol -- no error, pass it unmodified. */
  298. return true;
  299. }
  300. static bool nf_nat_ipv4_manip_pkt(struct sk_buff *skb,
  301. unsigned int iphdroff,
  302. const struct nf_conntrack_tuple *target,
  303. enum nf_nat_manip_type maniptype)
  304. {
  305. struct iphdr *iph;
  306. unsigned int hdroff;
  307. if (skb_ensure_writable(skb, iphdroff + sizeof(*iph)))
  308. return false;
  309. iph = (void *)skb->data + iphdroff;
  310. hdroff = iphdroff + iph->ihl * 4;
  311. if (!l4proto_manip_pkt(skb, iphdroff, hdroff, target, maniptype))
  312. return false;
  313. iph = (void *)skb->data + iphdroff;
  314. if (maniptype == NF_NAT_MANIP_SRC) {
  315. csum_replace4(&iph->check, iph->saddr, target->src.u3.ip);
  316. iph->saddr = target->src.u3.ip;
  317. } else {
  318. csum_replace4(&iph->check, iph->daddr, target->dst.u3.ip);
  319. iph->daddr = target->dst.u3.ip;
  320. }
  321. return true;
  322. }
  323. static bool nf_nat_ipv6_manip_pkt(struct sk_buff *skb,
  324. unsigned int iphdroff,
  325. const struct nf_conntrack_tuple *target,
  326. enum nf_nat_manip_type maniptype)
  327. {
  328. #if IS_ENABLED(CONFIG_IPV6)
  329. struct ipv6hdr *ipv6h;
  330. __be16 frag_off;
  331. int hdroff;
  332. u8 nexthdr;
  333. if (skb_ensure_writable(skb, iphdroff + sizeof(*ipv6h)))
  334. return false;
  335. ipv6h = (void *)skb->data + iphdroff;
  336. nexthdr = ipv6h->nexthdr;
  337. hdroff = ipv6_skip_exthdr(skb, iphdroff + sizeof(*ipv6h),
  338. &nexthdr, &frag_off);
  339. if (hdroff < 0)
  340. goto manip_addr;
  341. if ((frag_off & htons(~0x7)) == 0 &&
  342. !l4proto_manip_pkt(skb, iphdroff, hdroff, target, maniptype))
  343. return false;
  344. /* must reload, offset might have changed */
  345. ipv6h = (void *)skb->data + iphdroff;
  346. manip_addr:
  347. if (maniptype == NF_NAT_MANIP_SRC)
  348. ipv6h->saddr = target->src.u3.in6;
  349. else
  350. ipv6h->daddr = target->dst.u3.in6;
  351. #endif
  352. return true;
  353. }
  354. unsigned int nf_nat_manip_pkt(struct sk_buff *skb, struct nf_conn *ct,
  355. enum nf_nat_manip_type mtype,
  356. enum ip_conntrack_dir dir)
  357. {
  358. struct nf_conntrack_tuple target;
  359. /* We are aiming to look like inverse of other direction. */
  360. nf_ct_invert_tuple(&target, &ct->tuplehash[!dir].tuple);
  361. switch (target.src.l3num) {
  362. case NFPROTO_IPV6:
  363. if (nf_nat_ipv6_manip_pkt(skb, 0, &target, mtype))
  364. return NF_ACCEPT;
  365. break;
  366. case NFPROTO_IPV4:
  367. if (nf_nat_ipv4_manip_pkt(skb, 0, &target, mtype))
  368. return NF_ACCEPT;
  369. break;
  370. default:
  371. WARN_ON_ONCE(1);
  372. break;
  373. }
  374. return NF_DROP;
  375. }
  376. static void nf_nat_ipv4_csum_update(struct sk_buff *skb,
  377. unsigned int iphdroff, __sum16 *check,
  378. const struct nf_conntrack_tuple *t,
  379. enum nf_nat_manip_type maniptype)
  380. {
  381. struct iphdr *iph = (struct iphdr *)(skb->data + iphdroff);
  382. __be32 oldip, newip;
  383. if (maniptype == NF_NAT_MANIP_SRC) {
  384. oldip = iph->saddr;
  385. newip = t->src.u3.ip;
  386. } else {
  387. oldip = iph->daddr;
  388. newip = t->dst.u3.ip;
  389. }
  390. inet_proto_csum_replace4(check, skb, oldip, newip, true);
  391. }
  392. static void nf_nat_ipv6_csum_update(struct sk_buff *skb,
  393. unsigned int iphdroff, __sum16 *check,
  394. const struct nf_conntrack_tuple *t,
  395. enum nf_nat_manip_type maniptype)
  396. {
  397. #if IS_ENABLED(CONFIG_IPV6)
  398. const struct ipv6hdr *ipv6h = (struct ipv6hdr *)(skb->data + iphdroff);
  399. const struct in6_addr *oldip, *newip;
  400. if (maniptype == NF_NAT_MANIP_SRC) {
  401. oldip = &ipv6h->saddr;
  402. newip = &t->src.u3.in6;
  403. } else {
  404. oldip = &ipv6h->daddr;
  405. newip = &t->dst.u3.in6;
  406. }
  407. inet_proto_csum_replace16(check, skb, oldip->s6_addr32,
  408. newip->s6_addr32, true);
  409. #endif
  410. }
  411. static void nf_csum_update(struct sk_buff *skb,
  412. unsigned int iphdroff, __sum16 *check,
  413. const struct nf_conntrack_tuple *t,
  414. enum nf_nat_manip_type maniptype)
  415. {
  416. switch (t->src.l3num) {
  417. case NFPROTO_IPV4:
  418. nf_nat_ipv4_csum_update(skb, iphdroff, check, t, maniptype);
  419. return;
  420. case NFPROTO_IPV6:
  421. nf_nat_ipv6_csum_update(skb, iphdroff, check, t, maniptype);
  422. return;
  423. }
  424. }
  425. static void nf_nat_ipv4_csum_recalc(struct sk_buff *skb,
  426. u8 proto, void *data, __sum16 *check,
  427. int datalen, int oldlen)
  428. {
  429. if (skb->ip_summed != CHECKSUM_PARTIAL) {
  430. const struct iphdr *iph = ip_hdr(skb);
  431. skb->ip_summed = CHECKSUM_PARTIAL;
  432. skb->csum_start = skb_headroom(skb) + skb_network_offset(skb) +
  433. ip_hdrlen(skb);
  434. skb->csum_offset = (void *)check - data;
  435. *check = ~csum_tcpudp_magic(iph->saddr, iph->daddr, datalen,
  436. proto, 0);
  437. } else {
  438. inet_proto_csum_replace2(check, skb,
  439. htons(oldlen), htons(datalen), true);
  440. }
  441. }
  442. #if IS_ENABLED(CONFIG_IPV6)
  443. static void nf_nat_ipv6_csum_recalc(struct sk_buff *skb,
  444. u8 proto, void *data, __sum16 *check,
  445. int datalen, int oldlen)
  446. {
  447. if (skb->ip_summed != CHECKSUM_PARTIAL) {
  448. const struct ipv6hdr *ipv6h = ipv6_hdr(skb);
  449. skb->ip_summed = CHECKSUM_PARTIAL;
  450. skb->csum_start = skb_headroom(skb) + skb_network_offset(skb) +
  451. (data - (void *)skb->data);
  452. skb->csum_offset = (void *)check - data;
  453. *check = ~csum_ipv6_magic(&ipv6h->saddr, &ipv6h->daddr,
  454. datalen, proto, 0);
  455. } else {
  456. inet_proto_csum_replace2(check, skb,
  457. htons(oldlen), htons(datalen), true);
  458. }
  459. }
  460. #endif
  461. void nf_nat_csum_recalc(struct sk_buff *skb,
  462. u8 nfproto, u8 proto, void *data, __sum16 *check,
  463. int datalen, int oldlen)
  464. {
  465. switch (nfproto) {
  466. case NFPROTO_IPV4:
  467. nf_nat_ipv4_csum_recalc(skb, proto, data, check,
  468. datalen, oldlen);
  469. return;
  470. #if IS_ENABLED(CONFIG_IPV6)
  471. case NFPROTO_IPV6:
  472. nf_nat_ipv6_csum_recalc(skb, proto, data, check,
  473. datalen, oldlen);
  474. return;
  475. #endif
  476. }
  477. WARN_ON_ONCE(1);
  478. }
  479. int nf_nat_icmp_reply_translation(struct sk_buff *skb,
  480. struct nf_conn *ct,
  481. enum ip_conntrack_info ctinfo,
  482. unsigned int hooknum)
  483. {
  484. struct {
  485. struct icmphdr icmp;
  486. struct iphdr ip;
  487. } *inside;
  488. enum ip_conntrack_dir dir = CTINFO2DIR(ctinfo);
  489. enum nf_nat_manip_type manip = HOOK2MANIP(hooknum);
  490. unsigned int hdrlen = ip_hdrlen(skb);
  491. struct nf_conntrack_tuple target;
  492. unsigned long statusbit;
  493. WARN_ON(ctinfo != IP_CT_RELATED && ctinfo != IP_CT_RELATED_REPLY);
  494. if (skb_ensure_writable(skb, hdrlen + sizeof(*inside)))
  495. return 0;
  496. if (nf_ip_checksum(skb, hooknum, hdrlen, IPPROTO_ICMP))
  497. return 0;
  498. inside = (void *)skb->data + hdrlen;
  499. if (inside->icmp.type == ICMP_REDIRECT) {
  500. if ((ct->status & IPS_NAT_DONE_MASK) != IPS_NAT_DONE_MASK)
  501. return 0;
  502. if (ct->status & IPS_NAT_MASK)
  503. return 0;
  504. }
  505. if (manip == NF_NAT_MANIP_SRC)
  506. statusbit = IPS_SRC_NAT;
  507. else
  508. statusbit = IPS_DST_NAT;
  509. /* Invert if this is reply direction */
  510. if (dir == IP_CT_DIR_REPLY)
  511. statusbit ^= IPS_NAT_MASK;
  512. if (!(ct->status & statusbit))
  513. return 1;
  514. if (!nf_nat_ipv4_manip_pkt(skb, hdrlen + sizeof(inside->icmp),
  515. &ct->tuplehash[!dir].tuple, !manip))
  516. return 0;
  517. if (skb->ip_summed != CHECKSUM_PARTIAL) {
  518. /* Reloading "inside" here since manip_pkt may reallocate */
  519. inside = (void *)skb->data + hdrlen;
  520. inside->icmp.checksum = 0;
  521. inside->icmp.checksum =
  522. csum_fold(skb_checksum(skb, hdrlen,
  523. skb->len - hdrlen, 0));
  524. }
  525. /* Change outer to look like the reply to an incoming packet */
  526. nf_ct_invert_tuple(&target, &ct->tuplehash[!dir].tuple);
  527. target.dst.protonum = IPPROTO_ICMP;
  528. if (!nf_nat_ipv4_manip_pkt(skb, 0, &target, manip))
  529. return 0;
  530. return 1;
  531. }
  532. EXPORT_SYMBOL_GPL(nf_nat_icmp_reply_translation);
  533. static unsigned int
  534. nf_nat_ipv4_fn(void *priv, struct sk_buff *skb,
  535. const struct nf_hook_state *state)
  536. {
  537. struct nf_conn *ct;
  538. enum ip_conntrack_info ctinfo;
  539. ct = nf_ct_get(skb, &ctinfo);
  540. if (!ct)
  541. return NF_ACCEPT;
  542. if (ctinfo == IP_CT_RELATED || ctinfo == IP_CT_RELATED_REPLY) {
  543. if (ip_hdr(skb)->protocol == IPPROTO_ICMP) {
  544. if (!nf_nat_icmp_reply_translation(skb, ct, ctinfo,
  545. state->hook))
  546. return NF_DROP;
  547. else
  548. return NF_ACCEPT;
  549. }
  550. }
  551. return nf_nat_inet_fn(priv, skb, state);
  552. }
  553. static unsigned int
  554. nf_nat_ipv4_pre_routing(void *priv, struct sk_buff *skb,
  555. const struct nf_hook_state *state)
  556. {
  557. unsigned int ret;
  558. __be32 daddr = ip_hdr(skb)->daddr;
  559. ret = nf_nat_ipv4_fn(priv, skb, state);
  560. if (ret == NF_ACCEPT && daddr != ip_hdr(skb)->daddr)
  561. skb_dst_drop(skb);
  562. return ret;
  563. }
  564. static unsigned int
  565. nf_nat_ipv4_local_in(void *priv, struct sk_buff *skb,
  566. const struct nf_hook_state *state)
  567. {
  568. __be32 saddr = ip_hdr(skb)->saddr;
  569. struct sock *sk = skb->sk;
  570. unsigned int ret;
  571. ret = nf_nat_ipv4_fn(priv, skb, state);
  572. if (ret == NF_ACCEPT && sk && saddr != ip_hdr(skb)->saddr &&
  573. !inet_sk_transparent(sk))
  574. skb_orphan(skb); /* TCP edemux obtained wrong socket */
  575. return ret;
  576. }
  577. static unsigned int
  578. nf_nat_ipv4_out(void *priv, struct sk_buff *skb,
  579. const struct nf_hook_state *state)
  580. {
  581. #ifdef CONFIG_XFRM
  582. const struct nf_conn *ct;
  583. enum ip_conntrack_info ctinfo;
  584. int err;
  585. #endif
  586. unsigned int ret;
  587. ret = nf_nat_ipv4_fn(priv, skb, state);
  588. #ifdef CONFIG_XFRM
  589. if (ret != NF_ACCEPT)
  590. return ret;
  591. if (IPCB(skb)->flags & IPSKB_XFRM_TRANSFORMED)
  592. return ret;
  593. ct = nf_ct_get(skb, &ctinfo);
  594. if (ct) {
  595. enum ip_conntrack_dir dir = CTINFO2DIR(ctinfo);
  596. if (ct->tuplehash[dir].tuple.src.u3.ip !=
  597. ct->tuplehash[!dir].tuple.dst.u3.ip ||
  598. (ct->tuplehash[dir].tuple.dst.protonum != IPPROTO_ICMP &&
  599. ct->tuplehash[dir].tuple.src.u.all !=
  600. ct->tuplehash[!dir].tuple.dst.u.all)) {
  601. err = nf_xfrm_me_harder(state->net, skb, AF_INET);
  602. if (err < 0)
  603. ret = NF_DROP_ERR(err);
  604. }
  605. }
  606. #endif
  607. return ret;
  608. }
  609. static unsigned int
  610. nf_nat_ipv4_local_fn(void *priv, struct sk_buff *skb,
  611. const struct nf_hook_state *state)
  612. {
  613. const struct nf_conn *ct;
  614. enum ip_conntrack_info ctinfo;
  615. unsigned int ret;
  616. int err;
  617. ret = nf_nat_ipv4_fn(priv, skb, state);
  618. if (ret != NF_ACCEPT)
  619. return ret;
  620. ct = nf_ct_get(skb, &ctinfo);
  621. if (ct) {
  622. enum ip_conntrack_dir dir = CTINFO2DIR(ctinfo);
  623. if (ct->tuplehash[dir].tuple.dst.u3.ip !=
  624. ct->tuplehash[!dir].tuple.src.u3.ip) {
  625. err = ip_route_me_harder(state->net, state->sk, skb, RTN_UNSPEC);
  626. if (err < 0)
  627. ret = NF_DROP_ERR(err);
  628. }
  629. #ifdef CONFIG_XFRM
  630. else if (!(IPCB(skb)->flags & IPSKB_XFRM_TRANSFORMED) &&
  631. ct->tuplehash[dir].tuple.dst.protonum != IPPROTO_ICMP &&
  632. ct->tuplehash[dir].tuple.dst.u.all !=
  633. ct->tuplehash[!dir].tuple.src.u.all) {
  634. err = nf_xfrm_me_harder(state->net, skb, AF_INET);
  635. if (err < 0)
  636. ret = NF_DROP_ERR(err);
  637. }
  638. #endif
  639. }
  640. return ret;
  641. }
  642. static const struct nf_hook_ops nf_nat_ipv4_ops[] = {
  643. /* Before packet filtering, change destination */
  644. {
  645. .hook = nf_nat_ipv4_pre_routing,
  646. .pf = NFPROTO_IPV4,
  647. .hooknum = NF_INET_PRE_ROUTING,
  648. .priority = NF_IP_PRI_NAT_DST,
  649. },
  650. /* After packet filtering, change source */
  651. {
  652. .hook = nf_nat_ipv4_out,
  653. .pf = NFPROTO_IPV4,
  654. .hooknum = NF_INET_POST_ROUTING,
  655. .priority = NF_IP_PRI_NAT_SRC,
  656. },
  657. /* Before packet filtering, change destination */
  658. {
  659. .hook = nf_nat_ipv4_local_fn,
  660. .pf = NFPROTO_IPV4,
  661. .hooknum = NF_INET_LOCAL_OUT,
  662. .priority = NF_IP_PRI_NAT_DST,
  663. },
  664. /* After packet filtering, change source */
  665. {
  666. .hook = nf_nat_ipv4_local_in,
  667. .pf = NFPROTO_IPV4,
  668. .hooknum = NF_INET_LOCAL_IN,
  669. .priority = NF_IP_PRI_NAT_SRC,
  670. },
  671. };
  672. int nf_nat_ipv4_register_fn(struct net *net, const struct nf_hook_ops *ops)
  673. {
  674. return nf_nat_register_fn(net, ops->pf, ops, nf_nat_ipv4_ops,
  675. ARRAY_SIZE(nf_nat_ipv4_ops));
  676. }
  677. EXPORT_SYMBOL_GPL(nf_nat_ipv4_register_fn);
  678. void nf_nat_ipv4_unregister_fn(struct net *net, const struct nf_hook_ops *ops)
  679. {
  680. nf_nat_unregister_fn(net, ops->pf, ops, ARRAY_SIZE(nf_nat_ipv4_ops));
  681. }
  682. EXPORT_SYMBOL_GPL(nf_nat_ipv4_unregister_fn);
  683. #if IS_ENABLED(CONFIG_IPV6)
  684. int nf_nat_icmpv6_reply_translation(struct sk_buff *skb,
  685. struct nf_conn *ct,
  686. enum ip_conntrack_info ctinfo,
  687. unsigned int hooknum,
  688. unsigned int hdrlen)
  689. {
  690. struct {
  691. struct icmp6hdr icmp6;
  692. struct ipv6hdr ip6;
  693. } *inside;
  694. enum ip_conntrack_dir dir = CTINFO2DIR(ctinfo);
  695. enum nf_nat_manip_type manip = HOOK2MANIP(hooknum);
  696. struct nf_conntrack_tuple target;
  697. unsigned long statusbit;
  698. WARN_ON(ctinfo != IP_CT_RELATED && ctinfo != IP_CT_RELATED_REPLY);
  699. if (skb_ensure_writable(skb, hdrlen + sizeof(*inside)))
  700. return 0;
  701. if (nf_ip6_checksum(skb, hooknum, hdrlen, IPPROTO_ICMPV6))
  702. return 0;
  703. inside = (void *)skb->data + hdrlen;
  704. if (inside->icmp6.icmp6_type == NDISC_REDIRECT) {
  705. if ((ct->status & IPS_NAT_DONE_MASK) != IPS_NAT_DONE_MASK)
  706. return 0;
  707. if (ct->status & IPS_NAT_MASK)
  708. return 0;
  709. }
  710. if (manip == NF_NAT_MANIP_SRC)
  711. statusbit = IPS_SRC_NAT;
  712. else
  713. statusbit = IPS_DST_NAT;
  714. /* Invert if this is reply direction */
  715. if (dir == IP_CT_DIR_REPLY)
  716. statusbit ^= IPS_NAT_MASK;
  717. if (!(ct->status & statusbit))
  718. return 1;
  719. if (!nf_nat_ipv6_manip_pkt(skb, hdrlen + sizeof(inside->icmp6),
  720. &ct->tuplehash[!dir].tuple, !manip))
  721. return 0;
  722. if (skb->ip_summed != CHECKSUM_PARTIAL) {
  723. struct ipv6hdr *ipv6h = ipv6_hdr(skb);
  724. inside = (void *)skb->data + hdrlen;
  725. inside->icmp6.icmp6_cksum = 0;
  726. inside->icmp6.icmp6_cksum =
  727. csum_ipv6_magic(&ipv6h->saddr, &ipv6h->daddr,
  728. skb->len - hdrlen, IPPROTO_ICMPV6,
  729. skb_checksum(skb, hdrlen,
  730. skb->len - hdrlen, 0));
  731. }
  732. nf_ct_invert_tuple(&target, &ct->tuplehash[!dir].tuple);
  733. target.dst.protonum = IPPROTO_ICMPV6;
  734. if (!nf_nat_ipv6_manip_pkt(skb, 0, &target, manip))
  735. return 0;
  736. return 1;
  737. }
  738. EXPORT_SYMBOL_GPL(nf_nat_icmpv6_reply_translation);
  739. static unsigned int
  740. nf_nat_ipv6_fn(void *priv, struct sk_buff *skb,
  741. const struct nf_hook_state *state)
  742. {
  743. struct nf_conn *ct;
  744. enum ip_conntrack_info ctinfo;
  745. __be16 frag_off;
  746. int hdrlen;
  747. u8 nexthdr;
  748. ct = nf_ct_get(skb, &ctinfo);
  749. /* Can't track? It's not due to stress, or conntrack would
  750. * have dropped it. Hence it's the user's responsibilty to
  751. * packet filter it out, or implement conntrack/NAT for that
  752. * protocol. 8) --RR
  753. */
  754. if (!ct)
  755. return NF_ACCEPT;
  756. if (ctinfo == IP_CT_RELATED || ctinfo == IP_CT_RELATED_REPLY) {
  757. nexthdr = ipv6_hdr(skb)->nexthdr;
  758. hdrlen = ipv6_skip_exthdr(skb, sizeof(struct ipv6hdr),
  759. &nexthdr, &frag_off);
  760. if (hdrlen >= 0 && nexthdr == IPPROTO_ICMPV6) {
  761. if (!nf_nat_icmpv6_reply_translation(skb, ct, ctinfo,
  762. state->hook,
  763. hdrlen))
  764. return NF_DROP;
  765. else
  766. return NF_ACCEPT;
  767. }
  768. }
  769. return nf_nat_inet_fn(priv, skb, state);
  770. }
  771. static unsigned int
  772. nf_nat_ipv6_in(void *priv, struct sk_buff *skb,
  773. const struct nf_hook_state *state)
  774. {
  775. unsigned int ret;
  776. struct in6_addr daddr = ipv6_hdr(skb)->daddr;
  777. ret = nf_nat_ipv6_fn(priv, skb, state);
  778. if (ret != NF_DROP && ret != NF_STOLEN &&
  779. ipv6_addr_cmp(&daddr, &ipv6_hdr(skb)->daddr))
  780. skb_dst_drop(skb);
  781. return ret;
  782. }
  783. static unsigned int
  784. nf_nat_ipv6_out(void *priv, struct sk_buff *skb,
  785. const struct nf_hook_state *state)
  786. {
  787. #ifdef CONFIG_XFRM
  788. const struct nf_conn *ct;
  789. enum ip_conntrack_info ctinfo;
  790. int err;
  791. #endif
  792. unsigned int ret;
  793. ret = nf_nat_ipv6_fn(priv, skb, state);
  794. #ifdef CONFIG_XFRM
  795. if (ret != NF_ACCEPT)
  796. return ret;
  797. if (IP6CB(skb)->flags & IP6SKB_XFRM_TRANSFORMED)
  798. return ret;
  799. ct = nf_ct_get(skb, &ctinfo);
  800. if (ct) {
  801. enum ip_conntrack_dir dir = CTINFO2DIR(ctinfo);
  802. if (!nf_inet_addr_cmp(&ct->tuplehash[dir].tuple.src.u3,
  803. &ct->tuplehash[!dir].tuple.dst.u3) ||
  804. (ct->tuplehash[dir].tuple.dst.protonum != IPPROTO_ICMPV6 &&
  805. ct->tuplehash[dir].tuple.src.u.all !=
  806. ct->tuplehash[!dir].tuple.dst.u.all)) {
  807. err = nf_xfrm_me_harder(state->net, skb, AF_INET6);
  808. if (err < 0)
  809. ret = NF_DROP_ERR(err);
  810. }
  811. }
  812. #endif
  813. return ret;
  814. }
  815. static unsigned int
  816. nf_nat_ipv6_local_fn(void *priv, struct sk_buff *skb,
  817. const struct nf_hook_state *state)
  818. {
  819. const struct nf_conn *ct;
  820. enum ip_conntrack_info ctinfo;
  821. unsigned int ret;
  822. int err;
  823. ret = nf_nat_ipv6_fn(priv, skb, state);
  824. if (ret != NF_ACCEPT)
  825. return ret;
  826. ct = nf_ct_get(skb, &ctinfo);
  827. if (ct) {
  828. enum ip_conntrack_dir dir = CTINFO2DIR(ctinfo);
  829. if (!nf_inet_addr_cmp(&ct->tuplehash[dir].tuple.dst.u3,
  830. &ct->tuplehash[!dir].tuple.src.u3)) {
  831. err = nf_ip6_route_me_harder(state->net, state->sk, skb);
  832. if (err < 0)
  833. ret = NF_DROP_ERR(err);
  834. }
  835. #ifdef CONFIG_XFRM
  836. else if (!(IP6CB(skb)->flags & IP6SKB_XFRM_TRANSFORMED) &&
  837. ct->tuplehash[dir].tuple.dst.protonum != IPPROTO_ICMPV6 &&
  838. ct->tuplehash[dir].tuple.dst.u.all !=
  839. ct->tuplehash[!dir].tuple.src.u.all) {
  840. err = nf_xfrm_me_harder(state->net, skb, AF_INET6);
  841. if (err < 0)
  842. ret = NF_DROP_ERR(err);
  843. }
  844. #endif
  845. }
  846. return ret;
  847. }
  848. static const struct nf_hook_ops nf_nat_ipv6_ops[] = {
  849. /* Before packet filtering, change destination */
  850. {
  851. .hook = nf_nat_ipv6_in,
  852. .pf = NFPROTO_IPV6,
  853. .hooknum = NF_INET_PRE_ROUTING,
  854. .priority = NF_IP6_PRI_NAT_DST,
  855. },
  856. /* After packet filtering, change source */
  857. {
  858. .hook = nf_nat_ipv6_out,
  859. .pf = NFPROTO_IPV6,
  860. .hooknum = NF_INET_POST_ROUTING,
  861. .priority = NF_IP6_PRI_NAT_SRC,
  862. },
  863. /* Before packet filtering, change destination */
  864. {
  865. .hook = nf_nat_ipv6_local_fn,
  866. .pf = NFPROTO_IPV6,
  867. .hooknum = NF_INET_LOCAL_OUT,
  868. .priority = NF_IP6_PRI_NAT_DST,
  869. },
  870. /* After packet filtering, change source */
  871. {
  872. .hook = nf_nat_ipv6_fn,
  873. .pf = NFPROTO_IPV6,
  874. .hooknum = NF_INET_LOCAL_IN,
  875. .priority = NF_IP6_PRI_NAT_SRC,
  876. },
  877. };
  878. int nf_nat_ipv6_register_fn(struct net *net, const struct nf_hook_ops *ops)
  879. {
  880. return nf_nat_register_fn(net, ops->pf, ops, nf_nat_ipv6_ops,
  881. ARRAY_SIZE(nf_nat_ipv6_ops));
  882. }
  883. EXPORT_SYMBOL_GPL(nf_nat_ipv6_register_fn);
  884. void nf_nat_ipv6_unregister_fn(struct net *net, const struct nf_hook_ops *ops)
  885. {
  886. nf_nat_unregister_fn(net, ops->pf, ops, ARRAY_SIZE(nf_nat_ipv6_ops));
  887. }
  888. EXPORT_SYMBOL_GPL(nf_nat_ipv6_unregister_fn);
  889. #endif /* CONFIG_IPV6 */
  890. #if defined(CONFIG_NF_TABLES_INET) && IS_ENABLED(CONFIG_NFT_NAT)
  891. int nf_nat_inet_register_fn(struct net *net, const struct nf_hook_ops *ops)
  892. {
  893. int ret;
  894. if (WARN_ON_ONCE(ops->pf != NFPROTO_INET))
  895. return -EINVAL;
  896. ret = nf_nat_register_fn(net, NFPROTO_IPV6, ops, nf_nat_ipv6_ops,
  897. ARRAY_SIZE(nf_nat_ipv6_ops));
  898. if (ret)
  899. return ret;
  900. ret = nf_nat_register_fn(net, NFPROTO_IPV4, ops, nf_nat_ipv4_ops,
  901. ARRAY_SIZE(nf_nat_ipv4_ops));
  902. if (ret)
  903. nf_nat_unregister_fn(net, NFPROTO_IPV6, ops,
  904. ARRAY_SIZE(nf_nat_ipv6_ops));
  905. return ret;
  906. }
  907. EXPORT_SYMBOL_GPL(nf_nat_inet_register_fn);
  908. void nf_nat_inet_unregister_fn(struct net *net, const struct nf_hook_ops *ops)
  909. {
  910. nf_nat_unregister_fn(net, NFPROTO_IPV4, ops, ARRAY_SIZE(nf_nat_ipv4_ops));
  911. nf_nat_unregister_fn(net, NFPROTO_IPV6, ops, ARRAY_SIZE(nf_nat_ipv6_ops));
  912. }
  913. EXPORT_SYMBOL_GPL(nf_nat_inet_unregister_fn);
  914. #endif /* NFT INET NAT */