summaryrefslogtreecommitdiff
path: root/usr/src/uts/common/inet/udp/udp.c
diff options
context:
space:
mode:
Diffstat (limited to 'usr/src/uts/common/inet/udp/udp.c')
-rw-r--r--usr/src/uts/common/inet/udp/udp.c66
1 files changed, 36 insertions, 30 deletions
diff --git a/usr/src/uts/common/inet/udp/udp.c b/usr/src/uts/common/inet/udp/udp.c
index 3369ca915e..70677c86d8 100644
--- a/usr/src/uts/common/inet/udp/udp.c
+++ b/usr/src/uts/common/inet/udp/udp.c
@@ -78,6 +78,7 @@
#include <inet/ipclassifier.h>
#include <inet/ipsec_impl.h>
#include <inet/ipp_common.h>
+#include <sys/squeue_impl.h>
#include <inet/ipnet.h>
/*
@@ -196,14 +197,15 @@ static int udp_rinfop(queue_t *q, infod_t *dp);
static int udp_rrw(queue_t *q, struiod_t *dp);
static int udp_status_report(queue_t *q, mblk_t *mp, caddr_t cp,
cred_t *cr);
-static void udp_send_data(udp_t *, queue_t *, mblk_t *, ipha_t *);
+static void udp_send_data(udp_t *udp, queue_t *q, mblk_t *mp,
+ ipha_t *ipha);
static void udp_ud_err(queue_t *q, mblk_t *mp, uchar_t *destaddr,
t_scalar_t destlen, t_scalar_t err);
static void udp_unbind(queue_t *q, mblk_t *mp);
static in_port_t udp_update_next_port(udp_t *udp, in_port_t port,
boolean_t random);
static mblk_t *udp_output_v4(conn_t *, mblk_t *, ipaddr_t, uint16_t, uint_t,
- int *, boolean_t);
+ int *, boolean_t);
static mblk_t *udp_output_v6(conn_t *connp, mblk_t *mp, sin6_t *sin6,
int *error);
static void udp_wput_other(queue_t *q, mblk_t *mp);
@@ -4401,6 +4403,7 @@ udp_input(void *arg1, mblk_t *mp, void *arg2)
UDP_STAT(us, udp_in_recvucred);
}
+ /* XXX FIXME: apply to AF_INET6 as well */
/*
* If SO_TIMESTAMP is set allocate the appropriate sized
* buffer. Since gethrestime() expects a pointer aligned
@@ -6237,8 +6240,12 @@ udp_xmit(queue_t *q, mblk_t *mp, ire_t *ire, conn_t *connp, zoneid_t zoneid)
dev_q = ire->ire_stq->q_next;
ASSERT(dev_q != NULL);
+ ill = ire_to_ill(ire);
+ ASSERT(ill != NULL);
- if (DEV_Q_IS_FLOW_CTLED(dev_q)) {
+ /* is queue flow controlled? */
+ if (q->q_first != NULL || connp->conn_draining ||
+ DEV_Q_FLOW_BLOCKED(dev_q)) {
BUMP_MIB(&ipst->ips_ip_mib, ipIfStatsHCOutRequests);
BUMP_MIB(&ipst->ips_ip_mib, ipIfStatsOutDiscards);
if (ipst->ips_ip_output_queue)
@@ -6256,8 +6263,6 @@ udp_xmit(queue_t *q, mblk_t *mp, ire_t *ire, conn_t *connp, zoneid_t zoneid)
dst = ipha->ipha_dst;
src = ipha->ipha_src;
- ill = ire_to_ill(ire);
- ASSERT(ill != NULL);
BUMP_MIB(ill->ill_ip_mib, ipIfStatsHCOutRequests);
@@ -6334,31 +6339,32 @@ udp_xmit(queue_t *q, mblk_t *mp, ire_t *ire, conn_t *connp, zoneid_t zoneid)
UPDATE_MIB(ill->ill_ip_mib, ipIfStatsHCOutOctets,
ntohs(ipha->ipha_length));
- if (ILL_DLS_CAPABLE(ill)) {
- /*
- * Send the packet directly to DLD, where it may be queued
- * depending on the availability of transmit resources at
- * the media layer.
- */
- IP_DLS_ILL_TX(ill, ipha, mp, ipst, ire_fp_mp_len);
- } else {
- DTRACE_PROBE4(ip4__physical__out__start,
- ill_t *, NULL, ill_t *, ill,
- ipha_t *, ipha, mblk_t *, mp);
- FW_HOOKS(ipst->ips_ip4_physical_out_event,
- ipst->ips_ipv4firewall_physical_out,
- NULL, ill, ipha, mp, mp, ll_multicast, ipst);
- DTRACE_PROBE1(ip4__physical__out__end, mblk_t *, mp);
- if (mp != NULL) {
- if (ipst->ips_ipobs_enabled) {
- ipobs_hook(mp, IPOBS_HOOK_OUTBOUND,
- IP_REAL_ZONEID(connp->conn_zoneid, ipst),
- ALL_ZONES, ill, IPV4_VERSION, ire_fp_mp_len,
- ipst);
- }
- DTRACE_IP7(send, mblk_t *, mp, conn_t *, NULL,
- void_ip_t *, ipha, __dtrace_ipsr_ill_t *, ill,
- ipha_t *, ipha, ip6_t *, NULL, int, 0);
+ DTRACE_PROBE4(ip4__physical__out__start,
+ ill_t *, NULL, ill_t *, ill, ipha_t *, ipha, mblk_t *, mp);
+ FW_HOOKS(ipst->ips_ip4_physical_out_event,
+ ipst->ips_ipv4firewall_physical_out, NULL, ill, ipha, mp, mp,
+ ll_multicast, ipst);
+ DTRACE_PROBE1(ip4__physical__out__end, mblk_t *, mp);
+ if (ipst->ips_ipobs_enabled && mp != NULL) {
+ zoneid_t szone;
+
+ szone = ip_get_zoneid_v4(ipha->ipha_src, mp,
+ ipst, ALL_ZONES);
+ ipobs_hook(mp, IPOBS_HOOK_OUTBOUND, szone,
+ ALL_ZONES, ill, IPV4_VERSION, ire_fp_mp_len, ipst);
+ }
+
+ if (mp != NULL) {
+ DTRACE_IP7(send, mblk_t *, mp, conn_t *, NULL,
+ void_ip_t *, ipha, __dtrace_ipsr_ill_t *, ill,
+ ipha_t *, ipha, ip6_t *, NULL, int, 0);
+
+ if (ILL_DIRECT_CAPABLE(ill)) {
+ ill_dld_direct_t *idd = &ill->ill_dld_capab->idc_direct;
+
+ (void) idd->idd_tx_df(idd->idd_tx_dh, mp,
+ (uintptr_t)connp, 0);
+ } else {
putnext(ire->ire_stq, mp);
}
}