summaryrefslogtreecommitdiff
path: root/usr/src/uts/common/inet/ip/ip.c
diff options
context:
space:
mode:
Diffstat (limited to 'usr/src/uts/common/inet/ip/ip.c')
-rw-r--r--usr/src/uts/common/inet/ip/ip.c415
1 files changed, 196 insertions, 219 deletions
diff --git a/usr/src/uts/common/inet/ip/ip.c b/usr/src/uts/common/inet/ip/ip.c
index 05b22eacf3..5eee449379 100644
--- a/usr/src/uts/common/inet/ip/ip.c
+++ b/usr/src/uts/common/inet/ip/ip.c
@@ -1294,7 +1294,9 @@ ip_ioctl_cmd_t ip_ndx_ioctl_table[] = {
/* 181 */ { SIOCSIPMSFILTER, sizeof (struct ip_msfilter), IPI_WR,
MSFILT_CMD, ip_sioctl_msfilter, NULL },
/* 182 */ { SIOCSIPMPFAILBACK, sizeof (int), IPI_PRIV, MISC_CMD,
- ip_sioctl_set_ipmpfailback, NULL }
+ ip_sioctl_set_ipmpfailback, NULL },
+ /* SIOCSENABLESDP is handled by SDP */
+ /* 183 */ { IPI_DONTCARE /* SIOCSENABLESDP */, 0, 0, 0, NULL, NULL },
};
int ip_ndx_ioctl_count = sizeof (ip_ndx_ioctl_table) / sizeof (ip_ioctl_cmd_t);
@@ -5526,6 +5528,11 @@ ip_quiesce_conn(conn_t *connp)
drain_cleanup_reqd = B_TRUE;
if (connp->conn_oper_pending_ill != NULL)
conn_ioctl_cleanup_reqd = B_TRUE;
+ if (connp->conn_dhcpinit_ill != NULL) {
+ ASSERT(connp->conn_dhcpinit_ill->ill_dhcpinit != 0);
+ atomic_dec_32(&connp->conn_dhcpinit_ill->ill_dhcpinit);
+ connp->conn_dhcpinit_ill = NULL;
+ }
if (connp->conn_ilg_inuse != 0)
ilg_cleanup_reqd = B_TRUE;
mutex_exit(&connp->conn_lock);
@@ -7792,6 +7799,7 @@ ip_newroute(queue_t *q, mblk_t *mp, ipaddr_t dst, conn_t *connp,
MULTIRT_CACHEGW | MULTIRT_USESTAMP | MULTIRT_SETSTAMP;
boolean_t multirt_is_resolvable;
boolean_t multirt_resolve_next;
+ boolean_t unspec_src;
boolean_t do_attach_ill = B_FALSE;
boolean_t ip_nexthop = B_FALSE;
tsol_ire_gw_secattr_t *attrp = NULL;
@@ -8200,7 +8208,11 @@ ip_newroute(queue_t *q, mblk_t *mp, ipaddr_t dst, conn_t *connp,
src_ipif = ipif_lookup_addr(sire->ire_src_addr, NULL,
zoneid, NULL, NULL, NULL, NULL, ipst);
}
- if (src_ipif == NULL) {
+
+ unspec_src = (connp != NULL && connp->conn_unspec_src);
+
+ if (src_ipif == NULL &&
+ (!unspec_src || ipha->ipha_src != INADDR_ANY)) {
ire_marks |= IRE_MARK_USESRC_CHECK;
if ((dst_ill->ill_group != NULL) ||
(ire->ire_ipif->ipif_flags & IPIF_DEPRECATED) ||
@@ -8257,10 +8269,9 @@ ip_newroute(queue_t *q, mblk_t *mp, ipaddr_t dst, conn_t *connp,
* NOTE : ip_newroute_v6 does not have this piece of code as
* it uses ip6i to store this information.
*/
- if (ipha->ipha_src == INADDR_ANY &&
- (connp == NULL || !connp->conn_unspec_src)) {
+ if (ipha->ipha_src == INADDR_ANY && !unspec_src)
ipha->ipha_src = src_ipif->ipif_src_addr;
- }
+
if (ip_debug > 3) {
/* ip2dbg */
pr_addr_dbg("ip_newroute: first hop %s\n",
@@ -8963,7 +8974,7 @@ ip_opt_info_t zero_info;
* ip_rput_forward_multicast whenever we need to send
* out a packet to a destination address for which we do not have specific
* routing information. It is used when the packet will be sent out
- * on a specific interface. It is also called by ip_wput() when IP_XMIT_IF
+ * on a specific interface. It is also called by ip_wput() when IP_BOUND_IF
* socket option is set or icmp error message wants to go out on a particular
* interface for a unicast packet.
*
@@ -9005,6 +9016,7 @@ ip_newroute_ipif(queue_t *q, mblk_t *mp, ipif_t *ipif, ipaddr_t dst,
ire_t *fire = NULL;
mblk_t *copy_mp = NULL;
boolean_t multirt_resolve_next;
+ boolean_t unspec_src;
ipaddr_t ipha_dst;
ip_stack_t *ipst = ipif->ipif_ill->ill_ipst;
@@ -9105,14 +9117,6 @@ ip_newroute_ipif(queue_t *q, mblk_t *mp, ipif_t *ipif, ipaddr_t dst,
ASSERT(dst_ill == attach_ill);
} else {
/*
- * If this is set by IP_XMIT_IF, then make sure that
- * ipif is pointing to the same ill as the IP_XMIT_IF
- * specified ill.
- */
- ASSERT((connp == NULL) ||
- (connp->conn_xmit_if_ill == NULL) ||
- (connp->conn_xmit_if_ill == ipif->ipif_ill));
- /*
* If the interface belongs to an interface group,
* make sure the next possible interface in the group
* is used. This encourages load spreading among
@@ -9163,10 +9167,15 @@ ip_newroute_ipif(queue_t *q, mblk_t *mp, ipif_t *ipif, ipaddr_t dst,
src_ipif = ipif_lookup_addr(fire->ire_src_addr, NULL,
zoneid, NULL, NULL, NULL, NULL, ipst);
}
- if (((ipif->ipif_flags & IPIF_DEPRECATED) ||
+
+ unspec_src = (connp != NULL && connp->conn_unspec_src);
+
+ if (((!ipif->ipif_isv6 && ipif->ipif_lcl_addr == INADDR_ANY) ||
+ (ipif->ipif_flags & (IPIF_DEPRECATED|IPIF_UP)) != IPIF_UP ||
(connp != NULL && ipif->ipif_zoneid != zoneid &&
ipif->ipif_zoneid != ALL_ZONES)) &&
- (src_ipif == NULL)) {
+ (src_ipif == NULL) &&
+ (!unspec_src || ipha->ipha_src != INADDR_ANY)) {
src_ipif = ipif_select_source(dst_ill, dst, zoneid);
if (src_ipif == NULL) {
if (ip_debug > 2) {
@@ -9192,19 +9201,17 @@ ip_newroute_ipif(queue_t *q, mblk_t *mp, ipif_t *ipif, ipaddr_t dst,
* Assign a source address while we have the conn.
* We can't have ip_wput_ire pick a source address when the
* packet returns from arp since conn_unspec_src might be set
- * and we loose the conn when going through arp.
+ * and we lose the conn when going through arp.
*/
- if (ipha->ipha_src == INADDR_ANY &&
- (connp == NULL || !connp->conn_unspec_src)) {
+ if (ipha->ipha_src == INADDR_ANY && !unspec_src)
ipha->ipha_src = src_ipif->ipif_src_addr;
- }
/*
- * In the case of IP_XMIT_IF, it is possible that the
- * outgoing interface does not have an interface ire.
+ * In the case of IP_BOUND_IF and IP_PKTINFO, it is possible
+ * that the outgoing interface does not have an interface ire.
*/
if (CLASSD(ipha_dst) && (connp == NULL ||
- connp->conn_xmit_if_ill == NULL) &&
+ connp->conn_outgoing_ill == NULL) &&
infop->ip_opt_ill_index == 0) {
/* ipif_to_ire returns an held ire */
ire = ipif_to_ire(ipif);
@@ -9250,12 +9257,12 @@ ip_newroute_ipif(queue_t *q, mblk_t *mp, ipif_t *ipif, ipaddr_t dst,
}
} else {
ASSERT((connp == NULL) ||
- (connp->conn_xmit_if_ill != NULL) ||
+ (connp->conn_outgoing_ill != NULL) ||
(connp->conn_dontroute) ||
infop->ip_opt_ill_index != 0);
/*
* The only ways we can come here are:
- * 1) IP_XMIT_IF socket option is set
+ * 1) IP_BOUND_IF socket option is set
* 2) SO_DONTROUTE socket option is set
* 3) IP_PKTINFO option is passed in as ancillary data.
* In all cases, the new ire will not be added
@@ -10493,19 +10500,6 @@ setit:
0 : ifindex;
break;
- case IP_XMIT_IF:
- /*
- * Similar to IP_BOUND_IF, but this only
- * determines the outgoing interface for
- * unicast packets. Also no IRE_CACHE entry
- * is added for the destination of the
- * outgoing packets.
- */
- connp->conn_xmit_if_ill = ill;
- connp->conn_orig_xmit_ifindex = (ill == NULL) ?
- 0 : ifindex;
- break;
-
case IP_MULTICAST_IF:
/*
* This option is an internal special. The socket
@@ -10530,6 +10524,26 @@ setit:
}
}
break;
+
+ case IP_DHCPINIT_IF:
+ if (connp->conn_dhcpinit_ill != NULL) {
+ /*
+ * We've locked the conn so conn_cleanup_ill()
+ * cannot clear conn_dhcpinit_ill -- so it's
+ * safe to access the ill.
+ */
+ ill_t *oill = connp->conn_dhcpinit_ill;
+
+ ASSERT(oill->ill_dhcpinit != 0);
+ atomic_dec_32(&oill->ill_dhcpinit);
+ connp->conn_dhcpinit_ill = NULL;
+ }
+
+ if (ill != NULL) {
+ connp->conn_dhcpinit_ill = ill;
+ atomic_inc_32(&ill->ill_dhcpinit);
+ }
+ break;
}
} else {
switch (option) {
@@ -11048,7 +11062,7 @@ ip_opt_set(queue_t *q, uint_t optset_context, int level, int name,
*outlenp = inlen;
return (0);
case IP_BOUND_IF:
- case IP_XMIT_IF:
+ case IP_DHCPINIT_IF:
error = ip_opt_set_ill(connp, *i1, B_FALSE, checkonly,
level, name, first_mp);
if (error != 0)
@@ -15003,11 +15017,12 @@ ip_input(ill_t *ill, ill_rx_ring_t *ip_ring, mblk_t *mp_chain,
* o no options in the packet
* o not a RSVP packet
* o not a multicast packet
+ * o ill not in IP_DHCPINIT_IF mode
*/
if (!is_system_labeled() &&
!ipst->ips_ip_cgtp_filter && ipp_action_count == 0 &&
opt_len == 0 && ipha->ipha_protocol != IPPROTO_RSVP &&
- !ll_multicast && !CLASSD(dst)) {
+ !ll_multicast && !CLASSD(dst) && ill->ill_dhcpinit == 0) {
if (ire == NULL)
ire = ire_cache_lookup(dst, ALL_ZONES, NULL,
ipst);
@@ -15031,6 +15046,31 @@ ip_input(ill_t *ill, ill_rx_ring_t *ip_ring, mblk_t *mp_chain,
ire = NULL;
}
+ /*
+ * Brutal hack for DHCPv4 unicast: RFC2131 allows a DHCP
+ * server to unicast DHCP packets to a DHCP client using the
+ * IP address it is offering to the client. This can be
+ * disabled through the "broadcast bit", but not all DHCP
+ * servers honor that bit. Therefore, to interoperate with as
+ * many DHCP servers as possible, the DHCP client allows the
+ * server to unicast, but we treat those packets as broadcast
+ * here. Note that we don't rewrite the packet itself since
+ * (a) that would mess up the checksums and (b) the DHCP
+ * client conn is bound to INADDR_ANY so ip_fanout_udp() will
+ * hand it the packet regardless.
+ */
+ if (ill->ill_dhcpinit != 0 &&
+ IS_SIMPLE_IPH(ipha) && ipha->ipha_protocol == IPPROTO_UDP &&
+ MBLKL(mp) > sizeof (ipha_t) + sizeof (udpha_t)) {
+ udpha_t *udpha = (udpha_t *)&ipha[1];
+
+ if (ntohs(udpha->uha_dst_port) == IPPORT_BOOTPC) {
+ DTRACE_PROBE2(ip4__dhcpinit__pkt, ill_t *, ill,
+ mblk_t *, mp);
+ dst = INADDR_BROADCAST;
+ }
+ }
+
/* Full-blown slow path */
if (opt_len != 0) {
if (len != 0)
@@ -19988,7 +20028,7 @@ ip_output_options(void *arg, mblk_t *mp, void *arg2, int caller,
int match_flags;
ill_t *attach_ill = NULL;
/* Bind to IPIF_NOFAILOVER ill etc. */
- ill_t *xmit_ill = NULL; /* IP_XMIT_IF etc. */
+ ill_t *xmit_ill = NULL; /* IP_PKTINFO etc. */
ipif_t *dst_ipif;
boolean_t multirt_need_resolve = B_FALSE;
mblk_t *copy_mp = NULL;
@@ -20109,11 +20149,11 @@ ip_output_options(void *arg, mblk_t *mp, void *arg2, int caller,
}
/*
- * IP_DONTFAILOVER_IF and IP_XMIT_IF have precedence over
- * ill index passed in IP_PKTINFO.
+ * IP_DONTFAILOVER_IF and IP_BOUND_IF have precedence over ill index
+ * passed in IP_PKTINFO.
*/
if (infop->ip_opt_ill_index != 0 &&
- connp->conn_xmit_if_ill == NULL &&
+ connp->conn_outgoing_ill == NULL &&
connp->conn_nofailover_ill == NULL) {
xmit_ill = ill_lookup_on_ifindex(
@@ -20178,6 +20218,15 @@ ip_output_options(void *arg, mblk_t *mp, void *arg2, int caller,
}
}
+ /* If IP_BOUND_IF has been set, use that ill. */
+ if (connp->conn_outgoing_ill != NULL) {
+ xmit_ill = conn_get_held_ill(connp,
+ &connp->conn_outgoing_ill, &err);
+ if (err == ILL_LOOKUP_FAILED)
+ goto drop_pkt;
+
+ goto send_from_ill;
+ }
/* is packet multicast? */
if (CLASSD(dst))
@@ -20187,74 +20236,39 @@ ip_output_options(void *arg, mblk_t *mp, void *arg2, int caller,
* If xmit_ill is set above due to index passed in ip_pkt_info. It
* takes precedence over conn_dontroute and conn_nexthop_set
*/
- if (xmit_ill != NULL) {
+ if (xmit_ill != NULL)
goto send_from_ill;
- }
- if ((connp->conn_dontroute) || (connp->conn_xmit_if_ill != NULL) ||
- (connp->conn_nexthop_set)) {
+ if (connp->conn_dontroute || connp->conn_nexthop_set) {
/*
- * If the destination is a broadcast or a loopback
- * address, SO_DONTROUTE, IP_XMIT_IF and IP_NEXTHOP go
- * through the standard path. But in the case of local
- * destination only SO_DONTROUTE and IP_NEXTHOP go through
- * the standard path not IP_XMIT_IF.
+ * If the destination is a broadcast, local, or loopback
+ * address, SO_DONTROUTE and IP_NEXTHOP go through the
+ * standard path.
*/
ire = ire_cache_lookup(dst, zoneid, MBLK_GETLABEL(mp), ipst);
- if ((ire == NULL) || ((ire->ire_type != IRE_BROADCAST) &&
- (ire->ire_type != IRE_LOOPBACK))) {
- if ((connp->conn_dontroute ||
- connp->conn_nexthop_set) && (ire != NULL) &&
- (ire->ire_type == IRE_LOCAL))
- goto standard_path;
-
+ if ((ire == NULL) || (ire->ire_type &
+ (IRE_BROADCAST | IRE_LOCAL | IRE_LOOPBACK)) == 0) {
if (ire != NULL) {
ire_refrele(ire);
/* No more access to ire */
ire = NULL;
}
/*
- * bypass routing checks and go directly to
- * interface.
+ * bypass routing checks and go directly to interface.
*/
- if (connp->conn_dontroute) {
+ if (connp->conn_dontroute)
goto dontroute;
- } else if (connp->conn_nexthop_set) {
- ip_nexthop = B_TRUE;
- nexthop_addr = connp->conn_nexthop_v4;
- goto send_from_ill;
- }
- /*
- * If IP_XMIT_IF socket option is set,
- * then we allow unicast and multicast
- * packets to go through the ill. It is
- * quite possible that the destination
- * is not in the ire cache table and we
- * do not want to go to ip_newroute()
- * instead we call ip_newroute_ipif.
- */
- xmit_ill = conn_get_held_ill(connp,
- &connp->conn_xmit_if_ill, &err);
- if (err == ILL_LOOKUP_FAILED) {
- BUMP_MIB(&ipst->ips_ip_mib,
- ipIfStatsOutDiscards);
- if (attach_ill != NULL)
- ill_refrele(attach_ill);
- if (need_decref)
- CONN_DEC_REF(connp);
- freemsg(first_mp);
- return;
- }
+ ASSERT(connp->conn_nexthop_set);
+ ip_nexthop = B_TRUE;
+ nexthop_addr = connp->conn_nexthop_v4;
goto send_from_ill;
}
-standard_path:
+
/* Must be a broadcast, a loopback or a local ire */
- if (ire != NULL) {
- ire_refrele(ire);
- /* No more access to ire */
- ire = NULL;
- }
+ ire_refrele(ire);
+ /* No more access to ire */
+ ire = NULL;
}
if (attach_ill != NULL)
@@ -20819,17 +20833,16 @@ multicast:
ntohl(dst), ill->ill_name));
} else {
/*
- * The order of precedence is IP_XMIT_IF, IP_PKTINFO
- * and IP_MULTICAST_IF.
- * Block comment above this function explains the
- * locking mechanism used here
+ * The order of precedence is IP_BOUND_IF, IP_PKTINFO
+ * and IP_MULTICAST_IF. The block comment above this
+ * function explains the locking mechanism used here.
*/
if (xmit_ill == NULL) {
xmit_ill = conn_get_held_ill(connp,
- &connp->conn_xmit_if_ill, &err);
+ &connp->conn_outgoing_ill, &err);
if (err == ILL_LOOKUP_FAILED) {
ip1dbg(("ip_wput: No ill for "
- "IP_XMIT_IF\n"));
+ "IP_BOUND_IF\n"));
BUMP_MIB(&ipst->ips_ip_mib,
ipIfStatsOutNoRoutes);
goto drop_pkt;
@@ -20851,7 +20864,7 @@ multicast:
ipif = ipif_get_next_ipif(NULL, xmit_ill);
if (ipif == NULL) {
ip1dbg(("ip_wput: No ipif for "
- "IP_XMIT_IF\n"));
+ "xmit_ill\n"));
BUMP_MIB(&ipst->ips_ip_mib,
ipIfStatsOutNoRoutes);
goto drop_pkt;
@@ -20994,7 +21007,7 @@ multicast:
dst = ipif->ipif_lcl_addr;
/*
- * If IP_XMIT_IF is set, we branch out to ip_newroute_ipif.
+ * If xmit_ill is set, we branch out to ip_newroute_ipif.
* We don't need to lookup ire in ctable as the packet
* needs to be sent to the destination through the specified
* ill irrespective of ires in the cache table.
@@ -21095,54 +21108,39 @@ dontroute:
* connectivity.
*/
ipha->ipha_ttl = 1;
- /*
- * If IP_XMIT_IF is also set (conn_xmit_if_ill != NULL)
- * along with SO_DONTROUTE, higher precedence is
- * given to IP_XMIT_IF and the IP_XMIT_IF ipif is used.
- */
- if (connp->conn_xmit_if_ill == NULL) {
- /* If suitable ipif not found, drop packet */
- dst_ipif = ipif_lookup_onlink_addr(dst, zoneid,
- ipst);
- if (dst_ipif == NULL) {
- ip1dbg(("ip_wput: no route for "
- "dst using SO_DONTROUTE\n"));
- BUMP_MIB(&ipst->ips_ip_mib,
- ipIfStatsOutNoRoutes);
- mp->b_prev = mp->b_next = NULL;
- if (first_mp == NULL)
- first_mp = mp;
- goto drop_pkt;
- } else {
- /*
- * If suitable ipif has been found, set
- * xmit_ill to the corresponding
- * ipif_ill because we'll be following
- * the IP_XMIT_IF logic.
- */
- ASSERT(xmit_ill == NULL);
- xmit_ill = dst_ipif->ipif_ill;
- mutex_enter(&xmit_ill->ill_lock);
- if (!ILL_CAN_LOOKUP(xmit_ill)) {
- mutex_exit(&xmit_ill->ill_lock);
- xmit_ill = NULL;
- ipif_refrele(dst_ipif);
- ip1dbg(("ip_wput: no route for"
- " dst using"
- " SO_DONTROUTE\n"));
- BUMP_MIB(&ipst->ips_ip_mib,
- ipIfStatsOutNoRoutes);
- mp->b_prev = mp->b_next = NULL;
- if (first_mp == NULL)
- first_mp = mp;
- goto drop_pkt;
- }
- ill_refhold_locked(xmit_ill);
+
+ /* If suitable ipif not found, drop packet */
+ dst_ipif = ipif_lookup_onlink_addr(dst, zoneid, ipst);
+ if (dst_ipif == NULL) {
+noroute:
+ ip1dbg(("ip_wput: no route for dst using"
+ " SO_DONTROUTE\n"));
+ BUMP_MIB(&ipst->ips_ip_mib,
+ ipIfStatsOutNoRoutes);
+ mp->b_prev = mp->b_next = NULL;
+ if (first_mp == NULL)
+ first_mp = mp;
+ goto drop_pkt;
+ } else {
+ /*
+ * If suitable ipif has been found, set
+ * xmit_ill to the corresponding
+ * ipif_ill because we'll be using the
+ * send_from_ill logic below.
+ */
+ ASSERT(xmit_ill == NULL);
+ xmit_ill = dst_ipif->ipif_ill;
+ mutex_enter(&xmit_ill->ill_lock);
+ if (!ILL_CAN_LOOKUP(xmit_ill)) {
mutex_exit(&xmit_ill->ill_lock);
+ xmit_ill = NULL;
ipif_refrele(dst_ipif);
+ goto noroute;
}
+ ill_refhold_locked(xmit_ill);
+ mutex_exit(&xmit_ill->ill_lock);
+ ipif_refrele(dst_ipif);
}
-
}
/*
* If we are bound to IPIF_NOFAILOVER address, look for
@@ -21170,84 +21168,64 @@ send_from_ill:
ire = ire_ctable_lookup(dst, 0, 0, attach_ipif,
zoneid, MBLK_GETLABEL(mp), match_flags, ipst);
ipif_refrele(attach_ipif);
- } else if (xmit_ill != NULL || (connp != NULL &&
- connp->conn_xmit_if_ill != NULL)) {
+ } else if (xmit_ill != NULL) {
+ ipif_t *ipif;
+
/*
* Mark this packet as originated locally
*/
mp->b_prev = mp->b_next = NULL;
+
/*
- * xmit_ill could be NULL if SO_DONTROUTE
- * is also set.
+ * Could be SO_DONTROUTE case also.
+ * Verify that at least one ipif is up on the ill.
*/
- if (xmit_ill == NULL) {
- xmit_ill = conn_get_held_ill(connp,
- &connp->conn_xmit_if_ill, &err);
- if (err == ILL_LOOKUP_FAILED) {
- BUMP_MIB(&ipst->ips_ip_mib,
- ipIfStatsOutDiscards);
- if (need_decref)
- CONN_DEC_REF(connp);
- freemsg(first_mp);
- return;
- }
- if (xmit_ill == NULL) {
- if (connp->conn_dontroute)
- goto dontroute;
- goto send_from_ill;
- }
+ if (xmit_ill->ill_ipif_up_count == 0) {
+ ip1dbg(("ip_output: xmit_ill %s is down\n",
+ xmit_ill->ill_name));
+ goto drop_pkt;
}
+
+ ipif = ipif_get_next_ipif(NULL, xmit_ill);
+ if (ipif == NULL) {
+ ip1dbg(("ip_output: xmit_ill %s NULL ipif\n",
+ xmit_ill->ill_name));
+ goto drop_pkt;
+ }
+
/*
- * Could be SO_DONTROUTE case also.
- * check at least one interface is UP as
- * specified by this ILL
+ * Look for a ire that is part of the group,
+ * if found use it else call ip_newroute_ipif.
+ * IPCL_ZONEID is not used for matching because
+ * IP_ALLZONES option is valid only when the
+ * ill is accessible from all zones i.e has a
+ * valid ipif in all zones.
*/
- if (xmit_ill->ill_ipif_up_count > 0) {
- ipif_t *ipif;
-
- ipif = ipif_get_next_ipif(NULL, xmit_ill);
- if (ipif == NULL) {
- ip1dbg(("ip_output: "
- "xmit_ill NULL ipif\n"));
- goto drop_pkt;
- }
- /*
- * Look for a ire that is part of the group,
- * if found use it else call ip_newroute_ipif.
- * IPCL_ZONEID is not used for matching because
- * IP_ALLZONES option is valid only when the
- * ill is accessible from all zones i.e has a
- * valid ipif in all zones.
- */
- match_flags = MATCH_IRE_ILL_GROUP |
- MATCH_IRE_SECATTR;
- ire = ire_ctable_lookup(dst, 0, 0, ipif, zoneid,
- MBLK_GETLABEL(mp), match_flags, ipst);
- /*
- * If an ire exists use it or else create
- * an ire but don't add it to the cache.
- * Adding an ire may cause issues with
- * asymmetric routing.
- * In case of multiroute always act as if
- * ire does not exist.
- */
- if (ire == NULL ||
- ire->ire_flags & RTF_MULTIRT) {
- if (ire != NULL)
- ire_refrele(ire);
- ip_newroute_ipif(q, first_mp, ipif,
- dst, connp, 0, zoneid, infop);
- ipif_refrele(ipif);
- ip1dbg(("ip_wput: ip_unicast_if\n"));
- ill_refrele(xmit_ill);
- if (need_decref)
- CONN_DEC_REF(connp);
- return;
- }
+ match_flags = MATCH_IRE_ILL_GROUP | MATCH_IRE_SECATTR;
+ ire = ire_ctable_lookup(dst, 0, 0, ipif, zoneid,
+ MBLK_GETLABEL(mp), match_flags, ipst);
+ /*
+ * If an ire exists use it or else create
+ * an ire but don't add it to the cache.
+ * Adding an ire may cause issues with
+ * asymmetric routing.
+ * In case of multiroute always act as if
+ * ire does not exist.
+ */
+ if (ire == NULL || ire->ire_flags & RTF_MULTIRT) {
+ if (ire != NULL)
+ ire_refrele(ire);
+ ip_newroute_ipif(q, first_mp, ipif,
+ dst, connp, 0, zoneid, infop);
ipif_refrele(ipif);
- } else {
- goto drop_pkt;
+ ip1dbg(("ip_output: xmit_ill via %s\n",
+ xmit_ill->ill_name));
+ ill_refrele(xmit_ill);
+ if (need_decref)
+ CONN_DEC_REF(connp);
+ return;
}
+ ipif_refrele(ipif);
} else if (ip_nexthop || (connp != NULL &&
(connp->conn_nexthop_set)) && !ignore_nexthop) {
if (!ip_nexthop) {
@@ -21458,7 +21436,7 @@ ip_wput(queue_t *q, mblk_t *mp)
*
* The following rules must be observed when accessing any ipif or ill
* that has been cached in the conn. Typically conn_nofailover_ill,
- * conn_xmit_if_ill, conn_multicast_ipif and conn_multicast_ill.
+ * conn_outgoing_ill, conn_multicast_ipif and conn_multicast_ill.
*
* Access: The ipif or ill pointed to from the conn can be accessed under
* the protection of the conn_lock or after it has been refheld under the
@@ -22020,11 +21998,10 @@ ip_wput_ire(queue_t *q, mblk_t *mp, ire_t *ire, conn_t *connp, int caller,
}
/*
- * conn_outgoing_ill is used only in the broadcast loop.
+ * conn_outgoing_ill variable is used only in the broadcast loop.
* for performance we don't grab the mutexs in the fastpath
*/
if ((connp != NULL) &&
- (connp->conn_xmit_if_ill == NULL) &&
(ire->ire_type == IRE_BROADCAST) &&
((connp->conn_nofailover_ill != NULL) ||
(connp->conn_outgoing_ill != NULL))) {
@@ -22611,8 +22588,8 @@ broadcast:
rw_exit(&ire->ire_bucket->irb_lock);
/* Did not find a matching ill */
ip1dbg(("ip_wput_ire: broadcast with no "
- "matching IP_BOUND_IF ill %s\n",
- conn_outgoing_ill->ill_name));
+ "matching IP_BOUND_IF ill %s dst %x\n",
+ conn_outgoing_ill->ill_name, dst));
freemsg(first_mp);
if (ire != NULL)
ire_refrele(ire);