0001
0002 #ifndef _LINUX_ICMPV6_H
0003 #define _LINUX_ICMPV6_H
0004
0005 #include <linux/skbuff.h>
0006 #include <linux/ipv6.h>
0007 #include <uapi/linux/icmpv6.h>
0008
0009 static inline struct icmp6hdr *icmp6_hdr(const struct sk_buff *skb)
0010 {
0011 return (struct icmp6hdr *)skb_transport_header(skb);
0012 }
0013
0014 #include <linux/netdevice.h>
0015
0016 #if IS_ENABLED(CONFIG_IPV6)
0017
0018 typedef void ip6_icmp_send_t(struct sk_buff *skb, u8 type, u8 code, __u32 info,
0019 const struct in6_addr *force_saddr,
0020 const struct inet6_skb_parm *parm);
0021 void icmp6_send(struct sk_buff *skb, u8 type, u8 code, __u32 info,
0022 const struct in6_addr *force_saddr,
0023 const struct inet6_skb_parm *parm);
0024 #if IS_BUILTIN(CONFIG_IPV6)
0025 static inline void __icmpv6_send(struct sk_buff *skb, u8 type, u8 code, __u32 info,
0026 const struct inet6_skb_parm *parm)
0027 {
0028 icmp6_send(skb, type, code, info, NULL, parm);
0029 }
0030 static inline int inet6_register_icmp_sender(ip6_icmp_send_t *fn)
0031 {
0032 BUILD_BUG_ON(fn != icmp6_send);
0033 return 0;
0034 }
0035 static inline int inet6_unregister_icmp_sender(ip6_icmp_send_t *fn)
0036 {
0037 BUILD_BUG_ON(fn != icmp6_send);
0038 return 0;
0039 }
0040 #else
0041 extern void __icmpv6_send(struct sk_buff *skb, u8 type, u8 code, __u32 info,
0042 const struct inet6_skb_parm *parm);
0043 extern int inet6_register_icmp_sender(ip6_icmp_send_t *fn);
0044 extern int inet6_unregister_icmp_sender(ip6_icmp_send_t *fn);
0045 #endif
0046
0047 static inline void icmpv6_send(struct sk_buff *skb, u8 type, u8 code, __u32 info)
0048 {
0049 __icmpv6_send(skb, type, code, info, IP6CB(skb));
0050 }
0051
0052 int ip6_err_gen_icmpv6_unreach(struct sk_buff *skb, int nhs, int type,
0053 unsigned int data_len);
0054
0055 #if IS_ENABLED(CONFIG_NF_NAT)
0056 void icmpv6_ndo_send(struct sk_buff *skb_in, u8 type, u8 code, __u32 info);
0057 #else
0058 static inline void icmpv6_ndo_send(struct sk_buff *skb_in, u8 type, u8 code, __u32 info)
0059 {
0060 struct inet6_skb_parm parm = { 0 };
0061 __icmpv6_send(skb_in, type, code, info, &parm);
0062 }
0063 #endif
0064
0065 #else
0066
0067 static inline void icmpv6_send(struct sk_buff *skb,
0068 u8 type, u8 code, __u32 info)
0069 {
0070 }
0071
0072 static inline void icmpv6_ndo_send(struct sk_buff *skb,
0073 u8 type, u8 code, __u32 info)
0074 {
0075 }
0076 #endif
0077
0078 extern int icmpv6_init(void);
0079 extern int icmpv6_err_convert(u8 type, u8 code,
0080 int *err);
0081 extern void icmpv6_cleanup(void);
0082 extern void icmpv6_param_prob_reason(struct sk_buff *skb,
0083 u8 code, int pos,
0084 enum skb_drop_reason reason);
0085
0086 struct flowi6;
0087 struct in6_addr;
0088 extern void icmpv6_flow_init(struct sock *sk,
0089 struct flowi6 *fl6,
0090 u8 type,
0091 const struct in6_addr *saddr,
0092 const struct in6_addr *daddr,
0093 int oif);
0094
0095 static inline void icmpv6_param_prob(struct sk_buff *skb, u8 code, int pos)
0096 {
0097 icmpv6_param_prob_reason(skb, code, pos,
0098 SKB_DROP_REASON_NOT_SPECIFIED);
0099 }
0100
0101 static inline bool icmpv6_is_err(int type)
0102 {
0103 switch (type) {
0104 case ICMPV6_DEST_UNREACH:
0105 case ICMPV6_PKT_TOOBIG:
0106 case ICMPV6_TIME_EXCEED:
0107 case ICMPV6_PARAMPROB:
0108 return true;
0109 }
0110
0111 return false;
0112 }
0113
0114 #endif