summaryrefslogtreecommitdiff
path: root/usr/src/uts/common/inet/ip/ip_if.c
diff options
context:
space:
mode:
authormeem <none@none>2007-08-31 12:48:28 -0700
committermeem <none@none>2007-08-31 12:48:28 -0700
commit98e93c293033f1b35b7d58ec09c56fbf35f99a12 (patch)
tree3b27457eebd0ff4b173ce7f21d47d6b9169ea885 /usr/src/uts/common/inet/ip/ip_if.c
parent0398691684c2596072212e4ca9d7033ad7ccfa54 (diff)
downloadillumos-joyent-98e93c293033f1b35b7d58ec09c56fbf35f99a12.tar.gz
6375443 dead declarations in <inet/ip*.h>
6587730 MATCH_IRE_WQ logic has no consumers 6592926 NCE_F_PROXY handling is a dead-end 6592983 IP ioctl argument extraction logic can be simplified 6592998 SIOC*MSFILTER ioctls can induce panic 6594323 ipif_get_name() could be simpler and used more widely 6595071 ipif_ndp_up()'s second argument is needless 6597721 {O_,}SIOCGLIFCONF have bogus ipi_cmd_type values 6599009 bogus conn_ref assertion in ip_open()
Diffstat (limited to 'usr/src/uts/common/inet/ip/ip_if.c')
-rw-r--r--usr/src/uts/common/inet/ip/ip_if.c337
1 files changed, 130 insertions, 207 deletions
diff --git a/usr/src/uts/common/inet/ip/ip_if.c b/usr/src/uts/common/inet/ip/ip_if.c
index b35a69571c..e8b0259a2f 100644
--- a/usr/src/uts/common/inet/ip/ip_if.c
+++ b/usr/src/uts/common/inet/ip/ip_if.c
@@ -144,8 +144,6 @@ static int ip_sioctl_netmask_tail(ipif_t *ipif, sin_t *sin, queue_t *q,
mblk_t *mp);
static int ip_sioctl_subnet_tail(ipif_t *ipif, in6_addr_t, in6_addr_t,
queue_t *q, mblk_t *mp, boolean_t need_up);
-static int ip_sioctl_arp_common(ill_t *ill, queue_t *q, mblk_t *mp,
- sin_t *sin, boolean_t x_arp_ioctl, boolean_t if_arp_ioctl);
static int ip_sioctl_plink_ipmod(ipsq_t *ipsq, queue_t *q, mblk_t *mp,
int ioccmd, struct linkblk *li, boolean_t doconsist);
static ipaddr_t ip_subnet_mask(ipaddr_t addr, ipif_t **, ip_stack_t *);
@@ -4797,7 +4795,7 @@ ill_dls_info(struct sockaddr_dl *sdl, const ipif_t *ipif)
sdl->sdl_family = AF_LINK;
sdl->sdl_index = ill->ill_phyint->phyint_ifindex;
sdl->sdl_type = ill->ill_type;
- (void) ipif_get_name(ipif, sdl->sdl_data, sizeof (sdl->sdl_data));
+ ipif_get_name(ipif, sdl->sdl_data, sizeof (sdl->sdl_data));
len = strlen(sdl->sdl_data);
ASSERT(len < 256);
sdl->sdl_nlen = (uchar_t)len;
@@ -4819,8 +4817,7 @@ ill_xarp_info(struct sockaddr_dl *sdl, ill_t *ill)
sdl->sdl_family = AF_LINK;
sdl->sdl_index = ill->ill_phyint->phyint_ifindex;
sdl->sdl_type = ill->ill_type;
- (void) ipif_get_name(ill->ill_ipif, sdl->sdl_data,
- sizeof (sdl->sdl_data));
+ ipif_get_name(ill->ill_ipif, sdl->sdl_data, sizeof (sdl->sdl_data));
sdl->sdl_nlen = (uchar_t)mi_strlen(sdl->sdl_data);
sdl->sdl_alen = ill->ill_phys_addr_length;
sdl->sdl_slen = 0;
@@ -5502,6 +5499,8 @@ ip_ipif_report(queue_t *q, mblk_t *mp, caddr_t arg, cred_t *ioc_cr)
zoneid != ipif->ipif_zoneid &&
ipif->ipif_zoneid != ALL_ZONES)
continue;
+
+ ipif_get_name(ipif, buf, sizeof (buf));
(void) mi_mpprintf(mp,
MI_COL_PTRFMT_STR
"%04u %05u %u/%u/%u %s %d",
@@ -5510,7 +5509,7 @@ ip_ipif_report(queue_t *q, mblk_t *mp, caddr_t arg, cred_t *ioc_cr)
ipif->ipif_ib_pkt_count,
ipif->ipif_ob_pkt_count,
ipif->ipif_fo_pkt_count,
- ipif_get_name(ipif, buf, sizeof (buf)),
+ buf,
ipif->ipif_zoneid);
flags = ipif->ipif_flags | ipif->ipif_ill->ill_flags |
@@ -8225,8 +8224,10 @@ ip_sioctl_get_oindex(ipif_t *ipif, sin_t *sin, queue_t *q, mblk_t *mp,
* Parse an iftun_req structure coming down SIOC[GS]TUNPARAM ioctls,
* refhold and return the associated ipif
*/
+/* ARGSUSED */
int
-ip_extract_tunreq(queue_t *q, mblk_t *mp, ipif_t **ipifp, ipsq_func_t func)
+ip_extract_tunreq(queue_t *q, mblk_t *mp, const ip_ioctl_cmd_t *ipip,
+ cmd_info_t *ci, ipsq_func_t func)
{
boolean_t exists;
struct iftun_req *ta;
@@ -8289,7 +8290,7 @@ ip_extract_tunreq(queue_t *q, mblk_t *mp, ipif_t **ipifp, ipsq_func_t func)
*/
if (ill->ill_isv6)
ta->ifta_flags |= 0x80000000;
- *ipifp = ipif;
+ ci->ci_ipif = ipif;
return (0);
}
@@ -8302,7 +8303,7 @@ ip_extract_tunreq(queue_t *q, mblk_t *mp, ipif_t **ipifp, ipsq_func_t func)
* a held ipif in ci.ci_ipif.
*/
int
-ip_extract_lifreq_cmn(queue_t *q, mblk_t *mp, int cmd_type, int flags,
+ip_extract_lifreq(queue_t *q, mblk_t *mp, const ip_ioctl_cmd_t *ipip,
cmd_info_t *ci, ipsq_func_t func)
{
sin_t *sin;
@@ -8314,7 +8315,6 @@ ip_extract_lifreq_cmn(queue_t *q, mblk_t *mp, int cmd_type, int flags,
ill_t *ill;
conn_t *connp;
boolean_t isv6;
- struct iocblk *iocp = (struct iocblk *)mp->b_rptr;
boolean_t exists;
int err;
mblk_t *mp1;
@@ -8342,8 +8342,7 @@ ip_extract_lifreq_cmn(queue_t *q, mblk_t *mp, int cmd_type, int flags,
/* Has been checked in ip_wput_nondata */
mp1 = mp->b_cont->b_cont;
-
- if (cmd_type == IF_CMD) {
+ if (ipip->ipi_cmd_type == IF_CMD) {
/* This a old style SIOC[GS]IF* command */
ifr = (struct ifreq *)mp1->b_rptr;
/*
@@ -8359,7 +8358,7 @@ ip_extract_lifreq_cmn(queue_t *q, mblk_t *mp, int cmd_type, int flags,
ci->ci_lifr = (struct lifreq *)ifr;
} else {
/* This a new style SIOC[GS]LIF* command */
- ASSERT(cmd_type == LIF_CMD);
+ ASSERT(ipip->ipi_cmd_type == LIF_CMD);
lifr = (struct lifreq *)mp1->b_rptr;
/*
* Null terminate the string to protect against buffer
@@ -8370,7 +8369,7 @@ ip_extract_lifreq_cmn(queue_t *q, mblk_t *mp, int cmd_type, int flags,
name = lifr->lifr_name;
sin = (sin_t *)&lifr->lifr_addr;
sin6 = (sin6_t *)&lifr->lifr_addr;
- if (iocp->ioc_cmd == SIOCSLIFGROUPNAME) {
+ if (ipip->ipi_cmd == SIOCSLIFGROUPNAME) {
(void) strncpy(ci->ci_groupname, lifr->lifr_groupname,
LIFNAMSIZ);
}
@@ -8379,7 +8378,7 @@ ip_extract_lifreq_cmn(queue_t *q, mblk_t *mp, int cmd_type, int flags,
ci->ci_lifr = lifr;
}
- if (iocp->ioc_cmd == SIOCSLIFNAME) {
+ if (ipip->ipi_cmd == SIOCSLIFNAME) {
/*
* The ioctl will be failed if the ioctl comes down
* an conn stream
@@ -8401,8 +8400,8 @@ ip_extract_lifreq_cmn(queue_t *q, mblk_t *mp, int cmd_type, int flags,
if (ipif == NULL) {
if (err == EINPROGRESS)
return (err);
- if (iocp->ioc_cmd == SIOCLIFFAILOVER ||
- iocp->ioc_cmd == SIOCLIFFAILBACK) {
+ if (ipip->ipi_cmd == SIOCLIFFAILOVER ||
+ ipip->ipi_cmd == SIOCLIFFAILBACK) {
/*
* Need to try both v4 and v6 since this
* ioctl can come down either v4 or v6
@@ -8423,7 +8422,7 @@ ip_extract_lifreq_cmn(queue_t *q, mblk_t *mp, int cmd_type, int flags,
/*
* Old style [GS]IFCMD does not admit IPv6 ipif
*/
- if (ipif != NULL && ipif->ipif_isv6 && cmd_type == IF_CMD) {
+ if (ipif != NULL && ipif->ipif_isv6 && ipip->ipi_cmd_type == IF_CMD) {
ipif_refrele(ipif);
return (ENXIO);
}
@@ -8445,7 +8444,7 @@ ip_extract_lifreq_cmn(queue_t *q, mblk_t *mp, int cmd_type, int flags,
* Allow only GET operations if this ipif has been created
* temporarily due to a MOVE operation.
*/
- if (ipif->ipif_replace_zero && !(flags & IPI_REPL)) {
+ if (ipif->ipif_replace_zero && !(ipip->ipi_flags & IPI_REPL)) {
ipif_refrele(ipif);
return (EINVAL);
}
@@ -8725,8 +8724,7 @@ ip_sioctl_get_ifconf(ipif_t *dummy_ipif, sin_t *dummy_sin, queue_t *q,
goto if_copydone;
}
}
- (void) ipif_get_name(ipif,
- ifr->ifr_name,
+ ipif_get_name(ipif, ifr->ifr_name,
sizeof (ifr->ifr_name));
sin = (sin_t *)&ifr->ifr_addr;
*sin = sin_null;
@@ -8841,8 +8839,7 @@ ip_sioctl_get_lifsrcof(ipif_t *dummy_ipif, sin_t *dummy_sin, queue_t *q,
break;
ipif = ill->ill_ipif;
- (void) ipif_get_name(ipif,
- lifr->lifr_name, sizeof (lifr->lifr_name));
+ ipif_get_name(ipif, lifr->lifr_name, sizeof (lifr->lifr_name));
if (ipif->ipif_isv6) {
sin6 = (sin6_t *)&lifr->lifr_addr;
*sin6 = sin6_null;
@@ -9016,7 +9013,7 @@ ip_sioctl_get_lifconf(ipif_t *dummy_ipif, sin_t *dummy_sin, queue_t *q,
}
}
- (void) ipif_get_name(ipif, lifr->lifr_name,
+ ipif_get_name(ipif, lifr->lifr_name,
sizeof (lifr->lifr_name));
if (ipif->ipif_isv6) {
sin6 = (sin6_t *)&lifr->lifr_addr;
@@ -9520,9 +9517,24 @@ ip_sioctl_tunparam(ipif_t *ipif, sin_t *dummy_sin, queue_t *q, mblk_t *mp,
}
}
-static int
-ip_sioctl_arp_common(ill_t *ill, queue_t *q, mblk_t *mp, sin_t *sin,
- boolean_t x_arp_ioctl, boolean_t if_arp_ioctl)
+/*
+ * ARP IOCTLs.
+ * How does IP get in the business of fronting ARP configuration/queries?
+ * Well it's like this, the Berkeley ARP IOCTLs (SIOCGARP, SIOCDARP, SIOCSARP)
+ * are by tradition passed in through a datagram socket. That lands in IP.
+ * As it happens, this is just as well since the interface is quite crude in
+ * that it passes in no information about protocol or hardware types, or
+ * interface association. After making the protocol assumption, IP is in
+ * the position to look up the name of the ILL, which ARP will need, and
+ * format a request that can be handled by ARP. The request is passed up
+ * stream to ARP, and the original IOCTL is completed by IP when ARP passes
+ * back a response. ARP supports its own set of more general IOCTLs, in
+ * case anyone is interested.
+ */
+/* ARGSUSED */
+int
+ip_sioctl_arp(ipif_t *ipif, sin_t *sin, queue_t *q, mblk_t *mp,
+ ip_ioctl_cmd_t *ipip, void *dummy_ifreq)
{
mblk_t *mp1;
mblk_t *mp2;
@@ -9533,38 +9545,30 @@ ip_sioctl_arp_common(ill_t *ill, queue_t *q, mblk_t *mp, sin_t *sin,
conn_t *connp;
struct arpreq *ar;
struct xarpreq *xar;
- boolean_t success;
int flags, alength;
char *lladdr;
ip_stack_t *ipst;
+ ill_t *ill = ipif->ipif_ill;
+ boolean_t if_arp_ioctl = B_FALSE;
ASSERT(!(q->q_flag & QREADR) && q->q_next == NULL);
connp = Q_TO_CONN(q);
ipst = connp->conn_netstack->netstack_ip;
- iocp = (struct iocblk *)mp->b_rptr;
- /*
- * ill has already been set depending on whether
- * bsd style or interface style ioctl.
- */
- ASSERT(ill != NULL);
-
- /*
- * Is this one of the new SIOC*XARP ioctls?
- */
- if (x_arp_ioctl) {
+ if (ipip->ipi_cmd_type == XARP_CMD) {
/* We have a chain - M_IOCTL-->MI_COPY_MBLK-->XARPREQ_MBLK */
xar = (struct xarpreq *)mp->b_cont->b_cont->b_rptr;
ar = NULL;
flags = xar->xarp_flags;
lladdr = LLADDR(&xar->xarp_ha);
+ if_arp_ioctl = (xar->xarp_ha.sdl_nlen != 0);
/*
* Validate against user's link layer address length
* input and name and addr length limits.
*/
alength = ill->ill_phys_addr_length;
- if (iocp->ioc_cmd == SIOCSXARP) {
+ if (ipip->ipi_cmd == SIOCSXARP) {
if (alength != xar->xarp_ha.sdl_alen ||
(alength + xar->xarp_ha.sdl_nlen >
sizeof (xar->xarp_ha.sdl_data)))
@@ -9590,7 +9594,7 @@ ip_sioctl_arp_common(ill_t *ill, queue_t *q, mblk_t *mp, sin_t *sin,
* operation will succeed.
*/
alength = 6;
- if ((iocp->ioc_cmd != SIOCDARP) &&
+ if ((ipip->ipi_cmd != SIOCDARP) &&
(alength != ill->ill_phys_addr_length)) {
return (EINVAL);
}
@@ -9664,14 +9668,13 @@ ip_sioctl_arp_common(ill_t *ill, queue_t *q, mblk_t *mp, sin_t *sin,
area->area_proto_mask_offset = 0;
break;
case SIOCSARP:
- case SIOCSXARP: {
+ case SIOCSXARP:
/*
* Delete the corresponding ire to make sure IP will
* pick up any change from arp.
*/
if (!if_arp_ioctl) {
(void) ip_ire_clookup_and_delete(ipaddr, NULL, ipst);
- break;
} else {
ipif_t *ipif = ipif_get_next_ipif(NULL, ill);
if (ipif != NULL) {
@@ -9679,13 +9682,26 @@ ip_sioctl_arp_common(ill_t *ill, queue_t *q, mblk_t *mp, sin_t *sin,
ipst);
ipif_refrele(ipif);
}
- break;
}
- }
+ break;
}
iocp->ioc_cmd = area->area_cmd;
/*
+ * Fill in the rest of the ARP operation fields.
+ */
+ area->area_hw_addr_length = alength;
+ bcopy(lladdr, (char *)area + area->area_hw_addr_offset, alength);
+
+ /* Translate the flags. */
+ if (flags & ATF_PERM)
+ area->area_flags |= ACE_F_PERMANENT;
+ if (flags & ATF_PUBL)
+ area->area_flags |= ACE_F_PUBLISH;
+ if (flags & ATF_AUTHORITY)
+ area->area_flags |= ACE_F_AUTHORITY;
+
+ /*
* Before sending 'mp' to ARP, we have to clear the b_next
* and b_prev. Otherwise if STREAMS encounters such a message
* in freemsg(), (because ARP can close any time) it can cause
@@ -9702,101 +9718,93 @@ ip_sioctl_arp_common(ill_t *ill, queue_t *q, mblk_t *mp, sin_t *sin,
mutex_enter(&connp->conn_lock);
mutex_enter(&ill->ill_lock);
/* conn has not yet started closing, hence this can't fail */
- success = ill_pending_mp_add(ill, connp, pending_mp);
- ASSERT(success);
+ VERIFY(ill_pending_mp_add(ill, connp, pending_mp) != 0);
mutex_exit(&ill->ill_lock);
mutex_exit(&connp->conn_lock);
/*
- * Fill in the rest of the ARP operation fields.
- */
- area->area_hw_addr_length = alength;
- bcopy(lladdr,
- (char *)area + area->area_hw_addr_offset,
- area->area_hw_addr_length);
- /* Translate the flags. */
- if (flags & ATF_PERM)
- area->area_flags |= ACE_F_PERMANENT;
- if (flags & ATF_PUBL)
- area->area_flags |= ACE_F_PUBLISH;
- if (flags & ATF_AUTHORITY)
- area->area_flags |= ACE_F_AUTHORITY;
-
- /*
- * Up to ARP it goes. The response will come
- * back in ip_wput as an M_IOCACK message, and
- * will be handed to ip_sioctl_iocack for
- * completion.
+ * Up to ARP it goes. The response will come back in ip_wput() as an
+ * M_IOCACK, and will be handed to ip_sioctl_iocack() for completion.
*/
putnext(ill->ill_rq, mp1);
return (EINPROGRESS);
}
-/* ARGSUSED */
+/*
+ * Parse an [x]arpreq structure coming down SIOC[GSD][X]ARP ioctls, identify
+ * the associated sin and refhold and return the associated ipif via `ci'.
+ */
int
-ip_sioctl_xarp(ipif_t *ipif, sin_t *dummy_sin, queue_t *q, mblk_t *mp,
- ip_ioctl_cmd_t *ipip, void *ifreq)
+ip_extract_arpreq(queue_t *q, mblk_t *mp, const ip_ioctl_cmd_t *ipip,
+ cmd_info_t *ci, ipsq_func_t func)
{
- struct xarpreq *xar;
- boolean_t isv6;
mblk_t *mp1;
int err;
+ sin_t *sin;
conn_t *connp;
- int ifnamelen;
+ ipif_t *ipif;
ire_t *ire = NULL;
ill_t *ill = NULL;
- struct sockaddr_in *sin;
- boolean_t if_arp_ioctl = B_FALSE;
- ip_stack_t *ipst;
+ boolean_t exists;
+ ip_stack_t *ipst;
+ struct arpreq *ar;
+ struct xarpreq *xar;
+ struct sockaddr_dl *sdl;
- /* ioctl comes down on an conn */
+ /* ioctl comes down on a conn */
ASSERT(!(q->q_flag & QREADR) && q->q_next == NULL);
connp = Q_TO_CONN(q);
- isv6 = connp->conn_af_isv6;
+ if (connp->conn_af_isv6)
+ return (ENXIO);
+
ipst = connp->conn_netstack->netstack_ip;
- /* Existance verified in ip_wput_nondata */
+ /* Verified in ip_wput_nondata */
mp1 = mp->b_cont->b_cont;
- ASSERT(MBLKL(mp1) >= sizeof (*xar));
- xar = (struct xarpreq *)mp1->b_rptr;
- sin = (sin_t *)&xar->xarp_pa;
-
- if (isv6 || (xar->xarp_ha.sdl_family != AF_LINK) ||
- (xar->xarp_pa.ss_family != AF_INET))
- return (ENXIO);
-
- ifnamelen = xar->xarp_ha.sdl_nlen;
- if (ifnamelen != 0) {
- char *cptr, cval;
+ if (ipip->ipi_cmd_type == XARP_CMD) {
+ ASSERT(MBLKL(mp1) >= sizeof (struct xarpreq));
+ xar = (struct xarpreq *)mp1->b_rptr;
+ sin = (sin_t *)&xar->xarp_pa;
+ sdl = &xar->xarp_ha;
- if (ifnamelen >= LIFNAMSIZ)
+ if (sdl->sdl_family != AF_LINK || sin->sin_family != AF_INET)
+ return (ENXIO);
+ if (sdl->sdl_nlen >= LIFNAMSIZ)
return (EINVAL);
+ } else {
+ ASSERT(ipip->ipi_cmd_type == ARP_CMD);
+ ASSERT(MBLKL(mp1) >= sizeof (struct arpreq));
+ ar = (struct arpreq *)mp1->b_rptr;
+ sin = (sin_t *)&ar->arp_pa;
+ }
- /*
- * Instead of bcopying a bunch of bytes,
- * null-terminate the string in-situ.
- */
- cptr = xar->xarp_ha.sdl_data + ifnamelen;
- cval = *cptr;
- *cptr = '\0';
- ill = ill_lookup_on_name(xar->xarp_ha.sdl_data,
- B_FALSE, isv6, CONNP_TO_WQ(connp), mp, ip_process_ioctl,
- &err, NULL, ipst);
- *cptr = cval;
- if (ill == NULL)
+ if (ipip->ipi_cmd_type == XARP_CMD && sdl->sdl_nlen != 0) {
+ ipif = ipif_lookup_on_name(sdl->sdl_data, sdl->sdl_nlen,
+ B_FALSE, &exists, B_FALSE, ALL_ZONES, CONNP_TO_WQ(connp),
+ mp, func, &err, ipst);
+ if (ipif == NULL)
return (err);
- if (ill->ill_net_type != IRE_IF_RESOLVER) {
- ill_refrele(ill);
+ if (ipif->ipif_id != 0 ||
+ ipif->ipif_net_type != IRE_IF_RESOLVER) {
+ ipif_refrele(ipif);
return (ENXIO);
}
-
- if_arp_ioctl = B_TRUE;
} else {
/*
- * PSARC 2003/088 states that if sdl_nlen == 0, it behaves
- * as an extended BSD ioctl. The kernel uses the IP address
- * to figure out the network interface.
+ * Either an SIOC[DGS]ARP or an SIOC[DGS]XARP with sdl_nlen ==
+ * 0: use the IP address to figure out the ill. In the IPMP
+ * case, a simple forwarding table lookup will return the
+ * IRE_IF_RESOLVER for the first interface in the group, which
+ * might not be the interface on which the requested IP
+ * address was resolved due to the ill selection algorithm
+ * (see ip_newroute_get_dst_ill()). So we do a cache table
+ * lookup first: if the IRE cache entry for the IP address is
+ * still there, it will contain the ill pointer for the right
+ * interface, so we use that. If the cache entry has been
+ * flushed, we fall back to the forwarding table lookup. This
+ * should be rare enough since IRE cache entries have a longer
+ * life expectancy than ARP cache entries.
*/
ire = ire_cache_lookup(sin->sin_addr.s_addr, ALL_ZONES, NULL,
ipst);
@@ -9808,103 +9816,21 @@ ip_sioctl_xarp(ipif_t *ipif, sin_t *dummy_sin, queue_t *q, mblk_t *mp,
ire = ire_ftable_lookup(sin->sin_addr.s_addr,
0, 0, IRE_IF_RESOLVER, NULL, NULL, ALL_ZONES, 0,
NULL, MATCH_IRE_TYPE, ipst);
- if ((ire == NULL) ||
- ((ill = ire_to_ill(ire)) == NULL)) {
+ if (ire == NULL || ((ill = ire_to_ill(ire)) == NULL)) {
+
if (ire != NULL)
ire_refrele(ire);
return (ENXIO);
}
}
ASSERT(ire != NULL && ill != NULL);
- }
-
- err = ip_sioctl_arp_common(ill, q, mp, sin, B_TRUE, if_arp_ioctl);
- if (if_arp_ioctl)
- ill_refrele(ill);
- if (ire != NULL)
+ ipif = ill->ill_ipif;
+ ipif_refhold(ipif);
ire_refrele(ire);
-
- return (err);
-}
-
-/*
- * ARP IOCTLs.
- * How does IP get in the business of fronting ARP configuration/queries?
- * Well its like this, the Berkeley ARP IOCTLs (SIOCGARP, SIOCDARP, SIOCSARP)
- * are by tradition passed in through a datagram socket. That lands in IP.
- * As it happens, this is just as well since the interface is quite crude in
- * that it passes in no information about protocol or hardware types, or
- * interface association. After making the protocol assumption, IP is in
- * the position to look up the name of the ILL, which ARP will need, and
- * format a request that can be handled by ARP. The request is passed up
- * stream to ARP, and the original IOCTL is completed by IP when ARP passes
- * back a response. ARP supports its own set of more general IOCTLs, in
- * case anyone is interested.
- */
-/* ARGSUSED */
-int
-ip_sioctl_arp(ipif_t *dummy_ipif, sin_t *dummy_sin, queue_t *q, mblk_t *mp,
- ip_ioctl_cmd_t *ipip, void *dummy_ifreq)
-{
- struct arpreq *ar;
- struct sockaddr_in *sin;
- ire_t *ire;
- boolean_t isv6;
- mblk_t *mp1;
- int err;
- conn_t *connp;
- ill_t *ill;
- ip_stack_t *ipst;
-
- /* ioctl comes down on an conn */
- ASSERT(!(q->q_flag & QREADR) && q->q_next == NULL);
- connp = Q_TO_CONN(q);
- ipst = CONNQ_TO_IPST(q);
- isv6 = connp->conn_af_isv6;
- if (isv6)
- return (ENXIO);
-
- /* Existance verified in ip_wput_nondata */
- mp1 = mp->b_cont->b_cont;
-
- ar = (struct arpreq *)mp1->b_rptr;
- sin = (sin_t *)&ar->arp_pa;
-
- /*
- * We need to let ARP know on which interface the IP
- * address has an ARP mapping. In the IPMP case, a
- * simple forwarding table lookup will return the
- * IRE_IF_RESOLVER for the first interface in the group,
- * which might not be the interface on which the
- * requested IP address was resolved due to the ill
- * selection algorithm (see ip_newroute_get_dst_ill()).
- * So we do a cache table lookup first: if the IRE cache
- * entry for the IP address is still there, it will
- * contain the ill pointer for the right interface, so
- * we use that. If the cache entry has been flushed, we
- * fall back to the forwarding table lookup. This should
- * be rare enough since IRE cache entries have a longer
- * life expectancy than ARP cache entries.
- */
- ire = ire_cache_lookup(sin->sin_addr.s_addr, ALL_ZONES, NULL, ipst);
- if ((ire == NULL) || (ire->ire_type == IRE_LOOPBACK) ||
- ((ill = ire_to_ill(ire)) == NULL)) {
- if (ire != NULL)
- ire_refrele(ire);
- ire = ire_ftable_lookup(sin->sin_addr.s_addr,
- 0, 0, IRE_IF_RESOLVER, NULL, NULL, ALL_ZONES, 0,
- NULL, MATCH_IRE_TYPE, ipst);
- if ((ire == NULL) || ((ill = ire_to_ill(ire)) == NULL)) {
- if (ire != NULL)
- ire_refrele(ire);
- return (ENXIO);
- }
}
- ASSERT(ire != NULL && ill != NULL);
-
- err = ip_sioctl_arp_common(ill, q, mp, sin, B_FALSE, B_FALSE);
- ire_refrele(ire);
- return (err);
+ ci->ci_sin = sin;
+ ci->ci_ipif = ipif;
+ return (0);
}
/*
@@ -19213,19 +19139,17 @@ ipif_free_tail(ipif_t *ipif)
}
/*
- * Returns an ipif name in the form "ill_name/unit" if ipif_id is not zero,
- * "ill_name" otherwise.
+ * Sets `buf' to an ipif name of the form "ill_name:id", or "ill_name" if "id"
+ * is zero.
*/
-char *
+void
ipif_get_name(const ipif_t *ipif, char *buf, int len)
{
- char lbuf[32];
+ char lbuf[LIFNAMSIZ];
char *name;
size_t name_len;
buf[0] = '\0';
- if (!ipif)
- return (buf);
name = ipif->ipif_ill->ill_name;
name_len = ipif->ipif_ill->ill_name_length;
if (ipif->ipif_id != 0) {
@@ -19238,7 +19162,6 @@ ipif_get_name(const ipif_t *ipif, char *buf, int len)
buf[len] = '\0';
len = MIN(len, name_len);
bcopy(name, buf, len);
- return (buf);
}
/*
@@ -19981,7 +19904,7 @@ ipif_up(ipif_t *ipif, queue_t *q, mblk_t *mp)
* That ioctl will complete in ip_rput.
*/
if (isv6) {
- err = ipif_ndp_up(ipif, &ipif->ipif_v6lcl_addr);
+ err = ipif_ndp_up(ipif);
if (err != 0) {
if (err != EINPROGRESS)
mp = ipsq_pending_mp_get(ipsq, &connp);
@@ -21668,7 +21591,7 @@ ip_sioctl_slifname(ipif_t *ipif, sin_t *sin, queue_t *q, mblk_t *mp,
ill = (ill_t *)q->q_ptr;
/*
* If we are not writer on 'q' then this interface exists already
- * and previous lookups (ipif_extract_lifreq_cmn) found this ipif.
+ * and previous lookups (ipif_extract_lifreq()) found this ipif.
* So return EALREADY
*/
if (ill != ipif->ipif_ill)