123456789101112131415161718192021222324252627282930313233343536373839404142434445464748 |
- #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)
- static ip6_icmp_send_t __rcu *ip6_icmp_send;
- int inet6_register_icmp_sender(ip6_icmp_send_t *fn)
- {
- return (cmpxchg((ip6_icmp_send_t **)&ip6_icmp_send, NULL, fn) == NULL) ?
- 0 : -EBUSY;
- }
- EXPORT_SYMBOL(inet6_register_icmp_sender);
- int inet6_unregister_icmp_sender(ip6_icmp_send_t *fn)
- {
- int ret;
- ret = (cmpxchg((ip6_icmp_send_t **)&ip6_icmp_send, fn, NULL) == fn) ?
- 0 : -EINVAL;
- synchronize_net();
- return ret;
- }
- EXPORT_SYMBOL(inet6_unregister_icmp_sender);
- void icmpv6_send(struct sk_buff *skb, u8 type, u8 code, __u32 info)
- {
- ip6_icmp_send_t *send;
- rcu_read_lock();
- send = rcu_dereference(ip6_icmp_send);
- if (!send)
- goto out;
- send(skb, type, code, info);
- out:
- rcu_read_unlock();
- }
- EXPORT_SYMBOL(icmpv6_send);
- #endif
|