changeset 6048:fe40e7ead0fb

6452869 ipv6 MAC awareness is missing some basics, i.e. raw ipv6 mac awareness is non-existant 6478442 ip_wput_ire passed ALL_ZONES has bad assertions with an ipsec outbound policy 6578843 IPv6 tunnels subtract the encapsulation limit options from the effective mtu twice after CR#6535669 6629370 tunnels apparently get mac_exempt in Tx when they should not -- missing CIPSO labels. 6640590 TX: CIPSO and AH don't play well together
author wy83408
date Wed, 20 Feb 2008 12:21:06 -0800
parents 235fee4665e7
children 5569229e1d94
files usr/src/uts/common/inet/ip/ip.c usr/src/uts/common/inet/ip/ip6.c usr/src/uts/common/inet/ip/ipsecah.c usr/src/uts/common/inet/ip/tn_ipopt.c usr/src/uts/common/inet/ip/tun.c
diffstat 5 files changed, 66 insertions(+), 41 deletions(-) [+]
line wrap: on
line diff
--- a/usr/src/uts/common/inet/ip/ip.c	Wed Feb 20 11:04:28 2008 -0800
+++ b/usr/src/uts/common/inet/ip/ip.c	Wed Feb 20 12:21:06 2008 -0800
@@ -20691,10 +20691,11 @@
 	/*
 	 * Make sure we have a full-word aligned message and that at least
 	 * a simple IP header is accessible in the first message.  If not,
-	 * try a pullup.
+	 * try a pullup.  For labeled systems we need to always take this
+	 * path as M_CTLs are "notdata" but have trailing data to process.
 	 */
 	if (!OK_32PTR(rptr) ||
-	    (mp->b_wptr - rptr) < IP_SIMPLE_HDR_LENGTH) {
+	    (mp->b_wptr - rptr) < IP_SIMPLE_HDR_LENGTH || is_system_labeled()) {
 hdrtoosmall:
 		if (!pullupmsg(mp, IP_SIMPLE_HDR_LENGTH)) {
 			TRACE_2(TR_FAC_IP, TR_IP_WPUT_END,
@@ -22184,6 +22185,16 @@
 				ill_refrele(conn_outgoing_ill);
 			return;
 		}
+		/*
+		 * Trusted Extensions supports all-zones interfaces, so
+		 * zoneid == ALL_ZONES is valid, but IPsec maps ALL_ZONES to
+		 * the global zone.
+		 */
+		if (zoneid == ALL_ZONES && mp->b_datap->db_type == M_CTL) {
+			io = (ipsec_out_t *)mp->b_rptr;
+			ASSERT(io->ipsec_out_type == IPSEC_OUT);
+			zoneid = io->ipsec_out_zoneid;
+		}
 	}
 
 	first_mp = mp;
--- a/usr/src/uts/common/inet/ip/ip6.c	Wed Feb 20 11:04:28 2008 -0800
+++ b/usr/src/uts/common/inet/ip/ip6.c	Wed Feb 20 12:21:06 2008 -0800
@@ -1623,7 +1623,7 @@
 		}
 		msg_len = len_needed;
 	}
