From 12eb7261a0cfe78aca133bef5763942ab8a9d692 Mon Sep 17 00:00:00 2001 From: Stan Smith Date: Wed, 15 Sep 2010 16:52:15 +0000 Subject: [PATCH] [IPOIB] incorporate trunk commit svn.2927 git-svn-id: svn://openib.tc.cornell.edu/gen1@2929 ad392aa1-c5ef-ae45-8dd8-e69d62a5ef86 --- branches/WOF2-3/ulp/ipoib/kernel/ipoib_port.c | 105 ++++++++++++------ 1 file changed, 68 insertions(+), 37 deletions(-) diff --git a/branches/WOF2-3/ulp/ipoib/kernel/ipoib_port.c b/branches/WOF2-3/ulp/ipoib/kernel/ipoib_port.c index 4a8290bf..462a9c47 100644 --- a/branches/WOF2-3/ulp/ipoib/kernel/ipoib_port.c +++ b/branches/WOF2-3/ulp/ipoib/kernel/ipoib_port.c @@ -2365,17 +2365,24 @@ __recv_dhcp( if( p_cid ) /* from client */ { + int i; /* Validate that the length and type of the option is as required. */ - if( p_cid[1] != 21 ) + IPOIB_PRINT(TRACE_LEVEL_VERBOSE, IPOIB_DBG_RECV, + ("DHCP CID received is:")); + for ( i=0; i < coIPoIB_CID_TotalLen; ++i) { + IPOIB_PRINT(TRACE_LEVEL_VERBOSE, IPOIB_DBG_RECV, + ("[%d] 0x%x: \n",i, p_cid[i])); + } + if( p_cid[1] != coIPoIB_CID_Len ) { IPOIB_PRINT_EXIT( TRACE_LEVEL_ERROR, IPOIB_DBG_ERROR, - ("Client-identifier length not 21 as required.\n") ); + ("Client-identifier length is not equal to %d as required.\n",coIPoIB_CID_Len) ); return IB_INVALID_SETTING; } - if( p_cid[2] != DHCP_HW_TYPE_IB ) + if( p_cid[2] != coIPoIB_HwTypeIB) { IPOIB_PRINT_EXIT( TRACE_LEVEL_ERROR, IPOIB_DBG_ERROR, - ("Client-identifier type is wrong.\n") ); + ("Client-identifier type is %d <> %d and wrong \n", p_cid[2], coIPoIB_HwTypeIB) ); return IB_INVALID_SETTING; } /* @@ -2385,8 +2392,10 @@ __recv_dhcp( */ p_cid[1] = sizeof (ib_net64_t) + 1;// CID length p_cid[2] = DHCP_HW_TYPE_ETH;// CID type - RtlMoveMemory( &p_cid[3], &p_cid[15], sizeof (ib_net64_t) ); - RtlFillMemory(&p_cid[11], 12, 0); + //Copy the GUID to the 3-d byte of CID + RtlMoveMemory( &p_cid[3], &p_cid[coIPoIB_CID_TotalLen - sizeof (ib_net64_t)], sizeof (ib_net64_t) ); + // Clear the rest + RtlFillMemory(&p_cid[3+sizeof (ib_net64_t)],coIPoIB_CID_TotalLen - 3 -sizeof (ib_net64_t), 0); RtlCopyMemory( p_dhcp->chaddr, &p_src->mac, sizeof(p_src->mac) ); RtlFillMemory( &p_dhcp->chaddr[sizeof(p_src->mac)], @@ -3550,7 +3559,6 @@ __send_mgr_filter_dhcp( uint8_t *p_option, *p_cid = NULL; uint8_t msg = 0; size_t len; - ib_gid_t gid; IPOIB_ENTER( IPOIB_DBG_SEND ); @@ -3627,14 +3635,29 @@ __send_mgr_filter_dhcp( /* Fix up the client identifier option */ if( p_cid ) { - /* do we need to replace it ? len eq ETH MAC sz 'and' MAC is mine */ - if( p_cid[1] == HW_ADDR_LEN+1 && !cl_memcmp( &p_cid[3], - &p_port->p_adapter->params.conf_mac.addr, HW_ADDR_LEN ) ) - { - /* Make sure there's room to extend it. 23 is the size of - * the CID option for IPoIB. + /* The length of client identifier should be equal to ETH MAC size */ + if( p_cid[1] == HW_ADDR_LEN+1 ) { + + /* MAC should be mine except the case below */ + if ( cl_memcmp( &p_cid[3], + &p_port->p_adapter->params.conf_mac.addr, HW_ADDR_LEN ) ) + + { + /* According to http://support.microsoft.com/kb/945948 + * This behavior occurs because the server sends a Dynamic Host Configuration Protocol (DHCP) + * INFORM message to the network. This DHCP INFORM message contains a MAC address that is + * unrelated to the addresses to which the physical network adapters are assigned. + * The packets are expected. Therefore, the packets are not seen as malicious. + * IPoIB will replace this demo MAC address by its GUID as for regular DHCP_INFORM packet + */ + IPOIB_PRINT( TRACE_LEVEL_ERROR, IPOIB_DBG_ERROR, + ("NDIS sends client message with other than mine MAC ADDRESS to search other DHCP servers\n") ); + } + + /* Make sure there's room to extend it. 22 is the size of + * the CID option for IPoIB. (20 is the length, one byte for type and the second for lenght field) */ - if( buf_len + 23 - p_cid[1] > sizeof(dhcp_pkt_t) ) + if( buf_len + coIPoIB_CID_TotalLen - p_cid[1] > sizeof(dhcp_pkt_t) ) { IPOIB_PRINT_EXIT( TRACE_LEVEL_ERROR, IPOIB_DBG_ERROR, ("Can't convert CID to IPoIB format.\n") ); @@ -3647,14 +3670,17 @@ __send_mgr_filter_dhcp( p_cid += len; p_cid[0] = DHCP_OPT_CLIENT_ID; - p_cid[1] = 21; - p_cid[2] = DHCP_HW_TYPE_IB; - } + p_cid[1] = coIPoIB_CID_Len; + } else { - ASSERT(FALSE); // Do we ever reach here? does it work correct? - p_cid[2] = DHCP_HW_TYPE_IB; + ASSERT( FALSE ); + IPOIB_PRINT_EXIT( TRACE_LEVEL_ERROR, IPOIB_DBG_ERROR, + (" Invalid Client Identifier Format\n") ); + return NDIS_STATUS_INVALID_DATA; } + + } else { @@ -3662,7 +3688,7 @@ __send_mgr_filter_dhcp( * Make sure there's room to extend it. 23 is the size of * the CID option for IPoIB. */ - if( buf_len + 23 > sizeof(dhcp_pkt_t) ) + if( buf_len + coIPoIB_CID_TotalLen > sizeof(dhcp_pkt_t) ) { IPOIB_PRINT_EXIT( TRACE_LEVEL_ERROR, IPOIB_DBG_ERROR, ("Can't convert CID to IPoIB format.\n") ); @@ -3670,27 +3696,21 @@ __send_mgr_filter_dhcp( } p_cid = p_option; - p_option = p_cid + 23; - p_option[0] = DHCP_OPT_END; p_cid[0] = DHCP_OPT_CLIENT_ID; - p_cid[1] = 21; - p_cid[2] = DHCP_HW_TYPE_IB; + p_cid[1] = coIPoIB_CID_Len; } - CL_ASSERT( p_cid[1] == 21 ); - p_cid[23]= DHCP_OPT_END; - ib_gid_set_default( &gid, p_port->p_adapter->guids.port_guid.guid ); - cl_memcpy( &p_cid[7], &gid, sizeof(ib_gid_t) ); - cl_memcpy( &p_cid[3], &p_port->ib_mgr.qpn, sizeof(p_port->ib_mgr.qpn) ); + CL_ASSERT( p_cid[1] == coIPoIB_CID_Len); + p_cid[coIPoIB_CID_TotalLen]= DHCP_OPT_END; + + // Copy the default prefix for ALL DHCP messages + cl_memcpy( &p_cid[2], &coIBDefaultDHCPPrefix[0], sizeof coIBDefaultDHCPPrefix); + // Copy the GUID into the last 8 bytes of the CID field + cl_memcpy( &p_cid[2+ sizeof(coIBDefaultDHCPPrefix)],&p_port->p_adapter->guids.port_guid.guid , + sizeof(p_port->p_adapter->guids.port_guid.guid) ); + p_ib_dhcp->htype = DHCP_HW_TYPE_IB; - /* update lengths to include any change we made */ - p_desc->p_buf->ip.hdr.length = cl_ntoh16( sizeof(ip_hdr_t) + sizeof(udp_hdr_t) + sizeof(dhcp_pkt_t) ); - p_desc->p_buf->ip.prot.udp.hdr.length = cl_ntoh16( sizeof(udp_hdr_t) + sizeof(dhcp_pkt_t) ); - - /* update crc in ip header */ - p_desc->p_buf->ip.hdr.chksum = 0; - p_desc->p_buf->ip.hdr.chksum = ipchksum((unsigned short*) &p_desc->p_buf->ip.hdr, sizeof(ip_hdr_t)); break; /* Server messages. */ @@ -3705,10 +3725,21 @@ __send_mgr_filter_dhcp( ("Invalide message type.\n") ); return NDIS_STATUS_INVALID_DATA; } + + /* update lengths to include any change we made */ + p_desc->p_buf->ip.hdr.length = cl_ntoh16( sizeof(ip_hdr_t) + sizeof(udp_hdr_t) + sizeof(dhcp_pkt_t) ); + p_desc->p_buf->ip.prot.udp.hdr.length = cl_ntoh16( sizeof(udp_hdr_t) + sizeof(dhcp_pkt_t) ); + + /* update crc in ip header */ + p_desc->p_buf->ip.hdr.chksum = 0; + p_desc->p_buf->ip.hdr.chksum = ipchksum((unsigned short*) &p_desc->p_buf->ip.hdr, sizeof(ip_hdr_t)); + /* no chksum for udp */ p_desc->p_buf->ip.prot.udp.hdr.chksum = 0; p_desc->local_ds[1].vaddr = cl_get_physaddr( p_desc->p_buf ); - p_desc->local_ds[1].length = sizeof(ip_hdr_t) + sizeof(udp_hdr_t) + sizeof(dhcp_pkt_t); + p_desc->local_ds[1].length = sizeof(ip_hdr_t) + + sizeof(udp_hdr_t) + + sizeof(dhcp_pkt_t); p_desc->local_ds[1].lkey = p_port->ib_mgr.lkey; p_desc->wr.num_ds = 2; IPOIB_EXIT( IPOIB_DBG_SEND ); -- 2.46.0