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-or-later
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    3)  *	Extension Header handling for IPv6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    4)  *	Linux INET6 implementation
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    5)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    6)  *	Authors:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    7)  *	Pedro Roque		<roque@di.fc.ul.pt>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    8)  *	Andi Kleen		<ak@muc.de>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    9)  *	Alexey Kuznetsov	<kuznet@ms2.inr.ac.ru>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   10)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   11) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   12) /* Changes:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   13)  *	yoshfuji		: ensure not to overrun while parsing
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   14)  *				  tlv options.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   15)  *	Mitsuru KANDA @USAGI and: Remove ipv6_parse_exthdrs().
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   16)  *	YOSHIFUJI Hideaki @USAGI  Register inbound extension header
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   17)  *				  handlers as inet6_protocol{}.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   18)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   19) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   20) #include <linux/errno.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   21) #include <linux/types.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   22) #include <linux/socket.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   23) #include <linux/sockios.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   24) #include <linux/net.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   25) #include <linux/netdevice.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   26) #include <linux/in6.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   27) #include <linux/icmpv6.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   28) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   29) #include <linux/export.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   30) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   31) #include <net/dst.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   32) #include <net/sock.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   33) #include <net/snmp.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   34) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   35) #include <net/ipv6.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   36) #include <net/protocol.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   37) #include <net/transp_v6.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   38) #include <net/rawv6.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   39) #include <net/ndisc.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   40) #include <net/ip6_route.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   41) #include <net/addrconf.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   42) #include <net/calipso.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   43) #if IS_ENABLED(CONFIG_IPV6_MIP6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   44) #include <net/xfrm.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   45) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   46) #include <linux/seg6.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   47) #include <net/seg6.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   48) #ifdef CONFIG_IPV6_SEG6_HMAC
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   49) #include <net/seg6_hmac.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   50) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   51) #include <net/rpl.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   52) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   53) #include <linux/uaccess.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   54) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   55) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   56)  *	Parsing tlv encoded headers.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   57)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   58)  *	Parsing function "func" returns true, if parsing succeed
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   59)  *	and false, if it failed.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   60)  *	It MUST NOT touch skb->h.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   61)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   62) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   63) struct tlvtype_proc {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   64) 	int	type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   65) 	bool	(*func)(struct sk_buff *skb, int offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   66) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   67) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   68) /*********************
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   69)   Generic functions
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   70)  *********************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   71) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   72) /* An unknown option is detected, decide what to do */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   73) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   74) static bool ip6_tlvopt_unknown(struct sk_buff *skb, int optoff,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   75) 			       bool disallow_unknowns)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   76) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   77) 	if (disallow_unknowns) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   78) 		/* If unknown TLVs are disallowed by configuration
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   79) 		 * then always silently drop packet. Note this also
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   80) 		 * means no ICMP parameter problem is sent which
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   81) 		 * could be a good property to mitigate a reflection DOS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   82) 		 * attack.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   83) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   84) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   85) 		goto drop;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   86) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   87) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   88) 	switch ((skb_network_header(skb)[optoff] & 0xC0) >> 6) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   89) 	case 0: /* ignore */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   90) 		return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   91) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   92) 	case 1: /* drop packet */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   93) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   94) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   95) 	case 3: /* Send ICMP if not a multicast address and drop packet */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   96) 		/* Actually, it is redundant check. icmp_send
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   97) 		   will recheck in any case.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   98) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   99) 		if (ipv6_addr_is_multicast(&ipv6_hdr(skb)->daddr))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  100) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  101) 		fallthrough;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  102) 	case 2: /* send ICMP PARM PROB regardless and drop packet */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  103) 		icmpv6_param_prob(skb, ICMPV6_UNK_OPTION, optoff);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  104) 		return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  105) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  106) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  107) drop:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  108) 	kfree_skb(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  109) 	return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  110) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  111) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  112) /* Parse tlv encoded option header (hop-by-hop or destination) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  113) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  114) static bool ip6_parse_tlv(const struct tlvtype_proc *procs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  115) 			  struct sk_buff *skb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  116) 			  int max_count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  117) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  118) 	int len = (skb_transport_header(skb)[1] + 1) << 3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  119) 	const unsigned char *nh = skb_network_header(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  120) 	int off = skb_network_header_len(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  121) 	const struct tlvtype_proc *curr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  122) 	bool disallow_unknowns = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  123) 	int tlv_count = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  124) 	int padlen = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  125) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  126) 	if (unlikely(max_count < 0)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  127) 		disallow_unknowns = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  128) 		max_count = -max_count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  129) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  130) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  131) 	if (skb_transport_offset(skb) + len > skb_headlen(skb))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  132) 		goto bad;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  133) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  134) 	off += 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  135) 	len -= 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  136) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  137) 	while (len > 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  138) 		int optlen, i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  139) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  140) 		if (nh[off] == IPV6_TLV_PAD1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  141) 			padlen++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  142) 			if (padlen > 7)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  143) 				goto bad;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  144) 			off++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  145) 			len--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  146) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  147) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  148) 		if (len < 2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  149) 			goto bad;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  150) 		optlen = nh[off + 1] + 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  151) 		if (optlen > len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  152) 			goto bad;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  153) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  154) 		if (nh[off] == IPV6_TLV_PADN) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  155) 			/* RFC 2460 states that the purpose of PadN is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  156) 			 * to align the containing header to multiples
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  157) 			 * of 8. 7 is therefore the highest valid value.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  158) 			 * See also RFC 4942, Section 2.1.9.5.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  159) 			 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  160) 			padlen += optlen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  161) 			if (padlen > 7)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  162) 				goto bad;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  163) 			/* RFC 4942 recommends receiving hosts to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  164) 			 * actively check PadN payload to contain
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  165) 			 * only zeroes.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  166) 			 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  167) 			for (i = 2; i < optlen; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  168) 				if (nh[off + i] != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  169) 					goto bad;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  170) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  171) 		} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  172) 			tlv_count++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  173) 			if (tlv_count > max_count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  174) 				goto bad;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  175) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  176) 			for (curr = procs; curr->type >= 0; curr++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  177) 				if (curr->type == nh[off]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  178) 					/* type specific length/alignment
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  179) 					   checks will be performed in the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  180) 					   func(). */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  181) 					if (curr->func(skb, off) == false)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  182) 						return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  183) 					break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  184) 				}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  185) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  186) 			if (curr->type < 0 &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  187) 			    !ip6_tlvopt_unknown(skb, off, disallow_unknowns))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  188) 				return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  189) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  190) 			padlen = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  191) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  192) 		off += optlen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  193) 		len -= optlen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  194) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  195) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  196) 	if (len == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  197) 		return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  198) bad:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  199) 	kfree_skb(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  200) 	return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  201) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  202) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  203) /*****************************
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  204)   Destination options header.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  205)  *****************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  206) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  207) #if IS_ENABLED(CONFIG_IPV6_MIP6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  208) static bool ipv6_dest_hao(struct sk_buff *skb, int optoff)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  209) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  210) 	struct ipv6_destopt_hao *hao;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  211) 	struct inet6_skb_parm *opt = IP6CB(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  212) 	struct ipv6hdr *ipv6h = ipv6_hdr(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  213) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  214) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  215) 	if (opt->dsthao) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  216) 		net_dbg_ratelimited("hao duplicated\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  217) 		goto discard;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  218) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  219) 	opt->dsthao = opt->dst1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  220) 	opt->dst1 = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  221) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  222) 	hao = (struct ipv6_destopt_hao *)(skb_network_header(skb) + optoff);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  223) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  224) 	if (hao->length != 16) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  225) 		net_dbg_ratelimited("hao invalid option length = %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  226) 				    hao->length);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  227) 		goto discard;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  228) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  229) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  230) 	if (!(ipv6_addr_type(&hao->addr) & IPV6_ADDR_UNICAST)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  231) 		net_dbg_ratelimited("hao is not an unicast addr: %pI6\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  232) 				    &hao->addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  233) 		goto discard;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  234) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  235) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  236) 	ret = xfrm6_input_addr(skb, (xfrm_address_t *)&ipv6h->daddr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  237) 			       (xfrm_address_t *)&hao->addr, IPPROTO_DSTOPTS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  238) 	if (unlikely(ret < 0))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  239) 		goto discard;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  240) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  241) 	if (skb_cloned(skb)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  242) 		if (pskb_expand_head(skb, 0, 0, GFP_ATOMIC))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  243) 			goto discard;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  244) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  245) 		/* update all variable using below by copied skbuff */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  246) 		hao = (struct ipv6_destopt_hao *)(skb_network_header(skb) +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  247) 						  optoff);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  248) 		ipv6h = ipv6_hdr(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  249) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  250) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  251) 	if (skb->ip_summed == CHECKSUM_COMPLETE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  252) 		skb->ip_summed = CHECKSUM_NONE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  253) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  254) 	swap(ipv6h->saddr, hao->addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  255) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  256) 	if (skb->tstamp == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  257) 		__net_timestamp(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  258) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  259) 	return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  260) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  261)  discard:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  262) 	kfree_skb(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  263) 	return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  264) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  265) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  266) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  267) static const struct tlvtype_proc tlvprocdestopt_lst[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  268) #if IS_ENABLED(CONFIG_IPV6_MIP6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  269) 	{
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  270) 		.type	= IPV6_TLV_HAO,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  271) 		.func	= ipv6_dest_hao,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  272) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  273) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  274) 	{-1,			NULL}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  275) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  276) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  277) static int ipv6_destopt_rcv(struct sk_buff *skb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  278) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  279) 	struct inet6_dev *idev = __in6_dev_get(skb->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  280) 	struct inet6_skb_parm *opt = IP6CB(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  281) #if IS_ENABLED(CONFIG_IPV6_MIP6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  282) 	__u16 dstbuf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  283) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  284) 	struct dst_entry *dst = skb_dst(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  285) 	struct net *net = dev_net(skb->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  286) 	int extlen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  287) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  288) 	if (!pskb_may_pull(skb, skb_transport_offset(skb) + 8) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  289) 	    !pskb_may_pull(skb, (skb_transport_offset(skb) +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  290) 				 ((skb_transport_header(skb)[1] + 1) << 3)))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  291) 		__IP6_INC_STATS(dev_net(dst->dev), idev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  292) 				IPSTATS_MIB_INHDRERRORS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  293) fail_and_free:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  294) 		kfree_skb(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  295) 		return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  296) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  297) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  298) 	extlen = (skb_transport_header(skb)[1] + 1) << 3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  299) 	if (extlen > net->ipv6.sysctl.max_dst_opts_len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  300) 		goto fail_and_free;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  301) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  302) 	opt->lastopt = opt->dst1 = skb_network_header_len(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  303) #if IS_ENABLED(CONFIG_IPV6_MIP6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  304) 	dstbuf = opt->dst1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  305) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  306) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  307) 	if (ip6_parse_tlv(tlvprocdestopt_lst, skb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  308) 			  net->ipv6.sysctl.max_dst_opts_cnt)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  309) 		skb->transport_header += extlen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  310) 		opt = IP6CB(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  311) #if IS_ENABLED(CONFIG_IPV6_MIP6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  312) 		opt->nhoff = dstbuf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  313) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  314) 		opt->nhoff = opt->dst1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  315) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  316) 		return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  317) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  318) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  319) 	__IP6_INC_STATS(net, idev, IPSTATS_MIB_INHDRERRORS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  320) 	return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  321) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  322) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  323) static void seg6_update_csum(struct sk_buff *skb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  324) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  325) 	struct ipv6_sr_hdr *hdr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  326) 	struct in6_addr *addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  327) 	__be32 from, to;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  328) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  329) 	/* srh is at transport offset and seg_left is already decremented
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  330) 	 * but daddr is not yet updated with next segment
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  331) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  332) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  333) 	hdr = (struct ipv6_sr_hdr *)skb_transport_header(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  334) 	addr = hdr->segments + hdr->segments_left;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  335) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  336) 	hdr->segments_left++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  337) 	from = *(__be32 *)hdr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  338) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  339) 	hdr->segments_left--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  340) 	to = *(__be32 *)hdr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  341) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  342) 	/* update skb csum with diff resulting from seg_left decrement */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  343) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  344) 	update_csum_diff4(skb, from, to);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  345) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  346) 	/* compute csum diff between current and next segment and update */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  347) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  348) 	update_csum_diff16(skb, (__be32 *)(&ipv6_hdr(skb)->daddr),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  349) 			   (__be32 *)addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  350) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  351) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  352) static int ipv6_srh_rcv(struct sk_buff *skb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  353) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  354) 	struct inet6_skb_parm *opt = IP6CB(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  355) 	struct net *net = dev_net(skb->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  356) 	struct ipv6_sr_hdr *hdr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  357) 	struct inet6_dev *idev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  358) 	struct in6_addr *addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  359) 	int accept_seg6;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  360) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  361) 	hdr = (struct ipv6_sr_hdr *)skb_transport_header(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  362) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  363) 	idev = __in6_dev_get(skb->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  364) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  365) 	accept_seg6 = net->ipv6.devconf_all->seg6_enabled;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  366) 	if (accept_seg6 > idev->cnf.seg6_enabled)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  367) 		accept_seg6 = idev->cnf.seg6_enabled;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  368) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  369) 	if (!accept_seg6) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  370) 		kfree_skb(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  371) 		return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  372) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  373) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  374) #ifdef CONFIG_IPV6_SEG6_HMAC
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  375) 	if (!seg6_hmac_validate_skb(skb)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  376) 		kfree_skb(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  377) 		return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  378) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  379) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  380) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  381) looped_back:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  382) 	if (hdr->segments_left == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  383) 		if (hdr->nexthdr == NEXTHDR_IPV6) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  384) 			int offset = (hdr->hdrlen + 1) << 3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  385) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  386) 			skb_postpull_rcsum(skb, skb_network_header(skb),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  387) 					   skb_network_header_len(skb));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  388) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  389) 			if (!pskb_pull(skb, offset)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  390) 				kfree_skb(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  391) 				return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  392) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  393) 			skb_postpull_rcsum(skb, skb_transport_header(skb),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  394) 					   offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  395) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  396) 			skb_reset_network_header(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  397) 			skb_reset_transport_header(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  398) 			skb->encapsulation = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  399) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  400) 			__skb_tunnel_rx(skb, skb->dev, net);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  401) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  402) 			netif_rx(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  403) 			return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  404) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  405) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  406) 		opt->srcrt = skb_network_header_len(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  407) 		opt->lastopt = opt->srcrt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  408) 		skb->transport_header += (hdr->hdrlen + 1) << 3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  409) 		opt->nhoff = (&hdr->nexthdr) - skb_network_header(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  410) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  411) 		return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  412) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  413) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  414) 	if (hdr->segments_left >= (hdr->hdrlen >> 1)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  415) 		__IP6_INC_STATS(net, idev, IPSTATS_MIB_INHDRERRORS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  416) 		icmpv6_param_prob(skb, ICMPV6_HDR_FIELD,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  417) 				  ((&hdr->segments_left) -
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  418) 				   skb_network_header(skb)));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  419) 		return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  420) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  421) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  422) 	if (skb_cloned(skb)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  423) 		if (pskb_expand_head(skb, 0, 0, GFP_ATOMIC)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  424) 			__IP6_INC_STATS(net, ip6_dst_idev(skb_dst(skb)),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  425) 					IPSTATS_MIB_OUTDISCARDS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  426) 			kfree_skb(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  427) 			return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  428) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  429) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  430) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  431) 	hdr = (struct ipv6_sr_hdr *)skb_transport_header(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  432) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  433) 	hdr->segments_left--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  434) 	addr = hdr->segments + hdr->segments_left;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  435) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  436) 	skb_push(skb, sizeof(struct ipv6hdr));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  437) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  438) 	if (skb->ip_summed == CHECKSUM_COMPLETE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  439) 		seg6_update_csum(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  440) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  441) 	ipv6_hdr(skb)->daddr = *addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  442) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  443) 	skb_dst_drop(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  444) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  445) 	ip6_route_input(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  446) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  447) 	if (skb_dst(skb)->error) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  448) 		dst_input(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  449) 		return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  450) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  451) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  452) 	if (skb_dst(skb)->dev->flags & IFF_LOOPBACK) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  453) 		if (ipv6_hdr(skb)->hop_limit <= 1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  454) 			__IP6_INC_STATS(net, idev, IPSTATS_MIB_INHDRERRORS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  455) 			icmpv6_send(skb, ICMPV6_TIME_EXCEED,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  456) 				    ICMPV6_EXC_HOPLIMIT, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  457) 			kfree_skb(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  458) 			return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  459) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  460) 		ipv6_hdr(skb)->hop_limit--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  461) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  462) 		skb_pull(skb, sizeof(struct ipv6hdr));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  463) 		goto looped_back;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  464) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  465) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  466) 	dst_input(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  467) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  468) 	return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  469) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  470) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  471) static int ipv6_rpl_srh_rcv(struct sk_buff *skb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  472) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  473) 	struct ipv6_rpl_sr_hdr *hdr, *ohdr, *chdr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  474) 	struct inet6_skb_parm *opt = IP6CB(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  475) 	struct net *net = dev_net(skb->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  476) 	struct inet6_dev *idev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  477) 	struct ipv6hdr *oldhdr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  478) 	struct in6_addr addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  479) 	unsigned char *buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  480) 	int accept_rpl_seg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  481) 	int i, err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  482) 	u64 n = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  483) 	u32 r;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  484) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  485) 	idev = __in6_dev_get(skb->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  486) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  487) 	accept_rpl_seg = net->ipv6.devconf_all->rpl_seg_enabled;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  488) 	if (accept_rpl_seg > idev->cnf.rpl_seg_enabled)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  489) 		accept_rpl_seg = idev->cnf.rpl_seg_enabled;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  490) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  491) 	if (!accept_rpl_seg) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  492) 		kfree_skb(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  493) 		return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  494) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  495) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  496) looped_back:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  497) 	hdr = (struct ipv6_rpl_sr_hdr *)skb_transport_header(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  498) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  499) 	if (hdr->segments_left == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  500) 		if (hdr->nexthdr == NEXTHDR_IPV6) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  501) 			int offset = (hdr->hdrlen + 1) << 3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  502) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  503) 			skb_postpull_rcsum(skb, skb_network_header(skb),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  504) 					   skb_network_header_len(skb));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  505) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  506) 			if (!pskb_pull(skb, offset)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  507) 				kfree_skb(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  508) 				return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  509) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  510) 			skb_postpull_rcsum(skb, skb_transport_header(skb),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  511) 					   offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  512) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  513) 			skb_reset_network_header(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  514) 			skb_reset_transport_header(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  515) 			skb->encapsulation = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  516) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  517) 			__skb_tunnel_rx(skb, skb->dev, net);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  518) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  519) 			netif_rx(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  520) 			return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  521) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  522) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  523) 		opt->srcrt = skb_network_header_len(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  524) 		opt->lastopt = opt->srcrt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  525) 		skb->transport_header += (hdr->hdrlen + 1) << 3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  526) 		opt->nhoff = (&hdr->nexthdr) - skb_network_header(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  527) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  528) 		return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  529) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  530) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  531) 	if (!pskb_may_pull(skb, sizeof(*hdr))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  532) 		kfree_skb(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  533) 		return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  534) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  535) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  536) 	n = (hdr->hdrlen << 3) - hdr->pad - (16 - hdr->cmpre);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  537) 	r = do_div(n, (16 - hdr->cmpri));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  538) 	/* checks if calculation was without remainder and n fits into
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  539) 	 * unsigned char which is segments_left field. Should not be
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  540) 	 * higher than that.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  541) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  542) 	if (r || (n + 1) > 255) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  543) 		kfree_skb(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  544) 		return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  545) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  546) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  547) 	if (hdr->segments_left > n + 1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  548) 		__IP6_INC_STATS(net, idev, IPSTATS_MIB_INHDRERRORS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  549) 		icmpv6_param_prob(skb, ICMPV6_HDR_FIELD,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  550) 				  ((&hdr->segments_left) -
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  551) 				   skb_network_header(skb)));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  552) 		return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  553) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  554) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  555) 	if (skb_cloned(skb)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  556) 		if (pskb_expand_head(skb, IPV6_RPL_SRH_WORST_SWAP_SIZE, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  557) 				     GFP_ATOMIC)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  558) 			__IP6_INC_STATS(net, ip6_dst_idev(skb_dst(skb)),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  559) 					IPSTATS_MIB_OUTDISCARDS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  560) 			kfree_skb(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  561) 			return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  562) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  563) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  564) 		err = skb_cow_head(skb, IPV6_RPL_SRH_WORST_SWAP_SIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  565) 		if (unlikely(err)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  566) 			kfree_skb(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  567) 			return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  568) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  569) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  570) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  571) 	hdr = (struct ipv6_rpl_sr_hdr *)skb_transport_header(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  572) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  573) 	if (!pskb_may_pull(skb, ipv6_rpl_srh_size(n, hdr->cmpri,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  574) 						  hdr->cmpre))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  575) 		kfree_skb(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  576) 		return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  577) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  578) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  579) 	hdr->segments_left--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  580) 	i = n - hdr->segments_left;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  581) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  582) 	buf = kcalloc(struct_size(hdr, segments.addr, n + 2), 2, GFP_ATOMIC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  583) 	if (unlikely(!buf)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  584) 		kfree_skb(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  585) 		return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  586) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  587) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  588) 	ohdr = (struct ipv6_rpl_sr_hdr *)buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  589) 	ipv6_rpl_srh_decompress(ohdr, hdr, &ipv6_hdr(skb)->daddr, n);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  590) 	chdr = (struct ipv6_rpl_sr_hdr *)(buf + ((ohdr->hdrlen + 1) << 3));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  591) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  592) 	if ((ipv6_addr_type(&ipv6_hdr(skb)->daddr) & IPV6_ADDR_MULTICAST) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  593) 	    (ipv6_addr_type(&ohdr->rpl_segaddr[i]) & IPV6_ADDR_MULTICAST)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  594) 		kfree_skb(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  595) 		kfree(buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  596) 		return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  597) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  598) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  599) 	err = ipv6_chk_rpl_srh_loop(net, ohdr->rpl_segaddr, n + 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  600) 	if (err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  601) 		icmpv6_send(skb, ICMPV6_PARAMPROB, 0, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  602) 		kfree_skb(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  603) 		kfree(buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  604) 		return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  605) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  606) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  607) 	addr = ipv6_hdr(skb)->daddr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  608) 	ipv6_hdr(skb)->daddr = ohdr->rpl_segaddr[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  609) 	ohdr->rpl_segaddr[i] = addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  610) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  611) 	ipv6_rpl_srh_compress(chdr, ohdr, &ipv6_hdr(skb)->daddr, n);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  612) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  613) 	oldhdr = ipv6_hdr(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  614) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  615) 	skb_pull(skb, ((hdr->hdrlen + 1) << 3));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  616) 	skb_postpull_rcsum(skb, oldhdr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  617) 			   sizeof(struct ipv6hdr) + ((hdr->hdrlen + 1) << 3));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  618) 	skb_push(skb, ((chdr->hdrlen + 1) << 3) + sizeof(struct ipv6hdr));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  619) 	skb_reset_network_header(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  620) 	skb_mac_header_rebuild(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  621) 	skb_set_transport_header(skb, sizeof(struct ipv6hdr));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  622) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  623) 	memmove(ipv6_hdr(skb), oldhdr, sizeof(struct ipv6hdr));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  624) 	memcpy(skb_transport_header(skb), chdr, (chdr->hdrlen + 1) << 3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  625) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  626) 	ipv6_hdr(skb)->payload_len = htons(skb->len - sizeof(struct ipv6hdr));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  627) 	skb_postpush_rcsum(skb, ipv6_hdr(skb),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  628) 			   sizeof(struct ipv6hdr) + ((chdr->hdrlen + 1) << 3));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  629) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  630) 	kfree(buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  631) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  632) 	skb_dst_drop(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  633) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  634) 	ip6_route_input(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  635) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  636) 	if (skb_dst(skb)->error) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  637) 		dst_input(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  638) 		return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  639) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  640) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  641) 	if (skb_dst(skb)->dev->flags & IFF_LOOPBACK) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  642) 		if (ipv6_hdr(skb)->hop_limit <= 1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  643) 			__IP6_INC_STATS(net, idev, IPSTATS_MIB_INHDRERRORS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  644) 			icmpv6_send(skb, ICMPV6_TIME_EXCEED,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  645) 				    ICMPV6_EXC_HOPLIMIT, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  646) 			kfree_skb(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  647) 			return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  648) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  649) 		ipv6_hdr(skb)->hop_limit--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  650) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  651) 		skb_pull(skb, sizeof(struct ipv6hdr));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  652) 		goto looped_back;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  653) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  654) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  655) 	dst_input(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  656) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  657) 	return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  658) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  659) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  660) /********************************
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  661)   Routing header.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  662)  ********************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  663) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  664) /* called with rcu_read_lock() */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  665) static int ipv6_rthdr_rcv(struct sk_buff *skb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  666) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  667) 	struct inet6_dev *idev = __in6_dev_get(skb->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  668) 	struct inet6_skb_parm *opt = IP6CB(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  669) 	struct in6_addr *addr = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  670) 	struct in6_addr daddr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  671) 	int n, i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  672) 	struct ipv6_rt_hdr *hdr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  673) 	struct rt0_hdr *rthdr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  674) 	struct net *net = dev_net(skb->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  675) 	int accept_source_route = net->ipv6.devconf_all->accept_source_route;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  676) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  677) 	idev = __in6_dev_get(skb->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  678) 	if (idev && accept_source_route > idev->cnf.accept_source_route)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  679) 		accept_source_route = idev->cnf.accept_source_route;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  680) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  681) 	if (!pskb_may_pull(skb, skb_transport_offset(skb) + 8) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  682) 	    !pskb_may_pull(skb, (skb_transport_offset(skb) +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  683) 				 ((skb_transport_header(skb)[1] + 1) << 3)))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  684) 		__IP6_INC_STATS(net, idev, IPSTATS_MIB_INHDRERRORS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  685) 		kfree_skb(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  686) 		return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  687) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  688) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  689) 	hdr = (struct ipv6_rt_hdr *)skb_transport_header(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  690) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  691) 	if (ipv6_addr_is_multicast(&ipv6_hdr(skb)->daddr) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  692) 	    skb->pkt_type != PACKET_HOST) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  693) 		__IP6_INC_STATS(net, idev, IPSTATS_MIB_INADDRERRORS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  694) 		kfree_skb(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  695) 		return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  696) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  697) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  698) 	switch (hdr->type) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  699) 	case IPV6_SRCRT_TYPE_4:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  700) 		/* segment routing */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  701) 		return ipv6_srh_rcv(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  702) 	case IPV6_SRCRT_TYPE_3:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  703) 		/* rpl segment routing */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  704) 		return ipv6_rpl_srh_rcv(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  705) 	default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  706) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  707) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  708) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  709) looped_back:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  710) 	if (hdr->segments_left == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  711) 		switch (hdr->type) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  712) #if IS_ENABLED(CONFIG_IPV6_MIP6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  713) 		case IPV6_SRCRT_TYPE_2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  714) 			/* Silently discard type 2 header unless it was
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  715) 			 * processed by own
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  716) 			 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  717) 			if (!addr) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  718) 				__IP6_INC_STATS(net, idev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  719) 						IPSTATS_MIB_INADDRERRORS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  720) 				kfree_skb(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  721) 				return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  722) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  723) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  724) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  725) 		default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  726) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  727) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  728) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  729) 		opt->lastopt = opt->srcrt = skb_network_header_len(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  730) 		skb->transport_header += (hdr->hdrlen + 1) << 3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  731) 		opt->dst0 = opt->dst1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  732) 		opt->dst1 = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  733) 		opt->nhoff = (&hdr->nexthdr) - skb_network_header(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  734) 		return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  735) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  736) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  737) 	switch (hdr->type) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  738) #if IS_ENABLED(CONFIG_IPV6_MIP6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  739) 	case IPV6_SRCRT_TYPE_2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  740) 		if (accept_source_route < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  741) 			goto unknown_rh;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  742) 		/* Silently discard invalid RTH type 2 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  743) 		if (hdr->hdrlen != 2 || hdr->segments_left != 1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  744) 			__IP6_INC_STATS(net, idev, IPSTATS_MIB_INHDRERRORS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  745) 			kfree_skb(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  746) 			return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  747) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  748) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  749) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  750) 	default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  751) 		goto unknown_rh;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  752) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  753) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  754) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  755) 	 *	This is the routing header forwarding algorithm from
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  756) 	 *	RFC 2460, page 16.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  757) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  758) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  759) 	n = hdr->hdrlen >> 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  760) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  761) 	if (hdr->segments_left > n) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  762) 		__IP6_INC_STATS(net, idev, IPSTATS_MIB_INHDRERRORS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  763) 		icmpv6_param_prob(skb, ICMPV6_HDR_FIELD,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  764) 				  ((&hdr->segments_left) -
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  765) 				   skb_network_header(skb)));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  766) 		return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  767) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  768) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  769) 	/* We are about to mangle packet header. Be careful!
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  770) 	   Do not damage packets queued somewhere.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  771) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  772) 	if (skb_cloned(skb)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  773) 		/* the copy is a forwarded packet */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  774) 		if (pskb_expand_head(skb, 0, 0, GFP_ATOMIC)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  775) 			__IP6_INC_STATS(net, ip6_dst_idev(skb_dst(skb)),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  776) 					IPSTATS_MIB_OUTDISCARDS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  777) 			kfree_skb(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  778) 			return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  779) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  780) 		hdr = (struct ipv6_rt_hdr *)skb_transport_header(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  781) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  782) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  783) 	if (skb->ip_summed == CHECKSUM_COMPLETE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  784) 		skb->ip_summed = CHECKSUM_NONE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  785) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  786) 	i = n - --hdr->segments_left;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  787) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  788) 	rthdr = (struct rt0_hdr *) hdr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  789) 	addr = rthdr->addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  790) 	addr += i - 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  791) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  792) 	switch (hdr->type) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  793) #if IS_ENABLED(CONFIG_IPV6_MIP6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  794) 	case IPV6_SRCRT_TYPE_2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  795) 		if (xfrm6_input_addr(skb, (xfrm_address_t *)addr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  796) 				     (xfrm_address_t *)&ipv6_hdr(skb)->saddr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  797) 				     IPPROTO_ROUTING) < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  798) 			__IP6_INC_STATS(net, idev, IPSTATS_MIB_INADDRERRORS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  799) 			kfree_skb(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  800) 			return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  801) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  802) 		if (!ipv6_chk_home_addr(dev_net(skb_dst(skb)->dev), addr)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  803) 			__IP6_INC_STATS(net, idev, IPSTATS_MIB_INADDRERRORS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  804) 			kfree_skb(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  805) 			return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  806) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  807) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  808) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  809) 	default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  810) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  811) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  812) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  813) 	if (ipv6_addr_is_multicast(addr)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  814) 		__IP6_INC_STATS(net, idev, IPSTATS_MIB_INADDRERRORS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  815) 		kfree_skb(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  816) 		return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  817) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  818) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  819) 	daddr = *addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  820) 	*addr = ipv6_hdr(skb)->daddr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  821) 	ipv6_hdr(skb)->daddr = daddr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  822) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  823) 	skb_dst_drop(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  824) 	ip6_route_input(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  825) 	if (skb_dst(skb)->error) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  826) 		skb_push(skb, skb->data - skb_network_header(skb));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  827) 		dst_input(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  828) 		return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  829) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  830) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  831) 	if (skb_dst(skb)->dev->flags&IFF_LOOPBACK) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  832) 		if (ipv6_hdr(skb)->hop_limit <= 1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  833) 			__IP6_INC_STATS(net, idev, IPSTATS_MIB_INHDRERRORS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  834) 			icmpv6_send(skb, ICMPV6_TIME_EXCEED, ICMPV6_EXC_HOPLIMIT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  835) 				    0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  836) 			kfree_skb(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  837) 			return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  838) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  839) 		ipv6_hdr(skb)->hop_limit--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  840) 		goto looped_back;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  841) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  842) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  843) 	skb_push(skb, skb->data - skb_network_header(skb));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  844) 	dst_input(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  845) 	return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  846) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  847) unknown_rh:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  848) 	__IP6_INC_STATS(net, idev, IPSTATS_MIB_INHDRERRORS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  849) 	icmpv6_param_prob(skb, ICMPV6_HDR_FIELD,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  850) 			  (&hdr->type) - skb_network_header(skb));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  851) 	return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  852) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  853) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  854) static const struct inet6_protocol rthdr_protocol = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  855) 	.handler	=	ipv6_rthdr_rcv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  856) 	.flags		=	INET6_PROTO_NOPOLICY,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  857) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  858) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  859) static const struct inet6_protocol destopt_protocol = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  860) 	.handler	=	ipv6_destopt_rcv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  861) 	.flags		=	INET6_PROTO_NOPOLICY,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  862) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  863) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  864) static const struct inet6_protocol nodata_protocol = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  865) 	.handler	=	dst_discard,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  866) 	.flags		=	INET6_PROTO_NOPOLICY,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  867) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  868) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  869) int __init ipv6_exthdrs_init(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  870) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  871) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  872) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  873) 	ret = inet6_add_protocol(&rthdr_protocol, IPPROTO_ROUTING);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  874) 	if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  875) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  876) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  877) 	ret = inet6_add_protocol(&destopt_protocol, IPPROTO_DSTOPTS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  878) 	if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  879) 		goto out_rthdr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  880) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  881) 	ret = inet6_add_protocol(&nodata_protocol, IPPROTO_NONE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  882) 	if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  883) 		goto out_destopt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  884) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  885) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  886) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  887) out_destopt:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  888) 	inet6_del_protocol(&destopt_protocol, IPPROTO_DSTOPTS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  889) out_rthdr:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  890) 	inet6_del_protocol(&rthdr_protocol, IPPROTO_ROUTING);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  891) 	goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  892) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  893) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  894) void ipv6_exthdrs_exit(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  895) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  896) 	inet6_del_protocol(&nodata_protocol, IPPROTO_NONE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  897) 	inet6_del_protocol(&destopt_protocol, IPPROTO_DSTOPTS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  898) 	inet6_del_protocol(&rthdr_protocol, IPPROTO_ROUTING);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  899) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  900) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  901) /**********************************
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  902)   Hop-by-hop options.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  903)  **********************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  904) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  905) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  906)  * Note: we cannot rely on skb_dst(skb) before we assign it in ip6_route_input().
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  907)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  908) static inline struct inet6_dev *ipv6_skb_idev(struct sk_buff *skb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  909) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  910) 	return skb_dst(skb) ? ip6_dst_idev(skb_dst(skb)) : __in6_dev_get(skb->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  911) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  912) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  913) static inline struct net *ipv6_skb_net(struct sk_buff *skb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  914) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  915) 	return skb_dst(skb) ? dev_net(skb_dst(skb)->dev) : dev_net(skb->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  916) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  917) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  918) /* Router Alert as of RFC 2711 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  919) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  920) static bool ipv6_hop_ra(struct sk_buff *skb, int optoff)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  921) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  922) 	const unsigned char *nh = skb_network_header(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  923) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  924) 	if (nh[optoff + 1] == 2) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  925) 		IP6CB(skb)->flags |= IP6SKB_ROUTERALERT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  926) 		memcpy(&IP6CB(skb)->ra, nh + optoff + 2, sizeof(IP6CB(skb)->ra));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  927) 		return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  928) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  929) 	net_dbg_ratelimited("ipv6_hop_ra: wrong RA length %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  930) 			    nh[optoff + 1]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  931) 	kfree_skb(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  932) 	return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  933) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  934) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  935) /* Jumbo payload */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  936) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  937) static bool ipv6_hop_jumbo(struct sk_buff *skb, int optoff)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  938) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  939) 	const unsigned char *nh = skb_network_header(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  940) 	struct inet6_dev *idev = __in6_dev_get_safely(skb->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  941) 	struct net *net = ipv6_skb_net(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  942) 	u32 pkt_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  943) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  944) 	if (nh[optoff + 1] != 4 || (optoff & 3) != 2) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  945) 		net_dbg_ratelimited("ipv6_hop_jumbo: wrong jumbo opt length/alignment %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  946) 				    nh[optoff+1]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  947) 		__IP6_INC_STATS(net, idev, IPSTATS_MIB_INHDRERRORS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  948) 		goto drop;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  949) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  950) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  951) 	pkt_len = ntohl(*(__be32 *)(nh + optoff + 2));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  952) 	if (pkt_len <= IPV6_MAXPLEN) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  953) 		__IP6_INC_STATS(net, idev, IPSTATS_MIB_INHDRERRORS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  954) 		icmpv6_param_prob(skb, ICMPV6_HDR_FIELD, optoff+2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  955) 		return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  956) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  957) 	if (ipv6_hdr(skb)->payload_len) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  958) 		__IP6_INC_STATS(net, idev, IPSTATS_MIB_INHDRERRORS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  959) 		icmpv6_param_prob(skb, ICMPV6_HDR_FIELD, optoff);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  960) 		return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  961) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  962) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  963) 	if (pkt_len > skb->len - sizeof(struct ipv6hdr)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  964) 		__IP6_INC_STATS(net, idev, IPSTATS_MIB_INTRUNCATEDPKTS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  965) 		goto drop;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  966) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  967) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  968) 	if (pskb_trim_rcsum(skb, pkt_len + sizeof(struct ipv6hdr)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  969) 		goto drop;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  970) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  971) 	IP6CB(skb)->flags |= IP6SKB_JUMBOGRAM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  972) 	return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  973) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  974) drop:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  975) 	kfree_skb(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  976) 	return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  977) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  978) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  979) /* CALIPSO RFC 5570 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  980) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  981) static bool ipv6_hop_calipso(struct sk_buff *skb, int optoff)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  982) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  983) 	const unsigned char *nh = skb_network_header(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  984) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  985) 	if (nh[optoff + 1] < 8)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  986) 		goto drop;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  987) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  988) 	if (nh[optoff + 6] * 4 + 8 > nh[optoff + 1])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  989) 		goto drop;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  990) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  991) 	if (!calipso_validate(skb, nh + optoff))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  992) 		goto drop;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  993) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  994) 	return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  995) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  996) drop:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  997) 	kfree_skb(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  998) 	return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  999) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1000) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1001) static const struct tlvtype_proc tlvprochopopt_lst[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1002) 	{
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1003) 		.type	= IPV6_TLV_ROUTERALERT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1004) 		.func	= ipv6_hop_ra,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1005) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1006) 	{
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1007) 		.type	= IPV6_TLV_JUMBO,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1008) 		.func	= ipv6_hop_jumbo,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1009) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1010) 	{
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1011) 		.type	= IPV6_TLV_CALIPSO,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1012) 		.func	= ipv6_hop_calipso,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1013) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1014) 	{ -1, }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1015) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1016) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1017) int ipv6_parse_hopopts(struct sk_buff *skb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1018) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1019) 	struct inet6_skb_parm *opt = IP6CB(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1020) 	struct net *net = dev_net(skb->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1021) 	int extlen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1022) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1023) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1024) 	 * skb_network_header(skb) is equal to skb->data, and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1025) 	 * skb_network_header_len(skb) is always equal to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1026) 	 * sizeof(struct ipv6hdr) by definition of
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1027) 	 * hop-by-hop options.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1028) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1029) 	if (!pskb_may_pull(skb, sizeof(struct ipv6hdr) + 8) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1030) 	    !pskb_may_pull(skb, (sizeof(struct ipv6hdr) +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1031) 				 ((skb_transport_header(skb)[1] + 1) << 3)))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1032) fail_and_free:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1033) 		kfree_skb(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1034) 		return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1035) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1036) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1037) 	extlen = (skb_transport_header(skb)[1] + 1) << 3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1038) 	if (extlen > net->ipv6.sysctl.max_hbh_opts_len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1039) 		goto fail_and_free;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1040) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1041) 	opt->flags |= IP6SKB_HOPBYHOP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1042) 	if (ip6_parse_tlv(tlvprochopopt_lst, skb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1043) 			  net->ipv6.sysctl.max_hbh_opts_cnt)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1044) 		skb->transport_header += extlen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1045) 		opt = IP6CB(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1046) 		opt->nhoff = sizeof(struct ipv6hdr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1047) 		return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1048) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1049) 	return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1050) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1051) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1052) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1053)  *	Creating outbound headers.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1054)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1055)  *	"build" functions work when skb is filled from head to tail (datagram)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1056)  *	"push"	functions work when headers are added from tail to head (tcp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1057)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1058)  *	In both cases we assume, that caller reserved enough room
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1059)  *	for headers.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1060)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1061) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1062) static void ipv6_push_rthdr0(struct sk_buff *skb, u8 *proto,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1063) 			     struct ipv6_rt_hdr *opt,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1064) 			     struct in6_addr **addr_p, struct in6_addr *saddr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1065) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1066) 	struct rt0_hdr *phdr, *ihdr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1067) 	int hops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1068) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1069) 	ihdr = (struct rt0_hdr *) opt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1070) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1071) 	phdr = skb_push(skb, (ihdr->rt_hdr.hdrlen + 1) << 3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1072) 	memcpy(phdr, ihdr, sizeof(struct rt0_hdr));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1073) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1074) 	hops = ihdr->rt_hdr.hdrlen >> 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1075) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1076) 	if (hops > 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1077) 		memcpy(phdr->addr, ihdr->addr + 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1078) 		       (hops - 1) * sizeof(struct in6_addr));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1079) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1080) 	phdr->addr[hops - 1] = **addr_p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1081) 	*addr_p = ihdr->addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1082) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1083) 	phdr->rt_hdr.nexthdr = *proto;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1084) 	*proto = NEXTHDR_ROUTING;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1085) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1086) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1087) static void ipv6_push_rthdr4(struct sk_buff *skb, u8 *proto,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1088) 			     struct ipv6_rt_hdr *opt,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1089) 			     struct in6_addr **addr_p, struct in6_addr *saddr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1090) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1091) 	struct ipv6_sr_hdr *sr_phdr, *sr_ihdr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1092) 	int plen, hops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1093) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1094) 	sr_ihdr = (struct ipv6_sr_hdr *)opt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1095) 	plen = (sr_ihdr->hdrlen + 1) << 3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1096) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1097) 	sr_phdr = skb_push(skb, plen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1098) 	memcpy(sr_phdr, sr_ihdr, sizeof(struct ipv6_sr_hdr));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1099) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1100) 	hops = sr_ihdr->first_segment + 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1101) 	memcpy(sr_phdr->segments + 1, sr_ihdr->segments + 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1102) 	       (hops - 1) * sizeof(struct in6_addr));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1103) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1104) 	sr_phdr->segments[0] = **addr_p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1105) 	*addr_p = &sr_ihdr->segments[sr_ihdr->segments_left];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1106) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1107) 	if (sr_ihdr->hdrlen > hops * 2) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1108) 		int tlvs_offset, tlvs_length;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1109) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1110) 		tlvs_offset = (1 + hops * 2) << 3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1111) 		tlvs_length = (sr_ihdr->hdrlen - hops * 2) << 3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1112) 		memcpy((char *)sr_phdr + tlvs_offset,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1113) 		       (char *)sr_ihdr + tlvs_offset, tlvs_length);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1114) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1115) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1116) #ifdef CONFIG_IPV6_SEG6_HMAC
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1117) 	if (sr_has_hmac(sr_phdr)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1118) 		struct net *net = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1119) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1120) 		if (skb->dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1121) 			net = dev_net(skb->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1122) 		else if (skb->sk)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1123) 			net = sock_net(skb->sk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1124) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1125) 		WARN_ON(!net);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1126) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1127) 		if (net)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1128) 			seg6_push_hmac(net, saddr, sr_phdr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1129) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1130) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1131) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1132) 	sr_phdr->nexthdr = *proto;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1133) 	*proto = NEXTHDR_ROUTING;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1134) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1135) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1136) static void ipv6_push_rthdr(struct sk_buff *skb, u8 *proto,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1137) 			    struct ipv6_rt_hdr *opt,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1138) 			    struct in6_addr **addr_p, struct in6_addr *saddr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1139) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1140) 	switch (opt->type) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1141) 	case IPV6_SRCRT_TYPE_0:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1142) 	case IPV6_SRCRT_STRICT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1143) 	case IPV6_SRCRT_TYPE_2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1144) 		ipv6_push_rthdr0(skb, proto, opt, addr_p, saddr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1145) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1146) 	case IPV6_SRCRT_TYPE_4:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1147) 		ipv6_push_rthdr4(skb, proto, opt, addr_p, saddr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1148) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1149) 	default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1150) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1151) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1152) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1153) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1154) static void ipv6_push_exthdr(struct sk_buff *skb, u8 *proto, u8 type, struct ipv6_opt_hdr *opt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1155) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1156) 	struct ipv6_opt_hdr *h = skb_push(skb, ipv6_optlen(opt));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1157) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1158) 	memcpy(h, opt, ipv6_optlen(opt));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1159) 	h->nexthdr = *proto;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1160) 	*proto = type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1161) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1162) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1163) void ipv6_push_nfrag_opts(struct sk_buff *skb, struct ipv6_txoptions *opt,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1164) 			  u8 *proto,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1165) 			  struct in6_addr **daddr, struct in6_addr *saddr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1166) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1167) 	if (opt->srcrt) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1168) 		ipv6_push_rthdr(skb, proto, opt->srcrt, daddr, saddr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1169) 		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1170) 		 * IPV6_RTHDRDSTOPTS is ignored
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1171) 		 * unless IPV6_RTHDR is set (RFC3542).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1172) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1173) 		if (opt->dst0opt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1174) 			ipv6_push_exthdr(skb, proto, NEXTHDR_DEST, opt->dst0opt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1175) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1176) 	if (opt->hopopt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1177) 		ipv6_push_exthdr(skb, proto, NEXTHDR_HOP, opt->hopopt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1178) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1179) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1180) void ipv6_push_frag_opts(struct sk_buff *skb, struct ipv6_txoptions *opt, u8 *proto)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1181) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1182) 	if (opt->dst1opt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1183) 		ipv6_push_exthdr(skb, proto, NEXTHDR_DEST, opt->dst1opt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1184) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1185) EXPORT_SYMBOL(ipv6_push_frag_opts);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1186) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1187) struct ipv6_txoptions *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1188) ipv6_dup_options(struct sock *sk, struct ipv6_txoptions *opt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1189) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1190) 	struct ipv6_txoptions *opt2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1191) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1192) 	opt2 = sock_kmalloc(sk, opt->tot_len, GFP_ATOMIC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1193) 	if (opt2) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1194) 		long dif = (char *)opt2 - (char *)opt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1195) 		memcpy(opt2, opt, opt->tot_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1196) 		if (opt2->hopopt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1197) 			*((char **)&opt2->hopopt) += dif;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1198) 		if (opt2->dst0opt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1199) 			*((char **)&opt2->dst0opt) += dif;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1200) 		if (opt2->dst1opt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1201) 			*((char **)&opt2->dst1opt) += dif;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1202) 		if (opt2->srcrt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1203) 			*((char **)&opt2->srcrt) += dif;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1204) 		refcount_set(&opt2->refcnt, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1205) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1206) 	return opt2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1207) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1208) EXPORT_SYMBOL_GPL(ipv6_dup_options);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1209) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1210) static void ipv6_renew_option(int renewtype,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1211) 			      struct ipv6_opt_hdr **dest,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1212) 			      struct ipv6_opt_hdr *old,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1213) 			      struct ipv6_opt_hdr *new,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1214) 			      int newtype, char **p)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1215) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1216) 	struct ipv6_opt_hdr *src;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1217) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1218) 	src = (renewtype == newtype ? new : old);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1219) 	if (!src)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1220) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1221) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1222) 	memcpy(*p, src, ipv6_optlen(src));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1223) 	*dest = (struct ipv6_opt_hdr *)*p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1224) 	*p += CMSG_ALIGN(ipv6_optlen(*dest));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1225) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1226) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1227) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1228)  * ipv6_renew_options - replace a specific ext hdr with a new one.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1229)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1230)  * @sk: sock from which to allocate memory
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1231)  * @opt: original options
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1232)  * @newtype: option type to replace in @opt
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1233)  * @newopt: new option of type @newtype to replace (user-mem)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1234)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1235)  * Returns a new set of options which is a copy of @opt with the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1236)  * option type @newtype replaced with @newopt.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1237)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1238)  * @opt may be NULL, in which case a new set of options is returned
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1239)  * containing just @newopt.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1240)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1241)  * @newopt may be NULL, in which case the specified option type is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1242)  * not copied into the new set of options.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1243)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1244)  * The new set of options is allocated from the socket option memory
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1245)  * buffer of @sk.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1246)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1247) struct ipv6_txoptions *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1248) ipv6_renew_options(struct sock *sk, struct ipv6_txoptions *opt,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1249) 		   int newtype, struct ipv6_opt_hdr *newopt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1250) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1251) 	int tot_len = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1252) 	char *p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1253) 	struct ipv6_txoptions *opt2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1254) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1255) 	if (opt) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1256) 		if (newtype != IPV6_HOPOPTS && opt->hopopt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1257) 			tot_len += CMSG_ALIGN(ipv6_optlen(opt->hopopt));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1258) 		if (newtype != IPV6_RTHDRDSTOPTS && opt->dst0opt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1259) 			tot_len += CMSG_ALIGN(ipv6_optlen(opt->dst0opt));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1260) 		if (newtype != IPV6_RTHDR && opt->srcrt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1261) 			tot_len += CMSG_ALIGN(ipv6_optlen(opt->srcrt));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1262) 		if (newtype != IPV6_DSTOPTS && opt->dst1opt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1263) 			tot_len += CMSG_ALIGN(ipv6_optlen(opt->dst1opt));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1264) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1265) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1266) 	if (newopt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1267) 		tot_len += CMSG_ALIGN(ipv6_optlen(newopt));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1268) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1269) 	if (!tot_len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1270) 		return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1271) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1272) 	tot_len += sizeof(*opt2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1273) 	opt2 = sock_kmalloc(sk, tot_len, GFP_ATOMIC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1274) 	if (!opt2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1275) 		return ERR_PTR(-ENOBUFS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1276) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1277) 	memset(opt2, 0, tot_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1278) 	refcount_set(&opt2->refcnt, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1279) 	opt2->tot_len = tot_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1280) 	p = (char *)(opt2 + 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1281) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1282) 	ipv6_renew_option(IPV6_HOPOPTS, &opt2->hopopt,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1283) 			  (opt ? opt->hopopt : NULL),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1284) 			  newopt, newtype, &p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1285) 	ipv6_renew_option(IPV6_RTHDRDSTOPTS, &opt2->dst0opt,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1286) 			  (opt ? opt->dst0opt : NULL),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1287) 			  newopt, newtype, &p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1288) 	ipv6_renew_option(IPV6_RTHDR,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1289) 			  (struct ipv6_opt_hdr **)&opt2->srcrt,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1290) 			  (opt ? (struct ipv6_opt_hdr *)opt->srcrt : NULL),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1291) 			  newopt, newtype, &p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1292) 	ipv6_renew_option(IPV6_DSTOPTS, &opt2->dst1opt,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1293) 			  (opt ? opt->dst1opt : NULL),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1294) 			  newopt, newtype, &p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1295) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1296) 	opt2->opt_nflen = (opt2->hopopt ? ipv6_optlen(opt2->hopopt) : 0) +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1297) 			  (opt2->dst0opt ? ipv6_optlen(opt2->dst0opt) : 0) +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1298) 			  (opt2->srcrt ? ipv6_optlen(opt2->srcrt) : 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1299) 	opt2->opt_flen = (opt2->dst1opt ? ipv6_optlen(opt2->dst1opt) : 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1300) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1301) 	return opt2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1302) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1303) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1304) struct ipv6_txoptions *ipv6_fixup_options(struct ipv6_txoptions *opt_space,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1305) 					  struct ipv6_txoptions *opt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1306) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1307) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1308) 	 * ignore the dest before srcrt unless srcrt is being included.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1309) 	 * --yoshfuji
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1310) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1311) 	if (opt && opt->dst0opt && !opt->srcrt) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1312) 		if (opt_space != opt) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1313) 			memcpy(opt_space, opt, sizeof(*opt_space));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1314) 			opt = opt_space;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1315) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1316) 		opt->opt_nflen -= ipv6_optlen(opt->dst0opt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1317) 		opt->dst0opt = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1318) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1319) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1320) 	return opt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1321) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1322) EXPORT_SYMBOL_GPL(ipv6_fixup_options);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1323) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1324) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1325)  * fl6_update_dst - update flowi destination address with info given
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1326)  *                  by srcrt option, if any.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1327)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1328)  * @fl6: flowi6 for which daddr is to be updated
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1329)  * @opt: struct ipv6_txoptions in which to look for srcrt opt
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1330)  * @orig: copy of original daddr address if modified
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1331)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1332)  * Returns NULL if no txoptions or no srcrt, otherwise returns orig
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1333)  * and initial value of fl6->daddr set in orig
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1334)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1335) struct in6_addr *fl6_update_dst(struct flowi6 *fl6,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1336) 				const struct ipv6_txoptions *opt,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1337) 				struct in6_addr *orig)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1338) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1339) 	if (!opt || !opt->srcrt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1340) 		return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1341) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1342) 	*orig = fl6->daddr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1343) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1344) 	switch (opt->srcrt->type) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1345) 	case IPV6_SRCRT_TYPE_0:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1346) 	case IPV6_SRCRT_STRICT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1347) 	case IPV6_SRCRT_TYPE_2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1348) 		fl6->daddr = *((struct rt0_hdr *)opt->srcrt)->addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1349) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1350) 	case IPV6_SRCRT_TYPE_4:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1351) 	{
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1352) 		struct ipv6_sr_hdr *srh = (struct ipv6_sr_hdr *)opt->srcrt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1353) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1354) 		fl6->daddr = srh->segments[srh->segments_left];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1355) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1356) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1357) 	default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1358) 		return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1359) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1360) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1361) 	return orig;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1362) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1363) EXPORT_SYMBOL_GPL(fl6_update_dst);