-	mp1 = allocb(IPV6_HDR_LEN + len, BPRI_HI);
+	mp1 = allocb_cred(IPV6_HDR_LEN + len, DB_CRED(mp));
 	if (mp1 == NULL) {
 		BUMP_MIB(ill->ill_icmp6_mib, ipv6IfIcmpOutErrors);
 		freemsg(ipsec_mp);
@@ -9164,13 +9164,14 @@
 	boolean_t	drop_if_delayed = B_FALSE;
 	boolean_t	multirt_need_resolve = B_FALSE;
 	mblk_t		*copy_mp = NULL;
-	int		err;
+	int		err = 0;
 	int		ip6i_flags = 0;
 	zoneid_t	zoneid;
 	ill_t		*saved_ill = NULL;
 	boolean_t	conn_lock_held;
 	boolean_t	need_decref = B_FALSE;
 	ip_stack_t	*ipst;
+	int		adjust;
 
 	if (q->q_next != NULL) {
 		ill = (ill_t *)q->q_ptr;
@@ -9297,6 +9298,30 @@
 		goto notv6;
 	}
 
+	if (is_system_labeled() && DB_TYPE(mp) == M_DATA &&
+	    (connp == NULL || !connp->conn_ulp_labeled)) {
+		if (connp != NULL) {
+			ASSERT(CONN_CRED(connp) != NULL);
+			err = tsol_check_label_v6(BEST_CRED(mp, connp),
+			    &mp, &adjust, connp->conn_mac_exempt, ipst);
+		} else if (DB_CRED(mp) != NULL) {
+			err = tsol_check_label_v6(DB_CRED(mp),
+			    &mp, &adjust, 0, ipst);
+		}
+		if (mctl_present)
+			first_mp->b_cont = mp;
+		else
+			first_mp = mp;
+		if (err != 0) {
+			DTRACE_PROBE3(
+			    tsol_ip_log_drop_checklabel_ip6, char *,
+			    "conn(1), failed to check/update mp(2)",
+			    conn_t, connp, mblk_t, mp);
+			    freemsg(first_mp);
+			return;
+		}
+		ip6h = (ip6_t *)mp->b_rptr;
+	}
 	if (q->q_next != NULL) {
 		/*
 		 * We don't know if this ill will be used for IPv6
@@ -9328,7 +9353,6 @@
 		do_outrequests = B_FALSE;
 		zoneid = (zoneid_t)(uintptr_t)arg;
 	} else {
-		connp = (conn_t *)arg;
 		ASSERT(connp != NULL);
 		zoneid = connp->conn_zoneid;
 
--- a/usr/src/uts/common/inet/ip/ipsecah.c	Wed Feb 20 11:04:28 2008 -0800
+++ b/usr/src/uts/common/inet/ip/ipsecah.c	Wed Feb 20 12:21:06 2008 -0800
@@ -19,7 +19,7 @@
  * CDDL HEADER END
  */
 /*
- * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
  * Use is subject to license terms.
  */
 
@@ -2995,7 +2995,8 @@
 			return (NULL);
 	}
 
-	if ((phdr_mp = allocb(hdr_size + ah_data_sz, BPRI_HI)) == NULL) {
+	if ((phdr_mp = allocb_cred(hdr_size + ah_data_sz,
+	    DB_CRED(mp))) == NULL) {
 		return (NULL);
 	}
 
@@ -3126,7 +3127,7 @@
 		size += option_length;
 	}
 
-	if ((phdr_mp = allocb(size, BPRI_HI)) == NULL) {
+	if ((phdr_mp = allocb_cred(size, DB_CRED(mp))) == NULL) {
 		return (NULL);
 	}
 
@@ -4171,13 +4172,6 @@
 	}
 	freeb(phdr_mp);
 	ipsec_in->b_cont = mp;
-
-	if (is_system_labeled()) {
-		/*
-		 * inherit the label by setting it in the new ip header
-		 */
-		mblk_setcred(mp, DB_CRED(mp));
-	}
 	return (IPSEC_STATUS_SUCCESS);
 
 ah_in_discard:
@@ -4308,13 +4302,6 @@
 		nip6h->ip6_plen = htons((uint16_t)length);
 	}
 
