cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

ip6_icmp.c (2086B)


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