Back to home page

OSCL-LXR

 
 

    


0001 /* SPDX-License-Identifier: GPL-2.0 */
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