14703Shiremath /*
24703Shiremath * CDDL HEADER START
34703Shiremath *
44703Shiremath * The contents of this file are subject to the terms of the
54703Shiremath * Common Development and Distribution License (the "License").
64703Shiremath * You may not use this file except in compliance with the License.
74703Shiremath *
84703Shiremath * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
94703Shiremath * or http://www.opensolaris.org/os/licensing.
104703Shiremath * See the License for the specific language governing permissions
114703Shiremath * and limitations under the License.
124703Shiremath *
134703Shiremath * When distributing Covered Code, include this CDDL HEADER in each
144703Shiremath * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
154703Shiremath * If applicable, add the following below this CDDL HEADER, with the
164703Shiremath * fields enclosed by brackets "[]" replaced with your own identifying
174703Shiremath * information: Portions Copyright [yyyy] [name of copyright owner]
184703Shiremath *
194703Shiremath * CDDL HEADER END
204703Shiremath */
214703Shiremath /*
2212163SRamaswamy.Tummala@Sun.COM * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
234703Shiremath */
244703Shiremath
254703Shiremath #include <sys/types.h>
264703Shiremath #include <sys/ddi.h>
274703Shiremath #include <sys/sunddi.h>
284703Shiremath #include <sys/strsubr.h>
294703Shiremath #include <sys/socket.h>
304703Shiremath #include <net/if_arp.h>
318485SPeter.Memishian@Sun.COM #include <net/if_types.h>
324703Shiremath #include <sys/sockio.h>
334703Shiremath #include <sys/pathname.h>
344703Shiremath
354703Shiremath #include <sys/ib/mgt/ibcm/ibcm_arp.h>
364703Shiremath
374703Shiremath #include <sys/kstr.h>
384703Shiremath #include <sys/t_kuser.h>
394703Shiremath
4012163SRamaswamy.Tummala@Sun.COM #include <sys/dls.h>
4112163SRamaswamy.Tummala@Sun.COM
424703Shiremath extern char cmlog[];
434703Shiremath
4411042SErik.Nordmark@Sun.COM extern int ibcm_resolver_pr_lookup(ibcm_arp_streams_t *ib_s,
4511951SShantkumar.Hiremath@Sun.COM ibt_ip_addr_t *dst_addr, ibt_ip_addr_t *src_addr, zoneid_t myzoneid);
4611042SErik.Nordmark@Sun.COM extern void ibcm_arp_delete_prwqn(ibcm_arp_prwqn_t *wqnp);
474703Shiremath
484703Shiremath _NOTE(SCHEME_PROTECTS_DATA("Unshared data", ibt_ip_addr_s))
494703Shiremath _NOTE(SCHEME_PROTECTS_DATA("Unshared data", ibcm_arp_ip_t))
504703Shiremath _NOTE(SCHEME_PROTECTS_DATA("Unshared data", ibcm_arp_ibd_insts_t))
514703Shiremath _NOTE(SCHEME_PROTECTS_DATA("Unshared data", ibcm_arp_prwqn_t))
524703Shiremath _NOTE(SCHEME_PROTECTS_DATA("Unshared data", sockaddr_in))
534703Shiremath _NOTE(SCHEME_PROTECTS_DATA("Unshared data", sockaddr_in6))
544703Shiremath
559349SShantkumar.Hiremath@Sun.COM int ibcm_printip = 0;
569349SShantkumar.Hiremath@Sun.COM
579349SShantkumar.Hiremath@Sun.COM /*
589349SShantkumar.Hiremath@Sun.COM * Function:
599349SShantkumar.Hiremath@Sun.COM * ibcm_ip_print
609349SShantkumar.Hiremath@Sun.COM * Input:
619349SShantkumar.Hiremath@Sun.COM * label Arbitrary qualifying string
629349SShantkumar.Hiremath@Sun.COM * ipa Pointer to IP Address to print
639349SShantkumar.Hiremath@Sun.COM */
649349SShantkumar.Hiremath@Sun.COM void
ibcm_ip_print(char * label,ibt_ip_addr_t * ipaddr)659349SShantkumar.Hiremath@Sun.COM ibcm_ip_print(char *label, ibt_ip_addr_t *ipaddr)
669349SShantkumar.Hiremath@Sun.COM {
679349SShantkumar.Hiremath@Sun.COM char buf[INET6_ADDRSTRLEN];
689349SShantkumar.Hiremath@Sun.COM
699349SShantkumar.Hiremath@Sun.COM if (ipaddr->family == AF_INET) {
709349SShantkumar.Hiremath@Sun.COM IBTF_DPRINTF_L2(cmlog, "%s: %s", label,
719349SShantkumar.Hiremath@Sun.COM inet_ntop(AF_INET, &ipaddr->un.ip4addr, buf, sizeof (buf)));
729349SShantkumar.Hiremath@Sun.COM } else if (ipaddr->family == AF_INET6) {
739349SShantkumar.Hiremath@Sun.COM IBTF_DPRINTF_L2(cmlog, "%s: %s", label, inet_ntop(AF_INET6,
749349SShantkumar.Hiremath@Sun.COM &ipaddr->un.ip6addr, buf, sizeof (buf)));
759349SShantkumar.Hiremath@Sun.COM } else {
769349SShantkumar.Hiremath@Sun.COM IBTF_DPRINTF_L2(cmlog, "%s: IP ADDR NOT SPECIFIED ", label);
779349SShantkumar.Hiremath@Sun.COM }
789349SShantkumar.Hiremath@Sun.COM }
799349SShantkumar.Hiremath@Sun.COM
804703Shiremath
814703Shiremath ibt_status_t
ibcm_arp_get_ibaddr(zoneid_t myzoneid,ibt_ip_addr_t srcaddr,ibt_ip_addr_t destaddr,ib_gid_t * sgid,ib_gid_t * dgid,ibt_ip_addr_t * saddrp)8211951SShantkumar.Hiremath@Sun.COM ibcm_arp_get_ibaddr(zoneid_t myzoneid, ibt_ip_addr_t srcaddr,
8311951SShantkumar.Hiremath@Sun.COM ibt_ip_addr_t destaddr, ib_gid_t *sgid, ib_gid_t *dgid,
8411951SShantkumar.Hiremath@Sun.COM ibt_ip_addr_t *saddrp)
854703Shiremath {
864703Shiremath ibcm_arp_streams_t *ib_s;
8710174SShantkumar.Hiremath@Sun.COM ibcm_arp_prwqn_t *wqnp;
885752Shiremath int ret = 0;
8911951SShantkumar.Hiremath@Sun.COM int len;
904703Shiremath
9111951SShantkumar.Hiremath@Sun.COM IBTF_DPRINTF_L4(cmlog, "ibcm_arp_get_ibaddr(%d, %p, %p, %p, %p, %p)",
9211951SShantkumar.Hiremath@Sun.COM myzoneid, srcaddr, destaddr, sgid, dgid, saddrp);
934703Shiremath
944703Shiremath ib_s = (ibcm_arp_streams_t *)kmem_zalloc(sizeof (ibcm_arp_streams_t),
954703Shiremath KM_SLEEP);
964703Shiremath
974703Shiremath mutex_init(&ib_s->lock, NULL, MUTEX_DEFAULT, NULL);
984703Shiremath cv_init(&ib_s->cv, NULL, CV_DRIVER, NULL);
994703Shiremath
1005752Shiremath mutex_enter(&ib_s->lock);
1015752Shiremath ib_s->done = B_FALSE;
1025752Shiremath mutex_exit(&ib_s->lock);
1035752Shiremath
10411951SShantkumar.Hiremath@Sun.COM ret = ibcm_resolver_pr_lookup(ib_s, &destaddr, &srcaddr, myzoneid);
1054703Shiremath
10611042SErik.Nordmark@Sun.COM IBTF_DPRINTF_L3(cmlog, "ibcm_arp_get_ibaddr: ibcm_resolver_pr_lookup "
1074703Shiremath "returned: %d", ret);
1084703Shiremath if (ret == 0) {
1094703Shiremath mutex_enter(&ib_s->lock);
1105752Shiremath while (ib_s->done != B_TRUE)
1115752Shiremath cv_wait(&ib_s->cv, &ib_s->lock);
1124703Shiremath mutex_exit(&ib_s->lock);
1134703Shiremath }
1144703Shiremath
1155752Shiremath mutex_enter(&ib_s->lock);
11610174SShantkumar.Hiremath@Sun.COM wqnp = ib_s->wqnp;
11710174SShantkumar.Hiremath@Sun.COM if (ib_s->status == 0) {
1184703Shiremath if (sgid)
11911951SShantkumar.Hiremath@Sun.COM *sgid = wqnp->sgid;
1204703Shiremath if (dgid)
12111951SShantkumar.Hiremath@Sun.COM *dgid = wqnp->dgid;
12211951SShantkumar.Hiremath@Sun.COM /*
12311951SShantkumar.Hiremath@Sun.COM * If the user supplied a address, then verify we got
12411951SShantkumar.Hiremath@Sun.COM * for the same address.
12511951SShantkumar.Hiremath@Sun.COM */
12611951SShantkumar.Hiremath@Sun.COM if (wqnp->usrc_addr.family && sgid) {
12711951SShantkumar.Hiremath@Sun.COM len = (wqnp->usrc_addr.family == AF_INET) ?
12811951SShantkumar.Hiremath@Sun.COM IP_ADDR_LEN : sizeof (in6_addr_t);
12911951SShantkumar.Hiremath@Sun.COM if (bcmp(&wqnp->usrc_addr.un,
13011951SShantkumar.Hiremath@Sun.COM &wqnp->src_addr.un, len)) {
13111951SShantkumar.Hiremath@Sun.COM IBTF_DPRINTF_L3(cmlog, "ibcm_arp_get_ibaddr: "
13211951SShantkumar.Hiremath@Sun.COM "srcaddr mismatch");
13311951SShantkumar.Hiremath@Sun.COM
13411951SShantkumar.Hiremath@Sun.COM /* Clean-up old data, and reset the done flag */
13511951SShantkumar.Hiremath@Sun.COM ibcm_arp_delete_prwqn(wqnp);
13611951SShantkumar.Hiremath@Sun.COM ib_s->done = B_FALSE;
13711951SShantkumar.Hiremath@Sun.COM mutex_exit(&ib_s->lock);
13811951SShantkumar.Hiremath@Sun.COM
13911951SShantkumar.Hiremath@Sun.COM ret = ibcm_resolver_pr_lookup(ib_s, &srcaddr,
14011951SShantkumar.Hiremath@Sun.COM &srcaddr, myzoneid);
14111951SShantkumar.Hiremath@Sun.COM if (ret == 0) {
14211951SShantkumar.Hiremath@Sun.COM mutex_enter(&ib_s->lock);
14311951SShantkumar.Hiremath@Sun.COM while (ib_s->done != B_TRUE)
14411951SShantkumar.Hiremath@Sun.COM cv_wait(&ib_s->cv, &ib_s->lock);
14511951SShantkumar.Hiremath@Sun.COM mutex_exit(&ib_s->lock);
14611951SShantkumar.Hiremath@Sun.COM }
14711951SShantkumar.Hiremath@Sun.COM mutex_enter(&ib_s->lock);
14811951SShantkumar.Hiremath@Sun.COM wqnp = ib_s->wqnp;
14911951SShantkumar.Hiremath@Sun.COM if (ib_s->status == 0) {
15011951SShantkumar.Hiremath@Sun.COM if (sgid)
15111951SShantkumar.Hiremath@Sun.COM *sgid = wqnp->dgid;
15211951SShantkumar.Hiremath@Sun.COM
15311951SShantkumar.Hiremath@Sun.COM if (saddrp)
15411951SShantkumar.Hiremath@Sun.COM bcopy(&wqnp->src_addr, saddrp,
15511951SShantkumar.Hiremath@Sun.COM sizeof (ibt_ip_addr_t));
15611951SShantkumar.Hiremath@Sun.COM
15711951SShantkumar.Hiremath@Sun.COM IBTF_DPRINTF_L4(cmlog,
15811951SShantkumar.Hiremath@Sun.COM "ibcm_arp_get_ibaddr: "
15911951SShantkumar.Hiremath@Sun.COM "SGID: %llX:%llX DGID: %llX:%llX",
16011951SShantkumar.Hiremath@Sun.COM sgid->gid_prefix, sgid->gid_guid,
16111951SShantkumar.Hiremath@Sun.COM dgid->gid_prefix, dgid->gid_guid);
16211951SShantkumar.Hiremath@Sun.COM
16311951SShantkumar.Hiremath@Sun.COM ibcm_arp_delete_prwqn(wqnp);
16411951SShantkumar.Hiremath@Sun.COM } else if (ret == 0) {
16511951SShantkumar.Hiremath@Sun.COM if (wqnp)
16611951SShantkumar.Hiremath@Sun.COM kmem_free(wqnp,
16711951SShantkumar.Hiremath@Sun.COM sizeof (ibcm_arp_prwqn_t));
16811951SShantkumar.Hiremath@Sun.COM }
16911951SShantkumar.Hiremath@Sun.COM goto arp_ibaddr_done;
17011951SShantkumar.Hiremath@Sun.COM }
17111951SShantkumar.Hiremath@Sun.COM }
17211951SShantkumar.Hiremath@Sun.COM
17311951SShantkumar.Hiremath@Sun.COM if (saddrp)
17411951SShantkumar.Hiremath@Sun.COM bcopy(&wqnp->src_addr, saddrp, sizeof (ibt_ip_addr_t));
1754703Shiremath
1764703Shiremath IBTF_DPRINTF_L4(cmlog, "ibcm_arp_get_ibaddr: SGID: %llX:%llX"
17711951SShantkumar.Hiremath@Sun.COM " DGID: %llX:%llX", sgid->gid_prefix, sgid->gid_guid,
17811951SShantkumar.Hiremath@Sun.COM dgid->gid_prefix, dgid->gid_guid);
1794703Shiremath
18011042SErik.Nordmark@Sun.COM ibcm_arp_delete_prwqn(wqnp);
18110174SShantkumar.Hiremath@Sun.COM } else if (ret == 0) {
18210174SShantkumar.Hiremath@Sun.COM /*
18310174SShantkumar.Hiremath@Sun.COM * We come here only when lookup has returned empty (failed)
18411042SErik.Nordmark@Sun.COM * via callback routine.
18510174SShantkumar.Hiremath@Sun.COM * i.e. ib_s->status is non-zero, while ret is zero.
18610174SShantkumar.Hiremath@Sun.COM */
18710174SShantkumar.Hiremath@Sun.COM if (wqnp)
18810174SShantkumar.Hiremath@Sun.COM kmem_free(wqnp, sizeof (ibcm_arp_prwqn_t));
1894703Shiremath }
19011951SShantkumar.Hiremath@Sun.COM arp_ibaddr_done:
19110174SShantkumar.Hiremath@Sun.COM ret = ib_s->status;
1925752Shiremath mutex_exit(&ib_s->lock);
1935752Shiremath
1945752Shiremath arp_ibaddr_error:
1954703Shiremath
1964703Shiremath mutex_destroy(&ib_s->lock);
1974703Shiremath cv_destroy(&ib_s->cv);
1984703Shiremath kmem_free(ib_s, sizeof (ibcm_arp_streams_t));
1994703Shiremath
2004703Shiremath if (ret)
2014703Shiremath return (IBT_FAILURE);
2024703Shiremath else
2034703Shiremath return (IBT_SUCCESS);
2044703Shiremath }
2054703Shiremath
20612163SRamaswamy.Tummala@Sun.COM void
ibcm_arp_free_ibds(ibcm_arp_ibd_insts_t * ibds)20712163SRamaswamy.Tummala@Sun.COM ibcm_arp_free_ibds(ibcm_arp_ibd_insts_t *ibds)
2084703Shiremath {
20912163SRamaswamy.Tummala@Sun.COM if (ibds->ibcm_arp_ip) {
21012163SRamaswamy.Tummala@Sun.COM kmem_free(ibds->ibcm_arp_ip, ibds->ibcm_arp_ibd_alloc *
21112163SRamaswamy.Tummala@Sun.COM sizeof (ibcm_arp_ip_t));
21212163SRamaswamy.Tummala@Sun.COM ibds->ibcm_arp_ibd_alloc = 0;
21312163SRamaswamy.Tummala@Sun.COM ibds->ibcm_arp_ibd_cnt = 0;
21412163SRamaswamy.Tummala@Sun.COM ibds->ibcm_arp_ip = NULL;
2154703Shiremath }
2164703Shiremath }
2174703Shiremath
2184703Shiremath static void
ibcm_arp_get_ibd_insts(ibcm_arp_ibd_insts_t * ibds)2194703Shiremath ibcm_arp_get_ibd_insts(ibcm_arp_ibd_insts_t *ibds)
2204703Shiremath {
22112163SRamaswamy.Tummala@Sun.COM ibcm_arp_ip_t *ipp;
22212163SRamaswamy.Tummala@Sun.COM ib_gid_t port_gid;
22312163SRamaswamy.Tummala@Sun.COM ibt_part_attr_t *attr_list, *attr;
22412163SRamaswamy.Tummala@Sun.COM int nparts;
22512163SRamaswamy.Tummala@Sun.COM
22612163SRamaswamy.Tummala@Sun.COM if ((ibt_get_all_part_attr(&attr_list, &nparts) != IBT_SUCCESS) ||
22712163SRamaswamy.Tummala@Sun.COM (nparts == 0)) {
228*12965SWilliam.Taylor@Oracle.COM IBTF_DPRINTF_L2(cmlog, "ibcm_arp_get_ibd_insts: Failed to "
229*12965SWilliam.Taylor@Oracle.COM "IB Part List - %d", nparts);
23012163SRamaswamy.Tummala@Sun.COM ibds->ibcm_arp_ibd_alloc = 0;
23112163SRamaswamy.Tummala@Sun.COM ibds->ibcm_arp_ibd_cnt = 0;
23212163SRamaswamy.Tummala@Sun.COM ibds->ibcm_arp_ip = NULL;
23312163SRamaswamy.Tummala@Sun.COM return;
23412163SRamaswamy.Tummala@Sun.COM }
235*12965SWilliam.Taylor@Oracle.COM IBTF_DPRINTF_L4(cmlog, "ibcm_arp_get_ibd_insts: Found %d IB Part List",
236*12965SWilliam.Taylor@Oracle.COM nparts);
23712163SRamaswamy.Tummala@Sun.COM
23812163SRamaswamy.Tummala@Sun.COM ibds->ibcm_arp_ibd_alloc = nparts;
23912163SRamaswamy.Tummala@Sun.COM ibds->ibcm_arp_ibd_cnt = 0;
24012163SRamaswamy.Tummala@Sun.COM ibds->ibcm_arp_ip = (ibcm_arp_ip_t *)kmem_zalloc(
24112163SRamaswamy.Tummala@Sun.COM nparts * sizeof (ibcm_arp_ip_t), KM_SLEEP);
24212163SRamaswamy.Tummala@Sun.COM
24312163SRamaswamy.Tummala@Sun.COM attr = attr_list;
24412163SRamaswamy.Tummala@Sun.COM while (nparts--) {
24512163SRamaswamy.Tummala@Sun.COM if (ibt_get_port_state_byguid(attr->pa_hca_guid,
24612163SRamaswamy.Tummala@Sun.COM attr->pa_port, &port_gid, NULL) == IBT_SUCCESS) {
24712163SRamaswamy.Tummala@Sun.COM
24812163SRamaswamy.Tummala@Sun.COM ipp = &ibds->ibcm_arp_ip[ibds->ibcm_arp_ibd_cnt];
24912163SRamaswamy.Tummala@Sun.COM ipp->ip_linkid = attr->pa_plinkid;
25012163SRamaswamy.Tummala@Sun.COM ipp->ip_pkey = attr->pa_pkey;
25112163SRamaswamy.Tummala@Sun.COM ipp->ip_hca_guid = attr->pa_hca_guid;
25212163SRamaswamy.Tummala@Sun.COM ipp->ip_port_gid = port_gid;
25312163SRamaswamy.Tummala@Sun.COM ibds->ibcm_arp_ibd_cnt++;
254*12965SWilliam.Taylor@Oracle.COM
255*12965SWilliam.Taylor@Oracle.COM IBTF_DPRINTF_L4(cmlog, "PartAttr: p-linkid %lX, "
256*12965SWilliam.Taylor@Oracle.COM "d-linkid %lX, pkey 0x%lX", ipp->ip_linkid,
257*12965SWilliam.Taylor@Oracle.COM attr->pa_dlinkid, ipp->ip_pkey);
258*12965SWilliam.Taylor@Oracle.COM IBTF_DPRINTF_L4(cmlog, "hca_guid 0x%llX, "
259*12965SWilliam.Taylor@Oracle.COM "port_gid %llX \n attr-port_guid %llX",
260*12965SWilliam.Taylor@Oracle.COM ipp->ip_hca_guid, ipp->ip_port_gid.gid_guid,
261*12965SWilliam.Taylor@Oracle.COM attr->pa_port_guid);
26212163SRamaswamy.Tummala@Sun.COM }
26312163SRamaswamy.Tummala@Sun.COM attr++;
26412163SRamaswamy.Tummala@Sun.COM }
26512163SRamaswamy.Tummala@Sun.COM
26612163SRamaswamy.Tummala@Sun.COM (void) ibt_free_part_attr(attr_list, ibds->ibcm_arp_ibd_alloc);
2674703Shiremath }
2684703Shiremath
2694703Shiremath /*
2708485SPeter.Memishian@Sun.COM * Issue an ioctl down to IP. There are several similar versions of this
2718485SPeter.Memishian@Sun.COM * function (e.g., rpcib_do_ip_ioctl()); clearly a utility routine is needed.
2728485SPeter.Memishian@Sun.COM */
2738485SPeter.Memishian@Sun.COM static int
ibcm_do_ip_ioctl(int cmd,int len,void * arg)2748485SPeter.Memishian@Sun.COM ibcm_do_ip_ioctl(int cmd, int len, void *arg)
2758485SPeter.Memishian@Sun.COM {
27611185SSean.McEnroe@Sun.COM vnode_t *kkvp;
2778485SPeter.Memishian@Sun.COM TIUSER *tiptr;
2788485SPeter.Memishian@Sun.COM struct strioctl iocb;
2798485SPeter.Memishian@Sun.COM int err = 0;
2808485SPeter.Memishian@Sun.COM
28111185SSean.McEnroe@Sun.COM if (lookupname("/dev/udp", UIO_SYSSPACE, FOLLOW, NULLVPP, &kkvp) != 0)
2828485SPeter.Memishian@Sun.COM return (EPROTO);
2838485SPeter.Memishian@Sun.COM
28411185SSean.McEnroe@Sun.COM if (t_kopen(NULL, kkvp->v_rdev, FREAD|FWRITE, &tiptr, CRED()) != 0) {
28511185SSean.McEnroe@Sun.COM VN_RELE(kkvp);
2868485SPeter.Memishian@Sun.COM return (EPROTO);
2878485SPeter.Memishian@Sun.COM }
2888485SPeter.Memishian@Sun.COM
2898485SPeter.Memishian@Sun.COM iocb.ic_cmd = cmd;
2908485SPeter.Memishian@Sun.COM iocb.ic_timout = 0;
2918485SPeter.Memishian@Sun.COM iocb.ic_len = len;
2928485SPeter.Memishian@Sun.COM iocb.ic_dp = (caddr_t)arg;
2938485SPeter.Memishian@Sun.COM err = kstr_ioctl(tiptr->fp->f_vnode, I_STR, (intptr_t)&iocb);
2948485SPeter.Memishian@Sun.COM (void) t_kclose(tiptr, 0);
29511185SSean.McEnroe@Sun.COM VN_RELE(kkvp);
2968485SPeter.Memishian@Sun.COM return (err);
2978485SPeter.Memishian@Sun.COM }
2988485SPeter.Memishian@Sun.COM
2998485SPeter.Memishian@Sun.COM /*
3008485SPeter.Memishian@Sun.COM * Issue an SIOCGLIFCONF down to IP and return the result in `lifcp'.
3018485SPeter.Memishian@Sun.COM * lifcp->lifc_buf is dynamically allocated to be *bufsizep bytes.
3024703Shiremath */
3034703Shiremath static int
ibcm_do_lifconf(struct lifconf * lifcp,uint_t * bufsizep,sa_family_t family_loc)3049349SShantkumar.Hiremath@Sun.COM ibcm_do_lifconf(struct lifconf *lifcp, uint_t *bufsizep, sa_family_t family_loc)
3058485SPeter.Memishian@Sun.COM {
3068485SPeter.Memishian@Sun.COM int err;
3078485SPeter.Memishian@Sun.COM struct lifnum lifn;
3088485SPeter.Memishian@Sun.COM
3098485SPeter.Memishian@Sun.COM bzero(&lifn, sizeof (struct lifnum));
3109349SShantkumar.Hiremath@Sun.COM lifn.lifn_family = family_loc;
311*12965SWilliam.Taylor@Oracle.COM lifn.lifn_flags = LIFC_NOXMIT | LIFC_TEMPORARY | LIFC_ALLZONES;
3128485SPeter.Memishian@Sun.COM
3138485SPeter.Memishian@Sun.COM err = ibcm_do_ip_ioctl(SIOCGLIFNUM, sizeof (struct lifnum), &lifn);
3148485SPeter.Memishian@Sun.COM if (err != 0)
3158485SPeter.Memishian@Sun.COM return (err);
3168485SPeter.Memishian@Sun.COM
317*12965SWilliam.Taylor@Oracle.COM IBTF_DPRINTF_L3(cmlog, "ibcm_do_lifconf: Family %d, lifn_count %d",
3189349SShantkumar.Hiremath@Sun.COM family_loc, lifn.lifn_count);
3198485SPeter.Memishian@Sun.COM /*
3208485SPeter.Memishian@Sun.COM * Pad the interface count to account for additional interfaces that
3218485SPeter.Memishian@Sun.COM * may have been configured between the SIOCGLIFNUM and SIOCGLIFCONF.
3228485SPeter.Memishian@Sun.COM */
3238485SPeter.Memishian@Sun.COM lifn.lifn_count += 4;
3248485SPeter.Memishian@Sun.COM
3258485SPeter.Memishian@Sun.COM bzero(lifcp, sizeof (struct lifconf));
3268580SBill.Taylor@Sun.COM _NOTE(NOW_INVISIBLE_TO_OTHER_THREADS(*lifcp))
3279349SShantkumar.Hiremath@Sun.COM lifcp->lifc_family = family_loc;
3288485SPeter.Memishian@Sun.COM lifcp->lifc_len = *bufsizep = lifn.lifn_count * sizeof (struct lifreq);
3298485SPeter.Memishian@Sun.COM lifcp->lifc_buf = kmem_zalloc(*bufsizep, KM_SLEEP);
330*12965SWilliam.Taylor@Oracle.COM lifcp->lifc_flags = LIFC_NOXMIT | LIFC_TEMPORARY | LIFC_ALLZONES;
3318485SPeter.Memishian@Sun.COM
3328485SPeter.Memishian@Sun.COM err = ibcm_do_ip_ioctl(SIOCGLIFCONF, sizeof (struct lifconf), lifcp);
3338485SPeter.Memishian@Sun.COM if (err != 0) {
3348485SPeter.Memishian@Sun.COM kmem_free(lifcp->lifc_buf, *bufsizep);
3358485SPeter.Memishian@Sun.COM return (err);
3368485SPeter.Memishian@Sun.COM }
3378485SPeter.Memishian@Sun.COM return (0);
3388485SPeter.Memishian@Sun.COM }
3398485SPeter.Memishian@Sun.COM
34012163SRamaswamy.Tummala@Sun.COM static ibcm_arp_ip_t *
ibcm_arp_lookup(ibcm_arp_ibd_insts_t * ibds,char * linkname)34112163SRamaswamy.Tummala@Sun.COM ibcm_arp_lookup(ibcm_arp_ibd_insts_t *ibds, char *linkname)
34212163SRamaswamy.Tummala@Sun.COM {
34312163SRamaswamy.Tummala@Sun.COM datalink_id_t linkid;
34412163SRamaswamy.Tummala@Sun.COM int i;
34512163SRamaswamy.Tummala@Sun.COM
346*12965SWilliam.Taylor@Oracle.COM IBTF_DPRINTF_L4(cmlog, "ibcm_arp_lookup: linkname = %s", linkname);
34712163SRamaswamy.Tummala@Sun.COM
34812163SRamaswamy.Tummala@Sun.COM /*
34912163SRamaswamy.Tummala@Sun.COM * If at first we don't succeed, try again, just in case it is in
35012163SRamaswamy.Tummala@Sun.COM * hiding. The first call requires the datalink management daemon
35112163SRamaswamy.Tummala@Sun.COM * (the authorative source of information about name to id mapping)
35212163SRamaswamy.Tummala@Sun.COM * to be present and answering upcalls, the second does not.
35312163SRamaswamy.Tummala@Sun.COM */
35412163SRamaswamy.Tummala@Sun.COM if (dls_mgmt_get_linkid(linkname, &linkid) != 0) {
35512163SRamaswamy.Tummala@Sun.COM if (dls_devnet_macname2linkid(linkname, &linkid) != 0) {
356*12965SWilliam.Taylor@Oracle.COM IBTF_DPRINTF_L2(cmlog, "ibcm_arp_lookup: could not "
357*12965SWilliam.Taylor@Oracle.COM "get linkid from linkname (%s)", linkname);
35812163SRamaswamy.Tummala@Sun.COM return (NULL);
35912163SRamaswamy.Tummala@Sun.COM }
36012163SRamaswamy.Tummala@Sun.COM }
36112163SRamaswamy.Tummala@Sun.COM
36212163SRamaswamy.Tummala@Sun.COM for (i = 0; i < ibds->ibcm_arp_ibd_cnt; i++) {
36312163SRamaswamy.Tummala@Sun.COM if (ibds->ibcm_arp_ip[i].ip_linkid == linkid)
36412163SRamaswamy.Tummala@Sun.COM return (&ibds->ibcm_arp_ip[i]);
36512163SRamaswamy.Tummala@Sun.COM }
36612163SRamaswamy.Tummala@Sun.COM
367*12965SWilliam.Taylor@Oracle.COM IBTF_DPRINTF_L2(cmlog, "ibcm_arp_lookup: returning NULL for "
368*12965SWilliam.Taylor@Oracle.COM "linkname (%s)", linkname);
36912163SRamaswamy.Tummala@Sun.COM return (NULL);
37012163SRamaswamy.Tummala@Sun.COM }
37112163SRamaswamy.Tummala@Sun.COM
3728485SPeter.Memishian@Sun.COM /*
3738485SPeter.Memishian@Sun.COM * Fill in `ibds' with IP addresses tied to IFT_IB IP interfaces. Returns
3748485SPeter.Memishian@Sun.COM * B_TRUE if at least one address was filled in.
3758485SPeter.Memishian@Sun.COM */
3768485SPeter.Memishian@Sun.COM static boolean_t
ibcm_arp_get_ibd_ipaddr(ibcm_arp_ibd_insts_t * ibds,sa_family_t family_loc)3779349SShantkumar.Hiremath@Sun.COM ibcm_arp_get_ibd_ipaddr(ibcm_arp_ibd_insts_t *ibds, sa_family_t family_loc)
3784703Shiremath {
3798485SPeter.Memishian@Sun.COM int i, nifs, naddr = 0;
3808485SPeter.Memishian@Sun.COM uint_t bufsize;
3818485SPeter.Memishian@Sun.COM struct lifconf lifc;
382*12965SWilliam.Taylor@Oracle.COM struct lifreq *lifrp, lifr_copy;
3838485SPeter.Memishian@Sun.COM ibcm_arp_ip_t *ipp;
384*12965SWilliam.Taylor@Oracle.COM lifgroupinfo_t lifgr;
385*12965SWilliam.Taylor@Oracle.COM int err;
386*12965SWilliam.Taylor@Oracle.COM char ifname[LIFNAMSIZ + 1];
387*12965SWilliam.Taylor@Oracle.COM uint64_t ifflags = 0;
388*12965SWilliam.Taylor@Oracle.COM zoneid_t ifzoneid;
3898485SPeter.Memishian@Sun.COM
3909349SShantkumar.Hiremath@Sun.COM if (ibcm_do_lifconf(&lifc, &bufsize, family_loc) != 0)
3918485SPeter.Memishian@Sun.COM return (B_FALSE);
3928485SPeter.Memishian@Sun.COM
3938485SPeter.Memishian@Sun.COM nifs = lifc.lifc_len / sizeof (struct lifreq);
3949349SShantkumar.Hiremath@Sun.COM
3959349SShantkumar.Hiremath@Sun.COM IBTF_DPRINTF_L4(cmlog, "ibcm_arp_get_ibd_ipaddr: Family %d, nifs %d",
3969349SShantkumar.Hiremath@Sun.COM family_loc, nifs);
3979349SShantkumar.Hiremath@Sun.COM
39812163SRamaswamy.Tummala@Sun.COM for (lifrp = lifc.lifc_req, i = 0; i < nifs; i++, lifrp++) {
399*12965SWilliam.Taylor@Oracle.COM
4008485SPeter.Memishian@Sun.COM if (lifrp->lifr_type != IFT_IB)
4018485SPeter.Memishian@Sun.COM continue;
4024703Shiremath
403*12965SWilliam.Taylor@Oracle.COM IBTF_DPRINTF_L4(cmlog, "\nInterface# : %d", i);
404*12965SWilliam.Taylor@Oracle.COM IBTF_DPRINTF_L4(cmlog, "lifr_name : %s, lifr_family :%X, "
405*12965SWilliam.Taylor@Oracle.COM "lifr_type : 0x%lX", lifrp->lifr_name,
406*12965SWilliam.Taylor@Oracle.COM lifrp->lifr_addr.ss_family, lifrp->lifr_type);
407*12965SWilliam.Taylor@Oracle.COM
408*12965SWilliam.Taylor@Oracle.COM (void) strlcpy(ifname, lifrp->lifr_name, LIFNAMSIZ);
409*12965SWilliam.Taylor@Oracle.COM
410*12965SWilliam.Taylor@Oracle.COM /* Get ZoneId. */
411*12965SWilliam.Taylor@Oracle.COM lifr_copy = *lifrp;
412*12965SWilliam.Taylor@Oracle.COM ifzoneid = 0;
413*12965SWilliam.Taylor@Oracle.COM err = ibcm_do_ip_ioctl(SIOCGLIFZONE, sizeof (struct lifreq),
414*12965SWilliam.Taylor@Oracle.COM &lifr_copy);
415*12965SWilliam.Taylor@Oracle.COM if (err != 0) {
416*12965SWilliam.Taylor@Oracle.COM IBTF_DPRINTF_L2(cmlog, "IFZONE ioctl Failed: err = %d",
417*12965SWilliam.Taylor@Oracle.COM err);
418*12965SWilliam.Taylor@Oracle.COM } else {
419*12965SWilliam.Taylor@Oracle.COM IBTF_DPRINTF_L4(cmlog, "lifr_zoneid : 0x%X",
420*12965SWilliam.Taylor@Oracle.COM lifr_copy.lifr_zoneid);
421*12965SWilliam.Taylor@Oracle.COM ifzoneid = lifr_copy.lifr_zoneid;
422*12965SWilliam.Taylor@Oracle.COM }
423*12965SWilliam.Taylor@Oracle.COM
424*12965SWilliam.Taylor@Oracle.COM /* Get IfIndex. */
425*12965SWilliam.Taylor@Oracle.COM lifr_copy = *lifrp;
426*12965SWilliam.Taylor@Oracle.COM err = ibcm_do_ip_ioctl(SIOCGLIFINDEX, sizeof (struct lifreq),
427*12965SWilliam.Taylor@Oracle.COM &lifr_copy);
428*12965SWilliam.Taylor@Oracle.COM if (err != 0) {
429*12965SWilliam.Taylor@Oracle.COM IBTF_DPRINTF_L2(cmlog, "IFINDEX ioctl Failed: err = %d",
430*12965SWilliam.Taylor@Oracle.COM err);
431*12965SWilliam.Taylor@Oracle.COM } else
432*12965SWilliam.Taylor@Oracle.COM IBTF_DPRINTF_L4(cmlog, "lifr_index : 0x%X",
433*12965SWilliam.Taylor@Oracle.COM lifr_copy.lifr_index);
434*12965SWilliam.Taylor@Oracle.COM
435*12965SWilliam.Taylor@Oracle.COM /* Get Interface flags. */
436*12965SWilliam.Taylor@Oracle.COM lifr_copy = *lifrp;
437*12965SWilliam.Taylor@Oracle.COM err = ibcm_do_ip_ioctl(SIOCGLIFFLAGS, sizeof (struct lifreq),
438*12965SWilliam.Taylor@Oracle.COM &lifr_copy);
439*12965SWilliam.Taylor@Oracle.COM if (err != 0) {
440*12965SWilliam.Taylor@Oracle.COM IBTF_DPRINTF_L2(cmlog, "IFFLAGS ioctl Failed: err = %d",
441*12965SWilliam.Taylor@Oracle.COM err);
442*12965SWilliam.Taylor@Oracle.COM } else {
443*12965SWilliam.Taylor@Oracle.COM ifflags = lifr_copy.lifr_flags;
444*12965SWilliam.Taylor@Oracle.COM IBTF_DPRINTF_L4(cmlog, "lifr_flags : 0x%llX",
445*12965SWilliam.Taylor@Oracle.COM ifflags);
446*12965SWilliam.Taylor@Oracle.COM }
447*12965SWilliam.Taylor@Oracle.COM
448*12965SWilliam.Taylor@Oracle.COM lifr_copy = *lifrp;
449*12965SWilliam.Taylor@Oracle.COM err = ibcm_do_ip_ioctl(SIOCGLIFGROUPNAME,
450*12965SWilliam.Taylor@Oracle.COM sizeof (struct lifreq), &lifr_copy);
451*12965SWilliam.Taylor@Oracle.COM if (err != 0) {
452*12965SWilliam.Taylor@Oracle.COM IBTF_DPRINTF_L3(cmlog, "IFGroupName ioctl Failed: "
453*12965SWilliam.Taylor@Oracle.COM "err = %d", err);
454*12965SWilliam.Taylor@Oracle.COM }
455*12965SWilliam.Taylor@Oracle.COM
456*12965SWilliam.Taylor@Oracle.COM if (lifr_copy.lifr_groupname[0] != '\0') {
457*12965SWilliam.Taylor@Oracle.COM IBTF_DPRINTF_L4(cmlog, "lifr_groupname : %s",
458*12965SWilliam.Taylor@Oracle.COM lifr_copy.lifr_groupname);
459*12965SWilliam.Taylor@Oracle.COM (void) strlcpy(lifgr.gi_grname,
460*12965SWilliam.Taylor@Oracle.COM lifr_copy.lifr_groupname, LIFGRNAMSIZ);
461*12965SWilliam.Taylor@Oracle.COM err = ibcm_do_ip_ioctl(SIOCGLIFGROUPINFO,
462*12965SWilliam.Taylor@Oracle.COM sizeof (struct lifgroupinfo), &lifgr);
463*12965SWilliam.Taylor@Oracle.COM if (err != 0) {
464*12965SWilliam.Taylor@Oracle.COM IBTF_DPRINTF_L2(cmlog, "IFGroupINFO ioctl "
465*12965SWilliam.Taylor@Oracle.COM "Failed: err = %d", err);
466*12965SWilliam.Taylor@Oracle.COM } else {
467*12965SWilliam.Taylor@Oracle.COM IBTF_DPRINTF_L4(cmlog, "lifgroupinfo details");
468*12965SWilliam.Taylor@Oracle.COM IBTF_DPRINTF_L4(cmlog, "grname : %s, grifname :"
469*12965SWilliam.Taylor@Oracle.COM " %s, m4ifname : %s, m6ifname : %s",
470*12965SWilliam.Taylor@Oracle.COM lifgr.gi_grname, lifgr.gi_grifname,
471*12965SWilliam.Taylor@Oracle.COM lifgr.gi_m4ifname, lifgr.gi_m6ifname);
472*12965SWilliam.Taylor@Oracle.COM IBTF_DPRINTF_L4(cmlog, "gi_bcifname : %s",
473*12965SWilliam.Taylor@Oracle.COM lifgr.gi_bcifname);
474*12965SWilliam.Taylor@Oracle.COM IBTF_DPRINTF_L4(cmlog, "gi_v4 %d, gi_v6 %d, "
475*12965SWilliam.Taylor@Oracle.COM "gi_nv4 %d, gi_nv6 %d, gi_mactype %d",
476*12965SWilliam.Taylor@Oracle.COM lifgr.gi_v4, lifgr.gi_v6, lifgr.gi_nv4,
477*12965SWilliam.Taylor@Oracle.COM lifgr.gi_nv6, lifgr.gi_mactype);
478*12965SWilliam.Taylor@Oracle.COM
479*12965SWilliam.Taylor@Oracle.COM (void) strlcpy(ifname, lifgr.gi_bcifname,
480*12965SWilliam.Taylor@Oracle.COM LIFNAMSIZ);
481*12965SWilliam.Taylor@Oracle.COM }
482*12965SWilliam.Taylor@Oracle.COM }
483*12965SWilliam.Taylor@Oracle.COM
484*12965SWilliam.Taylor@Oracle.COM if ((ipp = ibcm_arp_lookup(ibds, ifname)) == NULL)
48512163SRamaswamy.Tummala@Sun.COM continue;
48612163SRamaswamy.Tummala@Sun.COM
487*12965SWilliam.Taylor@Oracle.COM ipp->ip_zoneid = ifzoneid; /* Copy back the zoneid info */
4888485SPeter.Memishian@Sun.COM switch (lifrp->lifr_addr.ss_family) {
4898485SPeter.Memishian@Sun.COM case AF_INET:
4908485SPeter.Memishian@Sun.COM ipp->ip_inet_family = AF_INET;
4918485SPeter.Memishian@Sun.COM bcopy(&lifrp->lifr_addr, &ipp->ip_cm_sin,
4928485SPeter.Memishian@Sun.COM sizeof (struct sockaddr_in));
4938485SPeter.Memishian@Sun.COM naddr++;
4948485SPeter.Memishian@Sun.COM break;
4958485SPeter.Memishian@Sun.COM case AF_INET6:
4968485SPeter.Memishian@Sun.COM ipp->ip_inet_family = AF_INET6;
4978485SPeter.Memishian@Sun.COM bcopy(&lifrp->lifr_addr, &ipp->ip_cm_sin6,
4988485SPeter.Memishian@Sun.COM sizeof (struct sockaddr_in6));
4998485SPeter.Memishian@Sun.COM naddr++;
5008485SPeter.Memishian@Sun.COM break;
5014703Shiremath }
5024703Shiremath }
5034703Shiremath
5048485SPeter.Memishian@Sun.COM kmem_free(lifc.lifc_buf, bufsize);
5058485SPeter.Memishian@Sun.COM return (naddr > 0);
5064703Shiremath }
5074703Shiremath
5084703Shiremath ibt_status_t
ibcm_arp_get_ibds(ibcm_arp_ibd_insts_t * ibdp,sa_family_t family_loc)5099349SShantkumar.Hiremath@Sun.COM ibcm_arp_get_ibds(ibcm_arp_ibd_insts_t *ibdp, sa_family_t family_loc)
5104703Shiremath {
5119349SShantkumar.Hiremath@Sun.COM #ifdef DEBUG
5129349SShantkumar.Hiremath@Sun.COM int i;
5139349SShantkumar.Hiremath@Sun.COM #endif
5149349SShantkumar.Hiremath@Sun.COM
5154703Shiremath IBTF_DPRINTF_L4(cmlog, "ibcm_arp_get_ibds(%p)", ibdp);
5164703Shiremath
5174703Shiremath ibcm_arp_get_ibd_insts(ibdp);
5184703Shiremath
5194703Shiremath IBTF_DPRINTF_L3(cmlog, "ibcm_arp_get_ibds: Found %d ibd instances",
5204703Shiremath ibdp->ibcm_arp_ibd_cnt);
5214703Shiremath
5224703Shiremath if (ibdp->ibcm_arp_ibd_cnt == 0)
5234703Shiremath return (IBT_SRC_IP_NOT_FOUND);
5244703Shiremath
5254703Shiremath /* Get the IP addresses of active ports. */
5269349SShantkumar.Hiremath@Sun.COM if (!ibcm_arp_get_ibd_ipaddr(ibdp, family_loc)) {
5274703Shiremath IBTF_DPRINTF_L2(cmlog, "ibcm_arp_get_ibds: failed to get "
5284703Shiremath "ibd instance: IBT_SRC_IP_NOT_FOUND");
52912163SRamaswamy.Tummala@Sun.COM ibcm_arp_free_ibds(ibdp);
5304703Shiremath return (IBT_SRC_IP_NOT_FOUND);
5314703Shiremath }
5324703Shiremath
5339349SShantkumar.Hiremath@Sun.COM #ifdef DEBUG
5349349SShantkumar.Hiremath@Sun.COM for (i = 0; i < ibdp->ibcm_arp_ibd_cnt; i++) {
5359349SShantkumar.Hiremath@Sun.COM char my_buf[INET6_ADDRSTRLEN];
5369349SShantkumar.Hiremath@Sun.COM ibcm_arp_ip_t *aip = &ibdp->ibcm_arp_ip[i];
5379349SShantkumar.Hiremath@Sun.COM
53812163SRamaswamy.Tummala@Sun.COM IBTF_DPRINTF_L4(cmlog, "ibcm_arp_get_ibds: Linkid %d Family %d "
53912163SRamaswamy.Tummala@Sun.COM "PKey 0x%lX \n HCAGUID 0x%llX SGID %llX:%llX",
54012163SRamaswamy.Tummala@Sun.COM aip->ip_linkid, aip->ip_inet_family, aip->ip_pkey,
5419349SShantkumar.Hiremath@Sun.COM aip->ip_hca_guid, aip->ip_port_gid.gid_prefix,
5429349SShantkumar.Hiremath@Sun.COM aip->ip_port_gid.gid_guid);
5439349SShantkumar.Hiremath@Sun.COM if (aip->ip_inet_family == AF_INET) {
5449349SShantkumar.Hiremath@Sun.COM IBTF_DPRINTF_L4(cmlog, "ibcm_arp_get_ibds: IPV4: %s",
5459349SShantkumar.Hiremath@Sun.COM inet_ntop(AF_INET, &aip->ip_cm_sin.sin_addr, my_buf,
5469349SShantkumar.Hiremath@Sun.COM sizeof (my_buf)));
5479349SShantkumar.Hiremath@Sun.COM } else if (aip->ip_inet_family == AF_INET6) {
5489349SShantkumar.Hiremath@Sun.COM IBTF_DPRINTF_L4(cmlog, "ibcm_arp_get_ibds: IPV6: %s",
5499349SShantkumar.Hiremath@Sun.COM inet_ntop(AF_INET6, &aip->ip_cm_sin6.sin6_addr,
5509349SShantkumar.Hiremath@Sun.COM my_buf, sizeof (my_buf)));
5519349SShantkumar.Hiremath@Sun.COM } else {
5529349SShantkumar.Hiremath@Sun.COM IBTF_DPRINTF_L2(cmlog, "ibcm_arp_get_ibds: Unknown "
5539349SShantkumar.Hiremath@Sun.COM "Family %d", aip->ip_inet_family);
5549349SShantkumar.Hiremath@Sun.COM }
5559349SShantkumar.Hiremath@Sun.COM }
5569349SShantkumar.Hiremath@Sun.COM #endif
5579349SShantkumar.Hiremath@Sun.COM
5584703Shiremath return (IBT_SUCCESS);
5594703Shiremath }
560