return true;
 }
 
+static struct ipv6hdr *icmpv6_bounced_ipv6hdr(struct sk_buff *skb,
+                                             struct ipv6hdr *_bounced_hdr)
+{
+       if (ipv6_hdr(skb)->nexthdr != IPPROTO_ICMPV6)
+               return NULL;
+
+       if (!icmpv6_is_err(icmp6_hdr(skb)->icmp6_type))
+               return NULL;
+
+       return skb_header_pointer(skb,
+                                 skb_transport_offset(skb) + sizeof(struct icmp6hdr),
+                                 sizeof(struct ipv6hdr),
+                                 _bounced_hdr);
+}
+
 static unsigned int
 ip6t_snpt_tg(struct sk_buff *skb, const struct xt_action_param *par)
 {
        const struct ip6t_npt_tginfo *npt = par->targinfo;
+       struct ipv6hdr _bounced_hdr;
+       struct ipv6hdr *bounced_hdr;
+       struct in6_addr bounced_pfx;
 
        if (!ip6t_npt_map_pfx(npt, &ipv6_hdr(skb)->saddr)) {
                icmpv6_send(skb, ICMPV6_PARAMPROB, ICMPV6_HDR_FIELD,
                            offsetof(struct ipv6hdr, saddr));
                return NF_DROP;
        }
+
+       /* rewrite dst addr of bounced packet which was sent to dst range */
+       bounced_hdr = icmpv6_bounced_ipv6hdr(skb, &_bounced_hdr);
+       if (bounced_hdr) {
+               ipv6_addr_prefix(&bounced_pfx, &bounced_hdr->daddr, npt->src_pfx_len);
+               if (ipv6_addr_cmp(&bounced_pfx, &npt->src_pfx.in6) == 0)
+                       ip6t_npt_map_pfx(npt, &bounced_hdr->daddr);
+       }
+
        return XT_CONTINUE;
 }
 
 ip6t_dnpt_tg(struct sk_buff *skb, const struct xt_action_param *par)
 {
        const struct ip6t_npt_tginfo *npt = par->targinfo;
+       struct ipv6hdr _bounced_hdr;
+       struct ipv6hdr *bounced_hdr;
+       struct in6_addr bounced_pfx;
 
        if (!ip6t_npt_map_pfx(npt, &ipv6_hdr(skb)->daddr)) {
                icmpv6_send(skb, ICMPV6_PARAMPROB, ICMPV6_HDR_FIELD,
                            offsetof(struct ipv6hdr, daddr));
                return NF_DROP;
        }
+
+       /* rewrite src addr of bounced packet which was sent from dst range */
+       bounced_hdr = icmpv6_bounced_ipv6hdr(skb, &_bounced_hdr);
+       if (bounced_hdr) {
+               ipv6_addr_prefix(&bounced_pfx, &bounced_hdr->saddr, npt->src_pfx_len);
+               if (ipv6_addr_cmp(&bounced_pfx, &npt->src_pfx.in6) == 0)
+                       ip6t_npt_map_pfx(npt, &bounced_hdr->saddr);
+       }
+
        return XT_CONTINUE;
 }