Mercurial > illumos > illumos-gate
changeset 3291:a0d6d28506cf
6504195 IPv6 doesn't send up self-generated ICMP6_PACKET_TOO_BIG to tunnels.
6504199 tun does a lot of freeb(ipsec_mp) where ipsec_mp is 0xdeadbeef.
author | danmcd |
---|---|
date | Wed, 20 Dec 2006 03:52:51 -0800 |
parents | 256464cbb73c |
children | f1a92dc5bc08 |
files | usr/src/uts/common/inet/ip/ip6.c usr/src/uts/common/inet/ip/tun.c |
diffstat | 2 files changed, 23 insertions(+), 54 deletions(-) [+] |
line wrap: on
line diff
--- a/usr/src/uts/common/inet/ip/ip6.c Tue Dec 19 23:13:06 2006 -0800 +++ b/usr/src/uts/common/inet/ip/ip6.c Wed Dec 20 03:52:51 2006 -0800 @@ -273,7 +273,6 @@ static boolean_t ip_source_routed_v6(ip6_t *, mblk_t *); static void ip_wput_ire_v6(queue_t *, mblk_t *, ire_t *, int, int, conn_t *, int, int, int, zoneid_t); -static boolean_t ip_ulp_cando_pkt2big(int); void ip_rput_v6(queue_t *, mblk_t *); static void ip_wput_v6(queue_t *, mblk_t *); @@ -1113,8 +1112,8 @@ * the IPsec overhead. */ if (ii != NULL) - icmp6->icmp6_mtu = htons( - ntohs(icmp6->icmp6_mtu) - + icmp6->icmp6_mtu = htonl( + ntohl(icmp6->icmp6_mtu) - ipsec_in_extra_length(first_mp)); } else { /* @@ -11437,7 +11436,7 @@ int extra_len = ipsec_out_extra_length(first_mp); if (ntohs(ip6h->ip6_plen) + IPV6_HDR_LEN + extra_len > - max_frag && ip_ulp_cando_pkt2big(nexthdr)) { + max_frag) { /* * IPsec headers will push the packet over the * MTU limit. Issue an ICMPv6 Packet Too Big @@ -12951,23 +12950,6 @@ } /* - * See if the upper-level protocol indicated by 'proto' will be able - * to do something with an ICMP_FRAGMENTATION_NEEDED (IPv4) or - * ICMP6_PACKET_TOO_BIG (IPv6). - */ -static boolean_t -ip_ulp_cando_pkt2big(int proto) -{ - /* - * For now, only TCP can handle this. - * Tunnels may be able to also, but since tun isn't working over - * IPv6 yet, don't worry about it for now. - */ - return (proto == IPPROTO_TCP); -} - - -/* * Propagate a multicast group membership operation (join/leave) (*fn) on * all interfaces crossed by the related multirt routes. * The call is considered successful if the operation succeeds
--- a/usr/src/uts/common/inet/ip/tun.c Tue Dec 19 23:13:06 2006 -0800 +++ b/usr/src/uts/common/inet/ip/tun.c Wed Dec 20 03:52:51 2006 -0800 @@ -3018,6 +3018,7 @@ atomic_add_32(&atp->tun_InErrors, 1); goto drop; } + ipsec_mp = NULL; if (data_mp != orig_mp) { /* mp has changed, reset appropriate pointers */ @@ -3051,6 +3052,7 @@ atomic_add_32(&atp->tun_InErrors, 1); goto drop; } + ipsec_mp = NULL; if (data_mp != orig_mp) { /* mp has changed, reset appropriate pointers */ /* v6src should still be a valid and relevant ptr */ @@ -3147,6 +3149,8 @@ if (!pullupmsg(data_mp, hdrlen + pullup_len)) { atomic_add_32(&atp->tun_InErrors, 1); atomic_add_32(&atp->tun_InDiscard, 1); + if (ipsec_mp != NULL) + freeb(ipsec_mp); goto drop; } iph = (ipha_t *)data_mp->b_rptr; @@ -3162,10 +3166,10 @@ ASSERT(IN6_ARE_ADDR_EQUAL(&v4mapped_dst, &atp->tun_laddr) && IN6_ARE_ADDR_EQUAL(&v4mapped_src, &atp->tun_faddr)); + /* NOTE: ipsec_tun_inbound() always frees ipsec_mp. */ if (!ipsec_tun_inbound(ipsec_mp, &data_mp, atp->tun_itp, inner_iph, NULL, iph, NULL, 0)) { data_mp = NULL; - ipsec_mp = NULL; atomic_add_32(&atp->tun_InErrors, 1); goto drop; } @@ -3195,10 +3199,10 @@ ip6h = (ip6_t *)data_mp->b_rptr; ASSERT(IPH_HDR_VERSION(ip6h) == IPV6_VERSION); + /* NOTE: ipsec_tun_inbound() always frees ipsec_mp. */ if (!ipsec_tun_inbound(ipsec_mp, &data_mp, atp->tun_itp, NULL, ip6h, iph, NULL, 0)) { data_mp = NULL; - ipsec_mp = NULL; atomic_add_32(&atp->tun_InErrors, 1); goto drop; } @@ -3426,8 +3430,6 @@ TUN_PUTMSG_CHAIN_STATS(q, data_mp, nmp, &atp->tun_HCInOctets); return (0); drop: - if (ipsec_mp != NULL) - freeb(ipsec_mp); tun_freemsg_chain(data_mp, NULL); return (0); } @@ -3578,7 +3580,8 @@ * us to receive it. We now have to use inner policy to see if * we want to percolate it up (like conn_t's are checked). * - * Use -outer_hlen to indicate this is an ICMP packet. + * Use -outer_hlen to indicate this is an ICMP packet. And + * ipsec_tun_inbound() always frees ipsec_mp. */ if (!ipsec_tun_inbound(ipsec_mp, &mp, atp->tun_itp, inner_ipha, NULL, outer_ipha, NULL, -outer_hlen)) { @@ -3602,8 +3605,6 @@ tun0dbg(("icmp_ricmp_err_v4_v4: invalid " \ "icmp mtu\n")); atomic_add_32(&atp->tun_InErrors, 1); - if (ipsec_mp != NULL) - freeb(ipsec_mp); freemsg(mp); return; } @@ -3657,8 +3658,6 @@ break; default: atomic_add_32(&atp->tun_InErrors, 1); - if (ipsec_mp != NULL) - freeb(ipsec_mp); freemsg(mp); return; } @@ -3674,8 +3673,6 @@ tun0dbg(("icmp_ricmp_err_v4_v4: ICMP_PARAM_PROBLEM " \ "too short\n")); atomic_add_32(&atp->tun_InErrors, 1); - if (ipsec_mp != NULL) - freeb(ipsec_mp); freemsg(mp); return; } @@ -3685,8 +3682,6 @@ break; default: atomic_add_32(&atp->tun_InErrors, 1); - if (ipsec_mp != NULL) - freeb(ipsec_mp); freemsg(mp); return; } @@ -3740,7 +3735,8 @@ * us to receive it. We now have to use inner policy to see if * we want to percolate it up (like conn_t's are checked). * - * Use -outer_hlen to indicate this is an ICMP packet. + * Use -outer_hlen to indicate this is an ICMP packet. And + * ipsec_tun_inbound() always frees ipsec_mp. */ if (!ipsec_tun_inbound(ipsec_mp, &mp, atp->tun_itp, ipha, NULL, NULL, ip6, -outer_hlen)) @@ -3807,8 +3803,6 @@ } if (found != B_TRUE) { - if (ipsec_mp != NULL) - freeb(ipsec_mp); freemsg(mp); return; } @@ -3832,13 +3826,16 @@ if (ipha->ipha_fragment_offset_and_flags & IPH_DF) { icmp.icmph_type = ICMP_DEST_UNREACHABLE; icmp.icmph_code = ICMP_FRAGMENTATION_NEEDED; - icmp.icmph_du_mtu = htonl(mtu); + /* + * NOTE - htons() because ICMP (for IPv4) uses a + * uint16_t here. + */ + icmp.icmph_du_mtu = htons(mtu); + icmp.icmph_du_zero = 0; } break; } default: - if (ipsec_mp != NULL) - freeb(ipsec_mp); freemsg(mp); return; } @@ -3893,7 +3890,8 @@ * us to receive it. We now have to use inner policy to see if * we want to percolate it up (like conn_t's are checked). * - * Use -outer_hlen to indicate this is an ICMP packet. + * Use -outer_hlen to indicate this is an ICMP packet. And + * ipsec_tun_inbound() always frees ipsec_mp. */ if (!ipsec_tun_inbound(ipsec_mp, &mp, atp->tun_itp, NULL, inner_ip6, NULL, ip6, -outer_hlen)) @@ -3960,8 +3958,6 @@ } if (found != B_TRUE) { - if (ipsec_mp != NULL) - freeb(ipsec_mp); freemsg(mp); return; /* case */ } @@ -3991,8 +3987,6 @@ break; } default: - if (ipsec_mp != NULL) - freeb(ipsec_mp); freemsg(mp); return; } @@ -4103,7 +4097,8 @@ * us to receive it. We now have to use inner policy to see if * we want to percolate it up (like conn_t's are checked). * - * Use -outer_hlen to indicate this is an ICMP packet. + * Use -outer_hlen to indicate this is an ICMP packet. And + * ipsec_tun_inbound() always frees ipsec_mp. */ if (!ipsec_tun_inbound(ipsec_mp, &mp, atp->tun_itp, NULL, ip6h, outer_ipha, NULL, -outer_hlen)) @@ -4126,8 +4121,6 @@ tun0dbg(("icmp_ricmp_err_v6_v4: invalid " \ "icmp mtu\n")); atomic_add_32(&atp->tun_InErrors, 1); - if (ipsec_mp != NULL) - freeb(ipsec_mp); freemsg(mp); return; } @@ -4195,8 +4188,6 @@ break; default: atomic_add_32(&atp->tun_InErrors, 1); - if (ipsec_mp != NULL) - freeb(ipsec_mp); freemsg(mp); return; } @@ -4212,8 +4203,6 @@ tun0dbg(("icmp_ricmp_err_v6_v4: ICMP_PARAM_PROBLEM " \ "too short\n")); atomic_add_32(&atp->tun_InErrors, 1); - if (ipsec_mp != NULL) - freeb(ipsec_mp); freemsg(mp); return; } @@ -4224,8 +4213,6 @@ default: atomic_add_32(&atp->tun_InErrors, 1); - if (ipsec_mp != NULL) - freeb(ipsec_mp); freemsg(mp); return; }