cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

exthdrs.c (33616B)


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