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