[ofw] [patch][IPoIB_NDIS6_CM] Network discovery support for IPv6
Alex Naslednikov
xalex at mellanox.co.il
Thu Jan 27 01:47:39 PST 2011
Applied at 7083
From: Alex Naslednikov
Sent: Wednesday, January 26, 2011 4:16 PM
To: Alex Naslednikov; ofw at lists.openfabrics.org
Subject: [ofw][patch][IPoIB_NDIS6_CM] Network discovery support for IPv6
Network discovery support for IPv6
Signed-off by: Galina Tcharny (galina at mellanox.co.il)
Index: inc/kernel/ip_packet.h
===================================================================
--- inc/kernel/ip_packet.h (revision 3080)
+++ inc/kernel/ip_packet.h (working copy)
@@ -49,6 +49,7 @@
#define ETH_PROT_TYPE_RARP CL_HTON16(0x8035)
#define ETH_PROT_VLAN_TAG CL_HTON16(0x8100)
+#define IPV6_ADDR_LENGTH 16
#define ETH_IS_LOCALLY_ADMINISTERED(addr) \
(BOOLEAN)(((PUCHAR)(addr))[0] & ((UCHAR)0x02))
@@ -637,7 +638,70 @@
} PACK_SUFFIX type;
} PACK_SUFFIX eth_pkt_t;
+
#include <complib/cl_packoff.h>
+#include <complib/cl_packon.h>
+#define ICMPV6_MSG_TYPE_NBR_SOL 135
+#define ICMPV6_MSG_TYPE_NBR_ADV 136
+
+typedef struct _icmpv6_hdr
+{
+ uint8_t type;
+ uint8_t code;
+ net16_t checksum;
+} icmpv6_hdr_t;
+
+typedef struct _icmpv6_pkt
+{
+ icmpv6_hdr_t hdr;
+
+ union
+ {
+ struct _icmpv6_neighbor_sol
+ {
+ net32_t reserved;
+ uint8_t target_addr[IPV6_ADDR_LENGTH];
+ } sol;
+
+ struct _icmpv6_neighbor_adv
+ {
+ net32_t flags;
+ uint8_t target_addr[IPV6_ADDR_LENGTH];
+ } adv;
+ } u;
+} icmpv6_pkt_t;
+
+#define ICMPV6_OPTION_SRC_LINK_ADDR 1
+#define ICMPV6_OPTION_TARGET_LINK_ADDR 2
+
+#define ICMPV6_IPOIB_LINK_ADDR_OPTION_LENGTH 24
+#define ICMPV6_IPOIB_LINK_ADDR_OPTION_ADDR_LENGTH (ICMPV6_IPOIB_LINK_ADDR_OPTION_LENGTH - 2)
+
+#define ICMPV6_ETH_LINK_ADDR_OPTION_LENGTH 8
+#define ICMPV6_ETH_LINK_ADDR_OPTION_ADDR_LENGTH (ICMPV6_ETH_LINK_ADDR_OPTION_LENGTH - 2)
+
+typedef struct _icmpv6_option
+{
+ uint8_t option_type;
+ uint8_t option_length; // length of the entire option in 8-byte blocks == 1(MAC Option)
+
+ union
+ {
+ struct _icmpv6_src_link_addr
+ {
+ uint8_t mac_addr[ICMPV6_IPOIB_LINK_ADDR_OPTION_ADDR_LENGTH];
+ } saddr;
+
+ struct _icmpv6_target_link_addr
+ {
+ uint8_t mac_addr[ICMPV6_IPOIB_LINK_ADDR_OPTION_ADDR_LENGTH];
+ } taddr;
+ } u;
+} icmpv6_option_t;
+
+
+#include <complib/cl_packoff.h>
+
#endif /* _IP_PACKET_H_ */
Index: ulp/ipoib_NDIS6_CM/kernel/ipoib_port.cpp
===================================================================
--- ulp/ipoib_NDIS6_CM/kernel/ipoib_port.cpp (revision 3080)
+++ ulp/ipoib_NDIS6_CM/kernel/ipoib_port.cpp (working copy)
@@ -305,6 +305,15 @@
IN ipoib_endpt_t* const p_dst );
static ib_api_status_t
+__recv_icmpv6(
+ IN ipoib_port_t* const p_port,
+ IN ib_wc_t* const p_wc,
+ IN ipoib_pkt_t* const p_ipoib,
+ OUT eth_pkt_t* const p_eth,
+ IN ipoib_endpt_t** const pp_src,
+ IN ipoib_endpt_t* const p_dst );
+
+static ib_api_status_t
__recv_mgr_prepare_NBL(
IN ipoib_port_t* const p_port,
IN ipoib_recv_desc_t* const p_desc,
@@ -377,6 +386,13 @@
IN size_t buf_len,
IN OUT ipoib_send_NB_SG* const s_buf );
+static NDIS_STATUS
+__send_mgr_filter_icmpv6(
+ IN const ipv6_hdr_t* const p_ipv6_hdr,
+ IN MDL* p_mdl,
+ IN size_t buf_len,
+ IN OUT ipoib_send_NB_SG* s_buf);
+
static inline void
__send_complete_net_buffer(
IN ipoib_send_NB_SG *s_buf,
@@ -419,6 +435,8 @@
IN PNDIS_TCP_LARGE_SEND_OFFLOAD_NET_BUFFER_LIST_INFO p_lso_info,
IN NET_BUFFER *p_netbuf);
+unsigned short ipchksum(unsigned short *ip, int len);
+
static inline void
ipoib_print_ip_hdr(
IN ip_hdr_t* const p_ip_hdr )
@@ -647,6 +665,13 @@
__leave_error_mcast_cb(
IN void *context );
+static ib_api_status_t
+__endpt_update(
+ IN ipoib_port_t* const p_port,
+ IN ipoib_endpt_t** const pp_src,
+ IN const ipoib_hw_addr_t* p_new_hw_addr,
+ IN ib_wc_t* const p_wc
+);
#if DBG
char *ref_cnt_str(int type);
@@ -2877,6 +2902,12 @@
status = IB_INVALID_SETTING;
break;
}
+
+ if( p_ipoib->type.ipv6.hdr.next_header == IP_PROT_ICMPV6 )
+ {
+ status = __recv_icmpv6( p_port, p_wc, p_ipoib, p_eth, &p_src, p_dst );
+ break;
+ }
if( p_ipoib->type.ipv6.hdr.next_header != IP_PROT_UDP )
{
@@ -3328,8 +3359,6 @@
ib_api_status_t status;
arp_pkt_t *p_arp;
const ipoib_arp_pkt_t *p_ib_arp;
- ib_gid_t gid;
- mac_addr_t mac;
ipoib_hw_addr_t null_hw = {0};
uint8_t cm_capable = 0;
boolean_t queue_rc_conn = FALSE;
@@ -3375,110 +3404,13 @@
if( !*pp_src )
*pp_src = __endpt_mgr_get_by_gid( p_port, &p_ib_arp->src_hw.gid );
- /*
- * If the endpoint exists for the GID, make sure
- * the dlid and qpn match the arp.
- */
- if( *pp_src )
- {
- if( memcmp( &(*pp_src)->dgid, &p_ib_arp->src_hw.gid, sizeof(ib_gid_t) ) )
- {
- /*
- * GIDs for the endpoint are different. The ARP must
- * have been proxied. Dereference it.
- */
- *pp_src = NULL;
- }
- else if( (*pp_src)->dlid && (*pp_src)->dlid != p_wc->recv.ud.remote_lid )
- {
- /* Out of date! Destroy the endpoint and replace it. */
- __endpt_mgr_remove( p_port, *pp_src );
- *pp_src = NULL;
- }
- else if ( ! ((*pp_src)->dlid))
- {
- /* Out of date! Destroy the endpoint and replace it. */
- __endpt_mgr_remove( p_port, *pp_src );
- *pp_src = NULL;
- }
- else if( ipoib_is_voltaire_router_gid( &(*pp_src)->dgid ) )
- {
- if( (*pp_src)->qpn != ipoib_addr_get_qpn( &p_ib_arp->src_hw ) &&
- p_wc->recv.ud.remote_qp != ipoib_addr_get_qpn( &p_ib_arp->src_hw ) )
- {
- /* Out of date! Destroy the endpoint and replace it. */
- __endpt_mgr_remove( p_port, *pp_src );
- *pp_src = NULL;
- }
- }
- else if( (*pp_src)->qpn != p_wc->recv.ud.remote_qp )
- {
- /* Out of date! Destroy the endpoint and replace it. */
- __endpt_mgr_remove( p_port, *pp_src );
- *pp_src = NULL;
- }
- }
+ status = __endpt_update(p_port, pp_src, &p_ib_arp->src_hw, p_wc);
- /* Do we need to create an endpoint for this GID? */
- if( !*pp_src )
+ if(status != IB_SUCCESS)
{
- /* Copy the src GID to allow aligned access */
- memcpy( &gid, &p_ib_arp->src_hw.gid, sizeof(ib_gid_t) );
- status = ipoib_mac_from_guid( gid.unicast.interface_id,
- p_port->p_adapter->params.guid_mask,
- &mac );
- if (status == IB_INVALID_GUID_MASK)
- {
- IPOIB_PRINT( TRACE_LEVEL_WARNING, IPOIB_DBG_ERROR,
- ("Invalid GUID mask received, rejecting it") );
- ipoib_create_log( p_port->p_adapter->h_adapter,
- GUID_MASK_LOG_INDEX,
- EVENT_IPOIB_WRONG_PARAMETER_WRN );
- return status;
- }
- else if( status != IB_SUCCESS )
- {
- IPOIB_PRINT_EXIT( TRACE_LEVEL_ERROR, IPOIB_DBG_ERROR,
- ("ipoib_mac_from_guid returned %s\n",
- p_port->p_adapter->p_ifc->get_err_str( status )) );
- return status;
- }
-
- /*
- * Create the endpoint.
- */
- *pp_src = ipoib_endpt_create( p_port,
- &p_ib_arp->src_hw.gid,
- p_wc->recv.ud.remote_lid, ipoib_addr_get_qpn( &p_ib_arp->src_hw ) );
-
- if( !*pp_src )
- {
- IPOIB_PRINT_EXIT( TRACE_LEVEL_ERROR, IPOIB_DBG_ERROR,
- ("ipoib_endpt_create failed\n") );
- return status;
- }
-#if DBG
- ipoib_port_ref( p_port, ref_endpt_track );
-#endif
- cl_obj_lock( &p_port->obj );
- status = __endpt_mgr_insert( p_port, mac, *pp_src );
- cl_obj_unlock( &p_port->obj );
- if( status != IB_SUCCESS )
- {
- IPOIB_PRINT_EXIT( TRACE_LEVEL_ERROR, IPOIB_DBG_ERROR,
- ("__endpt_mgr_insert return %s \n",
- p_port->p_adapter->p_ifc->get_err_str( status )) );
- return status;
- }
- IPOIB_PRINT( TRACE_LEVEL_INFORMATION, IPOIB_DBG_ARP,
- ("Created EP %p %s CM_cap %s cstate[%s] %s\n",
- (*pp_src),
- (*pp_src)->tag,
- (cm_capable == IPOIB_CM_FLAG_RC ? "1" : "0"),
- cm_get_state_str(endpt_cm_get_state((*pp_src))),
- mk_mac_str(&(*pp_src)->mac)) );
+ return status;
}
-
+
(*pp_src)->cm_flag = cm_capable;
CL_ASSERT( !memcmp(
@@ -3642,7 +3574,90 @@
return IB_SUCCESS;
}
+static ib_api_status_t
+__recv_icmpv6(
+ IN ipoib_port_t* const p_port,
+ IN ib_wc_t* const p_wc,
+ IN ipoib_pkt_t* const p_ipoib,
+ OUT eth_pkt_t* const p_eth,
+ IN ipoib_endpt_t** const pp_src,
+ IN ipoib_endpt_t* const p_dst )
+{
+ ib_api_status_t status;
+ ipv6_hdr_t *p_ipv6_hdr;
+ icmpv6_pkt_t *p_icmpv6_pkt;
+ icmpv6_option_t *p_icmpv6_opt;
+ IPOIB_ENTER( IPOIB_DBG_RECV );
+ if( !p_dst )
+ {
+ IPOIB_PRINT_EXIT( TRACE_LEVEL_ERROR, IPOIB_DBG_ERROR,
+ ("Unknown destination endpoint\n") );
+ return IB_INVALID_SETTING;
+ }
+
+ p_icmpv6_pkt = (icmpv6_pkt_t *) (&p_ipoib->type.ipv6.hdr + 1);
+
+ if(p_icmpv6_pkt->hdr.type != ICMPV6_MSG_TYPE_NBR_ADV &&
+ p_icmpv6_pkt->hdr.type != ICMPV6_MSG_TYPE_NBR_SOL)
+ {
+ goto recv_gen;
+ }
+
+ p_ipv6_hdr = &p_ipoib->type.ipv6.hdr;
+
+ if(CL_NTOH16(p_ipv6_hdr->payload_length) != sizeof(icmpv6_pkt_t) +
+ sizeof(icmpv6_option_t))
+ {
+ IPOIB_PRINT_EXIT( TRACE_LEVEL_ERROR, IPOIB_DBG_ERROR,
+ ("Malformed ICMPv6 neighbor discovery packet\n") );
+ return IB_INVALID_SETTING;
+ }
+
+ p_icmpv6_opt = (icmpv6_option_t *) (p_icmpv6_pkt + 1);
+
+ if(p_icmpv6_opt->option_type != ICMPV6_OPTION_SRC_LINK_ADDR &&
+ p_icmpv6_opt->option_type != ICMPV6_OPTION_TARGET_LINK_ADDR)
+ {
+ IPOIB_PRINT_EXIT( TRACE_LEVEL_ERROR, IPOIB_DBG_ERROR,
+ ("Invalid ICMPv6 option type\n") );
+ return IB_INVALID_SETTING;
+ }
+
+ if(p_icmpv6_opt->option_length != ICMPV6_IPOIB_LINK_ADDR_OPTION_LENGTH / 8)
+ {
+ IPOIB_PRINT_EXIT( TRACE_LEVEL_ERROR, IPOIB_DBG_ERROR,
+ ("Invalid ICMPv6 option length\n") );
+ return IB_INVALID_SETTING;
+ }
+
+ status = __endpt_update(p_port, pp_src, (ipoib_hw_addr_t *) p_icmpv6_opt->u.saddr.mac_addr, p_wc);
+
+ if(status != IB_SUCCESS)
+ {
+ return status;
+ }
+
+ p_ipv6_hdr->payload_length = cl_hton16(CL_NTOH16(p_ipv6_hdr->payload_length) +
+ ICMPV6_ETH_LINK_ADDR_OPTION_LENGTH - ICMPV6_IPOIB_LINK_ADDR_OPTION_LENGTH);
+ p_icmpv6_opt->option_length = ICMPV6_ETH_LINK_ADDR_OPTION_LENGTH / 8;
+ cl_memcpy(p_icmpv6_opt->u.saddr.mac_addr, &(*pp_src)->mac, sizeof(mac_addr_t));
+
+recv_gen:
+ status = __recv_gen( p_ipoib, p_eth, *pp_src, p_dst );
+
+ if( status != IB_SUCCESS )
+ {
+ IPOIB_PRINT_EXIT( TRACE_LEVEL_ERROR, IPOIB_DBG_ERROR,
+ ("__recv_gen returned %s.\n",
+ p_port->p_adapter->p_ifc->get_err_str( status )) );
+ return status;
+ }
+
+ IPOIB_EXIT( IPOIB_DBG_RECV );
+ return IB_SUCCESS;
+}
+
static ib_api_status_t
__recv_mgr_prepare_NBL(
IN ipoib_port_t* const p_port,
@@ -5193,15 +5208,24 @@
buf_len );
if( status != NDIS_STATUS_SUCCESS )
return status;
- break; // required if ICMP/ICMPV6 can go RC?
-
+ p_desc->send_dir = SEND_UD_QP;
+ break;
+
case IP_PROT_ICMP:
+ p_desc->send_dir = SEND_UD_QP;
+ break;
+
case IP_PROT_ICMPV6:
+ status = __send_mgr_filter_icmpv6( (ipv6_hdr_t*) p_ip_hdr,
+ p_mdl,
+ (buf_len - hdr_size), s_buf);
+
+ if( status != NDIS_STATUS_PENDING ) {
+ return status;
+ }
+ p_desc->send_dir = SEND_UD_QP;
break;
-
- case IPPROTO_HOPOPTS:
- break;
-
+
default:
break;
}
@@ -5256,6 +5280,100 @@
}
static NDIS_STATUS
+__send_mgr_filter_icmpv6(
+ IN const ipv6_hdr_t* const p_ipv6_hdr,
+ IN MDL* p_mdl,
+ IN size_t buf_len,
+ IN OUT ipoib_send_NB_SG* s_buf)
+{
+ icmpv6_pkt_t *p_icmpv6_orig_pkt;
+ icmpv6_pkt_t *p_icmpv6_new_pkt;
+
+ ipoib_send_desc_t *p_desc = s_buf->p_port->p_desc;
+
+ IPOIB_ENTER( IPOIB_DBG_SEND );
+ if( !buf_len )
+ {
+ NdisGetNextMdl( p_mdl, &p_mdl );
+ if( !p_mdl )
+ {
+ IPOIB_PRINT_EXIT( TRACE_LEVEL_ERROR, IPOIB_DBG_ERROR,
+ ("Failed to get DHCP buffer.\n") );
+ return NDIS_STATUS_FAILURE;
+ }
+ NdisQueryMdl( p_mdl, &p_icmpv6_orig_pkt, &buf_len, NormalPagePriority );
+ if( !p_icmpv6_orig_pkt )
+ {
+ IPOIB_PRINT_EXIT( TRACE_LEVEL_ERROR, IPOIB_DBG_ERROR,
+ ("Failed to query DHCP buffer.\n") );
+ return NDIS_STATUS_FAILURE;
+ }
+ }
+ else
+ {
+ p_icmpv6_orig_pkt = (icmpv6_pkt_t*)(p_ipv6_hdr + 1);
+ }
+
+ if( buf_len < sizeof(icmpv6_hdr_t) )
+ {
+ /* This buffer is done for. Get the next buffer. */
+ IPOIB_PRINT_EXIT( TRACE_LEVEL_ERROR, IPOIB_DBG_ERROR,
+ ("Buffer too small for ICMPv6 packet.\n") );
+ return NDIS_STATUS_BUFFER_TOO_SHORT;
+ }
+
+ if(p_icmpv6_orig_pkt->hdr.type != ICMPV6_MSG_TYPE_NBR_ADV &&
+ p_icmpv6_orig_pkt->hdr.type != ICMPV6_MSG_TYPE_NBR_SOL)
+ {
+ return NDIS_STATUS_PENDING;
+ }
+
+ /* Allocate our scratch buffer. */
+ ASSERT(s_buf->p_send_buf == NULL);
+ s_buf->p_send_buf = (send_buf_t*)
+ NdisAllocateFromNPagedLookasideList(
+ &s_buf->p_port->buf_mgr.send_buf_list );
+ if( !s_buf->p_send_buf )
+ {
+ IPOIB_PRINT_EXIT( TRACE_LEVEL_ERROR, IPOIB_DBG_ERROR,
+ ("Failed to query ARP packet buffer.\n") );
+ return NDIS_STATUS_RESOURCES;
+ }
+
+ ipv6_hdr_t *p_new_ipv6 = &s_buf->p_send_buf->ipv6.hdr;
+
+ cl_memcpy(p_new_ipv6, p_ipv6_hdr, sizeof(ipv6_hdr_t));
+
+ p_icmpv6_new_pkt = (icmpv6_pkt_t *) (p_new_ipv6 + 1);
+
+ cl_memcpy(p_icmpv6_new_pkt, p_icmpv6_orig_pkt, buf_len);
+
+ icmpv6_option_t *p_new_option = (icmpv6_option_t *) (p_icmpv6_new_pkt + 1);
+ p_new_option->option_type = (p_icmpv6_orig_pkt->hdr.type == ICMPV6_MSG_TYPE_NBR_SOL) ?
+ ICMPV6_OPTION_SRC_LINK_ADDR : ICMPV6_OPTION_TARGET_LINK_ADDR;
+ p_new_option->option_length = ICMPV6_IPOIB_LINK_ADDR_OPTION_LENGTH / 8;
+
+ ipoib_hw_addr_t* link_addr = (ipoib_hw_addr_t *) p_new_option->u.saddr.mac_addr;
+
+ ipoib_addr_set_qpn( link_addr, s_buf->p_port->ib_mgr.qpn );
+
+ ib_gid_set_default( &link_addr->gid,
+ s_buf->p_port->p_adapter->guids.port_guid.guid );
+
+ p_new_ipv6->payload_length = cl_hton16(sizeof(icmpv6_pkt_t) + sizeof(icmpv6_option_t));
+
+ p_desc->send_wr[0].local_ds[1].vaddr = cl_get_physaddr( s_buf->p_send_buf );
+ p_desc->send_wr[0].local_ds[1].length = sizeof(ipv6_hdr_t) + sizeof(icmpv6_pkt_t) + sizeof(icmpv6_option_t);
+ p_desc->send_wr[0].local_ds[1].lkey = s_buf->p_port->ib_mgr.lkey;
+ p_desc->send_wr[0].wr.num_ds = 2;
+ p_desc->send_wr[0].wr.p_next = NULL;
+ p_desc->send_dir = SEND_UD_QP;
+
+ IPOIB_EXIT( IPOIB_DBG_SEND );
+ return STATUS_SUCCESS;
+}
+
+static NDIS_STATUS
__send_mgr_filter_igmp_v2(
IN ipoib_port_t* const p_port,
IN const ip_hdr_t* const p_ip_hdr,
@@ -9289,6 +9407,118 @@
}
+static ib_api_status_t
+__endpt_update(
+ IN ipoib_port_t* const p_port,
+ IN ipoib_endpt_t** const pp_src,
+ IN const ipoib_hw_addr_t* p_new_hw_addr,
+ IN ib_wc_t* const p_wc
+)
+{
+ ib_api_status_t status = IB_ERROR;
+ ib_gid_t gid;
+ mac_addr_t mac;
+
+ /*
+ * If the endpoint exists for the GID, make sure
+ * the dlid and qpn match the arp.
+ */
+ if( *pp_src )
+ {
+ if( cl_memcmp( &(*pp_src)->dgid, &p_new_hw_addr->gid, sizeof(ib_gid_t) ) )
+ {
+ /*
+ * GIDs for the endpoint are different. The ARP must
+ * have been proxied. Dereference it.
+ */
+ *pp_src = NULL;
+ }
+ else if( (*pp_src)->dlid && (*pp_src)->dlid != p_wc->recv.ud.remote_lid )
+ {
+ /* Out of date! Destroy the endpoint and replace it. */
+ __endpt_mgr_remove( p_port, *pp_src );
+ *pp_src = NULL;
+ }
+ else if ( ! ((*pp_src)->dlid))
+ {
+ /* Out of date! Destroy the endpoint and replace it. */
+ __endpt_mgr_remove( p_port, *pp_src );
+ *pp_src = NULL;
+ }
+ else if( ipoib_is_voltaire_router_gid( &(*pp_src)->dgid ) )
+ {
+ if( (*pp_src)->qpn != ipoib_addr_get_qpn( p_new_hw_addr ) &&
+ p_wc->recv.ud.remote_qp != ipoib_addr_get_qpn( p_new_hw_addr ) )
+ {
+ /* Out of date! Destroy the endpoint and replace it. */
+ __endpt_mgr_remove( p_port, *pp_src );
+ *pp_src = NULL;
+ }
+ }
+ else if( (*pp_src)->qpn != p_wc->recv.ud.remote_qp )
+ {
+ /* Out of date! Destroy the endpoint and replace it. */
+ __endpt_mgr_remove( p_port, *pp_src );
+ *pp_src = NULL;
+ }
+ }
+
+ /* Do we need to create an endpoint for this GID? */
+ if( !*pp_src )
+ {
+ /* Copy the src GID to allow aligned access */
+ cl_memcpy( &gid, &p_new_hw_addr->gid, sizeof(ib_gid_t) );
+ status = ipoib_mac_from_guid( gid.unicast.interface_id,
+ p_port->p_adapter->params.guid_mask,
+ &mac );
+ if (status == IB_INVALID_GUID_MASK)
+ {
+ IPOIB_PRINT( TRACE_LEVEL_WARNING, IPOIB_DBG_ERROR,
+ ("Invalid GUID mask received, rejecting it") );
+ ipoib_create_log( p_port->p_adapter->h_adapter,
+ GUID_MASK_LOG_INDEX,
+ EVENT_IPOIB_WRONG_PARAMETER_WRN );
+ return status;
+ }
+ else if( status != IB_SUCCESS )
+ {
+ IPOIB_PRINT_EXIT( TRACE_LEVEL_ERROR, IPOIB_DBG_ERROR,
+ ("ipoib_mac_from_guid returned %s\n",
+ p_port->p_adapter->p_ifc->get_err_str( status )) );
+ return status;
+ }
+
+ /*
+ * Create the endpoint.
+ */
+ *pp_src = ipoib_endpt_create( &p_new_hw_addr->gid,
+ p_wc->recv.ud.remote_lid,
+ ipoib_addr_get_qpn( p_new_hw_addr ) );
+
+ if( !*pp_src )
+ {
+ IPOIB_PRINT_EXIT( TRACE_LEVEL_ERROR, IPOIB_DBG_ERROR,
+ ("ipoib_endpt_create failed\n") );
+ status = IB_INSUFFICIENT_MEMORY;
+ return status;
+ }
+
+ cl_obj_lock( &p_port->obj );
+ status = __endpt_mgr_insert( p_port, mac, *pp_src );
+ if( status != IB_SUCCESS )
+ {
+ cl_obj_unlock( &p_port->obj );
+ IPOIB_PRINT_EXIT( TRACE_LEVEL_ERROR, IPOIB_DBG_ERROR,
+ ("__endpt_mgr_insert return %s \n",
+ p_port->p_adapter->p_ifc->get_err_str( status )) );
+ return status;
+ }
+ cl_obj_unlock( &p_port->obj );
+ }
+
+ return IB_SUCCESS;
+}
+
/*
* Put all IP fragments into separate WRs and chain together.
* The last WR will be set to generate CQ Event.
Alexander (XaleX) Naslednikov
SW Networking Team
Mellanox Technologies
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.openfabrics.org/pipermail/ofw/attachments/20110127/23362358/attachment.html>
More information about the ofw
mailing list