[ofw] [Patch][ipoib] DHCP fix for ipoib (NDIS5)

Alex Naslednikov xalex at mellanox.co.il
Wed Sep 15 04:16:34 PDT 2010


Applied at 2927

________________________________
From: Alex Naslednikov
Sent: Wednesday, September 01, 2010 3:56 PM
To: ofw at lists.openfabrics.org
Subject: [ofw][Patch][ipoib] DHCP fix for ipoib (NDIS5)

This is the extension of the same patch for IPoIB_NDIS6_CM
It assumes that IPoIB_NDIS6_CM DHCP patch was previously applied,
because it assumes that changes at ip_packet.h are already done
The format of Client Identifier Field (CID) was changed.

/* The CID will contain of:
 CID[0] = DHCP_OPT_CLIENT_ID == 61
 CID[1] = coIPoIB_CID_Len == 22
 CID[2:13] = coIBDefaultDHCPPrefix; (Here CID[2] always == coIPoIB_HwTypeIB == 0xFF)
 CID[14:21] = GUID;
*/
Signed-off by: Alexander Naslednikov (xalex at mellanox.co.il)
Index: B:/users/xalex/MLNX_WinOF-2_1_2/ulp/ipoib/kernel/ipoib_port.c
===================================================================
--- B:/users/xalex/MLNX_WinOF-2_1_2/ulp/ipoib/kernel/ipoib_port.c (revision 6408)
+++ B:/users/xalex/MLNX_WinOF-2_1_2/ulp/ipoib/kernel/ipoib_port.c (revision 6409)
@@ -2370,17 +2370,24 @@

  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;
   }
   /*
@@ -2390,8 +2397,10 @@
    */
   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)],
@@ -3555,7 +3564,6 @@
  uint8_t    *p_option, *p_cid = NULL;
  uint8_t    msg = 0;
  size_t    len;
- ib_gid_t   gid;

  IPOIB_ENTER( IPOIB_DBG_SEND );

@@ -3632,14 +3640,29 @@
   /* 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") );
@@ -3652,16 +3675,17 @@

     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
    {
-    //
-    // BUGBUG:: We reach this code, need to handle it correctly
-    //
-    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
   {
@@ -3669,7 +3693,7 @@
     * 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") );
@@ -3677,27 +3701,21 @@
    }

    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. */
@@ -3712,10 +3730,21 @@
    ("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 );

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.openfabrics.org/pipermail/ofw/attachments/20100915/ddf7886c/attachment.html>


More information about the ofw mailing list