Orange Pi5 kernel

Deprecated Linux kernel 5.10.110 for OrangePi 5/5B/5+ boards

3 Commits   0 Branches   0 Tags
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1) // SPDX-License-Identifier: GPL-2.0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2) #include <linux/export.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3) #include <linux/icmpv6.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4) #include <linux/mutex.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5) #include <linux/netdevice.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6) #include <linux/spinlock.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8) #include <net/ipv6.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) #if IS_ENABLED(CONFIG_IPV6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #if !IS_BUILTIN(CONFIG_IPV6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) static ip6_icmp_send_t __rcu *ip6_icmp_send;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) int inet6_register_icmp_sender(ip6_icmp_send_t *fn)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) 	return (cmpxchg((ip6_icmp_send_t **)&ip6_icmp_send, NULL, fn) == NULL) ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) 		0 : -EBUSY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) EXPORT_SYMBOL(inet6_register_icmp_sender);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) int inet6_unregister_icmp_sender(ip6_icmp_send_t *fn)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) 	ret = (cmpxchg((ip6_icmp_send_t **)&ip6_icmp_send, fn, NULL) == fn) ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) 	      0 : -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) 	synchronize_net();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) EXPORT_SYMBOL(inet6_unregister_icmp_sender);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) void __icmpv6_send(struct sk_buff *skb, u8 type, u8 code, __u32 info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) 		   const struct inet6_skb_parm *parm)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) 	ip6_icmp_send_t *send;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) 	rcu_read_lock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) 	send = rcu_dereference(ip6_icmp_send);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) 	if (send)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) 		send(skb, type, code, info, NULL, parm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) 	rcu_read_unlock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) EXPORT_SYMBOL(__icmpv6_send);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) #if IS_ENABLED(CONFIG_NF_NAT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) #include <net/netfilter/nf_conntrack.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) void icmpv6_ndo_send(struct sk_buff *skb_in, u8 type, u8 code, __u32 info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) 	struct inet6_skb_parm parm = { 0 };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) 	struct sk_buff *cloned_skb = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) 	enum ip_conntrack_info ctinfo;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) 	struct in6_addr orig_ip;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) 	struct nf_conn *ct;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) 	ct = nf_ct_get(skb_in, &ctinfo);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) 	if (!ct || !(ct->status & IPS_SRC_NAT)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) 		__icmpv6_send(skb_in, type, code, info, &parm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) 	if (skb_shared(skb_in))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) 		skb_in = cloned_skb = skb_clone(skb_in, GFP_ATOMIC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) 	if (unlikely(!skb_in || skb_network_header(skb_in) < skb_in->head ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) 	    (skb_network_header(skb_in) + sizeof(struct ipv6hdr)) >
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) 	    skb_tail_pointer(skb_in) || skb_ensure_writable(skb_in,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) 	    skb_network_offset(skb_in) + sizeof(struct ipv6hdr))))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) 	orig_ip = ipv6_hdr(skb_in)->saddr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) 	ipv6_hdr(skb_in)->saddr = ct->tuplehash[0].tuple.src.u3.in6;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) 	__icmpv6_send(skb_in, type, code, info, &parm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) 	ipv6_hdr(skb_in)->saddr = orig_ip;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) 	consume_skb(cloned_skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) EXPORT_SYMBOL(icmpv6_ndo_send);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) #endif