-	if (is_system_labeled()) {
-		/*
-		 * inherit the label by setting it in the new ip header
-		 */
-		mblk_setcred(phdr_mp, DB_CRED(mp));
-	}
-
 	/* Skip the original IP header */
 	mp->b_rptr += hdrs_length;
 	if (mp->b_rptr == mp->b_wptr) {
--- a/usr/src/uts/common/inet/ip/tn_ipopt.c	Wed Feb 20 11:04:28 2008 -0800
+++ b/usr/src/uts/common/inet/ip/tn_ipopt.c	Wed Feb 20 12:21:06 2008 -0800
@@ -19,7 +19,7 @@
  * CDDL HEADER END
  */
 /*
- * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
  * Use is subject to license terms.
  */
 
@@ -675,11 +675,10 @@
 		copylen = MBLKL(mp);
 		if (copylen > 256)
 			copylen = 256;
-		new_mp = allocb(hlen + copylen +
-		    (mp->b_rptr - mp->b_datap->db_base), BPRI_HI);
+		new_mp = allocb_cred(hlen + copylen +
+		    (mp->b_rptr - mp->b_datap->db_base), DB_CRED(mp));
 		if (new_mp == NULL)
 			return (ENOMEM);
-		mblk_setcred(new_mp, DB_CRED(mp));
 
 		/* keep the bias */
 		new_mp->b_rptr += mp->b_rptr - mp->b_datap->db_base;
@@ -1251,11 +1250,10 @@
 			copylen = 256;
 		if (copylen < hdr_len)
 			copylen = hdr_len;
-		new_mp = allocb(hlen + copylen +
-		    (mp->b_rptr - mp->b_datap->db_base), BPRI_HI);
+		new_mp = allocb_cred(hlen + copylen +
+		    (mp->b_rptr - mp->b_datap->db_base), DB_CRED(mp));
 		if (new_mp == NULL)
 			return (ENOMEM);
-		mblk_setcred(new_mp, DB_CRED(mp));
 
 		/* keep the bias */
 		new_mp->b_rptr += mp->b_rptr - mp->b_datap->db_base;
--- a/usr/src/uts/common/inet/ip/tun.c	Wed Feb 20 11:04:28 2008 -0800
+++ b/usr/src/uts/common/inet/ip/tun.c	Wed Feb 20 12:21:06 2008 -0800
@@ -19,7 +19,7 @@
  * CDDL HEADER END
  */
 /*
- * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
  * Use is subject to license terms.
  */
 
@@ -75,6 +75,7 @@
 #include <net/if_dl.h>
 #include <inet/ip_if.h>
 #include <sys/strsun.h>
+#include <sys/strsubr.h>
 #include <inet/ipsec_impl.h>
 #include <inet/ipdrop.h>
 #include <inet/tun.h>
@@ -2780,7 +2781,9 @@
 	/*
 	 * If the pmtu provided came from an ICMP error being passed up
 	 * from below, then the pmtu argument has already been adjusted
-	 * by the IPsec overhead and ip header length.
+	 * by the IPsec overhead and ip header length.  For ICMP6, the
+	 * encap limit option's size is also accounted for as part of
+	 * outer_hlen in icmp_ricmp_err_v?_v6().
 	 */
 	if (!icmp && atp->tun_itp != NULL &&
 	    (atp->tun_itp->itp_flags & ITPF_P_ACTIVE))
@@ -2793,10 +2796,11 @@
 			newmtu = IP_MIN_MTU;
 	} else {
 		ASSERT(atp->tun_flags & TUN_L_V6);
-		if (!icmp)
+		if (!icmp) {
 			newmtu -= sizeof (ip6_t);
-		if (atp->tun_encap_lim > 0)
-			newmtu -= IPV6_TUN_ENCAP_OPT_LEN;
+			if (atp->tun_encap_lim > 0)
+				newmtu -= IPV6_TUN_ENCAP_OPT_LEN;
+		}
 		if (newmtu < IPV6_MIN_MTU)
 			newmtu = IPV6_MIN_MTU;
 	}
@@ -4729,7 +4733,8 @@
 		if ((mp->b_rptr - mp->b_datap->db_base) < hdrlen) {
 			/* no */
 
-			nmp = allocb(hdrlen + atp->tun_extra_offset, BPRI_HI);
+			nmp = allocb_cred(hdrlen + atp->tun_extra_offset,
+			    DB_CRED(mp));
 			if (nmp == NULL) {
 				atomic_add_32(&atp->tun_OutDiscard, 1);
 				atomic_add_32(&atp->tun_allocbfail, 1);
@@ -4773,8 +4778,8 @@
 
 		if ((mp->b_rptr - mp->b_datap->db_base) < hdrlen) {
 			/* no */
-			nmp = allocb(hdrlen + atp->tun_extra_offset,
-			    BPRI_HI);
+			nmp = allocb_cred(hdrlen + atp->tun_extra_offset,
+			    DB_CRED(mp));
 			if (nmp == NULL) {
 				atomic_add_32(&atp->tun_OutDiscard, 1);
 				atomic_add_32(&atp->tun_allocbfail, 1);
@@ -5251,8 +5256,8 @@
 		if ((mp->b_rptr - mp->b_datap->db_base) < sizeof (ipha_t)) {
 			/* no */
 
-			nmp = allocb(sizeof (ipha_t) + atp->tun_extra_offset,
-			    BPRI_HI);
+			nmp = allocb_cred(sizeof (ipha_t) +
+			    atp->tun_extra_offset, DB_CRED(mp));
 			if (nmp == NULL) {
 				atomic_add_32(&atp->tun_OutDiscard, 1);
 				atomic_add_32(&atp->tun_allocbfail, 1);
@@ -5438,8 +5443,8 @@
 
 		if ((mp->b_rptr - mp->b_datap->db_base) < hdrlen) {
 			/* no */
-			nmp = allocb(hdrlen + atp->tun_extra_offset,
-			    BPRI_HI);
+			nmp = allocb_cred(hdrlen + atp->tun_extra_offset,
+			    DB_CRED(mp));
 			if (nmp == NULL) {
 				atomic_add_32(&atp->tun_OutDiscard, 1);
 				atomic_add_32(&atp->tun_allocbfail, 1);