Contributors: 10
| Author |
Tokens |
Token Proportion |
Commits |
Commit Proportion |
| Jason A. Donenfeld |
189 |
67.74% |
2 |
11.76% |
| Linus Torvalds (pre-git) |
40 |
14.34% |
7 |
41.18% |
| Pravin B Shelar |
18 |
6.45% |
1 |
5.88% |
| Fabian Bläse |
16 |
5.73% |
1 |
5.88% |
| Fernando Fernandez Mancera |
7 |
2.51% |
1 |
5.88% |
| Brian Haley |
2 |
0.72% |
1 |
5.88% |
| David S. Miller |
2 |
0.72% |
1 |
5.88% |
| Denis V. Lunev |
2 |
0.72% |
1 |
5.88% |
| Hideaki Yoshifuji / 吉藤英明 |
2 |
0.72% |
1 |
5.88% |
| Greg Kroah-Hartman |
1 |
0.36% |
1 |
5.88% |
| Total |
279 |
|
17 |
|
// SPDX-License-Identifier: GPL-2.0
#include <linux/export.h>
#include <linux/icmpv6.h>
#include <linux/mutex.h>
#include <linux/netdevice.h>
#include <linux/spinlock.h>
#include <net/ipv6.h>
#if IS_ENABLED(CONFIG_IPV6) && IS_ENABLED(CONFIG_NF_NAT)
#include <net/netfilter/nf_conntrack.h>
void icmpv6_ndo_send(struct sk_buff *skb_in, u8 type, u8 code, __u32 info)
{
struct inet6_skb_parm parm = { 0 };
struct sk_buff *cloned_skb = NULL;
enum ip_conntrack_info ctinfo;
enum ip_conntrack_dir dir;
struct in6_addr orig_ip;
struct nf_conn *ct;
ct = nf_ct_get(skb_in, &ctinfo);
if (!ct || !(READ_ONCE(ct->status) & IPS_NAT_MASK)) {
icmp6_send(skb_in, type, code, info, NULL, &parm);
return;
}
if (skb_shared(skb_in))
skb_in = cloned_skb = skb_clone(skb_in, GFP_ATOMIC);
if (unlikely(!skb_in || skb_network_header(skb_in) < skb_in->head ||
(skb_network_header(skb_in) + sizeof(struct ipv6hdr)) >
skb_tail_pointer(skb_in) || skb_ensure_writable(skb_in,
skb_network_offset(skb_in) + sizeof(struct ipv6hdr))))
goto out;
orig_ip = ipv6_hdr(skb_in)->saddr;
dir = CTINFO2DIR(ctinfo);
ipv6_hdr(skb_in)->saddr = ct->tuplehash[dir].tuple.src.u3.in6;
icmp6_send(skb_in, type, code, info, NULL, &parm);
ipv6_hdr(skb_in)->saddr = orig_ip;
out:
consume_skb(cloned_skb);
}
EXPORT_SYMBOL(icmpv6_ndo_send);
#endif