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-only
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   2) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   3)  * Authors:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   4)  * (C) 2020 Alexander Aring <alex.aring@gmail.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   5)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   6) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   7) #include <net/ipv6.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   8) #include <net/rpl.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   9) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  10) #define IPV6_PFXTAIL_LEN(x) (sizeof(struct in6_addr) - (x))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  11) #define IPV6_RPL_BEST_ADDR_COMPRESSION 15
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  12) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  13) static void ipv6_rpl_addr_decompress(struct in6_addr *dst,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  14) 				     const struct in6_addr *daddr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  15) 				     const void *post, unsigned char pfx)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  16) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  17) 	memcpy(dst, daddr, pfx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  18) 	memcpy(&dst->s6_addr[pfx], post, IPV6_PFXTAIL_LEN(pfx));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  19) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  20) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  21) static void ipv6_rpl_addr_compress(void *dst, const struct in6_addr *addr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  22) 				   unsigned char pfx)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  23) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  24) 	memcpy(dst, &addr->s6_addr[pfx], IPV6_PFXTAIL_LEN(pfx));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  25) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  26) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  27) static void *ipv6_rpl_segdata_pos(const struct ipv6_rpl_sr_hdr *hdr, int i)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  28) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  29) 	return (void *)&hdr->rpl_segdata[i * IPV6_PFXTAIL_LEN(hdr->cmpri)];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  30) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  31) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  32) size_t ipv6_rpl_srh_size(unsigned char n, unsigned char cmpri,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  33) 			 unsigned char cmpre)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  34) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  35) 	return (n * IPV6_PFXTAIL_LEN(cmpri)) + IPV6_PFXTAIL_LEN(cmpre);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  36) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  37) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  38) void ipv6_rpl_srh_decompress(struct ipv6_rpl_sr_hdr *outhdr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  39) 			     const struct ipv6_rpl_sr_hdr *inhdr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  40) 			     const struct in6_addr *daddr, unsigned char n)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  41) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  42) 	int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  43) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  44) 	outhdr->nexthdr = inhdr->nexthdr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  45) 	outhdr->hdrlen = (((n + 1) * sizeof(struct in6_addr)) >> 3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  46) 	outhdr->pad = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  47) 	outhdr->type = inhdr->type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  48) 	outhdr->segments_left = inhdr->segments_left;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  49) 	outhdr->cmpri = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  50) 	outhdr->cmpre = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  51) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  52) 	for (i = 0; i < n; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  53) 		ipv6_rpl_addr_decompress(&outhdr->rpl_segaddr[i], daddr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  54) 					 ipv6_rpl_segdata_pos(inhdr, i),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  55) 					 inhdr->cmpri);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  56) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  57) 	ipv6_rpl_addr_decompress(&outhdr->rpl_segaddr[n], daddr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  58) 				 ipv6_rpl_segdata_pos(inhdr, n),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  59) 				 inhdr->cmpre);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  60) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  61) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  62) static unsigned char ipv6_rpl_srh_calc_cmpri(const struct ipv6_rpl_sr_hdr *inhdr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  63) 					     const struct in6_addr *daddr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  64) 					     unsigned char n)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  65) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  66) 	unsigned char plen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  67) 	int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  68) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  69) 	for (plen = 0; plen < sizeof(*daddr); plen++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  70) 		for (i = 0; i < n; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  71) 			if (daddr->s6_addr[plen] !=
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  72) 			    inhdr->rpl_segaddr[i].s6_addr[plen])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  73) 				return plen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  74) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  75) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  76) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  77) 	return IPV6_RPL_BEST_ADDR_COMPRESSION;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  78) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  79) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  80) static unsigned char ipv6_rpl_srh_calc_cmpre(const struct in6_addr *daddr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  81) 					     const struct in6_addr *last_segment)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  82) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  83) 	unsigned int plen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  84) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  85) 	for (plen = 0; plen < sizeof(*daddr); plen++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  86) 		if (daddr->s6_addr[plen] != last_segment->s6_addr[plen])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  87) 			return plen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  88) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  89) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  90) 	return IPV6_RPL_BEST_ADDR_COMPRESSION;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  91) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  92) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  93) void ipv6_rpl_srh_compress(struct ipv6_rpl_sr_hdr *outhdr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  94) 			   const struct ipv6_rpl_sr_hdr *inhdr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  95) 			   const struct in6_addr *daddr, unsigned char n)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  96) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  97) 	unsigned char cmpri, cmpre;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  98) 	size_t seglen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  99) 	int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) 	cmpri = ipv6_rpl_srh_calc_cmpri(inhdr, daddr, n);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) 	cmpre = ipv6_rpl_srh_calc_cmpre(daddr, &inhdr->rpl_segaddr[n]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) 	outhdr->nexthdr = inhdr->nexthdr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) 	seglen = (n * IPV6_PFXTAIL_LEN(cmpri)) + IPV6_PFXTAIL_LEN(cmpre);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) 	outhdr->hdrlen = seglen >> 3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) 	if (seglen & 0x7) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) 		outhdr->hdrlen++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) 		outhdr->pad = 8 - (seglen & 0x7);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) 		outhdr->pad = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) 	outhdr->type = inhdr->type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) 	outhdr->segments_left = inhdr->segments_left;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) 	outhdr->cmpri = cmpri;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) 	outhdr->cmpre = cmpre;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) 	for (i = 0; i < n; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) 		ipv6_rpl_addr_compress(ipv6_rpl_segdata_pos(outhdr, i),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) 				       &inhdr->rpl_segaddr[i], cmpri);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) 	ipv6_rpl_addr_compress(ipv6_rpl_segdata_pos(outhdr, n),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) 			       &inhdr->rpl_segaddr[n], cmpre);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) }