summaryrefslogtreecommitdiff
path: root/usr/src/uts/common/inet/ip
diff options
context:
space:
mode:
Diffstat (limited to 'usr/src/uts/common/inet/ip')
-rw-r--r--usr/src/uts/common/inet/ip/ip.c177
-rw-r--r--usr/src/uts/common/inet/ip/ip6_if.c12
-rw-r--r--usr/src/uts/common/inet/ip/ip6_ire.c2
-rw-r--r--usr/src/uts/common/inet/ip/ip_ftable.c1
-rw-r--r--usr/src/uts/common/inet/ip/ip_if.c337
-rw-r--r--usr/src/uts/common/inet/ip/ip_ire.c13
-rw-r--r--usr/src/uts/common/inet/ip/ip_multi.c12
-rw-r--r--usr/src/uts/common/inet/ip/ip_ndp.c39
8 files changed, 226 insertions, 367 deletions
diff --git a/usr/src/uts/common/inet/ip/ip.c b/usr/src/uts/common/inet/ip/ip.c
index 6514ff492d..1bc86df113 100644
--- a/usr/src/uts/common/inet/ip/ip.c
+++ b/usr/src/uts/common/inet/ip/ip.c
@@ -979,7 +979,7 @@ ip_ioctl_cmd_t ip_ndx_ioctl_table[] = {
/* 019 */ { IPI_DONTCARE, 0, 0, 0, NULL, NULL },
/* copyin size cannot be coded for SIOCGIFCONF */
- /* 020 */ { O_SIOCGIFCONF, 0, IPI_GET_CMD | IPI_REPL,
+ /* 020 */ { O_SIOCGIFCONF, 0, IPI_GET_CMD,
MISC_CMD, ip_sioctl_get_ifconf, NULL },
/* 021 */ { SIOCSIFMTU, sizeof (struct ifreq), IPI_PRIV | IPI_WR,
@@ -1005,11 +1005,11 @@ ip_ioctl_cmd_t ip_ndx_ioctl_table[] = {
/* See 166-168 below for extended SIOC*XARP ioctls */
/* 030 */ { SIOCSARP, sizeof (struct arpreq), IPI_PRIV,
- MISC_CMD, ip_sioctl_arp, NULL },
+ ARP_CMD, ip_sioctl_arp, NULL },
/* 031 */ { SIOCGARP, sizeof (struct arpreq), IPI_GET_CMD | IPI_REPL,
- MISC_CMD, ip_sioctl_arp, NULL },
+ ARP_CMD, ip_sioctl_arp, NULL },
/* 032 */ { SIOCDARP, sizeof (struct arpreq), IPI_PRIV,
- MISC_CMD, ip_sioctl_arp, NULL },
+ ARP_CMD, ip_sioctl_arp, NULL },
/* 033 */ { IPI_DONTCARE, 0, 0, 0, NULL, NULL },
/* 034 */ { IPI_DONTCARE, 0, 0, 0, NULL, NULL },
@@ -1090,7 +1090,7 @@ ip_ioctl_cmd_t ip_ndx_ioctl_table[] = {
IF_CMD, ip_sioctl_slifindex, NULL },
/* copyin size cannot be coded for SIOCGIFCONF */
- /* 092 */ { SIOCGIFCONF, 0, IPI_GET_CMD | IPI_REPL,
+ /* 092 */ { SIOCGIFCONF, 0, IPI_GET_CMD,
MISC_CMD, ip_sioctl_get_ifconf, NULL },
/* 093 */ { IPI_DONTCARE, 0, 0, 0, NULL, NULL },
/* 094 */ { IPI_DONTCARE, 0, 0, 0, NULL, NULL },
@@ -1138,7 +1138,7 @@ ip_ioctl_cmd_t ip_ndx_ioctl_table[] = {
/* 118 */ { IPI_DONTCARE, 0, 0, 0, NULL, NULL },
/* 119 */ { IPI_DONTCARE, 0, 0, 0, NULL, NULL },
- /* 120 */ { O_SIOCGLIFCONF, 0, IPI_GET_CMD, MISC_CMD | IPI_REPL,
+ /* 120 */ { O_SIOCGLIFCONF, 0, IPI_GET_CMD, MISC_CMD,
ip_sioctl_get_lifconf, NULL },
/* 121 */ { SIOCSLIFMTU, sizeof (struct lifreq), IPI_PRIV | IPI_WR,
LIF_CMD, ip_sioctl_mtu, NULL },
@@ -1249,15 +1249,15 @@ ip_ioctl_cmd_t ip_ndx_ioctl_table[] = {
MISC_CMD, NULL, NULL },
/* 164 */ { SIOCGDSTINFO, 0, IPI_GET_CMD, MISC_CMD, NULL, NULL },
- /* 165 */ { SIOCGLIFCONF, 0, IPI_GET_CMD, MISC_CMD | IPI_REPL,
+ /* 165 */ { SIOCGLIFCONF, 0, IPI_GET_CMD, MISC_CMD,
ip_sioctl_get_lifconf, NULL },
/* 166 */ { SIOCSXARP, sizeof (struct xarpreq), IPI_PRIV,
- MISC_CMD, ip_sioctl_xarp, NULL },
+ XARP_CMD, ip_sioctl_arp, NULL },
/* 167 */ { SIOCGXARP, sizeof (struct xarpreq), IPI_GET_CMD | IPI_REPL,
- MISC_CMD, ip_sioctl_xarp, NULL },
+ XARP_CMD, ip_sioctl_arp, NULL },
/* 168 */ { SIOCDXARP, sizeof (struct xarpreq), IPI_PRIV,
- MISC_CMD, ip_sioctl_xarp, NULL },
+ XARP_CMD, ip_sioctl_arp, NULL },
/* SIOCPOPSOCKFS is not handled by IP */
/* 169 */ { IPI_DONTCARE /* SIOCPOPSOCKFS */, 0, 0, 0, NULL, NULL },
@@ -1283,13 +1283,13 @@ ip_ioctl_cmd_t ip_ndx_ioctl_table[] = {
/* 177 */ { SIOCGLIFSRCOF, 0, IPI_GET_CMD, MISC_CMD,
ip_sioctl_get_lifsrcof, NULL },
/* 178 */ { SIOCGMSFILTER, sizeof (struct group_filter), IPI_GET_CMD,
- MISC_CMD, ip_sioctl_msfilter, NULL },
+ MSFILT_CMD, ip_sioctl_msfilter, NULL },
/* 179 */ { SIOCSMSFILTER, sizeof (struct group_filter), IPI_WR,
- MISC_CMD, ip_sioctl_msfilter, NULL },
+ MSFILT_CMD, ip_sioctl_msfilter, NULL },
/* 180 */ { SIOCGIPMSFILTER, sizeof (struct ip_msfilter), IPI_GET_CMD,
- MISC_CMD, ip_sioctl_msfilter, NULL },
+ MSFILT_CMD, ip_sioctl_msfilter, NULL },
/* 181 */ { SIOCSIPMSFILTER, sizeof (struct ip_msfilter), IPI_WR,
- MISC_CMD, ip_sioctl_msfilter, NULL },
+ MSFILT_CMD, ip_sioctl_msfilter, NULL },
/* 182 */ { SIOCSIPMPFAILBACK, sizeof (int), IPI_PRIV, MISC_CMD,
ip_sioctl_set_ipmpfailback, NULL }
};
@@ -3776,7 +3776,6 @@ ip_arp_excl(ipsq_t *ipsq, queue_t *rq, mblk_t *mp, void *dummy_arg)
IP_ADDR_LEN);
}
- (void) strlcpy(ibuf, ill->ill_name, sizeof (ibuf));
(void) mac_colon_addr((uint8_t *)(arh + 1), arh->arh_hlen, hbuf,
sizeof (hbuf));
(void) ip_dot_addr(src, sbuf);
@@ -3809,11 +3808,8 @@ ip_arp_excl(ipsq_t *ipsq, queue_t *rq, mblk_t *mp, void *dummy_arg)
if (bring_up == ((ipif->ipif_flags & IPIF_UP) != 0))
continue;
- if (ipif->ipif_id != 0) {
- (void) snprintf(ibuf + ill->ill_name_length - 1,
- sizeof (ibuf) - ill->ill_name_length + 1, ":%d",
- ipif->ipif_id);
- }
+ ipif_get_name(ipif, ibuf, sizeof (ibuf));
+
if (failtype == NULL) {
cmn_err(CE_NOTE, "recovered address %s on %s", sbuf,
ibuf);
@@ -9767,10 +9763,10 @@ ip_open(queue_t *q, dev_t *devp, int flag, int sflag, cred_t *credp)
/*
* Make the conn globally visible to walkers
*/
+ ASSERT(connp->conn_ref == 1);
mutex_enter(&connp->conn_lock);
connp->conn_state_flags &= ~CONN_INCIPIENT;
mutex_exit(&connp->conn_lock);
- ASSERT(connp->conn_ref == 1);
qprocson(q);
@@ -15553,8 +15549,7 @@ ip_rput_dlpi_writer(ipsq_t *ipsq, queue_t *q, mblk_t *mp, void *dummy_arg)
* in ip_rput(). If there's an error, we
* complete it here.
*/
- err = ipif_ndp_up(ipif, &ipif->ipif_v6lcl_addr);
- if (err == 0) {
+ if ((err = ipif_ndp_up(ipif)) == 0) {
if (ill->ill_flags & ILLF_XRESOLV) {
mutex_enter(&connp->conn_lock);
mutex_enter(&ill->ill_lock);
@@ -18143,8 +18138,7 @@ ip_snmp_get_mib2_ip_addr(queue_t *q, mblk_t *mpctl, ip_stack_t *ipst)
mae.ipAdEntInfo.ae_obcnt = ipif->ipif_ob_pkt_count;
mae.ipAdEntInfo.ae_focnt = ipif->ipif_fo_pkt_count;
- (void) ipif_get_name(ipif,
- mae.ipAdEntIfIndex.o_bytes,
+ ipif_get_name(ipif, mae.ipAdEntIfIndex.o_bytes,
OCTET_LENGTH);
mae.ipAdEntIfIndex.o_length =
mi_strlen(mae.ipAdEntIfIndex.o_bytes);
@@ -18225,8 +18219,7 @@ ip_snmp_get_mib2_ip6_addr(queue_t *q, mblk_t *mpctl, ip_stack_t *ipst)
mae6.ipv6AddrInfo.ae_obcnt = ipif->ipif_ob_pkt_count;
mae6.ipv6AddrInfo.ae_focnt = ipif->ipif_fo_pkt_count;
- (void) ipif_get_name(ipif,
- mae6.ipv6AddrIfIndex.o_bytes,
+ ipif_get_name(ipif, mae6.ipv6AddrIfIndex.o_bytes,
OCTET_LENGTH);
mae6.ipv6AddrIfIndex.o_length =
mi_strlen(mae6.ipv6AddrIfIndex.o_bytes);
@@ -18324,8 +18317,7 @@ ip_snmp_get_mib2_ip_group_mem(queue_t *q, mblk_t *mpctl, ip_stack_t *ipst)
if (ipif->ipif_zoneid != zoneid &&
ipif->ipif_zoneid != ALL_ZONES)
continue; /* not this zone */
- (void) ipif_get_name(ipif,
- ipm.ipGroupMemberIfIndex.o_bytes,
+ ipif_get_name(ipif, ipm.ipGroupMemberIfIndex.o_bytes,
OCTET_LENGTH);
ipm.ipGroupMemberIfIndex.o_length =
mi_strlen(ipm.ipGroupMemberIfIndex.o_bytes);
@@ -18447,8 +18439,7 @@ ip_snmp_get_mib2_ip_group_src(queue_t *q, mblk_t *mpctl, ip_stack_t *ipst)
ipif = ipif->ipif_next) {
if (ipif->ipif_zoneid != zoneid)
continue; /* not this zone */
- (void) ipif_get_name(ipif,
- ips.ipGroupSourceIfIndex.o_bytes,
+ ipif_get_name(ipif, ips.ipGroupSourceIfIndex.o_bytes,
OCTET_LENGTH);
ips.ipGroupSourceIfIndex.o_length =
mi_strlen(ips.ipGroupSourceIfIndex.o_bytes);
@@ -18981,8 +18972,7 @@ ip_snmp_get2_v4(ire_t *ire, iproutedata_t *ird)
bcopy(ill->ill_name, re->ipRouteIfIndex.o_bytes,
re->ipRouteIfIndex.o_length);
} else if (ipif != NULL) {
- (void) ipif_get_name(ipif, re->ipRouteIfIndex.o_bytes,
- OCTET_LENGTH);
+ ipif_get_name(ipif, re->ipRouteIfIndex.o_bytes, OCTET_LENGTH);
re->ipRouteIfIndex.o_length =
mi_strlen(re->ipRouteIfIndex.o_bytes);
}
@@ -19125,8 +19115,7 @@ ip_snmp_get2_v6_route(ire_t *ire, iproutedata_t *ird)
bcopy(ill->ill_name, re->ipv6RouteIfIndex.o_bytes,
re->ipv6RouteIfIndex.o_length);
} else if (ipif != NULL) {
- (void) ipif_get_name(ipif, re->ipv6RouteIfIndex.o_bytes,
- OCTET_LENGTH);
+ ipif_get_name(ipif, re->ipv6RouteIfIndex.o_bytes, OCTET_LENGTH);
re->ipv6RouteIfIndex.o_length =
mi_strlen(re->ipv6RouteIfIndex.o_bytes);
}
@@ -26664,23 +26653,25 @@ ip_reprocess_ioctl(ipsq_t *ipsq, queue_t *q, mblk_t *mp, void *dummy_arg)
/*
* ioctl processing
*
- * ioctl processing starts with ip_sioctl_copyin_setup which looks up
- * the ioctl command in the ioctl tables and determines the copyin data size
- * from the ioctl property ipi_copyin_size, and does an mi_copyin() of that
- * size.
+ * ioctl processing starts with ip_sioctl_copyin_setup(), which looks up
+ * the ioctl command in the ioctl tables, determines the copyin data size
+ * from the ipi_copyin_size field, and does an mi_copyin() of that size.
+ *
+ * ioctl processing then continues when the M_IOCDATA makes its way down to
+ * ip_wput_nondata(). The ioctl is looked up again in the ioctl table, its
+ * associated 'conn' is refheld till the end of the ioctl and the general
+ * ioctl processing function ip_process_ioctl() is called to extract the
+ * arguments and process the ioctl. To simplify extraction, ioctl commands
+ * are "typed" based on the arguments they take (e.g., LIF_CMD which takes a
+ * `struct lifreq'), and a common extract function (e.g., ip_extract_lifreq())
+ * is used to extract the ioctl's arguments.
*
- * ioctl processing then continues when the M_IOCDATA makes its way down.
- * Now the ioctl is looked up again in the ioctl table, and its properties are
- * extracted. The associated 'conn' is then refheld till the end of the ioctl
- * and the general ioctl processing function ip_process_ioctl is called.
* ip_process_ioctl determines if the ioctl needs to be serialized, and if
* so goes thru the serialization primitive ipsq_try_enter. Then the
* appropriate function to handle the ioctl is called based on the entry in
* the ioctl table. ioctl completion is encapsulated in ip_ioctl_finish
* which also refreleases the 'conn' that was refheld at the start of the
* ioctl. Finally ipsq_exit is called if needed to exit the ipsq.
- * ip_extract_lifreq_cmn extracts the interface name from the lifreq/ifreq
- * struct and looks up the ipif. ip_extract_tunreq handles the case of tunnel.
*
* Many exclusive ioctls go thru an internal down up sequence as part of
* the operation. For example an attempt to change the IP address of an
@@ -26692,7 +26683,8 @@ void
ip_process_ioctl(ipsq_t *ipsq, queue_t *q, mblk_t *mp, void *arg)
{
struct iocblk *iocp = (struct iocblk *)mp->b_rptr;
- ip_ioctl_cmd_t *ipip = (ip_ioctl_cmd_t *)arg;
+ ip_ioctl_cmd_t *ipip = arg;
+ ip_extract_func_t *extract_funcp;
cmd_info_t ci;
int err;
boolean_t entered_ipsq = B_FALSE;
@@ -26714,64 +26706,53 @@ ip_process_ioctl(ipsq_t *ipsq, queue_t *q, mblk_t *mp, void *arg)
}
ci.ci_ipif = NULL;
- switch (ipip->ipi_cmd_type) {
- case IF_CMD:
- case LIF_CMD:
+ if (ipip->ipi_cmd_type == MISC_CMD) {
/*
- * ioctls that pass in a [l]ifreq appear here.
- * ip_extract_lifreq_cmn returns a refheld ipif in
- * ci.ci_ipif
+ * All MISC_CMD ioctls come in here -- e.g. SIOCGLIFCONF.
*/
- err = ip_extract_lifreq_cmn(q, mp, ipip->ipi_cmd_type,
- ipip->ipi_flags, &ci, ip_process_ioctl);
- if (err != 0) {
- ip_ioctl_finish(q, mp, err, IPI2MODE(ipip), NULL);
- return;
+ if (ipip->ipi_cmd == IF_UNITSEL) {
+ /* ioctl comes down the ill */
+ ci.ci_ipif = ((ill_t *)q->q_ptr)->ill_ipif;
+ ipif_refhold(ci.ci_ipif);
}
- ASSERT(ci.ci_ipif != NULL);
- break;
+ err = 0;
+ ci.ci_sin = NULL;
+ ci.ci_sin6 = NULL;
+ ci.ci_lifr = NULL;
+ } else {
+ switch (ipip->ipi_cmd_type) {
+ case IF_CMD:
+ case LIF_CMD:
+ extract_funcp = ip_extract_lifreq;
+ break;
- case TUN_CMD:
- /*
- * SIOC[GS]TUNPARAM appear here. ip_extract_tunreq returns
- * a refheld ipif in ci.ci_ipif
- */
- err = ip_extract_tunreq(q, mp, &ci.ci_ipif, ip_process_ioctl);
+ case ARP_CMD:
+ case XARP_CMD:
+ extract_funcp = ip_extract_arpreq;
+ break;
+
+ case TUN_CMD:
+ extract_funcp = ip_extract_tunreq;
+ break;
+
+ case MSFILT_CMD:
+ extract_funcp = ip_extract_msfilter;
+ break;
+
+ default:
+ ASSERT(0);
+ }
+
+ err = (*extract_funcp)(q, mp, ipip, &ci, ip_process_ioctl);
if (err != 0) {
ip_ioctl_finish(q, mp, err, IPI2MODE(ipip), NULL);
return;
}
- ASSERT(ci.ci_ipif != NULL);
- break;
- case MISC_CMD:
/*
- * ioctls that neither pass in [l]ifreq or iftun_req come here
- * For eg. SIOCGLIFCONF will appear here.
+ * All of the extraction functions return a refheld ipif.
*/
- switch (ipip->ipi_cmd) {
- case IF_UNITSEL:
- /* ioctl comes down the ill */
- ci.ci_ipif = ((ill_t *)q->q_ptr)->ill_ipif;
- ipif_refhold(ci.ci_ipif);
- break;
- case SIOCGMSFILTER:
- case SIOCSMSFILTER:
- case SIOCGIPMSFILTER:
- case SIOCSIPMSFILTER:
- err = ip_extract_msfilter(q, mp, &ci.ci_ipif,
- ip_process_ioctl);
- if (err != 0) {
- ip_ioctl_finish(q, mp, err, IPI2MODE(ipip),
- NULL);
- }
- break;
- }
- err = 0;
- ci.ci_sin = NULL;
- ci.ci_sin6 = NULL;
- ci.ci_lifr = NULL;
- break;
+ ASSERT(ci.ci_ipif != NULL);
}
/*
@@ -26921,7 +26902,7 @@ ip_wput_nondata(ipsq_t *ipsq, queue_t *q, mblk_t *mp, void *dummy_arg)
ip_ioctl_cmd_t *ipip;
cred_t *cr;
conn_t *connp;
- int cmd, err;
+ int err;
nce_t *nce;
ipif_t *ipif;
ip_stack_t *ipst;
@@ -26967,8 +26948,8 @@ ip_wput_nondata(ipsq_t *ipsq, queue_t *q, mblk_t *mp, void *dummy_arg)
putnext(q, mp);
}
return;
- } else if ((q->q_next != NULL) &&
- !(ipip->ipi_flags & IPI_MODOK)) {
+ }
+ if ((q->q_next != NULL) && !(ipip->ipi_flags & IPI_MODOK)) {
/*
* the ioctl is one we recognise, but is not
* consumed by IP as a module, pass M_IOCDATA
@@ -27008,9 +26989,7 @@ ip_wput_nondata(ipsq_t *ipsq, queue_t *q, mblk_t *mp, void *dummy_arg)
* so we return; a return value of 1 means no more
* copying is needed, so we continue.
*/
- cmd = iocp->ioc_cmd;
- if ((cmd == SIOCGMSFILTER || cmd == SIOCSMSFILTER ||
- cmd == SIOCGIPMSFILTER || cmd == SIOCSIPMSFILTER) &&
+ if (ipip->ipi_cmd_type == MSFILT_CMD &&
MI_COPY_COUNT(mp) == 1) {
if (ip_copyin_msfilter(q, mp) == 0)
return;
diff --git a/usr/src/uts/common/inet/ip/ip6_if.c b/usr/src/uts/common/inet/ip/ip6_if.c
index 171f58e9f7..c5a18350a8 100644
--- a/usr/src/uts/common/inet/ip/ip6_if.c
+++ b/usr/src/uts/common/inet/ip/ip6_if.c
@@ -1379,26 +1379,24 @@ ipif_ndp_setup_multicast(ipif_t *ipif, nce_t **ret_nce)
}
/*
- * Get the resolver set up for a new interface address. (Always called
- * as writer.)
+ * Get the resolver set up for a new ipif. (Always called as writer.)
*/
int
-ipif_ndp_up(ipif_t *ipif, const in6_addr_t *addr)
+ipif_ndp_up(ipif_t *ipif)
{
ill_t *ill = ipif->ipif_ill;
int err = 0;
nce_t *nce = NULL;
nce_t *mnce = NULL;
- ip1dbg(("ipif_ndp_up(%s:%u)\n",
- ipif->ipif_ill->ill_name, ipif->ipif_id));
+ ip1dbg(("ipif_ndp_up(%s:%u)\n", ill->ill_name, ipif->ipif_id));
/*
* ND not supported on XRESOLV interfaces. If ND support (multicast)
* added later, take out this check.
*/
if ((ill->ill_flags & ILLF_XRESOLV) ||
- IN6_IS_ADDR_UNSPECIFIED(addr) ||
+ IN6_IS_ADDR_UNSPECIFIED(&ipif->ipif_v6lcl_addr) ||
(!(ill->ill_net_type & IRE_INTERFACE))) {
ipif->ipif_addr_ready = 1;
return (0);
@@ -1448,7 +1446,7 @@ ipif_ndp_up(ipif_t *ipif, const in6_addr_t *addr)
}
err = ndp_lookup_then_add_v6(ill,
hw_addr,
- addr,
+ &ipif->ipif_v6lcl_addr,
&ipv6_all_ones,
&ipv6_all_zeros,
0,
diff --git a/usr/src/uts/common/inet/ip/ip6_ire.c b/usr/src/uts/common/inet/ip/ip6_ire.c
index 5f57554840..60ecd3431f 100644
--- a/usr/src/uts/common/inet/ip/ip6_ire.c
+++ b/usr/src/uts/common/inet/ip/ip6_ire.c
@@ -1407,7 +1407,6 @@ ire_match_args_v6(ire_t *ire, const in6_addr_t *addr, const in6_addr_t *mask,
ASSERT((!(match_flags & MATCH_IRE_GW)) || gateway != NULL);
ASSERT((!(match_flags & (MATCH_IRE_ILL|MATCH_IRE_ILL_GROUP))) ||
(ipif != NULL && ipif->ipif_isv6));
- ASSERT(!(match_flags & MATCH_IRE_WQ));
/*
* HIDDEN cache entries have to be looked up specifically with
@@ -1646,7 +1645,6 @@ ire_ftable_lookup_v6(const in6_addr_t *addr, const in6_addr_t *mask,
ASSERT((!(flags & MATCH_IRE_MASK)) || mask != NULL);
ASSERT((!(flags & MATCH_IRE_GW)) || gateway != NULL);
ASSERT(ipif == NULL || ipif->ipif_isv6);
- ASSERT(!(flags & MATCH_IRE_WQ));
/*
* When we return NULL from this function, we should make
diff --git a/usr/src/uts/common/inet/ip/ip_ftable.c b/usr/src/uts/common/inet/ip/ip_ftable.c
index b9cf0cc6a2..4ae1cbd1dc 100644
--- a/usr/src/uts/common/inet/ip/ip_ftable.c
+++ b/usr/src/uts/common/inet/ip/ip_ftable.c
@@ -147,7 +147,6 @@ ire_ftable_lookup(ipaddr_t addr, ipaddr_t mask, ipaddr_t gateway,
boolean_t found_incomplete = B_FALSE;
ASSERT(ipif == NULL || !ipif->ipif_isv6);
- ASSERT(!(flags & MATCH_IRE_WQ));
/*
* When we return NULL from this function, we should make
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)
diff --git a/usr/src/uts/common/inet/ip/ip_ire.c b/usr/src/uts/common/inet/ip/ip_ire.c
index c85751f510..750813f5ef 100644
--- a/usr/src/uts/common/inet/ip/ip_ire.c
+++ b/usr/src/uts/common/inet/ip/ip_ire.c
@@ -2158,13 +2158,7 @@ ire_walk_ill_match(uint_t match_flags, uint_t ire_type, ire_t *ire,
ASSERT(match_flags != 0 || zoneid != ALL_ZONES);
/*
- * 1) MATCH_IRE_WQ : Used specifically to match on ire_stq.
- * The fast path update uses this to make sure it does not
- * update the fast path header of interface X with the fast
- * path updates it recieved on interface Y. It is similar
- * in handling DL_NOTE_FASTPATH_FLUSH.
- *
- * 2) MATCH_IRE_ILL/MATCH_IRE_ILL_GROUP : We match both on ill
+ * MATCH_IRE_ILL/MATCH_IRE_ILL_GROUP : We match both on ill
* pointed by ire_stq and ire_ipif. Only in the case of
* IRE_CACHEs can ire_stq and ire_ipif be pointing to
* different ills. But we want to keep this function generic
@@ -2279,8 +2273,6 @@ ire_walk_ill_match(uint_t match_flags, uint_t ire_type, ire_t *ire,
if (((!(match_flags & MATCH_IRE_TYPE)) ||
(ire->ire_type & ire_type)) &&
- ((!(match_flags & MATCH_IRE_WQ)) ||
- (ire->ire_stq == ill->ill_wq)) &&
((!(match_flags & MATCH_IRE_ILL)) ||
(ire_stq_ill == ill || ire_ipif_ill == ill)) &&
((!(match_flags & MATCH_IRE_ILL_GROUP)) ||
@@ -2334,7 +2326,7 @@ ire_walk_ill_tables(uint_t match_flags, uint_t ire_type, pfv_t func,
boolean_t ret;
struct rtfuncarg rtfarg;
- ASSERT((!(match_flags & (MATCH_IRE_WQ | MATCH_IRE_ILL |
+ ASSERT((!(match_flags & (MATCH_IRE_ILL |
MATCH_IRE_ILL_GROUP))) || (ill != NULL));
ASSERT(!(match_flags & MATCH_IRE_TYPE) || (ire_type != 0));
/*
@@ -3991,7 +3983,6 @@ ire_match_args(ire_t *ire, ipaddr_t addr, ipaddr_t mask, ipaddr_t gateway,
ASSERT((ire->ire_addr & ~ire->ire_mask) == 0);
ASSERT((!(match_flags & (MATCH_IRE_ILL|MATCH_IRE_ILL_GROUP))) ||
(ipif != NULL && !ipif->ipif_isv6));
- ASSERT(!(match_flags & MATCH_IRE_WQ));
/*
* HIDDEN cache entries have to be looked up specifically with
diff --git a/usr/src/uts/common/inet/ip/ip_multi.c b/usr/src/uts/common/inet/ip/ip_multi.c
index ad71011575..5816e7791f 100644
--- a/usr/src/uts/common/inet/ip/ip_multi.c
+++ b/usr/src/uts/common/inet/ip/ip_multi.c
@@ -2516,14 +2516,14 @@ ip_sioctl_msfilter(ipif_t *ipif, sin_t *dummy_sin, queue_t *q, mblk_t *mp,
/*
* Finds the ipif based on information in the ioctl headers. Needed to make
* ip_process_ioctl() happy (it needs to know the ipif for IPI_WR-flagged
- * ioctls prior to calling the ioctl's handler function). Somewhat analogous
- * to ip_extract_lifreq_cmn() and ip_extract_tunreq().
+ * ioctls prior to calling the ioctl's handler function).
*/
int
-ip_extract_msfilter(queue_t *q, mblk_t *mp, ipif_t **ipifpp, ipsq_func_t func)
+ip_extract_msfilter(queue_t *q, mblk_t *mp, const ip_ioctl_cmd_t *ipip,
+ cmd_info_t *ci, ipsq_func_t func)
{
- struct iocblk *iocp = (struct iocblk *)mp->b_rptr;
- int cmd = iocp->ioc_cmd, err = 0;
+ int cmd = ipip->ipi_cmd;
+ int err = 0;
conn_t *connp;
ipif_t *ipif;
/* caller has verified this mblk exists */
@@ -2594,7 +2594,7 @@ ip_extract_msfilter(queue_t *q, mblk_t *mp, ipif_t **ipifpp, ipsq_func_t func)
}
}
- *ipifpp = ipif;
+ ci->ci_ipif = ipif;
return (err);
}
diff --git a/usr/src/uts/common/inet/ip/ip_ndp.c b/usr/src/uts/common/inet/ip/ip_ndp.c
index 047866b76e..a87e0f9946 100644
--- a/usr/src/uts/common/inet/ip/ip_ndp.c
+++ b/usr/src/uts/common/inet/ip/ip_ndp.c
@@ -135,8 +135,6 @@ nce_advert_flags(const nce_t *nce)
if (nce->nce_flags & NCE_F_ISROUTER)
flag |= NDP_ISROUTER;
- if (!(nce->nce_flags & NCE_F_PROXY))
- flag |= NDP_ORIDE;
return (flag);
}
@@ -1287,8 +1285,6 @@ ndp_query(ill_t *ill, struct lif_nd_req *lnr)
(uchar_t *)&lnr->lnr_hdw_addr, lnr->lnr_hdw_len);
if (nce->nce_flags & NCE_F_ISROUTER)
lnr->lnr_flags = NDF_ISROUTER_ON;
- if (nce->nce_flags & NCE_F_PROXY)
- lnr->lnr_flags |= NDF_PROXY_ON;
if (nce->nce_flags & NCE_F_ANYCAST)
lnr->lnr_flags |= NDF_ANYCAST_ON;
done:
@@ -1498,7 +1494,7 @@ ip_ndp_recover(ipsq_t *ipsq, queue_t *rq, mblk_t *mp, void *dummy_arg)
mutex_exit(&ill->ill_lock);
ipif->ipif_was_dup = B_TRUE;
- if (ipif_ndp_up(ipif, addr) != EINPROGRESS)
+ if (ipif_ndp_up(ipif) != EINPROGRESS)
(void) ipif_up_done_v6(ipif);
}
freeb(mp);
@@ -1681,7 +1677,7 @@ ip_ndp_excl(ipsq_t *ipsq, queue_t *rq, mblk_t *mp, void *dummy_arg)
*/
goto ignore_conflict;
}
- (void) strlcpy(ibuf, ill->ill_name, sizeof (ibuf));
+
for (ipif = ill->ill_ipif; ipif != NULL; ipif = ipif->ipif_next) {
if ((ipif->ipif_flags & IPIF_POINTOPOINT) ||
@@ -1699,11 +1695,7 @@ ip_ndp_excl(ipsq_t *ipsq, queue_t *rq, mblk_t *mp, void *dummy_arg)
* complain. It may take a long time to recover.
*/
if (!ipif->ipif_was_dup) {
- if (ipif->ipif_id != 0) {
- (void) snprintf(ibuf + ill->ill_name_length - 1,
- sizeof (ibuf) - ill->ill_name_length + 1,
- ":%d", ipif->ipif_id);
- }
+ ipif_get_name(ipif, ibuf, sizeof (ibuf));
cmn_err(CE_WARN, "%s has duplicate address %s (in "
"use by %s); disabled", ibuf, sbuf, hbuf);
}
@@ -2693,18 +2685,11 @@ ndp_timer(void *arg)
char sbuf[INET6_ADDRSTRLEN];
ipif->ipif_was_dup = B_FALSE;
- (void) strlcpy(ibuf, ill->ill_name,
- sizeof (ibuf));
(void) inet_ntop(AF_INET6,
&ipif->ipif_v6lcl_addr,
sbuf, sizeof (sbuf));
- if (ipif->ipif_id != 0) {
- (void) snprintf(ibuf +
- ill->ill_name_length - 1,
- sizeof (ibuf) -
- ill->ill_name_length + 1,
- ":%d", ipif->ipif_id);
- }
+ ipif_get_name(ipif, ibuf,
+ sizeof (ibuf));
cmn_err(CE_NOTE, "recovered address "
"%s on %s", sbuf, ibuf);
}
@@ -3177,20 +3162,6 @@ ndp_sioc_update(ill_t *ill, lif_nd_req_t *lnr)
return (EINVAL);
}
- switch (inflags & (NDF_PROXY_ON|NDF_PROXY_OFF)) {
- case NDF_PROXY_ON:
- new_flags |= NCE_F_PROXY;
- break;
- case NDF_PROXY_OFF:
- new_flags &= ~NCE_F_PROXY;
- break;
- case (NDF_PROXY_OFF|NDF_PROXY_ON):
- mutex_exit(&ipst->ips_ndp6->ndp_g_lock);
- if (nce != NULL)
- NCE_REFRELE(nce);
- return (EINVAL);
- }
-
if (nce == NULL) {
err = ndp_add_v6(ill,
(uchar_t *)lnr->lnr_hdw_addr,