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