1 /* 2 * IPv6 library code, needed by static components when full IPv6 support is 3 * not configured or static. These functions are needed by GSO/GRO implementation. 4 */ 5 #include <linux/export.h> 6 #include <net/ip.h> 7 #include <net/ipv6.h> 8 #include <net/ip6_fib.h> 9 #include <net/addrconf.h> 10 #include <net/secure_seq.h> 11 12 static u32 __ipv6_select_ident(struct net *net, u32 hashrnd, 13 struct in6_addr *dst, struct in6_addr *src) 14 { 15 u32 hash, id; 16 17 hash = __ipv6_addr_jhash(dst, hashrnd); 18 hash = __ipv6_addr_jhash(src, hash); 19 hash ^= net_hash_mix(net); 20 21 /* Treat id of 0 as unset and if we get 0 back from ip_idents_reserve, 22 * set the hight order instead thus minimizing possible future 23 * collisions. 24 */ 25 id = ip_idents_reserve(hash, 1); 26 if (unlikely(!id)) 27 id = 1 << 31; 28 29 return id; 30 } 31 32 /* This function exists only for tap drivers that must support broken 33 * clients requesting UFO without specifying an IPv6 fragment ID. 34 * 35 * This is similar to ipv6_select_ident() but we use an independent hash 36 * seed to limit information leakage. 37 * 38 * The network header must be set before calling this. 39 */ 40 void ipv6_proxy_select_ident(struct net *net, struct sk_buff *skb) 41 { 42 static u32 ip6_proxy_idents_hashrnd __read_mostly; 43 struct in6_addr buf[2]; 44 struct in6_addr *addrs; 45 u32 id; 46 47 addrs = skb_header_pointer(skb, 48 skb_network_offset(skb) + 49 offsetof(struct ipv6hdr, saddr), 50 sizeof(buf), buf); 51 if (!addrs) 52 return; 53 54 net_get_random_once(&ip6_proxy_idents_hashrnd, 55 sizeof(ip6_proxy_idents_hashrnd)); 56 57 id = __ipv6_select_ident(net, ip6_proxy_idents_hashrnd, 58 &addrs[1], &addrs[0]); 59 skb_shinfo(skb)->ip6_frag_id = htonl(id); 60 } 61 EXPORT_SYMBOL_GPL(ipv6_proxy_select_ident); 62 63 void ipv6_select_ident(struct net *net, struct frag_hdr *fhdr, 64 struct rt6_info *rt) 65 { 66 static u32 ip6_idents_hashrnd __read_mostly; 67 u32 id; 68 69 net_get_random_once(&ip6_idents_hashrnd, sizeof(ip6_idents_hashrnd)); 70 71 id = __ipv6_select_ident(net, ip6_idents_hashrnd, &rt->rt6i_dst.addr, 72 &rt->rt6i_src.addr); 73 fhdr->identification = htonl(id); 74 } 75 EXPORT_SYMBOL(ipv6_select_ident); 76 77 int ip6_find_1stfragopt(struct sk_buff *skb, u8 **nexthdr) 78 { 79 u16 offset = sizeof(struct ipv6hdr); 80 struct ipv6_opt_hdr *exthdr = 81 (struct ipv6_opt_hdr *)(ipv6_hdr(skb) + 1); 82 unsigned int packet_len = skb_tail_pointer(skb) - 83 skb_network_header(skb); 84 int found_rhdr = 0; 85 *nexthdr = &ipv6_hdr(skb)->nexthdr; 86 87 while (offset + 1 <= packet_len) { 88 89 switch (**nexthdr) { 90 91 case NEXTHDR_HOP: 92 break; 93 case NEXTHDR_ROUTING: 94 found_rhdr = 1; 95 break; 96 case NEXTHDR_DEST: 97 #if IS_ENABLED(CONFIG_IPV6_MIP6) 98 if (ipv6_find_tlv(skb, offset, IPV6_TLV_HAO) >= 0) 99 break; 100 #endif 101 if (found_rhdr) 102 return offset; 103 break; 104 default: 105 return offset; 106 } 107 108 offset += ipv6_optlen(exthdr); 109 *nexthdr = &exthdr->nexthdr; 110 exthdr = (struct ipv6_opt_hdr *)(skb_network_header(skb) + 111 offset); 112 } 113 114 return offset; 115 } 116 EXPORT_SYMBOL(ip6_find_1stfragopt); 117 118 #if IS_ENABLED(CONFIG_IPV6) 119 int ip6_dst_hoplimit(struct dst_entry *dst) 120 { 121 int hoplimit = dst_metric_raw(dst, RTAX_HOPLIMIT); 122 if (hoplimit == 0) { 123 struct net_device *dev = dst->dev; 124 struct inet6_dev *idev; 125 126 rcu_read_lock(); 127 idev = __in6_dev_get(dev); 128 if (idev) 129 hoplimit = idev->cnf.hop_limit; 130 else 131 hoplimit = dev_net(dev)->ipv6.devconf_all->hop_limit; 132 rcu_read_unlock(); 133 } 134 return hoplimit; 135 } 136 EXPORT_SYMBOL(ip6_dst_hoplimit); 137 #endif 138 139 static int __ip6_local_out_sk(struct sock *sk, struct sk_buff *skb) 140 { 141 int len; 142 143 len = skb->len - sizeof(struct ipv6hdr); 144 if (len > IPV6_MAXPLEN) 145 len = 0; 146 ipv6_hdr(skb)->payload_len = htons(len); 147 IP6CB(skb)->nhoff = offsetof(struct ipv6hdr, nexthdr); 148 149 return nf_hook(NFPROTO_IPV6, NF_INET_LOCAL_OUT, sk, skb, 150 NULL, skb_dst(skb)->dev, dst_output_sk); 151 } 152 153 int __ip6_local_out(struct sk_buff *skb) 154 { 155 return __ip6_local_out_sk(skb->sk, skb); 156 } 157 EXPORT_SYMBOL_GPL(__ip6_local_out); 158 159 int ip6_local_out_sk(struct sock *sk, struct sk_buff *skb) 160 { 161 int err; 162 163 err = __ip6_local_out_sk(sk, skb); 164 if (likely(err == 1)) 165 err = dst_output_sk(sk, skb); 166 167 return err; 168 } 169 EXPORT_SYMBOL_GPL(ip6_local_out_sk); 170 171 int ip6_local_out(struct sk_buff *skb) 172 { 173 return ip6_local_out_sk(skb->sk, skb); 174 } 175 EXPORT_SYMBOL_GPL(ip6_local_out); 176