Orange Pi5 kernel

Deprecated Linux kernel 5.10.110 for OrangePi 5/5B/5+ boards

3 Commits   0 Branches   0 Tags
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   1) // SPDX-License-Identifier: GPL-2.0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   2) #include <net/ip.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   3) #include <net/udp.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   4) #include <net/udplite.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   5) #include <asm/checksum.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   6) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   7) #ifndef _HAVE_ARCH_IPV6_CSUM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   8) __sum16 csum_ipv6_magic(const struct in6_addr *saddr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   9) 			const struct in6_addr *daddr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  10) 			__u32 len, __u8 proto, __wsum csum)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  11) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  12) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  13) 	int carry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  14) 	__u32 ulen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  15) 	__u32 uproto;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  16) 	__u32 sum = (__force u32)csum;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  17) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  18) 	sum += (__force u32)saddr->s6_addr32[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  19) 	carry = (sum < (__force u32)saddr->s6_addr32[0]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  20) 	sum += carry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  21) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  22) 	sum += (__force u32)saddr->s6_addr32[1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  23) 	carry = (sum < (__force u32)saddr->s6_addr32[1]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  24) 	sum += carry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  25) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  26) 	sum += (__force u32)saddr->s6_addr32[2];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  27) 	carry = (sum < (__force u32)saddr->s6_addr32[2]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  28) 	sum += carry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  29) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  30) 	sum += (__force u32)saddr->s6_addr32[3];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  31) 	carry = (sum < (__force u32)saddr->s6_addr32[3]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  32) 	sum += carry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  33) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  34) 	sum += (__force u32)daddr->s6_addr32[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  35) 	carry = (sum < (__force u32)daddr->s6_addr32[0]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  36) 	sum += carry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  37) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  38) 	sum += (__force u32)daddr->s6_addr32[1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  39) 	carry = (sum < (__force u32)daddr->s6_addr32[1]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  40) 	sum += carry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  41) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  42) 	sum += (__force u32)daddr->s6_addr32[2];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  43) 	carry = (sum < (__force u32)daddr->s6_addr32[2]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  44) 	sum += carry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  45) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  46) 	sum += (__force u32)daddr->s6_addr32[3];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  47) 	carry = (sum < (__force u32)daddr->s6_addr32[3]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  48) 	sum += carry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  49) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  50) 	ulen = (__force u32)htonl((__u32) len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  51) 	sum += ulen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  52) 	carry = (sum < ulen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  53) 	sum += carry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  54) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  55) 	uproto = (__force u32)htonl(proto);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  56) 	sum += uproto;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  57) 	carry = (sum < uproto);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  58) 	sum += carry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  59) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  60) 	return csum_fold((__force __wsum)sum);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  61) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  62) EXPORT_SYMBOL(csum_ipv6_magic);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  63) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  64) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  65) int udp6_csum_init(struct sk_buff *skb, struct udphdr *uh, int proto)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  66) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  67) 	int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  68) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  69) 	UDP_SKB_CB(skb)->partial_cov = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  70) 	UDP_SKB_CB(skb)->cscov = skb->len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  71) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  72) 	if (proto == IPPROTO_UDPLITE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  73) 		err = udplite_checksum_init(skb, uh);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  74) 		if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  75) 			return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  76) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  77) 		if (UDP_SKB_CB(skb)->partial_cov) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  78) 			skb->csum = ip6_compute_pseudo(skb, proto);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  79) 			return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  80) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  81) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  82) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  83) 	/* To support RFC 6936 (allow zero checksum in UDP/IPV6 for tunnels)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  84) 	 * we accept a checksum of zero here. When we find the socket
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  85) 	 * for the UDP packet we'll check if that socket allows zero checksum
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  86) 	 * for IPv6 (set by socket option).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  87) 	 *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  88) 	 * Note, we are only interested in != 0 or == 0, thus the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  89) 	 * force to int.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  90) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  91) 	err = (__force int)skb_checksum_init_zero_check(skb, proto, uh->check,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  92) 							ip6_compute_pseudo);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  93) 	if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  94) 		return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  95) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  96) 	if (skb->ip_summed == CHECKSUM_COMPLETE && !skb->csum_valid) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  97) 		/* If SW calculated the value, we know it's bad */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  98) 		if (skb->csum_complete_sw)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  99) 			return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) 		/* HW says the value is bad. Let's validate that.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) 		 * skb->csum is no longer the full packet checksum,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) 		 * so don't treat is as such.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) 		skb_checksum_complete_unset(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) EXPORT_SYMBOL(udp6_csum_init);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) /* Function to set UDP checksum for an IPv6 UDP packet. This is intended
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113)  * for the simple case like when setting the checksum for a UDP tunnel.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) void udp6_set_csum(bool nocheck, struct sk_buff *skb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) 		   const struct in6_addr *saddr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) 		   const struct in6_addr *daddr, int len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) 	struct udphdr *uh = udp_hdr(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) 	if (nocheck)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) 		uh->check = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) 	else if (skb_is_gso(skb))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) 		uh->check = ~udp_v6_check(len, saddr, daddr, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) 	else if (skb->ip_summed == CHECKSUM_PARTIAL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) 		uh->check = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) 		uh->check = udp_v6_check(len, saddr, daddr, lco_csum(skb));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) 		if (uh->check == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) 			uh->check = CSUM_MANGLED_0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) 		skb->ip_summed = CHECKSUM_PARTIAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) 		skb->csum_start = skb_transport_header(skb) - skb->head;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) 		skb->csum_offset = offsetof(struct udphdr, check);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) 		uh->check = ~udp_v6_check(len, saddr, daddr, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) EXPORT_SYMBOL(udp6_set_csum);