Mercurial > illumos > illumos-gate
changeset 3392:2c3a1c7448cc
6471718 Polling capability corrupt IP header check before ip_input()
6501903 xge panics on recieving a packet
author | yl150051 |
---|---|
date | Mon, 08 Jan 2007 23:36:56 -0800 |
parents | 2e4fef544e31 |
children | 660717ce3a70 |
files | usr/src/uts/common/inet/ip/ip.c usr/src/uts/common/io/xge/drv/xgell.c usr/src/uts/common/io/xge/drv/xgell.h |
diffstat | 3 files changed, 40 insertions(+), 127 deletions(-) [+] |
line wrap: on
line diff
--- a/usr/src/uts/common/inet/ip/ip.c Mon Jan 08 22:48:10 2007 -0800 +++ b/usr/src/uts/common/inet/ip/ip.c Mon Jan 08 23:36:56 2007 -0800 @@ -14674,7 +14674,6 @@ ip_rput(queue_t *q, mblk_t *mp) { ill_t *ill; - mblk_t *dmp = NULL; TRACE_1(TR_FAC_IP, TR_IP_RPUT_START, "ip_rput_start: q %p", q); @@ -14766,23 +14765,6 @@ freemsg(mp); mp = mp1; } - if (DB_TYPE(mp) == M_DATA) { - dmp = mp; - } else if (DB_TYPE(mp) == M_PROTO && - *(t_uscalar_t *)mp->b_rptr == DL_UNITDATA_IND) { - dmp = mp->b_cont; - } - if (dmp != NULL) { - /* - * IP header ptr not aligned? - * OR IP header not complete in first mblk - */ - if (!OK_32PTR(dmp->b_rptr) || - (dmp->b_wptr - dmp->b_rptr) < IP_SIMPLE_HDR_LENGTH) { - if (!ip_check_and_align_header(q, dmp)) - return; - } - } TRACE_2(TR_FAC_IP, TR_IP_RPUT_END, "ip_rput_end: q %p (%S)", q, "end"); @@ -14805,7 +14787,9 @@ * - 'mp' is either an untagged or a special priority-tagged packet. * - Any VLAN tag that was in the MAC header has been stripped. * - * Thus, there is no need to adjust b_rptr in this function. + * If the IP header in packet is not 32-bit aligned, every message in the + * chain will be aligned before further operations. This is required on SPARC + * platform. */ /* ARGSUSED */ void @@ -14827,6 +14811,7 @@ mblk_t *tail = NULL; mblk_t *first_mp; mblk_t *mp; + mblk_t *dmp; int cnt = 0; ASSERT(mp_chain != NULL); @@ -14852,19 +14837,42 @@ prev_dst = dst; /* + * Check and align the IP header. + */ + if (DB_TYPE(mp) == M_DATA) { + dmp = mp; + } else if (DB_TYPE(mp) == M_PROTO && + *(t_uscalar_t *)mp->b_rptr == DL_UNITDATA_IND) { + dmp = mp->b_cont; + } else { + dmp = NULL; + } + if (dmp != NULL) { + /* + * IP header ptr not aligned? + * OR IP header not complete in first mblk + */ + if (!OK_32PTR(dmp->b_rptr) || + MBLKL(dmp) < IP_SIMPLE_HDR_LENGTH) { + if (!ip_check_and_align_header(q, dmp)) + continue; + } + } + + /* * ip_input fast path */ /* mblk type is not M_DATA */ - if (mp->b_datap->db_type != M_DATA) { + if (DB_TYPE(mp) != M_DATA) { if (ip_rput_process_notdata(q, &first_mp, ill, &ll_multicast, &mp)) continue; } /* Make sure its an M_DATA and that its aligned */ - ASSERT(mp->b_datap->db_type == M_DATA); - ASSERT(mp->b_datap->db_ref == 1 && OK_32PTR(mp->b_rptr)); + ASSERT(DB_TYPE(mp) == M_DATA); + ASSERT(DB_REF(mp) == 1 && OK_32PTR(mp->b_rptr)); ipha = (ipha_t *)mp->b_rptr; len = mp->b_wptr - rptr;
--- a/usr/src/uts/common/io/xge/drv/xgell.c Mon Jan 08 22:48:10 2007 -0800 +++ b/usr/src/uts/common/io/xge/drv/xgell.c Mon Jan 08 23:36:56 2007 -0800 @@ -20,7 +20,7 @@ */ /* - * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + * Copyright 2007 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -47,10 +47,8 @@ #define HEADROOM 2 /* for DIX-only packets */ -#ifdef XGELL_L3_ALIGNED void header_free_func(void *arg) { } frtn_t header_frtn = {header_free_func, NULL}; -#endif /* DMA attributes used for Tx side */ static struct ddi_dma_attr tx_dma_attr = { @@ -633,68 +631,17 @@ int pkt_length, xge_hal_dtr_info_t *ext_info, boolean_t *copyit) { mblk_t *mp; - mblk_t *nmp = NULL; char *vaddr; - int hdr_length = 0; - -#ifdef XGELL_L3_ALIGNED - boolean_t doalign = B_TRUE; - struct ip *ip; - struct tcphdr *tcp; - int tcp_off; - int mp_align_len; - int ip_off; -#endif vaddr = (char *)rx_buffer->vaddr + HEADROOM; -#ifdef XGELL_L3_ALIGNED - ip_off = xgell_get_ip_offset(ext_info); - - /* Check ip_off with HEADROOM */ - if ((ip_off & 3) == HEADROOM) { - doalign = B_FALSE; - } - - /* - * Doalign? Check for types of packets. - */ - /* Is IPv4 or IPv6? */ - if (doalign && !(ext_info->proto & XGE_HAL_FRAME_PROTO_IPV4 || - ext_info->proto & XGE_HAL_FRAME_PROTO_IPV6)) { - doalign = B_FALSE; - } - - /* Is TCP? */ - if (doalign && - ((ip = (struct ip *)(vaddr + ip_off))->ip_p == IPPROTO_TCP)) { - tcp_off = ip->ip_hl * 4 + ip_off; - tcp = (struct tcphdr *)(vaddr + tcp_off); - hdr_length = tcp_off + tcp->th_off * 4; - if (pkt_length < (XGE_HAL_TCPIP_HEADER_MAX_SIZE + - XGE_HAL_MAC_HEADER_MAX_SIZE)) { - hdr_length = pkt_length; - } - } else { - doalign = B_FALSE; - } -#endif - /* * Copy packet into new allocated message buffer, if pkt_length * is less than XGELL_RX_DMA_LOWAT */ if (*copyit || pkt_length <= lldev->config.rx_dma_lowat) { - /* Keep room for alignment */ - if ((mp = allocb(pkt_length + HEADROOM + 4, 0)) == NULL) { + if ((mp = allocb(pkt_length, 0)) == NULL) { return (NULL); } -#ifdef XGELL_L3_ALIGNED - if (doalign) { - mp_align_len = - (4 - ((uint64_t)(mp->b_rptr + ip_off) & 3)); - mp->b_rptr += mp_align_len; - } -#endif bcopy(vaddr, mp->b_rptr, pkt_length); mp->b_wptr = mp->b_rptr + pkt_length; *copyit = B_TRUE; @@ -704,53 +651,15 @@ /* * Just allocate mblk for current data buffer */ - if ((nmp = (mblk_t *)desballoc((unsigned char *)vaddr, pkt_length, 0, + if ((mp = (mblk_t *)desballoc((unsigned char *)vaddr, pkt_length, 0, &rx_buffer->frtn)) == NULL) { /* Drop it */ return (NULL); } - /* - * Adjust the b_rptr/b_wptr in the mblk_t structure to point to - * payload. + * Adjust the b_rptr/b_wptr in the mblk_t structure. */ - nmp->b_rptr += hdr_length; - nmp->b_wptr += pkt_length; - -#ifdef XGELL_L3_ALIGNED - if (doalign) { - if ((mp = esballoc(rx_buffer->header, hdr_length + 4, 0, - &header_frtn)) == NULL) { - /* can not align! */ - mp = nmp; - mp->b_rptr = (u8 *)vaddr; - mp->b_wptr = mp->b_rptr + pkt_length; - mp->b_next = NULL; - mp->b_cont = NULL; - } else { - /* align packet's ip-header offset */ - mp_align_len = - (4 - ((uint64_t)(mp->b_rptr + ip_off) & 3)); - mp->b_rptr += mp_align_len; - mp->b_wptr += mp_align_len + hdr_length; - mp->b_cont = nmp; - mp->b_next = NULL; - nmp->b_cont = NULL; - nmp->b_next = NULL; - - bcopy(vaddr, mp->b_rptr, hdr_length); - } - } else { - /* no need to align */ - mp = nmp; - mp->b_next = NULL; - mp->b_cont = NULL; - } -#else - mp = nmp; - mp->b_next = NULL; - mp->b_cont = NULL; -#endif + mp->b_wptr += pkt_length; return (mp); } @@ -2341,6 +2250,10 @@ if (mac_register(macp, &lldev->mh) != 0) goto xgell_register_fail; + /* Always free the macp after register */ + if (macp != NULL) + mac_free(macp); + /* Calculate tx_copied_max here ??? */ lldev->tx_copied_max = hldev->config.fifo.max_frags * hldev->config.fifo.alignment_size *
--- a/usr/src/uts/common/io/xge/drv/xgell.h Mon Jan 08 22:48:10 2007 -0800 +++ b/usr/src/uts/common/io/xge/drv/xgell.h Mon Jan 08 23:36:56 2007 -0800 @@ -20,7 +20,7 @@ */ /* - * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + * Copyright 2007 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -76,10 +76,6 @@ #include <xgehal.h> -#if defined(__sparc) || defined(__amd64) -#define XGELL_L3_ALIGNED 1 -#endif - /* * These default values can be overridden by vaules in xge.conf. * In xge.conf user has to specify actual (not percentages) values. @@ -239,10 +235,6 @@ ddi_acc_handle_t dma_acch; void *lldev; frtn_t frtn; -#ifdef XGELL_L3_ALIGNED - unsigned char header[XGE_HAL_TCPIP_HEADER_MAX_SIZE * 2 - + 8]; -#endif } xgell_rx_buffer_t; /* Buffer pool for all rings */