<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<HTML><HEAD>
<META http-equiv=Content-Type content="text/html; charset=us-ascii">
<META content="MSHTML 6.00.2900.2802" name=GENERATOR></HEAD>
<BODY>
<DIV><FONT face=Arial size=2><SPAN class=298441317-06032006>Hi
fab,</SPAN></FONT></DIV>
<DIV><FONT face=Arial size=2><SPAN
class=298441317-06032006></SPAN></FONT> </DIV>
<DIV><FONT face=Arial size=2><SPAN class=298441317-06032006>Attached is the
first patch of the virtualization code for IPOIB. </SPAN></FONT><FONT face=Arial
size=2><SPAN class=298441317-06032006></SPAN></FONT></DIV>
<DIV><FONT face=Arial size=2><SPAN
class=298441317-06032006></SPAN></FONT> </DIV>
<DIV><FONT face=Arial size=2><SPAN class=298441317-06032006>There is an
assumption that the number of virtual servers will be small and therefore they
are currently stored in an array. We can move to something more efficient if you
feel that it is needed. For example a sorted array which will make the lookups
faster or some hash mechanism.</SPAN></FONT></DIV>
<DIV><FONT face=Arial size=2><SPAN
class=298441317-06032006></SPAN></FONT> </DIV>
<DIV><FONT face=Arial size=2><SPAN class=298441317-06032006>There is also a need
to decide what are the conditions to get one out of the table (timeout ?)
Currently there is no way out, but as the number of virtual machines is small
there is no such (real) problem. We might change the table to have a fixed
size to solve any potential security problems.</SPAN></FONT></DIV>
<DIV><FONT face=Arial size=2><SPAN
class=298441317-06032006></SPAN></FONT> </DIV>
<DIV><FONT face=Arial size=2><SPAN class=298441317-06032006>There is also some
assert in the DHCP code (see bellow) not sure what it really means, but ignoring
it seems fine.</SPAN></FONT></DIV>
<DIV><FONT face=Arial size=2><SPAN
class=298441317-06032006></SPAN></FONT> </DIV>
<DIV><FONT face=Arial size=2><SPAN class=298441317-06032006>The last thing to
solve is the locking problem. The table is read many times and written only a
small time. I thought of using the same mechanism as for the end point manager
that you have. If this is true than we only have to add locking before inserting
to the table.</SPAN></FONT></DIV>
<DIV><FONT face=Arial size=2><SPAN
class=298441317-06032006></SPAN></FONT> </DIV>
<DIV><FONT face=Arial size=2><SPAN class=298441317-06032006>Please send me your
feedback.</SPAN></FONT></DIV>
<DIV><FONT face=Arial size=2><SPAN
class=298441317-06032006></SPAN></FONT> </DIV>
<DIV><FONT face=Arial size=2><SPAN
class=298441317-06032006>Thanks</SPAN></FONT></DIV>
<DIV><FONT face=Arial size=2><SPAN
class=298441317-06032006>Tzachi</SPAN></FONT></DIV>
<DIV><FONT face=Arial size=2><SPAN
class=298441317-06032006></SPAN></FONT> </DIV>
<DIV><FONT face=Arial size=2><SPAN class=298441317-06032006>Index:
Q:/OpenIb/gen1/trunk/ulp/ipoib/kernel/ipoib_debug.h<BR>===================================================================<BR>---
Q:/OpenIb/gen1/trunk/ulp/ipoib/kernel/ipoib_debug.h (revision 226)<BR>+++
Q:/OpenIb/gen1/trunk/ulp/ipoib/kernel/ipoib_debug.h (working copy)<BR>@@
-60,7 +60,9 @@<BR> #define IPOIB_DBG_ALLOC (1 <<
8)<BR> #define IPOIB_DBG_OID (1 << 9)<BR> #define
IPOIB_DBG_IOCTL (1 << 10)<BR>+#define IPOIB_DBG_VM (1 <<
11)<BR> <BR>+<BR> #define IPOIB_DBG_FUNC (1 << 28) /*
For function entry/exit */<BR> #define IPOIB_DBG_INFO (1 <<
29) /* For verbose information */<BR> #define IPOIB_DBG_WARN (1
<< 30) /* For warnings. */<BR>Index:
Q:/OpenIb/gen1/trunk/ulp/ipoib/kernel/ipoib_port.c<BR>===================================================================<BR>---
Q:/OpenIb/gen1/trunk/ulp/ipoib/kernel/ipoib_port.c (revision 226)<BR>+++
Q:/OpenIb/gen1/trunk/ulp/ipoib/kernel/ipoib_port.c (working copy)<BR>@@
-237,6 +237,7 @@<BR> <BR> static
ib_api_status_t<BR> __recv_gen(<BR>+ IN const
ipoib_port_t*
const p_port,<BR> IN const ipoib_pkt_t*
const p_ipoib,<BR> OUT eth_pkt_t*
const p_eth,<BR> IN ipoib_endpt_t*
const p_src,<BR>@@ -461,7 +462,34 @@<BR> return cl_memcmp(
p_key1, p_key2, sizeof(ib_gid_t)
);<BR> }<BR> <BR>+/******************************************************************************<BR>+*<BR>+*
Virtual server ip to mac
translations<BR>+*<BR>+******************************************************************************/<BR>+static
void<BR>+__init_vs_ip_to_mac_translation(<BR>+ IN VS_ip_mac_manager
* p_manager);<BR> <BR>+static
void<BR>+__shutdown_vs_ip_to_mac_translation(<BR>+ IN VS_ip_mac_manager
* p_manager);<BR>+<BR>+static
ib_api_status_t<BR>+__get_mac_from_ip(<BR>+ IN const VS_ip_mac_manager
* const p_manager,<BR>+ IN net32_t dst_ip,<BR>+ OUT mac_addr_t
* p_dst_mac);<BR>+<BR>+static
ib_api_status_t<BR>+__put_mac_ip_pair(<BR>+ IN VS_ip_mac_manager
* p_manager,<BR>+ IN net32_t dst_ip,<BR>+ IN mac_addr_t dst_mac);<BR>+<BR>+<BR>+<BR>+<BR> /******************************************************************************<BR> *<BR> *
Implementation<BR>@@ -548,6 +576,8
@@<BR> <BR> __endpt_mgr_construct( p_port
);<BR> <BR>+ __init_vs_ip_to_mac_translation(
&p_port->vs_manager );<BR>+<BR> IPOIB_EXIT( IPOIB_DBG_INIT
);<BR> }<BR> <BR>@@ -702,6 +732,8
@@<BR> <BR> cl_obj_deinit( p_obj
);<BR> <BR>+ __shutdown_vs_ip_to_mac_translation(
&p_port->vs_manager );<BR>+<BR> cl_free( p_port
);<BR> <BR> IPOIB_EXIT( IPOIB_DBG_INIT );<BR>@@ -1780,7 +1812,7
@@<BR> continue;<BR> }<BR> <BR>- len
= p_wc->length - sizeof(ib_grh_t);<BR>+ len = p_wc->length -
sizeof(ib_grh_t); //????? Can there be a buffer overrun here
????<BR> <BR> if( len < sizeof(ipoib_hdr_t)
)<BR> {<BR>@@ -1838,7 +1870,7
@@<BR> {<BR> /*
Unfiltered. Setup the ethernet header and report.
*/<BR> cl_perf_start( RecvTcp
);<BR>- status = __recv_gen( p_ipoib, p_eth, p_src, p_dst
);<BR>+ status = __recv_gen( p_port, p_ipoib, p_eth,
p_src, p_dst );<BR> cl_perf_stop(
&p_port->p_adapter->perf, RecvTcp
);<BR> break;<BR> }<BR>@@
-1876,7 +1908,7
@@<BR> {<BR> /*
Unfiltered. Setup the ethernet header and report.
*/<BR> cl_perf_start( RecvUdp
);<BR>- status = __recv_gen( p_ipoib, p_eth, p_src, p_dst
);<BR>+ status = __recv_gen( p_port, p_ipoib, p_eth,
p_src, p_dst );<BR> cl_perf_stop(
&p_port->p_adapter->perf, RecvUdp
);<BR> }<BR> break;<BR>@@ -1898,7
+1930,7 @@<BR> default:<BR> /*
Unfiltered. Setup the ethernet header and report.
*/<BR> cl_perf_start( RecvGen
);<BR>- status = __recv_gen( p_ipoib, p_eth, p_src, p_dst
);<BR>+ status = __recv_gen( p_port, p_ipoib, p_eth, p_src,
p_dst );<BR> cl_perf_stop(
&p_port->p_adapter->perf, RecvGen
);<BR> }<BR> <BR>@@ -1943,11 +1975,15
@@<BR> <BR> static
ib_api_status_t<BR> __recv_gen(<BR>+ IN const
ipoib_port_t*
const p_port,<BR> IN const ipoib_pkt_t*
const p_ipoib,<BR> OUT eth_pkt_t*
const p_eth,<BR> IN ipoib_endpt_t*
const p_src,<BR> IN ipoib_endpt_t*
const p_dst
)<BR> {<BR>+ net16_t OriginalType;<BR>+ ib_api_status_t status;<BR>+ mac_addr_t
dst_mac;<BR> IPOIB_ENTER( IPOIB_DBG_RECV
);<BR> <BR> if( !p_src || !p_dst )<BR>@@ -1957,6 +1993,8
@@<BR> return
IB_NOT_DONE;<BR> }<BR> <BR>+ OriginalType =
p_ipoib->hdr.type;<BR>+<BR> /*<BR> * Fill in the
ethernet header. Note that doing so will overwrite<BR> * the
IPoIB header, so start by moving the information from the IPoIB<BR>@@ -1966,6
+2004,14 @@<BR> p_eth->hdr.src =
p_src->mac;<BR> p_eth->hdr.dst =
p_dst->mac;<BR> <BR>+ if (OriginalType == ETH_PROT_TYPE_IP)
<BR>+ {<BR>+ status =
__get_mac_from_ip(&p_port->vs_manager, p_ipoib->type.ip.hdr.dst_ip,
&dst_mac);<BR>+ if ( status == IB_SUCCESS)
<BR>+ {<BR>+ p_eth->hdr.dst =
dst_mac;<BR>+ }<BR>+ }<BR> IPOIB_EXIT( IPOIB_DBG_RECV
);<BR> return IB_SUCCESS;<BR> }<BR>@@ -1991,7 +2037,7
@@<BR> UNUSED_PARAM( p_port );<BR> <BR> /* Create the
ethernet header. */<BR>- status = __recv_gen( p_ipoib, p_eth, p_src, p_dst
);<BR>+ status = __recv_gen( p_port, p_ipoib, p_eth, p_src, p_dst
);<BR> if( status != IB_SUCCESS
)<BR> {<BR> IPOIB_TRACE_EXIT( IPOIB_DBG_ERROR,<BR>@@
-2128,6 +2174,7 @@<BR> const
ipoib_arp_pkt_t *p_ib_arp;<BR> ib_gid_t gid;<BR> mac_addr_t mac;<BR>+ mac_addr_t
dst_mac;<BR> ipoib_hw_addr_t null_hw =
{0};<BR> <BR> IPOIB_ENTER( IPOIB_DBG_RECV );<BR>@@ -2279,7
+2326,7 @@<BR> * Create the ethernet header. Note that this is
done last so that<BR> * we have a chance to create a new
endpoint.<BR> */<BR>- status = __recv_gen( p_ipoib, p_eth,
*pp_src, p_dst );<BR>+ status = __recv_gen( p_port, p_ipoib, p_eth,
*pp_src, p_dst );<BR> if( status != IB_SUCCESS
)<BR> {<BR> IPOIB_TRACE_EXIT( IPOIB_DBG_ERROR,<BR>@@
-2288,6 +2335,20 @@<BR> return
status;<BR> }<BR> <BR>+ if (p_eth->hdr.type
== ETH_PROT_TYPE_ARP) {<BR>+ if ((p_eth->type.arp.op ==
ARP_OP_REP)) <BR>+ {<BR>+ status =
__get_mac_from_ip(&p_port->vs_manager, p_eth->type.arp.dst_ip,
&dst_mac);<BR>+ if ( status == IB_SUCCESS)
<BR>+ {<BR>+ p_eth->hdr.dst =
dst_mac;<BR>+ p_eth->type.arp.dst_hw =
dst_mac;<BR>+ }<BR>+ }
<BR>+<BR>+<BR>+ }<BR>+<BR> IPOIB_EXIT(
IPOIB_DBG_RECV );<BR> return IB_SUCCESS;<BR> }<BR>@@ -3133,7
+3194,7 @@<BR> p_cid[1] =
21;<BR> }<BR> <BR>- CL_ASSERT( p_cid[1] == 21
);<BR>+//?????? CL_ASSERT( p_cid[1] == 21 ); // This asserts seems to
bounce, nothing happens if ignored ???<BR> p_cid[23]=
DHCP_OPT_END;<BR> ib_gid_set_default( &gid,
p_port->p_adapter->guids.port_guid );<BR> cl_memcpy(
&p_cid[7], &gid, sizeof(ib_gid_t) );<BR>@@ -3219,6 +3280,11
@@<BR> return
NDIS_STATUS_INVALID_DATA;<BR> }<BR> <BR>+ if ((p_arp->op
== ARP_OP_REQ))
<BR>+ {<BR>+ __put_mac_ip_pair(&p_port->vs_manager,p_arp->src_ip,
p_arp->src_hw );<BR>+ }<BR>+<BR> /* Allocate our scratch
buffer. */<BR> p_desc->p_buf =
(send_buf_t*)<BR> ExAllocateFromNPagedLookasideList(
&p_port->buf_mgr.send_buf_list );<BR>@@ -5211,3 +5277,124
@@<BR> <BR> IPOIB_EXIT( IPOIB_DBG_MCAST
);<BR> }<BR>+<BR>+static
void<BR>+__init_vs_ip_to_mac_translation(<BR>+ IN VS_ip_mac_manager
* p_manager)<BR>+{<BR>+ p_manager->p_pairs =
NULL;<BR>+ p_manager->data_size = 0;<BR>+ p_manager->array_size
= 0;<BR>+}<BR>+<BR>+static
void<BR>+__shutdown_vs_ip_to_mac_translation(<BR>+ IN VS_ip_mac_manager
* p_manager)<BR>+{<BR>+ if ( p_manager->p_pairs != NULL
) <BR>+ {<BR>+ cl_free( p_manager->p_pairs
);<BR>+ }<BR>+}<BR>+<BR>+static
ib_api_status_t<BR>+__get_mac_from_ip(<BR>+ IN const VS_ip_mac_manager
* const p_manager,<BR>+ IN net32_t dst_ip,<BR>+ OUT mac_addr_t
* p_dst_mac)<BR>+{<BR>+ uint32_t i;<BR>+ for (i
= 0 ; i < p_manager->data_size; i++ ) <BR>+ {<BR>+ if
(p_manager->p_pairs[i].dst_ip == dst_ip)
<BR>+ {<BR>+ // We have found the IP that we are
looking for<BR>+ *p_dst_mac =
p_manager->p_pairs[i].mac;<BR>+ IPOIB_TRACE(
IPOIB_DBG_VM,("__get_mac_from_ip dst_ip = %d.%d.%d.%d found in table\n",
<BR>+ ((dst_ip & 0xff
) ),<BR>+ ((dst_ip
& 0xff00 ) >> 8
),<BR>+ ((dst_ip & 0xff0000 ) >> 16
),<BR>+ ((dst_ip & 0xff000000) >> 24
)));<BR>+ <BR>+ return
IB_SUCCESS;<BR>+ }<BR>+ <BR>+ }<BR>+ //
Not found<BR>+ IPOIB_TRACE( IPOIB_DBG_VM,("__get_mac_from_ip dst_ip =
%d.%d.%d.%d not found \n", <BR>+ ((dst_ip &
0xff )
),<BR>+ ((dst_ip & 0xff00 ) >>
8 ),<BR>+ ((dst_ip & 0xff0000 ) >> 16
),<BR>+ ((dst_ip & 0xff000000) >> 24
)));<BR>+<BR>+ <BR>+ return IB_NOT_FOUND;<BR>+}<BR>+<BR>+static
ib_api_status_t<BR>+__put_mac_ip_pair(<BR>+ IN VS_ip_mac_manager
* p_manager,<BR>+ IN net32_t dst_ip,<BR>+ IN mac_addr_t dst_mac)<BR>+{<BR>+ uint32_t
i;<BR>+ uint32_t new_size = 0;<BR>+ VS_ip_mac_pair
*new_array;<BR>+ IPOIB_ENTER( IPOIB_DBG_VM );<BR>+<BR>+ IPOIB_TRACE(
IPOIB_DBG_VM,("__put_mac_ip_pair dst_ip = %d.%d.%d.%d \n",
<BR>+ ((dst_ip & 0xff
) ),<BR>+ ((dst_ip
& 0xff00 ) >> 8
),<BR>+ ((dst_ip & 0xff0000 ) >> 16
),<BR>+ ((dst_ip & 0xff000000) >> 24
)));<BR>+<BR>+ // First step is to look if this is actually an update and
not adding<BR>+ for (i = 0 ; i < p_manager->data_size; i++ )
<BR>+ {<BR>+ if (p_manager->p_pairs[i].dst_ip == dst_ip)
<BR>+ {<BR>+ // We have found the IP that we are
looking for, update it<BR>+ p_manager->p_pairs[i].mac =
dst_mac;<BR>+ return
IB_SUCCESS;<BR>+ }<BR>+ <BR>+ }<BR>+ //
Not found, let see if we need to increase the table<BR>+ if (
p_manager->array_size <= p_manager->data_size
)<BR>+ {<BR>+ // Need to increase the array<BR>+ if
(p_manager->array_size < 4)
<BR>+ {<BR>+ new_size = 4;<BR>+ } else
{<BR>+ new_size = p_manager->array_size *
2;<BR>+ }<BR>+ new_array = cl_zalloc(new_size * sizeof
(VS_ip_mac_pair));<BR>+ if ( new_array == NULL
)<BR>+ {<BR>+ IPOIB_TRACE_EXIT(
IPOIB_DBG_ERROR,<BR>+ ("Failed to allocate new_array.\n")
);<BR>+ return
CL_INSUFFICIENT_MEMORY;<BR>+ }<BR>+ // copy the data to
the new array<BR>+ if ( p_manager->array_size > 0 )
<BR>+ {<BR>+ cl_memcpy ( new_array,
p_manager->p_pairs, p_manager->data_size * sizeof
(VS_ip_mac_pair));<BR>+ }<BR>+ if ( p_manager->p_pairs
!= NULL ) <BR>+ {<BR>+ cl_free(
p_manager->p_pairs );<BR>+ }<BR>+ p_manager->p_pairs
= new_array;<BR>+ new_array =
NULL;<BR>+ p_manager->array_size =
new_size; <BR>+ }<BR>+<BR>+ p_manager->p_pairs[p_manager->data_size].dst_ip
= dst_ip;<BR>+ p_manager->p_pairs[p_manager->data_size].mac =
dst_mac;<BR>+ p_manager->data_size++;<BR>+<BR>+ return
IB_SUCCESS;<BR>+<BR>+}<BR>+<BR>Index:
Q:/OpenIb/gen1/trunk/ulp/ipoib/kernel/ipoib_port.h<BR>===================================================================<BR>---
Q:/OpenIb/gen1/trunk/ulp/ipoib/kernel/ipoib_port.h (revision 226)<BR>+++
Q:/OpenIb/gen1/trunk/ulp/ipoib/kernel/ipoib_port.h (working copy)<BR>@@
-468,7 +468,20 @@<BR> * are inserted in the LID
map.<BR> *********/<BR> <BR>+typedef struct
_VS_ip_mac_pair<BR>+{<BR>+ mac_addr_t mac;<BR>+ net32_t dst_ip;<BR>+}
VS_ip_mac_pair;<BR> <BR>+typedef struct
_VS_ip_mac_manager<BR>+{<BR>+ VS_ip_mac_pair *p_pairs;<BR>+ uint32_t array_size;<BR>+ uint32_t data_size;<BR>+}
VS_ip_mac_manager;<BR>+<BR>+<BR> typedef struct
_ipoib_port<BR> {<BR> cl_obj_t obj;<BR>@@
-496,8 +509,12
@@<BR> atomic32_t endpt_rdr;<BR> <BR> atomic32_t hdr_idx;<BR>- ipoib_hdr_t hdr[1];<BR> <BR>+ VS_ip_mac_manager vs_manager;<BR>+<BR>+ //
Must be last<BR>+ ipoib_hdr_t hdr[1];
<BR>+<BR> } ipoib_port_t;<BR> /*<BR> * FIELDS<BR>@@ -536,7
+553,6 @@<BR> * Endpoint
manager.<BR> *********/<BR> <BR>-<BR> ib_api_status_t<BR> ipoib_create_port(<BR> IN struct
_ipoib_adapter* const p_adapter,<BR></SPAN></FONT></DIV></BODY></HTML>