ibcm_arp_link.c revision d3a82192edbbe93c6027629b50fd93fed5d0e1ab
/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License (the "License").
* You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
/*
* Copyright 2009 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
#include <sys/sysmacros.h>
#include <net/if_types.h>
#include <sys/ethernet.h>
#include <inet/ip_ftable.h>
static areq_t ibcm_arp_areq_template = {
AR_ENTRY_QUERY, /* cmd */
sizeof (areq_t), /* name len */
IP_ARP_PROTO_TYPE, /* protocol, from arps perspective */
sizeof (areq_t), /* target addr offset */
IP_ADDR_LEN, /* target ADDR_length */
0, /* flags */
IP_ADDR_LEN, /* sender addr length */
IBCM_ARP_XMIT_COUNT, /* xmit_count */
IBCM_ARP_XMIT_INTERVAL, /* (re)xmit_interval in milliseconds */
4 /* max # of requests to buffer */
/*
* anything else filled in by the code
*/
};
static area_t ibcm_arp_area_template = {
AR_ENTRY_ADD, /* cmd */
sizeof (area_t), /* name len */
IP_ARP_PROTO_TYPE, /* protocol, from arps perspective */
sizeof (area_t), /* proto addr offset */
IP_ADDR_LEN, /* proto ADDR_length */
0, /* flags */
IPOIB_ADDRL /* hw addr length */
};
extern char cmlog[];
static void ibcm_arp_timeout(void *arg);
static void ibcm_ipv6_resolver_ack(ip2mac_t *, void *);
/*
* issue a AR_ENTRY_QUERY to arp driver and schedule a timeout.
*/
static int
{
int len;
int name_len;
int name_offset;
char *cp;
/*
* allocate mblk for AR_ENTRY_QUERY
*/
return (ENOMEM);
}
/*
* allocate a mblk and set wqnp in the data
*/
return (ENOMEM);
}
/*
* issue the request to arp
*/
} else {
}
return (0);
}
/*
* issue AR_ENTRY_SQUERY to arp driver
*/
static int
{
int len;
int name_len;
char *cp;
/*
* allocate mblk for AR_ENTRY_SQUERY
*/
sizeof (uintptr_t);
return (ENOMEM);
}
return (ENOMEM);
}
} else {
}
return (0);
}
/*
* issue a AR_ENTRY_ADD to arp driver
* This is required as arp driver does not maintain a cache.
*/
static int
{
int len;
int name_len;
char *cp;
/*
* allocate mblk for AR_ENTRY_ADD
*/
return (ENOMEM);
}
} else {
}
return (0);
}
/*
* timeout routine when there is no response to AR_ENTRY_QUERY
*/
static void
ibcm_arp_timeout(void *arg)
{
/*
* indicate to user
*/
}
/*
* delete a wait queue node from the list.
* assumes mutex is acquired
*/
void
{
}
/*
* allocate a wait queue node, and insert it in the list
*/
static ibcm_arp_prwqn_t *
{
return (NULL);
}
NULL) {
return (NULL);
}
if (src_addr) {
}
return (wqnp);
}
/*
* call the user function
* called with lock held
*/
static void
{
}
/*
* Check if the interface is loopback or IB.
*/
static int
{
return (0);
return (ETIMEDOUT);
}
int
{
int len;
"ibcm_arp_create_prwqn failed");
return (1);
}
/*
* Get the ire for the local address
*/
"ire_ctable_lookup failed");
goto fail;
}
/*
* get an ire for the destination address with the matching
* source address
*/
"ire_ftable_lookup failed");
goto fail;
}
"done");
/*
* Get the ire for the local address
*/
"ire_ctable_lookup_v6 failed");
goto fail;
}
"ire_ctable_lookup_v6: done");
/*
* get an ire for the destination address with the matching
* source address
*/
"ire_ftable_lookup_v6 failed");
goto fail;
}
"ire_ftable_lookup_v6: done");
}
/*
* For IPMP data addresses, we need to use the hardware address of the
* interface bound to the given address.
*/
goto fail;
}
} else {
hwaddr_ill = ill;
}
"ibcm_arp_check_interface failed");
goto fail;
}
/*
* if the user supplied a address, then verify rts returned
* the same address
*/
IP_ADDR_LEN : sizeof (in6_addr_t);
"mismatch:%d", ENETUNREACH);
goto fail;
}
}
/*
* at this stage, we have the source address and the IB
* interface, now get the destination mac address from
* arp or ipv6 drivers
*/
goto fail;
}
} else {
0) {
goto fail;
}
}
return (0);
fail:
if (hwaddr_ill != NULL)
return (1);
}
/*
* called from lrsrv.
* process a AR_ENTRY_QUERY reply from arp
* the message should be M_DATA -->> dl_unitdata_req
*/
static void
{
char *cp;
int rc;
/*
* the first mblk contains the wqnp pointer for the request
*/
return;
}
/*
* cancel the timeout for this request
*/
/*
* sanity checks on the dl_unitdata_req block
*/
goto user_callback;
}
"dl_unitdatareq_t block\n");
goto user_callback;
}
"in dl_unitdatareq_t block\n");
goto user_callback;
}
goto user_callback;
}
/*
* now get the hca, port
*/
(void) ibcm_arp_add(wqnp);
ibcm_arp_pr_callback(wqnp, 0);
return;
/*
* indicate to user
*/
}
/*
* process a AR_ENTRY_SQUERY reply from arp
* the message should be M_IOCACK -->> area_t
*/
static void
{
char *cp;
return;
}
return;
}
sizeof (uintptr_t));
/*
* cancel the timeout for this request
*/
/* If the entry was not in arp cache, ioc_error is set */
/*
* send out AR_ENTRY_QUERY which would send
* arp-request on wire
*/
(void) ibcm_arp_query_arp(wqnp);
return;
}
/*
* now get the hca, port
*/
ibcm_arp_pr_callback(wqnp, 0);
}
/*
* Process arp ack's.
*/
void
{
} else {
}
}
/*
* query the ipv6 driver cache for ipv6 to mac address mapping.
*/
static int
{
int err;
return (1);
}
/*
* XXX XTBD set the scopeid?
* issue the request to IP for Neighbor Discovery
*/
zoneid);
if (err == EINPROGRESS) {
err = 0;
} else if (err == 0) {
}
return (err);
}
/*
* do sanity checks on the link-level sockaddr
*/
static boolean_t
{
return (B_FALSE);
return (B_TRUE);
}
/*
* callback for resolver lookups, both for success and failure.
* If Address resolution was succesful: return GID info.
*/
static void
{
int err = 0;
/*
* cancel the timeout for this request
*/
if (ip2macp->ip2mac_err != 0) {
err = EHOSTUNREACH;
goto user_callback;
}
err = EHOSTUNREACH;
goto user_callback;
}
/*
* now get the hca, port
*/
}