Print this page
Don't create DCE for bad MTU.

Split Close
Expand all
Collapse all
          --- old/usr/src/uts/common/inet/ip/ip6.c
          +++ new/usr/src/uts/common/inet/ip/ip6.c
↓ open down ↓ 675 lines elided ↑ open up ↑
 676  676          ill_t           *ill = ira->ira_ill;    /* Upper ill if IPMP */
 677  677          ip_stack_t      *ipst = ill->ill_ipst;
 678  678          int             old_max_frag;
 679  679          in6_addr_t      final_dst;
 680  680          ip6_t           *ip6h;  /* Inner IP header */
 681  681  
 682  682          /* Caller has already pulled up everything. */
 683  683          ip6h = (ip6_t *)&icmp6[1];
 684  684          final_dst = ip_get_dst_v6(ip6h, NULL, NULL);
 685  685  
      686 +        mtu = ntohl(icmp6->icmp6_mtu);
      687 +        if (mtu < IPV6_MIN_MTU) {
      688 +                /*
      689 +                 * RFC 8021 suggests to ignore messages where mtu is
      690 +                 * less than the IPv6 minimum.
      691 +                 */
      692 +                ip1dbg(("Received mtu less than IPv6 "
      693 +                    "min mtu %d: %d\n", IPV6_MIN_MTU, mtu));
      694 +                DTRACE_PROBE1(icmp6__too__small__mtu, uint32_t, mtu);
      695 +                return;
      696 +        }
      697 +
 686  698          /*
 687  699           * For link local destinations matching simply on address is not
 688  700           * sufficient. Same link local addresses for different ILL's is
 689  701           * possible.
 690  702           */
 691  703          if (IN6_IS_ADDR_LINKSCOPE(&final_dst)) {
 692  704                  dce = dce_lookup_and_add_v6(&final_dst,
 693  705                      ill->ill_phyint->phyint_ifindex, ipst);
 694  706          } else {
 695  707                  dce = dce_lookup_and_add_v6(&final_dst, 0, ipst);
↓ open down ↓ 2 lines elided ↑ open up ↑
 698  710                  /* Couldn't add a unique one - ENOMEM */
 699  711                  if (ip_debug > 2) {
 700  712                          /* ip1dbg */
 701  713                          pr_addr_dbg("icmp_inbound_too_big_v6:"
 702  714                              "no dce for dst %s\n", AF_INET6,
 703  715                              &final_dst);
 704  716                  }
 705  717                  return;
 706  718          }
 707  719  
 708      -        mtu = ntohl(icmp6->icmp6_mtu);
 709      -
 710  720          mutex_enter(&dce->dce_lock);
 711  721          if (dce->dce_flags & DCEF_PMTU)
 712  722                  old_max_frag = dce->dce_pmtu;
 713  723          else if (IN6_IS_ADDR_MULTICAST(&final_dst))
 714  724                  old_max_frag = ill->ill_mc_mtu;
 715  725          else
 716  726                  old_max_frag = ill->ill_mtu;
 717  727  
 718      -        if (mtu >= IPV6_MIN_MTU) {
 719      -                ip1dbg(("Received mtu from router: %d\n", mtu));
 720      -                DTRACE_PROBE1(icmp6__received__mtu, uint32_t, mtu);
 721      -                dce->dce_pmtu = MIN(old_max_frag, mtu);
 722      -                icmp6->icmp6_mtu = htonl(dce->dce_pmtu);
      728 +        ip1dbg(("Received mtu from router: %d\n", mtu));
      729 +        DTRACE_PROBE1(icmp6__received__mtu, uint32_t, mtu);
      730 +        dce->dce_pmtu = MIN(old_max_frag, mtu);
      731 +        icmp6->icmp6_mtu = htonl(dce->dce_pmtu);
 723  732  
 724      -                /* We now have a PMTU for sure */
 725      -                dce->dce_flags |= DCEF_PMTU;
 726      -                dce->dce_last_change_time = TICK_TO_SEC(ddi_get_lbolt64());
 727      -        } else {
 728      -                /*
 729      -                 * RFC 8021 suggests to ignore messages where mtu is
 730      -                 * less than the IPv6 minimum.
 731      -                 */
 732      -                ip1dbg(("Received mtu less than IPv6 "
 733      -                    "min mtu %d: %d\n", IPV6_MIN_MTU, mtu));
 734      -                DTRACE_PROBE1(icmp6__too__small__mtu, uint32_t, mtu);
 735      -        }
      733 +        /* We now have a PMTU for sure */
      734 +        dce->dce_flags |= DCEF_PMTU;
      735 +        dce->dce_last_change_time = TICK_TO_SEC(ddi_get_lbolt64());
 736  736  
 737  737          mutex_exit(&dce->dce_lock);
 738  738          /*
 739  739           * After dropping the lock the new value is visible to everyone.
 740  740           * Then we bump the generation number so any cached values reinspect
 741  741           * the dce_t.
 742  742           */
 743  743          dce_increment_generation(dce);
 744  744          dce_refrele(dce);
 745  745  }
↓ open down ↓ 4294 lines elided ↑ open up ↑
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX