[ofw] [Patch 32/62] Reference implementation of NDv2

Fab Tillier ftillier at microsoft.com
Wed Feb 20 18:06:08 PST 2013


This is a fairly sizeable patch, and moves all IBAT logic into the kernel.

IBAT moves out of IPoIB, and into ibbus.  All the IP address registration with the SA in IPoIB is gone (the ATS stuff that has been obsolete for probably 5 years now, if not more).  You'll see that IPoIB now registers with IBAT.  There is rudimentary support for RoCE.

The whole ibat_ex module is eliminated, and the number of IOCTLs supported is reduced.  The IBAL ND provider no longer queries for the path in user-mode, but just passes source and destination IP in the connect IOCTL, and everything else is taken care of in the kernel.

Signed-off-by: Fab Tillier <ftillier at microsoft.com>

diff -dwup3 -X excl.txt -r c:\dev\openib\ofw\gen1\branches\mlx4_30\trunk\core\al\al_dev.h .\core\al\al_dev.h
--- c:\dev\openib\ofw\gen1\branches\mlx4_30\trunk\core\al\al_dev.h	Tue Aug 07 14:17:47 2012
+++ .\core\al\al_dev.h	Tue Aug 07 14:21:19 2012
@@ -49,6 +49,7 @@
 #include <complib/cl_ioctl.h>
 #include <iba/ib_al.h>
 #include <iba/ib_al_ioctl.h>
+#include <iba/ib_at_ioctl.h>
 
 #include "al_common.h"
 
@@ -445,6 +446,10 @@ typedef enum _al_ndi_ops
 
 #define IS_NDI_IOCTL(cmd)		\
 	((cmd) > AL_NDI_OPS_START && (cmd) < AL_NDI_MAXOPS)
+
+// Note that the IOCTL definitions come from ib_at_ioctl.h
+#define IS_IBAT_IOCTL(cmd)      \
+    ((cmd) >= IOCTL_IBAT_IP_ADDRESSES && ((cmd) <= IOCTL_IBAT_QUERY_PATH))
 
 /* NDI Related ioctl commands */
 #define UAL_NDI_CREATE_CQ		IOCTL_CODE(ALDEV_KEY, ual_ndi_create_cq_ioctl_cmd)
diff -dwup3 -X excl.txt -r c:\dev\openib\ofw\gen1\branches\mlx4_30\trunk\core\al\kernel\al_dev.c .\core\al\kernel\al_dev.c
--- c:\dev\openib\ofw\gen1\branches\mlx4_30\trunk\core\al\kernel\al_dev.c	Tue Aug 07 11:02:41 2012
+++ .\core\al\kernel\al_dev.c	Thu Jul 26 15:31:13 2012
@@ -611,6 +611,13 @@ al_dev_ioctl(
 	else if( IS_NDI_IOCTL(ctl_code) )
     {
 		cl_status = ndi_ioctl( h_ioctl, &ret_bytes );
+    }
+    else if( IS_IBAT_IOCTL(ctl_code) )
+    {
+        // IBAT fully handles the IRP.
+        cl_status = ibat_ioctl( h_ioctl );
+        AL_EXIT( AL_DBG_DEV );
+        return cl_status;
     }
 	else
     {
diff -dwup3 -X excl.txt -r c:\dev\openib\ofw\gen1\branches\mlx4_30\trunk\core\al\kernel\al_mgr.c .\core\al\kernel\al_mgr.c
--- c:\dev\openib\ofw\gen1\branches\mlx4_30\trunk\core\al\kernel\al_mgr.c	Thu May 31 11:22:15 2012
+++ .\core\al\kernel\al_mgr.c	Thu Jul 26 15:31:13 2012
@@ -37,6 +37,7 @@
 #include <complib/cl_vector.h>
 
 #include <iba/ib_ci.h>
+#include <iba\ibat.h>
 
 #include "al.h"
 #include "al_cm_cep.h"
@@ -218,6 +219,8 @@ create_al_mgr()
 		return status;
 	}
 
+    status = IbatInitialize();
+
 	/* Release the reference taken in init_al_obj. */
 	deref_ctx_al_obj( &gp_al_mgr->obj, E_REF_INIT );
 
@@ -232,6 +235,8 @@ __free_al_mgr(
 	IN				al_obj_t					*p_obj )
 {
 	CL_ASSERT( p_obj == &gp_al_mgr->obj );
+
+    IbatCleanup();
 
 	/*
 	 * We need to destroy the AL object before the spinlock, since
diff -dwup3 -X excl.txt -r c:\dev\openib\ofw\gen1\branches\mlx4_30\trunk\core\al\kernel\al_ndi_cm.c .\core\al\kernel\al_ndi_cm.c
--- c:\dev\openib\ofw\gen1\branches\mlx4_30\trunk\core\al\kernel\al_ndi_cm.c	Tue Aug 07 12:08:10 2012
+++ .\core\al\kernel\al_ndi_cm.c	Tue Jun 19 17:44:59 2012
@@ -39,7 +39,7 @@
 #if WINVER <= 0x501
 #include "csq.h"
 #endif
-
+#include <kernel\iba\ibat.h>
 #if defined(EVENT_TRACING)
 #ifdef offsetof
 #undef offsetof
@@ -321,7 +321,12 @@ static NTSTATUS __ndi_insert_irp_ex(
 
 	case NDI_CM_CONNECTING_QPR_SENT:
 		status = __ndi_pr_query( pIrp );
+        if( STATUS_SUCCESS != status )
+        {
 		break;
+        }
+        Context = (VOID*)NDI_CM_CONNECTING_REQ_SENT;
+        __fallthrough;
 
 	case NDI_CM_CONNECTING_REQ_SENT:
 		status = __ndi_send_req( pIrp );
@@ -392,6 +397,7 @@ static PIRP __ndi_peek_next_irp(
 	IN	PVOID									PeekContext
 	)
 {
+    ULONG_PTR code;
 	PIRP nextIrp = NULL;
 	PLIST_ENTRY nextEntry;
 	PLIST_ENTRY listHead;
@@ -408,26 +414,37 @@ static PIRP __ndi_peek_next_irp(
 	//
 
 	if(Irp == NULL)
+    {
 		nextEntry = listHead->Flink;
+    }
 	else
+    {
 		nextEntry = Irp->Tail.Overlay.ListEntry.Flink;
+    }
 
-	while(nextEntry != listHead) {
-		nextIrp = CONTAINING_RECORD(nextEntry, IRP, Tail.Overlay.ListEntry);
 
 		//
-		// If context is present, continue until you find a matching one.
-		// Else you break out as you got next one.
+    // We will return the next irp that matches the following criteria:
+    //  1.  Has IOCTL that matches the value in context
+    //      This is the normal case where we pull an expected item from the queue
+    //  2.  No context specified and Irp does not have IOCTL code UAL_NDI_NOTIFY_DREQ
+    //      We special case the DREQ notify and don't remove it until it actually
+    //      happens (hits case 2).  This allows the client to post the pending IO
+    //      and it will complete when the disconnect happens.
 		//
+    while(nextEntry != listHead)
+    {
+        nextIrp = CONTAINING_RECORD(nextEntry, IRP, Tail.Overlay.ListEntry);
 
-		if(PeekContext) 
+        code = cl_ioctl_ctl_code( nextIrp );
+        CL_ASSERT( code != 0 );
+
+        if( (ULONG_PTR)PeekContext == code )
 		{
-			if( cl_ioctl_ctl_code( nextIrp ) == (ULONG_PTR)PeekContext )
 				break;
 		}
-		else
+        else if( NULL == PeekContext && code != UAL_NDI_NOTIFY_DREQ )
 		{
-			if( cl_ioctl_ctl_code( nextIrp ) != UAL_NDI_NOTIFY_DREQ )
 				break;
 		}
 
@@ -533,7 +550,6 @@ static VOID __ndi_complete_cancelled_irp
 }
 
 
-
 NTSTATUS
 nd_csq_init(
 	IN				ib_al_handle_t				h_al,
@@ -1153,9 +1169,9 @@ __ndi_send_req(
 	IN		IRP*								p_irp
 	)
 {
+    uint8_t pkt_life;
 	ib_api_status_t status;
 	nd_csq_t* p_csq = (nd_csq_t*)p_irp->Tail.Overlay.DriverContext[0];
-	ib_path_rec_t *p_path_rec = p_irp->Tail.Overlay.DriverContext[1];
 	ual_ndi_req_cm_ioctl_in_t *p_req = 
 		(ual_ndi_req_cm_ioctl_in_t*)cl_ioctl_in_buf( p_irp );
 	NTSTATUS nt_status;
@@ -1166,8 +1182,6 @@ __ndi_send_req(
 		("[ CID = %d, h_al %p, context %p\n",
 		p_req->cid, p_csq->h_al, p_csq) );
 
-	p_irp->Tail.Overlay.DriverContext[1] = NULL;
-
 	if( p_csq->state != NDI_CM_CONNECTING_QPR_SENT &&
 		p_csq->state != NDI_CM_IDLE )
 	{
@@ -1188,8 +1202,19 @@ __ndi_send_req(
 		return STATUS_CONNECTION_ABORTED;
 	}
 
+    //
+    // Fixup the packet life
+    //
+    pkt_life = ib_path_rec_pkt_life( &p_req->path ) + g_pkt_life_modifier;
+    if( pkt_life > 0x1F )
+    {
+        pkt_life = 0x1F;
+    }
+    p_req->path.pkt_life &= IB_PATH_REC_SELECTOR_MASK;
+    p_req->path.pkt_life |= pkt_life;
+
 	/* Format ib_cm_req_t structure */
-	__ndi_fill_cm_req( h_qp->num, p_req, p_path_rec, &cm_req );
+    __ndi_fill_cm_req( h_qp->num, p_req, &p_req->path, &cm_req );
 	deref_al_obj( &h_qp->obj );
 
 	/* prepare CEP for connection */
@@ -1236,22 +1261,23 @@ error:
 }
 
 
-static void AL_API
+static void
 __ndi_pr_query_cb(
-					ib_query_rec_t				*p_query_rec )
+    __in VOID* pCompletionContext,
+    __in NTSTATUS status,
+    __in ib_path_rec_t* const pPath
+    )
 {
 	cl_ioctl_handle_t p_irp;
-	uint8_t pkt_life;
-	ib_path_rec_t *p_path_rec;
-	nd_csq_t* p_csq = (nd_csq_t*)p_query_rec->query_context;
-	NTSTATUS status;
+    ual_ndi_req_cm_ioctl_in_t *p_req;
+    nd_csq_t* p_csq = (nd_csq_t*)pCompletionContext;
+
 	KIRQL irql;
 
 	AL_ENTER( AL_DBG_NDI );
 
 	AL_PRINT( TRACE_LEVEL_INFORMATION, AL_DBG_NDI,
-		("status is %d, count is %d, context %p\n", p_query_rec->status,
-		p_query_rec->result_cnt, p_query_rec->query_context) );
+        ("PR Query Async: status is %d, context %p\n", status, pCompletionContext) );
 
 	p_irp = IoCsqRemoveNextIrp( &p_csq->csq, (VOID*)(ULONG_PTR)UAL_NDI_REQ_CM );
 	if( p_irp == NULL )
@@ -1259,60 +1285,25 @@ __ndi_pr_query_cb(
 		goto exit;
 	}
 
-#pragma warning( disable:4305 )
-	InterlockedExchangePointer( &p_csq->h_query, NULL );
-#pragma warning( default:4305 )
-
-	if( p_query_rec->status != IB_SUCCESS || p_query_rec->result_cnt == 0 )
+    if( status != IB_SUCCESS )
 	{
 		__ndi_acquire_lock( &p_csq->csq, &irql );
 		if( p_csq->state != NDI_CM_INVALID )
-			p_csq->state = NDI_CM_IDLE;
-		__ndi_release_lock( &p_csq->csq, irql );
-		switch( p_query_rec->status )
 		{
-		case IB_TIMEOUT:
-		case IB_CANCELED:
-			status = ib_to_ntstatus( p_query_rec->status );
-			break;
-
-		case IB_REMOTE_ERROR:
-			CL_ASSERT( p_query_rec->p_result_mad );
-			switch( p_query_rec->p_result_mad->p_mad_buf->status )
-			{
-			case IB_MAD_STATUS_BUSY:
-			case IB_SA_MAD_STATUS_NO_RESOURCES:
-				status = STATUS_TIMEOUT;
-				break;
-
-			default:
-				status = STATUS_INVALID_PARAMETER_1 +
-					(p_query_rec->p_result_mad->p_mad_buf->status & 0xFF);
-				break;
-			}
-			break;
-
-		default:
-			status = STATUS_HOST_UNREACHABLE;
-			break;
+            p_csq->state = NDI_CM_IDLE;
 		}
+        __ndi_release_lock( &p_csq->csq, irql );
 		__ndi_complete_irp( p_csq, p_irp, status );
 		goto exit;
 	}
 
-	/* Path Record has been received ! */
-	p_path_rec = ib_get_query_path_rec( p_query_rec->p_result_mad, 0 );
-
-	/* fix packet life */
-	CL_ASSERT( p_path_rec );
-	pkt_life = ib_path_rec_pkt_life( p_path_rec ) + g_pkt_life_modifier;
-	if( pkt_life > 0x1F )
-		pkt_life = 0x1F;
-
-	p_path_rec->pkt_life &= IB_PATH_REC_SELECTOR_MASK;
-	p_path_rec->pkt_life |= pkt_life;
+    p_req = (ual_ndi_req_cm_ioctl_in_t*)cl_ioctl_in_buf( p_irp );
 
-	p_irp->Tail.Overlay.DriverContext[1] = p_path_rec;
+    RtlCopyMemory(
+        &p_req->path,
+        pPath,
+        sizeof(*pPath)
+        );
 
 	status = IoCsqInsertIrpEx(
 		&p_csq->csq,
@@ -1322,7 +1313,6 @@ __ndi_pr_query_cb(
 		);
 	if( !NT_SUCCESS( status ) )
 	{
-		p_irp->Tail.Overlay.DriverContext[1] = NULL;
 		__ndi_complete_irp( p_csq, p_irp, status );
 	}
 	else
@@ -1334,15 +1324,14 @@ __ndi_pr_query_cb(
 		nd_csq_release( p_csq ); /* Release IRP reference. */
 	}
 
-exit:
-	if( p_query_rec->p_result_mad )
-		ib_put_mad( p_query_rec->p_result_mad );
 
+exit:
 	nd_csq_release( p_csq );	/* release path query reference */
 	AL_EXIT( AL_DBG_NDI );
 }
 
 
+
 /*
  * Send asynchronous query to the SA for a path record.
  *
@@ -1353,12 +1342,10 @@ __ndi_pr_query(
 	IN		IRP*								p_irp
 	)
 {
-	ib_query_req_t query_req;
 	ib_api_status_t status;
 	ual_ndi_req_cm_ioctl_in_t *p_req = 
 		(ual_ndi_req_cm_ioctl_in_t*)cl_ioctl_in_buf( p_irp );
 	nd_csq_t* p_csq = (nd_csq_t*)p_irp->Tail.Overlay.DriverContext[0];
-	ib_gid_pair_t gids;
 
 	AL_ENTER( AL_DBG_NDI );
 
@@ -1370,34 +1357,87 @@ __ndi_pr_query(
 		return STATUS_CONNECTION_ACTIVE;
 	}
 
-	gids.src_gid = p_req->path.sgid;
-	gids.dest_gid = p_req->path.dgid;
 
-	query_req.query_type = IB_QUERY_PATH_REC_BY_GIDS;
-	query_req.p_query_input = &gids;
-	query_req.port_guid = p_req->guid;
-	query_req.timeout_ms = g_sa_timeout;
-	query_req.retry_cnt = g_sa_retries;
-	query_req.flags = 0;	/* IB_FLAGS_SYNC */
-	query_req.query_context = p_csq;
-	query_req.pfn_query_cb = __ndi_pr_query_cb;
+    nd_csq_ref( p_csq );        /* take path query reference */
 
-	AL_PRINT( TRACE_LEVEL_INFORMATION, AL_DBG_NDI,
-		("Query for path from %I64x to %I64x\n",
-		p_req->guid, ib_gid_get_guid( &p_req->path.dgid )) );
+    status = IbatQueryPathByPhysicalAddress(
+        p_req->src_mac,
+        p_req->dest_mac,
+        __ndi_pr_query_cb,
+        p_csq,
+        &p_req->path
+        );
 
-	nd_csq_ref( p_csq );		/* take path query reference */
-	status = ib_query( p_csq->h_al, &query_req, &p_csq->h_query );
-	if( status != IB_SUCCESS )
+    if( !NT_SUCCESS( status ) )
 	{
 		p_csq->state = NDI_CM_IDLE;
-		AL_PRINT_EXIT( TRACE_LEVEL_ERROR, AL_DBG_ERROR, ("ib_query failed (%d)\n", status) );
+        AL_PRINT( TRACE_LEVEL_ERROR, AL_DBG_ERROR, ("IbatQueryPathByPhysicalAddress failed (%d)\n", status) );
 		nd_csq_release( p_csq );	/* release path query reference */
-		return ib_to_ntstatus( status );
 	}
+    else if( STATUS_PENDING != status )
+    {
+        CL_ASSERT( STATUS_SUCCESS == status );
 
+        AL_PRINT( TRACE_LEVEL_INFORMATION, AL_DBG_NDI,
+        ("PR Query Sync: status is %d\n", status ) );
+        nd_csq_release( p_csq );    /* release path query reference */
+    }
 	AL_EXIT( AL_DBG_NDI );
-	return STATUS_PENDING;
+    return status;
+}
+
+
+static inline void
+NdInitializeSockAddrInet(
+    __out SOCKADDR_INET*            pAddr,
+    __in    uint8_t                 ipVersion,
+    __in_ecount(4)const uint32_t*   pBuffer
+    )
+{
+    switch( ipVersion )
+    {
+    case IB_REQ_CM_RDMA_IPV6:
+        {
+            pAddr->Ipv6.sin6_family = AF_INET6;
+            RtlCopyMemory(
+                &pAddr->Ipv6.sin6_addr,
+                pBuffer,
+                sizeof(pAddr->Ipv6.sin6_addr)
+                );
+        }
+        break;
+    case IB_REQ_CM_RDMA_IPV4:
+        {
+            pAddr->Ipv4.sin_family = AF_INET;
+            pAddr->Ipv4.sin_addr.S_un.S_addr = pBuffer[3];
+        }
+        break;
+    default:
+        {
+            pAddr->si_family = AF_UNSPEC;
+        }
+        break;
+    }
+}
+
+
+static inline NTSTATUS
+NdResolvePhysicalAddresses(
+    ual_ndi_req_cm_ioctl_in_t* pReq
+    )
+{
+    SOCKADDR_INET localAddress;
+    SOCKADDR_INET remoteAddress;
+
+    NdInitializeSockAddrInet(&localAddress, pReq->pdata.ipv, pReq->pdata.src_ip_addr);
+    NdInitializeSockAddrInet(&remoteAddress, pReq->pdata.ipv, pReq->pdata.dst_ip_addr);
+
+    return IbatResolvePhysicalAddress(
+        &localAddress,
+        &remoteAddress,
+        &pReq->src_mac,
+        &pReq->dest_mac
+        );
 }
 
 
@@ -1414,43 +1454,36 @@ ndi_req_cm(
 
 	AL_ENTER( AL_DBG_NDI );
 
+    //
+    // Before we can build the ND Path, we need to resolve the local port
+    //  and remote mac address inforation.  We do that here because the
+    //  ARP calls require IRQL < dispatch, but once inside the Csq callbacks,
+    //  we will be running IRQL == dispatch.
+    //
+    status = NdResolvePhysicalAddresses(p_req);
+    if( !NT_SUCCESS( status ) )
+    {
+        goto err;
+    }
+
 	p_csq = kal_cep_get_context( h_al, p_req->cid, nd_cm_handler, nd_csq_ref );
 	if( p_csq == NULL )
 	{
 		status = nd_csq_init( h_al, p_req->cid, p_req->h_qp, &p_csq );
 		if( status != STATUS_SUCCESS )
+        {
 			goto err;
+        }
 	}
 
 	p_irp->Tail.Overlay.DriverContext[0] = p_csq;
 
-	if( p_req->path.dlid != 0 || p_req->transport == RDMA_TRANSPORT_RDMAOE)
-	{
-		/* fix packet life */
-		uint8_t pkt_life = ib_path_rec_pkt_life( &p_req->path ) + g_pkt_life_modifier;
-		if( pkt_life > 0x1F )
-			pkt_life = 0x1F;
-
-		p_req->path.pkt_life &= IB_PATH_REC_SELECTOR_MASK;
-		p_req->path.pkt_life |= pkt_life;
-
-		p_irp->Tail.Overlay.DriverContext[1] = &p_req->path;
-		status = IoCsqInsertIrpEx(
-			&p_csq->csq,
-			p_irp,
-			NULL,
-			(VOID*)(ULONG_PTR)NDI_CM_CONNECTING_REQ_SENT
-			);
-	}
-	else
-	{
 		status = IoCsqInsertIrpEx(
 			&p_csq->csq,
 			p_irp,
 			NULL,
 			(VOID*)(ULONG_PTR)NDI_CM_CONNECTING_QPR_SENT
 			);
-	}
 
 	nd_csq_release( p_csq );
 err:
diff -dwup3 -X excl.txt -r c:\dev\openib\ofw\gen1\branches\mlx4_30\trunk\core\al\kernel\al_proxy.h .\core\al\kernel\al_proxy.h
--- c:\dev\openib\ofw\gen1\branches\mlx4_30\trunk\core\al\kernel\al_proxy.h	Tue Aug 07 11:02:41 2012
+++ .\core\al\kernel\al_proxy.h	Thu Jul 26 15:31:13 2012
@@ -414,6 +414,10 @@ cl_status_t ndi_ioctl(
 	IN		cl_ioctl_handle_t		h_ioctl,
 		OUT	size_t					*p_ret_bytes );
 
+NTSTATUS ibat_ioctl(
+    __in IRP* pIrp
+    );
+
 boolean_t
 proxy_queue_cb_buf(
 	IN		uintn_t					cb_type,
diff -dwup3 -X excl.txt -r c:\dev\openib\ofw\gen1\branches\mlx4_30\trunk\core\bus\kernel\bus_pnp.c .\core\bus\kernel\bus_pnp.c
--- c:\dev\openib\ofw\gen1\branches\mlx4_30\trunk\core\bus\kernel\bus_pnp.c	Tue Aug 07 11:48:15 2012
+++ .\core\bus\kernel\bus_pnp.c	Thu Jul 26 16:20:52 2012
@@ -40,6 +40,7 @@
 #include "rdma/verbs.h"
 #include "iba/ib_ci_ifc.h"
 #include "iba/ib_cm_ifc.h"
+#include "iba\ibat_ifc.h"
 
 /* Interface names are generated by IoRegisterDeviceInterface. */
 static UNICODE_STRING	al_ifc_name;
@@ -52,6 +53,7 @@ bus_filter_t			g_bus_filters[MAX_BUS_FIL
 
 extern PDEVICE_OBJECT	g_ControlDeviceObject;
 extern UNICODE_STRING	g_CDO_dev_name, g_CDO_dos_name;
+static UNICODE_STRING   g_IbatDosName;
 ET_POST_EVENT 			g_post_event_func = NULL;
 
 
@@ -610,13 +612,13 @@ fdo_start(
 	p_ext->mcast_mgr_created = TRUE;
 	guid = p_ext->hca_ifc.Verbs.guid;
 	
-
 	/* if 1st Bus Filter Instance, then create device names for user ioctl */
 	lock_control_event();
 	if ( ic == 1  && !g_ControlDeviceObject)
 	{
 		RtlInitUnicodeString( &g_CDO_dev_name, AL_DEVICE_NAME );
 		RtlInitUnicodeString( &g_CDO_dos_name, L"\\DosDevices\\Global\\ibal" );
+        RtlInitUnicodeString( &g_IbatDosName, IBAT_DOS_DEV_NAME );
 	
 		status = IoCreateDevice( p_ext->p_driver_obj, sizeof(bus_fdo_ext_t),
 			&g_CDO_dev_name, FILE_DEVICE_BUS_EXTENDER,
@@ -647,6 +649,19 @@ fdo_start(
 				unlock_control_event();
 				goto err;
 			}
+
+            /* Route IBAT IOCTLs to the same device object as IBAL. */
+            IoDeleteSymbolicLink( &g_IbatDosName );
+            status = IoCreateSymbolicLink( &g_IbatDosName, &g_CDO_dev_name );
+            if( !NT_SUCCESS(status) )
+            {
+                BUS_PRINT( BUS_DBG_ERROR,
+                    ("Failed to create symlink for IBAT dos name.\n") );
+                IoDeleteDevice( g_ControlDeviceObject );
+                g_ControlDeviceObject = NULL;
+                unlock_control_event();
+                goto err;
+            }
 			BUS_TRACE( BUS_DBG_PNP, ("Created dos_name symlink\n") );
 		}
 	}
@@ -841,7 +856,6 @@ fdo_stop_device(
 		return;
 	}
 
-		
 	bus_globals.started--;
 	p_ext->fdo_started = FALSE;
 
@@ -865,6 +879,7 @@ fdo_stop_device(
  	if ( ic == 1 && g_ControlDeviceObject )
 	{
 		IoDeleteSymbolicLink( &g_CDO_dos_name );
+		IoDeleteSymbolicLink( &g_IbatDosName );
 		IoDeleteDevice(g_ControlDeviceObject);
 		g_ControlDeviceObject = NULL; 
 	}
@@ -1373,6 +1388,12 @@ __set_ifc(
 	
 	p_ifc->open_al_trk = ib_open_al_trk;
 
+    p_ifc->ibat_register = IbatRegister;
+    p_ifc->ibat_deregister = IbatDeregister;
+    p_ifc->ibat_update_reg = IbatUpdateRegistration;
+    p_ifc->ibat_update_route = IbatUpdateRoute;
+    p_ifc->ibat_clear_all_routes = IbatClearAllRoutes;
+
 	BUS_EXIT( BUS_DBG_PNP );
 }
 
@@ -1485,6 +1506,48 @@ __query_cm_ifc(
 	return STATUS_SUCCESS;
 }
 
+
+static NTSTATUS
+__query_ibat_ifc(
+    IN              DEVICE_OBJECT* const        p_dev_obj,
+    IN              IO_STACK_LOCATION* const    p_io_stack )
+{
+    IBAT_IFC* p_ifc;
+
+    BUS_ENTER( BUS_DBG_PNP );
+
+    if( p_io_stack->Parameters.QueryInterface.Version != IBAT_INTERFACE_VERSION )
+    {
+        BUS_TRACE_EXIT( BUS_DBG_PNP, ("Incorrect interface version (%d)\n",
+            p_io_stack->Parameters.QueryInterface.Version ) );
+        return STATUS_NOT_SUPPORTED;
+    }
+
+    if( p_io_stack->Parameters.QueryInterface.Size < sizeof(IBAT_IFC) )
+    {
+        BUS_TRACE_EXIT( BUS_DBG_PNP, 
+            ("Buffer too small (%d given, %d required).\n",
+            p_io_stack->Parameters.QueryInterface.Size, sizeof(IBAT_IFC)) );
+        return STATUS_BUFFER_TOO_SMALL;
+    }
+
+    /* Copy the interface. */
+    p_ifc = (IBAT_IFC*)p_io_stack->Parameters.QueryInterface.Interface;
+
+    p_ifc->InterfaceHeader.Size = sizeof(IBAT_IFC);
+    p_ifc->InterfaceHeader.Version = IBAT_INTERFACE_VERSION;
+    p_ifc->InterfaceHeader.Context = p_dev_obj;
+    p_ifc->InterfaceHeader.InterfaceReference = al_ref_ifc;
+    p_ifc->InterfaceHeader.InterfaceDereference = al_deref_ifc;
+    IbatGetInterface(p_ifc);
+
+    /* take the reference before returning. */
+    al_ref_ifc( p_dev_obj );
+    BUS_EXIT( BUS_DBG_PNP );
+    return STATUS_SUCCESS;
+}
+
+
 static NTSTATUS
 fdo_query_pnp_state(
 	IN				DEVICE_OBJECT* const		p_dev_obj,
@@ -1537,6 +1600,11 @@ fdo_query_interface(
 	{
 		status = __query_cm_ifc( p_dev_obj, p_io_stack );
 	}
+	else if( IsEqualGUID( p_io_stack->Parameters.QueryInterface.InterfaceType,
+		&GUID_IBAT_INTERFACE ) )
+	{
+		status = __query_ibat_ifc( p_dev_obj, p_io_stack );
+	}
 	else
 	{
 		status = p_irp->IoStatus.Status;
diff -dwup3 -X excl.txt -r c:\dev\openib\ofw\gen1\branches\mlx4_30\trunk\core\bus\kernel\bus_port_mgr.c .\core\bus\kernel\bus_port_mgr.c
--- c:\dev\openib\ofw\gen1\branches\mlx4_30\trunk\core\bus\kernel\bus_port_mgr.c	Tue Aug 07 12:37:23 2012
+++ .\core\bus\kernel\bus_port_mgr.c	Thu Jul 26 16:38:31 2012
@@ -33,7 +33,6 @@
 #include <initguid.h>
 #include <wdmguid.h>
 #include "iba/ipoib_ifc.h"
-#include "public.h"
 
 
 /* {5A9649F4-0101-4a7c-8337-796C48082DA2} */
@@ -2128,12 +2127,6 @@ port_query_interface(
 		status = port_query_ipoib_ifc( p_dev_obj, p_io_stack );
 	}
 	else 
-	// forward down the stack 
-	if( IsEqualGUID( p_io_stack->Parameters.QueryInterface.InterfaceType, &GUID_BUS_INTERFACE_STANDARD ) || 
-		IsEqualGUID( p_io_stack->Parameters.QueryInterface.InterfaceType, &GUID_RDMA_INTERFACE_VERBS ) || 
-		IsEqualGUID( p_io_stack->Parameters.QueryInterface.InterfaceType, &MLX4_BUS_IB_INTERFACE_GUID ) ||
-		IsEqualGUID( p_io_stack->Parameters.QueryInterface.InterfaceType, &GUID_INFINIBAND_INTERFACE_CM ) ||
-		IsEqualGUID( p_io_stack->Parameters.QueryInterface.InterfaceType, &MLX4_BUS_NOTIFY_GUID ) )
 	{
 		p_ext = p_dev_obj->DeviceExtension;
 		if( !p_ext->h_ca ||
@@ -2147,7 +2140,11 @@ port_query_interface(
 		status = cl_fwd_query_ifc(
 			p_ext->h_ca->p_hca_dev, p_io_stack );
 	}
-	else
+
+    //
+    // Verifier assertion - if not supported, do not change status.
+    //
+    if( status == STATUS_NOT_SUPPORTED )
 	{
 		status = p_irp->IoStatus.Status;
 	}
diff -dwup3 -X excl.txt -r c:\dev\openib\ofw\gen1\branches\mlx4_30\trunk\core\ibat\user\ibat.cpp .\core\ibat\user\ibat.cpp
--- c:\dev\openib\ofw\gen1\branches\mlx4_30\trunk\core\ibat\user\ibat.cpp	Thu May 31 11:22:15 2012
+++ .\core\ibat\user\ibat.cpp	Wed May 23 18:26:47 2012
@@ -69,318 +69,91 @@ C_ASSERT( sizeof(IBAT_PATH_BLOB) == size
 namespace IBAT
 {
 
-    const IN6_ADDR x_DefaultGid = {0xFE,0x80,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
-
-class H
-{
-public:
-    H( HANDLE h = INVALID_HANDLE_VALUE ) : m_h( h ) {};
-    ~H(){ if( m_h != INVALID_HANDLE_VALUE ) CloseHandle( m_h ); }
-
-    H& operator =(HANDLE h){ CloseHandle( m_h ); m_h = h; }
-    operator HANDLE() const { return m_h; }
-
-private:
-    HANDLE m_h;
-};
-
-#if WINVER >= 0x600
+//
+// Summary:
+//  Utility method to send IoControl messages to IBAT
+//
 HRESULT
-Resolve(
-    __in const struct sockaddr* pSrcAddr,
-    __in const struct sockaddr* pDestAddr,
-    __out IBAT_PATH_BLOB* pPath
+IoControl(
+  __in         DWORD dwIoControlCode,
+  __in_opt     LPVOID lpInBuffer,
+  __in         DWORD nInBufferSize,
+  __out_opt    LPVOID lpOutBuffer,
+  __in         DWORD nOutBufferSize,
+  __out_opt    LPDWORD lpBytesReturned
     )
 {
-    if( pSrcAddr->sa_family != pDestAddr->sa_family )
-        return E_INVALIDARG;
-
-    H hIbatDev = CreateFileW( IBAT_WIN32_NAME,
-        MAXIMUM_ALLOWED,(FILE_SHARE_READ|FILE_SHARE_WRITE), NULL,
-        OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL );
-    if( hIbatDev == INVALID_HANDLE_VALUE )
-        return HRESULT_FROM_WIN32( GetLastError() );
-
-    bool fLoopback;
-    IOCTL_IBAT_IP_TO_PORT_IN port_in;
-    port_in.Version = IBAT_IOCTL_VERSION;
-    if( pSrcAddr->sa_family == AF_INET )
-    {
-        port_in.Address.IpVersion = 4;
-        RtlCopyMemory(
-            &port_in.Address.Address[12],
-            &((struct sockaddr_in*)pSrcAddr)->sin_addr,
-            sizeof( ((struct sockaddr_in*)pSrcAddr)->sin_addr ) );
+    HRESULT hr = S_OK;
+    HANDLE hIbat;
+    BOOL fSuccess;
 
-        fLoopback = ((struct sockaddr_in*)pDestAddr)->sin_addr.s_addr ==
-            ((struct sockaddr_in*)pSrcAddr)->sin_addr.s_addr;
-    }
-    else
+    hIbat = ::CreateFileW(
+        IBAT_WIN32_NAME,
+        MAXIMUM_ALLOWED,(FILE_SHARE_READ|FILE_SHARE_WRITE),
+        NULL,
+        OPEN_EXISTING,
+        FILE_ATTRIBUTE_NORMAL,
+        NULL
+        );
+    if( hIbat == INVALID_HANDLE_VALUE )
     {
-        port_in.Address.IpVersion = 6;
-        RtlCopyMemory(
-            port_in.Address.Address,
-            &((struct sockaddr_in6*)pSrcAddr)->sin6_addr,
-            sizeof(port_in.Address.Address) );
-        fLoopback = IN6_ADDR_EQUAL(
-            &((struct sockaddr_in6*)pDestAddr)->sin6_addr,
-            &((struct sockaddr_in6*)pSrcAddr)->sin6_addr
-            ) == TRUE;
-    }
-
-    IBAT_PORT_RECORD port_out;
-    DWORD size;
-    BOOL fSuccess = DeviceIoControl( hIbatDev, IOCTL_IBAT_IP_TO_PORT,
-        &port_in, sizeof(port_in), &port_out, sizeof(port_out), &size, NULL );
-
-    if( !fSuccess )
         return HRESULT_FROM_WIN32( GetLastError() );
-
-    // Check for loopback.
-    IOCTL_IBAT_MAC_TO_PATH_IN mac_in = {0};
-    mac_in.Version = IBAT_IOCTL_VERSION;
-    mac_in.PortGuid = port_out.PortGuid;
-    if( !fLoopback )
-    {
-        NET_LUID luid;
-        DWORD ret;
-        do
-        {
-            DWORD iIf;
-            ret = GetBestInterfaceEx( (struct sockaddr*)pSrcAddr, &iIf );
-            if( ret != NO_ERROR )
-                return HRESULT_FROM_WIN32( ret );
-
-            // Interface indexes are not constant, so get the LUID mapping for the
-            // returned interface for use in the rest of the function.
-            ret = ConvertInterfaceIndexToLuid( iIf, &luid );
-
-        } while( ret != NO_ERROR );
-
-        SOCKADDR_INET src;
-        MIB_IPNET_ROW2 net = {0};
-        net.InterfaceLuid = luid;
-        switch( pDestAddr->sa_family )
-        {
-        case AF_INET:
-            net.Address.si_family = src.si_family = AF_INET;
-            net.Address.Ipv4 = *(struct sockaddr_in*)pDestAddr;
-            src.Ipv4 = *(struct sockaddr_in*)pSrcAddr;
-            break;
-
-        case AF_INET6:
-            net.Address.si_family = src.si_family = AF_INET6;
-            net.Address.Ipv6 = *(struct sockaddr_in6*)pDestAddr;
-            src.Ipv6 = *(struct sockaddr_in6*)pSrcAddr;
-            break;
-
-        default:
-            return E_INVALIDARG;
-        }
-
-        bool fRetry = true;
-    retry:
-        ret = GetIpNetEntry2( &net );
-        if( ret == ERROR_NOT_FOUND )
-        {
-            net.State = NlnsUnreachable;
-        }
-        else if( ret != NO_ERROR )
-        {
-            return HRESULT_FROM_WIN32( ret );
         }
 
-        switch( net.State )
-        {
-        default:
-        case NlnsUnreachable:
-            ret = ResolveIpNetEntry2( &net, &src );
-            if( ret == ERROR_BAD_NET_NAME && fRetry )
-            {
-                fRetry = false;
-                goto retry;
-            }
-            else if( ret != NO_ERROR )
+    fSuccess  = ::DeviceIoControl(
+        hIbat,
+        dwIoControlCode,
+        lpInBuffer,
+        nInBufferSize,
+        lpOutBuffer,
+        nOutBufferSize,
+        lpBytesReturned,
+        NULL
+        );
+    if( FALSE == fSuccess )
             {
-                return HRESULT_FROM_WIN32( ret );
-            }
-            break;
-
-        case NlnsReachable:
-        case NlnsPermanent:
-            break;
-
-        case NlnsIncomplete:
-            return E_PENDING;
-        }
-
-        if( net.PhysicalAddressLength > 6 )
-            return E_UNEXPECTED;
-
-        RtlCopyMemory( mac_in.DestMac, net.PhysicalAddress, IBAT_MAC_LEN );
+        hr = HRESULT_FROM_WIN32( ::GetLastError() );
     }
-
-    fSuccess = DeviceIoControl( hIbatDev, IOCTL_IBAT_MAC_TO_PATH,
-        &mac_in, sizeof(mac_in), pPath, sizeof(*pPath), &size, NULL );
-    if( !fSuccess )
-        return HRESULT_FROM_WIN32( GetLastError() );
-
-    return S_OK;
+    ::CloseHandle(hIbat);
+    return hr;
 }
-#else   // Back compatibility with Windows Server 2003
 
 
-static HRESULT
-GetDestMac(
-    __in struct sockaddr_in* pDestAddr,
-    __out BYTE* pDestMac
+HRESULT
+QueryPath(
+    __in const struct sockaddr* pSrcAddr,
+    __in const struct sockaddr* pDestAddr,
+    __out IBAT_PATH_BLOB* pPath
     )
 {
-    DWORD ret;
-
-    MIB_IPNETTABLE* pTable = NULL;
-    ULONG len = 0;
-    do
-    {
-        ret = GetIpNetTable( pTable, &len, FALSE );
-        if( ret != ERROR_INSUFFICIENT_BUFFER )
-            break;
-
-        if( pTable != NULL )
-        {
-            HeapFree( GetProcessHeap(), 0, pTable );
-        }
-
-        pTable = (MIB_IPNETTABLE*)HeapAlloc( GetProcessHeap(), 0, len );
-    } while( ret == ERROR_INSUFFICIENT_BUFFER );
+    IOCTL_IBAT_QUERY_PATH_IN queryIn = {};
+    queryIn.Version = IBAT_IOCTL_VERSION;
 
-    if( ret != NO_ERROR )
-    {
-        if( pTable != NULL )
+    if( AF_INET == pSrcAddr->sa_family )
         {
-            HeapFree( GetProcessHeap(), 0, pTable );
-        }
-        return HRESULT_FROM_WIN32( ret );
+        queryIn.LocalAddress.Ipv4 = *reinterpret_cast<const sockaddr_in*>(pSrcAddr);
     }
-
-    ret = ERROR_NOT_SUPPORTED;
-    DWORD i;
-    for( i = 0; i < pTable->dwNumEntries; i++ )
-    {
-        if( pTable->table[i].dwType == MIB_IPNET_TYPE_OTHER ||
-            pTable->table[i].dwType == MIB_IPNET_TYPE_INVALID )
+    else
         {
-            continue;
+        queryIn.LocalAddress.Ipv6 = *reinterpret_cast<const sockaddr_in6*>(pSrcAddr);
         }
 
-        if( pTable->table[i].dwAddr !=
-            ((struct sockaddr_in*)pDestAddr)->sin_addr.s_addr )
+    if( AF_INET == pDestAddr->sa_family )
         {
-            continue;
+        queryIn.RemoteAddress.Ipv4 = *reinterpret_cast<const sockaddr_in*>(pDestAddr);
         }
-
-        if( pTable->table[i].dwPhysAddrLen != IBAT_MAC_LEN )
+    else
         {
-            continue;
-        }
-
-        RtlCopyMemory( pDestMac, pTable->table[i].bPhysAddr, IBAT_MAC_LEN );
-        ret = S_OK;
-        break;
-    }
-    HeapFree( GetProcessHeap(), 0, pTable );
-
-    return HRESULT_FROM_WIN32( ret );
+        queryIn.RemoteAddress.Ipv6 = *reinterpret_cast<const sockaddr_in6*>(pDestAddr);
 }
 
-HRESULT
-Resolve(
-    __in const struct sockaddr* pSrcAddr,
-    __in const struct sockaddr* pDestAddr,
-    __out IBAT_PATH_BLOB* pPath
-    )
-{
-    if( pDestAddr->sa_family != AF_INET )
-        return E_NOTIMPL;
-
-    H hIbatDev = CreateFileW( IBAT_WIN32_NAME,
-        MAXIMUM_ALLOWED,(FILE_SHARE_READ|FILE_SHARE_WRITE), NULL,
-        OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL );
-    if( hIbatDev == INVALID_HANDLE_VALUE )
-        return HRESULT_FROM_WIN32( GetLastError() );
-
-    IOCTL_IBAT_IP_TO_PORT_IN port_in;
-    port_in.Version = IBAT_IOCTL_VERSION;
-    port_in.Address.IpVersion = 4;
-    RtlCopyMemory(
-        &port_in.Address.Address[12],
-        &((struct sockaddr_in*)pSrcAddr)->sin_addr,
-        sizeof( ((struct sockaddr_in*)pSrcAddr)->sin_addr ) );
-
-    IBAT_PORT_RECORD port_out;
-    DWORD size;
-    BOOL fSuccess = DeviceIoControl( hIbatDev, IOCTL_IBAT_IP_TO_PORT,
-        &port_in, sizeof(port_in), &port_out, sizeof(port_out), &size, NULL );
-
-    if( !fSuccess )
-        return HRESULT_FROM_WIN32( GetLastError() );
-
-    // Check for loopback.
-    IOCTL_IBAT_MAC_TO_GID_IN mac_in = {0};
-    mac_in.Version = IBAT_IOCTL_VERSION;
-    mac_in.PortGuid = port_out.PortGuid;
-
-    if( ((struct sockaddr_in*)pDestAddr)->sin_addr.s_addr !=
-        ((struct sockaddr_in*)pSrcAddr)->sin_addr.s_addr )
-    {
-        HRESULT hr = GetDestMac( (struct sockaddr_in*)pDestAddr, mac_in.DestMac );
-        if( FAILED( hr ) )
-        {
-            ULONG len = sizeof(mac_in.DestMac);
-            DWORD ret = SendARP(
-                ((struct sockaddr_in*)pDestAddr)->sin_addr.s_addr,
-                ((struct sockaddr_in*)pSrcAddr)->sin_addr.s_addr,
-                (ULONG*)mac_in.DestMac,
-                &len
+    return IBAT::IoControl(
+                    IOCTL_IBAT_QUERY_PATH,
+                    queryIn,
+                    pPath
                 );
-            if( ret != NO_ERROR )
-                return HRESULT_FROM_WIN32( ret );
-        }
-    }
-
-    fSuccess = DeviceIoControl( hIbatDev, IOCTL_IBAT_MAC_TO_PATH,
-        &mac_in, sizeof(mac_in), pPath, sizeof(*pPath), &size, NULL );
-    if( !fSuccess )
-        return HRESULT_FROM_WIN32( GetLastError() );
-
-    return S_OK;
 }
 
-#endif // WINVER >= 0x600
-
-
-HRESULT
-ResolvePath(
-    __in const struct sockaddr* pSrcAddr,
-    __in const struct sockaddr* pDestAddr,
-    __out IBAT_PATH_BLOB* pPath,
-	__in DWORD Timeout)
-{
-	INT64 to;
-	HRESULT hr;
-
-	to = (Timeout == INFINITE) ? 0x7FFFFFFFFFFFFFFFL : (INT64) ((UINT64) Timeout);
-	for (;;) {
-		hr = Resolve(pSrcAddr, pDestAddr, pPath);
-		if( hr != E_PENDING || to <= 0 )
-			break;
-
-		to -= 10;
-		Sleep(10);
-	};
-
-	return hr;
-}
 
 } /* IBAT namespace */
 
@@ -388,23 +161,13 @@ extern "C"
 {
 
 HRESULT
-IbatResolve(
+IbatQueryPath(
     __in const struct sockaddr* pSrcAddr,
     __in const struct sockaddr* pDestAddr,
     __out IBAT_PATH_BLOB* pPath
     )
 {
-    return IBAT::Resolve( pSrcAddr, pDestAddr, pPath );
-}
-
-HRESULT
-IbatResolvePath(
-    __in const struct sockaddr* pSrcAddr,
-    __in const struct sockaddr* pDestAddr,
-    __out IBAT_PATH_BLOB* pPath,
-	__in DWORD Timeout)
-{
-	return IBAT::ResolvePath(pSrcAddr, pDestAddr, pPath, Timeout);
+    return IBAT::QueryPath(pSrcAddr, pDestAddr, pPath);
 }
 
 } /* extern "C" */
diff -dwup3 -X excl.txt -r c:\dev\openib\ofw\gen1\branches\mlx4_30\trunk\core\winverbs\user\wv_provider.cpp .\core\winverbs\user\wv_provider.cpp
--- c:\dev\openib\ofw\gen1\branches\mlx4_30\trunk\core\winverbs\user\wv_provider.cpp	Thu Mar 29 00:15:18 2012
+++ .\core\winverbs\user\wv_provider.cpp	Thu Sep 29 11:42:26 2011
@@ -35,7 +35,6 @@
 #include "wv_device.h"
 #include "wv_ep.h"
 #include "wv_ioctl.h"
-#include <iba/ibat_ex.h>
 
 CWVProvider::CWVProvider()
 {
@@ -137,14 +136,38 @@ out:
 STDMETHODIMP CWVProvider::
 TranslateAddress(const SOCKADDR* pAddress, WV_DEVICE_ADDRESS* pDeviceAddress)
 {
+	HANDLE hIbat;
+	IOCTL_IBAT_IP_TO_PORT_IN addr;
 	IBAT_PORT_RECORD port;
-	HRESULT hr = IBAT_EX::IpToPort( pAddress, &port );
-	if ( FAILED( hr ) )
-		return hr;
+	DWORD bytes;
+	HRESULT hr;
+
+	hIbat = CreateFileW(IBAT_WIN32_NAME, GENERIC_READ | GENERIC_WRITE,
+						FILE_SHARE_READ | FILE_SHARE_WRITE, NULL,
+						OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
+	if (hIbat == INVALID_HANDLE_VALUE) {
+		return HRESULT_FROM_WIN32(GetLastError());
+	}
+
+	addr.Version = IBAT_IOCTL_VERSION;
+	if (pAddress->sa_family == AF_INET) {
+        addr.Address.Ipv4 = *reinterpret_cast<const SOCKADDR_IN*>(pAddress);
+	} else {
+        addr.Address.Ipv6 = *reinterpret_cast<const SOCKADDR_IN6*>(pAddress);
+	}
+
+	if (DeviceIoControl(hIbat, IOCTL_IBAT_IP_TO_PORT,
+						&addr, sizeof addr, &port, sizeof port, &bytes, NULL)) {
+		hr = WV_SUCCESS;
 	pDeviceAddress->DeviceGuid = port.CaGuid;
 	pDeviceAddress->Pkey = port.PKey;
 	pDeviceAddress->PortNumber = port.PortNum;
-	return WV_SUCCESS;
+	} else {
+		hr = HRESULT_FROM_WIN32(GetLastError());
+	}
+
+	CloseHandle(hIbat);
+	return hr;
 }
 
 STDMETHODIMP CWVProvider::
diff -dwup3 -X excl.txt -r c:\dev\openib\ofw\gen1\branches\mlx4_30\trunk\inc\iba\ib_al_ioctl.h .\inc\iba\ib_al_ioctl.h
--- c:\dev\openib\ofw\gen1\branches\mlx4_30\trunk\inc\iba\ib_al_ioctl.h	Thu May 31 11:22:18 2012
+++ .\inc\iba\ib_al_ioctl.h	Fri Aug 03 14:21:53 2012
@@ -3475,13 +3475,13 @@ typedef struct _ual_ndi_req_cm_ioctl_in
 {
 	ib_path_rec_t				path;
 	uint64_t					h_qp;
-	net64_t						guid;
+    uint64_t                    src_mac;
+    uint64_t                    dest_mac;
 	net32_t						cid;
 	net16_t						dst_port;
 	uint8_t						resp_res;
 	uint8_t						init_depth;
 	uint8_t						prot;
-	enum rdma_transport_type	transport;
 	uint8_t						pdata_size;
 	ib_cm_rdma_req_t			pdata;
 
@@ -3491,11 +3491,21 @@ typedef struct _ual_ndi_req_cm_ioctl_in
 *	There is no output parameter.
 *
 * FIELDS
+*   path
+*       IB path record (reserved for internal use only)
+*
 *	h_qp
 *		A handle to the QP to modify.
 *
-*	guid
-*		Local port GUID to which to bind to.
+*   src_mac
+*       Local MAC address of the local HCA port to which to bind to.
+*       When IOCTL is dispatched from user mode, this field is reserved. It will
+*         be derived in the kernel from pdata.src_ip_addr
+*
+*   dest_mac
+*       The MAC address assigned to the remote host
+*       When IOCTL is dispatched from user mode, this field is reserved. It will
+*         be derived in the kernel from pdata.dst_ip_addr
 *
 *	cid
 *		CID of the CEP to use for the connection request.
@@ -3503,9 +3513,6 @@ typedef struct _ual_ndi_req_cm_ioctl_in
 *	dst_port
 *		Destination port number.
 *
-*   path
-*       Path record for the connection.
-*
 *   resp_res
 *       Responder resources for the QP.
 *
diff -dwup3 -X excl.txt -r c:\dev\openib\ofw\gen1\branches\mlx4_30\trunk\inc\iba\ib_at_ioctl.h .\inc\iba\ib_at_ioctl.h
--- c:\dev\openib\ofw\gen1\branches\mlx4_30\trunk\inc\iba\ib_at_ioctl.h	Thu May 31 11:22:18 2012
+++ .\inc\iba\ib_at_ioctl.h	Thu Jul 26 15:31:14 2012
@@ -35,10 +35,16 @@
 #ifndef	_IB_AT_IOCTL_H_
 #define	_IB_AT_IOCTL_H_
 
+
 #include <iba/ib_types.h>
 
+#ifdef _WDMDDK_
+#include <Netioapi.h>
+#else
+#include <ws2tcpip.h>
+#endif
 
-#define	IBAT_IOCTL_VERSION		5
+#define IBAT_IOCTL_VERSION      6
 
 #define	IBAT_MAC_LEN			6
 
@@ -47,9 +53,6 @@
 	CTL_CODE( FILE_DEVICE_UNKNOWN, (0x800 + n), \
 		METHOD_BUFFERED, FILE_ANY_ACCESS )
 
-/** This IRP is used to return all available CAs ports number
- * and port guid */
-#define	IOCTL_IBAT_PORTS	IOCTL_IBAT( 1 )
 
 typedef struct _IBAT_PORT_RECORD
 {
@@ -60,22 +63,6 @@ typedef struct _IBAT_PORT_RECORD
 
 } IBAT_PORT_RECORD;
 
-typedef struct _IOCTL_IBAT_PORTS_IN
-{
-	ULONG				Version;
-
-} IOCTL_IBAT_PORTS_IN;
-
-typedef struct _IOCTL_IBAT_PORTS_OUT
-{
-	/** Total size, of the output buffer needed if the
-	 * suplied buffer wasn't enough */
-	ULONG				Size;
-	LONG				NumPorts;
-	IBAT_PORT_RECORD	Ports[1];
-
-} IOCTL_IBAT_PORTS_OUT;
-
 
 /** This IRP is used to return all the ip addresses that
  * are assigned to a port */
@@ -90,42 +77,17 @@ typedef struct _IOCTL_IBAT_IP_ADDRESSES_
 
 } IOCTL_IBAT_IP_ADDRESSES_IN;
 
-typedef struct _IP_ADDRESS
-{
-	/** Might only be 4 or 6 */
-	CHAR				IpVersion;
-	/** Sized to support both IPv4 and IPv6 */
-	UCHAR				Address[16];
-
-} IP_ADDRESS;
-
 typedef struct _IOCTL_IBAT_IP_ADDRESSES_OUT
 {
 	/** Total size of the output buffer needed if the
 	 * suplied buffer wasn't enough */
 	ULONG				Size;
-	LONG				AddressCount;
-	IP_ADDRESS			Address[1];
+    ULONG               AddressCount;
+    SOCKADDR_INET       Address[1];
 
 } IOCTL_IBAT_IP_ADDRESSES_OUT;
 
 
-/** This IRP is used to convert a remote MAC addresses to a remote GID */
-#define	IOCTL_IBAT_MAC_TO_GID IOCTL_IBAT( 3 )
-
-typedef struct _IOCTL_IBAT_MAC_TO_GID_IN
-{
-	ULONG				Version;
-	UINT64				PortGuid;
-	UCHAR				DestMac[IBAT_MAC_LEN];
-
-} IOCTL_IBAT_MAC_TO_GID_IN;
-
-typedef struct _IOCTL_IBAT_MAC_TO_GID_OUT
-{
-	ib_gid_t			DestGid;
-
-} IOCTL_IBAT_MAC_TO_GID_OUT;
 
 /** This IRP is used to get port record, corresponding to its (loca) IP address */
 #define	IOCTL_IBAT_IP_TO_PORT		IOCTL_IBAT( 4 )
@@ -133,7 +95,7 @@ typedef struct _IOCTL_IBAT_MAC_TO_GID_OU
 typedef struct _IOCTL_IBAT_IP_TO_PORT_IN
 {
 	ULONG				Version;
-	IP_ADDRESS			Address;
+    SOCKADDR_INET       Address;
 
 } IOCTL_IBAT_IP_TO_PORT_IN;
 
@@ -144,22 +106,19 @@ typedef struct _IOCTL_IBAT_IP_TO_PORT_OU
 } IOCTL_IBAT_IP_TO_PORT_OUT;
 
 
-/** This IRP is used to convert a remote MAC addresses to a remote GID */
-#define	IOCTL_IBAT_MAC_TO_PATH IOCTL_IBAT( 5 )
 
-typedef struct _IOCTL_IBAT_MAC_TO_PATH_IN
+/** This IRP is used as a batch routine to do all path resolution in the kernal */
+#define IOCTL_IBAT_QUERY_PATH IOCTL_IBAT( 6 )
+
+typedef struct _IOCTL_IBAT_QUERY_PATH_IN
 {
 	ULONG				Version;
-	UINT64				PortGuid;
-	UCHAR				DestMac[IBAT_MAC_LEN];
-
-} IOCTL_IBAT_MAC_TO_PATH_IN;
+    SOCKADDR_INET           LocalAddress;
+    SOCKADDR_INET           RemoteAddress;
 
-typedef struct _IOCTL_IBAT_MAC_TO_PATH_OUT
-{
-	ib_path_rec_t		Path;
+} IOCTL_IBAT_QUERY_PATH_IN;
 
-} IOCTL_IBAT_MAC_TO_PATH_OUT;
+typedef ib_path_rec_t  IOCTL_IBAT_QUERY_PATH_OUT;
 
 /** This IRP is used to remove a remote MAC addresses from our endpoint DB */
 #define	IOCTL_IBAT_REMOVE_REMOTE_MAC IOCTL_IBAT( 6 )
diff -dwup3 -X excl.txt -r c:\dev\openib\ofw\gen1\branches\mlx4_30\trunk\inc\kernel\iba\ib_al_ifc.h .\inc\kernel\iba\ib_al_ifc.h
--- c:\dev\openib\ofw\gen1\branches\mlx4_30\trunk\inc\kernel\iba\ib_al_ifc.h	Thu May 31 11:22:17 2012
+++ .\inc\kernel\iba\ib_al_ifc.h	Thu Jul 26 15:31:14 2012
@@ -35,6 +35,7 @@
 
 
 #include <iba/ib_al.h>
+#include <iba\ibat.h>
 
 
 /****h* Access Layer/AL Interface
@@ -817,6 +818,12 @@ typedef struct _ib_al_ifc
 	ib_net64_t					ca_guid;
 	ib_pfn_to_ntstatus_t		to_ntstatus;
 
+    FN_IBAT_REGISTER*           ibat_register;
+    FN_IBAT_DEREGISTER*         ibat_deregister;
+    FN_IBAT_UPDATE_REGISTRATION* ibat_update_reg;
+    FN_IBAT_UPDATE_ROUTE*       ibat_update_route;
+    FN_IBAT_CLEAR_ALL_ROUTES*   ibat_clear_all_routes;
+
 	ib_ref_al_obj_t				ib_ref_al_obj;
 	ib_deref_al_obj_t			ib_deref_al_obj;
 
diff -dwup3 -X excl.txt -r c:\dev\openib\ofw\gen1\branches\mlx4_30\trunk\inc\user\iba\ibat.h .\inc\user\iba\ibat.h
--- c:\dev\openib\ofw\gen1\branches\mlx4_30\trunk\inc\user\iba\ibat.h	Thu May 31 11:22:18 2012
+++ .\inc\user\iba\ibat.h	Wed May 23 18:26:48 2012
@@ -44,36 +44,59 @@ namespace IBAT
 {
 
 HRESULT
-Resolve(
-    __in const struct sockaddr* pSrcAddr,
-    __in const struct sockaddr* pDestAddr,
-    __out IBAT_PATH_BLOB* pPath
+IoControl(
+  __in         DWORD dwIoControlCode,
+  __in_opt     LPVOID lpInBuffer,
+  __in         DWORD nInBufferSize,
+  __out_opt    LPVOID lpOutBuffer,
+  __in         DWORD nOutBufferSize,
+  __out_opt    LPDWORD lpBytesReturned
     );
 
-HRESULT
-ResolvePath(
-    __in const struct sockaddr* pSrcAddr,
-    __in const struct sockaddr* pDestAddr,
-    __out IBAT_PATH_BLOB* pPath,
-	__in DWORD Timeout	/* ms */
-    );
 
+template<typename InT, typename OutT>
+HRESULT  IoControl(
+    __in  DWORD               dwIoControlCode,
+    __in  const InT&          input,
+    __out OutT*               pOutput
+    )
+{
+    DWORD cb;
+    HRESULT hr = IBAT::IoControl(
+                dwIoControlCode,
+                (VOID*)&input,
+                sizeof(input),
+                (VOID*)pOutput,
+                sizeof(*pOutput),
+                &cb
+                );
+    if( SUCCEEDED( hr ) )
+    {
+        if( cb < sizeof( *pOutput ) )
+        {
+            return HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER);
 }
-#else /* __cplusplus */
+    }
+    return hr;
+}
+
 
 HRESULT
-IbatResolve(
+QueryPath(
     __in const struct sockaddr* pSrcAddr,
     __in const struct sockaddr* pDestAddr,
     __out IBAT_PATH_BLOB* pPath
     );
 
+}
+#else /* __cplusplus */
+
+
 HRESULT
-IbatResolvePath(
+IbatQueryPath(
     __in const struct sockaddr* pSrcAddr,
     __in const struct sockaddr* pDestAddr,
-    __out IBAT_PATH_BLOB* pPath,
-	__in DWORD Timeout	/* ms */
+    __out IBAT_PATH_BLOB* pPath
     );
 
 #endif /* __cplusplus */
diff -dwup3 -X excl.txt -r c:\dev\openib\ofw\gen1\branches\mlx4_30\trunk\ulp\ipoib\kernel\ipoib_adapter.cpp .\ulp\ipoib\kernel\ipoib_adapter.cpp
--- c:\dev\openib\ofw\gen1\branches\mlx4_30\trunk\ulp\ipoib\kernel\ipoib_adapter.cpp	Thu May 31 11:22:12 2012
+++ .\ulp\ipoib\kernel\ipoib_adapter.cpp	Thu Jul 26 15:31:14 2012
@@ -351,8 +351,6 @@ adapter_construct(
 
 	cl_thread_construct(&p_adapter->destroy_thread);
 	
-	cl_vector_construct( &p_adapter->ip_vector );
-
 	cl_perf_construct( &p_adapter->perf );
 
 	p_adapter->state = IB_PNP_PORT_ADD;
@@ -402,17 +400,6 @@ adapter_init(
 		return IB_ERROR;
 	}
 
-	/* We manually manage the size and capacity of the vector. */
-	cl_status = cl_vector_init( &p_adapter->ip_vector, 0,
-		0, sizeof(net_address_item_t), NULL, NULL, p_adapter );
-	if( cl_status != CL_SUCCESS )
-	{
-		IPOIB_PRINT_EXIT( TRACE_LEVEL_ERROR, IPOIB_DBG_ERROR,
-			("cl_vector_init for ip_vector returned %#x\n",
-			cl_status) );
-		return IB_ERROR;
-	}
-
 	/* Validate the port GUID and generate the MAC address. */
 	status = ipoib_mac_from_guid( p_adapter->guids.port_guid.guid,
 								  p_adapter->params.guid_mask,
@@ -570,7 +557,6 @@ __adapter_free(
 		p_adapter->p_ifc = NULL;
 	}
 
-	cl_vector_destroy( &p_adapter->ip_vector );
 	cl_qpool_destroy( &p_adapter->item_pool );
 	cl_spinlock_destroy( &p_adapter->recv_stat_lock );
 	cl_spinlock_destroy( &p_adapter->send_stat_lock );
@@ -1300,9 +1286,6 @@ ipoib_set_active(
 	switch( old_state )
 	{
 	case IB_PNP_PORT_ADD:
-		ipoib_reg_addrs( p_adapter );
-		/* Fall through. */
-
 	case IB_PNP_PORT_REMOVE:
 		ipoib_resume_oids( p_adapter );
 		break;
@@ -1329,9 +1312,6 @@ ipoib_set_active(
 		}
 		cl_spinlock_release( &p_adapter->p_port->send_lock );
 		
-		/* Register all existing addresses. */
-		ipoib_reg_addrs( p_adapter );
-
 		ipoib_resume_oids( p_adapter );
 
 		/*
diff -dwup3 -X excl.txt -r c:\dev\openib\ofw\gen1\branches\mlx4_30\trunk\ulp\ipoib\kernel\ipoib_adapter.h .\ulp\ipoib\kernel\ipoib_adapter.h
--- c:\dev\openib\ofw\gen1\branches\mlx4_30\trunk\ulp\ipoib\kernel\ipoib_adapter.h	Thu May 31 11:22:12 2012
+++ .\ulp\ipoib\kernel\ipoib_adapter.h	Thu Jul 26 15:31:14 2012
@@ -232,7 +232,6 @@ typedef struct _ipoib_adapter
 	KMUTEX					mutex;
 
 	cl_thread_t				destroy_thread;
-	cl_vector_t				ip_vector;
 
 	cl_perf_t				perf;
     NDIS_HANDLE  			NdisMiniportDmaHandle;
@@ -253,6 +252,8 @@ typedef struct _ipoib_adapter
 	NDK_HANDLE 				h_ndk;
 #endif
 
+    IBAT_ROUTING_CONTEXT    ibatRouter;
+
 }	ipoib_adapter_t;
 /*
 * FIELDS
@@ -355,50 +356,6 @@ typedef struct _ipoib_adapter
 *
 *********/
 
-
-typedef struct _ats_reg
-{
-	ipoib_adapter_t		*p_adapter;
-	ib_reg_svc_handle_t	h_reg_svc;
-
-}	ats_reg_t;
-/*
-* FIELDS
-*	p_adapter
-*		Pointer to the adapter to which this address is assigned.
-*
-*	h_reg_svc
-*		Service registration handle.
-*********/
-
-
-typedef struct _net_address_item
-{
-	ats_reg_t			*p_reg;
-	union _net_address_item_address
-	{
-		ULONG			as_ulong;
-		UCHAR			as_bytes[IPV4_ADDR_SIZE];
-	}	address;
-
-}	net_address_item_t;
-/*
-* FIELDS
-*	p_reg
-*		Pointer to the ATS registration assigned to this address.
-*
-*	address
-*		Union representing the IP address as an unsigned long or as
-*		an array of bytes.
-*
-*	as_ulong
-*		The IP address represented as an unsigned long.  Windows stores
-*		IPs this way.
-*
-*	as_bytes
-*		The IP address represented as an array of bytes.
-*********/
-
 static inline void ipoib_cnt_inc( PULONG p_cnt)
 {
 	++*p_cnt;
@@ -488,14 +445,6 @@ ipoib_set_inactive(
 
 ib_api_status_t
 ipoib_reset_adapter(
-	IN				ipoib_adapter_t* const		p_adapter );
-
-void
-ipoib_reg_addrs(
-	IN				ipoib_adapter_t* const		p_adapter );
-
-void
-ipoib_dereg_addrs(
 	IN				ipoib_adapter_t* const		p_adapter );
 
 #define IPOIB_INIT_NDIS_STATUS_INDICATION(_pStatusIndication, _M, _St, _Buf, _BufSize)        \
diff -dwup3 -X excl.txt -r c:\dev\openib\ofw\gen1\branches\mlx4_30\trunk\ulp\ipoib\kernel\ipoib_driver.cpp .\ulp\ipoib\kernel\ipoib_driver.cpp
--- c:\dev\openib\ofw\gen1\branches\mlx4_30\trunk\ulp\ipoib\kernel\ipoib_driver.cpp	Thu May 31 11:22:12 2012
+++ .\ulp\ipoib\kernel\ipoib_driver.cpp	Thu Jul 26 15:31:14 2012
@@ -40,7 +40,6 @@
 #endif
 
 #include "ipoib_port.h"
-#include "ipoib_ibat.h"
 #include <complib/cl_bus_ifc.h>
 #include <complib/cl_init.h>
 #include <initguid.h>
@@ -372,14 +371,6 @@ ipoib_complete_query(
 	IN		const	ULONG						buf_len );
 
 static NDIS_STATUS
-__ipoib_set_net_addr(
-	IN		ipoib_adapter_t *	p_adapter,
-	IN		PVOID				info_buf,
-	IN		ULONG				info_buf_len,
-		OUT	PULONG				p_bytes_read,
-		OUT	PULONG				p_bytes_needed );
-
-static NDIS_STATUS
 __ipoib_get_tcp_task_offload(
 	IN				ipoib_adapter_t*			p_adapter,
 	OUT				pending_oid_t				*pNdisRequest);
@@ -2070,6 +2061,34 @@ if(cl_get_time_stamp_sec() < 30) {
 			return NDIS_STATUS_FAILURE;
 		}
 
+        UINT64 mac = 0;
+        RtlCopyMemory( &mac, &p_adapter->mac, sizeof(p_adapter->mac) );
+
+        IBAT_PORT_RECORD rec;
+        rec.CaGuid = p_adapter->guids.ca_guid;
+        rec.PortGuid = p_adapter->guids.port_guid.guid;
+        rec.PortNum = p_adapter->guids.port_num;
+        rec.PKey = p_adapter->guids.port_guid.pkey;
+
+        status = p_adapter->p_ifc->ibat_register(
+            mac,
+            MiniportInitParameters->NetLuid.Value,
+            &p_adapter->guids.driver_id,
+            &rec,
+            FALSE,
+            &p_adapter->ibatRouter
+            );
+        if( !NT_SUCCESS(status) )
+        {
+#if  IPOIB_USE_DMA
+            NdisMDeregisterScatterGatherDma(p_adapter->NdisMiniportDmaHandle);
+#endif
+            ipoib_destroy_adapter( p_adapter );
+            IPOIB_PRINT_EXIT( TRACE_LEVEL_ERROR, IPOIB_DBG_ERROR,
+                ("Failed to register with IBAT: 0x%.8x.\n", status) );
+            return status;
+        }
+
 #if defined(NDIS630_MINIPORT)
 		// NDK support
 		ipoib_ifc_data_t *p = &p_adapter->guids;
@@ -2086,8 +2105,6 @@ if(cl_get_time_stamp_sec() < 30) {
         }
 #endif
 
-		ipoib_ref_ibat();
-	
 		IPOIB_EXIT( IPOIB_DBG_INIT );
 		return status;
 }
@@ -2110,11 +2127,13 @@ ipoib_halt_ex(
 
 	UNUSED_PARAM(HaltAction);
 		
-	ipoib_deref_ibat();
-
 	CL_ASSERT( adapter_context );
 	p_adapter = (ipoib_adapter_t*)adapter_context;
 
+    CL_ASSERT( p_adapter->p_ifc->ibat_deregister != NULL );
+    CL_ASSERT( p_adapter->ibatRouter != NULL );
+    p_adapter->p_ifc->ibat_deregister( p_adapter->ibatRouter );
+
 	IPOIB_PRINT( TRACE_LEVEL_INFORMATION, IPOIB_DBG_INIT,
 			("Port %016I64x (CA %016I64x port %d) halting\n",
 			p_adapter->guids.port_guid.guid, p_adapter->guids.ca_guid,
@@ -3271,20 +3290,9 @@ ipoib_set_info(
 				{
 					cl_qlist_insert_tail(
 						&g_ipoib.adapter_list, &p_adapter->entry );
-
-					/*
-					 * Filter was zero, now non-zero.  Register IP addresses
-					 * with SA.
-					 */
-					ipoib_reg_addrs( p_adapter );
 				}
 				else if( p_adapter->packet_filter && !(*(uint32_t*)info_buf) )
 				{
-					/*
-					 * Filter was non-zero, now zero.  Deregister IP addresses.
-					 */
-					ipoib_dereg_addrs( p_adapter );
-
 					ASSERT( cl_qlist_count( &g_ipoib.adapter_list ) );
 					cl_qlist_remove_item(
 						&g_ipoib.adapter_list, &p_adapter->entry );
@@ -3320,10 +3328,6 @@ ipoib_set_info(
 			status = NDIS_STATUS_INVALID_LENGTH;
 		break;
 
-	case OID_GEN_NETWORK_LAYER_ADDRESSES:
-		status = __ipoib_set_net_addr( p_adapter, info_buf, info_buf_len, p_bytes_read, p_bytes_needed);
-		break;
-
 	case OID_GEN_MACHINE_NAME:
 		IPOIB_PRINT( TRACE_LEVEL_INFORMATION, IPOIB_DBG_OID,
 			("Port %d received set for OID_GEN_MACHINE_NAME\n", port_num) );
@@ -3450,6 +3454,9 @@ ipoib_set_info(
 	case OID_GEN_MAXIMUM_SEND_PACKETS:
 	case OID_GEN_SUPPORTED_GUIDS:
 	case OID_GEN_PHYSICAL_MEDIUM:
+	case OID_GEN_NETWORK_LAYER_ADDRESSES:
+        status = NDIS_STATUS_NOT_SUPPORTED;
+        break;
 		
 	default:
 		status = NDIS_STATUS_INVALID_OID;
@@ -3826,17 +3833,9 @@ ipoib_resume_oids(
 			{
 				cl_qlist_insert_tail(
 					&g_ipoib.adapter_list, &p_adapter->entry );
-				/*
-				 * Filter was zero, now non-zero.  Register IP addresses
-				 * with SA.
-				 */
-				ipoib_reg_addrs( p_adapter );
 			}
 			else if( p_adapter->packet_filter && !(*(PULONG)set_oid.p_buf) )
 			{
-				/* Filter was non-zero, now zero.  Deregister IP addresses. */
-				ipoib_dereg_addrs( p_adapter );
-
 				ASSERT( cl_qlist_count( &g_ipoib.adapter_list ) );
 				cl_qlist_remove_item(
 					&g_ipoib.adapter_list, &p_adapter->entry );
@@ -3849,20 +3848,6 @@ ipoib_resume_oids(
 			NdisMOidRequestComplete( p_adapter->h_adapter, set_oid.p_pending_oid, status );
 			break;
 
-		case OID_GEN_NETWORK_LAYER_ADDRESSES:
-			status = __ipoib_set_net_addr( p_adapter,
-										   p_adapter->set_oid.p_buf,
-										   p_adapter->set_oid.buf_len,
-										   p_adapter->set_oid.p_bytes_used,
-										   p_adapter->set_oid.p_bytes_needed );
-
-			if( status != NDIS_STATUS_PENDING )
-			{
-				p_adapter->set_oid.p_pending_oid = NULL;
-				NdisMOidRequestComplete( p_adapter->h_adapter, set_oid.p_pending_oid, status );
-			}
-			break;
-
 		default:
 			CL_ASSERT( set_oid.oid && 0 );
 			break;
@@ -3873,468 +3858,6 @@ ipoib_resume_oids(
 }
 
 
-static NDIS_STATUS
-__ipoib_set_net_addr(
-	IN		ipoib_adapter_t *	p_adapter,
-	IN		PVOID				info_buf,
-	IN		ULONG				info_buf_len,
-		OUT	PULONG				p_bytes_read,
-		OUT	PULONG				p_bytes_needed )
-{
-	NDIS_STATUS				status;
-	PNETWORK_ADDRESS_LIST	p_net_addrs;
-	PNETWORK_ADDRESS		p_net_addr_oid;
-	PNETWORK_ADDRESS_IP		p_ip_addr;
-
-	net_address_item_t		*p_addr_item;
-
-	cl_status_t				cl_status;
-
-	size_t					idx;
-	LONG					i;
-	ULONG					addr_size;
-	ULONG					total_size;
-
-	uint8_t					port_num;
-
-	IPOIB_ENTER( IPOIB_DBG_OID );
-
-	status = NDIS_STATUS_SUCCESS;
-	port_num = p_adapter->guids.port_num;
-
-	IPOIB_PRINT( TRACE_LEVEL_INFORMATION,IPOIB_DBG_OID,
-		("Port %d received set for OID_GEN_NETWORK_LAYER_ADDRESSES\n",
-		port_num) );
-
-	if( !info_buf )
-	{
-		IPOIB_PRINT( TRACE_LEVEL_ERROR, IPOIB_DBG_ERROR,
-			("Port %d - OID_GEN_NETWORK_LAYER_ADDRESSES - "
-			"NULL buffer\n", port_num) );
-		IPOIB_EXIT( IPOIB_DBG_OID );
-		return NDIS_STATUS_INVALID_DATA;
-	}
-
-	/*
-	 * Must use field offset because the structures define array's of size one
-	 * of a the incorrect type for what is really stored.
-	 */
-	if( info_buf_len < FIELD_OFFSET(NETWORK_ADDRESS_LIST, Address) )
-	{
-		IPOIB_PRINT( TRACE_LEVEL_ERROR, IPOIB_DBG_ERROR, 
-			("Port %d OID_GEN_NETWORK_LAYER_ADDRESSES - "
-			"bad length of %d, not enough "
-			"for NETWORK_ADDRESS_LIST (%d)\n", port_num, info_buf_len,
-			FIELD_OFFSET(NETWORK_ADDRESS_LIST, Address)) );
-		*p_bytes_needed = FIELD_OFFSET(NETWORK_ADDRESS_LIST, Address);
-		IPOIB_EXIT( IPOIB_DBG_OID );
-		return NDIS_STATUS_INVALID_LENGTH;
-	}
-
-	p_net_addrs = (PNETWORK_ADDRESS_LIST)info_buf;
-	if( p_net_addrs->AddressCount == 0)
-	{
-		if( p_net_addrs->AddressType == NDIS_PROTOCOL_ID_TCP_IP )
-		{
-			IPOIB_PRINT( TRACE_LEVEL_INFORMATION, IPOIB_DBG_OID,
-				("Port %d OID_GEN_NETWORK_LAYER_ADDRESSES - "
-				"clear TCP/IP addresses\n", port_num) );
-		}
-		else
-		{
-			IPOIB_PRINT( TRACE_LEVEL_INFORMATION, IPOIB_DBG_OID,
-				("Port %d OID_GEN_NETWORK_LAYER_ADDRESSES - "
-				"Non TCP/IP address type of 0x%.4X on clear\n",
-				port_num, p_net_addrs->AddressType) );
-			IPOIB_EXIT( IPOIB_DBG_OID );
-			return NDIS_STATUS_SUCCESS;
-		}
-	}
-
-	addr_size = FIELD_OFFSET(NETWORK_ADDRESS, Address) +
-		NETWORK_ADDRESS_LENGTH_IP;
-	total_size = FIELD_OFFSET(NETWORK_ADDRESS_LIST, Address) +
-		addr_size * p_net_addrs->AddressCount;
-
-	if( info_buf_len < total_size )
-	{
-		IPOIB_PRINT( TRACE_LEVEL_ERROR, IPOIB_DBG_ERROR,
-			("Port %d OID_GEN_NETWORK_LAYER_ADDRESSES - "
-			"bad length of %d, %d required for %d addresses\n",
-			port_num, info_buf_len, total_size, p_net_addrs->AddressCount) );
-		*p_bytes_needed = total_size;
-		IPOIB_EXIT( IPOIB_DBG_OID );
-		return NDIS_STATUS_INVALID_LENGTH;
-	}
-
-	/* Lock lists for duration since SA callbacks can occur on other CPUs */
-	cl_obj_lock( &p_adapter->obj );
-
-	/* Set the capacity of the vector to accomodate all assinged addresses. */
-	cl_status = cl_vector_set_capacity(
-		&p_adapter->ip_vector, p_net_addrs->AddressCount );
-	if( cl_status != CL_SUCCESS )
-	{
-		cl_obj_unlock( &p_adapter->obj );
-		IPOIB_PRINT(TRACE_LEVEL_ERROR, IPOIB_DBG_ERROR,
-			("Port %d - OID_GEN_NETWORK_LAYER_ADDRESSES - "
-			"Failed to set IP vector capacity: %#x\n", port_num,
-			cl_status) );
-		IPOIB_EXIT( IPOIB_DBG_OID );
-		return NDIS_STATUS_RESOURCES;
-	}
-
-	*p_bytes_read = total_size;
-
-	IPOIB_PRINT( TRACE_LEVEL_INFORMATION,IPOIB_DBG_OID,
-		("Port %d OID_GEN_NETWORK_LAYER_ADDRESSES - List contains %d addresses\n",
-			port_num, p_net_addrs->AddressCount));
-
-	/* First look for addresses we had that should be removed */
-	for( idx = 0; idx != cl_vector_get_size( &p_adapter->ip_vector ); idx++ )
-	{
-		p_addr_item = (net_address_item_t*)
-			cl_vector_get_ptr( &p_adapter->ip_vector, idx );
-		p_net_addr_oid = (PNETWORK_ADDRESS)p_net_addrs->Address;
-
-		for( i = 0; i < p_net_addrs->AddressCount; ++i )
-		{
-			// Here we check that the data stored at 'AddressLength' field is valid;
-			// otherwise, it can lead to a memory violation (happened when AddressCount was > 1)
-			if( p_net_addr_oid->AddressLength != NETWORK_ADDRESS_LENGTH_IP)
-			{
-				IPOIB_PRINT(TRACE_LEVEL_ERROR, IPOIB_DBG_ERROR,
-					("Port %d OID_GEN_NETWORK_LAYER_ADDRESSES - Address %d is wrong size of %d, "
-						"should be %d\n", port_num, i, p_net_addr_oid->AddressLength,
-						NETWORK_ADDRESS_LENGTH_IP));
-				ASSERT ( p_net_addr_oid->AddressLength == NETWORK_ADDRESS_LENGTH_IPX );
-				break;
-			}
-			
-			ASSERT( p_net_addr_oid->AddressType == NDIS_PROTOCOL_ID_TCP_IP );
-			
-			p_ip_addr = (PNETWORK_ADDRESS_IP)p_net_addr_oid->Address;
-			if( !memcmp( &p_ip_addr->in_addr,
-						 &p_addr_item->address.as_ulong, sizeof(ULONG) ) )
-			{
-				break;
-			}
-			p_net_addr_oid = (PNETWORK_ADDRESS)((uint8_t *)p_net_addr_oid +
-								FIELD_OFFSET(NETWORK_ADDRESS, Address) +
-								p_net_addr_oid->AddressLength) ;
-		}
-
-		if( i == p_net_addrs->AddressCount )
-		{
-			/* Didn't find a match, delete from SA */
-			IPOIB_PRINT( TRACE_LEVEL_INFORMATION,IPOIB_DBG_OID,
-				("Port %d OID_GEN_NETWORK_LAYER_ADDRESSES - Deleting Address %d.%d.%d.%d\n",
-					port_num,
-					p_addr_item->address.as_bytes[0],
-					p_addr_item->address.as_bytes[1],
-					p_addr_item->address.as_bytes[2],
-					p_addr_item->address.as_bytes[3]));
-
-			if( p_addr_item->p_reg )
-			{
-				if( p_addr_item->p_reg->h_reg_svc )
-				{
-					p_adapter->p_ifc->dereg_svc(
-						p_addr_item->p_reg->h_reg_svc, __ipoib_ats_dereg_cb );
-				}
-				else
-				{
-					cl_free( p_addr_item->p_reg );
-				}
-				p_addr_item->p_reg = NULL;
-			}
-			p_addr_item->address.as_ulong = 0;
-		}
-	}
-
-	/* Now look for new addresses */
-	p_net_addr_oid = (NETWORK_ADDRESS *)p_net_addrs->Address;
-	idx = 0;
-	
-	for( i = 0; i < p_net_addrs->AddressCount; ++i )
-	{
-
-		// Here we check that the data stored at 'AddressLength' field is valid;
-		// otherwise, it can lead to a memory violation (happened when AddressCount was > 1)
-		if( p_net_addr_oid->AddressLength != NETWORK_ADDRESS_LENGTH_IP)
-		{
-			IPOIB_PRINT(TRACE_LEVEL_ERROR, IPOIB_DBG_ERROR,
-				("Port %d OID_GEN_NETWORK_LAYER_ADDRESSES - Address %d is wrong size of %d, "
-					"should be %d\n", port_num, i, p_net_addr_oid->AddressLength,
-					NETWORK_ADDRESS_LENGTH_IP));
-			ASSERT ( p_net_addr_oid->AddressLength == NETWORK_ADDRESS_LENGTH_IPX );
-			break;
-			
-		}
-		
-		ASSERT( p_net_addr_oid->AddressType == NDIS_PROTOCOL_ID_TCP_IP );		
-		
-		p_ip_addr = (PNETWORK_ADDRESS_IP)p_net_addr_oid->Address;
-
-		/* Size the vector as needed. */
-		if( cl_vector_get_size( &p_adapter->ip_vector ) <= idx )
-			cl_vector_set_size( &p_adapter->ip_vector, idx + 1 );
-
-		p_addr_item = (net_address_item_t *) cl_vector_get_ptr( &p_adapter->ip_vector, idx );
-		if( !memcmp( &p_ip_addr->in_addr, &p_addr_item->address.as_ulong,
-			sizeof(ULONG) ) )
-		{
-			idx++;
-			/* Already have this address - no change needed */
-			continue;
-		}
-
-		/*
-		 * Copy the address information, but don't register yet - the port
-		 * could be down.
-		 */
-		if( p_addr_item->p_reg )
-		{
-			/* If in use by some other address, deregister. */
-			if( p_addr_item->p_reg->h_reg_svc )
-			{
-				p_adapter->p_ifc->dereg_svc(
-					p_addr_item->p_reg->h_reg_svc, __ipoib_ats_dereg_cb );
-			}
-			else
-			{
-				cl_free( p_addr_item->p_reg );
-			}
-			p_addr_item->p_reg = NULL;
-		}
-		memcpy( (void *)&p_addr_item->address.as_ulong,
-				(const void *)&p_ip_addr->in_addr, sizeof(ULONG) );
-		IPOIB_PRINT( TRACE_LEVEL_INFORMATION,IPOIB_DBG_OID,
-			("Port %d OID_GEN_NETWORK_LAYER_ADDRESSES - Adding Address %d.%d.%d.%d\n",
-			port_num,
-			p_addr_item->address.as_bytes[0],
-			p_addr_item->address.as_bytes[1],
-			p_addr_item->address.as_bytes[2],
-			p_addr_item->address.as_bytes[3]) );
-		idx++;
-		p_net_addr_oid = (PNETWORK_ADDRESS)((uint8_t *)p_net_addr_oid +
-							FIELD_OFFSET(NETWORK_ADDRESS, Address) +
-							p_net_addr_oid->AddressLength) ;
-	}
-
-	/* Now clear any extra entries that shouldn't be there. */
-	while( idx < cl_vector_get_size( &p_adapter->ip_vector ) )
-	{
-		p_addr_item = (net_address_item_t*)
-			cl_vector_get_ptr( &p_adapter->ip_vector,
-			cl_vector_get_size( &p_adapter->ip_vector ) - 1 );
-
-		if( p_addr_item->p_reg )
-		{
-			if( p_addr_item->p_reg->h_reg_svc )
-			{
-				p_adapter->p_ifc->dereg_svc(
-					p_addr_item->p_reg->h_reg_svc, __ipoib_ats_dereg_cb );
-			}
-			else
-			{
-				cl_free( p_addr_item->p_reg );
-			}
-			p_addr_item->p_reg = NULL;
-			p_addr_item->address.as_ulong = 0;
-		}
-
-		/* No need to check return value - shrinking always succeeds. */
-		cl_vector_set_size( &p_adapter->ip_vector,
-			cl_vector_get_size( &p_adapter->ip_vector ) - 1 );
-	}
-
-	if( p_adapter->state == IB_PNP_PORT_ACTIVE && p_adapter->packet_filter )
-		ipoib_reg_addrs( p_adapter );
-
-	cl_obj_unlock( &p_adapter->obj );
-
-	IPOIB_EXIT( IPOIB_DBG_OID );
-	return NDIS_STATUS_SUCCESS;
-}
-
-
-/* Object lock is held when this function is called. */
-void
-ipoib_reg_addrs(
-	IN				ipoib_adapter_t* const		p_adapter )
-{
-	net_address_item_t		*p_addr_item;
-
-	size_t					idx;
-
-	uint8_t					port_num;
-
-	ib_api_status_t			ib_status;
-	ib_reg_svc_req_t		ib_service;
-	ib_gid_t				port_gid;
-
-	IPOIB_ENTER( IPOIB_DBG_OID );
-
-	if(p_adapter->guids.port_guid.pkey != IB_DEFAULT_PKEY)
-	{
-		IPOIB_PRINT_EXIT( TRACE_LEVEL_ERROR,IPOIB_DBG_ERROR,
-		("ATS Service available for default pkey only\n")); 	 
-		return;
-	}
-	port_num = p_adapter->guids.port_num;
-
-	/* Setup our service call with things common to all calls */
-	memset( &ib_service, 0, sizeof(ib_service) );
-
-	/* BUGBUG Only register local subnet GID prefix for now */
-	ib_gid_set_default( &port_gid, p_adapter->guids.port_guid.guid );
-	ib_service.svc_rec.service_gid		= port_gid;
-
-	ib_service.svc_rec.service_pkey		= IB_DEFAULT_PKEY;
-	ib_service.svc_rec.service_lease	= IB_INFINITE_SERVICE_LEASE;
-
-	/* Must cast here because the service name is an array of unsigned chars but
-	 * strcpy want a pointer to a signed char */
-	if ( StringCchCopy( (char *)ib_service.svc_rec.service_name, 
-		sizeof(ib_service.svc_rec.service_name) / sizeof(char), ATS_NAME ) != S_OK) {
-		ASSERT(FALSE);
-		IPOIB_PRINT_EXIT( TRACE_LEVEL_ERROR,IPOIB_DBG_ERROR,
-		("Problem copying ATS name: exiting\n"));
-		return;
-	}
-	
-	/* IP Address in question will be put in below */
-	ib_service.port_guid		= p_adapter->guids.port_guid.guid;
-	ib_service.timeout_ms		= p_adapter->params.sa_timeout;
-	ib_service.retry_cnt		= p_adapter->params.sa_retry_cnt;
-
-	/* Can't set IB_FLAGS_SYNC here because I can't wait at dispatch */
-	ib_service.flags			= 0;
-
-	/* Service context will be put in below */
-
-	ib_service.svc_data_mask	= IB_SR_COMPMASK_SID		|
-								  IB_SR_COMPMASK_SGID		|
-								  IB_SR_COMPMASK_SPKEY		|
-								  IB_SR_COMPMASK_SLEASE		|
-								  IB_SR_COMPMASK_SNAME		|
-								  IB_SR_COMPMASK_SDATA8_12	|
-								  IB_SR_COMPMASK_SDATA8_13	|
-								  IB_SR_COMPMASK_SDATA8_14	|
-								  IB_SR_COMPMASK_SDATA8_15;
-	ib_service.pfn_reg_svc_cb = __ipoib_ats_reg_cb;
-
-	for( idx = 0; idx < cl_vector_get_size( &p_adapter->ip_vector); idx++ )
-	{
-		p_addr_item = (net_address_item_t*)
-			cl_vector_get_ptr(	&p_adapter->ip_vector, idx );
-
-		if( p_addr_item->p_reg )
-			continue;
-
-		p_addr_item->p_reg = (ats_reg_t *) cl_zalloc( sizeof(ats_reg_t) );
-		if( !p_addr_item->p_reg )
-			break;
-
-		p_addr_item->p_reg->p_adapter = p_adapter;
-
-		ib_service.svc_context		= p_addr_item->p_reg;
-
-		ib_service.svc_rec.service_id =
-			ATS_SERVICE_ID & CL_HTON64(0xFFFFFFFFFFFFFF00);
-		/* ATS service IDs start at 0x10000CE100415453 */
-		ib_service.svc_rec.service_id |= ((uint64_t)(idx + 0x53)) << 56;
-
-		memcpy( &ib_service.svc_rec.service_data8[ATS_IPV4_OFFSET],
-			p_addr_item->address.as_bytes, IPV4_ADDR_SIZE );
-
-		/* Take a reference for each service request. */
-		cl_obj_ref(&p_adapter->obj);
-		IPOIB_PRINT( TRACE_LEVEL_INFORMATION, IPOIB_DBG_OBJ,
-			("[%p] Adapter refcount raised to %d\n",
-				p_adapter, p_adapter->obj.ref_cnt));
-
-		ib_status = p_adapter->p_ifc->reg_svc( p_adapter->h_al, &ib_service,
-												&p_addr_item->p_reg->h_reg_svc );
-
-		if( ib_status != IB_SUCCESS )
-		{
-			if( ib_status == IB_INVALID_GUID )
-			{
-				/* If this occurs, we log the error but do not fail the OID yet */
-				IPOIB_PRINT( TRACE_LEVEL_WARNING, IPOIB_DBG_OID,
-					("Port %d OID_GEN_NETWORK_LAYER_ADDRESSES - "
-					"Failed to register IP Address "
-					"of %d.%d.%d.%d with error IB_INVALID_GUID\n",
-					port_num,
-					p_addr_item->address.as_bytes[0],
-					p_addr_item->address.as_bytes[1],
-					p_addr_item->address.as_bytes[2],
-					p_addr_item->address.as_bytes[3]) );
-			}
-			else
-			{
-				/* Fatal error. */
-				IPOIB_PRINT( TRACE_LEVEL_ERROR, IPOIB_DBG_ERROR,
-					("Port %d OID_GEN_NETWORK_LAYER_ADDRESSES - Failed to "
-					 "register IP Address of %d.%d.%d.%d with error %s\n",
-					port_num,
-					p_addr_item->address.as_bytes[0],
-					p_addr_item->address.as_bytes[1],
-					p_addr_item->address.as_bytes[2],
-					p_addr_item->address.as_bytes[3],
-					p_adapter->p_ifc->get_err_str( ib_status )) );
-				p_adapter->hung = TRUE;
-			}
-			cl_obj_deref(&p_adapter->obj);
-			IPOIB_PRINT( TRACE_LEVEL_INFORMATION, IPOIB_DBG_OBJ,
-				("Adapter[%p] refcnt decremented to %d\n",
-					p_adapter, p_adapter->obj.ref_cnt));
-			cl_free( p_addr_item->p_reg );
-			p_addr_item->p_reg = NULL;
-		}
-	}
-
-	IPOIB_EXIT( IPOIB_DBG_OID );
-}
-
-
-/* Object lock is held when this function is called. */
-void
-ipoib_dereg_addrs(
-	IN				ipoib_adapter_t* const		p_adapter )
-{
-	net_address_item_t		*p_addr_item;
-
-	size_t					idx;
-
-	IPOIB_ENTER( IPOIB_DBG_OID );
-
-	for( idx = 0; idx < cl_vector_get_size( &p_adapter->ip_vector); idx++ )
-	{
-		p_addr_item = (net_address_item_t*)
-			cl_vector_get_ptr( &p_adapter->ip_vector, idx );
-
-		if( !p_addr_item->p_reg )
-			continue;
-
-		if( p_addr_item->p_reg->h_reg_svc )
-		{
-			p_adapter->p_ifc->dereg_svc(
-				p_addr_item->p_reg->h_reg_svc, __ipoib_ats_dereg_cb );
-		}
-		else
-		{
-			cl_free( p_addr_item->p_reg );
-		}
-		p_addr_item->p_reg = NULL;
-	}
-
-	IPOIB_EXIT( IPOIB_DBG_OID );
-}
-
-
 void
 ipoib_cancel_xmit(
 	IN				NDIS_HANDLE		adapter_context,
@@ -4351,69 +3874,6 @@ ipoib_cancel_xmit(
 
 	return;
 
-}
-
-
-static void
-__ipoib_ats_reg_cb(
-	IN				ib_reg_svc_rec_t			*p_reg_svc_rec )
-{
-	ats_reg_t				*p_reg;
-	uint8_t					port_num;
-
-	IPOIB_ENTER( IPOIB_DBG_OID );
-
-	CL_ASSERT( p_reg_svc_rec );
-	CL_ASSERT( p_reg_svc_rec->svc_context );
-
-	p_reg = (ats_reg_t*)p_reg_svc_rec->svc_context;
-	port_num = p_reg->p_adapter->guids.port_num;
-
-	cl_obj_lock( &p_reg->p_adapter->obj );
-
-	if( p_reg_svc_rec->req_status == IB_SUCCESS &&
-		!p_reg_svc_rec->resp_status )
-	{
-		IPOIB_PRINT( TRACE_LEVEL_INFORMATION,IPOIB_DBG_OID,
-			("Port %d OID_GEN_NETWORK_LAYER_ADDRESSES - Registered IP Address "
-			 "of %d.%d.%d.%d\n",
-				  port_num,
-				  p_reg_svc_rec->svc_rec.service_data8[ATS_IPV4_OFFSET],
-				  p_reg_svc_rec->svc_rec.service_data8[ATS_IPV4_OFFSET+1],
-				  p_reg_svc_rec->svc_rec.service_data8[ATS_IPV4_OFFSET+2],
-				  p_reg_svc_rec->svc_rec.service_data8[ATS_IPV4_OFFSET+3]) );
-	}
-	else if( p_reg_svc_rec->req_status != IB_CANCELED )
-	{
-		IPOIB_PRINT( TRACE_LEVEL_ERROR, IPOIB_DBG_OID,
-			("Port %d OID_GEN_NETWORK_LAYER_ADDRESSES - Failed to register IP Address "
-			 "of %d.%d.%d.%d with error %s\n",
-				  port_num,
-				  p_reg_svc_rec->svc_rec.service_data8[ATS_IPV4_OFFSET],
-				  p_reg_svc_rec->svc_rec.service_data8[ATS_IPV4_OFFSET+1],
-				  p_reg_svc_rec->svc_rec.service_data8[ATS_IPV4_OFFSET+2],
-				  p_reg_svc_rec->svc_rec.service_data8[ATS_IPV4_OFFSET+3],
-				  p_reg->p_adapter->p_ifc->get_err_str(
-								(ib_api_status_t) p_reg_svc_rec->resp_status )) );
-		p_reg->p_adapter->hung = TRUE;
-		p_reg->h_reg_svc = NULL;
-	}
-
-	cl_obj_unlock( &p_reg->p_adapter->obj );
-	cl_obj_deref(&p_reg->p_adapter->obj);
-	IPOIB_PRINT( TRACE_LEVEL_INFORMATION, IPOIB_DBG_OBJ,
-		("Adapter[%p] refcnt decremented to %d\n",
-			p_reg->p_adapter, p_reg->p_adapter->obj.ref_cnt));
-
-	IPOIB_EXIT( IPOIB_DBG_OID );
-}
-
-
-static void
-__ipoib_ats_dereg_cb(
-	IN				void						*context )
-{
-	cl_free( context );
 }
 
 
diff -dwup3 -X excl.txt -r c:\dev\openib\ofw\gen1\branches\mlx4_30\trunk\ulp\ipoib\kernel\ipoib_port.cpp .\ulp\ipoib\kernel\ipoib_port.cpp
--- c:\dev\openib\ofw\gen1\branches\mlx4_30\trunk\ulp\ipoib\kernel\ipoib_port.cpp	Wed Aug 01 17:16:52 2012
+++ .\ulp\ipoib\kernel\ipoib_port.cpp	Thu Jul 26 19:20:10 2012
@@ -7624,6 +7624,12 @@ __endpt_mgr_insert(
 		}
 	}
 
+    p_port->p_adapter->p_ifc->ibat_update_route(
+        p_port->p_adapter->ibatRouter,
+        key,
+        &p_endpt->dgid
+        );
+
 	IPOIB_EXIT( IPOIB_DBG_ENDPT );
 	return IB_SUCCESS;
 }
@@ -7847,8 +7853,8 @@ ipoib_port_up(
 	IPOIB_PRINT( TRACE_LEVEL_INFORMATION, IPOIB_DBG_INIT,
 		("Received port info: link width = %d.\n",
 			p_port_info->link_width_active) );
-	p_port->ib_mgr.rate = ib_port_info_compute_rate( p_port_info );
-	
+	p_port->ib_mgr.rate = ib_port_info_compute_rate( p_port_info,
+							p_port_info->capability_mask & IB_PORT_CAP_HAS_EXT_SPEEDS );
 	ipoib_set_rate( p_port->p_adapter,
 					p_port_info->link_width_active,
 					ib_port_info_get_link_speed_active( p_port_info ) );
@@ -8085,7 +8091,7 @@ done:
 
 	/* Return the response MAD to AL. */
 	if( p_query_rec->p_result_mad )
-		p_port->p_adapter->p_ifc->put_mad( p_query_rec->p_result_mad );
+		p_port->p_adapter->p_ifc->put_mad( __FILE__, __LINE__, p_query_rec->p_result_mad );
 
 	IPOIB_EXIT( IPOIB_DBG_INIT );
 }
@@ -8328,10 +8334,6 @@ ipoib_port_down(
 						   FALSE,
 						   NULL );
 	
-	cl_obj_lock( &p_port->p_adapter->obj );
-	ipoib_dereg_addrs( p_port->p_adapter );
-	cl_obj_unlock( &p_port->p_adapter->obj );
-	
 	IPOIB_EXIT( IPOIB_DBG_INIT );
 }
 
diff -dwup3 -X excl.txt -r c:\dev\openib\ofw\gen1\branches\mlx4_30\trunk\ulp\librdmacm\src\cma.cpp .\ulp\librdmacm\src\cma.cpp
--- c:\dev\openib\ofw\gen1\branches\mlx4_30\trunk\ulp\librdmacm\src\cma.cpp	Thu Mar 29 00:15:12 2012
+++ .\ulp\librdmacm\src\cma.cpp	Wed May 23 15:14:38 2012
@@ -576,8 +576,10 @@ int rdma_resolve_route(struct rdma_cm_id
 	IBAT_PATH_BLOB path;
 	HRESULT hr;
 
-	hr = IBAT::ResolvePath(&id->route.addr.src_addr, &id->route.addr.dst_addr,
-						   &path, timeout_ms);
+    UNREFERENCED_PARAMETER(timeout_ms);
+
+    hr = IBAT::QueryPath(&id->route.addr.src_addr, &id->route.addr.dst_addr,
+                         &path);
 	if (FAILED(hr)) {
 		return ibvw_wv_errno(hr);
 	}
diff -dwup3 -X excl.txt -r c:\dev\openib\ofw\gen1\branches\mlx4_30\trunk\ulp\nd\user\NdConnector.cpp .\ulp\nd\user\NdConnector.cpp
--- c:\dev\openib\ofw\gen1\branches\mlx4_30\trunk\ulp\nd\user\NdConnector.cpp	Tue Aug 07 12:08:10 2012
+++ .\ulp\nd\user\NdConnector.cpp	Tue Jun 19 17:48:26 2012
@@ -40,7 +40,7 @@
 #pragma warning( push, 3 )
 #include "winternl.h"
 #pragma warning( pop )
-#include <iba/ibat_ex.h>
+#include "iba/ibat.h"
 
 #include <assert.h>
 #include <limits.h>
@@ -267,6 +267,8 @@ HRESULT CConnector::Connect(
     __inout OVERLAPPED* pOverlapped
     )
 {
+    HRESULT hr;
+
     ND_ENTER( ND_DBG_NDI );
 
     if( AddressLength < sizeof(struct sockaddr) )
@@ -306,37 +308,6 @@ HRESULT CConnector::Connect(
     }
     ioctl.pdata.src_port = m_LocalPort;
 
-    // Resolve the GIDs.
-    enum rdma_transport_type transport;
-   HRESULT hr = IBAT_EX::Resolve(
-        &m_pParent->m_Addr.unspec,
-        pAddress,
-        (IBAT_PATH_BLOB*)&ioctl.path,
-        &transport
-        );
-    if( FAILED( hr ) )
-    {
-        if( hr == E_PENDING )
-        {
-            //
-            // Complete the request with a timeout status.
-            //
-            pOverlapped->Internal = ND_PENDING;
-            hr = g_NtDeviceIoControlFile(
-                m_pParent->GetFileHandle(),
-                pOverlapped->hEvent,
-                NULL,
-                (ULONG_PTR)pOverlapped->hEvent & 1 ? NULL : pOverlapped,
-                (IO_STATUS_BLOCK*)&pOverlapped->Internal,
-                UAL_NDI_NOOP,
-                &hr,
-                sizeof(hr),
-                NULL,
-                0 );
-        }
-        return hr;
-    }
-
     switch( ((struct sockaddr_in*)pAddress)->sin_family )
     {
     case AF_INET:
@@ -461,13 +432,11 @@ HRESULT CConnector::Connect(
     // to the kernel and let everything else be done there.
     //
     ioctl.h_qp = m_pEndpoint->m_hQp;
-    ioctl.guid = m_pParent->m_PortGuid;
     ioctl.cid = m_cid;
     ioctl.prot = m_Protocol;
     ioctl.pdata_size = sizeof(ioctl.pdata);
     ioctl.init_depth = m_pEndpoint->m_Ord;
     ioctl.resp_res = m_pEndpoint->m_Ird;
-	ioctl.transport = transport;
 
     ND_PRINT( TRACE_LEVEL_INFORMATION, ND_DBG_NDI,
         ("Connect QP %#I64x, QPn %#x, Guid %#I64x \n",
diff -dwup3 -X excl.txt -r c:\dev\openib\ofw\gen1\branches\mlx4_30\trunk\ulp\nd\user\NdProv.cpp .\ulp\nd\user\NdProv.cpp
--- c:\dev\openib\ofw\gen1\branches\mlx4_30\trunk\ulp\nd\user\NdProv.cpp	Thu May 31 11:22:11 2012
+++ .\ulp\nd\user\NdProv.cpp	Thu Jul 26 15:31:14 2012
@@ -42,7 +42,6 @@
 #pragma warning( pop )
 #include "ndprov.h"
 #include "ndadapter.h"
-#include <iba/ibat_ex.h>
 #include <process.h>
 
 #if defined(EVENT_TRACING)
@@ -117,52 +116,119 @@ namespace NetworkDirect
             __out_bcount_part_opt(*pBufferSize, *pBufferSize) SOCKET_ADDRESS_LIST* pAddressList,
             __inout SIZE_T* pBufferSize )
     {
-        IBAT_PORT_RECORD port;
-        struct addrinfo *res, *ai;
-        int cnt = 0;
-        size_t addrlen = 0, size;
-        UINT8 *offset;
+        SOCKADDR_INET* pInetAddrList;
 
-        HRESULT hr = getaddrinfo("..localmachine", NULL, NULL, &res);
-        if (hr) {
-            goto exit;
+        ND_ENTER( ND_DBG_NDI );
+
+        HANDLE hIbatDev = CreateFileW( IBAT_WIN32_NAME,
+            MAXIMUM_ALLOWED, 0, NULL,
+            OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL );
+        if( hIbatDev == INVALID_HANDLE_VALUE )
+            return ND_NO_MEMORY;
+
+        IOCTL_IBAT_IP_ADDRESSES_IN addrIn;
+        addrIn.Version = IBAT_IOCTL_VERSION;
+        addrIn.PortGuid = 0;
+
+        DWORD size = sizeof(IOCTL_IBAT_IP_ADDRESSES_OUT);
+        IOCTL_IBAT_IP_ADDRESSES_OUT *pAddrOut;
+        do
+        {
+            pAddrOut = (IOCTL_IBAT_IP_ADDRESSES_OUT*)HeapAlloc(
+                GetProcessHeap(),
+                0,
+                size );
+            if( !pAddrOut )
+            {
+                //AL_PRINT( TRACE_LEVEL_ERROR, AL_DBG_ERROR,
+                //    ("Failed to allocate output buffer.\n") );
+                return ND_NO_MEMORY;
         }
 
-        for (ai = res; ai; ai = ai->ai_next) {
-            ai->ai_flags = IBAT_EX::IpToPort( ai->ai_addr, &port );
-            if (SUCCEEDED(ai->ai_flags)) {
-                cnt++;
-                addrlen += ai->ai_addrlen;
+            if( !DeviceIoControl( hIbatDev, IOCTL_IBAT_IP_ADDRESSES,
+                &addrIn, sizeof(addrIn), pAddrOut, size, &size, NULL ) )
+            {
+                HeapFree( GetProcessHeap(), 0, pAddrOut );
+                //AL_PRINT( TRACE_LEVEL_ERROR, AL_DBG_ERROR,
+                //    ("IOCTL_IBAT_IP_ADDRESSES failed (%x).\n", GetLastError()) );
+                return ND_UNSUCCESSFUL;
             }
+
+            if( pAddrOut->Size > size )
+            {
+                size = pAddrOut->Size;
+                HeapFree( GetProcessHeap(), 0, pAddrOut );
+                pAddrOut = NULL;
         }
 
-        if (cnt == 0) {
-            *pBufferSize = 0;
-            goto free;
+        } while( !pAddrOut );
+
+        CloseHandle( hIbatDev );
+
+        //
+        // Note: the required size computed is a few bytes larger than necessary,
+        // but that keeps the code clean.
+        //
+        SIZE_T size_req;
+
+        if( pAddrOut->AddressCount > 0 )
+        {
+            //
+            // size of header + ((sizeof(element) + sizeof(addr)) * count)
+            //
+            size_req = (sizeof(*pAddressList) - sizeof(pAddressList->Address)) +
+                          (pAddrOut->AddressCount * (sizeof(pAddressList->Address[0]) + sizeof(*pInetAddrList) ));
+        }
+        else
+        {
+            size_req = sizeof(*pAddressList);
         }
 
-        size = sizeof(SOCKET_ADDRESS_LIST) + sizeof(SOCKET_ADDRESS) * (cnt - 1);
-        if (size + addrlen > *pBufferSize) {
-            *pBufferSize = size + addrlen;
-            hr = ND_BUFFER_OVERFLOW;
-            goto free;
+        if( size_req > *pBufferSize )
+        {
+            HeapFree( GetProcessHeap(), 0, pAddrOut );
+            *pBufferSize = size_req;
+            return ND_BUFFER_OVERFLOW;
         }
 
-        pAddressList->iAddressCount = cnt;
-        offset = (UINT8 *) pAddressList + size;
-        for (cnt = 0, ai = res; ai; ai = ai->ai_next) {
-            if (SUCCEEDED(ai->ai_flags)) {
-                pAddressList->Address[cnt].iSockaddrLength = (INT)ai->ai_addrlen;
-                pAddressList->Address[cnt++].lpSockaddr = (LPSOCKADDR) offset;
-                RtlCopyMemory(offset, ai->ai_addr, ai->ai_addrlen);
-                offset += ai->ai_addrlen;
+        RtlZeroMemory( pAddressList, size_req );
+
+        /* We store the array of addresses after the last address pointer:
+        *      iAddressCount
+        *      Address[0]; <-- points to sockaddr[0]
+        *      Address[1]; <-- points to sockaddr[1]
+        *      ...
+        *      Address[n-1]; <-- points to sockaddr[n-1]
+        *      sockaddr[0];
+        *      sockaddr[1];
+        *      ...
+        *      sockaddr[n-1]
+        */
+        pInetAddrList = reinterpret_cast<SOCKADDR_INET*>(
+            &(pAddressList->Address[pAddrOut->AddressCount])
+            );
+        *pBufferSize = size_req;
+
+        for( ULONG i = 0; i < pAddrOut->AddressCount; i++ )
+        {
+            pAddressList->Address[i].lpSockaddr =
+                reinterpret_cast<LPSOCKADDR>(&pInetAddrList[i]);
+            if( pAddrOut->Address[i].si_family == AF_INET )
+            {
+                pAddressList->Address[i].iSockaddrLength = sizeof(pInetAddrList[i].Ipv4);
             }
+            else
+            {
+                pAddressList->Address[i].iSockaddrLength = sizeof(pInetAddrList[i].Ipv6);
         }
 
-    free:
-        freeaddrinfo(res);
-    exit:
-        return hr;
+            pInetAddrList[i] = pAddrOut->Address[i];
+        }
+        pAddressList->iAddressCount = min( pAddrOut->AddressCount, LONG_MAX );
+
+        HeapFree( GetProcessHeap(), 0, pAddrOut );
+
+        return S_OK;
     }
 
     HRESULT CProvider::OpenAdapter(
@@ -175,10 +241,44 @@ namespace NetworkDirect
         if( AddressLength < sizeof(struct sockaddr) )
             return ND_INVALID_ADDRESS;
 
+        IOCTL_IBAT_IP_TO_PORT_IN in;
+        in.Version = IBAT_IOCTL_VERSION;
+
+        switch( pAddress->sa_family )
+        {
+        case AF_INET:
+            if( AddressLength < sizeof(in.Address.Ipv4) )
+                return ND_INVALID_ADDRESS;
+
+            RtlCopyMemory( &in.Address.Ipv4, pAddress, sizeof(in.Address.Ipv4) );
+            break;
+
+        case AF_INET6:
+            if( AddressLength < sizeof(in.Address.Ipv6) )
+                return ND_INVALID_ADDRESS;
+
+            RtlCopyMemory( &in.Address.Ipv6, pAddress, sizeof(in.Address.Ipv6) );
+            break;
+
+        default:
+            return ND_INVALID_ADDRESS;
+        }
+
+        HANDLE hIbatDev = CreateFileW( IBAT_WIN32_NAME,
+            MAXIMUM_ALLOWED, 0, NULL,
+            OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL );
+        if( hIbatDev == INVALID_HANDLE_VALUE )
+            return ND_NO_MEMORY;
+
         IBAT_PORT_RECORD out;
-        HRESULT hr = IBAT_EX::IpToPort( pAddress, &out );
-        if ( FAILED( hr ) )
-            return hr;
+        DWORD size;
+        BOOL fSuccess = DeviceIoControl( hIbatDev, IOCTL_IBAT_IP_TO_PORT,
+            &in, sizeof(in), &out, sizeof(out), &size, NULL );
+
+        CloseHandle( hIbatDev );
+        if( !fSuccess || size == 0 )
+            return ND_INVALID_ADDRESS;
+
         return CAdapter::Create( this, pAddress, &out, ppAdapter );
     }
 
diff -dwup3 -X excl.txt -r c:\dev\openib\ofw\gen1\branches\mlx4_30\trunk\ulp\netdirect\user\nd_connect.cpp .\ulp\netdirect\user\nd_connect.cpp
--- c:\dev\openib\ofw\gen1\branches\mlx4_30\trunk\ulp\netdirect\user\nd_connect.cpp	Thu Mar 29 00:15:02 2012
+++ .\ulp\netdirect\user\nd_connect.cpp	Mon Oct 03 17:07:29 2011
@@ -29,7 +29,8 @@
 
 #include "nd_connect.h"
 #include "nd_ep.h"
-#include <iba/ibat_ex.h>
+#include <iba/ibat.h>
+
 
 CNDConnector::CNDConnector(CNDAdapter *pAdapter)
 {
@@ -156,7 +157,7 @@ Connect(INDEndpoint* pEndpoint,
 		addr.Sin6.sin6_port = LocalPort;
 	}
 
-	hr = IBAT_EX::ResolvePath(&addr.Sa, pAddress, &path, NULL, INFINITE);
+    hr = IBAT::QueryPath(&addr.Sa, pAddress, &path);
 	if (FAILED(hr)) {
 		goto out;
 	}
diff -dwup3 -X excl.txt -r c:\dev\openib\ofw\gen1\branches\mlx4_30\trunk\ulp\wsd\user\ibsp_ip.c .\ulp\wsd\user\ibsp_ip.c
--- c:\dev\openib\ofw\gen1\branches\mlx4_30\trunk\ulp\wsd\user\ibsp_ip.c	Thu May 31 11:22:13 2012
+++ .\ulp\wsd\user\ibsp_ip.c	Wed May 23 18:26:50 2012
@@ -90,7 +90,7 @@ query_ip_address(
 	IOCTL_IBAT_IP_ADDRESSES_IN	in;
 	IOCTL_IBAT_IP_ADDRESSES_OUT	*p_out;
 	DWORD						size;
-	LONG						i;
+    ULONG                       i;
 	cl_fmap_item_t				*p_item;
 
 	IBSP_ENTER( IBSP_DBG_HW );
@@ -147,6 +147,11 @@ query_ip_address(
 	{
 		struct ibsp_ip_addr *ip_addr;
 
+        if( p_out->Address[i].si_family != AF_INET )
+        {
+            continue;
+        }
+
 		ip_addr = HeapAlloc(
 			g_ibsp.heap, 0, sizeof(struct ibsp_ip_addr) );
 		if( !ip_addr )
@@ -155,9 +160,9 @@ query_ip_address(
 			break;
 		}
 		/* Copy the IP address being ia64 friendly */
-		memcpy( (void*)&ip_addr->ip_addr.S_un.S_addr,
-				(void*)&p_out->Address[i].Address[ATS_IPV4_OFFSET],
-				sizeof(ib_net32_t) );
+        memcpy( (void*)&ip_addr->ip_addr,
+                (void*)&p_out->Address[i].Ipv4.sin_addr,
+                sizeof(ip_addr->ip_addr) );
 
 		ip_addr->p_port = p_port;
 
@@ -268,8 +273,7 @@ query_guid_address(
 	HRESULT hr;
 
 	IBSP_ENTER( IBSP_DBG_HW );
-	hr = IbatResolvePath(p_src_addr, p_dest_addr, (IBAT_PATH_BLOB*)&path,
-		INFINITE);
+    hr = IbatQueryPath(p_src_addr, p_dest_addr, (IBAT_PATH_BLOB*)&path);
 
 	if( hr == S_OK )
 	{
diff -dwup3 -X excl.txt -r c:\dev\openib\ofw\gen1\branches\mlx4_30\trunk\core\dirs .\core\dirs
--- c:\dev\openib\ofw\gen1\branches\mlx4_30\trunk\core\dirs	Thu Mar 29 00:15:22 2012
+++ .\core\dirs	Thu Jul 26 16:01:17 2012
@@ -3,7 +3,6 @@ DIRS=\
 	al			\
 	bus			\
 	ibat		\
-	ibat_ex   \
 	winverbs	\
 	winmad		\
 	fip
diff -dwup3 -X excl.txt -r c:\dev\openib\ofw\gen1\branches\mlx4_30\trunk\core\ibat\dirs .\core\ibat\dirs
--- c:\dev\openib\ofw\gen1\branches\mlx4_30\trunk\core\ibat\dirs	Thu Mar 29 00:15:17 2012
+++ .\core\ibat\dirs	Fri Sep 23 11:39:00 2011
@@ -1,2 +1,4 @@
 DIRS=\
-	user
+	user \
+	kernel \
+
Index: .\core\ibat\kernel\route.cpp
===================================================================
--- .\core\ibat\kernel\route.cpp	(revision 0)
+++ .\core\ibat\kernel\route.cpp	(revision 0)
@@ -0,0 +1,324 @@
+/*
+ * Copyright (c) Microsoft Corporation.  All rights reserved.
+ *
+ * This software is available to you under the OpenIB.org BSD license
+ * below:
+ *
+ *     Redistribution and use in source and binary forms, with or
+ *     without modification, are permitted provided that the following
+ *     conditions are met:
+ *
+ *      - Redistributions of source code must retain the above
+ *        copyright notice, this list of conditions and the following
+ *        disclaimer.
+ *
+ *      - Redistributions in binary form must reproduce the above
+ *        copyright notice, this list of conditions and the following
+ *        disclaimer in the documentation and/or other materials
+ *        provided with the distribution.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ */
+
+
+#include "ibatp.h"
+#include "route.h"
+
+
+#define IBAT_PATH_QUERY_TIMEOUT 500
+
+
+//
+// Structure used to track requests for routes, while the route hasn't been resolved.
+//
+struct IBAT_ROUTE_REQUEST
+{
+    IBAT_ROUTE_REQUEST* pNext;
+    FN_IBAT_QUERY_PATH_CALLBACK* callback;
+    VOID* completionContext;
+};
+
+
+IbatRoute*
+IbatRoute::Create(
+    const ib_gid_t* pSrcGid,
+    const ib_gid_t* pDestGid,
+    BOOLEAN isRoCE
+    )
+{
+    IbatRoute* pRoute = static_cast<IbatRoute*>(
+        ExAllocatePoolWithTag( NonPagedPool, sizeof(*pRoute), IBAT_POOL_TAG )
+        );
+
+    if( pRoute == NULL )
+    {
+        return NULL;
+    }
+
+    pRoute->m_srcGid = *pSrcGid;
+    pRoute->m_destGid = *pDestGid;
+
+    KeInitializeSpinLock( &pRoute->m_requestLock );
+    pRoute->m_requestList = NULL;
+    if( isRoCE == TRUE )
+    {
+        ib_path_rec_init_local(
+            &pRoute->m_path,
+            pDestGid,
+            pSrcGid,
+            0,
+            0,
+            0,
+            IB_DEFAULT_PKEY,
+            0,
+            0,
+            IB_PATH_SELECTOR_EXACTLY,
+            IB_MTU_LEN_1024,
+            IB_PATH_SELECTOR_EXACTLY,
+            IB_PATH_RECORD_RATE_10_GBS,
+            IB_PATH_SELECTOR_EXACTLY,
+            0,
+            0
+            );
+        ib_path_rec_set_hop_flow_raw( &pRoute->m_path, 1, 0, FALSE );
+
+        pRoute->m_state = NlnsReachable;
+    }
+    else
+    {
+        pRoute->m_state = NlnsUnreachable;
+    }
+    pRoute->m_hQuery = NULL;
+    pRoute->m_nRef = 1;
+
+    return pRoute;
+}
+
+
+VOID
+IbatRoute::QueryPathCompletion(
+    __in NTSTATUS status,
+    __in ib_path_rec_t* const pPath
+    )
+{
+    KLOCK_QUEUE_HANDLE hLock;
+    KeAcquireInStackQueuedSpinLock( &m_requestLock, &hLock );
+    if( status == STATUS_SUCCESS )
+    {
+        NT_ASSERT( m_state != NlnsReachable );
+        RtlCopyMemory( &m_path, pPath, sizeof(m_path) );
+        m_state = NlnsReachable;
+    }
+    else
+    {
+        m_state = NlnsUnreachable;
+    }
+
+    for( IBAT_ROUTE_REQUEST* pRequest = m_requestList;
+        pRequest != NULL;
+        pRequest = m_requestList
+        )
+    {
+        m_requestList = pRequest->pNext;
+        KeReleaseInStackQueuedSpinLock( &hLock );
+        pRequest->callback( pRequest->completionContext, status, pPath );
+        ExFreePoolWithTag( pRequest, IBAT_POOL_TAG );
+        KeAcquireInStackQueuedSpinLock( &m_requestLock, &hLock );
+    }
+    KeReleaseInStackQueuedSpinLock( &hLock );
+}
+
+
+VOID
+AL_API
+IbatRoute::PathQueryCallback(
+    __in ib_query_rec_t* pQueryResult
+    )
+{
+    ib_path_rec_t* pPath;
+    NTSTATUS status;
+    IbatRoute* pRoute = static_cast<IbatRoute*>(
+        const_cast<VOID*>(pQueryResult->query_context)
+        );
+
+    InterlockedExchangePointer( reinterpret_cast<PVOID*>(&pRoute->m_hQuery), NULL );
+
+    if( pQueryResult->status != IB_SUCCESS )
+    {
+        pPath = NULL;
+        switch( pQueryResult->status )
+        {
+        case IB_CANCELED:
+            //
+            // If there are requests left in the request list when we shutdown,
+            // don't complete them as cancelled.  The only reason we would shutdown
+            // a route is if:
+            //  - it is replaced by a new route, in which case the new route will take
+            //    over the request processing
+            //  - the port is going down, in which case the network is unreachable.
+            //
+            // Thus, if there are any requests here, the correct status is
+            // STATUS_NETWORK_UNREACHABLE.
+            //
+            status = STATUS_NETWORK_UNREACHABLE;
+            break;
+
+        case IB_TIMEOUT:
+            status = STATUS_IO_TIMEOUT;
+            break;
+
+        case IB_REMOTE_ERROR:
+            NT_ASSERT( pQueryResult->p_result_mad != NULL );
+            NT_ASSERT( pQueryResult->p_result_mad->p_mad_buf != NULL );
+            if( pQueryResult->p_result_mad->p_mad_buf->status == IB_SA_MAD_STATUS_NO_RESOURCES )
+            {
+                //
+                // SA can't process the request.
+                //
+                status = STATUS_IO_TIMEOUT;
+            }
+            else
+            {
+                status = STATUS_HOST_UNREACHABLE;
+            }
+            break;
+
+        default:
+            status = STATUS_HOST_UNREACHABLE;
+        }
+    }
+    else
+    {
+        pPath = ib_get_query_path_rec( pQueryResult->p_result_mad, 0 );
+        status = STATUS_SUCCESS;
+    }
+
+    pRoute->QueryPathCompletion( status, pPath );
+
+    if( pQueryResult->p_result_mad != NULL )
+    {
+        ib_put_mad( pQueryResult->p_result_mad );
+    }
+
+    pRoute->Release();
+}
+
+
+NTSTATUS
+IbatRoute::QueryPathUnsafe()
+{
+    if( m_state != NlnsUnreachable )
+    {
+        return STATUS_PENDING;
+    }
+
+    ib_gid_pair_t gidPair;
+    gidPair.src_gid = m_srcGid;
+    gidPair.dest_gid = m_destGid;
+
+    ib_query_req_t query;
+    query.query_type = IB_QUERY_PATH_REC_BY_GIDS;
+    query.p_query_input = &gidPair;
+    query.port_guid = m_srcGid.unicast.interface_id;
+
+    query.timeout_ms = IBAT_PATH_QUERY_TIMEOUT;
+    query.retry_cnt = 0;
+    query.flags = 0;
+
+    query.query_context = this;
+    query.pfn_query_cb = IbatRoute::PathQueryCallback;
+
+    AddRef();
+    ib_api_status_t ibStatus = ib_query( gh_al, &query, &m_hQuery );
+    if( ibStatus != IB_SUCCESS )
+    {
+        Release();
+        return STATUS_INSUFFICIENT_RESOURCES;
+    }
+
+    m_state = NlnsIncomplete;
+    return STATUS_PENDING;
+}
+
+
+//
+// Called with the IbatRouter's lock held.
+//
+NTSTATUS
+IbatRoute::Resolve(
+    __in FN_IBAT_QUERY_PATH_CALLBACK* completionCallback,
+    __in VOID* completionContext,
+    __out ib_path_rec_t* pPath
+    )
+{
+    KLOCK_QUEUE_HANDLE hLock;
+    IBAT_ROUTE_REQUEST* pRequest;
+
+    if( m_state == NlnsReachable )
+    {
+        RtlCopyMemory( pPath, &m_path, sizeof(*pPath) );
+        return STATUS_SUCCESS;
+    }
+
+    pRequest = static_cast<IBAT_ROUTE_REQUEST*>(
+        ExAllocatePoolWithTag( NonPagedPool, sizeof(*pRequest), IBAT_POOL_TAG )
+        );
+    if( pRequest == NULL )
+    {
+        return STATUS_INSUFFICIENT_RESOURCES;
+    }
+
+    pRequest->callback = completionCallback;
+    pRequest->completionContext = completionContext;
+
+    KeAcquireInStackQueuedSpinLock( &m_requestLock, &hLock );
+
+    pRequest->pNext = m_requestList;
+    m_requestList = pRequest;
+
+    NTSTATUS status = QueryPathUnsafe();
+    if( !NT_SUCCESS(status) )
+    {
+        m_requestList = m_requestList->pNext;
+        ExFreePoolWithTag( pRequest, IBAT_POOL_TAG );
+    }
+    KeReleaseInStackQueuedSpinLock( &hLock );
+    return status;
+}
+
+
+//
+// Called with the IbatRouter's lock held on a newly created route.
+//
+VOID
+IbatRoute::Resolve(
+    __in_opt IBAT_ROUTE_REQUEST* requestList
+    )
+{
+    if( requestList == NULL )
+    {
+        return;
+    }
+
+    KLOCK_QUEUE_HANDLE hLock;
+    KeAcquireInStackQueuedSpinLock( &m_requestLock, &hLock );
+    NT_ASSERT( m_requestList == NULL );
+    m_requestList = requestList;
+
+    NT_ASSERT( m_state == NlnsUnreachable );
+
+    NTSTATUS status = QueryPathUnsafe();
+    KeReleaseInStackQueuedSpinLock( &hLock );
+    if( !NT_SUCCESS(status) )
+    {
+        QueryPathCompletion( status, NULL );
+    }
+}
Index: .\core\ibat\kernel\ibat.cpp
===================================================================
--- .\core\ibat\kernel\ibat.cpp	(revision 0)
+++ .\core\ibat\kernel\ibat.cpp	(revision 0)
@@ -0,0 +1,970 @@
+/*
+ * Copyright (c) Microsoft Corporation.  All rights reserved.
+ *
+ * This software is available to you under the OpenIB.org BSD license
+ * below:
+ *
+ *     Redistribution and use in source and binary forms, with or
+ *     without modification, are permitted provided that the following
+ *     conditions are met:
+ *
+ *      - Redistributions of source code must retain the above
+ *        copyright notice, this list of conditions and the following
+ *        disclaimer.
+ *
+ *      - Redistributions in binary form must reproduce the above
+ *        copyright notice, this list of conditions and the following
+ *        disclaimer in the documentation and/or other materials
+ *        provided with the distribution.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ */
+
+
+#include "ibatp.h"
+#include "router.h"
+
+
+static ULONG g_nReg = 0;
+//
+// There are a number of operations that can be performed on an IBAT port:
+//  - Modification of the port array (register/update/deregister)
+//  - Lengthy access of a port in the array (anything that calls into IPHelper)
+//  - Short access of a port in the array (getting the path)
+//
+// For modifications, we first acquire the ERESOURCE for exclusive access, to ensure that
+// no further lengthy accesses are outstanding.  We then take the spinlock to serialize
+// actual changes to the port array.
+//
+// Because IPHelper calls may block, we cannot use the spinlock for lengthy accesses.
+// We thus use the ERESOURCE, with shared access for lengthy operations.
+//
+// For short operations, such as resolving the path given a physical address (MAC)
+// we can simply hold the spinlock and kick off path resolution (or copy the path if
+// it has already been resolved).
+//
+static ERESOURCE g_ibatLock;
+static KSPIN_LOCK g_ibatPortLock;
+//
+// Before Windows 8, ResolveIpNetEntry2 would always start a new neighbor resolution.
+// We need to serialize to allow resolution to finish if we started it.  This is not
+// needed for Windows 8 and beyond, as ResolveIpNetEntry2 does the right thing for
+// multiple concurrent callers.  Removing the mutex gives us better parallelism.
+//
+#if OSVER(NTDDI_VERSION) <= OSVER(NTDDI_WIN7)
+static KMUTEX g_ibatResolveMutex;
+//static KGUARDED_MUTEX g_ibatResolveMutex;
+#endif
+static MIB_UNICASTIPADDRESS_TABLE* g_ibatUnicastAddressTable;
+static HANDLE g_hIbatAddressNotification;
+
+//
+// We expect there to be only a handful of ports <= 4, typically <= 2, per node.
+// As such, we'll use a stupid array of IBAT_PORT structure.
+//
+static struct IBAT_PORT
+{
+    UINT64              Mac;
+    //
+    // In a VM environment, a local NIC can be shared with a VM and the
+    // management OS.  In this case the LUID of the local NIC will never
+    // have any IP addresses assigned.
+    //
+    // When IbatUpdateRegistration is called and an entry already exists, the LUID
+    // is overwritten.  The virtual NIC will send just such a request.
+    //
+    UINT64              Luid;
+
+    GUID                DriverId;
+    //
+    // The router is used to perform destination MAC to IB path resolution.
+    // It is a pointer to allow direct access in the data path, at DISPATCH_LEVEL.
+    //
+    IbatRouter*         pRouter;
+
+    IBAT_PORT_RECORD    Port;
+
+} g_ibatPorts[4];
+
+
+static
+VOID
+IbatpAddressChangeHandler(
+    __in VOID* /*context*/,
+    __in_opt MIB_UNICASTIPADDRESS_ROW* /*row*/,
+    __in MIB_NOTIFICATION_TYPE /*type*/
+    )
+{
+    MIB_UNICASTIPADDRESS_TABLE* pOldTable;
+    NTSTATUS status;
+
+    KeEnterCriticalRegion();
+    ExAcquireResourceExclusiveLite( &g_ibatLock, TRUE );
+
+    pOldTable = g_ibatUnicastAddressTable;
+
+    status = GetUnicastIpAddressTable( AF_UNSPEC, &g_ibatUnicastAddressTable );
+    if( !NT_SUCCESS(status) )
+    {
+        g_ibatUnicastAddressTable = pOldTable;
+    }
+    else if( pOldTable != NULL )
+    {
+        FreeMibTable( pOldTable );
+    }
+
+    ExReleaseResourceLite( &g_ibatLock );
+    KeLeaveCriticalRegion();
+}
+
+
+EXTERN_C
+NTSTATUS
+IbatInitialize()
+{
+    RtlZeroMemory( g_ibatPorts, sizeof(g_ibatPorts) );
+#if OSVER(NTDDI_VERSION) <= OSVER(NTDDI_WIN7)
+    KeInitializeMutex( &g_ibatResolveMutex, 0 );
+    //KeInitializeGuardedMutex( &g_ibatResolveMutex );
+#endif
+    KeInitializeSpinLock( &g_ibatPortLock );
+    g_ibatUnicastAddressTable = NULL;
+    g_hIbatAddressNotification = NULL;
+
+    NTSTATUS status = ExInitializeResourceLite( &g_ibatLock );
+    if( !NT_SUCCESS(status) )
+    {
+        return status;
+    }
+
+    IbatpAddressChangeHandler( NULL, NULL, MibInitialNotification );
+    if( g_ibatUnicastAddressTable == NULL )
+    {
+        ExDeleteResourceLite( &g_ibatLock );
+        return STATUS_INSUFFICIENT_RESOURCES;
+    }
+
+    status = NotifyUnicastIpAddressChange(
+        AF_UNSPEC,
+        IbatpAddressChangeHandler,
+        NULL,
+        TRUE,
+        &g_hIbatAddressNotification
+        );
+    if( !NT_SUCCESS(status) )
+    {
+        IbatCleanup();
+    }
+
+    return status;
+}
+
+
+EXTERN_C
+VOID
+IbatCleanup()
+{
+    if( g_hIbatAddressNotification != NULL )
+    {
+        CancelMibChangeNotify2( g_hIbatAddressNotification );
+    }
+
+    if( g_ibatUnicastAddressTable != NULL )
+    {
+        FreeMibTable( g_ibatUnicastAddressTable );
+    }
+
+    ExDeleteResourceLite( &g_ibatLock );
+}
+
+
+static IBAT_PORT*
+IbatpLookupPortUnsafe(
+    __in UINT64 mac
+    )
+{
+    for( ULONG i = 0; i < g_nReg; i++ )
+    {
+        if( g_ibatPorts[i].Mac == mac )
+        {
+            return &g_ibatPorts[i];
+        }
+    }
+
+    return NULL;
+}
+
+
+//
+// Called by the Virtual MiniPort NIC of VmSwitch to update the LUID of the associated
+// IPoIB instance.
+//
+NTSTATUS
+IbatUpdateRegistration(
+    __in UINT64 mac,
+    __in UINT64 luid
+    )
+{
+    IBAT_PORT* pPort;
+    NTSTATUS status = STATUS_SUCCESS;
+    KLOCK_QUEUE_HANDLE hLock;
+
+    NT_ASSERT( KeGetCurrentIrql() < DISPATCH_LEVEL );
+
+    KeEnterCriticalRegion();
+    ExAcquireResourceExclusiveLite( &g_ibatLock, TRUE );
+    KeAcquireInStackQueuedSpinLock( &g_ibatPortLock, &hLock );
+
+    pPort = IbatpLookupPortUnsafe( mac );
+
+    if( pPort != NULL )
+    {
+        pPort->Luid = luid;
+    }
+    else
+    {
+        // TODO: Should we support the Virtual MiniPort NIC to come up before the underlying
+        // protocl NIC?
+        status = STATUS_INVALID_PARAMETER;
+    }
+
+    KeReleaseInStackQueuedSpinLock( &hLock );
+    ExReleaseResourceLite( &g_ibatLock );
+    KeLeaveCriticalRegion();
+    return status;
+}
+
+
+//
+// Called by IPoIB.
+//
+NTSTATUS
+IbatRegister(
+    __in UINT64 mac,
+    __in UINT64 luid,
+    __in const GUID* pDriverId,
+    __in IBAT_PORT_RECORD* pPortRecord,
+    __in BOOLEAN isRoCE,
+    __out IBAT_ROUTING_CONTEXT* pRoutingContext
+    )
+{
+    IBAT_PORT* pPort;
+    NTSTATUS status = STATUS_SUCCESS;
+    KLOCK_QUEUE_HANDLE hLock;
+
+    NT_ASSERT( KeGetCurrentIrql() < DISPATCH_LEVEL );
+
+    KeEnterCriticalRegion();
+    ExAcquireResourceExclusiveLite( &g_ibatLock, TRUE );
+    KeAcquireInStackQueuedSpinLock( &g_ibatPortLock, &hLock );
+
+    pPort = IbatpLookupPortUnsafe( mac );
+
+    if( pPort != NULL )
+    {
+        // TODO: Should we support the Virtual MiniPort NIC to come up before the underlying
+        // protocl NIC?
+        status = STATUS_INVALID_PARAMETER;
+        goto done;
+    }
+
+    if( g_nReg == ARRAYSIZE(g_ibatPorts) )
+    {
+        status = STATUS_INSUFFICIENT_RESOURCES;
+        goto done;
+    }
+
+    g_ibatPorts[g_nReg].Mac = mac;
+    g_ibatPorts[g_nReg].Luid = luid;
+    g_ibatPorts[g_nReg].DriverId = *pDriverId;
+    g_ibatPorts[g_nReg].Port  = *pPortRecord;
+    g_ibatPorts[g_nReg].pRouter = IbatRouter::Create( pPortRecord->PortGuid, isRoCE );
+    if( g_ibatPorts[g_nReg].pRouter == NULL )
+    {
+        status = STATUS_INSUFFICIENT_RESOURCES;
+        goto done;
+    }
+    *pRoutingContext = g_ibatPorts[g_nReg].pRouter;
+
+    g_nReg++;
+
+done:
+    KeReleaseInStackQueuedSpinLock( &hLock );
+    ExReleaseResourceLite( &g_ibatLock );
+    KeLeaveCriticalRegion();
+
+    return status;
+}
+
+
+//
+// Called by IPoIB
+//
+VOID
+IbatDeregister(
+    __in IBAT_ROUTING_CONTEXT routingContext
+    )
+{
+    ULONG i;
+    KLOCK_QUEUE_HANDLE hLock;
+
+    NT_ASSERT( KeGetCurrentIrql() < DISPATCH_LEVEL );
+
+    KeEnterCriticalRegion();
+    ExAcquireResourceExclusiveLite( &g_ibatLock, TRUE );
+    KeAcquireInStackQueuedSpinLock( &g_ibatPortLock, &hLock );
+
+    //
+    // We must search for the proper index, as the index can change at runtime.
+    // A back pointer won't do at all.
+    //
+    for( i = 0; i < g_nReg; i++ )
+    {
+        if( g_ibatPorts[i].pRouter == routingContext )
+        {
+            break;
+        }
+    }
+
+    if( i < g_nReg )
+    {
+        g_ibatPorts[i].pRouter->Reset();
+        ExFreePoolWithTag( g_ibatPorts[i].pRouter, IBAT_POOL_TAG );
+
+        g_nReg--;
+        g_ibatPorts[i] = g_ibatPorts[g_nReg];
+        g_ibatPorts[g_nReg].Port.CaGuid = 0;
+    }
+
+    KeReleaseInStackQueuedSpinLock( &hLock );
+    ExReleaseResourceLite( &g_ibatLock );
+    KeLeaveCriticalRegion();
+}
+
+
+NTSTATUS
+IbatUpdateRoute(
+    __in IBAT_ROUTING_CONTEXT routingContext,
+    __in UINT64 destMac,
+    __in const ib_gid_t* pDestGid
+    )
+{
+    return routingContext->Update( destMac, pDestGid );
+}
+
+
+VOID
+IbatClearAllRoutes(
+    __in IBAT_ROUTING_CONTEXT routingContext
+    )
+{
+    routingContext->Reset();
+}
+
+
+EXTERN_C
+NTSTATUS
+IbatGetIpList(
+    __in_opt const GUID* pDriverId,
+    __in UINT64 caGuid,
+    __in UINT64 portGuid,
+    __in UINT16 pkey,
+    __inout ULONG* pnAddrs,
+    __out SOCKADDR_INET* pAddrs
+    )
+{
+    NTSTATUS status;
+    ULONG iAddrs = 0;
+
+    NT_ASSERT( KeGetCurrentIrql() < DISPATCH_LEVEL );
+
+    KeEnterCriticalRegion();
+    ExAcquireResourceSharedLite( &g_ibatLock, TRUE );
+    NT_ASSERT( g_ibatUnicastAddressTable != NULL );
+
+    for( ULONG i = 0; i < g_ibatUnicastAddressTable->NumEntries; i++ )
+    {
+        for( ULONG iReg = 0; iReg < g_nReg; iReg++ )
+        {
+            if( (caGuid != 0 && caGuid != g_ibatPorts[iReg].Port.CaGuid) ||
+                (portGuid != 0 && portGuid != g_ibatPorts[iReg].Port.PortGuid) ||
+                (pkey != 0 && pkey != g_ibatPorts[iReg].Port.PKey) ||
+                ((pDriverId != NULL) && (*pDriverId != g_ibatPorts[iReg].DriverId)) )
+            {
+                continue;
+            }
+
+            if( g_ibatPorts[iReg].Luid ==
+                g_ibatUnicastAddressTable->Table[i].InterfaceLuid.Value )
+            {
+                if( iAddrs < *pnAddrs )
+                {
+                    RtlCopyMemory(
+                        &pAddrs[iAddrs],
+                        &g_ibatUnicastAddressTable->Table[i].Address,
+                        sizeof(SOCKADDR_INET)
+                        );
+                }
+                iAddrs++;
+            }
+        }
+    }
+    ExReleaseResourceLite( &g_ibatLock );
+    KeLeaveCriticalRegion();
+
+    if( pAddrs == NULL )
+    {
+        status =  STATUS_BUFFER_OVERFLOW;
+    }
+    else if( iAddrs > *pnAddrs )
+    {
+        status = STATUS_MORE_ENTRIES;
+    }
+    else
+    {
+        status = STATUS_SUCCESS;
+    }
+
+    *pnAddrs = iAddrs;
+    return status;
+}
+
+
+EXTERN_C
+NTSTATUS
+IbatGetIpListIoctl(
+    __in IRP* pIrp
+    )
+{
+    IO_STACK_LOCATION* pIoStack;
+    IBAT_PORT_RECORD* in;
+    ULONG nAddrs;
+    NTSTATUS status;
+
+    pIoStack = IoGetCurrentIrpStackLocation( pIrp );
+
+    CL_ASSERT( (pIoStack->Parameters.DeviceIoControl.IoControlCode & 0x03) == METHOD_BUFFERED );
+
+    in = static_cast<IBAT_PORT_RECORD*>( pIrp->AssociatedIrp.SystemBuffer );
+
+    nAddrs = pIoStack->Parameters.DeviceIoControl.OutputBufferLength / sizeof(SOCKADDR_INET);
+
+    if( pIoStack->Parameters.DeviceIoControl.InputBufferLength == 0 )
+    {
+        status = IbatGetIpList(
+            NULL,
+            0,
+            0,
+            0,
+            &nAddrs,
+            static_cast<SOCKADDR_INET*>( pIrp->AssociatedIrp.SystemBuffer )
+            );
+    }
+    else if( pIoStack->Parameters.DeviceIoControl.InputBufferLength == sizeof(IBAT_PORT_RECORD) )
+    {
+        status = IbatGetIpList(
+            NULL,
+            in->CaGuid,
+            in->PortGuid,
+            in->PKey,
+            &nAddrs,
+            static_cast<SOCKADDR_INET*>( pIrp->AssociatedIrp.SystemBuffer )
+            );
+    }
+    else
+    {
+        status = STATUS_INVALID_PARAMETER;
+    }
+
+    switch( status )
+    {
+    case STATUS_SUCCESS:
+    case STATUS_BUFFER_OVERFLOW:
+        pIrp->IoStatus.Information = nAddrs * sizeof(SOCKADDR_INET);
+        break;
+
+    case STATUS_MORE_ENTRIES:
+        pIrp->IoStatus.Information = pIoStack->Parameters.DeviceIoControl.OutputBufferLength -
+            (pIoStack->Parameters.DeviceIoControl.OutputBufferLength % sizeof(SOCKADDR_INET));
+        break;
+
+    default:
+        pIrp->IoStatus.Information = 0;
+        break;
+    }
+    pIrp->IoStatus.Status = status;
+    IoCompleteRequest( pIrp, IO_NO_INCREMENT );
+    return status;
+}
+
+
+static NTSTATUS
+IbatpIpToIndexUnsafe(
+    __in const SOCKADDR_INET* pAddr,
+    __out ULONG* pIndex,
+    __out UINT64* pLuid
+    )
+{
+    NT_ASSERT( KeGetCurrentIrql() < DISPATCH_LEVEL );
+
+    NT_ASSERT( g_ibatUnicastAddressTable != NULL );
+
+    for( ULONG i = 0; i < g_ibatUnicastAddressTable->NumEntries; i++ )
+    {
+        if( IbatUtil::IsEqual(g_ibatUnicastAddressTable->Table[i].Address, *pAddr) == false )
+        {
+            continue;
+        }
+
+        for( ULONG iReg = 0; iReg < g_nReg; iReg++ )
+        {
+            if( g_ibatPorts[iReg].Luid ==
+                g_ibatUnicastAddressTable->Table[i].InterfaceLuid.Value )
+            {
+                *pIndex = iReg;
+                *pLuid = g_ibatPorts[iReg].Luid;
+                return STATUS_SUCCESS;
+            }
+        }
+    }
+
+    return STATUS_INVALID_ADDRESS;
+}
+
+
+static NTSTATUS
+IbatpPortToIndexUnsafe(
+    __in UINT64 mac,
+    __out ULONG* pIndex
+    )
+{
+    for( ULONG iReg = 0; iReg < g_nReg; iReg++ )
+    {
+        if( g_ibatPorts[iReg].Mac == mac )
+        {
+            *pIndex = iReg;
+            return STATUS_SUCCESS;
+        }
+    }
+    return STATUS_INVALID_PARAMETER;
+}
+
+
+EXTERN_C
+NTSTATUS
+IbatIpToPort(
+    __in const SOCKADDR_INET* pAddr,
+    __in_opt const GUID* pDriverId,
+    __out IBAT_PORT_RECORD* pPortRecord
+    )
+{
+    NTSTATUS status;
+    ULONG iReg;
+    UINT64 luid;
+
+    NT_ASSERT( KeGetCurrentIrql() < DISPATCH_LEVEL );
+
+    KeEnterCriticalRegion();
+    ExAcquireResourceSharedLite( &g_ibatLock, TRUE );
+    status = IbatpIpToIndexUnsafe( pAddr, &iReg, &luid );
+    if( NT_SUCCESS(status) )
+    {
+        if( (pDriverId != NULL) && (*pDriverId != g_ibatPorts[iReg].DriverId) )
+        {
+            status = STATUS_INVALID_ADDRESS;
+        }
+        else
+        {
+            *pPortRecord = g_ibatPorts[iReg].Port;
+        }
+    }
+
+    ExReleaseResourceLite( &g_ibatLock );
+    KeLeaveCriticalRegion();
+    return status;
+}
+
+
+EXTERN_C
+NTSTATUS
+IbatIpToPortIoctl(
+    __in IRP* pIrp
+    )
+{
+    IO_STACK_LOCATION* pIoStack;
+    SOCKADDR_INET* pAddr;
+    NTSTATUS status = STATUS_INVALID_PARAMETER;
+
+    pIoStack = IoGetCurrentIrpStackLocation( pIrp );
+
+    CL_ASSERT( (pIoStack->Parameters.DeviceIoControl.IoControlCode & 0x03) == METHOD_BUFFERED );
+
+    if( pIoStack->Parameters.DeviceIoControl.InputBufferLength != sizeof(SOCKADDR_INET) ||
+        pIoStack->Parameters.DeviceIoControl.OutputBufferLength != sizeof(IBAT_PORT_RECORD) )
+    {
+        goto error;
+    }
+
+    pAddr = static_cast<SOCKADDR_INET*>( pIrp->AssociatedIrp.SystemBuffer );
+    switch( pAddr->si_family )
+    {
+    case AF_INET:
+    case AF_INET6:
+        status = IbatIpToPort(
+            pAddr,
+            NULL,
+            static_cast<IBAT_PORT_RECORD*>( pIrp->AssociatedIrp.SystemBuffer )
+            );
+        break;
+
+    default:
+        status = STATUS_INVALID_PARAMETER;
+    }
+
+error:
+    if( !NT_SUCCESS( status ) )
+    {
+        pIrp->IoStatus.Information = 0;
+    }
+    else
+    {
+        pIrp->IoStatus.Information = sizeof(IBAT_PORT_RECORD);
+    }
+
+    pIrp->IoStatus.Status = status;
+    IoCompleteRequest( pIrp, IO_NO_INCREMENT );
+    return status;
+}
+
+
+EXTERN_C
+NTSTATUS
+IbatMacToPort(
+    __in UINT64 mac,
+    __in_opt const GUID* pDriverId,
+    __out IBAT_PORT_RECORD* pPortRecord
+    )
+{
+    NTSTATUS status;
+    ULONG iReg;
+
+    NT_ASSERT( KeGetCurrentIrql() < DISPATCH_LEVEL );
+
+    KeEnterCriticalRegion();
+    ExAcquireResourceSharedLite( &g_ibatLock, TRUE );
+    status = IbatpPortToIndexUnsafe( mac, &iReg );
+    if( NT_SUCCESS(status) )
+    {
+        if( (pDriverId != NULL) && (*pDriverId != g_ibatPorts[iReg].DriverId) )
+        {
+            status = STATUS_INVALID_ADDRESS;
+        }
+        else
+        {
+            *pPortRecord = g_ibatPorts[iReg].Port;
+        }
+    }
+    ExReleaseResourceLite( &g_ibatLock );
+    KeLeaveCriticalRegion();
+    return status;
+}
+
+
+static
+NTSTATUS
+IbatpResolveRemoteAddressUnsafe(
+    __in UINT64                 luid,
+    __in const SOCKADDR_INET*   pLocalAddress,
+    __in const SOCKADDR_INET*   pRemoteAddress,
+    __out UINT64*               pMac
+    )
+{
+    MIB_IPNET_ROW2 row;
+    NTSTATUS status;
+
+    NT_ASSERT( KeGetCurrentIrql() == PASSIVE_LEVEL );
+
+    row.Address             = *pRemoteAddress;
+    row.InterfaceIndex      = 0;
+    row.InterfaceLuid.Value = luid;
+
+#if OSVER(NTDDI_VERSION) <= OSVER(NTDDI_WIN7)
+    KeWaitForSingleObject( &g_ibatResolveMutex, UserRequest, KernelMode, FALSE, NULL );
+    //KeAcquireGuardedMutex( &g_ibatResolveMutex );
+#endif
+    status = GetIpNetEntry2( &row );
+    if( NT_SUCCESS( status ) && row.State < NlnsReachable )
+    {
+        NT_ASSERT( KeGetCurrentIrql() == PASSIVE_LEVEL );
+        status = ResolveIpNetEntry2( &row, pLocalAddress );
+    }
+#if OSVER(NTDDI_VERSION) <= OSVER(NTDDI_WIN7)
+    KeReleaseMutex( &g_ibatResolveMutex, FALSE );
+    //KeReleaseGuardedMutex( &g_ibatResolveMutex );
+#endif
+
+    if( !NT_SUCCESS( status ) )
+    {
+        return status;
+    }
+
+    if( row.State < NlnsReachable || row.PhysicalAddressLength > sizeof(*pMac) )
+    {
+        return STATUS_NETWORK_UNREACHABLE;
+    }
+
+    //
+    // The common case is that the physical address is an Ethernet MAC, and 6 bytes.
+    // We use the MAC for looking up a route in an AVL tree, and treat it as a
+    // 64-bit integer.  Clear the the entire 64-bit MAC variable and then copy the
+    // physical address to set only the valid bytes.
+    //
+    *pMac = 0;
+    RtlCopyMemory( pMac, row.PhysicalAddress, row.PhysicalAddressLength );
+
+    return STATUS_SUCCESS;
+}
+
+
+static
+NTSTATUS
+IbatpResolveLoopbackAddressUnsafe(
+    __in UINT64                 luid,
+    __out UINT64*               pMac
+    )
+{
+    MIB_IF_ROW2 row;
+    NTSTATUS status;
+
+    NT_ASSERT( KeGetCurrentIrql() < DISPATCH_LEVEL );
+
+    row.InterfaceIndex      = 0;
+    row.InterfaceLuid.Value = luid;
+
+    status = GetIfEntry2(&row);
+    if( !NT_SUCCESS(status) )
+    {
+        return status;
+    }
+
+    if( row.PhysicalAddressLength > sizeof(*pMac) )
+    {
+        return STATUS_NOT_FOUND;
+    }
+
+    //
+    // The common case is that the physical address is an Ethernet MAC, and 6 bytes.
+    // We use the MAC for looking up a route in an AVL tree, and treat it as a
+    // 64-bit integer.  Clear the the entire 64-bit MAC variable and then copy the
+    // physical address to set only the valid bytes.
+    //
+    *pMac = 0;
+    RtlCopyMemory( pMac, row.PhysicalAddress, row.PhysicalAddressLength );
+    return STATUS_SUCCESS;
+}
+
+
+static
+NTSTATUS
+IbatpResolvePhysicalAddressUnsafe(
+    __in const SOCKADDR_INET*   pLocalAddress,
+    __in const SOCKADDR_INET*   pRemoteAddress,
+    __out ULONG*                pIndex,
+    __out UINT64*               pMac
+    )
+{
+    NTSTATUS status;
+    UINT64 luid;
+
+    NT_ASSERT( KeGetCurrentIrql() < DISPATCH_LEVEL );
+
+    status = IbatpIpToIndexUnsafe( pLocalAddress, pIndex, &luid );
+    if( !NT_SUCCESS( status ) )
+    {
+        return status;
+    }
+
+    status = IbatpResolveRemoteAddressUnsafe( luid, pLocalAddress, pRemoteAddress, pMac );
+
+    if( (status == STATUS_NOT_FOUND) && 
+        (IbatUtil::IsEqual(*pLocalAddress, *pRemoteAddress) == true) )
+    {
+        status = IbatpResolveLoopbackAddressUnsafe( luid, pMac );
+    }
+
+    return status;
+}
+
+
+//
+// Summary:
+//  Gets a path record given the specified ip address information
+//
+// Parameters:
+//  pLocalAddress           - the local IP address assigned to an IB port.
+//  pRemoteAddress          - the destination IP Address
+//  pfnCompletionCallback   - call back function to be invoked if async operation required
+//  pCompletionContext      - context value to be passed to callback when completed.
+//  pPath                   - buffer to recieve the IB path if completed syncronously.
+//
+// Remarks:
+// If the function returns STATUS_PENDING, completion will be indicated through
+//   the completion callback and the path out parameter is not used.
+//   In this case, pPath value is not carried to the callback routine, and must thus
+//   be passed to the context via the pCompletionContext value in some way.  If the
+//   task succeeded, the callback should then copy the provided path record to the
+//   output buffer.
+//
+EXTERN_C
+NTSTATUS
+IbatQueryPathByIpAddress(
+    __in const SOCKADDR_INET* pLocalAddress,
+    __in const SOCKADDR_INET* pRemoteAddress,
+    __in FN_IBAT_QUERY_PATH_CALLBACK* completionCallback,
+    __in VOID* completionContext,
+    __out ib_path_rec_t* pPath
+    )
+{
+    NTSTATUS status;
+    ULONG iReg;
+    ULONG64 mac;
+
+    NT_ASSERT( KeGetCurrentIrql() == PASSIVE_LEVEL );
+
+    KeEnterCriticalRegion();
+    ExAcquireResourceSharedLite( &g_ibatLock, TRUE );
+
+    status = IbatpResolvePhysicalAddressUnsafe(
+                                pLocalAddress,
+                                pRemoteAddress,
+                                &iReg,
+                                &mac
+                                );
+
+    if( NT_SUCCESS( status ) )
+    {
+        status = g_ibatPorts[iReg].pRouter->Resolve(
+            mac,
+            completionCallback,
+            completionContext,
+            pPath
+            );
+    }
+
+    ExReleaseResourceLite( &g_ibatLock );
+    KeLeaveCriticalRegion();
+    return status;
+}
+
+
+EXTERN_C
+NTSTATUS
+IbatResolvePhysicalAddress(
+    __in const SOCKADDR_INET*   pLocalAddress,
+    __in const SOCKADDR_INET*   pRemoteAddress,
+    __out UINT64*               pSrcMac,
+    __out UINT64*               pDestMac
+    )
+{
+    NTSTATUS status;
+    ULONG iReg;
+
+    NT_ASSERT( KeGetCurrentIrql() == PASSIVE_LEVEL );
+
+    KeEnterCriticalRegion();
+    ExAcquireResourceSharedLite( &g_ibatLock, TRUE );
+
+    status = IbatpResolvePhysicalAddressUnsafe(
+                                pLocalAddress,
+                                pRemoteAddress,
+                                &iReg,
+                                pDestMac
+                                );
+    if( NT_SUCCESS( status ) )
+    {
+        *pSrcMac = g_ibatPorts[iReg].Mac;
+    }
+
+    ExReleaseResourceLite( &g_ibatLock );
+    KeLeaveCriticalRegion();
+    return status;
+}
+
+
+//
+// Summary:
+//  Gets a path record given the specified port and mac address information
+//
+// Parameters:
+//  guid                    - port GUID.
+//  pkey                    - port pkey
+//  pfnCompletionCallback   - call back function to be invoked if async operation required
+//  pCompletionContext      - context value to be passed to callback when completed.
+//  pPath                   - buffer to recieve the IB path if completed syncronously.
+//
+// Remarks:
+// If the function returns STATUS_PENDING, completion will be indicated through
+//   the completion callback and the path out parameter is not used.
+//   In this case, pPath value is not carried to the callback routine, and must thus
+//   be passed to the context via the pCompletionContext value in some way.  If the
+//   task succeeded, the callback should then copy the provided path record to the
+//   output buffer.
+//
+EXTERN_C
+NTSTATUS
+IbatQueryPathByPhysicalAddress(
+    __in UINT64 srcMac,
+    __in UINT64 destMac,
+    __in FN_IBAT_QUERY_PATH_CALLBACK* completionCallback,
+    __in VOID* completionContext,
+    __out ib_path_rec_t* pPath
+    )
+{
+    NTSTATUS status;
+    ULONG iReg;
+    KLOCK_QUEUE_HANDLE hLock;
+
+    KeAcquireInStackQueuedSpinLock( &g_ibatPortLock, &hLock );
+
+    status = IbatpPortToIndexUnsafe( srcMac, &iReg );
+    if( NT_SUCCESS( status ) )
+    {
+        status = g_ibatPorts[iReg].pRouter->Resolve(
+            destMac,
+            completionCallback,
+            completionContext,
+            pPath
+            );
+    }
+
+    KeReleaseInStackQueuedSpinLock( &hLock );
+    return status;
+}
+
+
+EXTERN_C
+void
+IbatGetInterface(
+    __out IBAT_IFC* pIbatIfc
+    )
+{
+    pIbatIfc->Register =                    IbatRegister;
+    pIbatIfc->Deregister =                  IbatDeregister;
+    pIbatIfc->UpdateRegistration =          IbatUpdateRegistration;
+    pIbatIfc->UpdateRoute =                 IbatUpdateRoute;
+    pIbatIfc->ClearAllRoutes =              IbatClearAllRoutes;
+    pIbatIfc->GetIpList =                   IbatGetIpList;
+    pIbatIfc->IpToPort =                    IbatIpToPort;
+    pIbatIfc->QueryPathByIpAddress =        IbatQueryPathByIpAddress;
+    pIbatIfc->QueryPathByPhysicalAddress =  IbatQueryPathByPhysicalAddress;
+    pIbatIfc->ResolvePhysicalAddress =      IbatResolvePhysicalAddress;
+    pIbatIfc->MacToPort =                   IbatMacToPort;
+}
Index: .\core\ibat\kernel\router.cpp
===================================================================
--- .\core\ibat\kernel\router.cpp	(revision 0)
+++ .\core\ibat\kernel\router.cpp	(revision 0)
@@ -0,0 +1,238 @@
+/*
+ * Copyright (c) Microsoft Corporation.  All rights reserved.
+ *
+ * This software is available to you under the OpenIB.org BSD license
+ * below:
+ *
+ *     Redistribution and use in source and binary forms, with or
+ *     without modification, are permitted provided that the following
+ *     conditions are met:
+ *
+ *      - Redistributions of source code must retain the above
+ *        copyright notice, this list of conditions and the following
+ *        disclaimer.
+ *
+ *      - Redistributions in binary form must reproduce the above
+ *        copyright notice, this list of conditions and the following
+ *        disclaimer in the documentation and/or other materials
+ *        provided with the distribution.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ */
+
+
+#include "ibatp.h"
+#include "route.h"
+#include "router.h"
+
+
+//
+// Structure to store a route in a router's AVL tree.
+//
+struct IBAT_ROUTE_ENTRY
+{
+    //
+    // The Ethernet MAC is stored as a 64-bit value to make arithmetic comparissons easy.
+    //
+    // This *must* be the first member, to allow the compare routine to compare on MAC only.
+    //
+    UINT64 mac;
+    IbatRoute* pRoute;
+};
+
+
+RTL_GENERIC_COMPARE_RESULTS
+NTAPI
+IbatRouter::RouteCompare(
+    __in RTL_AVL_TABLE* table,
+    __in PVOID firstStruct,
+    __in PVOID secondStruct
+    )
+{
+    UINT64 firstMac = *static_cast<UINT64*>(firstStruct);
+    UINT64 secondMac = *static_cast<UINT64*>(secondStruct);
+
+    if( firstMac > secondMac )
+    {
+        return GenericGreaterThan;
+    }
+    if( firstMac < secondMac )
+    {
+        return GenericLessThan;
+    }
+    return GenericEqual;
+
+    UNREFERENCED_PARAMETER(table);
+}
+
+
+PVOID
+NTAPI
+IbatRouter::RouteAlloc(
+    __in RTL_AVL_TABLE* table,
+    __in CLONG cbEntry
+    )
+{
+    return ExAllocatePoolWithTag( NonPagedPool, cbEntry, IBAT_POOL_TAG );
+    UNREFERENCED_PARAMETER(table);
+}
+
+
+VOID
+NTAPI
+IbatRouter::RouteFree(
+    __in RTL_AVL_TABLE* table,
+    __in __drv_freesMem(Mem) __post_invalid PVOID pEntry
+    )
+{
+    ExFreePoolWithTag( pEntry, IBAT_POOL_TAG );
+    UNREFERENCED_PARAMETER(table);
+}
+
+
+IbatRouter* IbatRouter::Create( UINT64 portGuid, BOOLEAN isRoCE )
+{
+    NT_ASSERT( portGuid != 0 );
+
+    IbatRouter* pRouter = static_cast<IbatRouter*>(
+        ExAllocatePoolWithTag( NonPagedPool, sizeof(IbatRouter), IBAT_POOL_TAG )
+        );
+    if( pRouter == NULL )
+    {
+        return NULL;
+    }
+
+    KeInitializeSpinLock( &pRouter->m_lock );
+    RtlInitializeGenericTableAvl(
+        &pRouter->m_table,
+        &IbatRouter::RouteCompare,
+        &IbatRouter::RouteAlloc,
+        &IbatRouter::RouteFree,
+        pRouter
+        );
+    pRouter->m_portGuid = portGuid;
+    pRouter->m_isRoCE = isRoCE;
+
+    return pRouter;
+}
+
+
+NTSTATUS
+IbatRouter::Update(
+    __in UINT64 destMac,
+    __in const ib_gid_t* pDestGid
+    )
+{
+    NTSTATUS status = STATUS_SUCCESS;
+    KLOCK_QUEUE_HANDLE hdl;
+    IbatRoute* pRoute;
+    IBAT_ROUTE_ENTRY routeEntry;
+    IBAT_ROUTE_ENTRY* pEntry;
+    BOOLEAN newElement;
+    ib_gid_t srcGid;
+
+    ib_gid_set_default( &srcGid, m_portGuid );
+    pRoute = IbatRoute::Create( &srcGid, pDestGid, m_isRoCE );
+    if( pRoute == NULL )
+    {
+        return STATUS_INSUFFICIENT_RESOURCES;
+    }
+
+    routeEntry.mac = destMac;
+    routeEntry.pRoute = pRoute;
+
+    KeAcquireInStackQueuedSpinLock( &m_lock, &hdl );
+    pEntry = static_cast<IBAT_ROUTE_ENTRY*>(
+        RtlInsertElementGenericTableAvl(
+            &m_table,
+            &routeEntry,
+            sizeof(routeEntry),
+            &newElement
+            )
+        );
+
+    if( pEntry == NULL )
+    {
+        pRoute->Release();
+        status = STATUS_INSUFFICIENT_RESOURCES;
+    }
+    else if( newElement == FALSE )
+    {
+        //
+        // Something about the destination changed - reset and update it.
+        //
+        // Note that we expect the caller to decide when to update a route, as
+        // the endpoint information alone might not reflect a change in the path.
+        //
+        pRoute->Resolve( pEntry->pRoute->PopRequestList() );
+        pEntry->pRoute->Release();
+        pEntry->pRoute = pRoute;
+    }
+
+    KeReleaseInStackQueuedSpinLock( &hdl );
+    return status;
+}
+
+
+VOID
+IbatRouter::Reset()
+{
+    KLOCK_QUEUE_HANDLE hdl;
+    IBAT_ROUTE_ENTRY* pRouteEntry;
+
+    KeAcquireInStackQueuedSpinLock( &m_lock, &hdl );
+    while( RtlIsGenericTableEmptyAvl( &m_table ) == FALSE )
+    {
+        pRouteEntry = static_cast<IBAT_ROUTE_ENTRY*>(
+            RtlGetElementGenericTableAvl( &m_table, 0 )
+            );
+
+        NT_ASSERT( pRouteEntry != NULL );
+
+        if( pRouteEntry->pRoute != NULL )
+        {
+            pRouteEntry->pRoute->Shutdown();
+            pRouteEntry->pRoute->Release();
+        }
+        RtlDeleteElementGenericTableAvl( &m_table, &pRouteEntry->mac );
+    }
+    KeReleaseInStackQueuedSpinLock( &hdl );
+}
+
+
+NTSTATUS
+IbatRouter::Resolve(
+    __in UINT64 mac,
+    __in FN_IBAT_QUERY_PATH_CALLBACK* completionCallback,
+    __in VOID* completionContext,
+    __out ib_path_rec_t* pPath
+    )
+{
+    NTSTATUS status = STATUS_HOST_UNREACHABLE;
+    KLOCK_QUEUE_HANDLE hdl;
+
+    KeAcquireInStackQueuedSpinLock( &m_lock, &hdl );
+    IBAT_ROUTE_ENTRY* pEntry = static_cast<IBAT_ROUTE_ENTRY*>(
+        RtlLookupElementGenericTableAvl( &m_table, &mac )
+        );
+
+    if( pEntry != NULL )
+    {
+        status = pEntry->pRoute->Resolve(
+            completionCallback,
+            completionContext,
+            pPath
+            );
+    }
+
+    KeReleaseInStackQueuedSpinLock( &hdl );
+    return status;
+}
Index: .\core\ibat\kernel\SOURCES
===================================================================
--- .\core\ibat\kernel\SOURCES	(revision 0)
+++ .\core\ibat\kernel\SOURCES	(revision 0)
@@ -0,0 +1,14 @@
+TARGETNAME=ibat
+TARGETPATH=..\..\..\bin\kernel\obj$(BUILD_ALT_DIR)
+TARGETTYPE=DRIVER_LIBRARY
+
+
+SOURCES= ibat.cpp \
+         route.cpp \
+         router.cpp
+
+INCLUDES=..;..\..\..\inc;..\..\..\inc\kernel;
+
+C_DEFINES=$(C_DEFINES) -DDRIVER -DDEPRECATE_DDK_FUNCTIONS
+
+MSC_WARNING_LEVEL= /W4
Index: .\core\ibat\kernel\route.h
===================================================================
--- .\core\ibat\kernel\route.h	(revision 0)
+++ .\core\ibat\kernel\route.h	(revision 0)
@@ -0,0 +1,136 @@
+/*
+ * Copyright (c) Microsoft Corporation.  All rights reserved.
+ *
+ * This software is available to you under the OpenIB.org BSD license
+ * below:
+ *
+ *     Redistribution and use in source and binary forms, with or
+ *     without modification, are permitted provided that the following
+ *     conditions are met:
+ *
+ *      - Redistributions of source code must retain the above
+ *        copyright notice, this list of conditions and the following
+ *        disclaimer.
+ *
+ *      - Redistributions in binary form must reproduce the above
+ *        copyright notice, this list of conditions and the following
+ *        disclaimer in the documentation and/or other materials
+ *        provided with the distribution.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ */
+
+
+///////////////////////////////////////////////////////////////////////////////
+//
+// IbatRoute
+//
+// The IBAT route tracks the state of the route, performs path queries to the
+// subnet administrator, and tracks route resolution requests.
+//
+class IbatRoute
+{
+    ib_path_rec_t m_path;
+
+    ib_gid_t m_srcGid;
+    ib_gid_t m_destGid;
+
+    ib_query_handle_t m_hQuery;
+
+    struct IBAT_ROUTE_REQUEST* m_requestList;
+
+    KSPIN_LOCK m_requestLock;
+
+    //
+    // Only NlnsUnreachable, NlnsIncomplete, and NlnsReachable are used.
+    //
+    NL_NEIGHBOR_STATE m_state;
+
+    volatile LONG m_nRef;
+
+public:
+    static IbatRoute* Create(
+        const ib_gid_t* pSrcGid,
+        const ib_gid_t* pDestGid,
+        BOOLEAN isRoCE
+        );
+
+    inline VOID AddRef(){ InterlockedIncrement( &m_nRef ); }
+    inline VOID Release();
+
+    inline VOID Shutdown();
+    inline IBAT_ROUTE_REQUEST* PopRequestList();
+
+    NTSTATUS Resolve(
+        __in FN_IBAT_QUERY_PATH_CALLBACK* completionCallback,
+        __in VOID* completionContext,
+        __out ib_path_rec_t* pPath
+        );
+
+    VOID Resolve(
+        __in_opt IBAT_ROUTE_REQUEST* pRequestList
+        );
+
+private:
+    static VOID AL_API PathQueryCallback( __in ib_query_rec_t* pQueryResult );
+    VOID
+    QueryPathCompletion(
+        __in NTSTATUS status,
+        __in_opt ib_path_rec_t* const pPath
+        );
+
+    NTSTATUS QueryPathUnsafe();
+};
+
+
+inline
+VOID
+IbatRoute::Release()
+{
+    NT_ASSERT( m_nRef != 0 );
+    if( InterlockedDecrement( &m_nRef ) == 0 )
+    {
+        ExFreePoolWithTag( this, IBAT_POOL_TAG );
+    }
+}
+
+
+inline
+VOID
+IbatRoute::Shutdown()
+{
+    ib_query_handle_t hQuery = static_cast<ib_query_handle_t>(
+        InterlockedExchangePointer(
+            reinterpret_cast<volatile PVOID*>(&m_hQuery),
+            NULL
+            )
+        );
+    if( hQuery != NULL )
+    {
+        ib_cancel_query( gh_al, hQuery );
+    }
+}
+
+
+inline
+IBAT_ROUTE_REQUEST*
+IbatRoute::PopRequestList()
+{
+    KLOCK_QUEUE_HANDLE hLock;
+    KeAcquireInStackQueuedSpinLock( &m_requestLock, &hLock );
+
+    IBAT_ROUTE_REQUEST* pHead = m_requestList;
+    m_requestList = NULL;
+
+    KeReleaseInStackQueuedSpinLock( &hLock );
+
+    return pHead;
+}
Index: .\core\ibat\kernel\ibatp.h
===================================================================
--- .\core\ibat\kernel\ibatp.h	(revision 0)
+++ .\core\ibat\kernel\ibatp.h	(revision 0)
@@ -0,0 +1,97 @@
+/*
+ * Copyright (c) Microsoft Corporation.  All rights reserved.
+ *
+ * This software is available to you under the OpenIB.org BSD license
+ * below:
+ *
+ *     Redistribution and use in source and binary forms, with or
+ *     without modification, are permitted provided that the following
+ *     conditions are met:
+ *
+ *      - Redistributions of source code must retain the above
+ *        copyright notice, this list of conditions and the following
+ *        disclaimer.
+ *
+ *      - Redistributions in binary form must reproduce the above
+ *        copyright notice, this list of conditions and the following
+ *        disclaimer in the documentation and/or other materials
+ *        provided with the distribution.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ */
+
+
+#include <ntddk.h>
+#include "iba\ibat.h"
+#include "iba\ibat_ifc.h"
+#include "iba\ib_al_ifc.h"
+
+
+#define IBAT_POOL_TAG 'tabi'
+
+EXTERN_C ib_al_handle_t gh_al;
+
+
+namespace IbatUtil
+{
+
+    inline
+    bool
+    IsEqual(const SOCKADDR_IN6& lhs, const SOCKADDR_IN6& rhs )
+    {
+        if (IN6_IS_ADDR_LOOPBACK(&lhs.sin6_addr) ||
+            IN6_IS_ADDR_LOOPBACK(&rhs.sin6_addr))
+        {
+            return true;
+        }
+        return IN6_ADDR_EQUAL( &lhs.sin6_addr, &rhs.sin6_addr ) == TRUE;
+    }
+
+
+    inline void MapTo6(__in const SOCKADDR_INET& in, __out SOCKADDR_IN6* out)
+    {
+        if (in.si_family == AF_INET)
+        {
+            if (in.Ipv4.sin_addr.s_addr == _byteswap_ulong(INADDR_LOOPBACK))
+            {
+                IN6ADDR_SETLOOPBACK(out);
+            }
+            else
+            {
+                out->sin6_family = AF_INET6;
+                out->sin6_port = 0;
+                out->sin6_flowinfo = 0;
+                out->sin6_addr = in6addr_v4mappedprefix;
+                out->sin6_addr.u.Word[6] = in.Ipv4.sin_addr.S_un.S_un_w.s_w1;
+                out->sin6_addr.u.Word[7] = in.Ipv4.sin_addr.S_un.S_un_w.s_w2;
+                out->sin6_scope_id = 0;
+            }
+        }
+        else
+        {
+            *out = in.Ipv6;
+        }
+    }
+
+    inline
+    bool
+    IsEqual(const SOCKADDR_INET& lhs, const SOCKADDR_INET& rhs)
+    {
+        SOCKADDR_IN6 lhs6;
+        SOCKADDR_IN6 rhs6;
+
+        MapTo6(lhs, &lhs6);
+        MapTo6(rhs, &rhs6);
+
+        return IsEqual(lhs6, rhs6);
+    }
+
+};
Index: .\core\ibat\kernel\router.h
===================================================================
--- .\core\ibat\kernel\router.h	(revision 0)
+++ .\core\ibat\kernel\router.h	(revision 0)
@@ -0,0 +1,71 @@
+/*
+ * Copyright (c) Microsoft Corporation.  All rights reserved.
+ *
+ * This software is available to you under the OpenIB.org BSD license
+ * below:
+ *
+ *     Redistribution and use in source and binary forms, with or
+ *     without modification, are permitted provided that the following
+ *     conditions are met:
+ *
+ *      - Redistributions of source code must retain the above
+ *        copyright notice, this list of conditions and the following
+ *        disclaimer.
+ *
+ *      - Redistributions in binary form must reproduce the above
+ *        copyright notice, this list of conditions and the following
+ *        disclaimer in the documentation and/or other materials
+ *        provided with the distribution.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ */
+
+
+///////////////////////////////////////////////////////////////////////////////
+//
+// IbatRouter
+//
+// The IbatRouter stores the routes for a given source port.  A source port
+// represents a single NDIS NIC, and has a single NET_LUID value.  The router
+// instance stores destination MAC address information.  All local IP to router
+// conversion is performed via IPHelper using the NET_LUID value.
+//
+// Defined as a struct to allow a handle to be defined such that C-code can use it.
+//
+struct IbatRouter
+{
+private:
+    KSPIN_LOCK m_lock;
+    RTL_AVL_TABLE m_table;
+    UINT64 m_portGuid;
+    BOOLEAN m_isRoCE;
+
+    static RTL_AVL_COMPARE_ROUTINE RouteCompare;
+    static RTL_AVL_ALLOCATE_ROUTINE RouteAlloc;
+    static RTL_AVL_FREE_ROUTINE RouteFree;
+
+public:
+    static IbatRouter* Create( UINT64 portGuid, BOOLEAN roce );
+
+    NTSTATUS Update(
+        __in UINT64 destMac,
+        __in const ib_gid_t* pDestGid
+        );
+
+    VOID Reset();
+
+    NTSTATUS Resolve(
+        __in UINT64 destMac,
+        __in FN_IBAT_QUERY_PATH_CALLBACK* completionCallback,
+        __in VOID* completionContext,
+        __out ib_path_rec_t* pPath
+        );
+};
Index: .\core\ibat\kernel\makefile
===================================================================
--- .\core\ibat\kernel\makefile	(revision 0)
+++ .\core\ibat\kernel\makefile	(revision 0)
@@ -0,0 +1,7 @@
+#
+# DO NOT EDIT THIS FILE!!!  Edit .\sources. if you want to add a new source
+# file to this component.  This file merely indirects to the real make file
+# that is shared by all the driver components of the OpenIB Windows project.
+#
+
+!INCLUDE ..\..\..\inc\openib.def
Index: .\ulp\ipoib\kernel\ipoib_ibat.cpp
===================================================================
--- .\ulp\ipoib\kernel\ipoib_ibat.cpp	(revision 3414)
+++ .\ulp\ipoib\kernel\ipoib_ibat.cpp	(working copy)
@@ -1,696 +0,0 @@
-/*
- * Copyright (c) 2005 Mellanox Technologies.  All rights reserved.
- * Copyright (c) 2005 SilverStorm Technologies.  All rights reserved.
- * Portions Copyright (c) 2008 Microsoft Corporation.  All rights reserved.
- *
- * This software is available to you under the OpenIB.org BSD license
- * below:
- *
- *     Redistribution and use in source and binary forms, with or
- *     without modification, are permitted provided that the following
- *     conditions are met:
- *
- *      - Redistributions of source code must retain the above
- *        copyright notice, this list of conditions and the following
- *        disclaimer.
- *
- *      - Redistributions in binary form must reproduce the above
- *        copyright notice, this list of conditions and the following
- *        disclaimer in the documentation and/or other materials
- *        provided with the distribution.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
- * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
- * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
- * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- */
-
-#include <precompile.h>
-
-
-#if defined(EVENT_TRACING)
-#ifdef offsetof
-#undef offsetof
-#endif
-#include "ipoib_ibat.tmh"
-#endif
-#include <iba/ib_at_ioctl.h>
-
-extern PDRIVER_OBJECT				g_p_drv_obj;
-
-static DRIVER_DISPATCH __ipoib_create;
-static NTSTATUS
-__ipoib_create(
-	IN				DEVICE_OBJECT* const		pDevObj,
-	IN				IRP* const					pIrp );
-
-static DRIVER_DISPATCH __ipoib_cleanup;
-static NTSTATUS
-__ipoib_cleanup(
-	IN				DEVICE_OBJECT* const		pDevObj,
-	IN				IRP* const					pIrp );
-
-static DRIVER_DISPATCH __ipoib_close;
-static NTSTATUS
-__ipoib_close(
-	IN				DEVICE_OBJECT* const		pDevObj,
-	IN				IRP* const					pIrp );
-
-static DRIVER_DISPATCH __ipoib_dispatch;
-static NTSTATUS
-__ipoib_dispatch(
-	IN				DEVICE_OBJECT* const		pDevObj,
-	IN				IRP* const					pIrp );
-
-
-static NTSTATUS
-__ibat_get_ports(
-	IN				IRP							*pIrp,
-	IN				IO_STACK_LOCATION			*pIoStack )
-{
-	IOCTL_IBAT_PORTS_IN		*pIn;
-	IOCTL_IBAT_PORTS_OUT	*pOut;
-	KLOCK_QUEUE_HANDLE		hdl;
-	cl_list_item_t			*pItem;
-	ipoib_adapter_t			*pAdapter;
-	LONG					nPorts;
-
-	IPOIB_ENTER(IPOIB_DBG_IOCTL);
-
-	if( pIoStack->Parameters.DeviceIoControl.InputBufferLength !=
-		sizeof(IOCTL_IBAT_PORTS_IN) )
-	{
-		IPOIB_PRINT_EXIT( TRACE_LEVEL_ERROR, IPOIB_DBG_ERROR,
-			("Invalid input buffer size.\n") );
-		return STATUS_INVALID_PARAMETER;
-	}
-	
-	if( pIoStack->Parameters.DeviceIoControl.OutputBufferLength <
-		sizeof(IOCTL_IBAT_PORTS_OUT) )
-	{
-		IPOIB_PRINT_EXIT( TRACE_LEVEL_ERROR, IPOIB_DBG_ERROR,
-			("Invalid output buffer size.\n") );
-		return STATUS_INVALID_PARAMETER;
-	}
-
-	pIn = (IOCTL_IBAT_PORTS_IN *) pIrp->AssociatedIrp.SystemBuffer;
-	pOut = (IOCTL_IBAT_PORTS_OUT *) pIrp->AssociatedIrp.SystemBuffer;
-
-	if( pIn->Version != IBAT_IOCTL_VERSION )
-	{
-		IPOIB_PRINT_EXIT( TRACE_LEVEL_ERROR, IPOIB_DBG_ERROR,
-			("Invalid version.\n") );
-		return STATUS_INVALID_PARAMETER;
-	}
-
-	KeAcquireInStackQueuedSpinLock( &g_ipoib.lock, &hdl );
-	nPorts = (LONG)cl_qlist_count( &g_ipoib.adapter_list );
-	switch( nPorts )
-	{
-	case 0:
-		memset( pOut->Ports, 0, sizeof(pOut->Ports) );
-		/* Fall through */
-	case 1:
-		pOut->Size = sizeof(IOCTL_IBAT_PORTS_OUT);
-		break;
-
-	default:
-		pOut->Size = sizeof(IOCTL_IBAT_PORTS_OUT) + 
-			(sizeof(IBAT_PORT_RECORD) * (nPorts - 1));
-		break;
-	}
-
-	pIrp->IoStatus.Information = pOut->Size;
-
-	if( pOut->Size > pIoStack->Parameters.DeviceIoControl.OutputBufferLength )
-	{
-		nPorts = 1 +
-			(pIoStack->Parameters.DeviceIoControl.OutputBufferLength -
-			sizeof(IOCTL_IBAT_PORTS_OUT)) / sizeof(IBAT_PORT_RECORD);
-
-		pIrp->IoStatus.Information = sizeof(IOCTL_IBAT_PORTS_OUT) +
-			((nPorts - 1) * sizeof(IBAT_PORT_RECORD));
-	}
-
-	pOut->NumPorts = 0;
-	pItem = cl_qlist_head( &g_ipoib.adapter_list );
-	while( pOut->NumPorts != nPorts )
-	{
-		pAdapter = CONTAINING_RECORD( pItem, ipoib_adapter_t, entry );
-		pOut->Ports[pOut->NumPorts].CaGuid = pAdapter->guids.ca_guid;
-		pOut->Ports[pOut->NumPorts].PortGuid = pAdapter->guids.port_guid.guid;
-		pOut->Ports[pOut->NumPorts].PKey = IB_DEFAULT_PKEY;
-		pOut->Ports[pOut->NumPorts].PortNum = pAdapter->guids.port_num;
-		pOut->NumPorts++;
-
-		pItem = cl_qlist_next( pItem );
-	}
-
-	KeReleaseInStackQueuedSpinLock( &hdl );
-	IPOIB_EXIT( IPOIB_DBG_IOCTL );
-	return STATUS_SUCCESS;
-}
-
-
-static NTSTATUS
-__ibat_get_ips(
-	IN				IRP							*pIrp,
-	IN				IO_STACK_LOCATION			*pIoStack )
-{
-	IOCTL_IBAT_IP_ADDRESSES_IN	*pIn;
-	IOCTL_IBAT_IP_ADDRESSES_OUT	*pOut;
-	KLOCK_QUEUE_HANDLE			hdl;
-	cl_list_item_t				*pItem;
-	ipoib_adapter_t				*pAdapter;
-	LONG						nIps, maxIps;
-	size_t						idx;
-	net_address_item_t			*pAddr;
-	UINT64						PortGuid;
-
-	IPOIB_ENTER(IPOIB_DBG_IOCTL);
-
-	if( pIoStack->Parameters.DeviceIoControl.InputBufferLength !=
-		sizeof(IOCTL_IBAT_IP_ADDRESSES_IN) )
-	{
-		IPOIB_PRINT_EXIT( TRACE_LEVEL_ERROR, IPOIB_DBG_ERROR,
-			("Invalid input buffer size.\n") );
-		return STATUS_INVALID_PARAMETER;
-	}
-	
-	if( pIoStack->Parameters.DeviceIoControl.OutputBufferLength <
-		sizeof(IOCTL_IBAT_IP_ADDRESSES_OUT) )
-	{
-		IPOIB_PRINT_EXIT( TRACE_LEVEL_ERROR, IPOIB_DBG_ERROR,
-			("Invalid output buffer size.\n") );
-		return STATUS_INVALID_PARAMETER;
-	}
-
-	pIn = (IOCTL_IBAT_IP_ADDRESSES_IN *) pIrp->AssociatedIrp.SystemBuffer;
-	pOut = (IOCTL_IBAT_IP_ADDRESSES_OUT *) pIrp->AssociatedIrp.SystemBuffer;
-
-	if( pIn->Version != IBAT_IOCTL_VERSION )
-	{
-		IPOIB_PRINT_EXIT( TRACE_LEVEL_ERROR, IPOIB_DBG_ERROR,
-			("Invalid version.\n") );
-		return STATUS_INVALID_PARAMETER;
-	}
-
-	PortGuid = pIn->PortGuid;
-
-	nIps = 0;
-	pOut->AddressCount = 0;
-	maxIps = 1 +
-		((pIoStack->Parameters.DeviceIoControl.OutputBufferLength -
-		sizeof(IOCTL_IBAT_IP_ADDRESSES_OUT)) / sizeof(IP_ADDRESS));
-
-	KeAcquireInStackQueuedSpinLock( &g_ipoib.lock, &hdl );
-	for( pItem = cl_qlist_head( &g_ipoib.adapter_list );
-		pItem != cl_qlist_end( &g_ipoib.adapter_list );
-		pItem = cl_qlist_next( pItem ) )
-	{
-		pAdapter = CONTAINING_RECORD( pItem, ipoib_adapter_t, entry );
-		if( PortGuid && pAdapter->guids.port_guid.guid != PortGuid )
-			continue;
-
-		cl_obj_lock( &pAdapter->obj );
-		nIps += (LONG)cl_vector_get_size( &pAdapter->ip_vector );
-
-		for( idx = 0;
-			idx < cl_vector_get_size( &pAdapter->ip_vector );
-			idx++ )
-		{
-			if( pOut->AddressCount == maxIps )
-				break;
-
-			pAddr = (net_address_item_t*)
-				cl_vector_get_ptr( &pAdapter->ip_vector, idx );
-
-			pOut->Address[pOut->AddressCount].IpVersion = 4;
-			memset( &pOut->Address[pOut->AddressCount].Address, 0, sizeof(IP_ADDRESS) );
-			memcpy( &pOut->Address[pOut->AddressCount].Address[12],
-					pAddr->address.as_bytes, IPV4_ADDR_SIZE );
-
-			pOut->AddressCount++;
-		}
-		cl_obj_unlock( &pAdapter->obj );
-	}
-
-	pOut->Size = sizeof(IOCTL_IBAT_IP_ADDRESSES_OUT);
-	if( --nIps )
-		pOut->Size += sizeof(IP_ADDRESS) * nIps;
-
-	pIrp->IoStatus.Information = sizeof(IOCTL_IBAT_IP_ADDRESSES_OUT);
-	if( --maxIps < nIps )
-		pIrp->IoStatus.Information += (sizeof(IP_ADDRESS) * maxIps);
-	else
-		pIrp->IoStatus.Information += (sizeof(IP_ADDRESS) * nIps);
-
-	KeReleaseInStackQueuedSpinLock( &hdl );
-	IPOIB_EXIT( IPOIB_DBG_IOCTL );
-	return STATUS_SUCCESS;
-}
-
-
-static NTSTATUS
-__ibat_mac_to_gid(
-	IN				IRP							*pIrp,
-	IN				IO_STACK_LOCATION			*pIoStack )
-{
-	NTSTATUS					status = STATUS_INVALID_PARAMETER;
-	IOCTL_IBAT_MAC_TO_GID_IN	*pIn;
-	IOCTL_IBAT_MAC_TO_GID_OUT	*pOut;
-	KLOCK_QUEUE_HANDLE			hdl;
-	cl_list_item_t				*pItem;
-	ipoib_adapter_t				*pAdapter;
-
-	IPOIB_ENTER(IPOIB_DBG_IOCTL);
-
-	if( pIoStack->Parameters.DeviceIoControl.InputBufferLength !=
-		sizeof(IOCTL_IBAT_MAC_TO_GID_IN) )
-	{
-		IPOIB_PRINT_EXIT( TRACE_LEVEL_ERROR, IPOIB_DBG_ERROR,
-			("Invalid input buffer size.\n") );
-		return STATUS_INVALID_PARAMETER;
-	}
-	
-	if( pIoStack->Parameters.DeviceIoControl.OutputBufferLength !=
-		sizeof(IOCTL_IBAT_MAC_TO_GID_OUT) )
-	{
-		IPOIB_PRINT_EXIT( TRACE_LEVEL_ERROR, IPOIB_DBG_ERROR,
-			("Invalid output buffer size.\n") );
-		return STATUS_INVALID_PARAMETER;
-	}
-
-	pIn = (IOCTL_IBAT_MAC_TO_GID_IN	*) pIrp->AssociatedIrp.SystemBuffer;
-	pOut = (IOCTL_IBAT_MAC_TO_GID_OUT *) pIrp->AssociatedIrp.SystemBuffer;
-
-	if( pIn->Version != IBAT_IOCTL_VERSION )
-	{
-		IPOIB_PRINT_EXIT( TRACE_LEVEL_ERROR, IPOIB_DBG_ERROR,
-			("Invalid version.\n") );
-		return STATUS_INVALID_PARAMETER;
-	}
-
-	KeAcquireInStackQueuedSpinLock( &g_ipoib.lock, &hdl );
-
-	for( pItem = cl_qlist_head( &g_ipoib.adapter_list );
-		pItem != cl_qlist_end( &g_ipoib.adapter_list );
-		pItem = cl_qlist_next( pItem ) )
-	{
-		pAdapter = CONTAINING_RECORD( pItem, ipoib_adapter_t, entry );
-		if( pIn->PortGuid != pAdapter->guids.port_guid.guid )
-			continue;
-
-		/* Found the port - lookup the MAC. */
-		cl_obj_lock( &pAdapter->obj );
-		if( pAdapter->p_port )
-		{
-			status = ipoib_mac_to_gid(
-				pAdapter->p_port, *(mac_addr_t*)pIn->DestMac, &pOut->DestGid );
-			if( NT_SUCCESS( status ) )
-			{
-				pIrp->IoStatus.Information =
-					sizeof(IOCTL_IBAT_MAC_TO_GID_OUT);
-			}
-		}
-		cl_obj_unlock( &pAdapter->obj );
-		break;
-	}
-
-	KeReleaseInStackQueuedSpinLock( &hdl );
-
-	IPOIB_EXIT( IPOIB_DBG_IOCTL );
-	return status;
-}
-
-
-NTSTATUS
-__ibat_mac_to_path(
-	IN				IRP							*pIrp,
-	IN				IO_STACK_LOCATION			*pIoStack )
-{
-	NTSTATUS					status = STATUS_INVALID_PARAMETER;
-	IOCTL_IBAT_MAC_TO_PATH_IN	*pIn;
-	IOCTL_IBAT_MAC_TO_PATH_OUT	*pOut;
-	KLOCK_QUEUE_HANDLE			hdl;
-	cl_list_item_t				*pItem;
-	ipoib_adapter_t				*pAdapter;
-
-	IPOIB_ENTER(IPOIB_DBG_IOCTL);
-
-	if( pIoStack->Parameters.DeviceIoControl.InputBufferLength !=
-		sizeof(IOCTL_IBAT_MAC_TO_PATH_IN) )
-	{
-		IPOIB_PRINT_EXIT( TRACE_LEVEL_ERROR, IPOIB_DBG_ERROR,
-			("Invalid input buffer size.\n") );
-		return STATUS_INVALID_PARAMETER;
-	}
-	
-	if( pIoStack->Parameters.DeviceIoControl.OutputBufferLength !=
-		sizeof(IOCTL_IBAT_MAC_TO_PATH_OUT) )
-	{
-		IPOIB_PRINT_EXIT( TRACE_LEVEL_ERROR, IPOIB_DBG_ERROR,
-			("Invalid output buffer size.\n") );
-		return STATUS_INVALID_PARAMETER;
-	}
-
-	pIn = (IOCTL_IBAT_MAC_TO_PATH_IN *) pIrp->AssociatedIrp.SystemBuffer;
-	pOut = (IOCTL_IBAT_MAC_TO_PATH_OUT *) pIrp->AssociatedIrp.SystemBuffer;
-
-	if( pIn->Version != IBAT_IOCTL_VERSION )
-	{
-		IPOIB_PRINT_EXIT( TRACE_LEVEL_ERROR, IPOIB_DBG_ERROR,
-			("Invalid version.\n") );
-		return STATUS_INVALID_PARAMETER;
-	}
-
-	KeAcquireInStackQueuedSpinLock( &g_ipoib.lock, &hdl );
-
-	for( pItem = cl_qlist_head( &g_ipoib.adapter_list );
-		pItem != cl_qlist_end( &g_ipoib.adapter_list );
-		pItem = cl_qlist_next( pItem ) )
-	{
-		pAdapter = CONTAINING_RECORD( pItem, ipoib_adapter_t, entry );
-		if( pIn->PortGuid != pAdapter->guids.port_guid.guid )
-			continue;
-
-		/* Found the port - lookup the MAC. */
-		cl_obj_lock( &pAdapter->obj );
-		if( pAdapter->p_port )
-		{
-			status = ipoib_mac_to_path(
-				pAdapter->p_port, *(mac_addr_t*)pIn->DestMac, &pOut->Path );
-
-			if( NT_SUCCESS( status ) )
-			{
-				pIrp->IoStatus.Information =
-					sizeof(IOCTL_IBAT_MAC_TO_PATH_OUT);
-			}
-		}
-		cl_obj_unlock( &pAdapter->obj );
-		break;
-	}
-
-	KeReleaseInStackQueuedSpinLock( &hdl );
-
-	IPOIB_EXIT( IPOIB_DBG_IOCTL );
-	return status;
-}
-
-
-NTSTATUS
-__ibat_ip_to_port(
-	IN				IRP							*pIrp,
-	IN				IO_STACK_LOCATION			*pIoStack )
-{
-	IOCTL_IBAT_IP_TO_PORT_IN	*pIn;
-	IOCTL_IBAT_IP_TO_PORT_OUT	*pOut;
-	KLOCK_QUEUE_HANDLE			hdl;
-	cl_list_item_t					*pItem;
-	ipoib_adapter_t				*pAdapter;
-	size_t						idx;
-	net_address_item_t			*pAddr;
-	NTSTATUS status = STATUS_NOT_FOUND;
-
-	IPOIB_ENTER(IPOIB_DBG_IOCTL);
-
-	if( pIoStack->Parameters.DeviceIoControl.InputBufferLength !=
-		sizeof(IOCTL_IBAT_IP_TO_PORT_IN) )
-	{
-		IPOIB_PRINT_EXIT( TRACE_LEVEL_ERROR, IPOIB_DBG_ERROR,
-			("Invalid input buffer size.\n") );
-		return STATUS_INVALID_PARAMETER;
-	}
-	
-	if( pIoStack->Parameters.DeviceIoControl.OutputBufferLength !=
-		sizeof(IOCTL_IBAT_IP_TO_PORT_OUT) )
-	{
-		IPOIB_PRINT_EXIT( TRACE_LEVEL_ERROR, IPOIB_DBG_ERROR,
-			("Invalid output buffer size.\n") );
-		return STATUS_INVALID_PARAMETER;
-	}
-
-	pIn = (IOCTL_IBAT_IP_TO_PORT_IN	*) pIrp->AssociatedIrp.SystemBuffer;
-	pOut = (IOCTL_IBAT_IP_TO_PORT_OUT *) pIrp->AssociatedIrp.SystemBuffer;
-
-	if( pIn->Version != IBAT_IOCTL_VERSION )
-	{
-		IPOIB_PRINT_EXIT( TRACE_LEVEL_ERROR, IPOIB_DBG_ERROR,
-			("Invalid version.\n") );
-		return STATUS_INVALID_PARAMETER;
-	}
-
-	if (pIn->Address.IpVersion != 4)
-	{
-		IPOIB_PRINT_EXIT( TRACE_LEVEL_ERROR, IPOIB_DBG_ERROR,
-			("Invalid IP version (%d). Supported only 4\n", pIn->Address.IpVersion) );
-		return STATUS_INVALID_PARAMETER;
-	}
-
-	KeAcquireInStackQueuedSpinLock( &g_ipoib.lock, &hdl );
-	for( pItem = cl_qlist_head( &g_ipoib.adapter_list );
-		pItem != cl_qlist_end( &g_ipoib.adapter_list );
-		pItem = cl_qlist_next( pItem ) )
-	{
-		pAdapter = CONTAINING_RECORD( pItem, ipoib_adapter_t, entry );
-
-		cl_obj_lock( &pAdapter->obj );
-
-		for( idx = 0;
-			idx < cl_vector_get_size( &pAdapter->ip_vector );
-			idx++ )
-		{
-			pAddr = (net_address_item_t*)
-				cl_vector_get_ptr( &pAdapter->ip_vector, idx );
-
-			if (!memcmp( &pIn->Address.Address[12], pAddr->address.as_bytes, IPV4_ADDR_SIZE))
-			{
-				pOut->Port.CaGuid = pAdapter->guids.ca_guid;
-				pOut->Port.PortGuid = pAdapter->guids.port_guid.guid;
-				pOut->Port.PKey = IB_DEFAULT_PKEY;
-				pOut->Port.PortNum = pAdapter->guids.port_num;
-				pIrp->IoStatus.Information = sizeof(IOCTL_IBAT_IP_TO_PORT_OUT);
-				status = STATUS_SUCCESS;
-				break;
-			}
-		}
-		cl_obj_unlock( &pAdapter->obj );
-		if (status == STATUS_SUCCESS)
-			break;
-	}
-
-	KeReleaseInStackQueuedSpinLock( &hdl );
-	IPOIB_EXIT( IPOIB_DBG_IOCTL );
-	return status;
-}
-
-void
-ipoib_ref_ibat()
-{
-	UNICODE_STRING      DeviceName;
-    UNICODE_STRING      DeviceLinkUnicodeString;
-    NDIS_DEVICE_OBJECT_ATTRIBUTES   DeviceObjectAttributes;
-    PDRIVER_DISPATCH    DispatchTable[IRP_MJ_MAXIMUM_FUNCTION+1];
-
-	NDIS_STATUS         Status = NDIS_STATUS_SUCCESS;
-
-	IPOIB_ENTER( IPOIB_DBG_IOCTL );
-
-	if( InterlockedIncrement( &g_ipoib.ibat_ref ) == 1 )
-	{
-
-		memset(DispatchTable, 0, (IRP_MJ_MAXIMUM_FUNCTION+1) * sizeof(PDRIVER_DISPATCH));
-				
-		DispatchTable[IRP_MJ_CREATE]					= __ipoib_create;
-		DispatchTable[IRP_MJ_CLEANUP]					= __ipoib_cleanup;
-		DispatchTable[IRP_MJ_CLOSE]						= __ipoib_close;
-		DispatchTable[IRP_MJ_DEVICE_CONTROL]			= __ipoib_dispatch;
-		DispatchTable[IRP_MJ_INTERNAL_DEVICE_CONTROL] 	= __ipoib_dispatch;		
-		
-				
-		NdisInitUnicodeString( &DeviceName, IBAT_DEV_NAME );
-		NdisInitUnicodeString( &DeviceLinkUnicodeString, IBAT_DOS_DEV_NAME );
-				
-		
-		memset(&DeviceObjectAttributes, 0, sizeof(NDIS_DEVICE_OBJECT_ATTRIBUTES));
-		
-		DeviceObjectAttributes.Header.Type = NDIS_OBJECT_TYPE_DEFAULT; // type implicit from the context
-		DeviceObjectAttributes.Header.Revision = NDIS_DEVICE_OBJECT_ATTRIBUTES_REVISION_1;
-		DeviceObjectAttributes.Header.Size = sizeof(NDIS_DEVICE_OBJECT_ATTRIBUTES);
-		DeviceObjectAttributes.DeviceName = &DeviceName;
-		DeviceObjectAttributes.SymbolicName = &DeviceLinkUnicodeString;
-		DeviceObjectAttributes.MajorFunctions = &DispatchTable[0];
-		DeviceObjectAttributes.ExtensionSize = 0;
-		DeviceObjectAttributes.DefaultSDDLString = NULL;
-		DeviceObjectAttributes.DeviceClassGuid = 0;
-		
-		Status = NdisRegisterDeviceEx(
-							g_IpoibMiniportDriverHandle,
-							&DeviceObjectAttributes,
-							&g_ipoib.h_ibat_dev,
-							&g_ipoib.h_ibat_dev_handle);
-
-
-	
-		if( Status != NDIS_STATUS_SUCCESS )
-		{
-			IPOIB_PRINT( TRACE_LEVEL_ERROR, IPOIB_DBG_ERROR, 
-				("NdisRegisterDeviceEx failed with status of %d\n", Status) );
-		}
-	}
-
-	IPOIB_EXIT( IPOIB_DBG_IOCTL );
-}
-
-
-void
-ipoib_deref_ibat()
-{
-	IPOIB_ENTER( IPOIB_DBG_IOCTL );
-
-	if( InterlockedDecrement( &g_ipoib.ibat_ref ) )
-	{
-		IPOIB_EXIT( IPOIB_DBG_IOCTL );
-		return;
-	}
-
-	if( g_ipoib.h_ibat_dev )
-	{
-		NdisDeregisterDeviceEx( g_ipoib.h_ibat_dev_handle );
-		g_ipoib.h_ibat_dev = NULL;
-		g_ipoib.h_ibat_dev_handle = NULL; //TODO set here INVALID_HANDLE_VALUE
-	}
-
-	IPOIB_EXIT( IPOIB_DBG_IOCTL );
-}
-
-
-static NTSTATUS
-__ipoib_create(
-	IN				DEVICE_OBJECT* const		pDevObj,
-	IN				IRP* const					pIrp )
-{
-	IPOIB_ENTER( IPOIB_DBG_IOCTL );
-
-	UNREFERENCED_PARAMETER( pDevObj );
-
-	ipoib_ref_ibat();
-
-	pIrp->IoStatus.Status = STATUS_SUCCESS;
-	pIrp->IoStatus.Information = 0;
-	IoCompleteRequest( pIrp, IO_NO_INCREMENT );
-
-	IPOIB_EXIT( IPOIB_DBG_IOCTL );
-	return STATUS_SUCCESS;
-}
-
-
-static NTSTATUS
-__ipoib_cleanup(
-	IN				DEVICE_OBJECT* const		pDevObj,
-	IN				IRP* const					pIrp )
-{
-	IPOIB_ENTER( IPOIB_DBG_IOCTL );
-
-	UNREFERENCED_PARAMETER( pDevObj );
-
-	ipoib_deref_ibat();
-
-	pIrp->IoStatus.Status = STATUS_SUCCESS;
-	pIrp->IoStatus.Information = 0;
-	IoCompleteRequest( pIrp, IO_NO_INCREMENT );
-
-	IPOIB_EXIT( IPOIB_DBG_IOCTL );
-	return STATUS_SUCCESS;
-}
-
-
-static NTSTATUS
-__ipoib_close(
-	IN				DEVICE_OBJECT* const		pDevObj,
-	IN				IRP* const					pIrp )
-{
-	IPOIB_ENTER( IPOIB_DBG_IOCTL );
-
-	UNREFERENCED_PARAMETER( pDevObj );
-
-	pIrp->IoStatus.Status = STATUS_SUCCESS;
-	pIrp->IoStatus.Information = 0;
-	IoCompleteRequest( pIrp, IO_NO_INCREMENT );
-
-	IPOIB_EXIT( IPOIB_DBG_IOCTL );
-	return STATUS_SUCCESS;
-}
-
-static NTSTATUS
-__ipoib_dispatch(
-	IN				DEVICE_OBJECT* const		pDevObj,
-	IN				IRP* const					pIrp )
-{
-	IO_STACK_LOCATION	*pIoStack;
-	NTSTATUS			status = STATUS_SUCCESS;
-
-	IPOIB_ENTER( IPOIB_DBG_IOCTL );
-
-	UNREFERENCED_PARAMETER( pDevObj );
-
-	pIoStack = IoGetCurrentIrpStackLocation( pIrp );
-
-	pIrp->IoStatus.Information = 0;
-
-	switch( pIoStack->Parameters.DeviceIoControl.IoControlCode )
-	{
-	case IOCTL_IBAT_PORTS:
-		IPOIB_PRINT(TRACE_LEVEL_INFORMATION, IPOIB_DBG_IOCTL,
-			("IOCTL_IBAT_PORTS received\n") );
-		status = __ibat_get_ports( pIrp, pIoStack );
-		break;
-
-	case IOCTL_IBAT_IP_ADDRESSES:
-		IPOIB_PRINT(TRACE_LEVEL_INFORMATION, IPOIB_DBG_IOCTL,
-			("IOCTL_IBAT_IP_ADDRESSES received\n" ));
-		status = __ibat_get_ips( pIrp, pIoStack );
-		break;
-
-	case IOCTL_IBAT_MAC_TO_GID:
-		IPOIB_PRINT(TRACE_LEVEL_INFORMATION, IPOIB_DBG_IOCTL,
-			("IOCTL_IBAT_MAC_TO_GID received\n" ));
-		status = __ibat_mac_to_gid( pIrp, pIoStack );
-		break;
-
-	case IOCTL_IBAT_IP_TO_PORT:
-		IPOIB_PRINT(TRACE_LEVEL_INFORMATION, IPOIB_DBG_IOCTL,
-			("IOCTL_IBAT_IP_TO_PORT received\n" ));
-		status = __ibat_ip_to_port( pIrp, pIoStack );
-		break;
-
-	case IOCTL_IBAT_MAC_TO_PATH:
-		IPOIB_PRINT(TRACE_LEVEL_INFORMATION, IPOIB_DBG_IOCTL,
-			("IOCTL_IBAT_MAC_TO_PATH received\n" ));
-		status = __ibat_mac_to_path( pIrp, pIoStack );
-		break;
-
-	default:
-		IPOIB_PRINT( TRACE_LEVEL_VERBOSE, IPOIB_DBG_IOCTL,
-			("unknow IOCTL code = 0x%x\n",
-			pIoStack->Parameters.DeviceIoControl.IoControlCode) );
-		status = STATUS_INVALID_PARAMETER;
-	}
-
-	pIrp->IoStatus.Status = status;
-	IoCompleteRequest( pIrp, IO_NO_INCREMENT );
-
-	IPOIB_EXIT( IPOIB_DBG_IOCTL );
-	return status;
-}
-
-PDRIVER_DISPATCH ipoib_get_dispatch_func()
-{
-	return __ipoib_dispatch;
-}
-
-
Index: .\ulp\ipoib\kernel\ipoib_ibat.h
===================================================================
--- .\ulp\ipoib\kernel\ipoib_ibat.h	(revision 3414)
+++ .\ulp\ipoib\kernel\ipoib_ibat.h	(working copy)
@@ -1,44 +0,0 @@
-/*
- * Copyright (c) 2005 Mellanox Technologies.  All rights reserved.
- * Copyright (c) 2005 SilverStorm Technologies.  All rights reserved.
- *
- * This software is available to you under the OpenIB.org BSD license
- * below:
- *
- *     Redistribution and use in source and binary forms, with or
- *     without modification, are permitted provided that the following
- *     conditions are met:
- *
- *      - Redistributions of source code must retain the above
- *        copyright notice, this list of conditions and the following
- *        disclaimer.
- *
- *      - Redistributions in binary form must reproduce the above
- *        copyright notice, this list of conditions and the following
- *        disclaimer in the documentation and/or other materials
- *        provided with the distribution.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
- * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
- * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
- * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- */
-
-
-#ifndef _IPOIB_IBAT_H_
-#define _IPOIB_IBAT_H_
-
-
-void
-ipoib_ref_ibat();
-
-void
-ipoib_deref_ibat();
-
-PDRIVER_DISPATCH ipoib_get_dispatch_func();
-
-#endif	/* _IPOIB_IBAT_H_ */
--- c:\dev\openib\ofw\gen1\branches\mlx4_30\trunk\ulp\ipoib\kernel\SOURCES	Thu Mar 29 00:15:08 2012
+++ .\ulp\ipoib\kernel\SOURCES	Thu Jul 26 15:31:14 2012
@@ -20,7 +20,6 @@ ENABLE_EVENT_TRACING=1
 		ipoib_adapter.cpp \
 		ipoib_endpoint.cpp \
 		ipoib_port.cpp \
-		ipoib_ibat.cpp \
 		ipoib_cm.cpp	\
 		ipoib_xfr_mgr.cpp \
 		ipoib_stat.cpp \
Index: .\inc\kernel\iba\ibat.h
===================================================================
--- .\inc\kernel\iba\ibat.h	(revision 0)
+++ .\inc\kernel\iba\ibat.h	(revision 0)
@@ -0,0 +1,237 @@
+/*
+ * Copyright (c) Microsoft Corporation.  All rights reserved.
+ *
+ * This software is available to you under the OpenIB.org BSD license
+ * below:
+ *
+ *     Redistribution and use in source and binary forms, with or
+ *     without modification, are permitted provided that the following
+ *     conditions are met:
+ *
+ *      - Redistributions of source code must retain the above
+ *        copyright notice, this list of conditions and the following
+ *        disclaimer.
+ *
+ *      - Redistributions in binary form must reproduce the above
+ *        copyright notice, this list of conditions and the following
+ *        disclaimer in the documentation and/or other materials
+ *        provided with the distribution.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+#ifndef _IBAT_H_
+#define _IBAT_H_
+
+#include "iba\ib_at_ioctl.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+typedef struct IbatRouter* IBAT_ROUTING_CONTEXT;
+
+//
+// The following function types are provided to kernel drivers that serve
+// as sources of routing data.  These functions are not intended to be used
+// by end-users.
+//
+
+//
+// Registers a routing provider with IBAT, including the local NET_LUID value
+// for the NDIS interface used to query IP Helper.
+//
+// Returns a routing context that can be used to update route information.
+//
+typedef NTSTATUS
+FN_IBAT_REGISTER(
+    __in UINT64 mac,
+    __in UINT64 luid,
+    __in const GUID* pDriverId,
+    __in IBAT_PORT_RECORD* pPortRecord,
+    __in BOOLEAN isRoCE,
+    __out IBAT_ROUTING_CONTEXT* pRoutingContext
+    );
+FN_IBAT_REGISTER IbatRegister;
+
+
+//
+// Updates the NET_LUID value associated with an existing registration.
+//
+typedef NTSTATUS
+FN_IBAT_UPDATE_REGISTRATION(
+    __in UINT64 mac,
+    __in UINT64 luid
+    );
+FN_IBAT_UPDATE_REGISTRATION IbatUpdateRegistration;
+
+//
+// Removes a routing provider from IBAT, including all associated routing information.
+//
+typedef VOID
+FN_IBAT_DEREGISTER(
+    __in IBAT_ROUTING_CONTEXT routingContext
+    );
+FN_IBAT_DEREGISTER IbatDeregister;
+
+//
+// Adds or updates a route to the destination MAC address.
+//
+typedef NTSTATUS
+FN_IBAT_UPDATE_ROUTE(
+    __in IBAT_ROUTING_CONTEXT routingContext,
+    __in UINT64 destMac,
+    __in const ib_gid_t* pDestGid
+    );
+FN_IBAT_UPDATE_ROUTE IbatUpdateRoute;
+
+//
+// Deletes all routing information for the supplied routing context.
+//
+typedef VOID
+FN_IBAT_CLEAR_ALL_ROUTES(
+    __in IBAT_ROUTING_CONTEXT routingContext
+    );
+FN_IBAT_CLEAR_ALL_ROUTES IbatClearAllRoutes;
+
+
+//
+// Initializes global structures - called by whoever provides IBAT support.
+//
+NTSTATUS
+IbatInitialize();
+
+
+//
+// Cleans up global structures.  Called by whoever provides IBAT support.
+//
+VOID
+IbatCleanup();
+
+
+//
+// Get the list of local IP addresses for a given input NIC port.
+//
+// Input parameter values of 0 indicate wildcard.
+//
+// TODO: Should pAddrs be SOCKADDR_STORAGE to allow extensions in the future to
+// other address families besides AF_INET and AF_INET6?
+//
+typedef
+__drv_maxFunctionIRQL(APC_LEVEL)
+NTSTATUS
+FN_IBAT_GET_IP_LIST(
+    __in_opt const GUID* pDriverId,
+    __in UINT64 caGuid,
+    __in UINT64 portGuid,
+    __in UINT16 pkey,
+    __inout ULONG* pnAddrs,
+    __out SOCKADDR_INET* pAddrs
+    );
+FN_IBAT_GET_IP_LIST IbatGetIpList;
+
+__drv_maxFunctionIRQL(PASSIVE_LEVEL)
+NTSTATUS
+IbatGetIpListIoctl(
+    __in IRP* pIrp
+    );
+
+
+//
+// Gets the local NIC port information for a given local IP address.
+//
+typedef
+__drv_maxFunctionIRQL(APC_LEVEL)
+NTSTATUS
+FN_IBAT_IP_TO_PORT(
+    __in const SOCKADDR_INET* pAddr,
+    __in_opt const GUID* pDriverId,
+    __out IBAT_PORT_RECORD* pPortRecord
+    );
+FN_IBAT_IP_TO_PORT IbatIpToPort;
+
+__drv_maxFunctionIRQL(PASSIVE_LEVEL)
+NTSTATUS
+IbatIpToPortIoctl(
+    __in IRP* pIrp
+    );
+
+
+typedef
+__drv_maxFunctionIRQL(APC_LEVEL)
+NTSTATUS
+FN_IBAT_MAC_TO_PORT(
+    __in UINT64 mac,
+    __in_opt const GUID* pDriverId,
+    __out IBAT_PORT_RECORD* pPortRecord
+    );
+FN_IBAT_MAC_TO_PORT IbatMacToPort;
+
+
+//
+// Gets a path record given a local and remote IP address.
+//
+// If the function returns STATUS_PENDING, completion will be indicated through
+// the completion callback and the path out parameter is not used.
+//
+typedef
+__drv_maxFunctionIRQL(DISPATCH_LEVEL)
+VOID
+FN_IBAT_QUERY_PATH_CALLBACK(
+    __in VOID* completionContext,
+    __in NTSTATUS status,
+    __in ib_path_rec_t* const pPath
+    );
+
+
+typedef
+__drv_maxFunctionIRQL(APC_LEVEL)
+NTSTATUS
+FN_IBAT_QUERY_PATH_BY_IP_ADDRESS(
+    __in const SOCKADDR_INET* pLocalAddress,
+    __in const SOCKADDR_INET* pRemoteAddress,
+    __in FN_IBAT_QUERY_PATH_CALLBACK* completionCallback,
+    __in VOID* completionContext,
+    __out ib_path_rec_t* pPath
+    );
+FN_IBAT_QUERY_PATH_BY_IP_ADDRESS IbatQueryPathByIpAddress;
+
+
+typedef
+__drv_maxFunctionIRQL(APC_LEVEL)
+NTSTATUS
+FN_IBAT_QUERY_PATH_BY_PHYSICAL_ADDRESS(
+    __in UINT64 srcMac,
+    __in UINT64 destMac,
+    __in FN_IBAT_QUERY_PATH_CALLBACK* completionCallback,
+    __in VOID* completionContext,
+    __out ib_path_rec_t* pPath
+    );
+FN_IBAT_QUERY_PATH_BY_PHYSICAL_ADDRESS IbatQueryPathByPhysicalAddress;
+
+
+typedef
+__drv_maxFunctionIRQL(APC_LEVEL)
+NTSTATUS
+FN_IBAT_RESOLVE_PHYSICAL_ADDRESS(
+    __in const SOCKADDR_INET*   pLocalAddress,
+    __in const SOCKADDR_INET*   pRemoteAddress,
+    __out UINT64*               pSrcMac,
+    __out UINT64*               pDestMac
+    );
+FN_IBAT_RESOLVE_PHYSICAL_ADDRESS IbatResolvePhysicalAddress;
+
+#ifdef __cplusplus
+} //extern "C" {
+#endif
+
+
+#endif  // _IBAT_H_
Index: .\inc\kernel\iba\ibat_ifc.h
===================================================================
--- .\inc\kernel\iba\ibat_ifc.h	(revision 0)
+++ .\inc\kernel\iba\ibat_ifc.h	(revision 0)
@@ -0,0 +1,77 @@
+/*
+ * Copyright (c) Microsoft Corporation.  All rights reserved.
+ *
+ * This software is available to you under the OpenIB.org BSD license
+ * below:
+ *
+ *     Redistribution and use in source and binary forms, with or
+ *     without modification, are permitted provided that the following
+ *     conditions are met:
+ *
+ *      - Redistributions of source code must retain the above
+ *        copyright notice, this list of conditions and the following
+ *        disclaimer.
+ *
+ *      - Redistributions in binary form must reproduce the above
+ *        copyright notice, this list of conditions and the following
+ *        disclaimer in the documentation and/or other materials
+ *        provided with the distribution.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ */
+
+#if !defined _IBAT_IFC_H_
+#define _IBAT_IFC_H_
+
+#include <iba\ibat.h>
+
+#define IBAT_INTERFACE_VERSION		(3)
+
+
+/* Interface definitions */
+typedef struct _IBAT_IFC
+{
+    /* Standard interface header. */
+    INTERFACE                               InterfaceHeader;
+
+    FN_IBAT_REGISTER*                       Register;
+    FN_IBAT_DEREGISTER*                     Deregister;
+    FN_IBAT_UPDATE_REGISTRATION*            UpdateRegistration;
+    FN_IBAT_UPDATE_ROUTE*                   UpdateRoute;
+    FN_IBAT_CLEAR_ALL_ROUTES*               ClearAllRoutes;
+    FN_IBAT_GET_IP_LIST*                    GetIpList;
+    FN_IBAT_IP_TO_PORT*                     IpToPort;
+    FN_IBAT_QUERY_PATH_BY_IP_ADDRESS*       QueryPathByIpAddress;
+    FN_IBAT_QUERY_PATH_BY_PHYSICAL_ADDRESS* QueryPathByPhysicalAddress;
+    FN_IBAT_RESOLVE_PHYSICAL_ADDRESS*       ResolvePhysicalAddress;
+    FN_IBAT_MAC_TO_PORT*                    MacToPort;
+
+}   IBAT_IFC;
+
+
+EXTERN_C
+void
+IbatGetInterface(
+    __out IBAT_IFC* pIbatIfc
+    );
+
+#endif	/* !defined _IB_AT_IFC_H_ */
+
+/*
+ * AL interface GUID.  The GUID is defined outside the conditional include
+ * on purpose so that it can be instantiated only once where it is actually
+ * needed.  See the DDK docs section "Using GUIDs in Drivers" for more info.
+ */
+#ifdef DEFINE_GUID
+// {6497B483-E13E-4887-97CE-1F0EE1D5FF7B}
+DEFINE_GUID(GUID_IBAT_INTERFACE, 
+0x6497b483, 0xe13e, 0x4887, 0x97, 0xce, 0x1f, 0xe, 0xe1, 0xd5, 0xff, 0x7b);
+#endif // DEFINE_GUID
--- c:\dev\openib\ofw\gen1\branches\mlx4_30\trunk\core\bus\kernel\SOURCES	Wed Aug 01 17:17:06 2012
+++ .\core\bus\kernel\SOURCES	Thu Jul 26 21:34:07 2012
@@ -26,10 +26,13 @@ SOURCES= ibbus.rc		\
 
 TARGETLIBS= \
     $(DDK_LIB_PATH)\ntstrsafe.lib \
+    $(DDK_LIB_PATH)\netio.lib \
+    $(DDK_LIB_PATH)\msnetioid.lib \
 	$(TARGETPATH)\*\complib.lib \
 	$(TARGETPATH)\*\ibal.lib \
 	$(TARGETPATH)\*\fip.lib \
-        $(TARGETPATH)\*\genutils.lib
+    $(TARGETPATH)\*\genutils.lib \
+    $(TARGETPATH)\*\ibat.lib \
 	
 !if !defined(DDK_TARGET_OS) || "$(DDK_TARGET_OS)"=="WinXP"
 TARGETLIBS=$(TARGETLIBS) $(DDK_LIB_PATH)\csq.lib
--- c:\dev\openib\ofw\gen1\branches\mlx4_30\trunk\core\al\kernel\SOURCES	Wed Aug 01 17:17:06 2012
+++ .\core\al\kernel\SOURCES	Thu Jul 26 15:31:13 2012
@@ -18,6 +18,7 @@ SOURCES= ibal.rc			\
 	al_cm.c					\
 	al_cm_cep.c				\
 	al_dev.c				\
+    al_ibat.cpp             \
 	al_ioc_pnp.c			\
 	al_mad_pool.c			\
 	al_fmr_pool.c			\
Index: .\core\al\kernel\al_ibat.cpp
===================================================================
--- .\core\al\kernel\al_ibat.cpp	(revision 0)
+++ .\core\al\kernel\al_ibat.cpp	(revision 0)
@@ -0,0 +1,327 @@
+/*
+ * Copyright (c) 2005 Mellanox Technologies.  All rights reserved.
+ * Copyright (c) 2005 SilverStorm Technologies.  All rights reserved.
+ * Portions Copyright (c) 2008 Microsoft Corporation.  All rights reserved.
+ *
+ * This software is available to you under the OpenIB.org BSD license
+ * below:
+ *
+ *     Redistribution and use in source and binary forms, with or
+ *     without modification, are permitted provided that the following
+ *     conditions are met:
+ *
+ *      - Redistributions of source code must retain the above
+ *        copyright notice, this list of conditions and the following
+ *        disclaimer.
+ *
+ *      - Redistributions in binary form must reproduce the above
+ *        copyright notice, this list of conditions and the following
+ *        disclaimer in the documentation and/or other materials
+ *        provided with the distribution.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ */
+
+
+#include "al_dev.h"
+#include <iba\ibat.h>
+extern "C"
+{
+#include "al_debug.h"
+}
+
+#if defined(EVENT_TRACING)
+#ifdef offsetof
+#undef offsetof
+#endif
+#include "al_ibat.tmh"
+#endif
+
+
+static NTSTATUS
+__ibat_get_ips(
+    IN              IRP                         *pIrp,
+    IN              IO_STACK_LOCATION           *pIoStack )
+{
+    IOCTL_IBAT_IP_ADDRESSES_IN  *pIn;
+    IOCTL_IBAT_IP_ADDRESSES_OUT *pOut;
+    ULONG                       nAddr;
+    ULONG                       maxIps;
+    NTSTATUS                    status;
+
+    AL_ENTER(AL_DBG_DEV);
+
+    if( pIoStack->Parameters.DeviceIoControl.InputBufferLength !=
+        sizeof(IOCTL_IBAT_IP_ADDRESSES_IN) )
+    {
+        AL_PRINT_EXIT( TRACE_LEVEL_ERROR, AL_DBG_ERROR,
+            ("Invalid input buffer size.\n") );
+        return STATUS_INVALID_PARAMETER;
+    }
+
+    if( pIoStack->Parameters.DeviceIoControl.OutputBufferLength <
+        sizeof(IOCTL_IBAT_IP_ADDRESSES_OUT) )
+    {
+        AL_PRINT_EXIT( TRACE_LEVEL_ERROR, AL_DBG_ERROR,
+            ("Invalid output buffer size.\n") );
+        return STATUS_INVALID_PARAMETER;
+    }
+
+    pIn = (IOCTL_IBAT_IP_ADDRESSES_IN *) pIrp->AssociatedIrp.SystemBuffer;
+    pOut = (IOCTL_IBAT_IP_ADDRESSES_OUT *) pIrp->AssociatedIrp.SystemBuffer;
+
+    if( pIn->Version != IBAT_IOCTL_VERSION )
+    {
+        AL_PRINT_EXIT( TRACE_LEVEL_ERROR, AL_DBG_ERROR,
+            ("Invalid version.\n") );
+        return STATUS_INVALID_PARAMETER;
+    }
+
+    maxIps = 1 +
+        ((pIoStack->Parameters.DeviceIoControl.OutputBufferLength -
+        sizeof(IOCTL_IBAT_IP_ADDRESSES_OUT)) / sizeof(SOCKADDR_INET));
+
+    nAddr = maxIps;
+    status = IbatGetIpList( NULL, 0, pIn->PortGuid, 0, &nAddr, pOut->Address );
+    if( status == STATUS_MORE_ENTRIES )
+    {
+        pOut->AddressCount = maxIps;
+    }
+    else if( status == STATUS_SUCCESS )
+    {
+        pOut->AddressCount = nAddr;
+    }
+    else
+    {
+        pOut->AddressCount = 0;
+        return status;
+    }
+
+    pOut->Size =
+        sizeof(*pOut) - sizeof(pOut->Address) + (sizeof(pOut->Address) * nAddr);
+    pIrp->IoStatus.Information = sizeof(*pOut) - sizeof(pOut->Address);
+    if( nAddr > maxIps )
+    {
+        pIrp->IoStatus.Information += sizeof(pOut->Address) * maxIps;
+    }
+    else
+    {
+        pIrp->IoStatus.Information += sizeof(pOut->Address) * nAddr;
+    }
+
+    AL_EXIT( AL_DBG_DEV );
+    return STATUS_SUCCESS;
+}
+
+
+static VOID
+__ibat_query_cb(
+    VOID* context,
+    NTSTATUS status,
+    ib_path_rec_t* const pPath
+    )
+{
+    IRP* pIrp = reinterpret_cast<IRP*>(context);
+
+    if( !NT_SUCCESS(status) )
+    {
+        pIrp->IoStatus.Information = 0;
+    }
+    else
+    {
+        pIrp->IoStatus.Information = sizeof(*pPath);
+        RtlCopyMemory( pIrp->AssociatedIrp.SystemBuffer, pPath, sizeof(*pPath) );
+    }
+    pIrp->IoStatus.Status = status;
+    IoCompleteRequest( pIrp, IO_NO_INCREMENT );
+}
+
+
+//
+// Summary:
+//  IOCTL handler wrapper for IbatCreatePath
+//
+// Returns:
+//  STATUS_SUCCESS - on success
+//  STATUS_NOT_FOUND - when local address does not match IB port.
+//  STATUS_BAD_NETWORK_NAME - when the remote address can not be resolved.
+//  STATUS_NOT_SUPPORTED - when remote physical address is not of expected size.
+//  STATUS_INVALID_PARAMETER - if input or output parameters are not valid
+//  STATUS_INVALID_ADDRESS - when input address are not othe same version or are a valid version.
+//
+static
+NTSTATUS
+__ibat_query_path(
+    __in IRP*                       pIrp,
+    __in IO_STACK_LOCATION*         pIoStack
+    )
+{
+    IOCTL_IBAT_QUERY_PATH_IN*      pIn;
+    IOCTL_IBAT_QUERY_PATH_OUT*     pOut;
+    NTSTATUS                        status;
+
+    if( pIoStack->Parameters.DeviceIoControl.InputBufferLength != sizeof(*pIn) )
+    {
+        AL_PRINT_EXIT( TRACE_LEVEL_ERROR, AL_DBG_ERROR,
+            ("Invalid input buffer size.\n") );
+        return STATUS_INVALID_PARAMETER;
+    }
+
+    if( pIoStack->Parameters.DeviceIoControl.OutputBufferLength != sizeof(*pOut) )
+    {
+        AL_PRINT_EXIT( TRACE_LEVEL_ERROR, AL_DBG_ERROR,
+            ("Invalid output buffer size.\n") );
+        return STATUS_INVALID_PARAMETER;
+    }
+
+    pIn = static_cast<IOCTL_IBAT_QUERY_PATH_IN*>(pIrp->AssociatedIrp.SystemBuffer);
+    pOut = static_cast<IOCTL_IBAT_QUERY_PATH_OUT*>( pIrp->AssociatedIrp.SystemBuffer );
+
+    if( pIn->Version != IBAT_IOCTL_VERSION )
+    {
+        AL_PRINT_EXIT( TRACE_LEVEL_ERROR, AL_DBG_ERROR,
+            ("Invalid version.\n") );
+        return STATUS_INVALID_PARAMETER;
+    }
+
+    IoMarkIrpPending( pIrp );
+    status = IbatQueryPathByIpAddress(
+        &pIn->LocalAddress,
+        &pIn->RemoteAddress,
+        __ibat_query_cb,
+        pIrp,
+        pOut
+        );
+    if( status == STATUS_SUCCESS )
+    {
+        pIrp->IoStatus.Information = sizeof(*pOut);
+        IoCompleteRequest( pIrp, IO_NO_INCREMENT );
+    }
+    else if( status != STATUS_PENDING )
+    {
+        pIrp->IoStatus.Information = 0;
+        IoCompleteRequest( pIrp, IO_NO_INCREMENT );
+    }
+
+    AL_EXIT( AL_DBG_DEV );
+    return STATUS_PENDING;
+}
+
+
+static NTSTATUS
+__ibat_ip_to_port(
+    IN              IRP                         *pIrp,
+    IN              IO_STACK_LOCATION           *pIoStack )
+{
+    IOCTL_IBAT_IP_TO_PORT_IN    *pIn;
+    IOCTL_IBAT_IP_TO_PORT_OUT   *pOut;
+    NTSTATUS                    status;
+
+    AL_ENTER(AL_DBG_DEV);
+
+    if( pIoStack->Parameters.DeviceIoControl.InputBufferLength !=
+        sizeof(IOCTL_IBAT_IP_TO_PORT_IN) )
+    {
+        AL_PRINT_EXIT( TRACE_LEVEL_ERROR, AL_DBG_ERROR,
+            ("Invalid input buffer size.\n") );
+        return STATUS_INVALID_PARAMETER;
+    }
+
+    if( pIoStack->Parameters.DeviceIoControl.OutputBufferLength !=
+        sizeof(IOCTL_IBAT_IP_TO_PORT_OUT) )
+    {
+        AL_PRINT_EXIT( TRACE_LEVEL_ERROR, AL_DBG_ERROR,
+            ("Invalid output buffer size.\n") );
+        return STATUS_INVALID_PARAMETER;
+    }
+
+    pIn = (IOCTL_IBAT_IP_TO_PORT_IN *) pIrp->AssociatedIrp.SystemBuffer;
+    pOut = (IOCTL_IBAT_IP_TO_PORT_OUT *) pIrp->AssociatedIrp.SystemBuffer;
+
+    if( pIn->Version != IBAT_IOCTL_VERSION )
+    {
+        AL_PRINT_EXIT( TRACE_LEVEL_ERROR, AL_DBG_ERROR,
+            ("Invalid version.\n") );
+        return STATUS_INVALID_PARAMETER;
+    }
+
+    status = IbatIpToPort( &pIn->Address, NULL, &pOut->Port );
+    if( status == STATUS_SUCCESS )
+    {
+        pIrp->IoStatus.Information = sizeof(*pOut);
+    }
+    else
+    {
+        if( status == STATUS_INVALID_ADDRESS )
+        {
+            status = STATUS_NOT_FOUND;
+        }
+        pIrp->IoStatus.Information = 0;
+    }
+
+    AL_EXIT( AL_DBG_DEV );
+    return status;
+}
+
+
+extern "C"
+NTSTATUS
+ibat_ioctl(
+    __in IRP* pIrp
+    )
+{
+    IO_STACK_LOCATION   *pIoStack;
+    NTSTATUS            status = STATUS_SUCCESS;
+
+    AL_ENTER( AL_DBG_DEV );
+
+    pIoStack = IoGetCurrentIrpStackLocation( pIrp );
+
+    pIrp->IoStatus.Information = 0;
+
+    switch( pIoStack->Parameters.DeviceIoControl.IoControlCode )
+    {
+    case IOCTL_IBAT_IP_ADDRESSES:
+        AL_PRINT(TRACE_LEVEL_INFORMATION, AL_DBG_DEV,
+            ("IOCTL_IBAT_IP_ADDRESSES received\n" ));
+        status = __ibat_get_ips( pIrp, pIoStack );
+        break;
+
+    case IOCTL_IBAT_IP_TO_PORT:
+        AL_PRINT(TRACE_LEVEL_INFORMATION, AL_DBG_DEV,
+            ("IOCTL_IBAT_IP_TO_PORT received\n" ));
+        status = __ibat_ip_to_port( pIrp, pIoStack );
+        break;
+
+    case IOCTL_IBAT_QUERY_PATH:
+        AL_PRINT(TRACE_LEVEL_INFORMATION, AL_DBG_DEV,
+            ("IOCTL_IBAT_QUERY_PATH received\n" ));
+        status = __ibat_query_path( pIrp, pIoStack );
+        break;
+
+    default:
+        AL_PRINT( TRACE_LEVEL_VERBOSE, AL_DBG_DEV,
+            ("unknow IOCTL code = 0x%x\n",
+            pIoStack->Parameters.DeviceIoControl.IoControlCode) );
+        status = STATUS_INVALID_DEVICE_REQUEST;
+    }
+
+    if( status != STATUS_PENDING )
+    {
+        pIrp->IoStatus.Status = status;
+        IoCompleteRequest( pIrp, IO_NO_INCREMENT );
+    }
+
+    AL_EXIT( AL_DBG_DEV );
+    return status;
+}
+
+
diff -dwup3 -X excl.txt -r c:\dev\openib\ofw\gen1\branches\mlx4_30\trunk\tests\wherebu\user\wherebu.cpp .\tests\wherebu\user\wherebu.cpp
--- c:\dev\openib\ofw\gen1\branches\mlx4_30\trunk\tests\wherebu\user\wherebu.cpp	Thu May 31 11:22:13 2012
+++ .\tests\wherebu\user\wherebu.cpp	Tue Aug 07 14:40:31 2012
@@ -70,7 +70,7 @@ int __cdecl main(int argc, char *argv[])
     destAddr.sin_addr.s_addr = inet_addr( argv[2] );
 
     ib_path_rec_t path;
-    HRESULT hr = IBAT::Resolve(
+    HRESULT hr = IBAT::QueryPath(
         (struct sockaddr*)&srcAddr,
         (struct sockaddr*)&destAddr,
         (IBAT_PATH_BLOB*)&path
@@ -100,7 +100,7 @@ int __cdecl main(int argc, char *argv[])
     LONGLONG StartTime = GetElapsedTime();
     for( int i = 0; i < 2000; i++ )
     {
-        HRESULT hr = IBAT::Resolve(
+        HRESULT hr = IBAT::QueryPath(
             (struct sockaddr*)&srcAddr,
             (struct sockaddr*)&destAddr,
             (IBAT_PATH_BLOB*)&path
Index: .\core\fip\kernel\fip_port.cpp
===================================================================
--- .\core\fip\kernel\fip_port.cpp	(revision 3414)
+++ .\core\fip\kernel\fip_port.cpp	(working copy)
@@ -42,6 +42,9 @@ Notes:
 --*/
 #include "precomp.h"
 
+#include <initguid.h>
+#include "public.h"
+
 
 #if defined(EVENT_TRACING)
 #ifdef offsetof
Index: .\core\ibat_ex\dirs
===================================================================
--- .\core\ibat_ex\dirs	(revision 3414)
+++ .\core\ibat_ex\dirs	(working copy)
@@ -1,2 +0,0 @@
-DIRS=\
-	user
Index: .\core\ibat_ex\dirs.sln
===================================================================
--- .\core\ibat_ex\dirs.sln	(revision 3414)
+++ .\core\ibat_ex\dirs.sln	(working copy)
@@ -1,50 +0,0 @@
-
-Microsoft Visual Studio Solution File, Format Version 11.00
-# Visual Studio 2010
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ibat_ex_UM", "user\ibat_ex_UM.VcxProj", "{C0EBFD4D-87D8-4619-B9D3-006471645000}"
-EndProject
-Global
-	GlobalSection(SolutionConfigurationPlatforms) = preSolution
-		Win8 beta Debug|Win32 = Win8 beta Debug|Win32
-		Win8 beta Debug|x64 = Win8 beta Debug|x64
-		Win8 beta Release|Win32 = Win8 beta Release|Win32
-		Win8 beta Release|x64 = Win8 beta Release|x64
-		Win7 Debug|Win32 = Win7 Debug|Win32
-		Win7 Debug|x64 = Win7 Debug|x64
-		Win7 Release|Win32 = Win7 Release|Win32
-		Win7 Release|x64 = Win7 Release|x64
-		Vista Debug|Win32 = Vista Debug|Win32
-		Vista Debug|x64 = Vista Debug|x64
-		Vista Release|Win32 = Vista Release|Win32
-		Vista Release|x64 = Vista Release|x64
-	EndGlobalSection
-	GlobalSection(ProjectConfigurationPlatforms) = postSolution
-		{C0EBFD4D-87D8-4619-B9D3-006471645000}.Win8 beta Debug|Win32.ActiveCfg = Win8 beta Debug|Win32
-		{C0EBFD4D-87D8-4619-B9D3-006471645000}.Win8 beta Debug|Win32.Build.0 = Win8 beta Debug|Win32
-		{C0EBFD4D-87D8-4619-B9D3-006471645000}.Win8 beta Debug|x64.ActiveCfg = Win8 beta Debug|x64
-		{C0EBFD4D-87D8-4619-B9D3-006471645000}.Win8 beta Debug|x64.Build.0 = Win8 beta Debug|x64
-		{C0EBFD4D-87D8-4619-B9D3-006471645000}.Win8 beta Release|Win32.ActiveCfg = Win8 beta Release|Win32
-		{C0EBFD4D-87D8-4619-B9D3-006471645000}.Win8 beta Release|Win32.Build.0 = Win8 beta Release|Win32
-		{C0EBFD4D-87D8-4619-B9D3-006471645000}.Win8 beta Release|x64.ActiveCfg = Win8 beta Release|x64
-		{C0EBFD4D-87D8-4619-B9D3-006471645000}.Win8 beta Release|x64.Build.0 = Win8 beta Release|x64
-		{C0EBFD4D-87D8-4619-B9D3-006471645000}.Win7 Debug|Win32.ActiveCfg = Win7 Debug|Win32
-		{C0EBFD4D-87D8-4619-B9D3-006471645000}.Win7 Debug|Win32.Build.0 = Win7 Debug|Win32
-		{C0EBFD4D-87D8-4619-B9D3-006471645000}.Win7 Debug|x64.ActiveCfg = Win7 Debug|x64
-		{C0EBFD4D-87D8-4619-B9D3-006471645000}.Win7 Debug|x64.Build.0 = Win7 Debug|x64
-		{C0EBFD4D-87D8-4619-B9D3-006471645000}.Win7 Release|Win32.ActiveCfg = Win7 Release|Win32
-		{C0EBFD4D-87D8-4619-B9D3-006471645000}.Win7 Release|Win32.Build.0 = Win7 Release|Win32
-		{C0EBFD4D-87D8-4619-B9D3-006471645000}.Win7 Release|x64.ActiveCfg = Win7 Release|x64
-		{C0EBFD4D-87D8-4619-B9D3-006471645000}.Win7 Release|x64.Build.0 = Win7 Release|x64
-		{C0EBFD4D-87D8-4619-B9D3-006471645000}.Vista Debug|Win32.ActiveCfg = Vista Debug|Win32
-		{C0EBFD4D-87D8-4619-B9D3-006471645000}.Vista Debug|Win32.Build.0 = Vista Debug|Win32
-		{C0EBFD4D-87D8-4619-B9D3-006471645000}.Vista Debug|x64.ActiveCfg = Vista Debug|x64
-		{C0EBFD4D-87D8-4619-B9D3-006471645000}.Vista Debug|x64.Build.0 = Vista Debug|x64
-		{C0EBFD4D-87D8-4619-B9D3-006471645000}.Vista Release|Win32.ActiveCfg = Vista Release|Win32
-		{C0EBFD4D-87D8-4619-B9D3-006471645000}.Vista Release|Win32.Build.0 = Vista Release|Win32
-		{C0EBFD4D-87D8-4619-B9D3-006471645000}.Vista Release|x64.ActiveCfg = Vista Release|x64
-		{C0EBFD4D-87D8-4619-B9D3-006471645000}.Vista Release|x64.Build.0 = Vista Release|x64
-	EndGlobalSection
-	GlobalSection(SolutionProperties) = preSolution
-		HideSolutionNode = FALSE
-	EndGlobalSection
-EndGlobal
Index: .\core\ibat_ex\user\ib_at.cpp
===================================================================
--- .\core\ibat_ex\user\ib_at.cpp	(revision 3414)
+++ .\core\ibat_ex\user\ib_at.cpp	(working copy)
@@ -1,181 +0,0 @@
-/*
- * Copyright (c) 2008 Microsoft Corporation.  All rights reserved.
- * Copyright (c) 2011 Mellanox Technologies. All rights reserved.
- *
- * This software is available to you under the OpenIB.org BSD license
- * below:
- *
- *     Redistribution and use in source and binary forms, with or
- *     without modification, are permitted provided that the following
- *     conditions are met:
- *
- *      - Redistributions of source code must retain the above
- *        copyright notice, this list of conditions and the following
- *        disclaimer.
- *
- *      - Redistributions in binary form must reproduce the above
- *        copyright notice, this list of conditions and the following
- *        disclaimer in the documentation and/or other materials
- *        provided with the distribution.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
- * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
- * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
- * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- */
-
-#pragma warning( push, 3 )
-#include <wtypes.h>
-
-#include <stdlib.h>
-#include <winioctl.h>
-#pragma warning( pop )
-#include "iba/ibat.h"
-#include "iba/ib_at_ioctl.h"
-
-namespace IBAT_EX
-{
-
-	HANDLE
-	IbOpen()
-	{
-		return CreateFileW( IBAT_WIN32_NAME,
-			MAXIMUM_ALLOWED,(FILE_SHARE_READ|FILE_SHARE_WRITE), NULL,
-			OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL );
-	}
-
-
-	VOID
-	IbClose( 
-		__in HANDLE hIbatDev 
-		)
-	{
-		CloseHandle( hIbatDev );
-	}
-
-	HRESULT
-	IbIpToPort(
-		__in const HANDLE hIbatDev,
-		__in const struct sockaddr* pSrcAddr,
-	    __out      IBAT_PORT_RECORD *pPortRec
-	    )
-	{
-		IOCTL_IBAT_IP_TO_PORT_IN port_in;
-		port_in.Version = IBAT_IOCTL_VERSION;
-		if( pSrcAddr->sa_family == AF_INET )
-		{
-			port_in.Address.IpVersion = 4;
-			RtlCopyMemory(
-				&port_in.Address.Address[12],
-				&((struct sockaddr_in*)pSrcAddr)->sin_addr,
-				sizeof( ((struct sockaddr_in*)pSrcAddr)->sin_addr ) );
-		}
-		else
-		{
-			port_in.Address.IpVersion = 6;
-			RtlCopyMemory(
-				port_in.Address.Address,
-				&((struct sockaddr_in6*)pSrcAddr)->sin6_addr,
-				sizeof(port_in.Address.Address) );
-		}
-		
-		DWORD size;
-		BOOL fSuccess = DeviceIoControl( hIbatDev, IOCTL_IBAT_IP_TO_PORT,
-			&port_in, sizeof(port_in), pPortRec, sizeof(*pPortRec), &size, NULL );
-		
-		if( !fSuccess )
-			return HRESULT_FROM_WIN32( GetLastError() );
-
-		if ( size != sizeof(*pPortRec) )
-			return E_FAIL;
-
-	    return S_OK;
-	}
-
-	HRESULT
-	IbMacToPath(
-		__in const HANDLE hIbatDev,
-		__in const ULONGLONG PortGuid,
-		__in const UCHAR DestMac[IBAT_MAC_LEN],
-		__out IBAT_PATH_BLOB* pPath
-		)
-	{
-		IOCTL_IBAT_MAC_TO_PATH_IN mac_in = {0};
-		mac_in.Version = IBAT_IOCTL_VERSION;
-		mac_in.PortGuid = PortGuid;
-        RtlCopyMemory( mac_in.DestMac, DestMac, IBAT_MAC_LEN );
-
-		DWORD size;
-	    BOOL fSuccess = DeviceIoControl( hIbatDev, IOCTL_IBAT_MAC_TO_PATH,
-	        &mac_in, sizeof(mac_in), pPath, sizeof(*pPath), &size, NULL );
-	    if( !fSuccess )
-	        return HRESULT_FROM_WIN32( GetLastError() );
-		return S_OK;
-	}
-
-	HRESULT
-	IbGetPorts(
-		__in const HANDLE hIbatDev,
-		__in const ULONG PortsSize,
-		__out IOCTL_IBAT_PORTS_OUT* pPorts
-		)
-	{
-		IOCTL_IBAT_PORTS_IN mac_in = {0};
-		mac_in.Version = IBAT_IOCTL_VERSION;
-
-		DWORD size;
-		BOOL fSuccess = DeviceIoControl( hIbatDev, IOCTL_IBAT_PORTS,
-			&mac_in, sizeof(mac_in), pPorts, PortsSize, &size, NULL );
-		if( !fSuccess )
-			return HRESULT_FROM_WIN32( GetLastError() );
-		return S_OK;
-	}
-
-	HRESULT
-	IbGetIpAddresses(
-		__in const HANDLE hIbatDev,
-		__in const ULONGLONG PortGuid,
-		__in const ULONG IPsSize,
-		__out IOCTL_IBAT_IP_ADDRESSES_OUT *pIPs
-		)
-	{
-		IOCTL_IBAT_IP_ADDRESSES_IN mac_in = {0};
-		mac_in.Version = IBAT_IOCTL_VERSION;
-		mac_in.PortGuid = PortGuid;
-
-		DWORD size;
-		BOOL fSuccess = DeviceIoControl( hIbatDev, IOCTL_IBAT_IP_ADDRESSES,
-			&mac_in, sizeof(mac_in), pIPs, IPsSize, &size, NULL );
-		if( !fSuccess )
-			return HRESULT_FROM_WIN32( GetLastError() );
-		return S_OK;
-	}
-
-	HRESULT
-	IbMacToGid(
-		__in const HANDLE hIbatDev,
-		__in const ULONGLONG PortGuid,
-		__in const UCHAR DestMac[IBAT_MAC_LEN],
-		__out ib_gid_t *pDestGid
-		)
-	{
-		IOCTL_IBAT_MAC_TO_PATH_IN mac_in = {0};
-		mac_in.Version = IBAT_IOCTL_VERSION;
-		mac_in.PortGuid = PortGuid;
-		RtlCopyMemory( mac_in.DestMac, DestMac, IBAT_MAC_LEN );
-
-		DWORD size;
-		BOOL fSuccess = DeviceIoControl( hIbatDev, IOCTL_IBAT_MAC_TO_GID,
-			&mac_in, sizeof(mac_in), pDestGid, sizeof(*pDestGid), &size, NULL );
-		if( !fSuccess )
-			return HRESULT_FROM_WIN32( GetLastError() );
-		return S_OK;
-	}
-
-}
-
Index: .\core\ibat_ex\user\roce_at.h
===================================================================
--- .\core\ibat_ex\user\roce_at.h	(revision 3414)
+++ .\core\ibat_ex\user\roce_at.h	(working copy)
@@ -1,119 +0,0 @@
-/*
- * Copyright (c) 2011 Mellanox Technologies. All rights reserved.
- *
- * This software is available to you under the OpenIB.org BSD license
- * below:
- *
- *     Redistribution and use in source and binary forms, with or
- *     without modification, are permitted provided that the following
- *     conditions are met:
- *
- *      - Redistributions of source code must retain the above
- *        copyright notice, this list of conditions and the following
- *        disclaimer.
- *
- *      - Redistributions in binary form must reproduce the above
- *        copyright notice, this list of conditions and the following
- *        disclaimer in the documentation and/or other materials
- *        provided with the distribution.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
- * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
- * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
- * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- */
-
-#ifndef _ROCE_AT_H_
-#define _ROCE_AT_H_
- 
-#include <winsock2.h>
-#include <ws2tcpip.h>
-#include <iba/ib_at_ioctl.h>
-
-#ifdef __cplusplus
-extern "C"
-{
-#endif
-
-#define CPU_LE		1
-#define CPU_BE		0
-
-#define cl_ntoh16	_byteswap_ushort
-#define cl_hton16	_byteswap_ushort
-
-#define cl_ntoh32	_byteswap_ulong
-#define cl_hton32	_byteswap_ulong
-
-#define cl_ntoh64	_byteswap_uint64
-#define cl_hton64	_byteswap_uint64
-
-#ifdef __cplusplus
-}	// extern "C"
-#endif
-
-#ifdef _PREFAST_
-#define CONDITION_ASSUMED(X) __analysis_assume((X))
-#else
-#define CONDITION_ASSUMED(X) 
-#endif // _PREFAST_
-
-#ifndef CL_ASSERT
-#if DBG
-#define CL_ASSERT( exp )	(void)(!(exp)?OutputDebugString("Assertion Failed:" #exp "\n"),DebugBreak(),FALSE:TRUE);CONDITION_ASSUMED(exp)
-#else
-#define CL_ASSERT( exp )
-#endif	/* _DEBUG_ */
-#endif	/* CL_ASSERT */
-
-
- 
-#ifdef __cplusplus
-namespace IBAT_EX
-{
-
-	HRESULT
-	RoceIpToPort(
-		__in const struct sockaddr* pSrcAddr,
-		__out	   IBAT_PORT_RECORD *pPortRec,
-		__out      UINT64 *pMac64
-		);
-
-	HRESULT
-	RoceMacToPath(
-		__in const UINT64 PortGuid,
-		__in const UCHAR DestMac[IBAT_MAC_LEN],
-		__out IBAT_PATH_BLOB* pPath
-		);
-
-	HRESULT
-	RoceMacToGid(
-		__in const ULONGLONG PortGuid,
-		__in const UCHAR DestMac[IBAT_MAC_LEN],
-		__out ib_gid_t *pDestGid
-		);
-
-	HRESULT
-	RoceGetPorts(
-		__in const ULONG PortsSize,
-		__out IOCTL_IBAT_PORTS_OUT* pPorts
-		);
-
-	HRESULT
-	RoceGetIpAddresses(
-		__in const ULONGLONG PortGuid,
-		__in const ULONG IPsSize,
-		__out IOCTL_IBAT_IP_ADDRESSES_OUT *pIPs
-		);
-
-	void be64_to_mac(PUCHAR csrc, UINT64 src);
-	
-
-}
-
-#endif /* __cplusplus */
-
-#endif // _ROCE_AT_H_ 
Index: .\core\ibat_ex\user\SOURCES
===================================================================
--- .\core\ibat_ex\user\SOURCES	(revision 3414)
+++ .\core\ibat_ex\user\SOURCES	(working copy)
@@ -1,10 +0,0 @@
-TARGETNAME = ibat_ex
-
-TARGETPATH = ..\..\..\bin\user\obj$(BUILD_ALT_DIR)
-TARGETTYPE = LIBRARY
-
-SOURCES = ibat_ex.cpp ib_at.cpp roce_at.cpp
-
-INCLUDES = ..\..\..\inc;..\..\..\inc\user;
-
-MSC_WARNING_LEVEL= /W4
Index: .\core\ibat_ex\user\ib_at.h
===================================================================
--- .\core\ibat_ex\user\ib_at.h	(revision 3414)
+++ .\core\ibat_ex\user\ib_at.h	(working copy)
@@ -1,92 +0,0 @@
-/*
- * Copyright (c) 2011 Mellanox Technologies. All rights reserved.
- *
- * This software is available to you under the OpenIB.org BSD license
- * below:
- *
- *     Redistribution and use in source and binary forms, with or
- *     without modification, are permitted provided that the following
- *     conditions are met:
- *
- *      - Redistributions of source code must retain the above
- *        copyright notice, this list of conditions and the following
- *        disclaimer.
- *
- *      - Redistributions in binary form must reproduce the above
- *        copyright notice, this list of conditions and the following
- *        disclaimer in the documentation and/or other materials
- *        provided with the distribution.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
- * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
- * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
- * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- */
-
-#ifndef _IB_AT_H_
-#define _IB_AT_H_
- 
-#include <winsock2.h>
-#include <ws2tcpip.h>
-#include <iba/ib_at_ioctl.h>
- 
-#ifdef __cplusplus
-namespace IBAT_EX
-{
-
-	HANDLE
-	IbOpen();
-
-	VOID
-	IbClose( 
-		__in HANDLE hIbatDev 
-		);
-
-	HRESULT
-	IbIpToPort(
-		__in const HANDLE hIbatDev,
-		__in const struct sockaddr* pSrcAddr,
-		__out	   IBAT_PORT_RECORD *pPortRec
-		);
-
-	HRESULT
-	IbMacToPath(
-		__in const HANDLE hIbatDev,
-		__in const ULONGLONG PortGuid,
-		__in const UCHAR DestMac[IBAT_MAC_LEN],
-	    __out IBAT_PATH_BLOB* pPath
-		);
-
-	HRESULT
-	IbMacToGid(
-		__in const HANDLE hIbatDev,
-		__in const ULONGLONG PortGuid,
-		__in const UCHAR DestMac[IBAT_MAC_LEN],
-		__out ib_gid_t *pDestGid
-		);
-
-	HRESULT
-	IbGetPorts(
-		__in const HANDLE hIbatDev,
-		__in const ULONG PortsSize,
-		__out IOCTL_IBAT_PORTS_OUT* pPorts
-		);
-
-	HRESULT
-	IbGetIpAddresses(
-		__in const HANDLE hIbatDev,
-		__in const ULONGLONG PortGuid,
-		__in const ULONG IPsSize,
-		__out IOCTL_IBAT_IP_ADDRESSES_OUT *pIPs
-		);
-
-}
-
-#endif /* __cplusplus */
-
-#endif	// _IB_AT_H_
-
Index: .\core\ibat_ex\user\sources.props
===================================================================
--- .\core\ibat_ex\user\sources.props	(revision 3414)
+++ .\core\ibat_ex\user\sources.props	(working copy)
@@ -1,11 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
-  <PropertyGroup>
-    <TARGETNAME Condition="'$(OVERRIDE_TARGETNAME)'!='true'">ibat_ex</TARGETNAME>
-    <TARGETPATH Condition="'$(OVERRIDE_TARGETPATH)'!='true'">..\..\..\bin\user\obj$(BUILD_ALT_DIR)</TARGETPATH>
-    <TARGETTYPE Condition="'$(OVERRIDE_TARGETTYPE)'!='true'">LIBRARY</TARGETTYPE>
-    <SOURCES Condition="'$(OVERRIDE_SOURCES)'!='true'">ibat_ex.cpp ib_at.cpp roce_at.cpp</SOURCES>
-    <INCLUDES Condition="'$(OVERRIDE_INCLUDES)'!='true'">..\..\..\inc;..\..\..\inc\user;</INCLUDES>
-    <MSC_WARNING_LEVEL Condition="'$(OVERRIDE_MSC_WARNING_LEVEL)'!='true'">/W4</MSC_WARNING_LEVEL>
-  </PropertyGroup>
-</Project>
\ No newline at end of file
Index: .\core\ibat_ex\user\ibat_ex_UM.VcxProj
===================================================================
--- .\core\ibat_ex\user\ibat_ex_UM.VcxProj	(revision 3414)
+++ .\core\ibat_ex\user\ibat_ex_UM.VcxProj	(working copy)
@@ -1,212 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
-  <ItemGroup Label="ProjectConfigurations">
-    <ProjectConfiguration Include="Win8 beta Debug|Win32">
-      <Configuration>Win8 beta Debug</Configuration>
-      <Platform>Win32</Platform>
-    </ProjectConfiguration>
-    <ProjectConfiguration Include="Win7 Debug|Win32">
-      <Configuration>Win7 Debug</Configuration>
-      <Platform>Win32</Platform>
-    </ProjectConfiguration>
-    <ProjectConfiguration Include="Vista Debug|Win32">
-      <Configuration>Vista Debug</Configuration>
-      <Platform>Win32</Platform>
-    </ProjectConfiguration>
-    <ProjectConfiguration Include="Win8 beta Release|Win32">
-      <Configuration>Win8 beta Release</Configuration>
-      <Platform>Win32</Platform>
-    </ProjectConfiguration>
-    <ProjectConfiguration Include="Win7 Release|Win32">
-      <Configuration>Win7 Release</Configuration>
-      <Platform>Win32</Platform>
-    </ProjectConfiguration>
-    <ProjectConfiguration Include="Vista Release|Win32">
-      <Configuration>Vista Release</Configuration>
-      <Platform>Win32</Platform>
-    </ProjectConfiguration>
-    <ProjectConfiguration Include="Win8 beta Debug|x64">
-      <Configuration>Win8 beta Debug</Configuration>
-      <Platform>x64</Platform>
-    </ProjectConfiguration>
-    <ProjectConfiguration Include="Win7 Debug|x64">
-      <Configuration>Win7 Debug</Configuration>
-      <Platform>x64</Platform>
-    </ProjectConfiguration>
-    <ProjectConfiguration Include="Vista Debug|x64">
-      <Configuration>Vista Debug</Configuration>
-      <Platform>x64</Platform>
-    </ProjectConfiguration>
-    <ProjectConfiguration Include="Win8 beta Release|x64">
-      <Configuration>Win8 beta Release</Configuration>
-      <Platform>x64</Platform>
-    </ProjectConfiguration>
-    <ProjectConfiguration Include="Win7 Release|x64">
-      <Configuration>Win7 Release</Configuration>
-      <Platform>x64</Platform>
-    </ProjectConfiguration>
-    <ProjectConfiguration Include="Vista Release|x64">
-      <Configuration>Vista Release</Configuration>
-      <Platform>x64</Platform>
-    </ProjectConfiguration>
-  </ItemGroup>
-  <PropertyGroup Label="PropertySheets">
-    <PlatformToolset>WindowsApplicationForDrivers8.0</PlatformToolset>
-    <ConfigurationType>StaticLibrary</ConfigurationType>
-    <DriverType />
-    <TARGETNAME>ibat_ex_UM</TARGETNAME>
-    <Configuration>Win8 beta Debug</Configuration>
-  </PropertyGroup>
-  <PropertyGroup Label="Globals">
-    <VCTargetsPath Condition="'$(VCTargetsPath11)' != '' and '$(VisualStudioVersion)' == '11.0'">$(VCTargetsPath11)</VCTargetsPath>
-  </PropertyGroup>
-  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
-  <PropertyGroup Label="PropertySheets">
-    <ConversionToolVersion>1.0</ConversionToolVersion>
-    <WDKContentRoot Condition="'$(WDKContentRoot)' == ''">$(Registry:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows Kits\WDK at WDKContentRoot)</WDKContentRoot>
-    <WDKContentRoot Condition="'$(WDKContentRoot)' == ''">$(Registry:HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\Windows Kits\WDK at WDKContentRoot)</WDKContentRoot>
-    <WDKContentRoot Condition="!HasTrailingSlash('$(WDKContentRoot)')">$(WDKContentRoot)\</WDKContentRoot>
-    <BUILD_ALT_DIR>$(Configuration.Replace(' ',''))</BUILD_ALT_DIR>
-    <IntDir Condition="'$(Platform)'!='Win32'">$(BUILD_ALT_DIR)\$(Platform)\</IntDir>
-    <IntDir Condition="'$(Platform)'=='Win32'">$(BUILD_ALT_DIR)\x86\</IntDir>
-    <OutDir>$(IntDir)</OutDir>
-  </PropertyGroup>
-  <ImportGroup Label="PreConfiguration">
-    <Import Project="$(WDKContentRoot)\bin\conversion\PreConfiguration.props" />
-  </ImportGroup>
-  <PropertyGroup Label="Globals">
-    <ProjectGuid>{C0EBFD4D-87D8-4619-B9D3-006471645000}</ProjectGuid>
-  </PropertyGroup>
-  <PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Win8 beta Debug|Win32'">
-    <TargetVersion>Win8</TargetVersion>
-    <UseDebugLibraries>True</UseDebugLibraries>
-  </PropertyGroup>
-  <PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Win7 Debug|Win32'">
-    <TargetVersion>Win7</TargetVersion>
-    <UseDebugLibraries>True</UseDebugLibraries>
-  </PropertyGroup>
-  <PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Vista Debug|Win32'">
-    <TargetVersion>Vista</TargetVersion>
-    <UseDebugLibraries>True</UseDebugLibraries>
-  </PropertyGroup>
-  <PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Win8 beta Release|Win32'">
-    <TargetVersion>Win8</TargetVersion>
-    <UseDebugLibraries>False</UseDebugLibraries>
-  </PropertyGroup>
-  <PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Win7 Release|Win32'">
-    <TargetVersion>Win7</TargetVersion>
-    <UseDebugLibraries>False</UseDebugLibraries>
-  </PropertyGroup>
-  <PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Vista Release|Win32'">
-    <TargetVersion>Vista</TargetVersion>
-    <UseDebugLibraries>False</UseDebugLibraries>
-  </PropertyGroup>
-  <PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Win8 beta Debug|x64'">
-    <TargetVersion>Win8</TargetVersion>
-    <UseDebugLibraries>True</UseDebugLibraries>
-  </PropertyGroup>
-  <PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Win7 Debug|x64'">
-    <TargetVersion>Win7</TargetVersion>
-    <UseDebugLibraries>True</UseDebugLibraries>
-  </PropertyGroup>
-  <PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Vista Debug|x64'">
-    <TargetVersion>Vista</TargetVersion>
-    <UseDebugLibraries>True</UseDebugLibraries>
-  </PropertyGroup>
-  <PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Win8 beta Release|x64'">
-    <TargetVersion>Win8</TargetVersion>
-    <UseDebugLibraries>False</UseDebugLibraries>
-  </PropertyGroup>
-  <PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Win7 Release|x64'">
-    <TargetVersion>Win7</TargetVersion>
-    <UseDebugLibraries>False</UseDebugLibraries>
-  </PropertyGroup>
-  <PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Vista Release|x64'">
-    <TargetVersion>Vista</TargetVersion>
-    <UseDebugLibraries>False</UseDebugLibraries>
-  </PropertyGroup>
-  <PropertyGroup>
-    <DebuggerFlavor Condition="'$(PlatformToolset)' == 'WindowsKernelModeDriver8.0'">DbgengKernelDebugger</DebuggerFlavor>
-    <DebuggerFlavor Condition="'$(PlatformToolset)' == 'WindowsUserModeDriver8.0'">DbgengRemoteDebugger</DebuggerFlavor>
-  </PropertyGroup>
-  <!-- Needed by any VcxProj -->
-  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
-  <ImportGroup Label="ExtensionSettings">
-  </ImportGroup>
-  <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Vista Release|x64'">
-    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" />
-  </ImportGroup>
-  <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Win7 Release|x64'">
-    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" />
-  </ImportGroup>
-  <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Win8 beta Release|x64'">
-    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" />
-  </ImportGroup>
-  <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Vista Debug|x64'">
-    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" />
-  </ImportGroup>
-  <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Win7 Debug|x64'">
-    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" />
-  </ImportGroup>
-  <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Win8 beta Debug|x64'">
-    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" />
-  </ImportGroup>
-  <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Vista Release|Win32'">
-    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" />
-  </ImportGroup>
-  <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Win7 Release|Win32'">
-    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" />
-  </ImportGroup>
-  <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Win8 beta Release|Win32'">
-    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" />
-  </ImportGroup>
-  <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Vista Debug|Win32'">
-    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" />
-  </ImportGroup>
-  <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Win7 Debug|Win32'">
-    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" />
-  </ImportGroup>
-  <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Win8 beta Debug|Win32'">
-    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" />
-  </ImportGroup>
-  <PropertyGroup Label="UserMacros" />
-  <!-- The WrappedTaskItems label is used by the conversion tool to identify the location where items 
-        associated with wrapped tasks will reside.-->
-  <ItemGroup Label="WrappedTaskItems" />
-  <ItemGroup>
-    <!-- We only add items (e.g. form ClSourceFiles) that do not already exist (e.g in the ClCompile list), this avoids duplication -->
-    <ClCompile Include="@(ClSourceFiles)" Exclude="@(ClCompile)" />
-    <ResourceCompile Include="@(RcSourceFiles)" Exclude="@(ResourceCompile)" />
-    <Midl Include="@(IdlSourceFiles)" Exclude="@(Midl)" />
-    <MessageCompile Include="@(McSourceFiles)" Exclude="@(MessageCompile)" />
-    <MASM Include="@(AsmSourceFiles)" Exclude="@(MASM)" />
-    <GenerateBmf Include="@(MofSourceFiles)" Exclude="@(GenerateBmf)" />
-  </ItemGroup>
-  <!-- Set default environment variables, e.g. for stampinf -->
-  <ItemGroup>
-    <BuildMacro Include="SDK_INC_PATH">
-      <Value>$(KIT_SHARED_INC_PATH)</Value>
-      <EnvironmentVariable>true</EnvironmentVariable>
-    </BuildMacro>
-  </ItemGroup>
-  <ItemGroup>
-    <Inf Include="*.inf" />
-    <FilesToPackage Include="$(TargetPath)" />
-  </ItemGroup>
-  <!-- Necessary to pick up propper files from local directory when in the IDE-->
-  <ItemGroup>
-    <None Include="*.txt;*.htm;*.html" />
-    <None Include="*.ico;*.cur;*.bmp;*.dlg;*.rct;*.gif;*.jpg;*.jpeg;*.wav;*.jpe;*.tiff;*.tif;*.png;*.rc2" />
-    <None Include="*.def;*.bat;*.hpj;*.asmx" />
-  </ItemGroup>
-  <ItemGroup>
-    <ClInclude Include="*.h;*.hpp;*.hxx;*.hm;*.inl;*.xsd" />
-  </ItemGroup>
-  <!-- /Necessary to pick up propper files from local directory when in the IDE-->
-  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
-  <Import Condition="'$(PlatformToolset)'=='Windows8.0SDK'" Project="$(WDKContentRoot)build\WindowsDriver8.0.Common.targets" />
-  <Import Condition="'$(Platform)'!='arm'" Project="$(VCTargetsPath)\BuildCustomizations\masm.props" />
-  <ImportGroup Label="ExtensionTargets">
-    <Import Condition="'$(Platform)'!='arm'" Project="$(VCTargetsPath)\BuildCustomizations\masm.targets" />
-  </ImportGroup>
-</Project>
\ No newline at end of file
Index: .\core\ibat_ex\user\ibat_ex.cpp
===================================================================
--- .\core\ibat_ex\user\ibat_ex.cpp	(revision 3414)
+++ .\core\ibat_ex\user\ibat_ex.cpp	(working copy)
@@ -1,565 +0,0 @@
-/*
- * Copyright (c) 2008 Microsoft Corporation.  All rights reserved.
- * Copyright (c) 2011 Mellanox Technologies. All rights reserved.
- *
- * This software is available to you under the OpenIB.org BSD license
- * below:
- *
- *     Redistribution and use in source and binary forms, with or
- *     without modification, are permitted provided that the following
- *     conditions are met:
- *
- *      - Redistributions of source code must retain the above
- *        copyright notice, this list of conditions and the following
- *        disclaimer.
- *
- *      - Redistributions in binary form must reproduce the above
- *        copyright notice, this list of conditions and the following
- *        disclaimer in the documentation and/or other materials
- *        provided with the distribution.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
- * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
- * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
- * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- */
-
-//
-// IBAT: InfiniBand Address Translation
-//
-// Description:
-//  Maps source & remote IP addresses (IPv4 and IPv6) to a path record.
-//
-//  The mapping requires two steps:
-//      1. Mapping the remote IP address to the remote Ethernet MAC address
-//      2. Retrieve the path given the remote Ethernet MAC address from IPoIB
-//
-//  The first step is accomplished as follows on Windows Server 2008:
-//      1. Lookup the desired MAC from the OS using GetIpNetEntry2
-//      2. If the remote IP isn't found, resolve the remote IP address
-//      using ResolveIpNetEntry2
-//
-//  The first step is accomplished as follows on Windows Server 2003:
-//      1. Retrieve the whole IP->MAC mapping table from the OS using
-//      GetIpNetTable.
-//      2. Walk the returned table looking for the destination IP to
-//      find the destination Ethernet MAC address.
-//      3. If the remote IP isn't found, resolve the remote IP address using
-//      SendARP.
-//
-//  The second step is accomplished by asking IPoIB for the path
-//  given the remote MAC.  IPoIB creates the path internally without going to
-//  the SA.
-
-#pragma warning( push, 3 )
-#include <wtypes.h>
-
-#include <stdlib.h>
-#include <winioctl.h>
-#pragma warning( pop )
-#include "iba/ibat_ex.h"
-#include <iphlpapi.h>
-#include "iba/ib_at_ioctl.h"
-#include "ib_at.h"
-#include "roce_at.h"
-
-
-C_ASSERT( sizeof(IBAT_PATH_BLOB) == sizeof(ib_path_rec_t) );
-
-namespace IBAT_EX
-{
-
-    const IN6_ADDR x_DefaultGid = {0xFE,0x80,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
-
-	class H
-	{
-	public:
-		H( HANDLE h = INVALID_HANDLE_VALUE ) : m_h( h ) {};
-		~H(){ if( m_h != INVALID_HANDLE_VALUE ) CloseHandle( m_h ); }
-	
-		H& operator =(HANDLE h){ CloseHandle( m_h ); m_h = h; }
-		operator HANDLE() const { return m_h; }
-	
-	private:
-		HANDLE m_h;
-	};
-	
-	HRESULT
-	IpToPort(
-		__in const struct sockaddr* pSrcAddr,
-	    __out      IBAT_PORT_RECORD *pPortRec
-	    )
-	{
-		HRESULT hr;
-		
-		H hIbatDev = IbOpen();
-		if( hIbatDev != INVALID_HANDLE_VALUE )
-			hr = IbIpToPort( hIbatDev, pSrcAddr, pPortRec ); 
-		else
-			hr = HRESULT_FROM_WIN32( GetLastError() );
-		
-		if ( FAILED( hr ) )
-			hr = RoceIpToPort( pSrcAddr, pPortRec, NULL ); 
-		
-		return hr;
-	}
-
-	HRESULT
-	MacToGid(
-		__in const ULONGLONG PortGuid,
-		__in const UCHAR DestMac[IBAT_MAC_LEN],
-		__out ib_gid_t *pDestGid
-		)
-	{
-		HRESULT hr;
-		
-		H hIbatDev = IbOpen();
-		if( hIbatDev != INVALID_HANDLE_VALUE )
-			hr = IbMacToGid( hIbatDev, PortGuid, DestMac, pDestGid ); 
-		else
-			hr = HRESULT_FROM_WIN32( GetLastError() );
-		
-		if ( FAILED( hr ) )
-			hr = RoceMacToGid( PortGuid, DestMac, pDestGid ); 
-		
-		return hr;
-	}
-
-	HRESULT
-	GetPorts(
-		__in const ULONG PortsSize,
-		__out IOCTL_IBAT_PORTS_OUT* pPorts
-		)
-	{
-		HRESULT hr;
-		
-		H hIbatDev = IbOpen();
-		if( hIbatDev != INVALID_HANDLE_VALUE )
-			hr = IbGetPorts( hIbatDev, PortsSize, pPorts );
-		else
-			hr = HRESULT_FROM_WIN32( GetLastError() );
-		
-		if ( FAILED( hr ) )
-			hr = RoceGetPorts( PortsSize, pPorts ); 
-		
-		return hr;
-	}
-
-	HRESULT
-	GetIpAddresses(
-		__in const ULONGLONG PortGuid,
-		__in const ULONG IPsSize,
-		__out IOCTL_IBAT_IP_ADDRESSES_OUT *pIPs
-		)
-	{
-		HRESULT hr;
-		
-		H hIbatDev = IbOpen();
-		if( hIbatDev != INVALID_HANDLE_VALUE )
-			hr = IbGetIpAddresses( hIbatDev, PortGuid, IPsSize, pIPs );
-		else
-			hr = HRESULT_FROM_WIN32( GetLastError() );
-		
-		if ( FAILED( hr ) )
-			hr = RoceGetIpAddresses( PortGuid, IPsSize, pIPs ); 
-		
-		return hr;
-	}
-		
-
-
-
-#if WINVER >= 0x600
-HRESULT
-Resolve(
-    __in const struct sockaddr* pSrcAddr,
-    __in const struct sockaddr* pDestAddr,
-    __out IBAT_PATH_BLOB* pPath,
-    __out enum rdma_transport_type *pTransport
-    )
-{
-	HRESULT hr;
-	BOOL port_is_roce = FALSE;
-	IBAT_PORT_RECORD port_out = {0};
-	UINT64 DestMac64 = 0;
-	
-	if( pSrcAddr->sa_family != pDestAddr->sa_family )
-		return E_INVALIDARG;
-
-	H hIbatDev = IbOpen();
-	if( hIbatDev != INVALID_HANDLE_VALUE )
-		hr = IbIpToPort( hIbatDev, pSrcAddr, &port_out ); 
-	else
-		hr = HRESULT_FROM_WIN32( GetLastError() );
-
-	if ( FAILED( hr ) )
-	{
-		port_is_roce = TRUE;
-		hr = RoceIpToPort( pSrcAddr, &port_out, &DestMac64 ); 
-	}
-
-	if( FAILED( hr ) )
-		return hr;
-
-	bool fLoopback;
-	if( pSrcAddr->sa_family == AF_INET )
-	{
-		fLoopback = ((struct sockaddr_in*)pDestAddr)->sin_addr.s_addr ==
-			((struct sockaddr_in*)pSrcAddr)->sin_addr.s_addr;
-	}
-	else
-	{
-		fLoopback = IN6_ADDR_EQUAL(
-			&((struct sockaddr_in6*)pDestAddr)->sin6_addr,
-			&((struct sockaddr_in6*)pSrcAddr)->sin6_addr
-			) == TRUE;
-	}
-
-
-	// Check for loopback.
-	UCHAR DestMac[IBAT_MAC_LEN] = {0};
-	if( !fLoopback )
-	{
-		NET_LUID luid;
-		DWORD ret;
-		do
-		{
-			DWORD iIf;
-			ret = GetBestInterfaceEx( (struct sockaddr*)pSrcAddr, &iIf );
-			if( ret != NO_ERROR )
-				return HRESULT_FROM_WIN32( ret );
-
-			// Interface indexes are not constant, so get the LUID mapping for the
-			// returned interface for use in the rest of the function.
-			ret = ConvertInterfaceIndexToLuid( iIf, &luid );
-
-		} while( ret != NO_ERROR );
-
-		SOCKADDR_INET src;
-		MIB_IPNET_ROW2 net = {0};
-		net.InterfaceLuid = luid;
-		switch( pDestAddr->sa_family )
-		{
-		case AF_INET:
-			net.Address.si_family = src.si_family = AF_INET;
-			net.Address.Ipv4 = *(struct sockaddr_in*)pDestAddr;
-			src.Ipv4 = *(struct sockaddr_in*)pSrcAddr;
-			break;
-
-		case AF_INET6:
-			net.Address.si_family = src.si_family = AF_INET6;
-			net.Address.Ipv6 = *(struct sockaddr_in6*)pDestAddr;
-			src.Ipv6 = *(struct sockaddr_in6*)pSrcAddr;
-			break;
-
-		default:
-			return E_INVALIDARG;
-		}
-
-		bool fRetry = true;
-	retry:
-		ret = GetIpNetEntry2( &net );
-		if( ret == ERROR_NOT_FOUND )
-		{
-			net.State = NlnsUnreachable;
-		}
-		else if( ret != NO_ERROR )
-		{
-			return HRESULT_FROM_WIN32( ret );
-		}
-
-		switch( net.State )
-		{
-		default:
-		case NlnsUnreachable:
-			ret = ResolveIpNetEntry2( &net, &src );
-			if( ret == ERROR_BAD_NET_NAME && fRetry )
-			{
-				fRetry = false;
-				goto retry;
-			}
-			else if( ret != NO_ERROR )
-			{
-				return HRESULT_FROM_WIN32( ret );
-			}
-			break;
-
-		case NlnsReachable:
-		case NlnsPermanent:
-			break;
-
-		case NlnsIncomplete:
-			return E_PENDING;
-		}
-
-		if( net.PhysicalAddressLength > 6 )
-			return E_UNEXPECTED;
-
-		RtlCopyMemory( DestMac, net.PhysicalAddress, IBAT_MAC_LEN );
-	} else {
-		if(port_is_roce) {
-			be64_to_mac(DestMac, DestMac64);
-		   }
-	}
-
-	if ( port_is_roce )
-	{
-		hr = RoceMacToPath( 
-			port_out.PortGuid, 
-			DestMac, 
-			pPath );
-		if ( pTransport )
-			*pTransport = RDMA_TRANSPORT_RDMAOE;
-	}
-	else
-	{
-		hr = IbMacToPath( 
-			hIbatDev, 
-			port_out.PortGuid, 
-			DestMac, 
-			pPath );
-		if ( pTransport )
-			*pTransport = RDMA_TRANSPORT_IB;
-	}
-	
-	return hr;
-}
-#else   // Back compatibility with Windows Server 2003
-
-
-static HRESULT
-GetDestMac(
-    __in struct sockaddr_in* pDestAddr,
-    __out BYTE* pDestMac
-    )
-{
-    DWORD ret;
-
-    MIB_IPNETTABLE* pTable = NULL;
-    ULONG len = 0;
-    do
-    {
-        ret = GetIpNetTable( pTable, &len, FALSE );
-        if( ret != ERROR_INSUFFICIENT_BUFFER )
-            break;
-
-        if( pTable != NULL )
-        {
-            HeapFree( GetProcessHeap(), 0, pTable );
-        }
-
-        pTable = (MIB_IPNETTABLE*)HeapAlloc( GetProcessHeap(), 0, len );
-    } while( ret == ERROR_INSUFFICIENT_BUFFER );
-
-    if( ret != NO_ERROR )
-    {
-        if( pTable != NULL )
-        {
-            HeapFree( GetProcessHeap(), 0, pTable );
-        }
-        return HRESULT_FROM_WIN32( ret );
-    }
-
-    ret = ERROR_NOT_SUPPORTED;
-    DWORD i;
-    for( i = 0; i < pTable->dwNumEntries; i++ )
-    {
-        if( pTable->table[i].dwType == MIB_IPNET_TYPE_OTHER ||
-            pTable->table[i].dwType == MIB_IPNET_TYPE_INVALID )
-        {
-            continue;
-        }
-
-        if( pTable->table[i].dwAddr !=
-            ((struct sockaddr_in*)pDestAddr)->sin_addr.s_addr )
-        {
-            continue;
-        }
-
-        if( pTable->table[i].dwPhysAddrLen != IBAT_MAC_LEN )
-        {
-            continue;
-        }
-
-        RtlCopyMemory( pDestMac, pTable->table[i].bPhysAddr, IBAT_MAC_LEN );
-        ret = S_OK;
-        break;
-    }
-    HeapFree( GetProcessHeap(), 0, pTable );
-
-    return HRESULT_FROM_WIN32( ret );
-}
-
-HRESULT
-Resolve(
-    __in const struct sockaddr* pSrcAddr,
-    __in const struct sockaddr* pDestAddr,
-    __out IBAT_PATH_BLOB* pPath,
-    __out enum rdma_transport_type *pTransport
-    )
-{
-    if( pDestAddr->sa_family != AF_INET )
-        return E_NOTIMPL;
-
-	HRESULT hr;
-	BOOL port_is_roce = FALSE;
-	IBAT_PORT_RECORD port_out = {0};
-
-	H hIbatDev = IbOpen();
-    if( hIbatDev != INVALID_HANDLE_VALUE )
-		hr = IbIpToPort( hIbatDev, pSrcAddr, &port_out ); 
-	else
-		hr = HRESULT_FROM_WIN32( GetLastError() );
-
-	if ( FAILED( hr ) )
-	{
-		port_is_roce = TRUE;
-		hr = RoceIpToPort( pSrcAddr, &port_out, NULL ); 
-	}
-
-	if( FAILED( hr ) )
-		return hr;
-
-    // Check for loopback.
-    IOCTL_IBAT_MAC_TO_GID_IN mac_in = {0};
-    mac_in.Version = IBAT_IOCTL_VERSION;
-    mac_in.PortGuid = port_out.PortGuid;
-
-    if( ((struct sockaddr_in*)pDestAddr)->sin_addr.s_addr !=
-        ((struct sockaddr_in*)pSrcAddr)->sin_addr.s_addr )
-    {
-        HRESULT hr = GetDestMac( (struct sockaddr_in*)pDestAddr, mac_in.DestMac );
-        if( FAILED( hr ) )
-        {
-            ULONG len = sizeof(mac_in.DestMac);
-            DWORD ret = SendARP(
-                ((struct sockaddr_in*)pDestAddr)->sin_addr.s_addr,
-                ((struct sockaddr_in*)pSrcAddr)->sin_addr.s_addr,
-                (ULONG*)mac_in.DestMac,
-                &len
-                );
-            if( ret != NO_ERROR )
-                return HRESULT_FROM_WIN32( ret );
-        }
-    }
-
-	if ( port_is_roce )
-	{
-		hr = RoceMacToPath( 
-			port_out.PortGuid, 
-			mac_in.DestMac, 
-			pPath );
-		if ( pTransport )
-			*pTransport = RDMA_TRANSPORT_RDMAOE;
-	}
-	else
-	{
-		hr = IbMacToPath( 
-			hIbatDev, 
-			port_out.PortGuid, 
-			mac_in.DestMac, 
-			pPath );
-		if ( pTransport )
-			*pTransport = RDMA_TRANSPORT_IB;
-	}
-
-	return hr;
-}
-
-#endif // WINVER >= 0x600
-
-
-HRESULT
-ResolvePath(
-    __in const struct sockaddr* pSrcAddr,
-    __in const struct sockaddr* pDestAddr,
-    __out IBAT_PATH_BLOB* pPath,
-    __out enum rdma_transport_type *pTransport,
-	__in DWORD Timeout)
-{
-	INT64 to;
-	HRESULT hr;
-
-	to = (Timeout == INFINITE) ? 0x7FFFFFFFFFFFFFFFL : (INT64) ((UINT64) Timeout);
-	for (;;) {
-		hr = Resolve(pSrcAddr, pDestAddr, pPath, pTransport);
-		if( hr != E_PENDING || to <= 0 )
-			break;
-
-		to -= 10;
-		Sleep(10);
-	};
-
-	return hr;
-}
-
-} /* IBAT namespace */
-
-extern "C"
-{
-
-HRESULT
-IbatexResolve(
-    __in const struct sockaddr* pSrcAddr,
-    __in const struct sockaddr* pDestAddr,
-    __out IBAT_PATH_BLOB* pPath,
-    __out enum rdma_transport_type *pTransport
-    )
-{
-    return IBAT_EX::Resolve( pSrcAddr, pDestAddr, pPath, pTransport );
-}
-
-HRESULT
-IbatexResolvePath(
-    __in const struct sockaddr* pSrcAddr,
-    __in const struct sockaddr* pDestAddr,
-    __out IBAT_PATH_BLOB* pPath,
-    __out enum rdma_transport_type *pTransport,
-	__in DWORD Timeout)
-{
-	return IBAT_EX::ResolvePath(pSrcAddr, pDestAddr, pPath, pTransport, Timeout);
-}
-
-HRESULT
-IbatexIpToPort(
-	__in const struct sockaddr* pSrcAddr,
-    __out      IBAT_PORT_RECORD *pPortRec
-    )
-{
-    return IBAT_EX::IpToPort( pSrcAddr, pPortRec );
-}
-
-HRESULT
-IbatexMacToGid(
-	__in const ULONGLONG PortGuid,
-	__in const UCHAR DestMac[IBAT_MAC_LEN],
-	__out ib_gid_t *pDestGid
-	)
-{
-	return IBAT_EX::MacToGid( PortGuid, DestMac, pDestGid ); 
-}
-
-HRESULT
-IbatexGetPorts(
-	__in const ULONG PortsSize,
-	__out IOCTL_IBAT_PORTS_OUT* pPorts
-	)
-{
-	return IBAT_EX::GetPorts( PortsSize, pPorts ); 
-}
-
-HRESULT
-IbatexGetIpAddresses(
-	__in const ULONGLONG PortGuid,
-	__in const ULONG IPsSize,
-	__out IOCTL_IBAT_IP_ADDRESSES_OUT *pIPs
-	)
-{
-	return IBAT_EX::GetIpAddresses( PortGuid, IPsSize, pIPs ); 
-}
-
-} /* extern "C" */
Index: .\core\ibat_ex\user\makefile
===================================================================
--- .\core\ibat_ex\user\makefile	(revision 3414)
+++ .\core\ibat_ex\user\makefile	(working copy)
@@ -1,7 +0,0 @@
-#
-# DO NOT EDIT THIS FILE!!!  Edit .\sources. if you want to add a new source
-# file to this component.  This file merely indirects to the real make file
-# that is shared by all the driver components of the OpenIB Windows project.
-#
-
-!INCLUDE ..\..\..\inc\openib.def
Index: .\core\ibat_ex\user\roce_at.cpp
===================================================================
--- .\core\ibat_ex\user\roce_at.cpp	(revision 3414)
+++ .\core\ibat_ex\user\roce_at.cpp	(working copy)
@@ -1,589 +0,0 @@
-/*
- Copyright (c) 2011  Mellanox Technologies. All rights reserved.
- *
- * This software is available to you under the OpenIB.org BSD license
- * below:
- *
- *     Redistribution and use in source and binary forms, with or
- *     without modification, are permitted provided that the following
- *     conditions are met:
- *
- *      - Redistributions of source code must retain the above
- *        copyright notice, this list of conditions and the following
- *        disclaimer.
- *
- *      - Redistributions in binary form must reproduce the above
- *        copyright notice, this list of conditions and the following
- *        disclaimer in the documentation and/or other materials
- *        provided with the distribution.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AWV
- * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
- * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
- * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
- * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- */
-
-#pragma warning( push, 3 )
-#include <wtypes.h>
-
-#include <stdlib.h>
-#include <winioctl.h>
-#pragma warning( pop )
-
-#include <winsock2.h>
-#include <ws2tcpip.h>
-#include <iphlpapi.h>
-
-#include <iba/ib_types.h>
-#include <iba/ib_al.h>
-#include "iba/ib_at_ioctl.h"
-#include "iba/ibat_ex.h"
-#include "roce_at.h"
-
-typedef UINT16 NET16;
-typedef UINT32 NET32;
-typedef UINT64 NET64;
-
-namespace IBAT_EX
-{
-
-
-	typedef struct _roce_ib_data
-	{
-		 NET64			ca_guid;			// HCA guid
-		 NET64			port_guid; 	 		// port guid
-		 NET64			mac64;				// mac64
-		 NET16			port_pkey; 	 		// port pkey
-		 UCHAR			port_num;			// port number (1 or 2)
-		 UCHAR			port_type;			// transport_type
-		 UCHAR			mac[IBAT_MAC_LEN];	// mac
-		 //TODO: use these values to set mtu and rate in RoceMacToPath
-		 UCHAR			mtu;				// mtu
-		 UCHAR			active_speed;		// active_speed
-		 UCHAR			ext_active_speed;	// ext_active_speed
-		 UCHAR			link_encoding;		// 1 - FDR10
-		 UCHAR			reserved[2];	
-	 
-	}	 roce_ib_data_t;
-
-	HRESULT IB2Hresult (ib_api_status_t ib_status)
-	{
-	    HRESULT hr;
-	    if ( ib_status == IB_SUCCESS ) {
-	        return S_OK;
-	    } if (( ib_status > IB_SUCCESS ) && (ib_status < IB_UNKNOWN_ERROR)) {
-	        hr = E_FAIL |  ib_status;
-	        CL_ASSERT(FAILED(hr));
-	        return hr;     
-	    }
-
-
-	    // Keep translating as the error pops
-	    CL_ASSERT(FALSE);
-	    return E_UNEXPECTED;
-
-	}
-	 
-	// mlx4_addrconf_ifid_eui48_win
-	static
-	void __mac_to_guid(UCHAR *eui, UINT64 mac)
-	{
-		UCHAR *p = (UCHAR*)&mac+2; //mac 6 bytes
-		memcpy(eui, p, 3);
-		memcpy(eui + 5, p + 3, 3);
-		eui[3] = 0xFF;
-		eui[4] = 0xFE;
-		eui[0] ^= 2;
-	}
-	 
-	static
-	void __guid_to_mac(UCHAR *mac, UINT64 guid)
-	{
-		UCHAR *p = (UCHAR*)&guid; //guid 8 bytes
-		memcpy(mac, p, 3);
-		memcpy(mac + 3, p + 5, 3);
-		mac[0] ^= 2;
-	}
-	 
-	 
-	// Convert the mac from the way that Windows gives it to the way we want it.
-	static
-	void __mac_to_be64(UINT64 *dst, PUCHAR csrc)
-	{
-		 char *cdst = (char *)dst;
-		 cdst[0] = csrc[5];
-		 cdst[1] = csrc[4];
-		 cdst[2] = csrc[3];
-		 cdst[3] = csrc[2];
-		 cdst[4] = csrc[1];
-		 cdst[5] = csrc[0];
-		 cdst[6] = 0;
-		 cdst[7] = 0;
-	}
-
-
-	void be64_to_mac(PUCHAR cmac, UINT64 src)
-	{
-		 char *cMac = (char *)&src;
-		 cmac[0] = cMac[5];
-		 cmac[1] = cMac[4];
-		 cmac[2] = cMac[3];
-		 cmac[3] = cMac[2];
-		 cmac[4] = cMac[1];
-		 cmac[5] = cMac[0];
-	}
-
-
-	static 
-	DWORD
-	__get_local_ifc(
-		__in		const struct sockaddr*	pAddr,
-		__out 	PULONG pIfIndex,
-		__out	NET_LUID *pLuid
-		)
-	{
-		DWORD status;
-		PMIB_UNICASTIPADDRESS_TABLE pUcastIpTable;
-		ULONG i;
-		PMIB_UNICASTIPADDRESS_ROW pUcasIpRow = NULL;
-
-		if(pAddr == NULL || pIfIndex == NULL)
-		{
-			return ERROR_INVALID_PARAMETER;
-		}
-
-		if (pLuid)
-			pLuid->Value = 0;
-		
-		status = GetUnicastIpAddressTable(pAddr->sa_family, &pUcastIpTable);
-
-		if( status != NO_ERROR )
-			return status;
-
-		for(i = 0; i < pUcastIpTable->NumEntries; i++)
-		{
-			pUcasIpRow = &pUcastIpTable->Table[i];
-			if( pAddr->sa_family == AF_INET )
-			{
-
-				if(((struct sockaddr_in*)pAddr)->sin_addr.s_addr ==
-					((struct sockaddr_in*)&pUcasIpRow->Address)->sin_addr.s_addr)
-				{
-					break;
-				}
-			}
-			else
-			if( pAddr->sa_family == AF_INET )
-			{
-				if(IN6_ADDR_EQUAL(
-					&((struct sockaddr_in6*)pAddr)->sin6_addr,
-					&((struct sockaddr_in6*)&pUcasIpRow->Address)->sin6_addr))
-				{
-					break;
-				}
-			}
-		}
-
-		if ( pUcasIpRow == NULL )
-		{
-			status = ERROR_GEN_FAILURE;
-			goto exit;
-		}
-			
-		if(i < pUcastIpTable->NumEntries)
-		{// found interface
-			*pIfIndex = pUcasIpRow->InterfaceIndex;
-			status = ERROR_SUCCESS;
-
-			// get the LUID by index
-			if (pLuid)
-				status = ConvertInterfaceIndexToLuid( pUcasIpRow->InterfaceIndex, pLuid );
-		}
-		else
-		{
-			*pIfIndex = 0;
-			status = ERROR_BAD_NETPATH;
-		}
-	exit:	
-		FreeMibTable(pUcastIpTable);
-		return status;
-	}
-
-
-	static
-	DWORD
-	__src_ip_2_mac64(
-		__in 	 const struct sockaddr*  pSrcAddr,
-		__out 	 UINT64		 	*pMac
-		)
-	{	
-		DWORD status;
-	 
-		//
-		// Getting source MAC
-		//
-
-		// get local interface index
-		NET_LUID luid;
-		ULONG iIf;
-		status = __get_local_ifc( (struct sockaddr*)pSrcAddr, &iIf, &luid );
-		if( status != NO_ERROR )
-			return status;
-
-		// get interface row
-		MIB_IF_ROW2 row;
-		memset( &row, 0, sizeof(row));
-		row.InterfaceLuid = luid;
-
-		status = GetIfEntry2( &row );
-		if ( status != NO_ERROR )
-		{
-			return status;
-		}
-
-		// get MAC
-		if( row.PhysicalAddressLength > 6 )
-			return ERROR_BAD_FORMAT;
-	 
-		//
-		// making source IB data
-		//
-		__mac_to_be64( pMac, row.PhysicalAddress);
-		status = ERROR_SUCCESS;
-		
-		return status;
-	}
-	 
-
-	static 
-	HRESULT
-	__build_port_list(
-		__out	roce_ib_data_t **pp_ib_data,
-		__out	uint32_t *p_port_ix
-		)
-	{
-		ib_api_status_t 	ib_status = IB_SUCCESS;
-		DWORD 	status = ERROR_SUCCESS;
-		size_t 			guid_count;
-		ib_net64_t		*ca_guid_array = NULL;
-		ib_ca_attr_t		*vstat_ca_attr;
-		size_t 			i;
-		ib_al_handle_t	h_al;
-		ib_ca_handle_t 	h_ca = NULL;
-		uint32_t 			bsize;
-		uint8_t			port_idx;
-		roce_ib_data_t *p_ib_data;
-		uint32_t		port_count, port_cur_ix=0;
-		ib_port_attr_t* portPtr;
-		
-		// Open the AL instance
-		ib_status = ib_open_al(&h_al);
-		if(ib_status != IB_SUCCESS)
-		{
-			status = IB2Hresult(ib_status);
-			goto exit;
-		}
-		CL_ASSERT(h_al);
-
-		// Get the Local CA Guids
-		ib_status = ib_get_ca_guids(h_al, NULL, &guid_count);
-		if(ib_status != IB_INSUFFICIENT_MEMORY)
-		{
-			status = IB2Hresult(ib_status);
-			goto err1;
-		}
-
-		// If no CA's Present then return
-		if(guid_count == 0)
-		{
-			status = HRESULT_FROM_WIN32( ERROR_FILE_NOT_FOUND );
-			goto err1;
-		}
-
-		// alloc GUID array
-		ca_guid_array = (ib_net64_t*)cl_zalloc(sizeof(ib_net64_t) * guid_count);
-		if (ca_guid_array == NULL)
-		{
-			status = HRESULT_FROM_WIN32( ERROR_NOT_ENOUGH_MEMORY );
-			goto err1;
-		}
-
-		// fill GUID array	
-		ib_status = ib_get_ca_guids(h_al, ca_guid_array, &guid_count);
-		if(ib_status != IB_SUCCESS)
-		{
-			status = IB2Hresult(ib_status);
-			goto err1;
-		}
-
-		// alloc ib_data array
-		port_count = (uint32_t)guid_count * 2;
-		p_ib_data = (roce_ib_data_t*)cl_zalloc(sizeof(roce_ib_data_t)*port_count);
-		if ( p_ib_data == NULL )
-		{
-			status = HRESULT_FROM_WIN32( ERROR_NOT_ENOUGH_MEMORY );
-			goto err1;
-		}
-
-		// For Each CA Guid found Open the CA, Query the CA Attribute and close the CA
-		for(i=0; i < guid_count; i++)
-		{
-
-			// Open the CA 
-			ib_status = ib_open_ca(h_al, ca_guid_array[i], NULL, NULL, &h_ca);
-
-			if(ib_status != IB_SUCCESS)
-			{
-				status = IB2Hresult(ib_status);
-				goto err2;
-			}
-
-			// Query the CA 
-			bsize = 0;
-			ib_status = ib_query_ca(h_ca, NULL, &bsize);
-			if(ib_status != IB_INSUFFICIENT_MEMORY)
-			{
-				status = IB2Hresult(ib_status);
-				goto err3;
-			}
-			CL_ASSERT(bsize);
-
-			vstat_ca_attr = (ib_ca_attr_t *)cl_zalloc(bsize);
-			if (vstat_ca_attr == NULL)
-			{
-				status = HRESULT_FROM_WIN32( ERROR_NOT_ENOUGH_MEMORY );
-				goto err3;
-			}
-
-			ib_status = ib_query_ca(h_ca, vstat_ca_attr, &bsize);
-			if ( ib_status != IB_SUCCESS )
-			{
-				status = IB2Hresult(ib_status);
-				goto err4;
-			}
-
-			if ( vstat_ca_attr->num_ports < 1 )
-				goto next_ca;
-
-			// fill ib_data array
-			for( port_idx =0; port_idx< vstat_ca_attr->num_ports; port_idx++ )
-			{
-				portPtr = vstat_ca_attr->p_port_attr+port_idx;
-				if( portPtr->transport == RDMA_TRANSPORT_RDMAOE && 
-					portPtr->link_state == 4 )
-				{
-					p_ib_data[port_cur_ix].ca_guid = vstat_ca_attr->ca_guid;
-					p_ib_data[port_cur_ix].port_num = port_idx + 1;
-					p_ib_data[port_cur_ix].port_guid = portPtr->p_gid_table->unicast.interface_id;
-					CL_ASSERT( portPtr->p_pkey_table[0] == 0xffff );
-					p_ib_data[port_cur_ix].port_pkey = portPtr->p_pkey_table[0];
-					p_ib_data[port_cur_ix].port_type = (UCHAR)portPtr->transport;
-					__guid_to_mac( (UCHAR *)&p_ib_data[port_cur_ix].mac, p_ib_data[port_cur_ix].port_guid );
-					__mac_to_be64( &p_ib_data[port_cur_ix].mac64, p_ib_data[port_cur_ix].mac );
-					p_ib_data[port_cur_ix].mtu = portPtr->mtu;
-					p_ib_data[port_cur_ix].active_speed = portPtr->active_speed;
-					p_ib_data[port_cur_ix].ext_active_speed = portPtr->ext_active_speed;
-					p_ib_data[port_cur_ix].link_encoding = portPtr->link_encoding;
-					port_cur_ix++;
-				}
-			}
-
-	next_ca:
-			// Free the memory 
-			cl_free(vstat_ca_attr);
-			vstat_ca_attr = NULL;
-			// Close the current open CA 
-			ib_close_ca(h_ca, NULL);
-			h_ca = NULL;
-
-		}
-
-		CL_ASSERT( status == ERROR_SUCCESS );
-		*pp_ib_data = p_ib_data;
-		*p_port_ix = port_cur_ix;
-		goto end;
-
-	err4:
-		cl_free(vstat_ca_attr);
-		
-	err3:
-		if(h_ca != NULL)
-			ib_close_ca(h_ca, NULL);
-
-	err2:
-		if ( p_ib_data )
-			cl_free(p_ib_data);
-		
-	err1:
-	end:	
-		if (ca_guid_array)
-			cl_free(ca_guid_array);
-		ib_close_al(h_al);
-	exit:
-		return status;
-	}
-
-	HRESULT
-	RoceIpToPort(
-		__in const struct sockaddr* pSrcAddr,
-		__out	   IBAT_PORT_RECORD *pPortRec,
-		__out      UINT64 *pMac64
-		)
-	{
-		HRESULT hr;
-		DWORD status;
-
-		// find our mac
-		UINT64 mac64;
-		status = __src_ip_2_mac64( pSrcAddr, &mac64 );
-		if( status != NO_ERROR )
-			return HRESULT_FROM_WIN32( status );
-
-		// build port list
-		uint32_t port_cnt;
-		roce_ib_data_t *p_ib_data;
-		hr = __build_port_list( &p_ib_data, &port_cnt );
-		if ( FAILED( hr ) )
-			return hr;
-
-		// find RoCE port
-		uint32_t ix;
-		for (ix = 0; ix < port_cnt; ++ix )
-		{
-			if ( p_ib_data[ix].mac64 == mac64 )
-				break;
-		}
-
-		// fill the results, when the port was found
-		if ( ix < port_cnt )
-		{
-			pPortRec->CaGuid 	= p_ib_data[ix].ca_guid;
-			pPortRec->PortGuid	= p_ib_data[ix].port_guid;
-			pPortRec->PKey 		= p_ib_data[ix].port_pkey;
-			pPortRec->PortNum	= p_ib_data[ix].port_num;
-			hr = S_OK;
-		}
-		else
-			hr = HRESULT_FROM_WIN32( ERROR_NOT_FOUND );
-
-		
-		if (pMac64) 
-		{
-			*pMac64 = mac64;
-		}
-		// release resources
-		cl_free( p_ib_data );		 
-		return hr;
-	}
-
-	static void AL_API
-	__path_rec_set_hop_flow_raw(
-			OUT 		ib_path_rec_t* const		p_rec,
-		IN		const	uint8_t 					hop_limit,
-		IN		const	net32_t 					flow_lbl,
-		IN		const	boolean_t					raw )
-	{
-		p_rec->hop_flow_raw = raw ? 0x80000000 : 0;
-		p_rec->hop_flow_raw |= (cl_ntoh32( flow_lbl ) & 0x000FFFFF) << 8;
-		p_rec->hop_flow_raw |= hop_limit;
-		p_rec->hop_flow_raw = cl_hton32( p_rec->hop_flow_raw );
-	}
-
-	static void AL_API
-	__path_rec_set_sl(IN ib_path_rec_t * const p_rec, IN const uint8_t sl)
-	{
-		p_rec->qos_class_sl =
-			(p_rec->qos_class_sl & CL_HTON16(IB_PATH_REC_QOS_CLASS_MASK)) |
-			cl_hton16(sl & IB_PATH_REC_SL_MASK);
-	}
-
-	static void AL_API
-	__path_rec_set_qos_class(IN ib_path_rec_t * const p_rec,
-				  IN const uint16_t qos_class)
-	{
-		p_rec->qos_class_sl =
-			(p_rec->qos_class_sl & CL_HTON16(IB_PATH_REC_SL_MASK)) |
-			cl_hton16(qos_class << 4);
-	}
-
-	HRESULT
-	RoceMacToPath(
-		__in const UINT64 PortGuid,
-		__in const UCHAR DestMac[IBAT_MAC_LEN],
-		__out IBAT_PATH_BLOB* pPath
-		)
-	{
-		ib_path_rec_t		 path;
-		UINT64 mac64;
-		__mac_to_be64( &mac64, (PUCHAR)DestMac);
-		RtlZeroMemory( &path, sizeof(path) );
-		path.service_id = 0;
-		__mac_to_guid((uint8_t*)&path.dgid.unicast.interface_id, cl_hton64(mac64));
-		path.dgid.unicast.prefix = cl_hton64((UINT64)0xfe80000000000000LL);
-		path.sgid.unicast.interface_id  = PortGuid;
-		path.sgid.unicast.prefix = cl_hton64((UINT64)0xfe80000000000000LL);
-		path.dlid = 0;
-		path.slid = 0;
-		__path_rec_set_hop_flow_raw( &path, 1, 0, 0 );
-		path.tclass = 0;
-		path.num_path = 0;
-		path.pkey = cl_hton16(IB_DEFAULT_PKEY);
-		__path_rec_set_sl(&path, 0);
-		__path_rec_set_qos_class(&path, 0);
-		//TODO - get the right MTU
-		path.mtu = IB_MTU_LEN_1024;
-		//TODO - get the right rate
-		path.rate = IB_PATH_RECORD_RATE_10_GBS;
-		path.pkt_life = 0;
-		path.preference = 0;
-	 
-		RtlCopyMemory(pPath, &path, sizeof(*pPath));
-		return S_OK;
-	}
-
-	HRESULT
-	RoceMacToGid(
-		__in const ULONGLONG PortGuid,
-		__in const UCHAR DestMac[IBAT_MAC_LEN],
-		__out ib_gid_t *pDestGid
-		)
-	{
-		UINT64 mac64;
-		UNREFERENCED_PARAMETER(PortGuid);
-		__mac_to_be64( &mac64, (PUCHAR)DestMac);
-		__mac_to_guid((uint8_t*)&pDestGid->unicast.interface_id, cl_hton64(mac64));
-		pDestGid->unicast.prefix	= cl_hton64((uint64_t)0xfe80000000000000LL);
-		return S_OK;
-	}
-
-	HRESULT
-	RoceGetPorts(
-		__in const ULONG PortsSize,
-		__out IOCTL_IBAT_PORTS_OUT* pPorts
-		)
-	{
-		UNREFERENCED_PARAMETER(PortsSize);
-		UNREFERENCED_PARAMETER(pPorts);
-
-		return HRESULT_FROM_WIN32(ERROR_NOT_SUPPORTED);
-	}
-
-	HRESULT
-	RoceGetIpAddresses(
-		__in const ULONGLONG PortGuid,
-		__in const ULONG IPsSize,
-		__out IOCTL_IBAT_IP_ADDRESSES_OUT *pIPs
-		)
-	{
-		UNREFERENCED_PARAMETER(PortGuid);
-		UNREFERENCED_PARAMETER(IPsSize);
-		UNREFERENCED_PARAMETER(pIPs);
-
-		return HRESULT_FROM_WIN32(ERROR_NOT_SUPPORTED);
-	}
-
-}
Index: .\inc\user\iba\ibat_ex.h
===================================================================
--- .\inc\user\iba\ibat_ex.h	(revision 3414)
+++ .\inc\user\iba\ibat_ex.h	(working copy)
@@ -1,140 +0,0 @@
-/*
- * Copyright (c) 2011 Mellanox Technologies. All rights reserved.
- *
- * This software is available to you under the OpenIB.org BSD license
- * below:
- *
- *     Redistribution and use in source and binary forms, with or
- *     without modification, are permitted provided that the following
- *     conditions are met:
- *
- *      - Redistributions of source code must retain the above
- *        copyright notice, this list of conditions and the following
- *        disclaimer.
- *
- *      - Redistributions in binary form must reproduce the above
- *        copyright notice, this list of conditions and the following
- *        disclaimer in the documentation and/or other materials
- *        provided with the distribution.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
- * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
- * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
- * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- */
-
-#ifndef _IBAT_EX_H_
-#define _IBAT_EX_H_
-
-#include <winsock2.h>
-#include <ws2tcpip.h>
-#include <iba/ib_at_ioctl.h>
-
-typedef struct _IBAT_PATH_BLOB
-{
-    UINT8 byte[64];
-
-} IBAT_PATH_BLOB;
-
-#ifdef __cplusplus
-namespace IBAT_EX
-{
-
-	HRESULT
-	Resolve(
-	    __in const struct sockaddr* pSrcAddr,
-	    __in const struct sockaddr* pDestAddr,
-	    __out IBAT_PATH_BLOB* pPath,
-		__out enum rdma_transport_type *pTransport
-	    );
-
-	HRESULT
-	ResolvePath(
-	    __in const struct sockaddr* pSrcAddr,
-	    __in const struct sockaddr* pDestAddr,
-	    __out IBAT_PATH_BLOB* pPath,
-		__out enum rdma_transport_type *pTransport,
-		__in DWORD Timeout	/* ms */
-	    );
-
-	HRESULT
-	IpToPort(
-		__in const struct sockaddr* pSrcAddr,
-	    __out      IBAT_PORT_RECORD *pPortRec
-	    );
-
-	HRESULT
-	MacToGid(
-		__in const ULONGLONG PortGuid,
-		__in const UCHAR DestMac[IBAT_MAC_LEN],
-		__out ib_gid_t *pDestGid
-		);
-
-	HRESULT
-	GetPorts(
-		__in const ULONG PortsSize,
-		__out IOCTL_IBAT_PORTS_OUT* pPorts
-		);
-
-	HRESULT
-	GetIpAddresses(
-		__in const ULONGLONG PortGuid,
-		__in const ULONG IPsSize,
-		__out IOCTL_IBAT_IP_ADDRESSES_OUT *pIPs
-		);
-
-}
-#else /* __cplusplus */
-
-HRESULT
-IbatexResolve(
-    __in const struct sockaddr* pSrcAddr,
-    __in const struct sockaddr* pDestAddr,
-    __out IBAT_PATH_BLOB* pPath,
-    __out enum rdma_transport_type *pTransport
-    );
-
-HRESULT
-IbatexResolvePath(
-    __in const struct sockaddr* pSrcAddr,
-    __in const struct sockaddr* pDestAddr,
-    __out IBAT_PATH_BLOB* pPath,
-    __out enum rdma_transport_type *pTransport,
-	__in DWORD Timeout	/* ms */
-    );
-
-HRESULT
-IbatexMacToGid(
-	__in const ULONGLONG PortGuid,
-	__in const UCHAR DestMac[IBAT_MAC_LEN],
-	__out ib_gid_t *pDestGid
-	);
-
-
-HRESULT
-IbatexIpToPort(
-	__in const struct sockaddr* pSrcAddr,
-    __out      IBAT_PORT_RECORD *pPortRec
-    );
-
-HRESULT
-IbatexGetPorts(
-	__in const ULONG PortsSize,
-	__out IOCTL_IBAT_PORTS_OUT* pPorts
-	);
-
-HRESULT
-IbatexGetIpAddresses(
-	__in const ULONGLONG PortGuid,
-	__in const ULONG IPsSize,
-	__out IOCTL_IBAT_IP_ADDRESSES_OUT *pIPs
-	);
-
-
-#endif /* __cplusplus */
-
-#endif	// _IBAT_EX_H_
Index: .\tests\ibat\dirs
===================================================================
--- .\tests\ibat\dirs	(revision 3414)
+++ .\tests\ibat\dirs	(working copy)
@@ -1,2 +0,0 @@
-DIRS=\
-	user
Index: .\tests\ibat\dirs.sln
===================================================================
--- .\tests\ibat\dirs.sln	(revision 3414)
+++ .\tests\ibat\dirs.sln	(working copy)
@@ -1,50 +0,0 @@
-
-Microsoft Visual Studio Solution File, Format Version 11.00
-# Visual Studio 2010
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "PrintIP", "user\PrintIP.VcxProj", "{172DBFAC-4E05-49C6-B040-1914A8B5F571}"
-EndProject
-Global
-	GlobalSection(SolutionConfigurationPlatforms) = preSolution
-		Win8 beta Debug|Win32 = Win8 beta Debug|Win32
-		Win8 beta Debug|x64 = Win8 beta Debug|x64
-		Win8 beta Release|Win32 = Win8 beta Release|Win32
-		Win8 beta Release|x64 = Win8 beta Release|x64
-		Win7 Debug|Win32 = Win7 Debug|Win32
-		Win7 Debug|x64 = Win7 Debug|x64
-		Win7 Release|Win32 = Win7 Release|Win32
-		Win7 Release|x64 = Win7 Release|x64
-		Vista Debug|Win32 = Vista Debug|Win32
-		Vista Debug|x64 = Vista Debug|x64
-		Vista Release|Win32 = Vista Release|Win32
-		Vista Release|x64 = Vista Release|x64
-	EndGlobalSection
-	GlobalSection(ProjectConfigurationPlatforms) = postSolution
-		{172DBFAC-4E05-49C6-B040-1914A8B5F571}.Win8 beta Debug|Win32.ActiveCfg = Win8 beta Debug|Win32
-		{172DBFAC-4E05-49C6-B040-1914A8B5F571}.Win8 beta Debug|Win32.Build.0 = Win8 beta Debug|Win32
-		{172DBFAC-4E05-49C6-B040-1914A8B5F571}.Win8 beta Debug|x64.ActiveCfg = Win8 beta Debug|x64
-		{172DBFAC-4E05-49C6-B040-1914A8B5F571}.Win8 beta Debug|x64.Build.0 = Win8 beta Debug|x64
-		{172DBFAC-4E05-49C6-B040-1914A8B5F571}.Win8 beta Release|Win32.ActiveCfg = Win8 beta Release|Win32
-		{172DBFAC-4E05-49C6-B040-1914A8B5F571}.Win8 beta Release|Win32.Build.0 = Win8 beta Release|Win32
-		{172DBFAC-4E05-49C6-B040-1914A8B5F571}.Win8 beta Release|x64.ActiveCfg = Win8 beta Release|x64
-		{172DBFAC-4E05-49C6-B040-1914A8B5F571}.Win8 beta Release|x64.Build.0 = Win8 beta Release|x64
-		{172DBFAC-4E05-49C6-B040-1914A8B5F571}.Win7 Debug|Win32.ActiveCfg = Win7 Debug|Win32
-		{172DBFAC-4E05-49C6-B040-1914A8B5F571}.Win7 Debug|Win32.Build.0 = Win7 Debug|Win32
-		{172DBFAC-4E05-49C6-B040-1914A8B5F571}.Win7 Debug|x64.ActiveCfg = Win7 Debug|x64
-		{172DBFAC-4E05-49C6-B040-1914A8B5F571}.Win7 Debug|x64.Build.0 = Win7 Debug|x64
-		{172DBFAC-4E05-49C6-B040-1914A8B5F571}.Win7 Release|Win32.ActiveCfg = Win7 Release|Win32
-		{172DBFAC-4E05-49C6-B040-1914A8B5F571}.Win7 Release|Win32.Build.0 = Win7 Release|Win32
-		{172DBFAC-4E05-49C6-B040-1914A8B5F571}.Win7 Release|x64.ActiveCfg = Win7 Release|x64
-		{172DBFAC-4E05-49C6-B040-1914A8B5F571}.Win7 Release|x64.Build.0 = Win7 Release|x64
-		{172DBFAC-4E05-49C6-B040-1914A8B5F571}.Vista Debug|Win32.ActiveCfg = Vista Debug|Win32
-		{172DBFAC-4E05-49C6-B040-1914A8B5F571}.Vista Debug|Win32.Build.0 = Vista Debug|Win32
-		{172DBFAC-4E05-49C6-B040-1914A8B5F571}.Vista Debug|x64.ActiveCfg = Vista Debug|x64
-		{172DBFAC-4E05-49C6-B040-1914A8B5F571}.Vista Debug|x64.Build.0 = Vista Debug|x64
-		{172DBFAC-4E05-49C6-B040-1914A8B5F571}.Vista Release|Win32.ActiveCfg = Vista Release|Win32
-		{172DBFAC-4E05-49C6-B040-1914A8B5F571}.Vista Release|Win32.Build.0 = Vista Release|Win32
-		{172DBFAC-4E05-49C6-B040-1914A8B5F571}.Vista Release|x64.ActiveCfg = Vista Release|x64
-		{172DBFAC-4E05-49C6-B040-1914A8B5F571}.Vista Release|x64.Build.0 = Vista Release|x64
-	EndGlobalSection
-	GlobalSection(SolutionProperties) = preSolution
-		HideSolutionNode = FALSE
-	EndGlobalSection
-EndGlobal
Index: .\tests\ibat\user\PrintIP.VcxProj
===================================================================
--- .\tests\ibat\user\PrintIP.VcxProj	(revision 3414)
+++ .\tests\ibat\user\PrintIP.VcxProj	(working copy)
@@ -1,212 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
-  <ItemGroup Label="ProjectConfigurations">
-    <ProjectConfiguration Include="Win8 beta Debug|Win32">
-      <Configuration>Win8 beta Debug</Configuration>
-      <Platform>Win32</Platform>
-    </ProjectConfiguration>
-    <ProjectConfiguration Include="Win7 Debug|Win32">
-      <Configuration>Win7 Debug</Configuration>
-      <Platform>Win32</Platform>
-    </ProjectConfiguration>
-    <ProjectConfiguration Include="Vista Debug|Win32">
-      <Configuration>Vista Debug</Configuration>
-      <Platform>Win32</Platform>
-    </ProjectConfiguration>
-    <ProjectConfiguration Include="Win8 beta Release|Win32">
-      <Configuration>Win8 beta Release</Configuration>
-      <Platform>Win32</Platform>
-    </ProjectConfiguration>
-    <ProjectConfiguration Include="Win7 Release|Win32">
-      <Configuration>Win7 Release</Configuration>
-      <Platform>Win32</Platform>
-    </ProjectConfiguration>
-    <ProjectConfiguration Include="Vista Release|Win32">
-      <Configuration>Vista Release</Configuration>
-      <Platform>Win32</Platform>
-    </ProjectConfiguration>
-    <ProjectConfiguration Include="Win8 beta Debug|x64">
-      <Configuration>Win8 beta Debug</Configuration>
-      <Platform>x64</Platform>
-    </ProjectConfiguration>
-    <ProjectConfiguration Include="Win7 Debug|x64">
-      <Configuration>Win7 Debug</Configuration>
-      <Platform>x64</Platform>
-    </ProjectConfiguration>
-    <ProjectConfiguration Include="Vista Debug|x64">
-      <Configuration>Vista Debug</Configuration>
-      <Platform>x64</Platform>
-    </ProjectConfiguration>
-    <ProjectConfiguration Include="Win8 beta Release|x64">
-      <Configuration>Win8 beta Release</Configuration>
-      <Platform>x64</Platform>
-    </ProjectConfiguration>
-    <ProjectConfiguration Include="Win7 Release|x64">
-      <Configuration>Win7 Release</Configuration>
-      <Platform>x64</Platform>
-    </ProjectConfiguration>
-    <ProjectConfiguration Include="Vista Release|x64">
-      <Configuration>Vista Release</Configuration>
-      <Platform>x64</Platform>
-    </ProjectConfiguration>
-  </ItemGroup>
-  <PropertyGroup Label="PropertySheets">
-    <PlatformToolset>WindowsApplicationForDrivers8.0</PlatformToolset>
-    <ConfigurationType>Application</ConfigurationType>
-    <DriverType />
-    <TARGETNAME>PrintIP</TARGETNAME>
-    <Configuration>Win8 beta Debug</Configuration>
-  </PropertyGroup>
-  <PropertyGroup Label="Globals">
-    <VCTargetsPath Condition="'$(VCTargetsPath11)' != '' and '$(VisualStudioVersion)' == '11.0'">$(VCTargetsPath11)</VCTargetsPath>
-  </PropertyGroup>
-  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
-  <PropertyGroup Label="PropertySheets">
-    <ConversionToolVersion>1.0</ConversionToolVersion>
-    <WDKContentRoot Condition="'$(WDKContentRoot)' == ''">$(Registry:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows Kits\WDK at WDKContentRoot)</WDKContentRoot>
-    <WDKContentRoot Condition="'$(WDKContentRoot)' == ''">$(Registry:HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\Windows Kits\WDK at WDKContentRoot)</WDKContentRoot>
-    <WDKContentRoot Condition="!HasTrailingSlash('$(WDKContentRoot)')">$(WDKContentRoot)\</WDKContentRoot>
-    <BUILD_ALT_DIR>$(Configuration.Replace(' ',''))</BUILD_ALT_DIR>
-    <IntDir Condition="'$(Platform)'!='Win32'">$(BUILD_ALT_DIR)\$(Platform)\</IntDir>
-    <IntDir Condition="'$(Platform)'=='Win32'">$(BUILD_ALT_DIR)\x86\</IntDir>
-    <OutDir>$(IntDir)</OutDir>
-  </PropertyGroup>
-  <ImportGroup Label="PreConfiguration">
-    <Import Project="$(WDKContentRoot)\bin\conversion\PreConfiguration.props" />
-  </ImportGroup>
-  <PropertyGroup Label="Globals">
-    <ProjectGuid>{172DBFAC-4E05-49C6-B040-1914A8B5F571}</ProjectGuid>
-  </PropertyGroup>
-  <PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Win8 beta Debug|Win32'">
-    <TargetVersion>Win8</TargetVersion>
-    <UseDebugLibraries>True</UseDebugLibraries>
-  </PropertyGroup>
-  <PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Win7 Debug|Win32'">
-    <TargetVersion>Win7</TargetVersion>
-    <UseDebugLibraries>True</UseDebugLibraries>
-  </PropertyGroup>
-  <PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Vista Debug|Win32'">
-    <TargetVersion>Vista</TargetVersion>
-    <UseDebugLibraries>True</UseDebugLibraries>
-  </PropertyGroup>
-  <PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Win8 beta Release|Win32'">
-    <TargetVersion>Win8</TargetVersion>
-    <UseDebugLibraries>False</UseDebugLibraries>
-  </PropertyGroup>
-  <PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Win7 Release|Win32'">
-    <TargetVersion>Win7</TargetVersion>
-    <UseDebugLibraries>False</UseDebugLibraries>
-  </PropertyGroup>
-  <PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Vista Release|Win32'">
-    <TargetVersion>Vista</TargetVersion>
-    <UseDebugLibraries>False</UseDebugLibraries>
-  </PropertyGroup>
-  <PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Win8 beta Debug|x64'">
-    <TargetVersion>Win8</TargetVersion>
-    <UseDebugLibraries>True</UseDebugLibraries>
-  </PropertyGroup>
-  <PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Win7 Debug|x64'">
-    <TargetVersion>Win7</TargetVersion>
-    <UseDebugLibraries>True</UseDebugLibraries>
-  </PropertyGroup>
-  <PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Vista Debug|x64'">
-    <TargetVersion>Vista</TargetVersion>
-    <UseDebugLibraries>True</UseDebugLibraries>
-  </PropertyGroup>
-  <PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Win8 beta Release|x64'">
-    <TargetVersion>Win8</TargetVersion>
-    <UseDebugLibraries>False</UseDebugLibraries>
-  </PropertyGroup>
-  <PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Win7 Release|x64'">
-    <TargetVersion>Win7</TargetVersion>
-    <UseDebugLibraries>False</UseDebugLibraries>
-  </PropertyGroup>
-  <PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Vista Release|x64'">
-    <TargetVersion>Vista</TargetVersion>
-    <UseDebugLibraries>False</UseDebugLibraries>
-  </PropertyGroup>
-  <PropertyGroup>
-    <DebuggerFlavor Condition="'$(PlatformToolset)' == 'WindowsKernelModeDriver8.0'">DbgengKernelDebugger</DebuggerFlavor>
-    <DebuggerFlavor Condition="'$(PlatformToolset)' == 'WindowsUserModeDriver8.0'">DbgengRemoteDebugger</DebuggerFlavor>
-  </PropertyGroup>
-  <!-- Needed by any VcxProj -->
-  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
-  <ImportGroup Label="ExtensionSettings">
-  </ImportGroup>
-  <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Vista Release|x64'">
-    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" />
-  </ImportGroup>
-  <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Win7 Release|x64'">
-    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" />
-  </ImportGroup>
-  <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Win8 beta Release|x64'">
-    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" />
-  </ImportGroup>
-  <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Vista Debug|x64'">
-    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" />
-  </ImportGroup>
-  <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Win7 Debug|x64'">
-    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" />
-  </ImportGroup>
-  <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Win8 beta Debug|x64'">
-    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" />
-  </ImportGroup>
-  <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Vista Release|Win32'">
-    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" />
-  </ImportGroup>
-  <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Win7 Release|Win32'">
-    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" />
-  </ImportGroup>
-  <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Win8 beta Release|Win32'">
-    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" />
-  </ImportGroup>
-  <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Vista Debug|Win32'">
-    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" />
-  </ImportGroup>
-  <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Win7 Debug|Win32'">
-    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" />
-  </ImportGroup>
-  <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Win8 beta Debug|Win32'">
-    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" />
-  </ImportGroup>
-  <PropertyGroup Label="UserMacros" />
-  <!-- The WrappedTaskItems label is used by the conversion tool to identify the location where items 
-        associated with wrapped tasks will reside.-->
-  <ItemGroup Label="WrappedTaskItems" />
-  <ItemGroup>
-    <!-- We only add items (e.g. form ClSourceFiles) that do not already exist (e.g in the ClCompile list), this avoids duplication -->
-    <ClCompile Include="@(ClSourceFiles)" Exclude="@(ClCompile)" />
-    <ResourceCompile Include="@(RcSourceFiles)" Exclude="@(ResourceCompile)" />
-    <Midl Include="@(IdlSourceFiles)" Exclude="@(Midl)" />
-    <MessageCompile Include="@(McSourceFiles)" Exclude="@(MessageCompile)" />
-    <MASM Include="@(AsmSourceFiles)" Exclude="@(MASM)" />
-    <GenerateBmf Include="@(MofSourceFiles)" Exclude="@(GenerateBmf)" />
-  </ItemGroup>
-  <!-- Set default environment variables, e.g. for stampinf -->
-  <ItemGroup>
-    <BuildMacro Include="SDK_INC_PATH">
-      <Value>$(KIT_SHARED_INC_PATH)</Value>
-      <EnvironmentVariable>true</EnvironmentVariable>
-    </BuildMacro>
-  </ItemGroup>
-  <ItemGroup>
-    <Inf Include="*.inf" />
-    <FilesToPackage Include="$(TargetPath)" />
-  </ItemGroup>
-  <!-- Necessary to pick up propper files from local directory when in the IDE-->
-  <ItemGroup>
-    <None Include="*.txt;*.htm;*.html" />
-    <None Include="*.ico;*.cur;*.bmp;*.dlg;*.rct;*.gif;*.jpg;*.jpeg;*.wav;*.jpe;*.tiff;*.tif;*.png;*.rc2" />
-    <None Include="*.def;*.bat;*.hpj;*.asmx" />
-  </ItemGroup>
-  <ItemGroup>
-    <ClInclude Include="*.h;*.hpp;*.hxx;*.hm;*.inl;*.xsd" />
-  </ItemGroup>
-  <!-- /Necessary to pick up propper files from local directory when in the IDE-->
-  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
-  <Import Condition="'$(PlatformToolset)'=='Windows8.0SDK'" Project="$(WDKContentRoot)build\WindowsDriver8.0.Common.targets" />
-  <Import Condition="'$(Platform)'!='arm'" Project="$(VCTargetsPath)\BuildCustomizations\masm.props" />
-  <ImportGroup Label="ExtensionTargets">
-    <Import Condition="'$(Platform)'!='arm'" Project="$(VCTargetsPath)\BuildCustomizations\masm.targets" />
-  </ImportGroup>
-</Project>
\ No newline at end of file
Index: .\tests\ibat\user\SOURCES
===================================================================
--- .\tests\ibat\user\SOURCES	(revision 3414)
+++ .\tests\ibat\user\SOURCES	(working copy)
@@ -1,27 +0,0 @@
-TARGETNAME=PrintIP
-TARGETPATH=..\..\..\bin\user\obj$(BUILD_ALT_DIR)
-TARGETTYPE=PROGRAM
-UMTYPE=console
-USE_MSVCRT=1
-
-SOURCES=\
-	PrintIp.c
-
-TARGETLIBS=\
-	$(SDK_LIB_PATH)\ws2_32.lib \
-	$(SDK_LIB_PATH)\Iphlpapi.lib
-
-!if !$(FREEBUILD)
-C_DEFINES=$(C_DEFINES) -D_DEBUG -DDEBUG -DDBG
-!endif
-
-MSC_WARNING_LEVEL= /W4
-
-INCLUDES=..\..\..\inc;\
-	..\..\..\inc\user;
-
-!if $(_NT_TARGET_VERSION) < 0x602
-INCLUDES=$(INCLUDES) \
-         $(PLATFORM_SDK_PATH)\include;
-!endif
-	
Index: .\tests\ibat\user\sources.props
===================================================================
--- .\tests\ibat\user\sources.props	(revision 3414)
+++ .\tests\ibat\user\sources.props	(working copy)
@@ -1,30 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
-  <PropertyGroup>
-    <TARGETNAME Condition="'$(OVERRIDE_TARGETNAME)'!='true'">PrintIP</TARGETNAME>
-    <TARGETPATH Condition="'$(OVERRIDE_TARGETPATH)'!='true'">..\..\..\bin\user\obj$(BUILD_ALT_DIR)</TARGETPATH>
-    <TARGETTYPE Condition="'$(OVERRIDE_TARGETTYPE)'!='true'">PROGRAM</TARGETTYPE>
-    <UMTYPE Condition="'$(OVERRIDE_UMTYPE)'!='true'">console</UMTYPE>
-    <USE_MSVCRT Condition="'$(OVERRIDE_USE_MSVCRT)'!='true'">1</USE_MSVCRT>
-    <SOURCES Condition="'$(OVERRIDE_SOURCES)'!='true'">PrintIp.c</SOURCES>
-    <TARGETLIBS Condition="'$(OVERRIDE_TARGETLIBS)'!='true'">$(SDK_LIB_PATH)\ws2_32.lib  	$(SDK_LIB_PATH)\Iphlpapi.lib</TARGETLIBS>
-  </PropertyGroup>
-  <Choose>
-    <When Condition="!('$(FREEBUILD)'!='' And $(FREEBUILD)!=0)">
-      <PropertyGroup>
-        <C_DEFINES Condition="'$(OVERRIDE_C_DEFINES)'!='true'">$(C_DEFINES) -D_DEBUG -DDEBUG -DDBG</C_DEFINES>
-      </PropertyGroup>
-    </When>
-  </Choose>
-  <PropertyGroup>
-    <MSC_WARNING_LEVEL Condition="'$(OVERRIDE_MSC_WARNING_LEVEL)'!='true'">/W4</MSC_WARNING_LEVEL>
-    <INCLUDES Condition="'$(OVERRIDE_INCLUDES)'!='true'">..\..\..\inc; 	..\..\..\inc\user;</INCLUDES>
-  </PropertyGroup>
-  <Choose>
-    <When Condition="$(_NT_TARGET_VERSION)<0x602">
-      <PropertyGroup>
-        <INCLUDES Condition="'$(OVERRIDE_INCLUDES)'!='true'">$(INCLUDES)           $(PLATFORM_SDK_PATH)\include;</INCLUDES>
-      </PropertyGroup>
-    </When>
-  </Choose>
-</Project>
\ No newline at end of file
Index: .\tests\ibat\user\PrintIp.c
===================================================================
--- .\tests\ibat\user\PrintIp.c	(revision 3414)
+++ .\tests\ibat\user\PrintIp.c	(working copy)
@@ -1,252 +0,0 @@
-/*
- * Copyright (c) 2005 Mellanox Technologies.  All rights reserved.
- * Copyright (c) 2005 SilverStorm Technologies.  All rights reserved.
- *
- * This software is available to you under the OpenIB.org BSD license
- * below:
- *
- *     Redistribution and use in source and binary forms, with or
- *     without modification, are permitted provided that the following
- *     conditions are met:
- *
- *      - Redistributions of source code must retain the above
- *        copyright notice, this list of conditions and the following
- *        disclaimer.
- *
- *      - Redistributions in binary form must reproduce the above
- *        copyright notice, this list of conditions and the following
- *        disclaimer in the documentation and/or other materials
- *        provided with the distribution.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
- * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
- * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
- * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- */
-
-
-#include <windows.h>
-#include <devioctl.h>
-#include <stdio.h>
-#include <Iphlpapi.h>
-#include "iba\ib_types.h"
-#include <iba\ib_at_ioctl.h>
-
-
-// Print all ips that are related to infiniband on this computer
-int print_ips()
-{
-	HANDLE hKernelLib;
-	HRESULT hr = S_OK;
-	char temp [1000];
-	char temp1 [1000];
-	IOCTL_IBAT_PORTS_IN ipoib_ports_in;
-	IOCTL_IBAT_PORTS_OUT *p_ipoib_ports_out;
-	IBAT_PORT_RECORD *ports_records;
-
-	IOCTL_IBAT_IP_ADDRESSES_IN addresses_in;
-	IOCTL_IBAT_IP_ADDRESSES_OUT *addresses_out;
-	IP_ADDRESS       *ip_addreses;
-
-	BOOL ret;
-	int i,j;
-	DWORD BytesReturned = 0;
-
-	printf("Adapters that are known to the ipoib modules are:\n\n");
-
-	hKernelLib =
-		CreateFileW(
-		IBAT_WIN32_NAME,
-		GENERIC_READ | GENERIC_WRITE,
-		FILE_SHARE_READ | FILE_SHARE_WRITE, // share mode none
-		NULL,                               // no security
-		OPEN_EXISTING,
-		FILE_ATTRIBUTE_NORMAL,
-		NULL                                // no template
-		);
-
-	if (hKernelLib == INVALID_HANDLE_VALUE) {
-		hr = HRESULT_FROM_WIN32(GetLastError());
-		printf("failed to open the kernel device hr=0x%x\n", hr);
-		return 1;
-	}
-    RtlSecureZeroMemory(&ipoib_ports_in, sizeof (ipoib_ports_in));
-    RtlSecureZeroMemory(&addresses_in, sizeof(addresses_in));
-	ipoib_ports_in.Version = IBAT_IOCTL_VERSION;
-
-	p_ipoib_ports_out = (IOCTL_IBAT_PORTS_OUT *)temp;
-
-	ret = DeviceIoControl(
-		hKernelLib,
-		IOCTL_IBAT_PORTS,
-		&ipoib_ports_in,
-		sizeof(ipoib_ports_in),
-		p_ipoib_ports_out,
-		sizeof(temp),
-		&BytesReturned,
-		NULL
-		);
-
-	if (ret == 0) {
-		hr = HRESULT_FROM_WIN32(GetLastError());
-		printf("DeviceIoControl failed for IOCTL_IBAT_PORTS hr=0x%x\n", hr);
-		return 1;
-	}
-	if (p_ipoib_ports_out->Size > sizeof(temp)) {
-		printf("Data truncated, please call again with a buffer of %d bytes", p_ipoib_ports_out->Size);
-	}
-
-	ports_records = p_ipoib_ports_out->Ports;
-	printf("Number of devices %d\n", p_ipoib_ports_out->NumPorts);
-	for (i = 0 ; i < p_ipoib_ports_out->NumPorts; i++)
-	{
-		printf("%d: ca guid = 0x%I64x port guid=0x%I64x\n", i, CL_NTOH64(ports_records[i].CaGuid), CL_NTOH64(ports_records[i].PortGuid));
-
-		// print the ip adresses of this port
-		addresses_in.Version = IBAT_IOCTL_VERSION;
-		addresses_in.PortGuid = ports_records[i].PortGuid;
-
-		addresses_out = (IOCTL_IBAT_IP_ADDRESSES_OUT *)temp1;
-
-		ret = DeviceIoControl(
-			hKernelLib,
-			IOCTL_IBAT_IP_ADDRESSES,
-			&addresses_in,
-			sizeof(addresses_in),
-			addresses_out,
-			sizeof(temp1),
-			&BytesReturned,
-			NULL
-			);
-
-		if (ret == 0)
-		{
-			hr = HRESULT_FROM_WIN32(GetLastError());
-			printf("DeviceIoControl failed for IOCTL_IBAT_IP_ADDRESSES hr=0x%x\n", hr);
-			return 1;
-		}
-		if (addresses_out->Size > sizeof(temp1) )
-		{
-			printf("Data truncated, please call again with a buffer of %d bytes", p_ipoib_ports_out->Size);
-			return 1;
-		}
-
-		printf("   found %d ips:", addresses_out->AddressCount);
-		ip_addreses = addresses_out->Address;
-		for (j = 0; j < addresses_out->AddressCount; j++)
-		{
-			printf("    %d.%d.%d.%d   ",
-				ip_addreses[j].Address[12],
-				ip_addreses[j].Address[13],
-				ip_addreses[j].Address[14],
-				ip_addreses[j].Address[15]);
-		}
-		printf("\n");
-	}
-
-	return 0;
-};
-
-void print_usage(char *argv[])
-{
-	printf("This program is used to print ip adapters and their addresses or to do arp\n");
-	printf("Usage is: %s <print_ips> \n",argv[0]);
-	printf("or %s <remoteip> <ip>  (for example %s remoteip 1.2.3.4)\n", argv[0],argv[0]);
-}
-
-int remote_ip(char *remote_ip)
-{
-	HANDLE hKernelLib;
-	HRESULT hr = S_OK;
-	IPAddr ip;
-	char *pIp = (char *)&ip;
-	int b1,b2,b3,b4;
-	DWORD  ret;
-	IOCTL_IBAT_MAC_TO_GID_IN mac;
-	IOCTL_IBAT_MAC_TO_GID_OUT gid;
-	DWORD BytesReturned = 0;
-
-	ULONG pMacAddr[2], PhyAddrLen ;
-	unsigned char *pMac = (unsigned char *)&pMacAddr;
-	PhyAddrLen = sizeof(pMacAddr);
-    RtlSecureZeroMemory(&mac, sizeof(mac));
-	hKernelLib =
-		CreateFileW(
-		IBAT_WIN32_NAME,
-		GENERIC_READ | GENERIC_WRITE,
-		FILE_SHARE_READ | FILE_SHARE_WRITE, // share mode none
-		NULL,                               // no security
-		OPEN_EXISTING,
-		FILE_ATTRIBUTE_NORMAL,
-		NULL                                // no template
-		);
-
-	if (hKernelLib == INVALID_HANDLE_VALUE)
-	{
-		hr = HRESULT_FROM_WIN32(GetLastError());
-		printf("failed to open the kernel device hr=0x%x\n", hr);
-		return 1;
-	}
-
-	sscanf_s(remote_ip, "%d.%d.%d.%d", &b1, &b2, &b3, &b4);
-	printf("Calling arp for addresses %d.%d.%d.%d\n", b1, b2, b3, b4);
-
-	pIp[0] = (char)b1;
-	pIp[1] = (char)b2;
-	pIp[2] = (char)b3;
-	pIp[3] = (char)b4;
-
-	ret = SendARP(ip ,0 ,pMacAddr, &PhyAddrLen );
-	if (ret != NO_ERROR)
-	{
-		printf("Error in SendARP");
-		return 1;
-	}
-
-	printf("Mac of the remote addresses is %x-%x-%x-%x-%x-%x\n",
-		pMac[0], pMac[1], pMac[2], pMac[3], pMac[4], pMac[5] );
-
-	// query for the gid
-	memcpy(mac.DestMac, pMac, 6);
-
-	ret = DeviceIoControl(
-		hKernelLib,
-		IOCTL_IBAT_MAC_TO_GID,
-		&mac,
-		sizeof(mac),
-		&gid,
-		sizeof(gid),
-		&BytesReturned,
-		NULL );
-
-	if (ret == 0)
-	{
-		hr = HRESULT_FROM_WIN32(GetLastError());
-		printf("DeviceIoControl failed for IOCTL_IBAT_IP_ADDRESSES hr=0x%x\n", hr);
-	}
-
-	printf("lid of remote ip is = 0x%I64x : 0x%I64x\n", CL_NTOH64(gid.DestGid.unicast.prefix), CL_NTOH64(gid.DestGid.unicast.interface_id));
-
-	return 0;
-}
-
-
-int __cdecl main(int argc, char *argv[])
-{
-	if (argc < 2) {
-		print_usage(argv);
-		return 1;
-	}
-	if (!strcmp(argv[1], "print_ips")) {
-		return print_ips();
-	}
-	if (!strcmp(argv[1], "remoteip")) {
-		return remote_ip(argv[2]);
-	}
-	print_usage(argv);
-	return 1;
-}
Index: .\tests\ibat\user\makefile
===================================================================
--- .\tests\ibat\user\makefile	(revision 3414)
+++ .\tests\ibat\user\makefile	(working copy)
@@ -1,7 +0,0 @@
-#
-# DO NOT EDIT THIS FILE!!!  Edit .\sources. if you want to add a new source
-# file to this component.  This file merely indirects to the real make file
-# that is shared by all the driver components of the Windows NT DDK
-#
-
-!INCLUDE ..\..\..\inc\openib.def
Index: .\tests\dirs
===================================================================
--- .\tests\dirs	(revision 3414)
+++ .\tests\dirs	(working copy)
@@ -2,7 +2,6 @@ DIRS=\
 	alts	\
 	cmtest	\
 	wsd	\
-	ibat	\
 	limits	\
 	wherebu	\
 	perftest	\
diff -dwup3 -X excl.txt -r c:\dev\openib\ofw\gen1\branches\mlx4_30\trunk\ulp\netdirect\user\SOURCES .\ulp\netdirect\user\SOURCES
--- c:\dev\openib\ofw\gen1\branches\mlx4_30\trunk\ulp\netdirect\user\SOURCES	Wed Aug 01 17:18:35 2012
+++ .\ulp\netdirect\user\SOURCES	Thu Jul 26 21:27:21 2012
@@ -24,23 +24,15 @@ SOURCES =			\
 	nd_cq.cpp
 
 INCLUDES = ..\..\..\inc;..\..\..\inc\user;\
-	   ..\..\..\inc\user\linux;$(ND_SDK_PATH)\include; \
-	   ..\..\..\core\complib\user\$(O); \
-	   ..\..\..\core\winverbs\user\$(O); \
-	   ..\..\..\core\al\user\$(O); \
-	   ..\..\..\core\ibat_ex\user\$(O); \
-	
-           
+           ..\..\..\inc\user\linux;$(ND_SDK_PATH)\include;
 
 TARGETLIBS =					\
 	$(SDK_LIB_PATH)\kernel32.lib	\
 	$(SDK_LIB_PATH)\uuid.lib		\
 	$(SDK_LIB_PATH)\ws2_32.lib	\
 	$(SDK_LIB_PATH)\iphlpapi.lib	\
-	$(TARGETPATH)\*\ibat_ex.lib \
-        $(TARGETPATH)\*\winverbs.lib	\
-        $(TARGETPATH)\*\ibal.lib			\
-        $(TARGETPATH)\*\complib.lib
+    $(TARGETPATH)\*\ibat.lib        \
+    $(TARGETPATH)\*\winverbs.lib
 
 
 !if !$(FREEBUILD)
Index: .\core\winverbs\user\SOURCES
===================================================================
--- .\core\winverbs\user\SOURCES	(revision 3429)
+++ .\core\winverbs\user\SOURCES	(working copy)
@@ -37,7 +37,6 @@
 	$(SDK_LIB_PATH)\uuid.lib		\
 	$(SDK_LIB_PATH)\ws2_32.lib	\
 	$(SDK_LIB_PATH)\iphlpapi.lib 	\
-	$(TARGETPATH)\*\ibat_ex.lib     \
         $(TARGETPATH)\*\ibal.lib \
         $(TARGETPATH)\*\complib.lib
 
Index: ulp/nd/user/SOURCES
===================================================================
--- ulp/nd/user/SOURCES	(revision 3429)
+++ ulp/nd/user/SOURCES	(working copy)
@@ -28,7 +28,6 @@
 
 INCLUDES=$(SDK_INC_PATH);..\..\..\inc;..\..\..\inc\user;..\..\..\core\al;\
 		  ..\..\..\core\al\user;$(ND_SDK_PATH)\include;\
-		  ..\..\..\core\ibat_ex\user\$(O);
 
 !if $(_NT_TARGET_VERSION) < 0x602
 INCLUDES=$(INCLUDES) \
@@ -45,7 +40,6 @@
 			$(SDK_LIB_PATH)\Advapi32.lib	\
 			$(SDK_LIB_PATH)\ws2_32.lib 	\
 			$(SDK_LIB_PATH)\iphlpapi.lib 	\
-			$(TARGETPATH)\*\ibat_ex.lib \
                         $(TARGETPATH)\*\complib.lib \
                         $(SDK_LIB_PATH)\uuid.lib

-------------- next part --------------
A non-text attachment was scrubbed...
Name: ndv2.32.patch
Type: application/octet-stream
Size: 277144 bytes
Desc: ndv2.32.patch
URL: <http://lists.openfabrics.org/pipermail/ofw/attachments/20130221/a1414b9b/attachment.obj>


More information about the ofw mailing list